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