]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
Check the input VaraibleName for db/dbx when appending variables with formatted as...
[mirror_edk2.git] / ArmPlatformPkg / Drivers / PL061GpioDxe / PL061Gpio.c
CommitLineData
5a62a8b7 1/** @file
2*
3* Copyright (c) 2011, ARM Limited. All rights reserved.
4*
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
9*
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.
12*
13**/
14
15
5a62a8b7 16#include <PiDxe.h>
17
18#include <Library/BaseLib.h>
5a62a8b7 19#include <Library/BaseMemoryLib.h>
5cc45b70 20#include <Library/DebugLib.h>
21#include <Library/IoLib.h>
22#include <Library/PcdLib.h>
5a62a8b7 23#include <Library/UefiBootServicesTableLib.h>
5a62a8b7 24#include <Library/UefiLib.h>
5cc45b70 25#include <Library/UefiRuntimeServicesTableLib.h>
5a62a8b7 26
27#include <Protocol/EmbeddedGpio.h>
5a62a8b7 28#include <Drivers/PL061Gpio.h>
29
5a62a8b7 30BOOLEAN mPL061Initialized = FALSE;
31
32/**
33 Function implementations
34**/
35
36EFI_STATUS
37PL061Identify (
38 VOID
39 )
40{
41 // Check if this is a PrimeCell Peripheral
5cc45b70 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)) {
5a62a8b7 46 return EFI_NOT_FOUND;
47 }
48
49 // Check if this PrimeCell Peripheral is the PL061 GPIO
5cc45b70 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)) {
5a62a8b7 54 return EFI_NOT_FOUND;
55 }
56
57 return EFI_SUCCESS;
58}
59
60EFI_STATUS
61PL061Initialize (
5cc45b70 62 VOID
5a62a8b7 63 )
64{
65 EFI_STATUS Status;
66
67 // Check if the PL061 GPIO module exists on board
68 Status = PL061Identify();
5cc45b70 69 if (EFI_ERROR (Status)) {
5a62a8b7 70 Status = EFI_DEVICE_ERROR;
71 goto EXIT;
72 }
73
74 // Do other hardware initialisation things here as required
75
76 // Disable Interrupts
5cc45b70 77 //if (MmioRead8 (PL061_GPIO_IE_REG) != 0) {
5a62a8b7 78 // // Ensure interrupts are disabled
79 //}
80
81 mPL061Initialized = TRUE;
82
83 EXIT:
84 return Status;
85}
86
87/**
88
89Routine Description:
90
91 Gets the state of a GPIO pin
92
93Arguments:
94
95 This - pointer to protocol
96 Gpio - which pin to read
97 Value - state of the pin
98
99Returns:
100
101 EFI_SUCCESS - GPIO state returned in Value
102 EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
103**/
104EFI_STATUS
105EFIAPI
106Get (
107 IN EMBEDDED_GPIO *This,
108 IN EMBEDDED_GPIO_PIN Gpio,
109 OUT UINTN *Value
110 )
111{
112 EFI_STATUS Status = EFI_SUCCESS;
113
5cc45b70 114 if ( (Value == NULL)
115 || (Gpio > LAST_GPIO_PIN))
5a62a8b7 116 {
117 return EFI_INVALID_PARAMETER;
118 }
119
120 // Initialize the hardware if not already done
5cc45b70 121 if (!mPL061Initialized) {
5a62a8b7 122 Status = PL061Initialize();
5cc45b70 123 if (EFI_ERROR(Status)) {
5a62a8b7 124 goto EXIT;
125 }
126 }
127
5cc45b70 128 if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
5a62a8b7 129 *Value = 1;
130 } else {
131 *Value = 0;
132 }
133
134 EXIT:
135 return Status;
136}
137
138/**
139
140Routine Description:
141
142 Sets the state of a GPIO pin
143
144Arguments:
145
146 This - pointer to protocol
147 Gpio - which pin to modify
148 Mode - mode to set
149
150Returns:
151
152 EFI_SUCCESS - GPIO set as requested
153 EFI_UNSUPPORTED - Mode is not supported
154 EFI_INVALID_PARAMETER - Gpio pin is out of range
155**/
156EFI_STATUS
157EFIAPI
158Set (
159 IN EMBEDDED_GPIO *This,
160 IN EMBEDDED_GPIO_PIN Gpio,
161 IN EMBEDDED_GPIO_MODE Mode
162 )
163{
164 EFI_STATUS Status = EFI_SUCCESS;
165
166 // Check for errors
5cc45b70 167 if (Gpio > LAST_GPIO_PIN) {
5a62a8b7 168 Status = EFI_INVALID_PARAMETER;
169 goto EXIT;
170 }
171
172 // Initialize the hardware if not already done
5cc45b70 173 if (!mPL061Initialized) {
5a62a8b7 174 Status = PL061Initialize();
5cc45b70 175 if (EFI_ERROR(Status)) {
5a62a8b7 176 goto EXIT;
177 }
178 }
179
180 switch (Mode)
181 {
182 case GPIO_MODE_INPUT:
183 // Set the corresponding direction bit to LOW for input
5cc45b70 184 MmioAnd8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio));
5a62a8b7 185 break;
186
187 case GPIO_MODE_OUTPUT_0:
188 // Set the corresponding data bit to LOW for 0
5cc45b70 189 MmioAnd8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio));
5a62a8b7 190 // Set the corresponding direction bit to HIGH for output
5cc45b70 191 MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
5a62a8b7 192 break;
193
194 case GPIO_MODE_OUTPUT_1:
195 // Set the corresponding data bit to HIGH for 1
5cc45b70 196 MmioOr8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
5a62a8b7 197 // Set the corresponding direction bit to HIGH for output
5cc45b70 198 MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
5a62a8b7 199 break;
200
201 default:
202 // Other modes are not supported
203 return EFI_UNSUPPORTED;
204 }
205
206EXIT:
207 return Status;
208}
209
210/**
211
212Routine Description:
213
214 Gets the mode (function) of a GPIO pin
215
216Arguments:
217
218 This - pointer to protocol
219 Gpio - which pin
220 Mode - pointer to output mode value
221
222Returns:
223
224 EFI_SUCCESS - mode value retrieved
225 EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
226
227**/
228EFI_STATUS
229EFIAPI
230GetMode (
231 IN EMBEDDED_GPIO *This,
232 IN EMBEDDED_GPIO_PIN Gpio,
233 OUT EMBEDDED_GPIO_MODE *Mode
234 )
235{
236 EFI_STATUS Status;
237
238 // Check for errors
5cc45b70 239 if ( (Mode == NULL)
240 || (Gpio > LAST_GPIO_PIN)) {
5a62a8b7 241 return EFI_INVALID_PARAMETER;
242 }
243
244 // Initialize the hardware if not already done
5cc45b70 245 if (!mPL061Initialized) {
5a62a8b7 246 Status = PL061Initialize();
5cc45b70 247 if (EFI_ERROR(Status)) {
5a62a8b7 248 return Status;
249 }
250 }
251
252 // Check if it is input or output
5cc45b70 253 if (MmioRead8 (PL061_GPIO_DIR_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
5a62a8b7 254 // Pin set to output
5cc45b70 255 if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
5a62a8b7 256 *Mode = GPIO_MODE_OUTPUT_1;
257 } else {
258 *Mode = GPIO_MODE_OUTPUT_0;
259 }
260 } else {
261 // Pin set to input
262 *Mode = GPIO_MODE_INPUT;
263 }
264
265 return EFI_SUCCESS;
266}
267
268/**
269
270Routine Description:
271
272 Sets the pull-up / pull-down resistor of a GPIO pin
273
274Arguments:
275
276 This - pointer to protocol
277 Gpio - which pin
278 Direction - pull-up, pull-down, or none
279
280Returns:
281
282 EFI_UNSUPPORTED - Can not perform the requested operation
283
284**/
285EFI_STATUS
286EFIAPI
287SetPull (
288 IN EMBEDDED_GPIO *This,
289 IN EMBEDDED_GPIO_PIN Gpio,
290 IN EMBEDDED_GPIO_PULL Direction
291 )
292{
293 return EFI_UNSUPPORTED;
294}
295
296/**
297 Protocol variable definition
298 **/
299EMBEDDED_GPIO gGpio = {
300 Get,
301 Set,
302 GetMode,
303 SetPull
304};
305
306/**
307 Initialize the state information for the Embedded Gpio protocol.
308
309 @param ImageHandle of the loaded driver
310 @param SystemTable Pointer to the System Table
311
312 @retval EFI_SUCCESS Protocol registered
313 @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
314 @retval EFI_DEVICE_ERROR Hardware problems
315
316**/
317EFI_STATUS
318EFIAPI
319PL061InstallProtocol (
320 IN EFI_HANDLE ImageHandle,
321 IN EFI_SYSTEM_TABLE *SystemTable
322 )
323{
324 EFI_STATUS Status;
325 EFI_HANDLE Handle;
326
327 //
328 // Make sure the Gpio protocol has not been installed in the system yet.
329 //
330 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid);
331
332 // Install the Embedded GPIO Protocol onto a new handle
333 Handle = NULL;
334 Status = gBS->InstallMultipleProtocolInterfaces(
335 &Handle,
336 &gEmbeddedGpioProtocolGuid, &gGpio,
337 NULL
5cc45b70 338 );
5a62a8b7 339 if (EFI_ERROR(Status)) {
340 Status = EFI_OUT_OF_RESOURCES;
341 }
342
343 return Status;
344}