]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c
QuarkPlatformPkg: Add new package for Galileo boards
[mirror_edk2.git] / QuarkPlatformPkg / Library / PlatformHelperLib / PlatformHelperDxe.c
CommitLineData
b303605e
MK
1/** @file\r
2Implementation of helper routines for DXE environment.\r
3\r
4Copyright (c) 2013 Intel Corporation.\r
5\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PiDxe.h>\r
17\r
18#include <Library/UefiBootServicesTableLib.h>\r
19#include <Library/S3BootScriptLib.h>\r
20#include <Library/DxeServicesLib.h>\r
21#include <Library/UefiRuntimeServicesTableLib.h>\r
22#include <Library/I2cLib.h>\r
23#include <Protocol/SmmBase2.h>\r
24#include <Protocol/Spi.h>\r
25#include <Protocol/VariableLock.h>\r
26\r
27#include <Guid/MemoryConfigData.h>\r
28#include <Guid/QuarkVariableLock.h>\r
29\r
30#include "CommonHeader.h"\r
31\r
32#define FLASH_BLOCK_SIZE SIZE_4KB\r
33\r
34//\r
35// Global variables.\r
36//\r
37EFI_SPI_PROTOCOL *mPlatHelpSpiProtocolRef = NULL;\r
38\r
39//\r
40// Routines defined in other source modules of this component.\r
41//\r
42\r
43//\r
44// Routines local to this component.\r
45//\r
46\r
47//\r
48// Routines shared with other souce modules in this component.\r
49//\r
50\r
51BOOLEAN\r
52Pcal9555GetPortRegBit (\r
53 IN CONST UINT32 Pcal9555SlaveAddr,\r
54 IN CONST UINT32 GpioNum,\r
55 IN CONST UINT8 RegBase\r
56 )\r
57{\r
58 EFI_STATUS Status;\r
59 UINTN ReadLength;\r
60 UINTN WriteLength;\r
61 UINT8 Data[2];\r
62 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
63 EFI_I2C_ADDR_MODE I2cAddrMode;\r
64 UINT8 *RegValuePtr;\r
65 UINT8 GpioNumMask;\r
66 UINT8 SubAddr;\r
67\r
68 I2cDeviceAddr.I2CDeviceAddress = (UINTN) Pcal9555SlaveAddr;\r
69 I2cAddrMode = EfiI2CSevenBitAddrMode;\r
70\r
71 if (GpioNum < 8) {\r
72 SubAddr = RegBase;\r
73 GpioNumMask = (UINT8) (1 << GpioNum);\r
74 } else {\r
75 SubAddr = RegBase + 1;\r
76 GpioNumMask = (UINT8) (1 << (GpioNum - 8));\r
77 }\r
78\r
79 //\r
80 // Output port value always at 2nd byte in Data variable.\r
81 //\r
82 RegValuePtr = &Data[1];\r
83\r
84 //\r
85 // On read entry sub address at 2nd byte, on read exit output\r
86 // port value in 2nd byte.\r
87 //\r
88 Data[1] = SubAddr;\r
89 WriteLength = 1;\r
90 ReadLength = 1;\r
91 Status = I2cReadMultipleByte (\r
92 I2cDeviceAddr,\r
93 I2cAddrMode,\r
94 &WriteLength,\r
95 &ReadLength,\r
96 &Data[1]\r
97 );\r
98 ASSERT_EFI_ERROR (Status);\r
99\r
100 //\r
101 // Adjust output port bit given callers request.\r
102 //\r
103 return ((*RegValuePtr & GpioNumMask) != 0);\r
104}\r
105\r
106VOID\r
107Pcal9555SetPortRegBit (\r
108 IN CONST UINT32 Pcal9555SlaveAddr,\r
109 IN CONST UINT32 GpioNum,\r
110 IN CONST UINT8 RegBase,\r
111 IN CONST BOOLEAN LogicOne\r
112 )\r
113{\r
114 EFI_STATUS Status;\r
115 UINTN ReadLength;\r
116 UINTN WriteLength;\r
117 UINT8 Data[2];\r
118 EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;\r
119 EFI_I2C_ADDR_MODE I2cAddrMode;\r
120 UINT8 *RegValuePtr;\r
121 UINT8 GpioNumMask;\r
122 UINT8 SubAddr;\r
123\r
124 I2cDeviceAddr.I2CDeviceAddress = (UINTN) Pcal9555SlaveAddr;\r
125 I2cAddrMode = EfiI2CSevenBitAddrMode;\r
126\r
127 if (GpioNum < 8) {\r
128 SubAddr = RegBase;\r
129 GpioNumMask = (UINT8) (1 << GpioNum);\r
130 } else {\r
131 SubAddr = RegBase + 1;\r
132 GpioNumMask = (UINT8) (1 << (GpioNum - 8));\r
133 }\r
134\r
135 //\r
136 // Output port value always at 2nd byte in Data variable.\r
137 //\r
138 RegValuePtr = &Data[1];\r
139\r
140 //\r
141 // On read entry sub address at 2nd byte, on read exit output\r
142 // port value in 2nd byte.\r
143 //\r
144 Data[1] = SubAddr;\r
145 WriteLength = 1;\r
146 ReadLength = 1;\r
147 Status = I2cReadMultipleByte (\r
148 I2cDeviceAddr,\r
149 I2cAddrMode,\r
150 &WriteLength,\r
151 &ReadLength,\r
152 &Data[1]\r
153 );\r
154 ASSERT_EFI_ERROR (Status);\r
155\r
156 //\r
157 // Adjust output port bit given callers request.\r
158 //\r
159 if (LogicOne) {\r
160 *RegValuePtr = *RegValuePtr | GpioNumMask;\r
161 } else {\r
162 *RegValuePtr = *RegValuePtr & ~(GpioNumMask);\r
163 }\r
164\r
165 //\r
166 // Update register. Sub address at 1st byte, value at 2nd byte.\r
167 //\r
168 WriteLength = 2;\r
169 Data[0] = SubAddr;\r
170 Status = I2cWriteMultipleByte (\r
171 I2cDeviceAddr,\r
172 I2cAddrMode,\r
173 &WriteLength,\r
174 Data\r
175 );\r
176 ASSERT_EFI_ERROR (Status);\r
177}\r
178\r
179\r
180EFI_SPI_PROTOCOL *\r
181LocateSpiProtocol (\r
182 IN EFI_SMM_SYSTEM_TABLE2 *Smst\r
183 )\r
184{\r
185 if (mPlatHelpSpiProtocolRef == NULL) {\r
186 if (Smst != NULL) {\r
187 Smst->SmmLocateProtocol (\r
188 &gEfiSmmSpiProtocolGuid,\r
189 NULL,\r
190 (VOID **) &mPlatHelpSpiProtocolRef\r
191 );\r
192 } else {\r
193 gBS->LocateProtocol (\r
194 &gEfiSpiProtocolGuid,\r
195 NULL,\r
196 (VOID **) &mPlatHelpSpiProtocolRef\r
197 );\r
198 }\r
199 ASSERT (mPlatHelpSpiProtocolRef != NULL);\r
200 }\r
201 return mPlatHelpSpiProtocolRef;\r
202}\r
203\r
204//\r
205// Routines exported by this source module.\r
206//\r
207\r
208/**\r
209 Find pointer to RAW data in Firmware volume file.\r
210\r
211 @param FvNameGuid Firmware volume to search. If == NULL search all.\r
212 @param FileNameGuid Firmware volume file to search for.\r
213 @param SectionData Pointer to RAW data section of found file.\r
214 @param SectionDataSize Pointer to UNITN to get size of RAW data.\r
215\r
216 @retval EFI_SUCCESS Raw Data found.\r
217 @retval EFI_INVALID_PARAMETER FileNameGuid == NULL.\r
218 @retval EFI_NOT_FOUND Firmware volume file not found.\r
219 @retval EFI_UNSUPPORTED Unsupported in current enviroment (PEI or DXE).\r
220\r
221**/\r
222EFI_STATUS\r
223EFIAPI\r
224PlatformFindFvFileRawDataSection (\r
225 IN CONST EFI_GUID *FvNameGuid OPTIONAL,\r
226 IN CONST EFI_GUID *FileNameGuid,\r
227 OUT VOID **SectionData,\r
228 OUT UINTN *SectionDataSize\r
229 )\r
230{\r
231 if (FileNameGuid == NULL || SectionData == NULL || SectionDataSize == NULL) {\r
232 return EFI_INVALID_PARAMETER;\r
233 }\r
234 if (FvNameGuid != NULL) {\r
235 return EFI_UNSUPPORTED; // Searching in specific FV unsupported in DXE.\r
236 }\r
237\r
238 return GetSectionFromAnyFv (FileNameGuid, EFI_SECTION_RAW, 0, SectionData, SectionDataSize);\r
239}\r
240\r
241/**\r
242 Find free spi protect register and write to it to protect a flash region.\r
243\r
244 @param DirectValue Value to directly write to register.\r
245 if DirectValue == 0 the use Base & Length below.\r
246 @param BaseAddress Base address of region in Flash Memory Map.\r
247 @param Length Length of region to protect.\r
248\r
249 @retval EFI_SUCCESS Free spi protect register found & written.\r
250 @retval EFI_NOT_FOUND Free Spi protect register not found.\r
251 @retval EFI_DEVICE_ERROR Unable to write to spi protect register.\r
252**/\r
253EFI_STATUS\r
254EFIAPI\r
255PlatformWriteFirstFreeSpiProtect (\r
256 IN CONST UINT32 DirectValue,\r
257 IN CONST UINT32 BaseAddress,\r
258 IN CONST UINT32 Length\r
259 )\r
260{\r
261 UINT32 FreeOffset;\r
262 UINT32 PchRootComplexBar;\r
263 EFI_STATUS Status;\r
264\r
265 PchRootComplexBar = QNC_RCRB_BASE;\r
266\r
267 Status = WriteFirstFreeSpiProtect (\r
268 PchRootComplexBar,\r
269 DirectValue,\r
270 BaseAddress,\r
271 Length,\r
272 &FreeOffset\r
273 );\r
274\r
275 if (!EFI_ERROR (Status)) {\r
276 S3BootScriptSaveMemWrite (\r
277 S3BootScriptWidthUint32,\r
278 (UINTN) (PchRootComplexBar + FreeOffset),\r
279 1,\r
280 (VOID *) (UINTN) (PchRootComplexBar + FreeOffset)\r
281 );\r
282 }\r
283\r
284 return Status;\r
285}\r
286\r
287/**\r
288 Lock legacy SPI static configuration information.\r
289\r
290 Function will assert if unable to lock config.\r
291\r
292**/\r
293VOID\r
294EFIAPI\r
295PlatformFlashLockConfig (\r
296 VOID\r
297 )\r
298{\r
299 EFI_STATUS Status;\r
300 EFI_SPI_PROTOCOL *SpiProtocol;\r
301\r
302 //\r
303 // Enable lock of legacy SPI static configuration information.\r
304 //\r
305\r
306 SpiProtocol = LocateSpiProtocol (NULL); // This routine will not be called in SMM.\r
307 ASSERT_EFI_ERROR (SpiProtocol != NULL);\r
308 if (SpiProtocol != NULL) {\r
309 Status = SpiProtocol->Lock (SpiProtocol);\r
310\r
311 if (!EFI_ERROR (Status)) {\r
312 DEBUG ((EFI_D_INFO, "Platform: Spi Config Locked Down\n"));\r
313 } else if (Status == EFI_ACCESS_DENIED) {\r
314 DEBUG ((EFI_D_INFO, "Platform: Spi Config already locked down\n"));\r
315 } else {\r
316 ASSERT_EFI_ERROR (Status);\r
317 }\r
318 }\r
319}\r
320\r
321/**\r
322 Platform Variable Lock.\r
323\r
324 @retval EFI_SUCCESS Platform Variable Lock successful.\r
325 @retval EFI_NOT_FOUND No protocol instances were found that match Protocol and\r
326 Registration.\r
327\r
328**/\r
329VOID\r
330EFIAPI\r
331PlatformVariableLock (\r
332 )\r
333{\r
334 EFI_STATUS Status;\r
335 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;\r
336\r
337 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);\r
338 ASSERT_EFI_ERROR (Status);\r
339\r
340 Status = VariableLockProtocol->RequestToLock (\r
341 VariableLockProtocol,\r
342 QUARK_VARIABLE_LOCK_NAME,\r
343 &gQuarkVariableLockGuid\r
344 );\r
345 ASSERT_EFI_ERROR (Status);\r
346\r
347 // Memory Config Data shouldn't be writable when Quark Variable Lock is enabled.\r
348 Status = VariableLockProtocol->RequestToLock (\r
349 VariableLockProtocol,\r
350 EFI_MEMORY_CONFIG_DATA_NAME,\r
351 &gEfiMemoryConfigDataGuid\r
352 );\r
353 ASSERT_EFI_ERROR (Status);\r
354}\r
355\r
356/**\r
357 Lock regions and config of SPI flash given the policy for this platform.\r
358\r
359 Function will assert if unable to lock regions or config.\r
360\r
361 @param PreBootPolicy If TRUE do Pre Boot Flash Lock Policy.\r
362\r
363**/\r
364VOID\r
365EFIAPI\r
366PlatformFlashLockPolicy (\r
367 IN CONST BOOLEAN PreBootPolicy\r
368 )\r
369{\r
370 EFI_STATUS Status;\r
371 UINT64 CpuAddressNvStorage;\r
372 UINT64 CpuAddressFlashDevice;\r
373 UINT64 SpiAddress;\r
374 EFI_BOOT_MODE BootMode;\r
375 UINTN SpiFlashDeviceSize;\r
376\r
377 BootMode = GetBootModeHob ();\r
378\r
379 SpiFlashDeviceSize = (UINTN) PcdGet32 (PcdSpiFlashDeviceSize);\r
380 CpuAddressFlashDevice = SIZE_4GB - SpiFlashDeviceSize;\r
381 DEBUG (\r
382 (EFI_D_INFO,\r
383 "Platform:FlashDeviceSize = 0x%08x Bytes\n",\r
384 SpiFlashDeviceSize)\r
385 );\r
386\r
387 //\r
388 // If not in update or recovery mode, lock stuff down\r
389 //\r
390 if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) {\r
391\r
392 //\r
393 // Lock regions\r
394 //\r
395 CpuAddressNvStorage = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase);\r
396\r
397 //\r
398 // Lock from start of flash device up to Smi writable flash storage areas.\r
399 //\r
400 SpiAddress = 0;\r
401 if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice))) {\r
402 DEBUG (\r
403 (EFI_D_INFO,\r
404 "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",\r
405 (UINTN) SpiAddress, (UINTN)(CpuAddressNvStorage - CpuAddressFlashDevice))\r
406 );\r
407 Status = PlatformWriteFirstFreeSpiProtect (\r
408 0,\r
409 (UINT32) SpiAddress,\r
410 (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice)\r
411 );\r
412\r
413 ASSERT_EFI_ERROR (Status);\r
414 }\r
415 //\r
416 // Move Spi Address to after Smi writable flash storage areas.\r
417 //\r
418 SpiAddress = CpuAddressNvStorage - CpuAddressFlashDevice;\r
419 SpiAddress += ((UINT64) PcdGet32 (PcdFlashNvStorageVariableSize));\r
420\r
421 //\r
422 // Lock from end of OEM area to end of flash part.\r
423 //\r
424 if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, SpiFlashDeviceSize - ((UINT32) SpiAddress))) {\r
425 DEBUG (\r
426 (EFI_D_INFO,\r
427 "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",\r
428 (UINTN) SpiAddress,\r
429 (UINTN) (SpiFlashDeviceSize - ((UINT32) SpiAddress)))\r
430 );\r
431 ASSERT (SpiAddress < ((UINT64) SpiFlashDeviceSize));\r
432 Status = PlatformWriteFirstFreeSpiProtect (\r
433 0,\r
434 (UINT32) SpiAddress,\r
435 SpiFlashDeviceSize - ((UINT32) SpiAddress)\r
436 );\r
437\r
438 ASSERT_EFI_ERROR (Status);\r
439 }\r
440 }\r
441\r
442 //\r
443 // Always Lock flash config registers if about to boot a boot option\r
444 // else lock depending on boot mode.\r
445 //\r
446 if (PreBootPolicy || (BootMode != BOOT_ON_FLASH_UPDATE)) {\r
447 PlatformFlashLockConfig ();\r
448 }\r
449\r
450 //\r
451 // Enable Quark Variable lock if PreBootPolicy.\r
452 //\r
453 if (PreBootPolicy) {\r
454 PlatformVariableLock ();\r
455 }\r
456}\r
457\r
458/**\r
459 Erase and Write to platform flash.\r
460\r
461 Routine accesses one flash block at a time, each access consists\r
462 of an erase followed by a write of FLASH_BLOCK_SIZE. One or both\r
463 of DoErase & DoWrite params must be TRUE.\r
464\r
465 Limitations:-\r
466 CpuWriteAddress must be aligned to FLASH_BLOCK_SIZE.\r
467 DataSize must be a multiple of FLASH_BLOCK_SIZE.\r
468\r
469 @param Smst If != NULL then InSmm and use to locate\r
470 SpiProtocol.\r
471 @param CpuWriteAddress Address in CPU memory map of flash region.\r
472 @param Data The buffer containing the data to be written.\r
473 @param DataSize Amount of data to write.\r
474 @param DoErase Earse each block.\r
475 @param DoWrite Write to each block.\r
476\r
477 @retval EFI_SUCCESS Operation successful.\r
478 @retval EFI_NOT_READY Required resources not setup.\r
479 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
480 @retval Others Unexpected error happened.\r
481\r
482**/\r
483EFI_STATUS\r
484EFIAPI\r
485PlatformFlashEraseWrite (\r
486 IN VOID *Smst,\r
487 IN UINTN CpuWriteAddress,\r
488 IN UINT8 *Data,\r
489 IN UINTN DataSize,\r
490 IN BOOLEAN DoErase,\r
491 IN BOOLEAN DoWrite\r
492 )\r
493{\r
494 EFI_STATUS Status;\r
495 UINT64 CpuBaseAddress;\r
496 SPI_INIT_INFO *SpiInfo;\r
497 UINT8 *WriteBuf;\r
498 UINTN Index;\r
499 UINTN SpiWriteAddress;\r
500 EFI_SPI_PROTOCOL *SpiProtocol;\r
501\r
502 if (!DoErase && !DoWrite) {\r
503 return EFI_INVALID_PARAMETER;\r
504 }\r
505 if (DoWrite && Data == NULL) {\r
506 return EFI_INVALID_PARAMETER;\r
507 }\r
508 if ((CpuWriteAddress % FLASH_BLOCK_SIZE) != 0) {\r
509 return EFI_INVALID_PARAMETER;\r
510 }\r
511 if ((DataSize % FLASH_BLOCK_SIZE) != 0) {\r
512 return EFI_INVALID_PARAMETER;\r
513 }\r
514 SpiProtocol = LocateSpiProtocol ((EFI_SMM_SYSTEM_TABLE2 *)Smst);\r
515 if (SpiProtocol == NULL) {\r
516 return EFI_NOT_READY;\r
517 }\r
518\r
519 //\r
520 // Find info to allow usage of SpiProtocol->Execute.\r
521 //\r
522 Status = SpiProtocol->Info (\r
523 SpiProtocol,\r
524 &SpiInfo\r
525 );\r
526 if (EFI_ERROR(Status)) {\r
527 return Status;\r
528 }\r
529 ASSERT (SpiInfo->InitTable != NULL);\r
530 ASSERT (SpiInfo->EraseOpcodeIndex < SPI_NUM_OPCODE);\r
531 ASSERT (SpiInfo->ProgramOpcodeIndex < SPI_NUM_OPCODE);\r
532\r
533 CpuBaseAddress = PcdGet32 (PcdFlashAreaBaseAddress) - (UINT32)SpiInfo->InitTable->BiosStartOffset;\r
534 ASSERT(CpuBaseAddress >= (SIZE_4GB - SIZE_8MB));\r
535 if (CpuWriteAddress < CpuBaseAddress) {\r
536 return (EFI_INVALID_PARAMETER);\r
537 }\r
538\r
539 SpiWriteAddress = CpuWriteAddress - ((UINTN) CpuBaseAddress);\r
540 WriteBuf = Data;\r
541 DEBUG (\r
542 (EFI_D_INFO, "PlatformFlashWrite:SpiWriteAddress=%08x EraseIndex=%d WriteIndex=%d\n",\r
543 SpiWriteAddress,\r
544 (UINTN) SpiInfo->EraseOpcodeIndex,\r
545 (UINTN) SpiInfo->ProgramOpcodeIndex\r
546 ));\r
547 for (Index =0; Index < DataSize / FLASH_BLOCK_SIZE; Index++) {\r
548 if (DoErase) {\r
549 DEBUG (\r
550 (EFI_D_INFO, "PlatformFlashWrite:Erase[%04x] SpiWriteAddress=%08x\n",\r
551 Index,\r
552 SpiWriteAddress\r
553 ));\r
554 Status = SpiProtocol->Execute (\r
555 SpiProtocol,\r
556 SpiInfo->EraseOpcodeIndex,// OpcodeIndex\r
557 0, // PrefixOpcodeIndex\r
558 FALSE, // DataCycle\r
559 TRUE, // Atomic\r
560 FALSE, // ShiftOut\r
561 SpiWriteAddress, // Address\r
562 0, // Data Number\r
563 NULL,\r
564 EnumSpiRegionAll // SPI_REGION_TYPE\r
565 );\r
566 if (EFI_ERROR(Status)) {\r
567 return Status;\r
568 }\r
569 }\r
570\r
571 if (DoWrite) {\r
572 DEBUG (\r
573 (EFI_D_INFO, "PlatformFlashWrite:Write[%04x] SpiWriteAddress=%08x\n",\r
574 Index,\r
575 SpiWriteAddress\r
576 ));\r
577 Status = SpiProtocol->Execute (\r
578 SpiProtocol,\r
579 SpiInfo->ProgramOpcodeIndex, // OpcodeIndex\r
580 0, // PrefixOpcodeIndex\r
581 TRUE, // DataCycle\r
582 TRUE, // Atomic\r
583 TRUE, // ShiftOut\r
584 SpiWriteAddress, // Address\r
585 FLASH_BLOCK_SIZE, // Data Number\r
586 WriteBuf,\r
587 EnumSpiRegionAll\r
588 );\r
589 if (EFI_ERROR(Status)) {\r
590 return Status;\r
591 }\r
592 WriteBuf+=FLASH_BLOCK_SIZE;\r
593 }\r
594 SpiWriteAddress+=FLASH_BLOCK_SIZE;\r
595 }\r
596 return EFI_SUCCESS;\r
597}\r
598\r
599/** Check if System booted with recovery Boot Stage1 image.\r
600\r
601 @retval TRUE If system booted with recovery Boot Stage1 image.\r
602 @retval FALSE If system booted with normal stage1 image.\r
603\r
604**/\r
605BOOLEAN\r
606EFIAPI\r
607PlatformIsBootWithRecoveryStage1 (\r
608 VOID\r
609 )\r
610{\r
611 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
612 return FALSE;\r
613}\r
614\r
615/**\r
616 Set the direction of Pcal9555 IO Expander GPIO pin.\r
617\r
618 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
619 @param GpioNum Gpio direction to configure - values 0-7 for Port0\r
620 and 8-15 for Port1.\r
621 @param CfgAsInput If TRUE set pin direction as input else set as output.\r
622\r
623**/\r
624VOID\r
625EFIAPI\r
626PlatformPcal9555GpioSetDir (\r
627 IN CONST UINT32 Pcal9555SlaveAddr,\r
628 IN CONST UINT32 GpioNum,\r
629 IN CONST BOOLEAN CfgAsInput\r
630 )\r
631{\r
632 Pcal9555SetPortRegBit (\r
633 Pcal9555SlaveAddr,\r
634 GpioNum,\r
635 PCAL9555_REG_CFG_PORT0,\r
636 CfgAsInput\r
637 );\r
638}\r
639\r
640/**\r
641 Set the level of Pcal9555 IO Expander GPIO high or low.\r
642\r
643 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
644 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
645 for Port1.\r
646 @param HighLevel If TRUE set pin high else set pin low.\r
647\r
648**/\r
649VOID\r
650EFIAPI\r
651PlatformPcal9555GpioSetLevel (\r
652 IN CONST UINT32 Pcal9555SlaveAddr,\r
653 IN CONST UINT32 GpioNum,\r
654 IN CONST BOOLEAN HighLevel\r
655 )\r
656{\r
657 Pcal9555SetPortRegBit (\r
658 Pcal9555SlaveAddr,\r
659 GpioNum,\r
660 PCAL9555_REG_OUT_PORT0,\r
661 HighLevel\r
662 );\r
663}\r
664\r
665/**\r
666\r
667 Enable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
668\r
669 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
670 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
671 for Port1.\r
672\r
673**/\r
674VOID\r
675EFIAPI\r
676PlatformPcal9555GpioEnablePull (\r
677 IN CONST UINT32 Pcal9555SlaveAddr,\r
678 IN CONST UINT32 GpioNum\r
679 )\r
680{\r
681 Pcal9555SetPortRegBit (\r
682 Pcal9555SlaveAddr,\r
683 GpioNum,\r
684 PCAL9555_REG_PULL_EN_PORT0,\r
685 TRUE\r
686 );\r
687}\r
688\r
689/**\r
690\r
691 Disable pull-up/pull-down resistors of Pcal9555 GPIOs.\r
692\r
693 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
694 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
695 for Port1.\r
696\r
697**/\r
698VOID\r
699EFIAPI\r
700PlatformPcal9555GpioDisablePull (\r
701 IN CONST UINT32 Pcal9555SlaveAddr,\r
702 IN CONST UINT32 GpioNum\r
703 )\r
704{\r
705 Pcal9555SetPortRegBit (\r
706 Pcal9555SlaveAddr,\r
707 GpioNum,\r
708 PCAL9555_REG_PULL_EN_PORT0,\r
709 FALSE\r
710 );\r
711}\r
712\r
713/**\r
714\r
715 Get state of Pcal9555 GPIOs.\r
716\r
717 @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.\r
718 @param GpioNum Gpio to change values 0-7 for Port0 and 8-15\r
719 for Port1.\r
720\r
721 @retval TRUE GPIO pin is high\r
722 @retval FALSE GPIO pin is low\r
723**/\r
724BOOLEAN\r
725EFIAPI\r
726PlatformPcal9555GpioGetState (\r
727 IN CONST UINT32 Pcal9555SlaveAddr,\r
728 IN CONST UINT32 GpioNum\r
729 )\r
730{\r
731 return Pcal9555GetPortRegBit (Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_IN_PORT0);\r
732}\r