summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru M Stan <amstan@chromium.org>2014-09-26 14:05:17 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-09-27 04:57:49 +0000
commitc83db9a1199cff57d0286e4e6416a99de335b9ee (patch)
tree824304db5461d1f4fce1700173f32d7cc79f7f2c
parent458d39c1a88013227148db86dfc9a9edf67e9453 (diff)
downloadchrome-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.c9
-rw-r--r--chip/stm32/i2c-stm32l.c8
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);
}