3 * Copyright (c) 2011, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/IoLib.h>
22 #include <Library/PcdLib.h>
23 #include <Library/UefiBootServicesTableLib.h>
24 #include <Library/UefiLib.h>
25 #include <Library/UefiRuntimeServicesTableLib.h>
27 #include <Protocol/EmbeddedGpio.h>
28 #include <Drivers/PL061Gpio.h>
30 BOOLEAN mPL061Initialized
= FALSE
;
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)) {
67 // Check if the PL061 GPIO module exists on board
68 Status
= PL061Identify();
69 if (EFI_ERROR (Status
)) {
70 Status
= EFI_DEVICE_ERROR
;
74 // Do other hardware initialisation things here as required
77 //if (MmioRead8 (PL061_GPIO_IE_REG) != 0) {
78 // // Ensure interrupts are disabled
81 mPL061Initialized
= TRUE
;
91 Gets the state of a GPIO pin
95 This - pointer to protocol
96 Gpio - which pin to read
97 Value - state of the pin
101 EFI_SUCCESS - GPIO state returned in Value
102 EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
107 IN EMBEDDED_GPIO
*This
,
108 IN EMBEDDED_GPIO_PIN Gpio
,
112 EFI_STATUS Status
= EFI_SUCCESS
;
115 || (Gpio
> LAST_GPIO_PIN
))
117 return EFI_INVALID_PARAMETER
;
120 // Initialize the hardware if not already done
121 if (!mPL061Initialized
) {
122 Status
= PL061Initialize();
123 if (EFI_ERROR(Status
)) {
128 if (MmioRead8 (PL061_GPIO_DATA_REG
) & GPIO_PIN_MASK_HIGH_8BIT(Gpio
)) {
142 Sets the state of a GPIO pin
146 This - pointer to protocol
147 Gpio - which pin to modify
152 EFI_SUCCESS - GPIO set as requested
153 EFI_UNSUPPORTED - Mode is not supported
154 EFI_INVALID_PARAMETER - Gpio pin is out of range
159 IN EMBEDDED_GPIO
*This
,
160 IN EMBEDDED_GPIO_PIN Gpio
,
161 IN EMBEDDED_GPIO_MODE Mode
164 EFI_STATUS Status
= EFI_SUCCESS
;
167 if (Gpio
> LAST_GPIO_PIN
) {
168 Status
= EFI_INVALID_PARAMETER
;
172 // Initialize the hardware if not already done
173 if (!mPL061Initialized
) {
174 Status
= PL061Initialize();
175 if (EFI_ERROR(Status
)) {
182 case GPIO_MODE_INPUT
:
183 // Set the corresponding direction bit to LOW for input
184 MmioAnd8 (PL061_GPIO_DIR_REG
, GPIO_PIN_MASK_LOW_8BIT(Gpio
));
187 case GPIO_MODE_OUTPUT_0
:
188 // Set the corresponding data bit to LOW for 0
189 MmioAnd8 (PL061_GPIO_DATA_REG
, GPIO_PIN_MASK_LOW_8BIT(Gpio
));
190 // Set the corresponding direction bit to HIGH for output
191 MmioOr8 (PL061_GPIO_DIR_REG
, GPIO_PIN_MASK_HIGH_8BIT(Gpio
));
194 case GPIO_MODE_OUTPUT_1
:
195 // Set the corresponding data bit to HIGH for 1
196 MmioOr8 (PL061_GPIO_DATA_REG
, GPIO_PIN_MASK_HIGH_8BIT(Gpio
));
197 // Set the corresponding direction bit to HIGH for output
198 MmioOr8 (PL061_GPIO_DIR_REG
, GPIO_PIN_MASK_HIGH_8BIT(Gpio
));
202 // Other modes are not supported
203 return EFI_UNSUPPORTED
;
214 Gets the mode (function) of a GPIO pin
218 This - pointer to protocol
220 Mode - pointer to output mode value
224 EFI_SUCCESS - mode value retrieved
225 EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
231 IN EMBEDDED_GPIO
*This
,
232 IN EMBEDDED_GPIO_PIN Gpio
,
233 OUT EMBEDDED_GPIO_MODE
*Mode
240 || (Gpio
> LAST_GPIO_PIN
)) {
241 return EFI_INVALID_PARAMETER
;
244 // Initialize the hardware if not already done
245 if (!mPL061Initialized
) {
246 Status
= PL061Initialize();
247 if (EFI_ERROR(Status
)) {
252 // Check if it is input or output
253 if (MmioRead8 (PL061_GPIO_DIR_REG
) & GPIO_PIN_MASK_HIGH_8BIT(Gpio
)) {
255 if (MmioRead8 (PL061_GPIO_DATA_REG
) & GPIO_PIN_MASK_HIGH_8BIT(Gpio
)) {
256 *Mode
= GPIO_MODE_OUTPUT_1
;
258 *Mode
= GPIO_MODE_OUTPUT_0
;
262 *Mode
= GPIO_MODE_INPUT
;
272 Sets the pull-up / pull-down resistor of a GPIO pin
276 This - pointer to protocol
278 Direction - pull-up, pull-down, or none
282 EFI_UNSUPPORTED - Can not perform the requested operation
288 IN EMBEDDED_GPIO
*This
,
289 IN EMBEDDED_GPIO_PIN Gpio
,
290 IN EMBEDDED_GPIO_PULL Direction
293 return EFI_UNSUPPORTED
;
297 Protocol variable definition
299 EMBEDDED_GPIO gGpio
= {
307 Initialize the state information for the Embedded Gpio protocol.
309 @param ImageHandle of the loaded driver
310 @param SystemTable Pointer to the System Table
312 @retval EFI_SUCCESS Protocol registered
313 @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
314 @retval EFI_DEVICE_ERROR Hardware problems
319 PL061InstallProtocol (
320 IN EFI_HANDLE ImageHandle
,
321 IN EFI_SYSTEM_TABLE
*SystemTable
328 // Make sure the Gpio protocol has not been installed in the system yet.
330 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gEmbeddedGpioProtocolGuid
);
332 // Install the Embedded GPIO Protocol onto a new handle
334 Status
= gBS
->InstallMultipleProtocolInterfaces(
336 &gEmbeddedGpioProtocolGuid
, &gGpio
,
339 if (EFI_ERROR(Status
)) {
340 Status
= EFI_OUT_OF_RESOURCES
;