summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2021-03-05 14:01:47 +0800
committerCommit Bot <commit-bot@chromium.org>2021-04-01 05:49:03 +0000
commitbfd3e5a9bf19e2066ad58f36f7dd9248cdf0b930 (patch)
tree512d486df10bfec8672c09d46b3b09547271945b
parenta8bedfe1474c3042ee8d7cde3c38afd20d4c1dc6 (diff)
downloadchrome-ec-bfd3e5a9bf19e2066ad58f36f7dd9248cdf0b930.tar.gz
ppc/syv682x: support C version
C version won't block I2C accessing to CONTROL4(to on/off Vconn) reg when smart discahrge enabled. This allows us to re-enable the smart discahrge on boards using SYV682C. This CL support the feature by adding: 1. CONFIG_USBC_PPC_SYV682C 2. CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE also, hayato uses different SYV682 versions across revisions, add a overridable function syv682x_board_is_syv682c() for handling board revision issue. BUG=b:160548079 b:176876036 TEST=Hayato meets tVconnOff, and tVbusDischarge BRANCH=asurada Change-Id: I89b57b8c20907249d5d97140289fb0570bd58b46 Signed-off-by: Eric Yilun Lin <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2738506 Reviewed-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--driver/ppc/syv682x.c49
-rw-r--r--driver/ppc/syv682x.h12
-rw-r--r--include/config.h11
3 files changed, 61 insertions, 11 deletions
diff --git a/driver/ppc/syv682x.c b/driver/ppc/syv682x.c
index e66411fd0a..0e49abdf6a 100644
--- a/driver/ppc/syv682x.c
+++ b/driver/ppc/syv682x.c
@@ -82,16 +82,29 @@ static int read_reg(uint8_t port, int reg, int *regval)
regval);
}
+#ifdef CONFIG_USBC_PPC_SYV682C
+__overridable int syv682x_board_is_syv682c(int port)
+{
+ return true;
+}
+#endif
+
/*
- * During channel transition or discharge, the SYV682A silently ignores I2C
+ * During channel transition or discharge, the SYV682X silently ignores I2C
* writes. Poll the BUSY bit until the SYV682A is ready.
*/
-static int syv682x_wait_for_ready(int port)
+static int syv682x_wait_for_ready(int port, int reg)
{
int regval;
int rv;
timestamp_t deadline;
+#ifdef CONFIG_USBC_PPC_SYV682C
+ /* On SYV682C, busy bit is not applied to CONTROL_4 */
+ if (syv682x_board_is_syv682c(port) && reg == SYV682X_CONTROL_4_REG)
+ return EC_SUCCESS;
+#endif
+
deadline.val = get_time().val
+ (SYV682X_MAX_VBUS_DISCHARGE_TIME_MS * MSEC);
@@ -118,7 +131,7 @@ static int write_reg(uint8_t port, int reg, int regval)
{
int rv;
- rv = syv682x_wait_for_ready(port);
+ rv = syv682x_wait_for_ready(port, reg);
if (rv)
return rv;
@@ -135,6 +148,7 @@ static int syv682x_is_sourcing_vbus(int port)
static int syv682x_discharge_vbus(int port, int enable)
{
+#ifndef CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE
int regval;
int rv;
@@ -148,7 +162,12 @@ static int syv682x_discharge_vbus(int port, int enable)
regval &= ~SYV682X_CONTROL_2_FDSG;
return write_reg(port, SYV682X_CONTROL_2_REG, regval);
-
+#else
+ /*
+ * Smart discharge mode is enabled, nothing to do
+ */
+ return EC_SUCCESS;
+#endif
}
static int syv682x_vbus_source_enable(int port, int enable)
@@ -654,6 +673,7 @@ static int syv682x_set_frs_enable(int port, int enable)
}
#endif /*CONFIG_USB_PD_FRS_PPC*/
+#ifndef CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE
static int syv682x_dev_is_connected(int port, enum ppc_device_role dev)
{
/*
@@ -667,6 +687,7 @@ static int syv682x_dev_is_connected(int port, enum ppc_device_role dev)
return EC_SUCCESS;
}
+#endif
static bool syv682x_is_sink(uint8_t control_1)
{
@@ -745,15 +766,19 @@ static int syv682x_init(int port)
return rv;
/*
- * Set Control Reg 2 to defaults.
- * Note: do not enable smart discharge since it would block
- * i2c transactions for 50ms (discharge time) and this prevents
- * us from disabling Vconn when stop sourcing Vbus and has tVconnOff
- * (35ms) timeout.
+ * Set Control Reg 2 to defaults except 50ms smart discharge time.
+ * Note: On SYV682A/B, enable smart discharge would block i2c
+ * transactions for 50ms (discharge time) and this
+ * prevents us from disabling Vconn when stop sourcing Vbus and has
+ * tVconnOff (35ms) timeout.
+ * On SYV682C, we are allowed to access CONTROL4 while the i2c busy.
*/
regval = (SYV682X_OC_DELAY_10MS << SYV682X_OC_DELAY_SHIFT)
- | (SYV682X_DSG_TIME_200MS << SYV682X_DSG_TIME_SHIFT)
- | (SYV682X_DSG_RON_200_OHM << SYV682X_DSG_RON_SHIFT);
+ | (SYV682X_DSG_RON_200_OHM << SYV682X_DSG_RON_SHIFT)
+ | (SYV682X_DSG_TIME_50MS << SYV682X_DSG_TIME_SHIFT);
+
+ if (IS_ENABLED(CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE))
+ regval |= SYV682X_CONTROL_2_SDSG;
rv = write_reg(port, SYV682X_CONTROL_2_REG, regval);
if (rv)
@@ -800,7 +825,9 @@ const struct ppc_drv syv682x_drv = {
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
.set_vbus_source_current_limit = &syv682x_set_vbus_source_current_limit,
.discharge_vbus = &syv682x_discharge_vbus,
+#ifndef CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE
.dev_is_connected = &syv682x_dev_is_connected,
+#endif /* defined(CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE) */
#ifdef CONFIG_USBC_PPC_POLARITY
.set_polarity = &syv682x_set_polarity,
#endif
diff --git a/driver/ppc/syv682x.h b/driver/ppc/syv682x.h
index 3ecbede18c..d9416f47f1 100644
--- a/driver/ppc/syv682x.h
+++ b/driver/ppc/syv682x.h
@@ -8,6 +8,7 @@
#ifndef __CROS_EC_SYV682X_H
#define __CROS_EC_SYV682X_H
+#include "common.h"
#include "driver/ppc/syv682x_public.h"
/* Source OC deglitch implemented in HW for SYV682B */
@@ -97,4 +98,15 @@
#define SYV682X_CONTROL_4_CC_FRS BIT(1)
#define SYV682X_CONTROL_4_INT_MASK 0x0c
+/*
+ * syv682x_board_is_syv682c
+ *
+ * b:160548079 This is a function to workaround that some board revisions
+ * might have different SYV682 sub-version.
+ *
+ * @param port the query port
+ * @return 1 if the PPC is SYV682C else 0
+ */
+__override_proto int syv682x_board_is_syv682c(int port);
+
#endif /* defined(__CROS_EC_SYV682X_H) */
diff --git a/include/config.h b/include/config.h
index ef029f2b45..c0a88cda53 100644
--- a/include/config.h
+++ b/include/config.h
@@ -4574,6 +4574,7 @@
#undef CONFIG_USBC_PPC_NX20P3481
#undef CONFIG_USBC_PPC_NX20P3483
#undef CONFIG_USBC_PPC_SN5S330
+#undef CONFIG_USBC_PPC_SYV682C
#undef CONFIG_USBC_PPC_SYV682X
/*
@@ -4585,6 +4586,9 @@
/* SYV682 does not pass through CC, instead it bypasses to the TCPC */
#undef CONFIG_SYV682X_NO_CC
+/* Define to enable SYV682X VBUS smart discharge. */
+#undef CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE
+
/* PPC is capable of gating the SBU lines. */
#undef CONFIG_USBC_PPC_SBU
@@ -5498,6 +5502,13 @@
#define CONFIG_USBC_PPC_VCONN
#endif
+
+/*****************************************************************************/
+/* PPC SYV682C is a subset of SYV682X. */
+#if defined(CONFIG_USBC_PPC_SYV682C)
+#define CONFIG_USBC_PPC_SYV682X
+#endif
+
/*
* The SYV682X supports VCONN and needs to be informed of CC polarity.
* There is a 3.6V limit on the HOST_CC signals, so the TCPC should not source