summaryrefslogtreecommitdiff
path: root/driver/tcpm/nct38xx.c
diff options
context:
space:
mode:
authorEdward Hill <ecgh@chromium.org>2020-08-29 17:23:44 -0600
committerCommit Bot <commit-bot@chromium.org>2020-09-03 19:18:34 +0000
commit463967bcaa76158527af3cd337c7e06677fd751f (patch)
treeca2429cba8142bdc4838d55bcee7ee30a7706411 /driver/tcpm/nct38xx.c
parent81832b5d2e00c5d606d78f8cbd6b4074af75c0c0 (diff)
downloadchrome-ec-463967bcaa76158527af3cd337c7e06677fd751f.tar.gz
nct38xx: Only disable SNKEN if we are sink
Disabling SNKEN makes the VBSNK_EN pin Hi-Z, so USB_Cx_TCPC_VBSNK_EN_L will be asserted by external pull-down, so only do so if already sinking, otherwise both source and sink switches can be closed, which should never happen. BUG=b:166850036 b:166527561 BRANCH=zork TEST=EC reboot with sink device in C0 and charger in C1 Signed-off-by: Edward Hill <ecgh@chromium.org> Change-Id: Ib4400a16b02e47eca109b95bf912b7f23325c8af Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2384009 Reviewed-by: Denis Brockus <dbrockus@chromium.org> Tested-by: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'driver/tcpm/nct38xx.c')
-rw-r--r--driver/tcpm/nct38xx.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/driver/tcpm/nct38xx.c b/driver/tcpm/nct38xx.c
index 308cefe928..79e46fa12a 100644
--- a/driver/tcpm/nct38xx.c
+++ b/driver/tcpm/nct38xx.c
@@ -98,6 +98,7 @@ static int nct38xx_init(int port)
return rv;
}
+
static int nct38xx_tcpm_init(int port)
{
int rv;
@@ -109,12 +110,11 @@ static int nct38xx_tcpm_init(int port)
return nct38xx_init(port);
}
-int nct38xx_tcpm_set_cc(int port, int pull)
+static int nct38xx_tcpm_set_cc(int port, int pull)
{
/*
* Setting the CC lines to open/open requires that the NCT CTRL_OUT
- * register has sink disabled. Otherwise the following happens, as
- * described by Nuvoton:
+ * register has sink disabled. Otherwise, when no battery is connected:
*
* 1. You set CC lines to Open/Open. This is physically happening on
* the CC line.
@@ -125,20 +125,58 @@ int nct38xx_tcpm_set_cc(int port, int pull)
* 4. When TCPC VCC gets below ~2.7V the TCPC will reset and therefore
* it will present Rd/Rd on the CC lines. Also the VBSNK_EN pin
* after reset is Hi-Z, so the sink switch will get closed again.
+ *
+ * Disabling SNKEN makes the VBSNK_EN pin Hi-Z, so
+ * USB_Cx_TCPC_VBSNK_EN_L will be asserted by external
+ * pull-down, so only do so if already sinking, otherwise
+ * both source and sink switches can be closed, which should
+ * never happen (b/166850036).
+ *
+ * SNKEN will be re-enabled in nct38xx_init above (from tcpm_init), or
+ * when CC lines are set again, or when sinking is disabled.
*/
+ enum mask_update_action action = MASK_SET;
+ int rv;
+
if (pull == TYPEC_CC_OPEN) {
- int rv;
+ bool is_sinking;
+
+ rv = tcpm_get_snk_ctrl(port, &is_sinking);
+ if (rv)
+ return rv;
+
+ if (is_sinking)
+ action = MASK_CLR;
+ }
+
+ rv = tcpc_update8(port,
+ NCT38XX_REG_CTRL_OUT_EN,
+ NCT38XX_REG_CTRL_OUT_EN_SNKEN,
+ action);
+ if (rv)
+ return rv;
+
+ return tcpci_tcpm_set_cc(port, pull);
+}
+
+static int nct38xx_tcpm_set_snk_ctrl(int port, int enable)
+{
+ int rv;
- /* Disable SNKEN, it will be re-enabled in tcpm_init path */
+ /*
+ * To disable sinking, SNKEN must be enabled so that
+ * USB_Cx_TCPC_VBSNK_EN_L will be driven high.
+ */
+ if (!enable) {
rv = tcpc_update8(port,
NCT38XX_REG_CTRL_OUT_EN,
NCT38XX_REG_CTRL_OUT_EN_SNKEN,
- MASK_CLR);
+ MASK_SET);
if (rv)
return rv;
}
- return tcpci_tcpm_set_cc(port, pull);
+ return tcpci_tcpm_set_snk_ctrl(port, enable);
}
static void nct38xx_tcpc_alert(int port)
@@ -222,7 +260,7 @@ const struct tcpm_drv nct38xx_tcpm_drv = {
#endif
#ifdef CONFIG_USBC_PPC
.get_snk_ctrl = &tcpci_tcpm_get_snk_ctrl,
- .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl,
+ .set_snk_ctrl = &nct38xx_tcpm_set_snk_ctrl,
.get_src_ctrl = &tcpci_tcpm_get_src_ctrl,
.set_src_ctrl = &tcpci_tcpm_set_src_ctrl,
#endif