summaryrefslogtreecommitdiff
path: root/driver/ppc/syv682x.c
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 /driver/ppc/syv682x.c
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>
Diffstat (limited to 'driver/ppc/syv682x.c')
-rw-r--r--driver/ppc/syv682x.c49
1 files changed, 38 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