diff options
author | Eric Yilun Lin <yllin@chromium.org> | 2021-03-05 14:01:47 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-04-01 05:49:03 +0000 |
commit | bfd3e5a9bf19e2066ad58f36f7dd9248cdf0b930 (patch) | |
tree | 512d486df10bfec8672c09d46b3b09547271945b | |
parent | a8bedfe1474c3042ee8d7cde3c38afd20d4c1dc6 (diff) | |
download | chrome-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.c | 49 | ||||
-rw-r--r-- | driver/ppc/syv682x.h | 12 | ||||
-rw-r--r-- | include/config.h | 11 |
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 |