Home | History | Annotate | Download | only in CirrusLogic5430Dxe
      1 /** @file
      2   I2C Bus implementation upon CirrusLogic.
      3 
      4   Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
      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 #include "CirrusLogic5430.h"
     16 #include "CirrusLogic5430I2c.h"
     17 
     18 #define SEQ_ADDRESS_REGISTER    0x3c4
     19 #define SEQ_DATA_REGISTER       0x3c5
     20 
     21 #define I2C_CONTROL             0x08
     22 #define I2CDAT_IN               7
     23 #define I2CCLK_IN               2
     24 #define I2CDAT_OUT              1
     25 #define I2CCLK_OUT              0
     26 
     27 #define I2C_BUS_SPEED           100  //100kbps
     28 
     29 /**
     30   PCI I/O byte write function.
     31 
     32   @param  PciIo        The pointer to PCI_IO_PROTOCOL.
     33   @param  Address      The bit map of I2C Data or I2C Clock pins.
     34   @param  Data         The date to write.
     35 
     36 **/
     37 VOID
     38 I2cOutb (
     39   EFI_PCI_IO_PROTOCOL    *PciIo,
     40   UINTN                  Address,
     41   UINT8                  Data
     42   )
     43 {
     44   PciIo->Io.Write (
     45              PciIo,
     46              EfiPciIoWidthUint8,
     47              EFI_PCI_IO_PASS_THROUGH_BAR,
     48              Address,
     49              1,
     50              &Data
     51              );
     52 }
     53 /**
     54   PCI I/O byte read function.
     55 
     56   @param  PciIo        The pointer to PCI_IO_PROTOCOL.
     57   @param  Address      The bit map of I2C Data or I2C Clock pins.
     58 
     59   return byte value read from PCI I/O space.
     60 
     61 **/
     62 UINT8
     63 I2cInb (
     64   EFI_PCI_IO_PROTOCOL    *PciIo,
     65   UINTN                  Address
     66   )
     67 {
     68   UINT8 Data;
     69 
     70   PciIo->Io.Read (
     71              PciIo,
     72              EfiPciIoWidthUint8,
     73              EFI_PCI_IO_PASS_THROUGH_BAR,
     74              Address,
     75              1,
     76              &Data
     77              );
     78   return Data;
     79 }
     80 
     81 /**
     82   Read status of I2C Data and I2C Clock Pins.
     83 
     84   @param  PciIo        The pointer to PCI_IO_PROTOCOL.
     85   @param  Blt          The bit map of I2C Data or I2C Clock pins.
     86 
     87   @retval 0            Low on I2C Data or I2C Clock Pin.
     88   @retval 1            High on I2C Data or I2C Clock Pin.
     89 
     90 **/
     91 UINT8
     92 I2cPinRead (
     93   EFI_PCI_IO_PROTOCOL    *PciIo,
     94   UINT8                  Bit
     95   )
     96 {
     97   I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
     98   return (UINT8) ((I2cInb (PciIo, SEQ_DATA_REGISTER) >> Bit ) & 0xfe);
     99 }
    100 
    101 
    102 /**
    103   Set/Clear I2C Data and I2C Clock Pins.
    104 
    105   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    106   @param  Blt                The bit map to controller I2C Data or I2C Clock pins.
    107   @param  Value              1 or 0 stands for Set or Clear I2C Data and I2C Clock Pins.
    108 
    109 **/
    110 VOID
    111 I2cPinWrite (
    112   EFI_PCI_IO_PROTOCOL    *PciIo,
    113   UINT8                  Bit,
    114   UINT8                  Value
    115   )
    116 {
    117   UINT8        Byte;
    118   I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
    119   Byte = (UINT8) (I2cInb (PciIo, SEQ_DATA_REGISTER) & (UINT8) ~(1 << Bit)) ;
    120   Byte = (UINT8) (Byte | ((Value & 0x01) << Bit));
    121   I2cOutb (PciIo, SEQ_DATA_REGISTER, (UINT8) (Byte | 0x40));
    122   return;
    123 }
    124 
    125 /**
    126   Read/write delay acoording to I2C Bus Speed.
    127 
    128 **/
    129 VOID
    130 I2cDelay (
    131   VOID
    132   )
    133 {
    134   MicroSecondDelay (1000 / I2C_BUS_SPEED);
    135 }
    136 
    137 /**
    138   Write a 8-bit data onto I2C Data Pin.
    139 
    140   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    141   @param  Data               The byte data to write.
    142 
    143 **/
    144 VOID
    145 I2cSendByte (
    146   EFI_PCI_IO_PROTOCOL    *PciIo,
    147   UINT8                  Data
    148   )
    149 {
    150   UINTN                  Index;
    151   //
    152   // Send byte data onto I2C Bus
    153   //
    154   for (Index = 0; Index < 8; Index --) {
    155     I2cPinWrite (PciIo, I2CDAT_OUT, (UINT8) (Data >> (7 - Index)));
    156     I2cPinWrite (PciIo, I2CCLK_OUT, 1);
    157     I2cDelay ();
    158     I2cPinWrite (PciIo, I2CCLK_OUT, 0);
    159   }
    160 }
    161 
    162 /**
    163   Read a 8-bit data from I2C Data Pin.
    164 
    165   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    166 
    167   Return the byte data read from I2C Data Pin.
    168 **/
    169 UINT8
    170 I2cReceiveByte (
    171   EFI_PCI_IO_PROTOCOL    *PciIo
    172   )
    173 {
    174   UINT8          Data;
    175   UINTN          Index;
    176 
    177   Data = 0;
    178   //
    179   // Read byte data from I2C Bus
    180   //
    181   for (Index = 0; Index < 8; Index --) {
    182     I2cPinWrite (PciIo, I2CCLK_OUT, 1);
    183     I2cDelay ();
    184     Data = (UINT8) (Data << 1);
    185     Data = (UINT8) (Data | I2cPinRead (PciIo, I2CDAT_IN));
    186     I2cPinWrite (PciIo, I2CCLK_OUT, 0);
    187   }
    188 
    189   return Data;
    190 }
    191 
    192 /**
    193   Receive an ACK signal from I2C Bus.
    194 
    195   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    196 
    197 **/
    198 BOOLEAN
    199 I2cWaitAck (
    200   EFI_PCI_IO_PROTOCOL    *PciIo
    201   )
    202 {
    203   //
    204   // Wait for ACK signal
    205   //
    206   I2cPinWrite (PciIo, I2CDAT_OUT, 1);
    207   I2cPinWrite (PciIo, I2CCLK_OUT, 1);
    208   I2cDelay ();
    209   if (I2cPinRead (PciIo, I2CDAT_IN) == 0) {
    210     I2cPinWrite (PciIo, I2CDAT_OUT, 1);
    211     return TRUE;
    212   } else {
    213     return FALSE;
    214   }
    215 }
    216 
    217 /**
    218   Send an ACK signal onto I2C Bus.
    219 
    220   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    221 
    222 **/
    223 VOID
    224 I2cSendAck (
    225   EFI_PCI_IO_PROTOCOL    *PciIo
    226   )
    227 {
    228   I2cPinWrite (PciIo, I2CCLK_OUT, 1);
    229   I2cPinWrite (PciIo, I2CDAT_OUT, 1);
    230   I2cPinWrite (PciIo, I2CDAT_OUT, 0);
    231   I2cPinWrite (PciIo, I2CCLK_OUT, 0);
    232 }
    233 
    234 /**
    235   Start a I2C transfer on I2C Bus.
    236 
    237   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    238 
    239 **/
    240 VOID
    241 I2cStart (
    242   EFI_PCI_IO_PROTOCOL    *PciIo
    243   )
    244 {
    245   //
    246   // Init CLK and DAT pins
    247   //
    248   I2cPinWrite (PciIo, I2CCLK_OUT, 1);
    249   I2cPinWrite (PciIo, I2CDAT_OUT, 1);
    250   //
    251   // Start a I2C transfer, set SDA low from high, when SCL is high
    252   //
    253   I2cPinWrite (PciIo, I2CDAT_OUT, 0);
    254   I2cPinWrite (PciIo, I2CCLK_OUT, 0);
    255 }
    256 
    257 /**
    258   Stop a I2C transfer on I2C Bus.
    259 
    260   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    261 
    262 **/
    263 VOID
    264 I2cStop (
    265   EFI_PCI_IO_PROTOCOL    *PciIo
    266   )
    267 {
    268   //
    269   // Stop a I2C transfer, set SDA high from low, when SCL is high
    270   //
    271   I2cPinWrite (PciIo, I2CDAT_OUT, 0);
    272   I2cPinWrite (PciIo, I2CCLK_OUT, 1);
    273   I2cPinWrite (PciIo, I2CDAT_OUT, 1);
    274 }
    275 
    276 /**
    277   Read one byte data on I2C Bus.
    278 
    279   Read one byte data from the slave device connectet to I2C Bus.
    280   If Data is NULL, then ASSERT().
    281 
    282   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    283   @param  DeviceAddress      Slave device's address.
    284   @param  RegisterAddress    The register address on slave device.
    285   @param  Data               The pointer to returned data if EFI_SUCCESS returned.
    286 
    287   @retval EFI_DEVICE_ERROR
    288   @retval EFI_SUCCESS
    289 
    290 **/
    291 EFI_STATUS
    292 EFIAPI
    293 I2cReadByte (
    294   EFI_PCI_IO_PROTOCOL    *PciIo,
    295   UINT8                  DeviceAddress,
    296   UINT8                  RegisterAddress,
    297   UINT8                  *Data
    298   )
    299 {
    300   ASSERT (Data != NULL);
    301 
    302   //
    303   // Start I2C transfer
    304   //
    305   I2cStart (PciIo);
    306 
    307   //
    308   // Send slave address with enabling write flag
    309   //
    310   I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
    311 
    312   //
    313   // Wait for ACK signal
    314   //
    315   if (I2cWaitAck (PciIo) == FALSE) {
    316     return EFI_DEVICE_ERROR;
    317   }
    318 
    319   //
    320   // Send register address
    321   //
    322   I2cSendByte (PciIo, RegisterAddress);
    323 
    324   //
    325   // Wait for ACK signal
    326   //
    327   if (I2cWaitAck (PciIo) == FALSE) {
    328     return EFI_DEVICE_ERROR;
    329   }
    330 
    331   //
    332   // Send slave address with enabling read flag
    333   //
    334   I2cSendByte (PciIo, (UINT8) (DeviceAddress | 0x01));
    335 
    336   //
    337   // Wait for ACK signal
    338   //
    339   if (I2cWaitAck (PciIo) == FALSE) {
    340     return EFI_DEVICE_ERROR;
    341   }
    342 
    343   //
    344   // Read byte data from I2C Bus
    345   //
    346   *Data = I2cReceiveByte (PciIo);
    347 
    348   //
    349   // Send ACK signal onto I2C Bus
    350   //
    351   I2cSendAck (PciIo);
    352 
    353   //
    354   // Stop a I2C transfer
    355   //
    356   I2cStop (PciIo);
    357 
    358   return EFI_SUCCESS;
    359 }
    360 
    361 /**
    362   Write one byte data onto I2C Bus.
    363 
    364   Write one byte data to the slave device connectet to I2C Bus.
    365   If Data is NULL, then ASSERT().
    366 
    367   @param  PciIo              The pointer to PCI_IO_PROTOCOL.
    368   @param  DeviceAddress      Slave device's address.
    369   @param  RegisterAddress    The register address on slave device.
    370   @param  Data               The pointer to write data.
    371 
    372   @retval EFI_DEVICE_ERROR
    373   @retval EFI_SUCCESS
    374 
    375 **/
    376 EFI_STATUS
    377 EFIAPI
    378 I2cWriteByte (
    379   EFI_PCI_IO_PROTOCOL    *PciIo,
    380   UINT8                  DeviceAddress,
    381   UINT8                  RegisterAddress,
    382   UINT8                  *Data
    383   )
    384 {
    385   ASSERT (Data != NULL);
    386 
    387   I2cStart (PciIo);
    388   //
    389   // Send slave address with enabling write flag
    390   //
    391   I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
    392 
    393   //
    394   // Wait for ACK signal
    395   //
    396   if (I2cWaitAck (PciIo) == FALSE) {
    397     return EFI_DEVICE_ERROR;
    398   }
    399 
    400   //
    401   // Send register address
    402   //
    403   I2cSendByte (PciIo, RegisterAddress);
    404 
    405   //
    406   // Wait for ACK signal
    407   //
    408   if (I2cWaitAck (PciIo) == FALSE) {
    409     return EFI_DEVICE_ERROR;
    410   }
    411 
    412   //
    413   // Send byte data onto I2C Bus
    414   //
    415   I2cSendByte (PciIo, *Data);
    416 
    417   //
    418   // Wait for ACK signal
    419   //
    420   if (I2cWaitAck (PciIo) == FALSE) {
    421     return EFI_DEVICE_ERROR;
    422   }
    423 
    424   //
    425   // Stop a I2C transfer
    426   //
    427   I2cStop (PciIo);
    428 
    429   return EFI_SUCCESS;
    430 }
    431 
    432 
    433 
    434