diff options
author | Abe Levkoy <alevkoy@chromium.org> | 2020-05-19 11:00:39 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-29 00:05:11 +0000 |
commit | fda7ea9671ce6b7d7d1bdc47ef3dbfd8cbffd971 (patch) | |
tree | 884dcac0411c7f5680ecdb6e30114923020687fa | |
parent | a09f762f948e05c45d980cb4e216c748bda42369 (diff) | |
download | chrome-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.c | 44 |
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, |