3 * Copyright (c) 2011, ARM Limited. All rights reserved.
4 * Copyright (c) 2016, Linaro Limited. All rights reserved.
6 * This program and the accompanying materials
7 * are licensed and made available under the terms and conditions of the BSD
8 * License which accompanies this distribution. The full text of the license
9 * may be found at http://opensource.org/licenses/bsd-license.php
11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/BaseLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/IoLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/UefiLib.h>
26 #include <Library/UefiRuntimeServicesTableLib.h>
28 #include <Protocol/EmbeddedGpio.h>
29 #include <Drivers/PL061Gpio.h>
33 Function implementations
41 // Check if this is a PrimeCell Peripheral
42 if ( (MmioRead8 (PL061_GPIO_PCELL_ID0
) != 0x0D)
43 || (MmioRead8 (PL061_GPIO_PCELL_ID1
) != 0xF0)
44 || (MmioRead8 (PL061_GPIO_PCELL_ID2
) != 0x05)
45 || (MmioRead8 (PL061_GPIO_PCELL_ID3
) != 0xB1)) {
49 // Check if this PrimeCell Peripheral is the PL061 GPIO
50 if ( (MmioRead8 (PL061_GPIO_PERIPH_ID0
) != 0x61)
51 || (MmioRead8 (PL061_GPIO_PERIPH_ID1
) != 0x10)
52 || ((MmioRead8 (PL061_GPIO_PERIPH_ID2
) & 0xF) != 0x04)
53 || (MmioRead8 (PL061_GPIO_PERIPH_ID3
) != 0x00)) {
64 Gets the state of a GPIO pin
68 This - pointer to protocol
69 Gpio - which pin to read
70 Value - state of the pin
74 EFI_SUCCESS - GPIO state returned in Value
75 EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
80 IN EMBEDDED_GPIO
*This
,
81 IN EMBEDDED_GPIO_PIN Gpio
,
86 || (Gpio
> LAST_GPIO_PIN
))
88 return EFI_INVALID_PARAMETER
;
91 if (MmioRead8 (PL061_GPIO_DATA_REG
) & GPIO_PIN_MASK_HIGH_8BIT(Gpio
)) {
104 Sets the state of a GPIO pin
108 This - pointer to protocol
109 Gpio - which pin to modify
114 EFI_SUCCESS - GPIO set as requested
115 EFI_UNSUPPORTED - Mode is not supported
116 EFI_INVALID_PARAMETER - Gpio pin is out of range
121 IN EMBEDDED_GPIO
*This
,
122 IN EMBEDDED_GPIO_PIN Gpio
,
123 IN EMBEDDED_GPIO_MODE Mode
126 EFI_STATUS Status
= EFI_SUCCESS
;
129 if (Gpio
> LAST_GPIO_PIN
) {
130 Status
= EFI_INVALID_PARAMETER
;
136 case GPIO_MODE_INPUT
:
137 // Set the corresponding direction bit to LOW for input
138 MmioAnd8 (PL061_GPIO_DIR_REG
, GPIO_PIN_MASK_LOW_8BIT(Gpio
));
141 case GPIO_MODE_OUTPUT_0
:
142 // Set the corresponding data bit to LOW for 0
143 MmioAnd8 (PL061_GPIO_DATA_REG
, GPIO_PIN_MASK_LOW_8BIT(Gpio
));
144 // Set the corresponding direction bit to HIGH for output
145 MmioOr8 (PL061_GPIO_DIR_REG
, GPIO_PIN_MASK_HIGH_8BIT(Gpio
));
148 case GPIO_MODE_OUTPUT_1
:
149 // Set the corresponding data bit to HIGH for 1
150 MmioOr8 (PL061_GPIO_DATA_REG
, GPIO_PIN_MASK_HIGH_8BIT(Gpio
));
151 // Set the corresponding direction bit to HIGH for output
152 MmioOr8 (PL061_GPIO_DIR_REG
, GPIO_PIN_MASK_HIGH_8BIT(Gpio
));
156 // Other modes are not supported
157 return EFI_UNSUPPORTED
;
168 Gets the mode (function) of a GPIO pin
172 This - pointer to protocol
174 Mode - pointer to output mode value
178 EFI_SUCCESS - mode value retrieved
179 EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
185 IN EMBEDDED_GPIO
*This
,
186 IN EMBEDDED_GPIO_PIN Gpio
,
187 OUT EMBEDDED_GPIO_MODE
*Mode
192 || (Gpio
> LAST_GPIO_PIN
)) {
193 return EFI_INVALID_PARAMETER
;
196 // Check if it is input or output
197 if (MmioRead8 (PL061_GPIO_DIR_REG
) & GPIO_PIN_MASK_HIGH_8BIT(Gpio
)) {
199 if (MmioRead8 (PL061_GPIO_DATA_REG
) & GPIO_PIN_MASK_HIGH_8BIT(Gpio
)) {
200 *Mode
= GPIO_MODE_OUTPUT_1
;
202 *Mode
= GPIO_MODE_OUTPUT_0
;
206 *Mode
= GPIO_MODE_INPUT
;
216 Sets the pull-up / pull-down resistor of a GPIO pin
220 This - pointer to protocol
222 Direction - pull-up, pull-down, or none
226 EFI_UNSUPPORTED - Can not perform the requested operation
232 IN EMBEDDED_GPIO
*This
,
233 IN EMBEDDED_GPIO_PIN Gpio
,
234 IN EMBEDDED_GPIO_PULL Direction
237 return EFI_UNSUPPORTED
;
241 Protocol variable definition
243 EMBEDDED_GPIO gGpio
= {
251 Initialize the state information for the Embedded Gpio protocol.
253 @param ImageHandle of the loaded driver
254 @param SystemTable Pointer to the System Table
256 @retval EFI_SUCCESS Protocol registered
257 @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
258 @retval EFI_DEVICE_ERROR Hardware problems
263 PL061InstallProtocol (
264 IN EFI_HANDLE ImageHandle
,
265 IN EFI_SYSTEM_TABLE
*SystemTable
272 // Make sure the Gpio protocol has not been installed in the system yet.
274 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gEmbeddedGpioProtocolGuid
);
276 Status
= PL061Identify();
277 if (EFI_ERROR(Status
)) {
278 return EFI_DEVICE_ERROR
;
281 // Install the Embedded GPIO Protocol onto a new handle
283 Status
= gBS
->InstallMultipleProtocolInterfaces(
285 &gEmbeddedGpioProtocolGuid
, &gGpio
,
288 if (EFI_ERROR(Status
)) {
289 Status
= EFI_OUT_OF_RESOURCES
;