summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbe Levkoy <alevkoy@chromium.org>2020-05-19 11:00:39 -0600
committerCommit Bot <commit-bot@chromium.org>2020-05-29 00:05:11 +0000
commitfda7ea9671ce6b7d7d1bdc47ef3dbfd8cbffd971 (patch)
tree884dcac0411c7f5680ecdb6e30114923020687fa
parenta09f762f948e05c45d980cb4e216c748bda42369 (diff)
downloadchrome-ec-fda7ea9671ce6b7d7d1bdc47ef3dbfd8cbffd971.tar.gz
tusb422: Enable ADD before setting CC
Enable AutoDischargeDisconnect before setting CC lines. Unless ADD is enabled, TUSB422 will not enter active mode, and CC ADC comparators will be disabled. Disable internal VBUS discharge to avoid side effects from this non-standard behavior. BUG=b:156110530 TEST=Detach external VBUS source from attached dongle; observe EC port TEST=switch from sink to source. BRANCH=none Change-Id: Icd39334c6a43016970a87def41232053b8cc722a Signed-off-by: Abe Levkoy <alevkoy@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2209186 Tested-by: Eric Herrmann <eherrmann@chromium.org> Reviewed-by: Eric Herrmann <eherrmann@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org> Commit-Queue: Keith Short <keithshort@chromium.org>
-rw-r--r--driver/tcpm/tusb422.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/driver/tcpm/tusb422.c b/driver/tcpm/tusb422.c
index 6c26646384..b16b066160 100644
--- a/driver/tcpm/tusb422.c
+++ b/driver/tcpm/tusb422.c
@@ -24,6 +24,21 @@
#error "CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE is enabled"
#endif
+#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && \
+ defined(CONFIG_USB_PD_DISCHARGE_TCPC)
+#error "TUSB422 must disable TCPC discharge to support enabling Auto Discharge"
+#error "Disconnect all the time."
+#endif
+
+enum tusb422_reg_addr {
+ TUSB422_REG_VBUS_AND_VCONN_CONTROL = 0x98,
+};
+
+enum vbus_and_vconn_control_mask {
+ INT_VCONNDIS_DISABLE = BIT(1),
+ INT_VBUSDIS_DISABLE = BIT(2),
+};
+
static int tusb422_tcpci_tcpm_init(int port)
{
int rv = tcpci_tcpm_init(port);
@@ -40,6 +55,18 @@ static int tusb422_tcpci_tcpm_init(int port)
* after updating the ROLE Control register on a device connect.
*/
tusb422_tcpm_drv.tcpc_enable_auto_discharge_disconnect(port, 1);
+
+ /*
+ * Disable internal VBUS discharge. AutoDischargeDisconnect must
+ * generally remain enabled to keep TUSB422 in active mode.
+ * However, this will interfere with FRS by default by
+ * discharging at inappropriate times. Mitigate this by
+ * disabling internal VBUS discharge. The TUSB422 must rely on
+ * external VBUS discharge. See TUSB422 datasheet, 7.4.2 Active
+ * Mode.
+ */
+ tcpc_write(port, TUSB422_REG_VBUS_AND_VCONN_CONTROL,
+ INT_VBUSDIS_DISABLE);
}
/*
@@ -50,6 +77,21 @@ static int tusb422_tcpci_tcpm_init(int port)
return tcpc_write16(port, TCPC_REG_COMMAND, 0x33);
}
+static int tusb422_tcpm_set_cc(int port, int pull)
+{
+
+ /*
+ * Enable AutoDischargeDisconnect to keep TUSB422 in active mode through
+ * this transition. Note that the configuration keeps the TCPC from
+ * actually discharging VBUS in this case.
+ */
+ if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE))
+ tusb422_tcpm_drv.tcpc_enable_auto_discharge_disconnect(port, 1);
+
+ return tcpci_tcpm_set_cc(port, pull);
+
+}
+
const struct tcpm_drv tusb422_tcpm_drv = {
.init = &tusb422_tcpci_tcpm_init,
.release = &tcpci_tcpm_release,
@@ -58,7 +100,7 @@ const struct tcpm_drv tusb422_tcpm_drv = {
.check_vbus_level = &tcpci_tcpm_check_vbus_level,
#endif
.select_rp_value = &tcpci_tcpm_select_rp_value,
- .set_cc = &tcpci_tcpm_set_cc,
+ .set_cc = &tusb422_tcpm_set_cc,
.set_polarity = &tcpci_tcpm_set_polarity,
.set_vconn = &tcpci_tcpm_set_vconn,
.set_msg_header = &tcpci_tcpm_set_msg_header,