summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2016-05-31 11:31:02 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-06-01 03:44:31 -0700
commitb6576ce2db7840f59ab330f1f3721a299c3d8cf8 (patch)
tree7a6dfae568ba94de45e03712dae0aca01bfd6fae
parentaca616c551d635a9e3bcfd627b26cede69abb419 (diff)
downloadchrome-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>
-rw-r--r--util/ectool.c181
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");