1 /** @file
2 *
3 * Copyright (c) 2015, Hisilicon Limited. All rights reserved.
4 * Copyright (c) 2015, Linaro Limited. All rights reserved.
5 *
6 * This program and the accompanying materials
7 * are licensed and made available under the terms and conditions of the BSD License
8 * which accompanies this distribution. The full text of the license may be found at
9 * http://opensource.org/licenses/bsd-license.php
10 *
11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 *
14 **/
15
16
17
18 #include <PiDxe.h>
19 #include <Library/DebugLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/ArmLib.h>
22 #include <Library/BaseLib.h>
23 #include <Library/I2CLib.h>
24 #include <Library/TimerLib.h>
25
26 #include <Library/PlatformSysCtrlLib.h>
27
28 #include "I2CLibInternal.h"
29 #include "I2CHw.h"
30
I2C_Delay(UINT32 ulCount)31 VOID I2C_Delay(UINT32 ulCount)
32 {
33 MicroSecondDelay(ulCount);
34 return;
35 }
36
37
38 EFI_STATUS
39 EFIAPI
I2C_Disable(UINT32 Socket,UINT8 Port)40 I2C_Disable(UINT32 Socket,UINT8 Port)
41 {
42 UINT32 ulTimeCnt = I2C_READ_TIMEOUT;
43 I2C0_STATUS_U I2cStatusReg;
44 I2C0_ENABLE_U I2cEnableReg;
45 I2C0_ENABLE_STATUS_U I2cEnableStatusReg;
46
47 UINTN Base = GetI2cBase(Socket, Port);
48
49 I2C_REG_READ((Base + I2C_STATUS_OFFSET), I2cStatusReg.Val32);
50
51 while (I2cStatusReg.bits.activity)
52 {
53 I2C_Delay(10000);
54
55 ulTimeCnt--;
56 I2C_REG_READ(Base + I2C_STATUS_OFFSET, I2cStatusReg.Val32);
57 if (0 == ulTimeCnt)
58 {
59 return EFI_DEVICE_ERROR;
60 }
61 }
62
63
64 I2C_REG_READ(Base + I2C_ENABLE_OFFSET, I2cEnableReg.Val32);
65 I2cEnableReg.bits.enable = 0;
66 I2C_REG_WRITE(Base + I2C_ENABLE_OFFSET,I2cEnableReg.Val32);
67
68 I2C_REG_READ(Base + I2C_ENABLE_OFFSET,I2cEnableStatusReg.Val32);
69 if (0 == I2cEnableStatusReg.bits.ic_en)
70 {
71 return EFI_SUCCESS;
72 }
73 else
74 {
75 return EFI_DEVICE_ERROR;
76 }
77 }
78
79
80 EFI_STATUS
81 EFIAPI
I2C_Enable(UINT32 Socket,UINT8 Port)82 I2C_Enable(UINT32 Socket,UINT8 Port)
83 {
84 I2C0_ENABLE_U I2cEnableReg;
85 I2C0_ENABLE_STATUS_U I2cEnableStatusReg;
86
87 UINTN Base = GetI2cBase(Socket, Port);
88
89
90 I2C_REG_READ(Base + I2C_ENABLE_OFFSET, I2cEnableReg.Val32);
91 I2cEnableReg.bits.enable = 1;
92 I2C_REG_WRITE(Base + I2C_ENABLE_OFFSET, I2cEnableReg.Val32);
93
94
95 I2C_REG_READ(Base + I2C_ENABLE_STATUS_OFFSET, I2cEnableStatusReg.Val32);
96 if (1 == I2cEnableStatusReg.bits.ic_en)
97 {
98 return EFI_SUCCESS;
99 }
100 else
101 {
102 return EFI_DEVICE_ERROR;
103 }
104 }
105
I2C_SetTarget(UINT32 Socket,UINT8 Port,UINT32 I2cDeviceAddr)106 void I2C_SetTarget(UINT32 Socket,UINT8 Port,UINT32 I2cDeviceAddr)
107 {
108 I2C0_TAR_U I2cTargetReg;
109 UINTN Base = GetI2cBase(Socket, Port);
110
111
112 I2C_REG_READ(Base + I2C_TAR_OFFSET, I2cTargetReg.Val32);
113 I2cTargetReg.bits.ic_tar = I2cDeviceAddr;
114 I2C_REG_WRITE(Base + I2C_TAR_OFFSET, I2cTargetReg.Val32);
115
116 return;
117 }
118
119
120 EFI_STATUS
121 EFIAPI
I2CInit(UINT32 Socket,UINT32 Port,SPEED_MODE SpeedMode)122 I2CInit(UINT32 Socket, UINT32 Port, SPEED_MODE SpeedMode)
123 {
124 I2C0_CON_U I2cControlReg;
125 I2C0_SS_SCL_HCNT_U I2cStandardSpeedSclHighCount;
126 I2C0_SS_SCL_LCNT_U I2cStandardSpeedSclLowCount;
127 I2C0_RX_TL_U I2cRxFifoReg;
128 I2C0_TX_TL_U I2cTxFifoReg;
129 I2C0_INTR_MASK_U I2cIntrMask;
130 EFI_STATUS Status;
131
132 UINTN Base = GetI2cBase(Socket, Port);
133
134 if((Socket >= MAX_SOCKET) || (Port >= I2C_PORT_MAX) || (SpeedMode >= SPEED_MODE_MAX)){
135 return EFI_INVALID_PARAMETER;
136 }
137
138
139 Status = I2C_Disable(Socket,Port);
140 if(EFI_ERROR(Status))
141 {
142 return EFI_DEVICE_ERROR;
143 }
144
145
146 I2C_REG_READ(Base + I2C_CON_OFFSET, I2cControlReg.Val32);
147 I2cControlReg.bits.master = 1;
148 I2cControlReg.bits.spedd = 0x1;
149 I2cControlReg.bits.restart_en = 1;
150 I2cControlReg.bits.slave_disable = 1;
151 I2C_REG_WRITE(Base + I2C_CON_OFFSET,I2cControlReg.Val32);
152
153
154 if(Normal == SpeedMode)
155 {
156 I2C_REG_READ(Base + I2C_SS_SCL_HCNT_OFFSET,I2cStandardSpeedSclHighCount.Val32);
157 I2cStandardSpeedSclHighCount.bits.ic_ss_scl_hcnt = I2C_SS_SCLHCNT;
158 I2C_REG_WRITE(Base + I2C_SS_SCL_HCNT_OFFSET, I2cStandardSpeedSclHighCount.Val32);
159 I2C_REG_READ(Base + I2C_SS_SCL_LCNT_OFFSET, I2cStandardSpeedSclLowCount.Val32);
160 I2cStandardSpeedSclLowCount.bits.ic_ss_scl_lcnt = I2C_SS_SCLLCNT;
161 I2C_REG_WRITE(Base + I2C_SS_SCL_LCNT_OFFSET, I2cStandardSpeedSclLowCount.Val32);
162 }
163 else
164 {
165 I2C_REG_READ(Base + I2C_FS_SCL_HCNT_OFFSET,I2cStandardSpeedSclHighCount.Val32);
166 I2cStandardSpeedSclHighCount.bits.ic_ss_scl_hcnt = I2C_SS_SCLHCNT;
167 I2C_REG_WRITE(Base + I2C_FS_SCL_HCNT_OFFSET, I2cStandardSpeedSclHighCount.Val32);
168 I2C_REG_READ(Base + I2C_FS_SCL_LCNT_OFFSET, I2cStandardSpeedSclLowCount.Val32);
169 I2cStandardSpeedSclLowCount.bits.ic_ss_scl_lcnt = I2C_SS_SCLLCNT;
170 I2C_REG_WRITE(Base + I2C_FS_SCL_LCNT_OFFSET, I2cStandardSpeedSclLowCount.Val32);
171 }
172
173
174 I2C_REG_READ(Base + I2C_RX_TL_OFFSET, I2cRxFifoReg.Val32);
175 I2cRxFifoReg.bits.rx_tl = I2C_TXRX_THRESHOLD;
176 I2C_REG_WRITE(Base + I2C_RX_TL_OFFSET, I2cRxFifoReg.Val32);
177 I2C_REG_READ(Base + I2C_TX_TL_OFFSET,I2cTxFifoReg.Val32);
178 I2cTxFifoReg.bits.tx_tl = I2C_TXRX_THRESHOLD;
179 I2C_REG_WRITE(Base + I2C_TX_TL_OFFSET, I2cTxFifoReg.Val32);
180
181
182 I2C_REG_READ(Base + I2C_INTR_MASK_OFFSET, I2cIntrMask.Val32);
183 I2cIntrMask.Val32 = 0x0;
184 I2C_REG_WRITE(Base + I2C_INTR_MASK_OFFSET, I2cIntrMask.Val32);
185
186
187 Status = I2C_Enable(Socket,Port);
188 if(EFI_ERROR(Status))
189 {
190 return EFI_DEVICE_ERROR;
191 }
192
193 return I2cLibRuntimeSetup (Socket, Port);
194 }
195
196 EFI_STATUS
197 EFIAPI
I2CSdaConfig(UINT32 Socket,UINT32 Port)198 I2CSdaConfig(UINT32 Socket, UINT32 Port)
199 {
200
201 UINTN Base = GetI2cBase(Socket, Port);
202
203 if((Socket >= MAX_SOCKET) || (Port >= I2C_PORT_MAX)){
204 return EFI_INVALID_PARAMETER;
205 }
206
207 I2C_REG_WRITE(Base + I2C_SDA_HOLD, 0x14);
208
209 return EFI_SUCCESS;
210 }
211
212
213
I2C_GetTxStatus(UINT32 Socket,UINT8 Port)214 UINT32 I2C_GetTxStatus(UINT32 Socket,UINT8 Port)
215 {
216 I2C0_TXFLR_U ulFifo;
217 UINTN Base = GetI2cBase(Socket, Port);
218
219 I2C_REG_READ(Base + I2C_TXFLR_OFFSET, ulFifo.Val32);
220 return ulFifo.bits.txflr;
221 }
222
223 UINT32
I2C_GetRxStatus(UINT32 Socket,UINT8 Port)224 I2C_GetRxStatus(UINT32 Socket,UINT8 Port)
225 {
226 I2C0_RXFLR_U ulFifo;
227 UINTN Base = GetI2cBase(Socket, Port);
228
229 I2C_REG_READ(Base + I2C_RXFLR_OFFSET, ulFifo.Val32);
230 return ulFifo.bits.rxflr;
231 }
232
233 EFI_STATUS
234 EFIAPI
WriteBeforeRead(I2C_DEVICE * I2cInfo,UINT32 ulLength,UINT8 * pBuf)235 WriteBeforeRead(I2C_DEVICE *I2cInfo, UINT32 ulLength, UINT8 *pBuf)
236 {
237 UINT32 ulFifo;
238 UINT32 ulCnt;
239 UINT32 ulTimes = 0;
240
241 UINTN Base = GetI2cBase(I2cInfo->Socket, I2cInfo->Port);
242
243
244 I2C_SetTarget(I2cInfo->Socket,I2cInfo->Port,I2cInfo->SlaveDeviceAddress);
245
246 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
247 while(0 != ulFifo)
248 {
249 I2C_Delay(2);
250 if(++ulTimes > I2C_READ_TIMEOUT)
251 {
252 return EFI_TIMEOUT;
253 }
254 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
255 }
256
257 for(ulCnt = 0; ulCnt < ulLength; ulCnt++)
258 {
259 ulTimes = 0;
260 while(ulFifo > I2C_TXRX_THRESHOLD)
261 {
262 I2C_Delay(2);
263 if(++ulTimes > I2C_READ_TIMEOUT)
264 {
265 return EFI_TIMEOUT;
266 }
267 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
268 }
269
270 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, *pBuf++);
271 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
272 }
273
274 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
275 ulTimes = 0;
276 while(0 != ulFifo)
277 {
278 I2C_Delay(2);
279
280 if(++ulTimes > I2C_READ_TIMEOUT)
281 {
282 return EFI_TIMEOUT;
283 }
284 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
285 }
286
287 return EFI_SUCCESS;
288 }
289
290
291 EFI_STATUS
292 EFIAPI
I2CWrite(I2C_DEVICE * I2cInfo,UINT16 InfoOffset,UINT32 ulLength,UINT8 * pBuf)293 I2CWrite(I2C_DEVICE *I2cInfo, UINT16 InfoOffset, UINT32 ulLength, UINT8 *pBuf)
294 {
295 UINT32 ulFifo;
296 UINT32 ulTimes = 0;
297 UINT32 Idx;
298 UINTN Base;
299
300
301 if(I2cInfo->Port >= I2C_PORT_MAX)
302 {
303 return EFI_INVALID_PARAMETER;
304 }
305
306 Base = GetI2cBase(I2cInfo->Socket, I2cInfo->Port);
307
308 (VOID)I2C_Enable(I2cInfo->Socket, I2cInfo->Port);
309
310 I2C_SetTarget(I2cInfo->Socket,I2cInfo->Port,I2cInfo->SlaveDeviceAddress);
311
312 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
313 while(0 != ulFifo)
314 {
315 I2C_Delay(2);
316 if(++ulTimes > I2C_READ_TIMEOUT)
317 {
318 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
319 return EFI_TIMEOUT;
320 }
321 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
322 }
323
324
325 if(I2cInfo->DeviceType)
326 {
327 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (InfoOffset >> 8) & 0xff);
328 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, InfoOffset & 0xff);
329 }
330 else
331 {
332 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, InfoOffset & 0xff);
333 }
334
335 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
336 ulTimes = 0;
337 while(0 != ulFifo)
338 {
339 I2C_Delay(2);
340 if(++ulTimes > I2C_READ_TIMEOUT)
341 {
342 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
343 return EFI_TIMEOUT;
344 }
345 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
346 }
347
348 for(Idx = 0; Idx < ulLength; Idx++)
349 {
350 ulTimes = 0;
351 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
352 while(ulFifo > I2C_TXRX_THRESHOLD)
353 {
354 I2C_Delay(2);
355 if(++ulTimes > I2C_READ_TIMEOUT)
356 {
357 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
358 return EFI_TIMEOUT;
359 }
360 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
361 }
362
363 if (Idx < ulLength - 1) {
364 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (*pBuf++));
365 } else {
366 //Send command stop bit for the last transfer
367 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (*pBuf++) | I2C_CMD_STOP_BIT);
368 }
369 }
370
371 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
372 ulTimes = 0;
373 while(0 != ulFifo)
374 {
375 I2C_Delay(2);
376
377 if(++ulTimes > I2C_READ_TIMEOUT)
378 {
379 DEBUG ((EFI_D_ERROR, "I2C Write try to finished,time out!\n"));
380 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
381 return EFI_TIMEOUT;
382 }
383 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
384 }
385 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
386
387 return EFI_SUCCESS;
388 }
389
390 EFI_STATUS
391 EFIAPI
I2CRead(I2C_DEVICE * I2cInfo,UINT16 InfoOffset,UINT32 ulRxLen,UINT8 * pBuf)392 I2CRead(I2C_DEVICE *I2cInfo, UINT16 InfoOffset,UINT32 ulRxLen,UINT8 *pBuf)
393 {
394 UINT32 ulFifo;
395 UINT32 ulTimes = 0;
396 UINT8 I2CWAddr[2];
397 EFI_STATUS Status;
398 UINT32 Idx = 0;
399 UINTN Base;
400
401
402 if(I2cInfo->Port >= I2C_PORT_MAX)
403 {
404 return EFI_INVALID_PARAMETER;
405 }
406
407 (VOID)I2C_Enable(I2cInfo->Socket, I2cInfo->Port);
408 Base = GetI2cBase(I2cInfo->Socket, I2cInfo->Port);
409 if(I2cInfo->DeviceType)
410 {
411 I2CWAddr[0] = (InfoOffset >> 8) & 0xff;
412 I2CWAddr[1] = (InfoOffset & 0xff);
413 Status = WriteBeforeRead(I2cInfo, 2,I2CWAddr);
414 if(EFI_ERROR(Status))
415 {
416 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
417 return EFI_ABORTED;
418 }
419 }
420 else
421 {
422 I2CWAddr[0] = (InfoOffset & 0xff);
423 Status = WriteBeforeRead(I2cInfo, 1,I2CWAddr);
424 if(EFI_ERROR(Status))
425 {
426 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
427 return EFI_ABORTED;
428 }
429 }
430
431 I2C_SetTarget(I2cInfo->Socket,I2cInfo->Port,I2cInfo->SlaveDeviceAddress);
432
433 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
434 while(0 != ulFifo)
435 {
436 I2C_Delay(2);
437
438 while(++ulTimes > I2C_READ_TIMEOUT)
439 {
440 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
441 return EFI_TIMEOUT;
442 }
443 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
444 }
445
446 while (ulRxLen > 0) {
447 if (ulRxLen > 1) {
448 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, I2C_READ_SIGNAL);
449 } else {
450 //Send command stop bit for the last transfer
451 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, I2C_READ_SIGNAL | I2C_CMD_STOP_BIT);
452 }
453
454 ulTimes = 0;
455 do {
456 I2C_Delay(2);
457
458 while(++ulTimes > I2C_READ_TIMEOUT) {
459 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
460 return EFI_TIMEOUT;
461 }
462 ulFifo = I2C_GetRxStatus(I2cInfo->Socket,I2cInfo->Port);
463 }while(0 == ulFifo);
464
465 I2C_REG_READ(Base + I2C_DATA_CMD_OFFSET, pBuf[Idx++]);
466
467 ulRxLen --;
468 }
469 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
470
471 return EFI_SUCCESS;
472 }
473
474 EFI_STATUS
475 EFIAPI
I2CReadMultiByte(I2C_DEVICE * I2cInfo,UINT32 InfoOffset,UINT32 ulRxLen,UINT8 * pBuf)476 I2CReadMultiByte(I2C_DEVICE *I2cInfo, UINT32 InfoOffset,UINT32 ulRxLen,UINT8 *pBuf)
477 {
478 UINT32 ulCnt;
479 UINT16 usTotalLen = 0;
480 UINT32 ulFifo;
481 UINT32 ulTimes = 0;
482 UINT8 I2CWAddr[4];
483 EFI_STATUS Status;
484 UINT32 BytesLeft;
485 UINT32 Idx = 0;
486 UINTN Base;
487
488
489 if(I2cInfo->Port >= I2C_PORT_MAX)
490 {
491 return EFI_INVALID_PARAMETER;
492 }
493
494 (VOID)I2C_Enable(I2cInfo->Socket, I2cInfo->Port);
495 Base = GetI2cBase(I2cInfo->Socket, I2cInfo->Port);
496 if(I2cInfo->DeviceType == DEVICE_TYPE_E2PROM)
497 {
498 I2CWAddr[0] = (InfoOffset >> 8) & 0xff;
499 I2CWAddr[1] = (InfoOffset & 0xff);
500 Status = WriteBeforeRead(I2cInfo, 2,I2CWAddr);
501 if(EFI_ERROR(Status))
502 {
503 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
504 return EFI_ABORTED;
505 }
506 }
507
508 else if(I2cInfo->DeviceType == DEVICE_TYPE_CPLD_3BYTE_OPERANDS)
509 {
510 I2CWAddr[0] = (InfoOffset >> 16) & 0xff;
511 I2CWAddr[1] = (InfoOffset >> 8) & 0xff;
512 I2CWAddr[2] = (InfoOffset & 0xff);
513 Status = WriteBeforeRead(I2cInfo, 3,I2CWAddr);
514 if(EFI_ERROR(Status))
515 {
516 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
517 return EFI_ABORTED;
518 }
519 }
520
521 else if(I2cInfo->DeviceType == DEVICE_TYPE_CPLD_4BYTE_OPERANDS)
522 {
523 I2CWAddr[0] = (InfoOffset >> 24) & 0xff;
524 I2CWAddr[1] = (InfoOffset >> 16) & 0xff;
525 I2CWAddr[2] = (InfoOffset >> 8) & 0xff;
526 I2CWAddr[3] = (InfoOffset & 0xff);
527 Status = WriteBeforeRead(I2cInfo, 4,I2CWAddr);
528 if(EFI_ERROR(Status))
529 {
530 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
531 return EFI_ABORTED;
532 }
533 }
534
535 else
536 {
537 I2CWAddr[0] = (InfoOffset & 0xff);
538 Status = WriteBeforeRead(I2cInfo, 1,I2CWAddr);
539 if(EFI_ERROR(Status))
540 {
541 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
542 return EFI_ABORTED;
543 }
544 }
545
546
547 I2C_SetTarget(I2cInfo->Socket,I2cInfo->Port,I2cInfo->SlaveDeviceAddress);
548 usTotalLen = ulRxLen;
549 BytesLeft = usTotalLen;
550
551 for(ulCnt = 0; ulCnt < BytesLeft; ulCnt++) {
552 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, I2C_READ_SIGNAL);
553 }
554
555
556 for(ulCnt = 0; ulCnt < BytesLeft; ulCnt++) {
557 ulTimes = 0;
558 do {
559 I2C_Delay(2);
560
561 while(++ulTimes > I2C_READ_TIMEOUT) {
562 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
563 return EFI_TIMEOUT;
564 }
565 ulFifo = I2C_GetRxStatus(I2cInfo->Socket,I2cInfo->Port);
566 }while(0 == ulFifo);
567
568 I2C_REG_READ(Base + I2C_DATA_CMD_OFFSET, pBuf[Idx++]);
569 }
570 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
571
572 return EFI_SUCCESS;
573 }
574
575 EFI_STATUS
576 EFIAPI
I2CWriteMultiByte(I2C_DEVICE * I2cInfo,UINT32 InfoOffset,UINT32 ulLength,UINT8 * pBuf)577 I2CWriteMultiByte(I2C_DEVICE *I2cInfo, UINT32 InfoOffset, UINT32 ulLength, UINT8 *pBuf)
578 {
579 UINT32 ulFifo;
580 UINT32 ulTimes = 0;
581 UINT32 Idx;
582 UINTN Base;
583
584
585 if(I2cInfo->Port >= I2C_PORT_MAX)
586 {
587 return EFI_INVALID_PARAMETER;
588 }
589
590 Base = GetI2cBase(I2cInfo->Socket, I2cInfo->Port);
591
592 (VOID)I2C_Enable(I2cInfo->Socket, I2cInfo->Port);
593
594 I2C_SetTarget(I2cInfo->Socket,I2cInfo->Port,I2cInfo->SlaveDeviceAddress);
595
596 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
597 while(0 != ulFifo)
598 {
599 I2C_Delay(2);
600 if(++ulTimes > I2C_READ_TIMEOUT)
601 {
602 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
603 return EFI_TIMEOUT;
604 }
605 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
606 }
607
608
609 if(I2cInfo->DeviceType == DEVICE_TYPE_CPLD_3BYTE_OPERANDS)
610 {
611 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (InfoOffset >> 16) & 0xff);
612 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (InfoOffset >> 8) & 0xff);
613 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, InfoOffset & 0xff);
614 }
615
616 else if(I2cInfo->DeviceType == DEVICE_TYPE_CPLD_4BYTE_OPERANDS)
617 {
618 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (InfoOffset >> 24) & 0xff);
619 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (InfoOffset >> 16) & 0xff);
620 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (InfoOffset >> 8) & 0xff);
621 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, InfoOffset & 0xff);
622 }
623
624 else
625 {
626
627 }
628
629 ulTimes = 0;
630 for(Idx = 0; Idx < ulLength; Idx++)
631 {
632
633 I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, *pBuf++);
634
635 }
636
637 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
638 ulTimes = 0;
639 while(0 != ulFifo)
640 {
641 I2C_Delay(2);
642
643 if(++ulTimes > I2C_READ_TIMEOUT)
644 {
645 DEBUG ((EFI_D_ERROR, "I2C Write try to finished,time out!\n"));
646 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
647 return EFI_TIMEOUT;
648 }
649 ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
650 }
651 (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
652
653 return EFI_SUCCESS;
654 }
655
656