summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-10-31 16:34:42 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-11 05:41:01 +0000
commit73e182a443fcaeacbcc6d5c2123852bc3d377890 (patch)
tree9ac63b04245f0defd7a50b06960e6495e3009cc8
parent84681349f444a9596d38117b41e8a279bb52a856 (diff)
downloadchrome-ec-73e182a443fcaeacbcc6d5c2123852bc3d377890.tar.gz
pd: Add SVDM discovery info into host command.
During the discovery identity phase of type-C devices that support it there is some info that could be useful to kernel & userland for policy decisions. CL starts by passing up the vid, pid & product type (ptype) of the discover identity VDO. BRANCH=samus BUG=chrome-os-partner:32650 TEST=manual, From host, w/ hoho in port 1 ectool --name=cros_pd infopddev 1 Port:1 Device:4 Hash: 0x57b1e4e0 0x7204075f 0x65c0fa72 0xdcca15ed 0xf3231237 Port:1 ptype:6 vid:0x18d1 pid:0x5010 Change-Id: Ie05d191149ada0ec860b713d780b0345eab3a647 Signed-off-by: Todd Broch <tbroch@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/226899 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--common/usb_pd_policy.c46
-rw-r--r--include/ec_commands.h8
-rw-r--r--include/usb_pd.h3
-rw-r--r--util/ectool.c23
4 files changed, 75 insertions, 5 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 11f8c35620..7a77708f37 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -39,6 +39,7 @@ static void dfp_consume_identity(int port, uint32_t *payload)
{
int ptype = PD_IDH_PTYPE(payload[VDO_I(IDH)]);
pe_init(port);
+ memcpy(&pe[port].identity, payload + 1, sizeof(pe[port].identity));
switch (ptype) {
case IDH_PTYPE_AMA:
/* TODO(tbroch) do I disable VBUS here if power contract
@@ -189,7 +190,27 @@ int pd_exit_mode(int port, uint32_t *payload)
static void dump_pe(int port)
{
- int i, j;
+ const char * const idh_ptype_names[] = {
+ "UNDEF", "Hub", "Periph", "PCable", "ACable", "AMA",
+ "RSV6", "RSV7"};
+
+ int i, j, idh_ptype;
+
+ if (pe[port].identity[0] == 0) {
+ ccprintf("No identity discovered yet.\n");
+ return;
+ }
+ idh_ptype = PD_IDH_PTYPE(pe[port].identity[0]);
+ ccprintf("IDENT:\n");
+ ccprintf("\t[ID Header] %08x :: %s, VID:%04x\n", pe[port].identity[0],
+ idh_ptype_names[idh_ptype], PD_IDH_VID(pe[port].identity[0]));
+ ccprintf("\t[Cert Stat] %08x\n", pe[port].identity[1]);
+ for (i = 2; i < ARRAY_SIZE(pe[port].identity); i++) {
+ ccprintf("\t");
+ if (pe[port].identity[i])
+ ccprintf("[%d] %08x ", i, pe[port].identity[i]);
+ }
+ ccprintf("\n");
if (pe[port].svid_cnt < 1) {
ccprintf("No SVIDS discovered yet.\n");
@@ -423,3 +444,26 @@ int pd_exit_mode(int port, uint32_t *payload)
return 0;
}
#endif /* !CONFIG_USB_PD_ALT_MODE_DFP */
+
+#ifdef CONFIG_USB_PD_ALT_MODE_DFP
+static int hc_remote_pd_discovery(struct host_cmd_handler_args *args)
+{
+ const uint8_t *port = args->params;
+ struct ec_params_usb_pd_discovery_entry *r = args->response;
+
+ if (*port >= PD_PORT_COUNT)
+ return EC_RES_INVALID_PARAM;
+
+ r->vid = PD_IDH_VID(pe[*port].identity[0]);
+ r->ptype = PD_IDH_PTYPE(pe[*port].identity[0]);
+ /* pid only included if vid is assigned */
+ if (r->vid)
+ r->pid = PD_PRODUCT_PID(pe[*port].identity[2]);
+
+ args->response_size = sizeof(*r);
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_USB_PD_DISCOVERY,
+ hc_remote_pd_discovery,
+ EC_VER_MASK(0));
+#endif
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 2266f07971..574475ea09 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2824,6 +2824,14 @@ struct ec_params_usb_pd_info_request {
uint8_t port;
} __packed;
+/* Read USB-PD Device discovery info */
+#define EC_CMD_USB_PD_DISCOVERY 0x113
+struct ec_params_usb_pd_discovery_entry {
+ uint16_t vid; /* USB-IF VID */
+ uint16_t pid; /* USB-IF PID */
+ uint8_t ptype; /* product type (hub,periph,cable,ama) */
+} __packed;
+
#endif /* !__ACPI__ */
/*****************************************************************************/
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 848586aea7..c5b90b4872 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -166,6 +166,8 @@ struct pd_policy {
int svid_idx;
/* count of svids discovered */
int svid_cnt;
+ /* SVDM identity info (Id, Cert Stat, 0-4 Typec specific) */
+ uint32_t identity[PDO_MAX_OBJECTS - 1];
/* supported svids & corresponding vdo mode data */
struct svdm_svid_data svids[SVID_DISCOVERY_MAX];
/* active mode */
@@ -302,6 +304,7 @@ struct pd_policy {
* <15:0> : USB bcdDevice
*/
#define VDO_PRODUCT(pid, bcd) (((pid) & 0xffff) << 16 | ((bcd) & 0xffff))
+#define PD_PRODUCT_PID(vdo) (((vdo) >> 16) & 0xffff)
/*
* Cable VDO
diff --git a/util/ectool.c b/util/ectool.c
index 062ffafedb..f8043cefb0 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -825,8 +825,9 @@ int cmd_pd_device_info(int argc, char *argv[])
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 *r0 =
(struct ec_params_usb_pd_rw_hash_entry *)ec_inbuf;
+ struct ec_params_usb_pd_discovery_entry *r1;
if (argc < 2) {
fprintf(stderr, "Usage: %s <port>\n", argv[0]);
@@ -844,14 +845,28 @@ int cmd_pd_device_info(int argc, char *argv[])
if (rv < 0)
return rv;
- if (!r->dev_id)
+ if (!r0->dev_id)
printf("Port:%d has no valid device\n", p->port);
else {
- printf("Port:%d Device:%d Hash: ", p->port, r->dev_id);
+ printf("Port:%d Device:%d Hash: ", p->port, r0->dev_id);
for (i = 0; i < 5; i++)
- printf(" 0x%08x", r->dev_rw_hash.w[i]);
+ printf(" 0x%08x", r0->dev_rw_hash.w[i]);
printf("\n");
}
+
+ r1 = (struct ec_params_usb_pd_discovery_entry *)ec_inbuf;
+ rv = ec_command(EC_CMD_USB_PD_DISCOVERY, 0, p, sizeof(*p),
+ ec_inbuf, ec_max_insize);
+ if (rv < 0)
+ return rv;
+
+ if (!r1->vid)
+ printf("Port:%d has no discovered device\n", p->port);
+ else {
+ printf("Port:%d ptype:%d vid:0x%04x pid:0x%04x\n", p->port,
+ r1->ptype, r1->vid, r1->pid);
+ }
+
return rv;
}