diff options
author | Alexandru M Stan <amstan@chromium.org> | 2014-09-26 14:05:17 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-09-27 04:57:49 +0000 |
commit | c83db9a1199cff57d0286e4e6416a99de335b9ee (patch) | |
tree | 824304db5461d1f4fce1700173f32d7cc79f7f2c | |
parent | 458d39c1a88013227148db86dfc9a9edf67e9453 (diff) | |
download | chrome-ec-c83db9a1199cff57d0286e4e6416a99de335b9ee.tar.gz |
stm32f0/i2c: Return error if we see a NACK
i2cdetect -q was broken on the AP. The way it works is by sending a 0 length
write request and checking for NACK. The stm32f0 driver had to be fixed to
actually return non-success if there was a NACK. i2cdetect -r worked so far
because it relied on a 1-length read and we indirectly detected NACKs by the
lack of data.
The error catching also had to be moved(in both drivers) before the success
returns, because it is possible to transmit something successfully(buffer got
emptied) without getting an ACK. We want this to be an error.
BUG=None
BRANCH=None
TEST=veyron: i2cdetect -y -r 20 0x09 0x0b should display -- on the 0x0a spot
since there's no device there. i2cdetect -y -{r,q} 20 should display the same
thing.
Change-Id: Id6cadb798e4d972dea089f15742e5b30888a038b
Signed-off-by: Alexandru M Stan <amstan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/220185
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | chip/stm32/i2c-stm32f0.c | 9 | ||||
-rw-r--r-- | chip/stm32/i2c-stm32l.c | 8 |
2 files changed, 9 insertions, 8 deletions
diff --git a/chip/stm32/i2c-stm32f0.c b/chip/stm32/i2c-stm32f0.c index 47393fc209..01e3269263 100644 --- a/chip/stm32/i2c-stm32f0.c +++ b/chip/stm32/i2c-stm32f0.c @@ -50,14 +50,15 @@ static int wait_isr(int port, int mask) while (get_time().val < timeout) { int isr = STM32_I2C_ISR(port); + /* Check for errors */ + if (isr & (STM32_I2C_ISR_ARLO | STM32_I2C_ISR_BERR | + STM32_I2C_ISR_NACK)) + return EC_ERROR_UNKNOWN; + /* Check for desired mask */ if ((isr & mask) == mask) return EC_SUCCESS; - /* Check for errors */ - if (isr & (STM32_I2C_ISR_ARLO | STM32_I2C_ISR_BERR)) - return EC_ERROR_UNKNOWN; - /* I2C is slow, so let other things run while we wait */ usleep(100); } diff --git a/chip/stm32/i2c-stm32l.c b/chip/stm32/i2c-stm32l.c index e274207cb8..8b37eb3ef9 100644 --- a/chip/stm32/i2c-stm32l.c +++ b/chip/stm32/i2c-stm32l.c @@ -73,10 +73,6 @@ static int wait_sr1(int port, int mask) while (get_time().val < timeout) { int sr1 = STM32_I2C_SR1(port); - /* Check for desired mask */ - if ((sr1 & mask) == mask) - return EC_SUCCESS; - /* Check for errors */ if (sr1 & (STM32_I2C_SR1_ARLO | STM32_I2C_SR1_BERR | STM32_I2C_SR1_AF)) { @@ -84,6 +80,10 @@ static int wait_sr1(int port, int mask) return EC_ERROR_UNKNOWN; } + /* Check for desired mask */ + if ((sr1 & mask) == mask) + return EC_SUCCESS; + /* I2C is slow, so let other things run while we wait */ usleep(100); } |