+++ /dev/null
-/** @file\r
- I2C Bus implementation upon CirrusLogic.\r
-\r
- Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "CirrusLogic5430.h"\r
-#include "CirrusLogic5430I2c.h"\r
-\r
-#define SEQ_ADDRESS_REGISTER 0x3c4\r
-#define SEQ_DATA_REGISTER 0x3c5\r
-\r
-#define I2C_CONTROL 0x08\r
-#define I2CDAT_IN 7\r
-#define I2CCLK_IN 2\r
-#define I2CDAT_OUT 1\r
-#define I2CCLK_OUT 0\r
-\r
-#define I2C_BUS_SPEED 100 //100kbps\r
-\r
-/**\r
- PCI I/O byte write function.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
- @param Address The bit map of I2C Data or I2C Clock pins.\r
- @param Data The date to write.\r
-\r
-**/\r
-VOID\r
-I2cOutb (\r
- EFI_PCI_IO_PROTOCOL *PciIo,\r
- UINTN Address,\r
- UINT8 Data\r
- )\r
-{\r
- PciIo->Io.Write (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- Address,\r
- 1,\r
- &Data\r
- );\r
-}\r
-/**\r
- PCI I/O byte read function.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
- @param Address The bit map of I2C Data or I2C Clock pins.\r
-\r
- return byte value read from PCI I/O space.\r
-\r
-**/\r
-UINT8\r
-I2cInb (\r
- EFI_PCI_IO_PROTOCOL *PciIo,\r
- UINTN Address\r
- )\r
-{\r
- UINT8 Data;\r
-\r
- PciIo->Io.Read (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- Address,\r
- 1,\r
- &Data\r
- );\r
- return Data;\r
-}\r
-\r
-/**\r
- Read status of I2C Data and I2C Clock Pins.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
- @param Blt The bit map of I2C Data or I2C Clock pins.\r
-\r
- @retval 0 Low on I2C Data or I2C Clock Pin.\r
- @retval 1 High on I2C Data or I2C Clock Pin.\r
-\r
-**/\r
-UINT8\r
-I2cPinRead (\r
- EFI_PCI_IO_PROTOCOL *PciIo,\r
- UINT8 Bit\r
- )\r
-{\r
- I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);\r
- return (UINT8) ((I2cInb (PciIo, SEQ_DATA_REGISTER) >> Bit ) & 0xfe);\r
-}\r
-\r
-\r
-/**\r
- Set/Clear I2C Data and I2C Clock Pins.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
- @param Blt The bit map to controller I2C Data or I2C Clock pins.\r
- @param Value 1 or 0 stands for Set or Clear I2C Data and I2C Clock Pins.\r
-\r
-**/\r
-VOID\r
-I2cPinWrite (\r
- EFI_PCI_IO_PROTOCOL *PciIo,\r
- UINT8 Bit,\r
- UINT8 Value\r
- )\r
-{\r
- UINT8 Byte;\r
- I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);\r
- Byte = (UINT8) (I2cInb (PciIo, SEQ_DATA_REGISTER) & (UINT8) ~(1 << Bit)) ;\r
- Byte = (UINT8) (Byte | ((Value & 0x01) << Bit));\r
- I2cOutb (PciIo, SEQ_DATA_REGISTER, (UINT8) (Byte | 0x40));\r
- return;\r
-}\r
-\r
-/**\r
- Read/write delay acoording to I2C Bus Speed.\r
-\r
-**/\r
-VOID\r
-I2cDelay (\r
- VOID\r
- )\r
-{\r
- MicroSecondDelay (1000 / I2C_BUS_SPEED);\r
-}\r
-\r
-/**\r
- Write a 8-bit data onto I2C Data Pin.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
- @param Data The byte data to write.\r
-\r
-**/\r
-VOID\r
-I2cSendByte (\r
- EFI_PCI_IO_PROTOCOL *PciIo,\r
- UINT8 Data\r
- )\r
-{\r
- UINTN Index;\r
- //\r
- // Send byte data onto I2C Bus\r
- //\r
- for (Index = 0; Index < 8; Index --) {\r
- I2cPinWrite (PciIo, I2CDAT_OUT, (UINT8) (Data >> (7 - Index)));\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
- I2cDelay ();\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
- }\r
-}\r
-\r
-/**\r
- Read a 8-bit data from I2C Data Pin.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
-\r
- Return the byte data read from I2C Data Pin.\r
-**/\r
-UINT8\r
-I2cReceiveByte (\r
- EFI_PCI_IO_PROTOCOL *PciIo\r
- )\r
-{\r
- UINT8 Data;\r
- UINTN Index;\r
-\r
- Data = 0;\r
- //\r
- // Read byte data from I2C Bus\r
- //\r
- for (Index = 0; Index < 8; Index --) {\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
- I2cDelay ();\r
- Data = (UINT8) (Data << 1);\r
- Data = (UINT8) (Data | I2cPinRead (PciIo, I2CDAT_IN));\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
- }\r
-\r
- return Data;\r
-}\r
-\r
-/**\r
- Receive an ACK signal from I2C Bus.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
-\r
-**/\r
-BOOLEAN\r
-I2cWaitAck (\r
- EFI_PCI_IO_PROTOCOL *PciIo\r
- )\r
-{\r
- //\r
- // Wait for ACK signal\r
- //\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
- I2cDelay ();\r
- if (I2cPinRead (PciIo, I2CDAT_IN) == 0) {\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-/**\r
- Send an ACK signal onto I2C Bus.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
-\r
-**/\r
-VOID\r
-I2cSendAck (\r
- EFI_PCI_IO_PROTOCOL *PciIo\r
- )\r
-{\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 0);\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
-}\r
-\r
-/**\r
- Start a I2C transfer on I2C Bus.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
-\r
-**/\r
-VOID\r
-I2cStart (\r
- EFI_PCI_IO_PROTOCOL *PciIo\r
- )\r
-{\r
- //\r
- // Init CLK and DAT pins\r
- //\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
- //\r
- // Start a I2C transfer, set SDA low from high, when SCL is high\r
- //\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 0);\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
-}\r
-\r
-/**\r
- Stop a I2C transfer on I2C Bus.\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
-\r
-**/\r
-VOID\r
-I2cStop (\r
- EFI_PCI_IO_PROTOCOL *PciIo\r
- )\r
-{\r
- //\r
- // Stop a I2C transfer, set SDA high from low, when SCL is high\r
- //\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 0);\r
- I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
- I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
-}\r
-\r
-/**\r
- Read one byte data on I2C Bus.\r
-\r
- Read one byte data from the slave device connectet to I2C Bus.\r
- If Data is NULL, then ASSERT().\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
- @param DeviceAddress Slave device's address.\r
- @param RegisterAddress The register address on slave device.\r
- @param Data The pointer to returned data if EFI_SUCCESS returned.\r
-\r
- @retval EFI_DEVICE_ERROR\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-I2cReadByte (\r
- EFI_PCI_IO_PROTOCOL *PciIo,\r
- UINT8 DeviceAddress,\r
- UINT8 RegisterAddress,\r
- UINT8 *Data\r
- )\r
-{\r
- ASSERT (Data != NULL);\r
-\r
- //\r
- // Start I2C transfer\r
- //\r
- I2cStart (PciIo);\r
-\r
- //\r
- // Send slave address with enabling write flag\r
- //\r
- I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));\r
-\r
- //\r
- // Wait for ACK signal\r
- //\r
- if (I2cWaitAck (PciIo) == FALSE) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Send register address\r
- //\r
- I2cSendByte (PciIo, RegisterAddress);\r
-\r
- //\r
- // Wait for ACK signal\r
- //\r
- if (I2cWaitAck (PciIo) == FALSE) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Send slave address with enabling read flag\r
- //\r
- I2cSendByte (PciIo, (UINT8) (DeviceAddress | 0x01));\r
-\r
- //\r
- // Wait for ACK signal\r
- //\r
- if (I2cWaitAck (PciIo) == FALSE) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Read byte data from I2C Bus\r
- //\r
- *Data = I2cReceiveByte (PciIo);\r
-\r
- //\r
- // Send ACK signal onto I2C Bus\r
- //\r
- I2cSendAck (PciIo);\r
-\r
- //\r
- // Stop a I2C transfer\r
- //\r
- I2cStop (PciIo);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Write one byte data onto I2C Bus.\r
-\r
- Write one byte data to the slave device connectet to I2C Bus.\r
- If Data is NULL, then ASSERT().\r
-\r
- @param PciIo The pointer to PCI_IO_PROTOCOL.\r
- @param DeviceAddress Slave device's address.\r
- @param RegisterAddress The register address on slave device.\r
- @param Data The pointer to write data.\r
-\r
- @retval EFI_DEVICE_ERROR\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-I2cWriteByte (\r
- EFI_PCI_IO_PROTOCOL *PciIo,\r
- UINT8 DeviceAddress,\r
- UINT8 RegisterAddress,\r
- UINT8 *Data\r
- )\r
-{\r
- ASSERT (Data != NULL);\r
-\r
- I2cStart (PciIo);\r
- //\r
- // Send slave address with enabling write flag\r
- //\r
- I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));\r
-\r
- //\r
- // Wait for ACK signal\r
- //\r
- if (I2cWaitAck (PciIo) == FALSE) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Send register address\r
- //\r
- I2cSendByte (PciIo, RegisterAddress);\r
-\r
- //\r
- // Wait for ACK signal\r
- //\r
- if (I2cWaitAck (PciIo) == FALSE) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Send byte data onto I2C Bus\r
- //\r
- I2cSendByte (PciIo, *Data);\r
-\r
- //\r
- // Wait for ACK signal\r
- //\r
- if (I2cWaitAck (PciIo) == FALSE) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Stop a I2C transfer\r
- //\r
- I2cStop (PciIo);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r