diff options
author | Nicolas Boichat <drinkcat@google.com> | 2016-05-31 11:31:02 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-06-01 03:44:31 -0700 |
commit | b6576ce2db7840f59ab330f1f3721a299c3d8cf8 (patch) | |
tree | 7a6dfae568ba94de45e03712dae0aca01bfd6fae /util | |
parent | aca616c551d635a9e3bcfd627b26cede69abb419 (diff) | |
download | chrome-ec-b6576ce2db7840f59ab330f1f3721a299c3d8cf8.tar.gz |
ectool: i2cread/write: Use EC_CMD_I2C_PASSTHRU
EC_CMD_I2C_READ/WRITE are deprecated, and can easily be replaced
by EC_CMD_I2C_PASSTHRU: stop using them so that we can remove them
from EC image.
BRANCH=none
BUG=chrome-os-partner:23570
TEST=emerge-elm ec-utils && cros deploy IP ec-utils
cd /usr/sbin
./ectool i2cxfer 1 0x28 0 0xE0 0xAB 0xCD
./ectool i2cxfer 1 0x28 2 0xE0
./ectool i2cwrite 16 1 0x50 0xE0 0xDEEF
./ectool i2cread 16 1 0x50 0xE0
./ectool i2cwrite 8 1 0x50 0xE0 0xAA
./ectool i2cread 8 1 0x50 0xE0
Change-Id: Ia2a6115b62e81e4f256d67340993c55bf016989a
Signed-off-by: Nicolas Boichat <drinkcat@google.com>
Reviewed-on: https://chromium-review.googlesource.com/348126
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'util')
-rw-r--r-- | util/ectool.c | 181 |
1 files changed, 106 insertions, 75 deletions
diff --git a/util/ectool.c b/util/ectool.c index 364ec2f99f..ab4fdcccd1 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -4928,10 +4928,75 @@ int cmd_i2c_protect(int argc, char *argv[]) } +int do_i2c_xfer(unsigned int port, unsigned int addr, + uint8_t *write_buf, int write_len, + uint8_t **read_buf, int read_len) { + struct ec_params_i2c_passthru *p = + (struct ec_params_i2c_passthru *)ec_outbuf; + struct ec_response_i2c_passthru *r = + (struct ec_response_i2c_passthru *)ec_inbuf; + struct ec_params_i2c_passthru_msg *msg = p->msg; + uint8_t *pdata; + int size; + int rv; + + p->port = port; + p->num_msgs = (read_len != 0) + (write_len != 0); + + size = sizeof(*p) + p->num_msgs * sizeof(*msg); + if (size + write_len > ec_max_outsize) { + fprintf(stderr, "Params too large for buffer\n"); + return -1; + } + if (sizeof(*r) + read_len > ec_max_insize) { + fprintf(stderr, "Read length too big for buffer\n"); + return -1; + } + + pdata = (uint8_t *)p + size; + if (write_len) { + msg->addr_flags = addr; + msg->len = write_len; + + memcpy(pdata, write_buf, write_len); + msg++; + } + + if (read_len) { + msg->addr_flags = addr | EC_I2C_FLAG_READ; + msg->len = read_len; + } + + rv = ec_command(EC_CMD_I2C_PASSTHRU, 0, p, size + write_len, + r, sizeof(*r) + read_len); + if (rv < 0) + return rv; + + /* Parse response */ + if (r->i2c_status & (EC_I2C_STATUS_NAK | EC_I2C_STATUS_TIMEOUT)) { + fprintf(stderr, "Transfer failed with status=0x%x\n", + r->i2c_status); + return -1; + } + + if (rv < sizeof(*r) + read_len) { + fprintf(stderr, "Truncated read response\n"); + return -1; + } + + if (read_len) + *read_buf = r->data; + + return 0; +} + + int cmd_i2c_read(int argc, char *argv[]) { - struct ec_params_i2c_read p; - struct ec_response_i2c_read r; + unsigned int port, addr; + int read_len, write_len; + uint8_t write_buf[1]; + uint8_t *read_buf; char *e; int rv; @@ -4941,49 +5006,50 @@ int cmd_i2c_read(int argc, char *argv[]) return -1; } - p.read_size = strtol(argv[1], &e, 0); - if ((e && *e) || (p.read_size != 8 && p.read_size != 16)) { + read_len = strtol(argv[1], &e, 0); + if ((e && *e) || (read_len != 8 && read_len != 16)) { fprintf(stderr, "Bad read size.\n"); return -1; } + read_len = read_len / 8; - p.port = strtol(argv[2], &e, 0); + port = strtol(argv[2], &e, 0); if (e && *e) { fprintf(stderr, "Bad port.\n"); return -1; } - p.addr = strtol(argv[3], &e, 0); + addr = strtol(argv[3], &e, 0); if (e && *e) { fprintf(stderr, "Bad address.\n"); return -1; } + /* Convert from 8-bit to 7-bit address */ + addr = addr >> 1; - p.offset = strtol(argv[4], &e, 0); + write_buf[0] = strtol(argv[4], &e, 0); if (e && *e) { fprintf(stderr, "Bad offset.\n"); return -1; } + write_len = 1; - /* - * TODO(crosbug.com/p/23570): use I2C_XFER command if supported, then - * fall back to I2C_READ. - */ - - rv = ec_command(EC_CMD_I2C_READ, 0, &p, sizeof(p), &r, sizeof(r)); + rv = do_i2c_xfer(port, addr, write_buf, write_len, &read_buf, read_len); if (rv < 0) return rv; printf("Read from I2C port %d at 0x%x offset 0x%x = 0x%x\n", - p.port, p.addr, p.offset, r.data); + port, addr, write_buf[0], *(uint16_t *)read_buf); return 0; } int cmd_i2c_write(int argc, char *argv[]) { - struct ec_params_i2c_write p; + unsigned int port, addr; + int write_len; + uint8_t write_buf[3]; char *e; int rv; @@ -4994,64 +5060,58 @@ int cmd_i2c_write(int argc, char *argv[]) return -1; } - p.write_size = strtol(argv[1], &e, 0); - if ((e && *e) || (p.write_size != 8 && p.write_size != 16)) { + write_len = strtol(argv[1], &e, 0); + if ((e && *e) || (write_len != 8 && write_len != 16)) { fprintf(stderr, "Bad write size.\n"); return -1; } + /* Include offset (length 1) */ + write_len = 1 + write_len / 8; - p.port = strtol(argv[2], &e, 0); + port = strtol(argv[2], &e, 0); if (e && *e) { fprintf(stderr, "Bad port.\n"); return -1; } - p.addr = strtol(argv[3], &e, 0); + addr = strtol(argv[3], &e, 0); if (e && *e) { fprintf(stderr, "Bad address.\n"); return -1; } + /* Convert from 8-bit to 7-bit address */ + addr = addr >> 1; - p.offset = strtol(argv[4], &e, 0); + write_buf[0] = strtol(argv[4], &e, 0); if (e && *e) { fprintf(stderr, "Bad offset.\n"); return -1; } - p.data = strtol(argv[5], &e, 0); + *((uint16_t *)&write_buf[1]) = strtol(argv[5], &e, 0); if (e && *e) { fprintf(stderr, "Bad data.\n"); return -1; } - /* - * TODO(crosbug.com/p/23570): use I2C_XFER command if supported, then - * fall back to I2C_WRITE. - */ - - rv = ec_command(EC_CMD_I2C_WRITE, 0, &p, sizeof(p), NULL, 0); + rv = do_i2c_xfer(port, addr, write_buf, write_len, NULL, 0); if (rv < 0) return rv; printf("Wrote 0x%x to I2C port %d at 0x%x offset 0x%x.\n", - p.data, p.port, p.addr, p.offset); + *((uint16_t *)&write_buf[1]), port, addr, write_buf[0]); return 0; } int cmd_i2c_xfer(int argc, char *argv[]) { - struct ec_params_i2c_passthru *p = - (struct ec_params_i2c_passthru *)ec_outbuf; - struct ec_response_i2c_passthru *r = - (struct ec_response_i2c_passthru *)ec_inbuf; - struct ec_params_i2c_passthru_msg *msg = p->msg; - unsigned int addr; - uint8_t *pdata; - char *e; + unsigned int port, addr; int read_len, write_len; - int size; + uint8_t *write_buf = NULL; + uint8_t *read_buf; + char *e; int rv, i; if (argc < 4) { @@ -5061,7 +5121,7 @@ int cmd_i2c_xfer(int argc, char *argv[]) return -1; } - p->port = strtol(argv[1], &e, 0); + port = strtol(argv[1], &e, 0); if (e && *e) { fprintf(stderr, "Bad port.\n"); return -1; @@ -5083,59 +5143,30 @@ int cmd_i2c_xfer(int argc, char *argv[]) argc -= 4; argv += 4; write_len = argc; - p->num_msgs = (read_len != 0) + (write_len != 0); - - size = sizeof(*p) + p->num_msgs * sizeof(*msg); - if (size + write_len > ec_max_outsize) { - fprintf(stderr, "Params too large for buffer\n"); - return -1; - } - if (sizeof(*r) + read_len > ec_max_insize) { - fprintf(stderr, "Read length too big for buffer\n"); - return -1; - } - pdata = (uint8_t *)p + size; if (write_len) { - msg->addr_flags = addr; - msg->len = write_len; - + write_buf = malloc(write_len); for (i = 0; i < write_len; i++) { - pdata[i] = strtol(argv[i], &e, 0); + write_buf[i] = strtol(argv[i], &e, 0); if (e && *e) { fprintf(stderr, "Bad write byte %d\n", i); return -1; } } - msg++; } - if (read_len) { - msg->addr_flags = addr | EC_I2C_FLAG_READ; - msg->len = read_len; - } + rv = do_i2c_xfer(port, addr, write_buf, write_len, &read_buf, read_len); - rv = ec_command(EC_CMD_I2C_PASSTHRU, 0, p, size + write_len, - r, sizeof(*r) + read_len); - if (rv < 0) - return rv; - - /* Parse response */ - if (r->i2c_status & (EC_I2C_STATUS_NAK | EC_I2C_STATUS_TIMEOUT)) { - fprintf(stderr, "Transfer failed with status=0x%x\n", - r->i2c_status); - return -1; - } + if (write_len) + free(write_buf); - if (rv < sizeof(*r) + read_len) { - fprintf(stderr, "Truncated read response\n"); - return -1; - } + if (rv) + return rv; if (read_len) { printf("Read bytes:"); for (i = 0; i < read_len; i++) - printf(" %#02x", r->data[i]); + printf(" %#02x", read_buf[i]); printf("\n"); } else { printf("Write successful.\n"); |