diff options
author | Edward Hill <ecgh@chromium.org> | 2019-12-10 18:12:19 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-12 03:53:57 +0000 |
commit | 1e078bcf88708ee3f1b78b7a0bd765ba94674ab9 (patch) | |
tree | 3682d1cc97c11fe92a9e21c7f7276958aec45680 /driver/tcpm/nct38xx.c | |
parent | d0c9cbf5772959dccbba8953b725b710fcdce234 (diff) | |
download | chrome-ec-1e078bcf88708ee3f1b78b7a0bd765ba94674ab9.tar.gz |
nct38xx: Set pull on both CC lines on disconnect
tcpci_nct38xx_set_cc() only sets the pull resistor on one CC line according
to polarity. This is correct when attached, but on disconnect we need to
set the pull resistor on both CC lines, since polarity is no longer known
(unless DRP toggle is enabled, since that will take care of setting both
CC lines to do the toggling).
This workaround for chromium:951681 can be removed once that bug is fixed
in the TCPCI common code.
BUG=b:146003980, chromium:951681
BRANCH=none
TEST=Charging works with both plug orientations with AP off
Change-Id: I1406263011a4c8d595be0d7093f2ab220690de3f
Signed-off-by: Edward Hill <ecgh@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1961305
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'driver/tcpm/nct38xx.c')
-rw-r--r-- | driver/tcpm/nct38xx.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/driver/tcpm/nct38xx.c b/driver/tcpm/nct38xx.c index d89c91522d..6630d570c9 100644 --- a/driver/tcpm/nct38xx.c +++ b/driver/tcpm/nct38xx.c @@ -8,8 +8,10 @@ #include "common.h" #include "console.h" +#include "hooks.h" #include "ioexpander_nct38xx.h" #include "nct38xx.h" +#include "task.h" #include "tcpci.h" #if !defined(CONFIG_USB_PD_TCPM_TCPCI) @@ -29,6 +31,7 @@ static unsigned char txBuf[33]; static unsigned char rxBuf[33]; /* Save the selected rp value */ static int selected_rp[CONFIG_USB_PD_PORT_MAX_COUNT]; +static int selected_pull[CONFIG_USB_PD_PORT_MAX_COUNT]; static int nct38xx_tcpm_init(int port) { @@ -36,6 +39,7 @@ static int nct38xx_tcpm_init(int port) int reg; cable_polarity[port] = POLARITY_NONE; + selected_pull[port] = TYPEC_CC_OPEN; rv = tcpci_tcpm_init(port); if (rv) @@ -150,9 +154,10 @@ int tcpci_nct38xx_select_rp_value(int port, int rp) */ static int tcpci_nct38xx_set_cc(int port, int pull) { - int rv; + selected_pull[port] = pull; + if (cable_polarity[port] == POLARITY_NONE) { rv = tcpci_nct38xx_check_cable_polarity(port); if (rv) @@ -174,6 +179,30 @@ static int tcpci_nct38xx_set_cc(int port, int pull) return rv; } +/* + * tcpci_nct38xx_set_cc() only sets the pull resistor on one CC line according + * to polarity. This is correct when attached, but on disconnect we need to + * set the pull resistor on both CC lines, since polarity is no longer known + * (unless DRP toggle is enabled, since that will take care of setting both + * CC lines to do the toggling). + * TODO(crbug.com/951681): This code can be removed once that bug is fixed. + */ +static void disconnect_hook(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + int rv; + + if (pd_get_dual_role(port) != PD_DRP_TOGGLE_ON + && selected_pull[port] != TYPEC_CC_OPEN) { + rv = tcpc_write(port, TCPC_REG_ROLE_CTRL, + TCPC_REG_ROLE_CTRL_SET(0, selected_rp[port], + selected_pull[port], selected_pull[port])); + if (rv) + CPRINTS("C%d failed to set pull on disconnect", port); + } +} +DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, disconnect_hook, HOOK_PRIO_DEFAULT); + static int tcpci_nct38xx_get_cc(int port, enum tcpc_cc_voltage_status *cc1, enum tcpc_cc_voltage_status *cc2) { |