summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/servo_v4p1/board.h3
-rw-r--r--common/i2c_master.c65
-rw-r--r--include/config.h1
3 files changed, 68 insertions, 1 deletions
diff --git a/board/servo_v4p1/board.h b/board/servo_v4p1/board.h
index 621ea5fa8e..02bc4431ef 100644
--- a/board/servo_v4p1/board.h
+++ b/board/servo_v4p1/board.h
@@ -217,6 +217,9 @@
#define PD_MAX_POWER_MW 60000
#define PD_MAX_CURRENT_MA 3000
#define PD_MAX_VOLTAGE_MV 20000
+
+/* Add the raw option to the i2c_xfer command */
+#define CONFIG_CMD_I2C_XFER_RAW
#else
#undef CONFIG_CMD_I2C_XFER
#undef CONFIG_USB_POWER_DELIVERY
diff --git a/common/i2c_master.c b/common/i2c_master.c
index 23164720b5..09d446bf94 100644
--- a/common/i2c_master.c
+++ b/common/i2c_master.c
@@ -1514,7 +1514,66 @@ static int command_i2cxfer(int argc, char **argv)
else
rv = i2c_write16(port, addr_flags,
offset, v);
+#ifdef CONFIG_CMD_I2C_XFER_RAW
+ } else if (strcasecmp(argv[1], "raw") == 0) {
+ /* <port> <slave_addr> <read_count> [write_bytes..] */
+ int i;
+ int write_count = 0, read_count = 0;
+ int xferflags = I2C_XFER_START;
+
+ read_count = offset;
+ if (read_count < 0 || read_count > sizeof(data))
+ return EC_ERROR_PARAM5;
+
+ if (argc >= 6) {
+ /* Parse bytes to write */
+ argc -= 5;
+ argv += 5;
+ write_count = argc;
+ if (write_count > sizeof(data)) {
+ ccprintf("Too many bytes to write\n");
+ return EC_ERROR_PARAM_COUNT;
+ }
+
+ for (i = 0; i < write_count; i++) {
+ data[i] = strtoi(argv[i], &e, 0);
+ if (*e) {
+ ccprintf("Bad write byte %d\n", i);
+ return EC_ERROR_INVAL;
+ }
+ }
+ }
+ if (write_count) {
+ if (read_count == 0)
+ xferflags |= I2C_XFER_STOP;
+ ccprintf("Writing %d bytes\n", write_count);
+ i2c_lock(port, 1);
+ rv = i2c_xfer_unlocked(port,
+ addr_flags,
+ data, write_count,
+ NULL, 0,
+ xferflags);
+ if (rv || read_count == 0) {
+ i2c_lock(port, 0);
+ return rv;
+ }
+ }
+ if (read_count) {
+ ccprintf("Reading %d bytes\n", read_count);
+ if (write_count == 0)
+ i2c_lock(port, 1);
+ rv = i2c_xfer_unlocked(port,
+ addr_flags,
+ NULL, 0,
+ data, read_count,
+ I2C_XFER_START | I2C_XFER_STOP);
+ i2c_lock(port, 0);
+ if (!rv)
+ ccprintf("Data: %ph\n",
+ HEX_BUF(data, read_count));
+ }
+#endif /* CONFIG_CMD_I2C_XFER_RAW */
} else {
return EC_ERROR_PARAM1;
}
@@ -1522,7 +1581,11 @@ static int command_i2cxfer(int argc, char **argv)
return rv;
}
DECLARE_CONSOLE_COMMAND(i2cxfer, command_i2cxfer,
- "r/r16/rlen/w/w16 port addr offset [value | len]",
+ "r/r16/rlen/w/w16 port addr offset [value | len]"
+#ifdef CONFIG_CMD_I2C_XFER_RAW
+ "\nraw port addr read_count [bytes_to_write..]"
+#endif /* CONFIG_CMD_I2C_XFER_RAW */
+ ,
"Read write I2C");
#endif
diff --git a/include/config.h b/include/config.h
index 47e6641645..b3a92c859d 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1345,6 +1345,7 @@
#undef CONFIG_CMD_I2C_STRESS_TEST_CHARGER
#undef CONFIG_CMD_I2C_STRESS_TEST_TCPC
#define CONFIG_CMD_I2C_XFER
+#undef CONFIG_CMD_I2C_XFER_RAW
#define CONFIG_CMD_IDLE_STATS
#undef CONFIG_CMD_ILIM
#define CONFIG_CMD_INA