diff options
-rw-r--r-- | common/usb_pd_protocol.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index efa196925e..04b3b5223b 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1243,6 +1243,15 @@ static void handle_vdm_request(int port, int cnt, uint32_t *payload) port, PD_VDO_VID(payload[0]), payload[0] & 0xFFFF); } +static __maybe_unused int pd_is_disconnected(int port) +{ + return pd[port].task_state == PD_STATE_SRC_DISCONNECTED +#ifdef CONFIG_USB_PD_DUAL_ROLE + || pd[port].task_state == PD_STATE_SNK_DISCONNECTED +#endif + ; +} + static void set_usb_mux_with_current_data_role(int port) { #ifdef CONFIG_USBC_SS_MUX @@ -1258,21 +1267,29 @@ static void set_usb_mux_with_current_data_role(int port) } #endif /* CONFIG_POWER_COMMON */ -#ifdef CONFIG_USBC_SS_MUX_DFP_ONLY /* - * Need to connect SS mux for if new data role is DFP. - * If new data role is UFP, then disconnect the SS mux. + * When PD stack is disconnected, then mux should be disconnected, which + * is also what happens in the set_state disconnection code. Once the + * PD state machine progresses out of disconnect, the MUX state will + * be set correctly again. */ - if (pd[port].data_role == PD_ROLE_DFP) - usb_mux_set(port, TYPEC_MUX_USB, USB_SWITCH_CONNECT, + if (pd_is_disconnected(port)) + usb_mux_set(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, pd[port].polarity); - else + /* + * If new data role isn't DFP and we only support DFP, also disconnect. + */ + else if (IS_ENABLED(CONFIG_USBC_SS_MUX_DFP_ONLY) && + pd[port].data_role != PD_ROLE_DFP) usb_mux_set(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, pd[port].polarity); -#else - usb_mux_set(port, TYPEC_MUX_USB, USB_SWITCH_CONNECT, - pd[port].polarity); -#endif /* CONFIG_USBC_SS_MUX_DFP_ONLY */ + /* + * Otherwise connect mux since we are in S3+ + */ + else + usb_mux_set(port, TYPEC_MUX_USB, USB_SWITCH_CONNECT, + pd[port].polarity); + #endif /* CONFIG_USBC_SS_MUX */ } |