summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-09-05 15:03:02 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-09-11 20:00:07 +0000
commit7698c323eae7da62890a7d01447894629d29b22b (patch)
treeb643b71dbe4e6cc74aa379d40fa3f5b6f8910d20
parent5bb0fd6b053c8f62993ce521c43daffb50b69a66 (diff)
downloadchrome-ec-7698c323eae7da62890a7d01447894629d29b22b.tar.gz
samus: Add host command to query USB type-C accessory attached.
PD accessories that are RW update-able will broadcast their rw_hash SHA1 digest upon connection to the PD MCU which will store it. For update purposes, the host needs that accessories device id and rw_hash to determine its proper firmware update payload. This CL creates a host command that requests the type-C accessory info attached to a particular port. It also implements an ectool command to expose the host command. BRANCH=none BUG=chrome-os-partner:31361 TEST=manual, # connect zinger to port 1 on samus ectool --dev=1 --interface=lpc infopddev 1 Port:0 Device:1 Hash: 0x7f4d7a13 0xf07b65b9 0x41181e10 0xb99b3d5f 0x9dee1206 ectool --dev=1 --interface=lpc infopddev 0 Port:0 has no valid device Also do the same on port 0 with similar results. Change-Id: Id63c7edad77a43d43c14d8cd6bd96e08d0d9b501 Signed-off-by: Todd Broch <tbroch@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/216814 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--board/fruitpie/usb_pd_policy.c16
-rw-r--r--board/samus_pd/usb_pd_policy.c16
-rw-r--r--common/usb_pd_protocol.c55
-rw-r--r--include/ec_commands.h7
-rw-r--r--include/usb_pd.h5
-rw-r--r--util/ectool.c40
6 files changed, 115 insertions, 24 deletions
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c
index 0a4b1be7ee..e9f32efb20 100644
--- a/board/fruitpie/usb_pd_policy.c
+++ b/board/fruitpie/usb_pd_policy.c
@@ -139,6 +139,7 @@ int pd_board_checks(void)
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
{
int cmd = PD_VDO_CMD(payload[0]);
+ uint8_t dev_id = 0;
ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]);
/* make sure we have some payload */
@@ -152,16 +153,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
ccprintf("version: %s\n", (char *)(payload+1));
break;
case VDO_CMD_READ_INFO:
- /* copy hash */
- if (cnt >= 6)
- pd_dev_store_rw_hash(port, payload + 1);
-
/* if last word is present, it contains lots of info */
- if (cnt == 7)
- ccprintf("Dev:%d SW:%d RW:%d\n",
- VDO_INFO_HW_DEV_ID(payload[6]),
+ if (cnt == 7) {
+ dev_id = VDO_INFO_HW_DEV_ID(payload[6]);
+ ccprintf("Dev:%d SW:%d RW:%d\n", dev_id,
VDO_INFO_SW_DBG_VER(payload[6]),
VDO_INFO_IS_RW(payload[6]));
+ }
+ /* copy hash */
+ if (cnt >= 6)
+ pd_dev_store_rw_hash(port, dev_id, payload + 1);
+
break;
}
diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c
index bf24b2eb07..97bab9338f 100644
--- a/board/samus_pd/usb_pd_policy.c
+++ b/board/samus_pd/usb_pd_policy.c
@@ -154,6 +154,7 @@ int pd_board_checks(void)
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
{
int cmd = PD_VDO_CMD(payload[0]);
+ uint8_t dev_id = 0;
ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]);
/* make sure we have some payload */
@@ -167,16 +168,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
ccprintf("version: %s\n", (char *)(payload+1));
break;
case VDO_CMD_READ_INFO:
- /* copy hash */
- if (cnt >= 6)
- pd_dev_store_rw_hash(port, payload + 1);
-
/* if last word is present, it contains lots of info */
- if (cnt == 7)
- ccprintf("Dev:%d SW:%d RW:%d\n",
- VDO_INFO_HW_DEV_ID(payload[6]),
+ if (cnt == 7) {
+ dev_id = VDO_INFO_HW_DEV_ID(payload[6]);
+ ccprintf("Dev:%d SW:%d RW:%d\n", dev_id,
VDO_INFO_SW_DBG_VER(payload[6]),
VDO_INFO_IS_RW(payload[6]));
+ }
+ /* copy hash */
+ if (cnt >= 6)
+ pd_dev_store_rw_hash(port, dev_id, payload + 1);
+
break;
case VDO_CMD_CURRENT:
ccprintf("Current: %dmA\n", payload[1]);
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 5923164746..55f17a0eb0 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -253,7 +253,8 @@ static struct pd_protocol {
uint32_t vdo_data[VDO_MAX_SIZE];
uint8_t vdo_count;
- /* Attached ChromeOS device RW hash */
+ /* Attached ChromeOS device id & RW hash */
+ uint8_t dev_id;
uint32_t dev_rw_hash[SHA1_DIGEST_SIZE/4];
} pd[PD_PORT_COUNT];
@@ -290,9 +291,11 @@ static inline void set_state(int port, enum pd_states next_state)
pd[port].task_state = next_state;
#ifdef CONFIG_USBC_SS_MUX
- if (next_state == PD_STATE_SRC_DISCONNECTED)
+ if (next_state == PD_STATE_SRC_DISCONNECTED) {
+ pd[port].dev_id = 0;
board_set_usb_mux(port, TYPEC_MUX_NONE,
pd[port].polarity);
+ }
#endif
/* Log state transition, except for toggling between sink and source */
@@ -1083,9 +1086,21 @@ static void pd_vdm_send_state_machine(int port)
}
}
-void pd_dev_store_rw_hash(int port, uint32_t *rw_hash)
+static inline void pd_dev_dump_info(uint8_t dev_id, uint32_t *hash)
{
+ int j;
+ ccprintf("Device:%d Hash:", dev_id);
+ for (j = 0; j < SHA1_DIGEST_SIZE/4; j++)
+ ccprintf(" 0x%08x", hash[j]);
+ ccprintf("\n");
+}
+
+void pd_dev_store_rw_hash(int port, uint8_t dev_id, uint32_t *rw_hash)
+{
+ pd[port].dev_id = dev_id;
memcpy(pd[port].dev_rw_hash, rw_hash, SHA1_DIGEST_SIZE);
+ if (debug_level >= 1)
+ pd_dev_dump_info(dev_id, rw_hash);
}
#ifdef CONFIG_USB_PD_DUAL_ROLE
@@ -1700,14 +1715,11 @@ static int command_pd(int argc, char **argv)
ccprintf("Ports %s\n", enable ? "enabled" : "disabled");
return EC_SUCCESS;
} else if (!strncasecmp(argv[1], "rwhashtable", 3)) {
- int i, j;
+ int i;
struct ec_params_usb_pd_rw_hash_entry *p;
for (i = 0; i < RW_HASH_ENTRIES; i++) {
p = &rw_hash_table[i];
- ccprintf("Device:%d Hash:", p->dev_id);
- for (j = 0; j < SHA1_DIGEST_SIZE/4; j++)
- ccprintf(" 0x%08x", p->dev_rw_hash.w[j]);
- ccprintf("\n");
+ pd_dev_dump_info(p->dev_id, p->dev_rw_hash.w);
}
return EC_SUCCESS;
}
@@ -2028,4 +2040,31 @@ DECLARE_HOST_COMMAND(EC_CMD_USB_PD_RW_HASH_ENTRY,
hc_remote_rw_hash_entry,
EC_VER_MASK(0));
+static int hc_remote_pd_dev_info(struct host_cmd_handler_args *args)
+{
+ const uint8_t *port = args->params;
+ struct ec_params_usb_pd_rw_hash_entry *r = args->response;
+
+ if (*port >= PD_PORT_COUNT) {
+ ccprintf("PD DEV_INFO - Port:%d >= %d (max ports)\n",
+ *port, PD_PORT_COUNT);
+ return EC_RES_INVALID_PARAM;
+ }
+ r->dev_id = pd[*port].dev_id;
+ ccprintf("PD DEV_INFO - requested Port:%d has Device:%d\n",
+ *port, r->dev_id);
+
+ if (r->dev_id) {
+ memcpy(r->dev_rw_hash.b, pd[*port].dev_rw_hash,
+ SHA1_DIGEST_SIZE);
+ }
+
+ args->response_size = sizeof(*r);
+ return EC_RES_SUCCESS;
+}
+
+DECLARE_HOST_COMMAND(EC_CMD_USB_PD_DEV_INFO,
+ hc_remote_pd_dev_info,
+ EC_VER_MASK(0));
+
#endif /* CONFIG_COMMON_RUNTIME */
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 27b3107c16..6cbfe4fd4c 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2637,6 +2637,13 @@ struct ec_params_usb_pd_rw_hash_entry {
uint32_t w[DIV_ROUND_UP(SHA1_DIGEST_SIZE, sizeof(uint32_t))];
} dev_rw_hash;
} __packed;
+
+/* Read USB-PD Accessory info */
+#define EC_CMD_USB_PD_DEV_INFO 0x112
+
+struct ec_params_usb_pd_info_request {
+ uint8_t port;
+} __packed;
/*****************************************************************************/
/*
* Passthru commands
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 507a81fe7f..08c8038b3a 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -307,12 +307,13 @@ int pd_board_checks(void);
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload);
/**
- * Store RW hash of device
+ * Store Device ID & RW hash of device
*
* @param port USB-C port number
+ * @param dev_id device identifier
* @param rw_hash pointer to sha1 rw_hash
*/
-void pd_dev_store_rw_hash(int port, uint32_t *rw_hash);
+void pd_dev_store_rw_hash(int port, uint8_t dev_id, uint32_t *rw_hash);
/**
* Send Vendor Defined Message
diff --git a/util/ectool.c b/util/ectool.c
index 0d380c0e78..822a418260 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -118,6 +118,8 @@ const char help_str[] =
" Write I2C bus\n"
" i2cxfer <port> <slave_addr> <read_count> [write bytes...]\n"
" Perform I2C transfer on EC's I2C bus\n"
+ " infopddev <port>\n"
+ " Get info about USB type-C accessory attached to port\n"
" keyscan <beat_us> <filename>\n"
" Test low-level key scanning\n"
" led <name> <query | auto | off | <color> | <color>=<value>...>\n"
@@ -812,6 +814,43 @@ int cmd_rw_hash_pd(int argc, char *argv[])
}
+int cmd_pd_device_info(int argc, char *argv[])
+{
+ int i, rv;
+ char *e;
+ struct ec_params_usb_pd_info_request *p =
+ (struct ec_params_usb_pd_info_request *)ec_outbuf;
+ struct ec_params_usb_pd_rw_hash_entry *r =
+ (struct ec_params_usb_pd_rw_hash_entry *)ec_inbuf;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <port>\n", argv[0]);
+ return -1;
+ }
+
+ p->port = strtol(argv[1], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad port\n");
+ return -1;
+ }
+
+ rv = ec_command(EC_CMD_USB_PD_DEV_INFO, 0, p, sizeof(*p),
+ ec_inbuf, ec_max_insize);
+ if (rv < 0)
+ return rv;
+
+ if (!r->dev_id)
+ printf("Port:%d has no valid device\n", p->port);
+ else {
+ printf("Port:%d Device:%d Hash: ", p->port, r->dev_id);
+ for (i = 0; i < 5; i++)
+ printf(" 0x%08x", r->dev_rw_hash.w[i]);
+ printf("\n");
+ }
+ return rv;
+}
+
+
/* PD image size is 16k minus 32 bits for the RW hash */
#define PD_RW_IMAGE_SIZE (16 * 1024 - 32)
static struct sha1_ctx ctx;
@@ -4742,6 +4781,7 @@ const struct command commands[] = {
{"i2cread", cmd_i2c_read},
{"i2cwrite", cmd_i2c_write},
{"i2cxfer", cmd_i2c_xfer},
+ {"infopddev", cmd_pd_device_info},
{"led", cmd_led},
{"lightbar", cmd_lightbar},
{"keyconfig", cmd_keyconfig},