summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@chromium.org>2021-09-21 16:28:42 -0700
committerCommit Bot <commit-bot@chromium.org>2021-10-01 22:25:12 +0000
commit70b07f8504ba32ace9292b36e0bc22fa2319c4e9 (patch)
treed8431c65fafab582f392686f58aeff928f1a6b6c
parentf92bca6657e571259911e33f88af2a301c887b01 (diff)
downloadchrome-ec-70b07f8504ba32ace9292b36e0bc22fa2319c4e9.tar.gz
ectool: Split I2C commands into separate file
This splits the I2C related commands into their own file. BRANCH=none BUG=b:201039003 TEST=buildall passes Change-Id: Iaa22bcb624580e5a3893791a46e11afc8b7517f6 Signed-off-by: Caveh Jalali <caveh@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3181507 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Boris Mittelberg <bmbm@google.com>
-rw-r--r--util/build.mk1
-rw-r--r--util/ectool.c311
-rw-r--r--util/ectool.h8
-rw-r--r--util/ectool_i2c.c321
4 files changed, 331 insertions, 310 deletions
diff --git a/util/build.mk b/util/build.mk
index 9f9430a3b4..3c8ce256e0 100644
--- a/util/build.mk
+++ b/util/build.mk
@@ -30,6 +30,7 @@ comm-objs+=comm-lpc.o comm-i2c.o misc_util.o
iteflash-objs = iteflash.o usb_if.o
ectool-objs=ectool.o ectool_keyscan.o ec_flash.o ec_panicinfo.o $(comm-objs)
+ectool-objs+=ectool_i2c.o
ectool-objs+=../common/crc.o
ectool_servo-objs=$(ectool-objs) comm-servo-spi.o
ec_sb_firmware_update-objs=ec_sb_firmware_update.o $(comm-objs) misc_util.o
diff --git a/util/ectool.c b/util/ectool.c
index e70c5ae711..8d338c04ff 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -362,7 +362,7 @@ static const char * const led_names[] = {
BUILD_ASSERT(ARRAY_SIZE(led_names) == EC_LED_ID_COUNT);
/* ASCII mode for printing, default off */
-static int ascii_mode = 0;
+int ascii_mode;
/* Check SBS numerical value range */
int is_battery_range(int val)
@@ -7052,315 +7052,6 @@ int cmd_wireless(int argc, char *argv[])
}
-int cmd_i2c_protect(int argc, char *argv[])
-{
- struct ec_params_i2c_passthru_protect p;
- char *e;
- int rv;
-
- if (argc != 2 && (argc != 3 || strcmp(argv[2], "status"))) {
- fprintf(stderr, "Usage: %s <port> [status]\n",
- argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- if (argc == 3) {
- struct ec_response_i2c_passthru_protect r;
-
- p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_STATUS;
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
- &r, sizeof(r));
-
- if (rv < 0)
- return rv;
-
- printf("I2C port %d: %s (%d)\n", p.port,
- r.status ? "Protected" : "Unprotected", r.status);
- } else {
- p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE;
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
- NULL, 0);
-
- if (rv < 0)
- return rv;
- }
- return 0;
-}
-
-
-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;
-}
-
-static void cmd_i2c_help(void)
-{
- fprintf(stderr,
- " Usage: i2cread <8 | 16> <port> <addr8> <offset>\n"
- " Usage: i2cwrite <8 | 16> <port> <addr8> <offset> <data>\n"
- " Usage: i2cxfer <port> <addr7> <read_count> [bytes...]\n"
- " <port> i2c port number\n"
- " <addr8> 8-bit i2c address\n"
- " <addr7> 7-bit i2c address\n"
- " <offset> offset to read from or write to\n"
- " <data> data to write\n"
- " <read_count> number of bytes to read\n"
- " [bytes ...] data to write\n"
- );
-
-}
-
-int cmd_i2c_read(int argc, char *argv[])
-{
- unsigned int port, addr8, addr7;
- int read_len, write_len;
- uint8_t write_buf[1];
- uint8_t *read_buf = NULL;
- char *e;
- int rv;
-
- if (argc != 5) {
- cmd_i2c_help();
- return -1;
- }
-
- 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;
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr8 = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad address.\n");
- return -1;
- }
- addr7 = addr8 >> 1;
-
- write_buf[0] = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- write_len = 1;
-
- rv = do_i2c_xfer(port, addr7, 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",
- port, addr8, write_buf[0], *(uint16_t *)read_buf);
- return 0;
-}
-
-
-int cmd_i2c_write(int argc, char *argv[])
-{
- unsigned int port, addr8, addr7;
- int write_len;
- uint8_t write_buf[3];
- char *e;
- int rv;
-
- if (argc != 6) {
- cmd_i2c_help();
- return -1;
- }
-
- 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;
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr8 = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad address.\n");
- return -1;
- }
- addr7 = addr8 >> 1;
-
- write_buf[0] = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- *((uint16_t *)&write_buf[1]) = strtol(argv[5], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad data.\n");
- return -1;
- }
-
- rv = do_i2c_xfer(port, addr7, 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",
- *((uint16_t *)&write_buf[1]), port, addr8, write_buf[0]);
- return 0;
-}
-
-int cmd_i2c_xfer(int argc, char *argv[])
-{
- unsigned int port, addr;
- int read_len, write_len;
- uint8_t *write_buf = NULL;
- uint8_t *read_buf;
- char *e;
- int rv, i;
-
- if (argc < 4) {
- cmd_i2c_help();
- return -1;
- }
-
- port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr = strtol(argv[2], &e, 0) & 0x7f;
- if (e && *e) {
- fprintf(stderr, "Bad peripheral address.\n");
- return -1;
- }
-
- read_len = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad read length.\n");
- return -1;
- }
-
- /* Skip over params to bytes to write */
- argc -= 4;
- argv += 4;
- write_len = argc;
-
- if (write_len) {
- write_buf = (uint8_t *)(malloc(write_len));
- if (write_buf == NULL)
- return -1;
- for (i = 0; i < write_len; i++) {
- write_buf[i] = strtol(argv[i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad write byte %d\n", i);
- free(write_buf);
- return -1;
- }
- }
- }
-
- rv = do_i2c_xfer(port, addr, write_buf, write_len, &read_buf, read_len);
-
- if (write_len)
- free(write_buf);
-
- if (rv)
- return rv;
-
- if (read_len) {
- if (ascii_mode) {
- for (i = 0; i < read_len; i++)
- printf(isprint(read_buf[i]) ? "%c" : "\\x%02x",
- read_buf[i]);
- } else {
- printf("Read bytes:");
- for (i = 0; i < read_len; i++)
- printf(" %#02x", read_buf[i]);
- }
- printf("\n");
- } else {
- printf("Write successful.\n");
- }
-
- return 0;
-}
-
static void cmd_locate_chip_help(const char *const cmd)
{
fprintf(stderr,
diff --git a/util/ectool.h b/util/ectool.h
index c47edbf27c..a0cc0c72a0 100644
--- a/util/ectool.h
+++ b/util/ectool.h
@@ -40,3 +40,11 @@ struct command {
* The key matrix is read from the fdt.
*/
int cmd_keyscan(int argc, char *argv[]);
+
+/* ASCII mode for printing, default off */
+extern int ascii_mode;
+
+int cmd_i2c_protect(int argc, char *argv[]);
+int cmd_i2c_read(int argc, char *argv[]);
+int cmd_i2c_write(int argc, char *argv[]);
+int cmd_i2c_xfer(int argc, char *argv[]);
diff --git a/util/ectool_i2c.c b/util/ectool_i2c.c
new file mode 100644
index 0000000000..cf016d44a8
--- /dev/null
+++ b/util/ectool_i2c.c
@@ -0,0 +1,321 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <endian.h>
+
+#include "comm-host.h"
+#include "ectool.h"
+
+int cmd_i2c_protect(int argc, char *argv[])
+{
+ struct ec_params_i2c_passthru_protect p;
+ char *e;
+ int rv;
+
+ if (argc != 2 && (argc != 3 || strcmp(argv[2], "status"))) {
+ fprintf(stderr, "Usage: %s <port> [status]\n",
+ argv[0]);
+ return -1;
+ }
+
+ p.port = strtol(argv[1], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad port.\n");
+ return -1;
+ }
+
+ if (argc == 3) {
+ struct ec_response_i2c_passthru_protect r;
+
+ p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_STATUS;
+
+ rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
+ &r, sizeof(r));
+
+ if (rv < 0)
+ return rv;
+
+ printf("I2C port %d: %s (%d)\n", p.port,
+ r.status ? "Protected" : "Unprotected", r.status);
+ } else {
+ p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE;
+
+ rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
+ NULL, 0);
+
+ if (rv < 0)
+ return rv;
+ }
+ return 0;
+}
+
+static 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;
+}
+
+static void cmd_i2c_help(void)
+{
+ fprintf(stderr,
+ " Usage: i2cread <8 | 16> <port> <addr8> <offset>\n"
+ " Usage: i2cwrite <8 | 16> <port> <addr8> <offset> <data>\n"
+ " Usage: i2cxfer <port> <addr7> <read_count> [bytes...]\n"
+ " <port> i2c port number\n"
+ " <addr8> 8-bit i2c address\n"
+ " <addr7> 7-bit i2c address\n"
+ " <offset> offset to read from or write to\n"
+ " <data> data to write\n"
+ " <read_count> number of bytes to read\n"
+ " [bytes ...] data to write\n"
+ );
+
+}
+
+int cmd_i2c_read(int argc, char *argv[])
+{
+ unsigned int port, addr8, addr7;
+ int read_len, write_len;
+ uint8_t write_buf[1];
+ uint8_t *read_buf = NULL;
+ char *e;
+ int rv;
+
+ if (argc != 5) {
+ cmd_i2c_help();
+ return -1;
+ }
+
+ 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;
+
+ port = strtol(argv[2], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad port.\n");
+ return -1;
+ }
+
+ addr8 = strtol(argv[3], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad address.\n");
+ return -1;
+ }
+ addr7 = addr8 >> 1;
+
+ write_buf[0] = strtol(argv[4], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad offset.\n");
+ return -1;
+ }
+ write_len = 1;
+
+ rv = do_i2c_xfer(port, addr7, 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",
+ port, addr8, write_buf[0], *(uint16_t *)read_buf);
+ return 0;
+}
+
+int cmd_i2c_write(int argc, char *argv[])
+{
+ unsigned int port, addr8, addr7;
+ int write_len;
+ uint8_t write_buf[3];
+ char *e;
+ int rv;
+
+ if (argc != 6) {
+ cmd_i2c_help();
+ return -1;
+ }
+
+ 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;
+
+ port = strtol(argv[2], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad port.\n");
+ return -1;
+ }
+
+ addr8 = strtol(argv[3], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad address.\n");
+ return -1;
+ }
+ addr7 = addr8 >> 1;
+
+ write_buf[0] = strtol(argv[4], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad offset.\n");
+ return -1;
+ }
+
+ *((uint16_t *)&write_buf[1]) = strtol(argv[5], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad data.\n");
+ return -1;
+ }
+
+ rv = do_i2c_xfer(port, addr7, 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",
+ *((uint16_t *)&write_buf[1]), port, addr8, write_buf[0]);
+ return 0;
+}
+
+int cmd_i2c_xfer(int argc, char *argv[])
+{
+ unsigned int port, addr;
+ int read_len, write_len;
+ uint8_t *write_buf = NULL;
+ uint8_t *read_buf;
+ char *e;
+ int rv, i;
+
+ if (argc < 4) {
+ cmd_i2c_help();
+ return -1;
+ }
+
+ port = strtol(argv[1], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad port.\n");
+ return -1;
+ }
+
+ addr = strtol(argv[2], &e, 0) & 0x7f;
+ if (e && *e) {
+ fprintf(stderr, "Bad peripheral address.\n");
+ return -1;
+ }
+
+ read_len = strtol(argv[3], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad read length.\n");
+ return -1;
+ }
+
+ /* Skip over params to bytes to write */
+ argc -= 4;
+ argv += 4;
+ write_len = argc;
+
+ if (write_len) {
+ write_buf = (uint8_t *)(malloc(write_len));
+ if (write_buf == NULL)
+ return -1;
+ for (i = 0; i < write_len; i++) {
+ write_buf[i] = strtol(argv[i], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad write byte %d\n", i);
+ free(write_buf);
+ return -1;
+ }
+ }
+ }
+
+ rv = do_i2c_xfer(port, addr, write_buf, write_len, &read_buf, read_len);
+
+ if (write_len)
+ free(write_buf);
+
+ if (rv)
+ return rv;
+
+ if (read_len) {
+ if (ascii_mode) {
+ for (i = 0; i < read_len; i++)
+ printf(isprint(read_buf[i]) ? "%c" : "\\x%02x",
+ read_buf[i]);
+ } else {
+ printf("Read bytes:");
+ for (i = 0; i < read_len; i++)
+ printf(" %#02x", read_buf[i]);
+ }
+ printf("\n");
+ } else {
+ printf("Write successful.\n");
+ }
+
+ return 0;
+}