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