summaryrefslogtreecommitdiff
path: root/common/usbc/tbt_alt_mode.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usbc/tbt_alt_mode.c')
-rw-r--r--common/usbc/tbt_alt_mode.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/common/usbc/tbt_alt_mode.c b/common/usbc/tbt_alt_mode.c
index 1319263e74..0785376355 100644
--- a/common/usbc/tbt_alt_mode.c
+++ b/common/usbc/tbt_alt_mode.c
@@ -69,8 +69,9 @@
* with a partner. It may be fixed in b/159495742, in which case this
* logic is unneeded.
*/
-#define TBT_FLAG_RETRY_DONE BIT(0)
-#define TBT_FLAG_EXIT_DONE BIT(1)
+#define TBT_FLAG_RETRY_DONE BIT(0)
+#define TBT_FLAG_EXIT_DONE BIT(1)
+#define TBT_FLAG_CABLE_ENTRY_DONE BIT(2)
static uint8_t tbt_flags[CONFIG_USB_PD_PORT_MAX_COUNT];
@@ -115,6 +116,7 @@ void tbt_init(int port)
tbt_state[port] = TBT_START;
TBT_CLR_FLAG(port, TBT_FLAG_RETRY_DONE);
TBT_SET_FLAG(port, TBT_FLAG_EXIT_DONE);
+ TBT_CLR_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
}
bool tbt_is_active(int port)
@@ -129,10 +131,16 @@ bool tbt_entry_is_done(int port)
tbt_state[port] == TBT_INACTIVE;
}
+bool tbt_cable_entry_is_done(int port)
+{
+ return TBT_CHK_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
+}
+
static void tbt_exit_done(int port)
{
tbt_state[port] = TBT_INACTIVE;
TBT_CLR_FLAG(port, TBT_FLAG_RETRY_DONE);
+ TBT_CLR_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
if (!TBT_CHK_FLAG(port, TBT_FLAG_EXIT_DONE)) {
TBT_SET_FLAG(port, TBT_FLAG_EXIT_DONE);
@@ -147,6 +155,14 @@ void tbt_exit_mode_request(int port)
{
TBT_SET_FLAG(port, TBT_FLAG_RETRY_DONE);
TBT_CLR_FLAG(port, TBT_FLAG_EXIT_DONE);
+ /*
+ * If the port has entered USB4 mode with Thunderbolt mode for the
+ * cable, on request to exit, only exit Thunderbolt mode for the
+ * cable.
+ * TODO (b/156749387): Remove once data reset feature is in place.
+ */
+ if (tbt_state[port] == TBT_ENTER_SOP)
+ tbt_state[port] = TBT_EXIT_SOP_PRIME_PRIME;
}
static bool tbt_response_valid(int port, enum tcpm_transmit_type type,
@@ -203,12 +219,15 @@ void intel_vdm_acked(int port, enum tcpm_transmit_type type, int vdo_count,
switch (tbt_state[port]) {
case TBT_ENTER_SOP_PRIME:
- if (disc->identity.product_t1.a_rev20.sop_p_p)
+ if (disc->identity.product_t1.a_rev20.sop_p_p) {
tbt_state[port] = TBT_ENTER_SOP_PRIME_PRIME;
- else
+ } else {
+ TBT_SET_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
tbt_state[port] = TBT_ENTER_SOP;
+ }
break;
case TBT_ENTER_SOP_PRIME_PRIME:
+ TBT_SET_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
tbt_state[port] = TBT_ENTER_SOP;
break;
case TBT_ENTER_SOP:
@@ -315,6 +334,7 @@ void intel_vdm_naked(int port, enum tcpm_transmit_type type, uint8_t vdm_cmd)
break;
case TBT_EXIT_SOP:
/* Exit SOP got NAK'ed */
+ tbt_prints("exit mode SOP failed", port);
set_usb_mux_with_current_data_role(port);
if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE)
tbt_active_cable_exit_mode(port);