diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2017-09-04 18:05:13 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-09-08 22:08:53 -0700 |
commit | b39f6780a15920e4c2c5d1b25c4d99d57c8544ff (patch) | |
tree | 10faf160f105c9a5648fba1d0a2dcfafda5c1c68 /chip | |
parent | 1623f192e865709a1071bde37819963dd5d0e17c (diff) | |
download | chrome-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')
-rw-r--r-- | chip/it83xx/i2c.c | 27 |
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 */ |