• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
I2cOutb(EFI_PCI_IO_PROTOCOL * PciIo,UINTN Address,UINT8 Data)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
I2cInb(EFI_PCI_IO_PROTOCOL * PciIo,UINTN Address)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
I2cPinRead(EFI_PCI_IO_PROTOCOL * PciIo,UINT8 Bit)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
I2cPinWrite(EFI_PCI_IO_PROTOCOL * PciIo,UINT8 Bit,UINT8 Value)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
I2cDelay(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
I2cSendByte(EFI_PCI_IO_PROTOCOL * PciIo,UINT8 Data)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
I2cReceiveByte(EFI_PCI_IO_PROTOCOL * PciIo)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
I2cWaitAck(EFI_PCI_IO_PROTOCOL * PciIo)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
I2cSendAck(EFI_PCI_IO_PROTOCOL * PciIo)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
I2cStart(EFI_PCI_IO_PROTOCOL * PciIo)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
I2cStop(EFI_PCI_IO_PROTOCOL * PciIo)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
I2cReadByte(EFI_PCI_IO_PROTOCOL * PciIo,UINT8 DeviceAddress,UINT8 RegisterAddress,UINT8 * Data)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
I2cWriteByte(EFI_PCI_IO_PROTOCOL * PciIo,UINT8 DeviceAddress,UINT8 RegisterAddress,UINT8 * Data)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