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