summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/mock/usb_tc_sm_mock.c5
-rw-r--r--common/usb_common.c9
-rw-r--r--common/usb_pd_protocol.c9
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c10
-rw-r--r--include/usb_pd.h10
-rw-r--r--test/fake_usbc.c5
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)
{