diff options
-rw-r--r-- | common/usb_pd_host_cmd.c | 152 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 215 | ||||
-rw-r--r-- | common/usbc/usb_sm.c | 32 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 158 | ||||
-rw-r--r-- | include/usb_pd.h | 63 | ||||
-rw-r--r-- | test/fake_usbc.c | 66 |
6 files changed, 399 insertions, 287 deletions
diff --git a/common/usb_pd_host_cmd.c b/common/usb_pd_host_cmd.c index 712d6182e7..bb8a1532a7 100644 --- a/common/usb_pd_host_cmd.c +++ b/common/usb_pd_host_cmd.c @@ -11,6 +11,7 @@ #include "ec_commands.h" #include "host_command.h" #include "tcpm.h" +#include "usb_mux.h" #include "usb_pd.h" #include "usb_pd_tcpm.h" @@ -216,6 +217,157 @@ static enum ec_status hc_remote_pd_dev_info(struct host_cmd_handler_args *args) DECLARE_HOST_COMMAND(EC_CMD_USB_PD_DEV_INFO, hc_remote_pd_dev_info, EC_VER_MASK(0)); + +static const enum pd_dual_role_states dual_role_map[USB_PD_CTRL_ROLE_COUNT] = { + [USB_PD_CTRL_ROLE_TOGGLE_ON] = PD_DRP_TOGGLE_ON, + [USB_PD_CTRL_ROLE_TOGGLE_OFF] = PD_DRP_TOGGLE_OFF, + [USB_PD_CTRL_ROLE_FORCE_SINK] = PD_DRP_FORCE_SINK, + [USB_PD_CTRL_ROLE_FORCE_SOURCE] = PD_DRP_FORCE_SOURCE, + [USB_PD_CTRL_ROLE_FREEZE] = PD_DRP_FREEZE, +}; + +static const mux_state_t typec_mux_map[USB_PD_CTRL_MUX_COUNT] = { + [USB_PD_CTRL_MUX_NONE] = USB_PD_MUX_NONE, + [USB_PD_CTRL_MUX_USB] = USB_PD_MUX_USB_ENABLED, + [USB_PD_CTRL_MUX_AUTO] = USB_PD_MUX_DP_ENABLED, + [USB_PD_CTRL_MUX_DP] = USB_PD_MUX_DP_ENABLED, + [USB_PD_CTRL_MUX_DOCK] = USB_PD_MUX_DOCK, +}; + +/* + * Combines the following information into a single byte + * Bit 0: Active/Passive cable + * Bit 1: Optical/Non-optical cable + * Bit 2: Legacy Thunderbolt adapter + * Bit 3: Active Link Uni-Direction/Bi-Direction + */ +static uint8_t get_pd_control_flags(int port) +{ + union tbt_mode_resp_cable cable_resp = get_cable_tbt_vdo(port); + union tbt_mode_resp_device device_resp = get_dev_tbt_vdo(port); + + /* + * Ref: USB Type-C Cable and Connector Specification + * Table F-11 TBT3 Cable Discover Mode VDO Responses + * For Passive cables, Active Cable Plug link training is set to 0 + */ + return (cable_resp.lsrx_comm == UNIDIR_LSRX_COMM ? + USB_PD_CTRL_ACTIVE_LINK_UNIDIR : 0) | + (device_resp.tbt_adapter == TBT_ADAPTER_TBT2_LEGACY ? + USB_PD_CTRL_TBT_LEGACY_ADAPTER : 0) | + (cable_resp.tbt_cable == TBT_CABLE_OPTICAL ? + USB_PD_CTRL_OPTICAL_CABLE : 0) | + (cable_resp.retimer_type == USB_RETIMER ? + USB_PD_CTRL_ACTIVE_CABLE : 0); +} + +static uint8_t pd_get_role_flags(int port) +{ + return (pd_get_power_role(port) == PD_ROLE_SOURCE ? + PD_CTRL_RESP_ROLE_POWER : 0) | + (pd_get_data_role(port) == PD_ROLE_DFP ? + PD_CTRL_RESP_ROLE_DATA : 0) | + (pd_get_vconn_state(port) ? + PD_CTRL_RESP_ROLE_VCONN : 0) | + (pd_get_partner_dual_role_power(port) ? + PD_CTRL_RESP_ROLE_DR_POWER : 0) | + (pd_get_partner_data_swap_capable(port) ? + PD_CTRL_RESP_ROLE_DR_DATA : 0) | + (pd_get_partner_usb_comm_capable(port) ? + PD_CTRL_RESP_ROLE_USB_COMM : 0) | + (pd_get_partner_unconstr_power(port) ? + PD_CTRL_RESP_ROLE_UNCONSTRAINED : 0); +} + +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_v2 *r_v2 = args->response; + struct ec_response_usb_pd_control_v1 *r_v1 = args->response; + struct ec_response_usb_pd_control *r = args->response; + const char *task_state_name; + + if (p->port >= board_get_usb_pd_port_count()) + return EC_RES_INVALID_PARAM; + + if (p->role >= USB_PD_CTRL_ROLE_COUNT || + p->mux >= USB_PD_CTRL_MUX_COUNT) + return EC_RES_INVALID_PARAM; + + if (p->role != USB_PD_CTRL_ROLE_NO_CHANGE) { + if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE)) + pd_set_dual_role(p->port, dual_role_map[p->role]); + else + return EC_RES_INVALID_PARAM; + } + + if (IS_ENABLED(CONFIG_USBC_SS_MUX) && + p->mux != USB_PD_CTRL_MUX_NO_CHANGE) + usb_mux_set(p->port, typec_mux_map[p->mux], + typec_mux_map[p->mux] == USB_PD_MUX_NONE ? + USB_SWITCH_DISCONNECT : + USB_SWITCH_CONNECT, + pd_get_polarity(p->port)); + + if (p->swap == USB_PD_CTRL_SWAP_DATA) { + pd_request_data_swap(p->port); + } else if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE)) { + if (p->swap == USB_PD_CTRL_SWAP_POWER) + pd_request_power_swap(p->port); + else if (IS_ENABLED(CONFIG_USBC_VCONN_SWAP) && + p->swap == USB_PD_CTRL_SWAP_VCONN) + pd_request_vconn_swap(p->port); + } + + switch (args->version) { + case 0: + r->enabled = pd_comm_is_enabled(p->port); + r->polarity = pd_get_polarity(p->port); + r->role = pd_get_power_role(p->port); + r->state = pd_get_task_state(p->port); + args->response_size = sizeof(*r); + break; + case 1: + case 2: + 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) | + (pd_capable(p->port) ? + PD_CTRL_RESP_ENABLED_PD_CAPABLE : 0); + r_v2->role = pd_get_role_flags(p->port); + r_v2->polarity = pd_get_polarity(p->port); + + r_v2->cc_state = pd_get_task_cc_state(p->port); + task_state_name = pd_get_task_state_name(p->port); + if (task_state_name) + strzcpy(r_v2->state, task_state_name, + sizeof(r_v2->state)); + else + r_v2->state[0] = '\0'; + + if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) + r_v2->dp_mode = get_dp_pin_mode(p->port); + + r_v2->control_flags = get_pd_control_flags(p->port); + r_v2->cable_speed = get_tbt_cable_speed(p->port); + r_v2->cable_gen = get_tbt_rounded_support(p->port); + + if (args->version == 1) + args->response_size = sizeof(*r_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(2)); #endif /* CONFIG_COMMON_RUNTIME */ __overridable enum ec_pd_port_location board_get_pd_port_location(int port) diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 97aeb3eb2c..1a4093d32a 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -358,9 +358,9 @@ int pd_ts_dts_plugged(int port) } /* Return true if partner port is known to be PD capable. */ -int pd_capable(int port) +bool pd_capable(int port) { - return pd[port].flags & PD_FLAGS_PREVIOUS_PD_CONN; + return !!(pd[port].flags & PD_FLAGS_PREVIOUS_PD_CONN); } /* @@ -1709,7 +1709,7 @@ void pd_request_power_swap(int port) } #ifdef CONFIG_USBC_VCONN_SWAP -static void pd_request_vconn_swap(int port) +void pd_request_vconn_swap(int port) { if (pd[port].task_state == PD_STATE_SRC_READY || pd[port].task_state == PD_STATE_SNK_READY) @@ -2509,16 +2509,6 @@ static void pd_update_dual_role_config(int port) } } -enum pd_power_role pd_get_power_role(int port) -{ - return pd[port].power_role; -} - -enum pd_data_role pd_get_data_role(int port) -{ - return pd[port].data_role; -} - static int pd_is_power_swapping(int port) { /* return true if in the act of swapping power roles */ @@ -2581,15 +2571,59 @@ static void pd_partner_port_reset(int port) } #endif /* CONFIG_USB_PD_DUAL_ROLE */ +enum pd_power_role pd_get_power_role(int port) +{ + return pd[port].power_role; +} + +enum pd_data_role pd_get_data_role(int port) +{ + return pd[port].data_role; +} + +enum pd_cc_states pd_get_task_cc_state(int port) +{ + return pd[port].cc_state; +} + +uint8_t pd_get_task_state(int port) +{ + return pd[port].task_state; +} + +const char *pd_get_task_state_name(int port) +{ +#ifdef CONFIG_COMMON_RUNTIME + if (debug_level > 0) + return pd_state_names[pd[port].task_state]; +#endif + return NULL; +} + +bool pd_get_vconn_state(int port) +{ + return !!(pd[port].flags & PD_FLAGS_VCONN_ON); +} + +bool pd_get_partner_dual_role_power(int port) +{ + return !!(pd[port].flags & PD_FLAGS_PARTNER_DR_POWER); +} + +bool pd_get_partner_unconstr_power(int port) +{ + return !!(pd[port].flags & PD_FLAGS_PARTNER_UNCONSTR); +} + enum tcpc_cc_polarity pd_get_polarity(int port) { return pd[port].polarity; } -int pd_get_partner_data_swap_capable(int port) +bool pd_get_partner_data_swap_capable(int port) { /* return data swap capable status of port partner */ - return pd[port].flags & PD_FLAGS_PARTNER_DR_DATA; + return !!(pd[port].flags & PD_FLAGS_PARTNER_DR_DATA); } #ifdef CONFIG_COMMON_RUNTIME @@ -5336,157 +5370,6 @@ DECLARE_CONSOLE_COMMAND(pd, command_pd, #ifdef HAS_TASK_HOSTCMD -#ifdef CONFIG_USB_PD_DUAL_ROLE -static const enum pd_dual_role_states dual_role_map[USB_PD_CTRL_ROLE_COUNT] = { - [USB_PD_CTRL_ROLE_TOGGLE_ON] = PD_DRP_TOGGLE_ON, - [USB_PD_CTRL_ROLE_TOGGLE_OFF] = PD_DRP_TOGGLE_OFF, - [USB_PD_CTRL_ROLE_FORCE_SINK] = PD_DRP_FORCE_SINK, - [USB_PD_CTRL_ROLE_FORCE_SOURCE] = PD_DRP_FORCE_SOURCE, - [USB_PD_CTRL_ROLE_FREEZE] = PD_DRP_FREEZE, -}; -#endif - -#ifdef CONFIG_USBC_SS_MUX -static const mux_state_t typec_mux_map[USB_PD_CTRL_MUX_COUNT] = { - [USB_PD_CTRL_MUX_NONE] = USB_PD_MUX_NONE, - [USB_PD_CTRL_MUX_USB] = USB_PD_MUX_USB_ENABLED, - [USB_PD_CTRL_MUX_AUTO] = USB_PD_MUX_DP_ENABLED, - [USB_PD_CTRL_MUX_DP] = USB_PD_MUX_DP_ENABLED, - [USB_PD_CTRL_MUX_DOCK] = USB_PD_MUX_DOCK, -}; -#endif - -/* - * Combines the following information into a single byte - * Bit 0: Active/Passive cable - * Bit 1: Optical/Non-optical cable - * Bit 2: Legacy Thunderbolt adapter - * Bit 3: Active Link Uni-Direction/Bi-Direction - */ -static uint8_t get_pd_control_flags(int port) -{ - union tbt_mode_resp_cable cable_resp = get_cable_tbt_vdo(port); - union tbt_mode_resp_device device_resp = get_dev_tbt_vdo(port); - - /* - * Ref: USB Type-C Cable and Connector Specification - * Table F-11 TBT3 Cable Discover Mode VDO Responses - * For Passive cables, Active Cable Plug link training is set to 0 - */ - return (cable_resp.lsrx_comm == UNIDIR_LSRX_COMM ? - USB_PD_CTRL_ACTIVE_LINK_UNIDIR : 0) | - (device_resp.tbt_adapter == TBT_ADAPTER_TBT2_LEGACY ? - USB_PD_CTRL_TBT_LEGACY_ADAPTER : 0) | - (cable_resp.tbt_cable == TBT_CABLE_OPTICAL ? - USB_PD_CTRL_OPTICAL_CABLE : 0) | - (cable_resp.retimer_type == USB_RETIMER ? - USB_PD_CTRL_ACTIVE_CABLE : 0); -} - -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_v2 *r_v2 = args->response; - struct ec_response_usb_pd_control_v1 *r_v1 = args->response; - struct ec_response_usb_pd_control *r = args->response; - - if (p->port >= board_get_usb_pd_port_count()) - return EC_RES_INVALID_PARAM; - - if (p->role >= USB_PD_CTRL_ROLE_COUNT || - p->mux >= USB_PD_CTRL_MUX_COUNT) - return EC_RES_INVALID_PARAM; - - if (p->role != USB_PD_CTRL_ROLE_NO_CHANGE) -#ifdef CONFIG_USB_PD_DUAL_ROLE - pd_set_dual_role(p->port, dual_role_map[p->role]); -#else - return EC_RES_INVALID_PARAM; -#endif - -#ifdef CONFIG_USBC_SS_MUX - if (p->mux != USB_PD_CTRL_MUX_NO_CHANGE) - usb_mux_set(p->port, typec_mux_map[p->mux], - typec_mux_map[p->mux] == USB_PD_MUX_NONE ? - USB_SWITCH_DISCONNECT : - USB_SWITCH_CONNECT, - pd_get_polarity(p->port)); -#endif /* CONFIG_USBC_SS_MUX */ - - if (p->swap == USB_PD_CTRL_SWAP_DATA) - pd_request_data_swap(p->port); -#ifdef CONFIG_USB_PD_DUAL_ROLE - else if (p->swap == USB_PD_CTRL_SWAP_POWER) - pd_request_power_swap(p->port); -#ifdef CONFIG_USBC_VCONN_SWAP - else if (p->swap == USB_PD_CTRL_SWAP_VCONN) - pd_request_vconn_swap(p->port); -#endif -#endif - - switch (args->version) { - case 0: - r->enabled = pd_comm_is_enabled(p->port); - r->role = pd[p->port].power_role; - r->polarity = pd[p->port].polarity; - r->state = pd[p->port].task_state; - args->response_size = sizeof(*r); - break; - case 1: - case 2: - 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) | - ((pd[p->port].flags & PD_FLAGS_PREVIOUS_PD_CONN) ? - PD_CTRL_RESP_ENABLED_PD_CAPABLE : 0); - r_v2->role = - (pd[p->port].power_role ? PD_CTRL_RESP_ROLE_POWER : 0) | - (pd[p->port].data_role ? PD_CTRL_RESP_ROLE_DATA : 0) | - ((pd[p->port].flags & PD_FLAGS_VCONN_ON) ? - PD_CTRL_RESP_ROLE_VCONN : 0) | - ((pd[p->port].flags & PD_FLAGS_PARTNER_DR_POWER) ? - PD_CTRL_RESP_ROLE_DR_POWER : 0) | - ((pd[p->port].flags & PD_FLAGS_PARTNER_DR_DATA) ? - PD_CTRL_RESP_ROLE_DR_DATA : 0) | - ((pd[p->port].flags & PD_FLAGS_PARTNER_USB_COMM) ? - PD_CTRL_RESP_ROLE_USB_COMM : 0) | - ((pd[p->port].flags & PD_FLAGS_PARTNER_UNCONSTR) ? - PD_CTRL_RESP_ROLE_UNCONSTRAINED : 0); - r_v2->polarity = pd[p->port].polarity; - - if (debug_level > 0) - strzcpy(r_v2->state, - pd_state_names[pd[p->port].task_state], - sizeof(r_v2->state)); - else - r_v2->state[0] = '\0'; - - r_v2->cc_state = pd[p->port].cc_state; - - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) - r_v2->dp_mode = get_dp_pin_mode(p->port); - - r_v2->control_flags = get_pd_control_flags(p->port); - r_v2->cable_speed = get_tbt_cable_speed(p->port); - r_v2->cable_gen = get_tbt_rounded_support(p->port); - - if (args->version == 1) - args->response_size = sizeof(*r_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(2)); - #ifdef CONFIG_HOSTCMD_FLASHPD static enum ec_status hc_remote_flash(struct host_cmd_handler_args *args) { diff --git a/common/usbc/usb_sm.c b/common/usbc/usb_sm.c index bb5c923dec..800181f7b2 100644 --- a/common/usbc/usb_sm.c +++ b/common/usbc/usb_sm.c @@ -192,3 +192,35 @@ void run_state(const int port, struct sm_ctx *const ctx) internal->running = false; } +/* TODO (b/148528713): Need to enable Thunderbolt-compatible mode on TCPMv2 */ +union tbt_mode_resp_cable get_cable_tbt_vdo(int port) +{ + union tbt_mode_resp_cable cable_resp = { + .raw_value = 0, + }; + + return cable_resp; +} + +union tbt_mode_resp_device get_dev_tbt_vdo(int port) +{ + union tbt_mode_resp_device dev_resp = { + .raw_value = 0, + }; + + return dev_resp; +} + +enum tbt_compat_cable_speed get_tbt_cable_speed(int port) +{ + enum tbt_compat_cable_speed cable_speed = 0; + + return cable_speed; +} + +enum tbt_compat_rounded_support get_tbt_rounded_support(int port) +{ + enum tbt_compat_rounded_support tbt_round = 0; + + return tbt_round; +} diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index c4049451fc..698aca248e 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -394,10 +394,10 @@ void pd_set_dual_role(int port, enum pd_dual_role_states state) } #ifdef CONFIG_USB_PE_SM -int pd_get_partner_data_swap_capable(int port) +bool pd_get_partner_data_swap_capable(int port) { /* return data swap capable status of port partner */ - return TC_CHK_FLAG(port, TC_FLAGS_PARTNER_DR_DATA); + return !!TC_CHK_FLAG(port, TC_FLAGS_PARTNER_DR_DATA); } int pd_comm_is_enabled(int port) @@ -434,9 +434,9 @@ int pd_ts_dts_plugged(int port) } /* Return true if partner port is known to be PD capable. */ -int pd_capable(int port) +bool pd_capable(int port) { - return TC_CHK_FLAG(port, TC_FLAGS_PARTNER_PD_CAPABLE); + return !!TC_CHK_FLAG(port, TC_FLAGS_PARTNER_PD_CAPABLE); } /* @@ -670,6 +670,36 @@ enum pd_power_role pd_get_power_role(int port) return tc[port].power_role; } +enum pd_cc_states pd_get_task_cc_state(int port) +{ + return tc[port].cc_state; +} + +uint8_t pd_get_task_state(int port) +{ + return get_state_tc(port); +} + +bool pd_get_vconn_state(int port) +{ + return !!TC_CHK_FLAG(port, TC_FLAGS_VCONN_ON); +} + +bool pd_get_partner_dual_role_power(int port) +{ + return !!TC_CHK_FLAG(port, TC_FLAGS_PARTNER_DR_POWER); +} + +bool pd_get_partner_unconstr_power(int port) +{ + return !!TC_CHK_FLAG(port, TC_FLAGS_PARTNER_UNCONSTRAINED); +} + +const char *pd_get_task_state_name(int port) +{ + return tc_state_names[get_state_tc(port)]; +} + int pd_is_vbus_present(int port) { if (IS_ENABLED(CONFIG_USB_PD_VBUS_DETECT_TCPC)) @@ -1182,121 +1212,6 @@ static void handle_new_power_state(int port) * HOST COMMANDS */ #ifdef HAS_TASK_HOSTCMD -static const enum pd_dual_role_states dual_role_map[USB_PD_CTRL_ROLE_COUNT] = { - [USB_PD_CTRL_ROLE_TOGGLE_ON] = PD_DRP_TOGGLE_ON, - [USB_PD_CTRL_ROLE_TOGGLE_OFF] = PD_DRP_TOGGLE_OFF, - [USB_PD_CTRL_ROLE_FORCE_SINK] = PD_DRP_FORCE_SINK, - [USB_PD_CTRL_ROLE_FORCE_SOURCE] = PD_DRP_FORCE_SOURCE, - [USB_PD_CTRL_ROLE_FREEZE] = PD_DRP_FREEZE, -}; - -#ifdef CONFIG_USBC_SS_MUX -static const mux_state_t typec_mux_map[USB_PD_CTRL_MUX_COUNT] = { - [USB_PD_CTRL_MUX_NONE] = USB_PD_MUX_NONE, - [USB_PD_CTRL_MUX_USB] = USB_PD_MUX_USB_ENABLED, - [USB_PD_CTRL_MUX_AUTO] = USB_PD_MUX_DP_ENABLED, - [USB_PD_CTRL_MUX_DP] = USB_PD_MUX_DP_ENABLED, - [USB_PD_CTRL_MUX_DOCK] = USB_PD_MUX_DOCK, -}; -#endif - -/* - * 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_v2 *r_v2 = args->response; - struct ec_response_usb_pd_control *r = args->response; - - if (p->port >= board_get_usb_pd_port_count()) - return EC_RES_INVALID_PARAM; - - if (p->role >= USB_PD_CTRL_ROLE_COUNT || - p->mux >= USB_PD_CTRL_MUX_COUNT) - return EC_RES_INVALID_PARAM; - - if (p->role != USB_PD_CTRL_ROLE_NO_CHANGE) - pd_set_dual_role(p->port, dual_role_map[p->role]); - -#ifdef CONFIG_USBC_SS_MUX - if (p->mux != USB_PD_CTRL_MUX_NO_CHANGE) - usb_mux_set(p->port, typec_mux_map[p->mux], - typec_mux_map[p->mux] == USB_PD_MUX_NONE ? - USB_SWITCH_DISCONNECT : - USB_SWITCH_CONNECT, - pd_get_polarity(p->port)); -#endif /* CONFIG_USBC_SS_MUX */ - - if (p->swap == USB_PD_CTRL_SWAP_DATA) - pd_request_data_swap(p->port); - else if (p->swap == USB_PD_CTRL_SWAP_POWER) - pd_request_power_swap(p->port); -#ifdef CONFIG_USBC_VCONN_SWAP - else if (p->swap == USB_PD_CTRL_SWAP_VCONN) - pe_dpm_request(p->port, DPM_REQUEST_VCONN_SWAP); -#endif - - 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); - 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_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) ? - PD_CTRL_RESP_ROLE_VCONN : 0) | - (TC_CHK_FLAG(p->port, TC_FLAGS_PARTNER_DR_POWER) ? - PD_CTRL_RESP_ROLE_DR_POWER : 0) | - (TC_CHK_FLAG(p->port, TC_FLAGS_PARTNER_DR_DATA) ? - PD_CTRL_RESP_ROLE_DR_DATA : 0) | - (TC_CHK_FLAG(p->port, TC_FLAGS_PARTNER_USB_COMM) ? - PD_CTRL_RESP_ROLE_USB_COMM : 0) | - (TC_CHK_FLAG(p->port, TC_FLAGS_PARTNER_UNCONSTRAINED) ? - PD_CTRL_RESP_ROLE_UNCONSTRAINED : 0); - r_v2->polarity = tc[p->port].polarity; - r_v2->cc_state = tc[p->port].cc_state; - - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) - r_v2->dp_mode = get_dp_pin_mode(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(2)); static enum ec_status hc_remote_flash(struct host_cmd_handler_args *args) { @@ -1428,6 +1343,11 @@ void pd_request_vconn_swap_on(int port) task_wake(PD_PORT_TO_TASK_ID(port)); } } + +void pd_request_vconn_swap(int port) +{ + pe_dpm_request(port, DPM_REQUEST_VCONN_SWAP); +} #endif #ifdef CONFIG_USBC_VCONN diff --git a/include/usb_pd.h b/include/usb_pd.h index 994ffb9422..59b293fe15 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -923,6 +923,63 @@ enum pd_data_role pd_get_data_role(int port); */ enum pd_power_role pd_get_power_role(int port); +/** + * Request for VCONN swap + * + * @param port USB-C Port number + */ +void pd_request_vconn_swap(int port); + +/** + * Get the current CC line states from PD task + * + * @param port USB-C Port number + * @return CC state + */ +enum pd_cc_states pd_get_task_cc_state(int port); + +/** + * Get the current PD state of USB-C port + * + * @param port USB-C Port number + * @return PD state + * Note: TCPMv1 returns enum pd_states + * TCPMv2 returns enum usb_tc_state + */ +uint8_t pd_get_task_state(int port); + +/** + * Get the current PD state name of USB-C port + * + * @param port USB-C Port number + * @return Pointer to PD state name + */ +const char *pd_get_task_state_name(int port); + +/** + * Get current VCONN state of USB-C port + * + * @param port USB-C Port number + * @return true if VCONN is on else false + */ +bool pd_get_vconn_state(int port); + +/** + * Check if port partner is dual role power + * + * @param port USB-C Port number + * @return true if partner is dual role power else false + */ +bool pd_get_partner_dual_role_power(int port); + +/** + * Check if port partner is unconstrained power + * + * @param port USB-C Port number + * @return true if partner is unconstrained power else false + */ +bool pd_get_partner_unconstr_power(int port); + /* Control Message type */ enum pd_ctrl_msg_type { /* 0 Reserved */ @@ -2075,8 +2132,9 @@ enum tcpc_cc_polarity pd_get_polarity(int port); * Get port partner data swap capable status * * @param port USB-C port number + * @return True if data swap capable else false */ -int pd_get_partner_data_swap_capable(int port); +bool pd_get_partner_data_swap_capable(int port); /** * Handle an overcurrent protection event. The port acting as a source has @@ -2160,8 +2218,9 @@ int pd_ts_dts_plugged(int port); * Return true if partner port is known to be PD capable. * * @param port USB-C port number + * @return true if PD capable else false */ -int pd_capable(int port); +bool pd_capable(int port); /** * Returns the source caps list diff --git a/test/fake_usbc.c b/test/fake_usbc.c index 2ee1791717..36e0d7ca48 100644 --- a/test/fake_usbc.c +++ b/test/fake_usbc.c @@ -142,9 +142,75 @@ void pd_dev_get_rw_hash(int port, uint16_t *dev_id, uint8_t *rw_hash, { } +int pd_comm_is_enabled(int port) +{ + return 0; +} + +bool pd_get_partner_data_swap_capable(int port) +{ + return true; +} + +bool pd_capable(int port) +{ + return true; +} + +#ifndef CONFIG_TEST_USB_PE_SM +enum idh_ptype get_usb_pd_mux_cable_type(int port) +{ + return IDH_PTYPE_UNDEF; +} +#endif + #ifndef CONFIG_USB_TYPEC_DRP_ACC_TRYSRC bool pd_is_disconnected(int port) { return false; } + +void pd_set_dual_role(int port, enum pd_dual_role_states state) +{ +} + +enum tcpc_cc_polarity pd_get_polarity(int port) +{ + return POLARITY_CC1; +} + +bool pd_get_vconn_state(int port) +{ + return false; +} + +bool pd_get_partner_dual_role_power(int port) +{ + return false; +} + +uint8_t pd_get_task_state(int port) +{ + return 0; +} + +enum pd_cc_states pd_get_task_cc_state(int port) +{ + return PD_CC_NONE; +} + +int pd_is_connected(int port) +{ + return true; +} + +bool pd_get_partner_unconstr_power(int port) +{ + return 0; +} + +const char *pd_get_task_state_name(int port) +{ + return NULL; +} #endif /* CONFIG_USB_TYPEC_DRP_ACC_TRYSRC */ |