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