diff mbox

[Linaro-uefi,07/27] Hisilicon/I2CLib: Extend to support Hi1616

Message ID 1478785950-24197-8-git-send-email-heyi.guo@linaro.org
State Superseded
Headers show

Commit Message

gary guo Nov. 10, 2016, 1:52 p.m. UTC
Hi1616 has 10 I2C ports and the IP of I2C controller is DesignWare v2,
which requires to write I2C_CMD_STOP bit (BIT9) for the last transfer.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Chips/Hisilicon/Include/Library/I2CLib.h |  2 +-
 Chips/Hisilicon/Library/I2CLib/I2CHw.h   |  1 +
 Chips/Hisilicon/Library/I2CLib/I2CLib.c  | 50 +++++++++-----------------------
 3 files changed, 15 insertions(+), 38 deletions(-)
diff mbox

Patch

diff --git a/Chips/Hisilicon/Include/Library/I2CLib.h b/Chips/Hisilicon/Include/Library/I2CLib.h
index c3597f6..36e9f5f 100644
--- a/Chips/Hisilicon/Include/Library/I2CLib.h
+++ b/Chips/Hisilicon/Include/Library/I2CLib.h
@@ -33,7 +33,7 @@  typedef enum {
 }SPEED_MODE;
 
 
-#define    I2C_PORT_MAX            9
+#define    I2C_PORT_MAX            10
 
 
 
diff --git a/Chips/Hisilicon/Library/I2CLib/I2CHw.h b/Chips/Hisilicon/Library/I2CLib/I2CHw.h
index 0937997..aa561e9 100644
--- a/Chips/Hisilicon/Library/I2CLib/I2CHw.h
+++ b/Chips/Hisilicon/Library/I2CLib/I2CHw.h
@@ -26,6 +26,7 @@ 
 #define I2C_TXRX_THRESHOLD           0x7
 #define I2C_SS_SCLHCNT               0x493
 #define I2C_SS_SCLLCNT               0x4fe
+#define I2C_CMD_STOP_BIT             BIT9
 
 #define I2C_REG_WRITE(reg,data) \
      MmioWrite32 ((reg), (data))
diff --git a/Chips/Hisilicon/Library/I2CLib/I2CLib.c b/Chips/Hisilicon/Library/I2CLib/I2CLib.c
index 087a4ba..b5b388d 100644
--- a/Chips/Hisilicon/Library/I2CLib/I2CLib.c
+++ b/Chips/Hisilicon/Library/I2CLib/I2CLib.c
@@ -360,7 +360,12 @@  I2CWrite(I2C_DEVICE *I2cInfo, UINT16 InfoOffset, UINT32 ulLength, UINT8 *pBuf)
             ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
         }
 
-        I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, *pBuf++);
+        if (Idx < ulLength - 1) {
+            I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (*pBuf++));
+        } else {
+            //Send command stop bit for the last transfer
+            I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, (*pBuf++) | I2C_CMD_STOP_BIT);
+        }
     }
 
     ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
@@ -386,13 +391,10 @@  EFI_STATUS
 EFIAPI
 I2CRead(I2C_DEVICE *I2cInfo, UINT16 InfoOffset,UINT32 ulRxLen,UINT8 *pBuf)
 {
-    UINT32 ulCnt;
-    UINT16 usTotalLen = 0;
     UINT32 ulFifo;
     UINT32 ulTimes = 0;
     UINT8  I2CWAddr[2];
     EFI_STATUS  Status;
-    UINT32  BytesLeft;
     UINT32  Idx = 0;
     UINTN Base;
 
@@ -441,42 +443,14 @@  I2CRead(I2C_DEVICE *I2cInfo, UINT16 InfoOffset,UINT32 ulRxLen,UINT8 *pBuf)
         ulFifo = I2C_GetTxStatus(I2cInfo->Socket,I2cInfo->Port);
     }
 
-    usTotalLen = ulRxLen;
-    BytesLeft = usTotalLen;
-
-    while(BytesLeft >= I2C_DRV_ONCE_READ_BYTES_NUM){
-
-
-        for(ulCnt = 0; ulCnt < I2C_DRV_ONCE_READ_BYTES_NUM; ulCnt++) {
+    while (ulRxLen > 0) {
+        if (ulRxLen > 1) {
             I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, I2C_READ_SIGNAL);
+        } else {
+            //Send command stop bit for the last transfer
+            I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, I2C_READ_SIGNAL | I2C_CMD_STOP_BIT);
         }
 
-
-        for(ulCnt = 0; ulCnt < I2C_DRV_ONCE_READ_BYTES_NUM; ulCnt++) {
-            ulTimes = 0;
-            do {
-                I2C_Delay(2);
-
-                while(++ulTimes > I2C_READ_TIMEOUT) {
-                    (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);
-                    return EFI_TIMEOUT;
-                }
-                ulFifo = I2C_GetRxStatus(I2cInfo->Socket,I2cInfo->Port);
-
-            }while(0 == ulFifo);
-
-            I2C_REG_READ(Base + I2C_DATA_CMD_OFFSET, pBuf[Idx++]);
-        }
-        BytesLeft -= I2C_DRV_ONCE_READ_BYTES_NUM;
-    }
-
-
-    for(ulCnt = 0; ulCnt < BytesLeft; ulCnt++) {
-        I2C_REG_WRITE(Base + I2C_DATA_CMD_OFFSET, I2C_READ_SIGNAL);
-    }
-
-
-    for(ulCnt = 0; ulCnt < BytesLeft; ulCnt++) {
         ulTimes = 0;
         do {
             I2C_Delay(2);
@@ -489,6 +463,8 @@  I2CRead(I2C_DEVICE *I2cInfo, UINT16 InfoOffset,UINT32 ulRxLen,UINT8 *pBuf)
         }while(0 == ulFifo);
 
         I2C_REG_READ(Base + I2C_DATA_CMD_OFFSET, pBuf[Idx++]);
+
+        ulRxLen --;
     }
     (VOID)I2C_Disable(I2cInfo->Socket, I2cInfo->Port);