summaryrefslogtreecommitdiff
path: root/driver/tcpm/nct38xx.c
diff options
context:
space:
mode:
authorEdward Hill <ecgh@chromium.org>2019-12-10 18:12:19 -0700
committerCommit Bot <commit-bot@chromium.org>2019-12-12 03:53:57 +0000
commit1e078bcf88708ee3f1b78b7a0bd765ba94674ab9 (patch)
tree3682d1cc97c11fe92a9e21c7f7276958aec45680 /driver/tcpm/nct38xx.c
parentd0c9cbf5772959dccbba8953b725b710fcdce234 (diff)
downloadchrome-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.c31
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)
{