summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorli feng <li1.feng@intel.com>2015-06-02 18:23:20 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-06-04 20:51:07 +0000
commit5b2e673948086bd9a63ffabc96beb98e6409d549 (patch)
tree7ff4250a44004e14a250d7ed66c29d48597e944f
parentf64945d8d12a061bc8ce2ba31077c9fc3cac8947 (diff)
downloadchrome-ec-5b2e673948086bd9a63ffabc96beb98e6409d549.tar.gz
i2c: Retry i2c operation if fails on nack'd(EC_ERROR_BUSY).
Retry count is defined by CONFIG_I2C_NACK_RETRY_COUNT. BUG=chrome-os-partner:37494 TEST=Tested on Cyan, observed retry happens on nack'd i2c. BRANCH=None Signed-off-by: li feng <li1.feng@intel.com> Change-Id: I73ed15a52335de6c5a5b647660bfe431a8238716 Reviewed-on: https://chromium-review.googlesource.com/274689 Reviewed-by: Shawn N <shawnn@chromium.org> Commit-Queue: Divya Jyothi <divya.jyothi@intel.com> Tested-by: Divya Jyothi <divya.jyothi@intel.com>
-rw-r--r--board/cyan/board.h3
-rw-r--r--chip/mec1322/i2c.c23
-rw-r--r--common/i2c.c12
-rw-r--r--include/config.h4
4 files changed, 33 insertions, 9 deletions
diff --git a/board/cyan/board.h b/board/cyan/board.h
index 30805dea96..ddbd24ba9f 100644
--- a/board/cyan/board.h
+++ b/board/cyan/board.h
@@ -79,6 +79,9 @@
#define I2C_PORT_ACCEL MEC1322_I2C1
#define I2C_PORT_THERMAL MEC1322_I2C3
+#undef CONFIG_I2C_NACK_RETRY_COUNT
+#define CONFIG_I2C_NACK_RETRY_COUNT 2
+
/* power signal definitions */
enum power_signal {
X86_ALL_SYS_PWRGD = 0,
diff --git a/chip/mec1322/i2c.c b/chip/mec1322/i2c.c
index df08479ab0..846bcb969e 100644
--- a/chip/mec1322/i2c.c
+++ b/chip/mec1322/i2c.c
@@ -229,6 +229,7 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
int skip = 0;
int bytes_to_read;
uint8_t reg;
+ int ret_done;
if (out_size == 0 && in_size == 0)
return EC_SUCCESS;
@@ -272,11 +273,13 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
}
for (i = 0; i < out_size; ++i) {
- if (wait_byte_done(controller))
+ ret_done = wait_byte_done(controller);
+ if (ret_done)
goto err_chip_i2c_xfer;
MEC1322_I2C_DATA(controller) = out[i];
}
- if (wait_byte_done(controller))
+ ret_done = wait_byte_done(controller);
+ if (ret_done)
goto err_chip_i2c_xfer;
/*
@@ -320,12 +323,14 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
bytes_to_read = send_stop ? in_size - 2 : in_size;
for (i = 0; i < bytes_to_read; ++i) {
- if (wait_byte_done(controller))
+ ret_done = wait_byte_done(controller);
+ if (ret_done)
goto err_chip_i2c_xfer;
push_in_buf(&in, MEC1322_I2C_DATA(controller), skip);
skip = 0;
}
- if (wait_byte_done(controller))
+ ret_done = wait_byte_done(controller);
+ if (ret_done)
goto err_chip_i2c_xfer;
if (send_stop) {
@@ -335,7 +340,8 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
*/
MEC1322_I2C_CTRL(controller) = CTRL_ESO | CTRL_ENI;
push_in_buf(&in, MEC1322_I2C_DATA(controller), skip);
- if (wait_byte_done(controller))
+ ret_done = wait_byte_done(controller);
+ if (ret_done)
goto err_chip_i2c_xfer;
/* Send STOP */
@@ -362,7 +368,12 @@ err_chip_i2c_xfer:
/* Send STOP and return error */
MEC1322_I2C_CTRL(controller) = CTRL_PIN | CTRL_ESO |
CTRL_STO | CTRL_ACK;
- return EC_ERROR_UNKNOWN;
+ if (ret_done == STS_LRB)
+ return EC_ERROR_BUSY;
+ else if (ret_done == EC_ERROR_TIMEOUT)
+ return EC_ERROR_TIMEOUT;
+ else
+ return EC_ERROR_UNKNOWN;
}
int i2c_raw_get_scl(int port)
diff --git a/common/i2c.c b/common/i2c.c
index 189420c102..3975bf1927 100644
--- a/common/i2c.c
+++ b/common/i2c.c
@@ -36,8 +36,16 @@ static struct mutex port_mutex[I2C_CONTROLLER_COUNT];
int i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
uint8_t *in, int in_size, int flags)
{
- return chip_i2c_xfer(port, slave_addr, out, out_size, in,
- in_size, flags);
+ int i;
+ int ret = EC_SUCCESS;
+
+ for (i = 0; i <= CONFIG_I2C_NACK_RETRY_COUNT; i++) {
+ ret = chip_i2c_xfer(port, slave_addr, out, out_size, in,
+ in_size, flags);
+ if (ret != EC_ERROR_BUSY)
+ break;
+ }
+ return ret;
}
void i2c_lock(int port, int lock)
diff --git a/include/config.h b/include/config.h
index b670d748ad..b867a440ab 100644
--- a/include/config.h
+++ b/include/config.h
@@ -805,6 +805,8 @@
#undef CONFIG_I2C_PASSTHROUGH
#undef CONFIG_I2C_PASSTHRU_RESTRICTED
+/* Defines I2C operation retry count when slave nack'd(EC_ERROR_BUSY) */
+#define CONFIG_I2C_NACK_RETRY_COUNT 0
/*
* I2C SCL gating.
*
@@ -1381,7 +1383,7 @@
/* Compile chip support for the USB device controller */
#undef CONFIG_USB
-/* USB device buffers and descriptors in dedicated RAM */
+/* USB device buffers and descriptors */
#undef CONFIG_USB_RAM_ACCESS_SIZE
#undef CONFIG_USB_RAM_ACCESS_TYPE
#undef CONFIG_USB_RAM_BASE