summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Brandmeyer <jbrandmeyer@chromium.org>2018-09-25 10:13:34 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-09-25 15:48:08 -0700
commit8649d800a9dd9c23de199029b2db25827f687925 (patch)
treec4176eeaebb6b0d761895858e8d6b03b21a4526b
parentde0629592aef6e9d77821bb89b62d2a733675e2b (diff)
downloadchrome-ec-stabilize-11101.B.tar.gz
i2c: Do not attempt bus clear on split xfer failurestabilize-11101.B
If a split transaction fails after its first half, the chip driver has a few options for dealing with the bus state. It can either release the bus by sending a stop bit, or it can leave the bus busy and use a repeated start for the next transaction. ChromeEC does not support multimaster I2C, so either condition is acceptable. TEST=boot a bip with a battery disconnected. Observe that the bus reset error path is not taken when attempting to read the battery identification registers. BRANCH=none BUG=b:116603165, b:112862656 Change-Id: Ieb29233b0701edc2135707247b15a637e9d4d25b Signed-off-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1243707 Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Scott Collyer <scollyer@chromium.org>
-rw-r--r--common/i2c_master.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/common/i2c_master.c b/common/i2c_master.c
index fb967afd0f..b4b403f877 100644
--- a/common/i2c_master.c
+++ b/common/i2c_master.c
@@ -319,12 +319,8 @@ int i2c_read_string(int port, int slave_addr, int offset, uint8_t *data,
*/
rv = i2c_xfer_unlocked(port, slave_addr, &reg, 1, &block_length, 1,
I2C_XFER_START);
- if (rv) {
- /* Dummy read for the stop bit */
- i2c_xfer_unlocked(port, slave_addr, 0, 0, &reg, 1,
- I2C_XFER_STOP);
+ if (rv)
goto exit;
- }
if (len && block_length > (len - 1))
block_length = len - 1;
@@ -351,7 +347,7 @@ int i2c_read_block(int port, int slave_addr, int offset, uint8_t *data,
int i2c_write_block(int port, int slave_addr, int offset, const uint8_t *data,
int len)
{
- int rv0, rv1;
+ int rv;
uint8_t reg_address = offset;
/*
@@ -361,14 +357,15 @@ int i2c_write_block(int port, int slave_addr, int offset, const uint8_t *data,
* order to have a better chance at sending out the stop bit.
*/
i2c_lock(port, 1);
- rv0 = i2c_xfer_unlocked(port, slave_addr, &reg_address, 1, NULL, 0,
- I2C_XFER_START);
- rv1 = i2c_xfer_unlocked(port, slave_addr, data, len, NULL, 0,
- I2C_XFER_STOP);
+ rv = i2c_xfer_unlocked(port, slave_addr, &reg_address, 1, NULL, 0,
+ I2C_XFER_START);
+ if (!rv) {
+ rv = i2c_xfer_unlocked(port, slave_addr, data, len, NULL, 0,
+ I2C_XFER_STOP);
+ }
i2c_lock(port, 0);
- /* Guess that the first error seen is more helpful. */
- return (rv0 != EC_SUCCESS) ? rv0 : rv1;
+ return rv;
}
int get_sda_from_i2c_port(int port, enum gpio_signal *sda)