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