summaryrefslogtreecommitdiff
path: root/chip/it83xx/i2c.c
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2017-09-04 18:05:13 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-09-08 22:08:53 -0700
commitb39f6780a15920e4c2c5d1b25c4d99d57c8544ff (patch)
tree10faf160f105c9a5648fba1d0a2dcfafda5c1c68 /chip/it83xx/i2c.c
parent1623f192e865709a1071bde37819963dd5d0e17c (diff)
downloadchrome-ec-b39f6780a15920e4c2c5d1b25c4d99d57c8544ff.tar.gz
it83xx: i2c: fix i2c stop bit
We disable i2c interface immediately after stop bit is set. This might caused bus busy bit of status register unable to clear (bus busy bit will be set at start condition and cleared at stop condition). So the next transaction, we won't get a good state to start. This change also fix incorrect stop bit for write transaction: IT83XX_I2C_CTR(p_ch) = xx BRANCH=none BUG=none TEST=Ensure i2c interface is disabled after i2c stop condition. Change-Id: I5416bfcef3f95357c6771dead6b0611b908f787e Signed-off-by: Dino Li <Dino.Li@ite.com.tw> Reviewed-on: https://chromium-review.googlesource.com/645407 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip/it83xx/i2c.c')
-rw-r--r--chip/it83xx/i2c.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/chip/it83xx/i2c.c b/chip/it83xx/i2c.c
index 146c38294c..f746bd94b4 100644
--- a/chip/it83xx/i2c.c
+++ b/chip/it83xx/i2c.c
@@ -91,6 +91,8 @@ enum enhanced_i2c_ctl {
E_INT_EN = 0x40,
/* 0 : Standard mode , 1 : Receive mode */
E_RX_MODE = 0x80,
+ /* Generate stop condition */
+ E_FINISH = (E_INT_EN | E_MODE_SEL | E_ACK | E_STOP | E_HW_RST),
};
enum i2c_host_status_mask {
@@ -554,13 +556,9 @@ static int enhanced_i2c_tran_write(int p)
(pd->addr + 1), 1);
} else {
if (pd->flags & I2C_XFER_STOP) {
- /* Stop and finish */
- IT83XX_I2C_CTR(p) =
- (E_STOP | E_HW_RST);
- i2c_reset(p, 0);
- /* Disable i2c module */
- IT83XX_I2C_CTR1(p_ch) = 0x00;
- return 0;
+ IT83XX_I2C_CTR(p_ch) = E_FINISH;
+ /* wait for stop bit interrupt*/
+ return 1;
}
/* Direct write with direct read */
pd->i2ccs = I2C_CH_WAIT_NEXT_XFER;
@@ -643,12 +641,9 @@ static int enhanced_i2c_tran_read(int p)
pd->in_size = 0;
if (pd->flags & I2C_XFER_STOP) {
pd->i2ccs = I2C_CH_NORMAL;
- /* Stop and finish */
- IT83XX_I2C_CTR(p_ch) =
- (E_STOP | E_HW_RST);
- /* Disable i2c module */
- IT83XX_I2C_CTR1(p_ch) = 0x00;
- return 0;
+ IT83XX_I2C_CTR(p_ch) = E_FINISH;
+ /* wait for stop bit interrupt*/
+ return 1;
}
/* End the transaction */
pd->i2ccs = I2C_CH_WAIT_READ;
@@ -700,6 +695,12 @@ static int i2c_transaction(int p)
/* i2c read */
else if (pd->in_size)
return enhanced_i2c_tran_read(p);
+ /* transaction done */
+ if (pd->flags & I2C_XFER_STOP) {
+ /* disable i2c interface */
+ IT83XX_I2C_CTR1(p_ch) = 0;
+ IT83XX_I2C_CTR(p_ch) = 0;
+ }
}
}
/* done doing work */