summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-02-28 12:39:43 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-03-01 02:38:30 +0000
commita35bfd69e9a749fbaa152937dd91a6ed407a9005 (patch)
tree3256b6a6e6ca08e730ce73961df0a597768ef6eb
parent832a0c7988eff6a70fbb685577b7b15b36e23f4f (diff)
downloadchrome-ec-a35bfd69e9a749fbaa152937dd91a6ed407a9005.tar.gz
Add arbitrary-length read support to i2cxfer
Previously, it could only read 8 or 16 bit values BUG=chrome-os-partner:26191 BRANCH=rambi TEST=manual Counted string for battery manufacturer name: > i2cxfer rlen 0 0x16 0x20 16 Data: 0653696d706c6fe1e1e1e1e1e1e1e1e1 Read lifetime data block 1 (also tests 16-bit writes) > i2cxfer w16 0 0x16 0 0x60 > i2cxfer rlen 0 0x16 0x23 32 Data: 20d2d2d2d2948700000d0a0a060a000000020000000000000000000000000000 Read lifetime data block 2 > i2cxfer w16 0 0x16 0 0x61 > i2cxfer rlen 0 0x16 0x23 27 Data: 1b0000000000010200010c02000201000100000300002008082009 8 and 16 bit reads still work > i2cxfer r 0 0x16 0x23 0x1b [27] > i2cxfer r16 0 0x16 0x23 0x001b [27] Change-Id: Ibba5aced60c0b2de04c3f86cf5fd2ab3db1b6308 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/188379 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--common/i2c.c123
1 files changed, 55 insertions, 68 deletions
diff --git a/common/i2c.c b/common/i2c.c
index 995d7cb7cb..f5ac9ff7f8 100644
--- a/common/i2c.c
+++ b/common/i2c.c
@@ -396,95 +396,82 @@ DECLARE_CONSOLE_COMMAND(i2cscan, command_scan,
"Scan I2C ports for devices",
NULL);
-
static int command_i2cxfer(int argc, char **argv)
{
- int rw = 0;
- int port, slave_addr, offset;
- int value = 0;
+ int port, slave_addr;
+ uint8_t offset;
+ int v = 0;
+ uint8_t data[32];
char *e;
int rv = 0;
- if (argc < 5) {
- ccputs("Usage: i2cxfer r/r16/w/w16 port addr offset [value]\n");
- return EC_ERROR_UNKNOWN;
- }
-
- if (strcasecmp(argv[1], "r") == 0) {
- rw = 0;
- } else if (strcasecmp(argv[1], "r16") == 0) {
- rw = 1;
- } else if (strcasecmp(argv[1], "w") == 0) {
- rw = 2;
- } else if (strcasecmp(argv[1], "w16") == 0) {
- rw = 3;
- } else {
- ccputs("Invalid rw mode : r / w / r16 / w16\n");
- return EC_ERROR_INVAL;
- }
+ if (argc < 5)
+ return EC_ERROR_PARAM_COUNT;
port = strtoi(argv[2], &e, 0);
- if (*e) {
- ccputs("Invalid port\n");
- return EC_ERROR_INVAL;
- }
+ if (*e)
+ return EC_ERROR_PARAM2;
slave_addr = strtoi(argv[3], &e, 0);
- if (*e) {
- ccputs("Invalid slave_addr\n");
- return EC_ERROR_INVAL;
- }
+ if (*e)
+ return EC_ERROR_PARAM3;
offset = strtoi(argv[4], &e, 0);
- if (*e) {
- ccputs("Invalid addr\n");
- return EC_ERROR_INVAL;
- }
+ if (*e)
+ return EC_ERROR_PARAM4;
- if (rw > 1) {
- if (argc < 6) {
- ccputs("No write value\n");
- return EC_ERROR_INVAL;
- }
- value = strtoi(argv[5], &e, 0);
- if (*e) {
- ccputs("Invalid write value\n");
- return EC_ERROR_INVAL;
- }
+ if (argc >= 5) {
+ v = strtoi(argv[5], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM5;
}
+ if (strcasecmp(argv[1], "r") == 0) {
+ /* 8-bit read */
+ rv = i2c_read8(port, slave_addr, offset, &v);
+ if (!rv)
+ ccprintf("0x%02x [%d]\n", v);
- switch (rw) {
- case 0:
- rv = i2c_read8(port, slave_addr, offset, &value);
- break;
- case 1:
- rv = i2c_read16(port, slave_addr, offset, &value);
- break;
- case 2:
- rv = i2c_write8(port, slave_addr, offset, value);
- break;
- case 3:
- rv = i2c_write16(port, slave_addr, offset, value);
- break;
- }
+ } else if (strcasecmp(argv[1], "r16") == 0) {
+ /* 16-bit read */
+ rv = i2c_read16(port, slave_addr, offset, &v);
+ if (!rv)
+ ccprintf("0x%04x [%d]\n", v);
+ } else if (strcasecmp(argv[1], "rlen") == 0) {
+ /* Arbitrary length read; param5 = len */
+ if (argc < 6 || v < 0 || v > sizeof(data))
+ return EC_ERROR_PARAM5;
- if (rv) {
- ccprintf("i2c command failed\n", rv);
- return rv;
- }
+ i2c_lock(port, 1);
+ rv = i2c_xfer(port, slave_addr,
+ &offset, 1, data, v, I2C_XFER_SINGLE);
+ i2c_lock(port, 0);
- if (rw == 0)
- ccprintf("0x%02x [%d]\n", value);
- else if (rw == 1)
- ccprintf("0x%04x [%d]\n", value);
+ if (!rv)
+ ccprintf("Data: %.*h\n", v, data);
- ccputs("ok\n");
+ } else if (strcasecmp(argv[1], "w") == 0) {
+ /* 8-bit write */
+ if (argc < 6)
+ return EC_ERROR_PARAM5;
- return EC_SUCCESS;
+ rv = i2c_write8(port, slave_addr, offset, v);
+
+ } else if (strcasecmp(argv[1], "w16") == 0) {
+ /* 16-bit write */
+ if (argc < 6)
+ return EC_ERROR_PARAM5;
+
+ rv = i2c_write16(port, slave_addr, offset, v);
+
+ } else {
+ return EC_ERROR_PARAM1;
+ }
+
+ return rv;
}
DECLARE_CONSOLE_COMMAND(i2cxfer, command_i2cxfer,
- "r/r16/w/w16 port addr offset [value]",
+ "r/r16/rlen/w/w16 port addr offset [value | len]",
"Read write I2C",
NULL);