[PATCH v1] usb: typec: tcpm: Fix TDA 2.2.1.1 and TDA 2.2.1.2 failures

From: Badhri Jagan Sridharan
Date: Mon Aug 10 2020 - 21:11:33 EST


>From the spec:
"7.1.5 Response to Hard Resets
Hard Reset Signaling indicates a communication failure has occurred and
the Source Shall stop driving VCONN, Shall remove Rp from the VCONN pin
and Shall drive VBUS to vSafe0V as shown in Figure 7-9. The USB connection
May reset during a Hard Reset since the VBUS voltage will be less than
vSafe5V for an extended period of time. After establishing the vSafe0V
voltage condition on VBUS, the Source Shall wait tSrcRecover before
re-applying VCONN and restoring VBUS to vSafe5V. A Source Shall conform
to the VCONN timing as specified in [USB Type-C 1.3]."

Signed-off-by: Badhri Jagan Sridharan <badhri@xxxxxxxxxx>
---
drivers/usb/typec/tcpm/tcpm.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 3ef37202ee37..e41c4e5d3c71 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -3372,13 +3372,19 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_state(port, SNK_HARD_RESET_SINK_OFF, 0);
break;
case SRC_HARD_RESET_VBUS_OFF:
- tcpm_set_vconn(port, true);
+ /*
+ * 7.1.5 Response to Hard Resets
+ * Hard Reset Signaling indicates a communication failure has occurred and the
+ * Source Shall stop driving VCONN, Shall remove Rp from the VCONN pin and Shall
+ * drive VBUS to vSafe0V as shown in Figure 7-9.
+ */
+ tcpm_set_vconn(port, false);
tcpm_set_vbus(port, false);
tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
tcpm_data_role_for_source(port));
- tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
break;
case SRC_HARD_RESET_VBUS_ON:
+ tcpm_set_vconn(port, true);
tcpm_set_vbus(port, true);
port->tcpc->set_pd_rx(port->tcpc, true);
tcpm_set_attached_state(port, true);
@@ -3944,7 +3950,11 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
tcpm_set_state(port, SNK_HARD_RESET_WAIT_VBUS, 0);
break;
case SRC_HARD_RESET_VBUS_OFF:
- tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, 0);
+ /*
+ * After establishing the vSafe0V voltage condition on VBUS, the Source Shall wait
+ * tSrcRecover before re-applying VCONN and restoring VBUS to vSafe5V.
+ */
+ tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
break;
case HARD_RESET_SEND:
break;
--
2.28.0.236.gb10cc79966-goog