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 31 VOID I2C_Delay(UINT32 ulCount) 32 { 33 MicroSecondDelay(ulCount); 34 return; 35 } 36 37 38 EFI_STATUS 39 EFIAPI 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 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 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 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 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 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 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 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 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 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 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 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