diff options
author | Vic Yang <victoryang@chromium.org> | 2013-09-26 17:39:40 +0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-09-27 04:33:33 +0000 |
commit | 4de56d4a7f2fb9fb459f31a8e8f1616e54852157 (patch) | |
tree | 1b35b453482fe64a0d43a81df0af9a6f7373e413 | |
parent | 09de4c720d790a7243808e82264e8a1bb122a99d (diff) | |
download | chrome-ec-4de56d4a7f2fb9fb459f31a8e8f1616e54852157.tar.gz |
Test interface for detaching fake I2C devices
This provides an interface to detach and re-attach fake I2C devices,
which can be used to test I2C connection failure.
BUG=chrome-os-partner:19235
TEST=Pass sbs_charging test along with the next CL
BRANCH=None
Change-Id: Ibfee79b13d45e62377d894aa28547e77bef2189e
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/170752
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | chip/host/i2c.c | 76 | ||||
-rw-r--r-- | include/test_util.h | 21 |
2 files changed, 97 insertions, 0 deletions
diff --git a/chip/host/i2c.c b/chip/host/i2c.c index 072d4564f8..3f8a8b8241 100644 --- a/chip/host/i2c.c +++ b/chip/host/i2c.c @@ -5,15 +5,83 @@ * Dummy I2C driver for unit test. */ +#include "hooks.h" #include "i2c.h" #include "link_defs.h" #include "test_util.h" +#define MAX_DETACHED_DEV_COUNT 3 + +struct i2c_dev { + int port; + int slave_addr; + int valid; +}; + +static struct i2c_dev detached_devs[MAX_DETACHED_DEV_COUNT]; + +static void detach_init(void) +{ + int i; + for (i = 0; i < MAX_DETACHED_DEV_COUNT; ++i) + detached_devs[i].valid = 0; +} +DECLARE_HOOK(HOOK_INIT, detach_init, HOOK_PRIO_FIRST); + +int test_detach_i2c(int port, int slave_addr) +{ + int i; + + for (i = 0; i < MAX_DETACHED_DEV_COUNT; ++i) + if (detached_devs[i].valid == 0) + break; + + if (i == MAX_DETACHED_DEV_COUNT) + return EC_ERROR_OVERFLOW; + + detached_devs[i].port = port; + detached_devs[i].slave_addr = slave_addr; + detached_devs[i].valid = 1; + + return EC_SUCCESS; +} + +int test_attach_i2c(int port, int slave_addr) +{ + int i; + + for (i = 0; i < MAX_DETACHED_DEV_COUNT; ++i) + if (detached_devs[i].valid && + detached_devs[i].port == port && + detached_devs[i].slave_addr == slave_addr) + break; + + if (i == MAX_DETACHED_DEV_COUNT) + return EC_ERROR_INVAL; + + detached_devs[i].valid = 0; + return EC_SUCCESS; +} + +static int test_check_detached(int port, int slave_addr) +{ + int i; + + for (i = 0; i < MAX_DETACHED_DEV_COUNT; ++i) + if (detached_devs[i].valid && + detached_devs[i].port == port && + detached_devs[i].slave_addr == slave_addr) + return 1; + return 0; +} + int i2c_read16(int port, int slave_addr, int offset, int *data) { const struct test_i2c_read_dev *p; int rv; + if (test_check_detached(port, slave_addr)) + return EC_ERROR_UNKNOWN; for (p = __test_i2c_read16; p < __test_i2c_read16_end; ++p) { rv = p->routine(port, slave_addr, offset, data); if (rv != EC_ERROR_INVAL) @@ -27,6 +95,8 @@ int i2c_write16(int port, int slave_addr, int offset, int data) const struct test_i2c_write_dev *p; int rv; + if (test_check_detached(port, slave_addr)) + return EC_ERROR_UNKNOWN; for (p = __test_i2c_write16; p < __test_i2c_write16_end; ++p) { rv = p->routine(port, slave_addr, offset, data); if (rv != EC_ERROR_INVAL) @@ -40,6 +110,8 @@ int i2c_read8(int port, int slave_addr, int offset, int *data) const struct test_i2c_read_dev *p; int rv; + if (test_check_detached(port, slave_addr)) + return EC_ERROR_UNKNOWN; for (p = __test_i2c_read8; p < __test_i2c_read8_end; ++p) { rv = p->routine(port, slave_addr, offset, data); if (rv != EC_ERROR_INVAL) @@ -53,6 +125,8 @@ int i2c_write8(int port, int slave_addr, int offset, int data) const struct test_i2c_write_dev *p; int rv; + if (test_check_detached(port, slave_addr)) + return EC_ERROR_UNKNOWN; for (p = __test_i2c_write8; p < __test_i2c_write8_end; ++p) { rv = p->routine(port, slave_addr, offset, data); if (rv != EC_ERROR_INVAL) @@ -67,6 +141,8 @@ int i2c_read_string(int port, int slave_addr, int offset, uint8_t *data, const struct test_i2c_read_string_dev *p; int rv; + if (test_check_detached(port, slave_addr)) + return EC_ERROR_UNKNOWN; for (p = __test_i2c_read_string; p < __test_i2c_read_string_end; ++p) { rv = p->routine(port, slave_addr, offset, data, len); if (rv != EC_ERROR_INVAL) diff --git a/include/test_util.h b/include/test_util.h index a05165148e..1dc737b986 100644 --- a/include/test_util.h +++ b/include/test_util.h @@ -218,4 +218,25 @@ struct test_i2c_write_dev { __attribute__((section(".rodata.test_i2c.read_string"))) \ = {routine} +/* + * Detach an I2C device. Once detached, any read/write command regarding the + * specified port and slave address returns error. + * + * @param port The port that the detached device is connected to + * @param slave_addr The address of the detached device + * @return EC_SUCCESS if detached; EC_ERROR_OVERFLOW if too many devices are + * detached. + */ +int test_detach_i2c(int port, int slave_addr); + +/* + * Re-attach an I2C device. + * + * @param port The port that the detached device is connected to + * @param slave_addr The address of the detached device + * @return EC_SUCCESS if re-attached; EC_ERROR_INVAL if the specified device + * is not a detached device. + */ +int test_attach_i2c(int port, int slave_addr); + #endif /* __CROS_EC_TEST_UTIL_H */ |