diff options
author | Ayushee <ayushee.shah@intel.com> | 2019-10-02 12:13:17 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-01 01:48:40 +0000 |
commit | 3ad88b367cf49da53865890bd7539827d1f29813 (patch) | |
tree | 068df49e9a628a3d0d09b6388d164ed872541b43 | |
parent | 510df8cb6ae9f78fea9a5f8bbac09c5d131ad357 (diff) | |
download | chrome-ec-3ad88b367cf49da53865890bd7539827d1f29813.tar.gz |
usbc: Get current DP pin mode and CC state
To configure Intel virtual mux and burnside bridge retimer,
current DP pin mode, cc state and the type of the cable is
required. Hence, implemented a board level function that
returns the current DP pin mode and added a function that
returns the type of cable inaccordance to the cable vdo response.
Also added a new version to USB_PD_CONTROL host command, to return
the DP mode, cc_state and the cable type
BUG=b:141971044
BRANCH=None
TEST=Verifed with ectool usbpd command on CPU console, able to get
correct CC state, pin mode and cable type
Pin mode: USB:0x0 (No DP)
DP cable:0x4 (Mode:C)
USBC dock:0x8 (Mode:D)
Change-Id: If87ae6b77e5fa2ceaa22319dfa2d2c802460edfa
Signed-off-by: Ayushee <ayushee.shah@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1835030
Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r-- | common/usb_pd_policy.c | 2 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 5 | ||||
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 22 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 64 | ||||
-rw-r--r-- | include/usb_pd.h | 4 | ||||
-rw-r--r-- | util/ectool.c | 10 |
6 files changed, 89 insertions, 18 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 6adff73183..090588a034 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -200,7 +200,7 @@ void reset_pd_cable(int port) memset(&cable[port], 0, sizeof(cable[port])); } -uint8_t get_usb_pd_mux_cable_type(int port) +enum idh_ptype get_usb_pd_mux_cable_type(int port) { return cable[port].type; } diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index ad4ff19fa0..03a2f84c95 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -396,7 +396,10 @@ int pd_is_vbus_present(int port) #ifdef CONFIG_USB_PD_RETIMER int pd_is_ufp(int port) { - return pd[port].cc_state == PD_CC_UFP_ATTACHED; + /* Returns true if port partner is UFP */ + return pd[port].cc_state == PD_CC_UFP_ATTACHED || + pd[port].cc_state == PD_CC_UFP_DEBUG_ACC || + pd[port].cc_state == PD_CC_UFP_AUDIO_ACC; } int pd_is_debug_acc(int port) diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 959a9ffcbc..15d6c7b356 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -283,6 +283,8 @@ static struct policy_engine { enum sub_state sub; /* VDO */ + + /* PD_VDO_INVALID is used when there is an invalid VDO */ int32_t active_cable_vdo1; int32_t active_cable_vdo2; int32_t passive_cable_vdo; @@ -903,11 +905,11 @@ static void pe_src_startup_entry(int port) print_current_state(port); /* Initialize VDOs to default values */ - pe[port].active_cable_vdo1 = -1; - pe[port].active_cable_vdo2 = -1; - pe[port].passive_cable_vdo = -1; - pe[port].ama_vdo = -1; - pe[port].vpd_vdo = -1; + pe[port].active_cable_vdo1 = PD_VDO_INVALID; + pe[port].active_cable_vdo2 = PD_VDO_INVALID; + pe[port].passive_cable_vdo = PD_VDO_INVALID; + pe[port].ama_vdo = PD_VDO_INVALID; + pe[port].vpd_vdo = PD_VDO_INVALID; /* Reset CapsCounter */ pe[port].caps_counter = 0; @@ -3632,6 +3634,16 @@ static void pe_vdm_request_exit(int port) PE_CLR_FLAG(port, PE_FLAGS_INTERRUPTIBLE_AMS); } +enum idh_ptype get_usb_pd_mux_cable_type(int port) +{ + if (pe[port].passive_cable_vdo != PD_VDO_INVALID) + return IDH_PTYPE_PCABLE; + else if (pe[port].active_cable_vdo1 != PD_VDO_INVALID) + return IDH_PTYPE_ACABLE; + else + return IDH_PTYPE_UNDEF; +} + /** * PE_VDM_Acked */ diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 286fa3a660..b0550fca90 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -1003,10 +1003,19 @@ static const enum typec_mux typec_mux_map[USB_PD_CTRL_MUX_COUNT] = { }; #endif +__overridable uint8_t board_get_dp_pin_mode(int port) +{ + return 0; +} + +/* + * TODO(b/142911453): Move this function to a common/usb_common.c to avoid + * duplicate code + */ static enum ec_status hc_usb_pd_control(struct host_cmd_handler_args *args) { const struct ec_params_usb_pd_control *p = args->params; - struct ec_response_usb_pd_control_v1 *r_v1 = args->response; + struct ec_response_usb_pd_control_v2 *r_v2 = args->response; struct ec_response_usb_pd_control *r = args->response; if (p->port >= CONFIG_USB_PD_PORT_COUNT) @@ -1037,21 +1046,27 @@ static enum ec_status hc_usb_pd_control(struct host_cmd_handler_args *args) pe_dpm_request(p->port, DPM_REQUEST_VCONN_SWAP); #endif - if (args->version == 0) { + switch (args->version) { + case 0: r->enabled = pd_comm_is_enabled(p->port); r->role = tc[p->port].power_role; r->polarity = tc[p->port].polarity; r->state = get_state_tc(p->port); args->response_size = sizeof(*r); - } else { - r_v1->enabled = + break; + case 1: + case 2: + if (sizeof(*r_v2) > args->response_max) + return EC_RES_INVALID_PARAM; + + r_v2->enabled = (pd_comm_is_enabled(p->port) ? PD_CTRL_RESP_ENABLED_COMMS : 0) | (pd_is_connected(p->port) ? PD_CTRL_RESP_ENABLED_CONNECTED : 0) | (TC_CHK_FLAG(p->port, TC_FLAGS_PARTNER_PD_CAPABLE) ? PD_CTRL_RESP_ENABLED_PD_CAPABLE : 0); - r_v1->role = + r_v2->role = (tc[p->port].power_role ? PD_CTRL_RESP_ROLE_POWER : 0) | (tc[p->port].data_role ? PD_CTRL_RESP_ROLE_DATA : 0) | (TC_CHK_FLAG(p->port, TC_FLAGS_VCONN_ON) ? @@ -1064,16 +1079,31 @@ static enum ec_status hc_usb_pd_control(struct host_cmd_handler_args *args) PD_CTRL_RESP_ROLE_USB_COMM : 0) | (TC_CHK_FLAG(p->port, TC_FLAGS_PARTNER_EXTPOWER) ? PD_CTRL_RESP_ROLE_EXT_POWERED : 0); - r_v1->polarity = tc[p->port].polarity; - strzcpy(r_v1->state, tc_state_names[get_state_tc(p->port)], - sizeof(r_v1->state)); - args->response_size = sizeof(*r_v1); + r_v2->polarity = tc[p->port].polarity; + r_v2->cc_state = tc[p->port].cc_state; + r_v2->dp_mode = board_get_dp_pin_mode(p->port); + r_v2->cable_type = get_usb_pd_mux_cable_type(p->port); + + strzcpy(r_v2->state, tc_state_names[get_state_tc(p->port)], + sizeof(r_v2->state)); + if (args->version == 1) { + /* + * ec_response_usb_pd_control_v2 (r_v2) is a + * strict superset of ec_response_usb_pd_control_v1 + */ + args->response_size = + sizeof(struct ec_response_usb_pd_control_v1); + } else + args->response_size = sizeof(*r_v2); + break; + default: + return EC_RES_INVALID_PARAM; } return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_USB_PD_CONTROL, hc_usb_pd_control, - EC_VER_MASK(0) | EC_VER_MASK(1)); + EC_VER_MASK(0) | EC_VER_MASK(1) | EC_VER_MASK(2)); static enum ec_status hc_remote_flash(struct host_cmd_handler_args *args) { @@ -2642,6 +2672,20 @@ void tc_run(const int port) run_state(port, &tc[port].ctx); } +int pd_is_ufp(int port) +{ + /* Returns true if port partner is UFP */ + return tc[port].cc_state == PD_CC_UFP_ATTACHED || + tc[port].cc_state == PD_CC_UFP_DEBUG_ACC || + tc[port].cc_state == PD_CC_UFP_AUDIO_ACC; +} + +int pd_is_debug_acc(int port) +{ + return tc[port].cc_state == PD_CC_UFP_DEBUG_ACC || + tc[port].cc_state == PD_CC_DFP_DEBUG_ACC; +} + /* * Type-C State Hierarchy (Sub-States are listed inside the boxes) * diff --git a/include/usb_pd.h b/include/usb_pd.h index 0608078fe0..f94686f599 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -337,6 +337,8 @@ struct pd_policy { #define VDM_VER10 0 #define VDM_VER20 1 +#define PD_VDO_INVALID -1 + /* * VDM header * ---------- @@ -1789,7 +1791,7 @@ void reset_pd_cable(int port); * @param port USB-C port number * @return cable type */ -uint8_t get_usb_pd_mux_cable_type(int port); +enum idh_ptype get_usb_pd_mux_cable_type(int port); /** * Store Device ID & RW hash of device diff --git a/util/ectool.c b/util/ectool.c index 9942142fa3..32ebe478e9 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -5560,6 +5560,16 @@ int cmd_usb_pd(int argc, char *argv[]) printf("UNKNOWN"); printf("\n"); } + if (r_v2->cable_type) { + printf("Cable type:"); + if (r_v2->cable_type == IDH_PTYPE_ACABLE) + printf("Active"); + else if (r_v2->cable_type == IDH_PTYPE_PCABLE) + printf("Passive"); + else + printf("UNKNOWN"); + printf("\n"); + } } /* If connected to a PD device, then print port partner info */ |