diff options
-rw-r--r-- | common/usb_pd_policy.c | 46 | ||||
-rw-r--r-- | include/ec_commands.h | 8 | ||||
-rw-r--r-- | include/usb_pd.h | 3 | ||||
-rw-r--r-- | util/ectool.c | 23 |
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; } |