mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
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>
This commit is contained in:
committed by
chrome-internal-fetch
parent
5bb0fd6b05
commit
7698c323ea
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user