diff options
-rw-r--r-- | common/mock/usb_tc_sm_mock.c | 5 | ||||
-rw-r--r-- | common/usb_common.c | 9 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 9 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 10 | ||||
-rw-r--r-- | include/usb_pd.h | 10 | ||||
-rw-r--r-- | test/fake_usbc.c | 5 |
6 files changed, 47 insertions, 1 deletions
diff --git a/common/mock/usb_tc_sm_mock.c b/common/mock/usb_tc_sm_mock.c index 259170d6bf..f2c2ecf5c8 100644 --- a/common/mock/usb_tc_sm_mock.c +++ b/common/mock/usb_tc_sm_mock.c @@ -181,6 +181,11 @@ bool pd_capable(int port) return true; } +bool pd_waiting_on_partner_src_caps(int port) +{ + return false; +} + void pd_set_suspend(int port, int suspend) { } diff --git a/common/usb_common.c b/common/usb_common.c index 4f9e17fa4f..dc8fb21e0a 100644 --- a/common/usb_common.c +++ b/common/usb_common.c @@ -481,10 +481,17 @@ mux_state_t get_mux_mode_to_set(int port) /* * If the power role is sink and the PD partner device is not capable * of USB communication then disconnect. + * + * On an entry into Unattached.SNK, the partner may be PD capable but + * hasn't yet sent source capabilities. In this case, hold off enabling + * USB3 termination until the PD capability is resolved. + * + * TODO(b/188588458): TCPMv2: Delay enabling USB3 termination when USB4 + * is supported. */ if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE) && pd_get_power_role(port) == PD_ROLE_SINK && - pd_capable(port) && + (pd_capable(port) || pd_waiting_on_partner_src_caps(port)) && !pd_get_partner_usb_comm_capable(port)) return USB_PD_MUX_NONE; diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 13e6c7842f..6a72d8e62a 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -399,6 +399,15 @@ bool pd_capable(int port) } /* + * For TCPMv1, this routine always returns false so that the USB3 signals + * are connected without delay when the initial connection is UFP. + */ +bool pd_waiting_on_partner_src_caps(int port) +{ + return false; +} + +/* * Return true if partner port is capable of communication over USB data * lines. */ diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index b15918b1bc..554cf5129b 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -765,6 +765,16 @@ bool pd_capable(int port) return !!TC_CHK_FLAG(port, TC_FLAGS_PARTNER_PD_CAPABLE); } +/* + * Return true if we transition through Unattached.SNK, but we're still waiting + * to receive source caps from the partner. This indicates that the PD + * capabilities are not yet known. + */ +bool pd_waiting_on_partner_src_caps(int port) +{ + return !pd_get_src_cap_cnt(port); +} + enum pd_dual_role_states pd_get_dual_role(int port) { return drp_state[port]; diff --git a/include/usb_pd.h b/include/usb_pd.h index ba29e04c86..cc85cbf2c2 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -2910,6 +2910,16 @@ void pd_set_new_power_request(int port); bool pd_capable(int port); /** + * Return true if we transition through Unattached.SNK, but we're still waiting + * to receive source caps from the partner. This indicates that the PD + * capabilities are not yet known. + * + * @param port USB-C port number + * @return true if partner is SRC, but PD capability not known + */ +bool pd_waiting_on_partner_src_caps(int port); + +/** * Returns the source caps list * * @param port USB-C port number diff --git a/test/fake_usbc.c b/test/fake_usbc.c index b744007a66..dc27c0e941 100644 --- a/test/fake_usbc.c +++ b/test/fake_usbc.c @@ -166,6 +166,11 @@ bool pd_capable(int port) return true; } +bool pd_waiting_on_partner_src_caps(int port) +{ + return false; +} + #ifndef CONFIG_TEST_USB_PE_SM enum idh_ptype get_usb_pd_mux_cable_type(int port) { |