2 I2C Bus Libary implementation upon CirrusLogic.
4 Copyright (c) 2008, Intel Corporation
5 All rights reserved. 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
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.
17 #include <Library/DxeI2cLib.h>
18 #include <Library/TimerLib.h>
19 #include <Library/DebugLib.h>
21 #define SEQ_ADDRESS_REGISTER 0x3c4
22 #define SEQ_DATA_REGISTER 0x3c5
24 #define I2C_CONTROL 0x08
30 #define I2C_BUS_SPEED 100 //100kbps
33 PCI I/O byte write function.
35 @param PciIo The pointer to PCI_IO_PROTOCOL.
36 @param Address The bit map of I2C Data or I2C Clock pins.
37 @param Data The date to write.
43 EFI_PCI_IO_PROTOCOL
*PciIo
,
51 EFI_PCI_IO_PASS_THROUGH_BAR
,
58 PCI I/O byte read function.
60 @param PciIo The pointer to PCI_IO_PROTOCOL.
61 @param Address The bit map of I2C Data or I2C Clock pins.
63 return byte value read from PCI I/O space.
69 EFI_PCI_IO_PROTOCOL
*PciIo
,
78 EFI_PCI_IO_PASS_THROUGH_BAR
,
87 Read status of I2C Data and I2C Clock Pins.
89 @param PciIo The pointer to PCI_IO_PROTOCOL.
90 @param Blt The bit map of I2C Data or I2C Clock pins.
92 @retval 0 Low on I2C Data or I2C Clock Pin.
93 @retval 1 High on I2C Data or I2C Clock Pin.
99 EFI_PCI_IO_PROTOCOL
*PciIo
,
103 outb (PciIo
, SEQ_ADDRESS_REGISTER
, I2C_CONTROL
);
104 return (UINT8
) ((inb (PciIo
, SEQ_DATA_REGISTER
) >> Bit
) & 0xfe);
109 Set/Clear I2C Data and I2C Clock Pins.
111 @param PciIo The pointer to PCI_IO_PROTOCOL.
112 @param Blt The bit map to controller I2C Data or I2C Clock pins.
113 @param Value 1 or 0 stands for Set or Clear I2C Data and I2C Clock Pins.
119 EFI_PCI_IO_PROTOCOL
*PciIo
,
125 outb (PciIo
, SEQ_ADDRESS_REGISTER
, I2C_CONTROL
);
126 Byte
= (UINT8
) (inb (PciIo
, SEQ_DATA_REGISTER
) & (UINT8
) ~(1 << Bit
)) ;
127 Byte
= (UINT8
) (Byte
| ((Value
& 0x01) << Bit
));
128 outb (PciIo
, SEQ_DATA_REGISTER
, (UINT8
) (Byte
| 0x40));
133 Read/write delay acoording to I2C Bus Speed.
142 MicroSecondDelay (1000 / I2C_BUS_SPEED
);
146 Write a 8-bit data onto I2C Data Pin.
148 @param PciIo The pointer to PCI_IO_PROTOCOL.
149 @param Data The byte data to write.
155 EFI_PCI_IO_PROTOCOL
*PciIo
,
161 // Send byte data onto I2C Bus
163 for (Index
= 0; Index
< 8; Index
--) {
164 I2cPinWrite (PciIo
, I2CDAT_OUT
, (UINT8
) (Data
>> (7 - Index
)));
165 I2cPinWrite (PciIo
, I2CCLK_OUT
, 1);
167 I2cPinWrite (PciIo
, I2CCLK_OUT
, 0);
172 Read a 8-bit data from I2C Data Pin.
174 @param PciIo The pointer to PCI_IO_PROTOCOL.
176 Return the byte data read from I2C Data Pin.
181 EFI_PCI_IO_PROTOCOL
*PciIo
189 // Read byte data from I2C Bus
191 for (Index
= 0; Index
< 8; Index
--) {
192 I2cPinWrite (PciIo
, I2CCLK_OUT
, 1);
194 Data
= (UINT8
) (Data
<< 1);
195 Data
= (UINT8
) (Data
| I2cPinRead (PciIo
, I2CDAT_IN
));
196 I2cPinWrite (PciIo
, I2CCLK_OUT
, 0);
203 Receive an ACK signal from I2C Bus.
205 @param PciIo The pointer to PCI_IO_PROTOCOL.
211 EFI_PCI_IO_PROTOCOL
*PciIo
215 // Wait for ACK signal
217 I2cPinWrite (PciIo
, I2CDAT_OUT
, 1);
218 I2cPinWrite (PciIo
, I2CCLK_OUT
, 1);
220 if (I2cPinRead (PciIo
, I2CDAT_IN
) == 0) {
221 I2cPinWrite (PciIo
, I2CDAT_OUT
, 1);
229 Send an ACK signal onto I2C Bus.
231 @param PciIo The pointer to PCI_IO_PROTOCOL.
237 EFI_PCI_IO_PROTOCOL
*PciIo
240 I2cPinWrite (PciIo
, I2CCLK_OUT
, 1);
241 I2cPinWrite (PciIo
, I2CDAT_OUT
, 1);
242 I2cPinWrite (PciIo
, I2CDAT_OUT
, 0);
243 I2cPinWrite (PciIo
, I2CCLK_OUT
, 0);
247 Start a I2C transfer on I2C Bus.
249 @param PciIo The pointer to PCI_IO_PROTOCOL.
255 EFI_PCI_IO_PROTOCOL
*PciIo
259 // Init CLK and DAT pins
261 I2cPinWrite (PciIo
, I2CCLK_OUT
, 1);
262 I2cPinWrite (PciIo
, I2CDAT_OUT
, 1);
264 // Start a I2C transfer, set SDA low from high, when SCL is high
266 I2cPinWrite (PciIo
, I2CDAT_OUT
, 0);
267 I2cPinWrite (PciIo
, I2CCLK_OUT
, 0);
271 Stop a I2C transfer on I2C Bus.
273 @param PciIo The pointer to PCI_IO_PROTOCOL.
279 EFI_PCI_IO_PROTOCOL
*PciIo
283 // Stop a I2C transfer, set SDA high from low, when SCL is high
285 I2cPinWrite (PciIo
, I2CDAT_OUT
, 0);
286 I2cPinWrite (PciIo
, I2CCLK_OUT
, 1);
287 I2cPinWrite (PciIo
, I2CDAT_OUT
, 1);
291 Read one byte data on I2C Bus.
293 Read one byte data from the slave device connectet to I2C Bus.
294 If Data is NULL, then ASSERT().
296 @param PciIo The pointer to PCI_IO_PROTOCOL.
297 @param DeviceAddress Slave device's address.
298 @param RegisterAddress The register address on slave device.
299 @param Data The pointer to returned data if EFI_SUCCESS returned.
301 @retval EFI_DEVICE_ERROR
308 EFI_PCI_IO_PROTOCOL
*PciIo
,
310 UINT8 RegisterAddress
,
314 ASSERT (Data
!= NULL
);
317 // Start I2C transfer
322 // Send slave address with enabling write flag
324 I2cSendByte (PciIo
, (UINT8
) (DeviceAddress
& 0xfe));
327 // Wait for ACK signal
329 if (I2cWaitAck (PciIo
) == FALSE
) {
330 return EFI_DEVICE_ERROR
;
334 // Send register address
336 I2cSendByte (PciIo
, RegisterAddress
);
339 // Wait for ACK signal
341 if (I2cWaitAck (PciIo
) == FALSE
) {
342 return EFI_DEVICE_ERROR
;
346 // Send slave address with enabling read flag
348 I2cSendByte (PciIo
, (UINT8
) (DeviceAddress
| 0x01));
351 // Wait for ACK signal
353 if (I2cWaitAck (PciIo
) == FALSE
) {
354 return EFI_DEVICE_ERROR
;
358 // Read byte data from I2C Bus
360 *Data
= I2cReceiveByte (PciIo
);
363 // Send ACK signal onto I2C Bus
368 // Stop a I2C transfer
376 Write one byte data onto I2C Bus.
378 Write one byte data to the slave device connectet to I2C Bus.
379 If Data is NULL, then ASSERT().
381 @param PciIo The pointer to PCI_IO_PROTOCOL.
382 @param DeviceAddress Slave device's address.
383 @param RegisterAddress The register address on slave device.
384 @param Data The pointer to write data.
386 @retval EFI_DEVICE_ERROR
393 EFI_PCI_IO_PROTOCOL
*PciIo
,
395 UINT8 RegisterAddress
,
399 ASSERT (Data
!= NULL
);
403 // Send slave address with enabling write flag
405 I2cSendByte (PciIo
, (UINT8
) (DeviceAddress
& 0xfe));
408 // Wait for ACK signal
410 if (I2cWaitAck (PciIo
) == FALSE
) {
411 return EFI_DEVICE_ERROR
;
415 // Send register address
417 I2cSendByte (PciIo
, RegisterAddress
);
420 // Wait for ACK signal
422 if (I2cWaitAck (PciIo
) == FALSE
) {
423 return EFI_DEVICE_ERROR
;
427 // Send byte data onto I2C Bus
429 I2cSendByte (PciIo
, *Data
);
432 // Wait for ACK signal
434 if (I2cWaitAck (PciIo
) == FALSE
) {
435 return EFI_DEVICE_ERROR
;
439 // Stop a I2C transfer