summaryrefslogtreecommitdiff
path: root/common/usb_pd_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usb_pd_policy.c')
-rw-r--r--common/usb_pd_policy.c126
1 files changed, 125 insertions, 1 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index ddfaa41d2a..0e53f80c65 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -378,8 +378,22 @@ static void dfp_consume_identity(int port, int cnt, uint32_t *payload)
static void dfp_consume_cable_response(int port, int cnt, uint32_t *payload)
{
- if (is_vdo_present(cnt, VDO_INDEX_IDH))
+ if (is_vdo_present(cnt, VDO_INDEX_IDH)) {
cable[port].type = PD_IDH_PTYPE(payload[VDO_INDEX_IDH]);
+ if (is_vdo_present(cnt, VDO_INDEX_PTYPE_CABLE1))
+ cable[port].attr.raw_value =
+ payload[VDO_INDEX_PTYPE_CABLE1];
+ }
+ /*
+ * Ref USB PD Spec 3.0 Pg 145. For active cable there are two VDOs.
+ * Hence storing the second VDO.
+ */
+ if (IS_ENABLED(CONFIG_USB_PD_REV30) &&
+ is_vdo_present(cnt, VDO_INDEX_PTYPE_CABLE2) &&
+ cable[port].type == IDH_PTYPE_ACABLE) {
+ cable[port].rev = PD_REV30;
+ cable[port].attr2.raw_value = payload[VDO_INDEX_PTYPE_CABLE2];
+ }
}
static int dfp_discover_ident(int port, uint32_t *payload)
@@ -940,6 +954,116 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
#endif /* CONFIG_USB_PD_ALT_MODE */
+#ifdef CONFIG_CMD_USB_PD_CABLE
+static const char * const cable_type[] = {
+ [IDH_PTYPE_PCABLE] = "Passive",
+ [IDH_PTYPE_ACABLE] = "Active",
+};
+
+static const char * const cable_curr[] = {
+ [CABLE_CURRENT_3A] = "3A",
+ [CABLE_CURRENT_5A] = "5A",
+};
+
+static const char * const cable_ss_support[] = {
+ [USB_SS_U2_ONLY] = "Not supported",
+ [USB_SS_U31_GEN1] = "Gen 1",
+ [USB_SS_U31_GEN2] = "Gen 1 and Gen 2",
+};
+
+static const char * const vbus_max[] = {
+ [CABLE_VBUS_20V] = "20V",
+ [CABLE_VBUS_30V] = "30V",
+ [CABLE_VBUS_40V] = "40V",
+ [CABLE_VBUS_50V] = "50V",
+};
+static const char * const conn_type[] = {
+ [CONNECTOR_ATYPE] = "Type A",
+ [CONNECTOR_BTYPE] = "Type B",
+ [CONNECTOR_CTYPE] = "Type C",
+ [CONNECTOR_CAPTIVE] = "Captive",
+};
+
+static int command_cable(int argc, char **argv)
+{
+ int port;
+ char *e;
+
+ if (argc < 2)
+ return EC_ERROR_PARAM_COUNT;
+ port = strtoi(argv[1], &e, 0);
+ if (*e || port >= CONFIG_USB_PD_PORT_COUNT)
+ return EC_ERROR_PARAM2;
+
+ ccprintf("Cable Type: ");
+ if (cable[port].type != IDH_PTYPE_PCABLE &&
+ cable[port].type != IDH_PTYPE_ACABLE) {
+ ccprintf("Not Emark Cable\n");
+ return EC_SUCCESS;
+ }
+ ccprintf("%s\n", cable_type[cable[port].type]);
+
+ /*
+ * For rev 2.0, rev 3.0 active and passive cables have same bits for
+ * connector type (Bit 19:18) and current handling capability bit 6:5
+ */
+ ccprintf("Connector Type: %s\n",
+ cable[port].attr.rev20.connector > ARRAY_SIZE(conn_type) ?
+ "Invalid" : conn_type[cable[port].attr.rev20.connector]);
+
+ if (cable[port].attr.rev20.current) {
+ ccprintf("Cable Current: %s\n",
+ cable[port].attr.rev20.current > ARRAY_SIZE(cable_curr) ?
+ "Invalid" : cable_curr[cable[port].attr.rev20.current]);
+ } else
+ ccprintf("Cable Current: Invalid\n");
+
+ /*
+ * For Rev 3.0 passive cables and Rev 2.0 active and passive cables,
+ * USB Superspeed Signaling support have same bits 2:0
+ */
+ if (cable[port].type == IDH_PTYPE_PCABLE) {
+ ccprintf("USB Superspeed Signaling support: %s\n",
+ cable[port].attr.rev20.ss >
+ ARRAY_SIZE(cable_ss_support) ? "Invalid" :
+ cable_ss_support[cable[port].attr.p_rev30.ss]);
+ }
+
+ /*
+ * For Rev 3.0 active cables and Rev 2.0 active and passive cables,
+ * SOP" controller preset have same bit 3
+ */
+ if (cable[port].type == IDH_PTYPE_ACABLE) {
+ ccprintf("SOP' ' Controller: %s present\n",
+ cable[port].attr.rev20.controller ? "" : "Not");
+ }
+
+ if (cable[port].rev == PD_REV30) {
+ /*
+ * For Rev 3.0 active and passive cables, Max Vbus vtg have
+ * same bits 10:9.
+ */
+ ccprintf("Max vbus voltage: %s\n",
+ cable[port].attr.p_rev30.vbus_max >
+ ARRAY_SIZE(vbus_max) ? "Invaild" :
+ vbus_max[cable[port].attr.p_rev30.vbus_max]);
+
+ /* For Rev 3.0 Active cables */
+ if (cable[port].type == IDH_PTYPE_ACABLE) {
+ ccprintf("SS signaling: USB_SS_GEN%u\n",
+ cable[port].attr2.a2_rev30.sss ? 2 : 1);
+ ccprintf("Number of SS lanes supported: %u\n",
+ cable[port].attr2.a2_rev30.lanes);
+ }
+ }
+ return EC_SUCCESS;
+}
+
+DECLARE_CONSOLE_COMMAND(pdcable, command_cable,
+ "<port>",
+ "Cable Characteristics");
+#endif /* CONFIG_CMD_USB_PD_CABLE */
+
static void pd_usb_billboard_deferred(void)
{
#if defined(CONFIG_USB_PD_ALT_MODE) && !defined(CONFIG_USB_PD_ALT_MODE_DFP) \