diff options
author | Michael5 Chen <michael5_chen@pegatroncorp.com> | 2019-09-25 19:46:20 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-06 22:19:34 +0000 |
commit | d3e5ed7540d2ad903aa70b67dad0ac02d694a78e (patch) | |
tree | e8307aa6257043dc27fd62d676e08afb8a8a994f /driver | |
parent | 5cc4b989df0b814fea8c3bc949bf188a9ea7039d (diff) | |
download | chrome-ec-d3e5ed7540d2ad903aa70b67dad0ac02d694a78e.tar.gz |
helios: Detect PPC sn5s330 CC1/CC2 OVP and release OVP.
If PPC have CC OVP protection, check VBUS_GOOD.
If VBUS_GOOD is ok, release CC OVP.
BUG=b:141587322
BRANCH=Master
TEST=Manual
Do ESD test to trigger CC1/CC2 OVP.
Using EC console command PPC_DUMP to check ppc regiset is correct.
Change-Id: I3b817cc1dcec4c14ed4e2098b7ad7582b938f613
Signed-off-by: Michael5 Chen <michael5_chen@pegatroncorp.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1826098
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1933787
Reviewed-by: Edward Hill <ecgh@chromium.org>
Commit-Queue: Edward Hill <ecgh@chromium.org>
Tested-by: Edward Hill <ecgh@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/ppc/sn5s330.c | 63 | ||||
-rw-r--r-- | driver/ppc/sn5s330.h | 9 |
2 files changed, 58 insertions, 14 deletions
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c index 85db762148..a94c2ae652 100644 --- a/driver/ppc/sn5s330.c +++ b/driver/ppc/sn5s330.c @@ -342,6 +342,12 @@ static int sn5s330_init(int port) clr_flags(port, SN5S330_INT_MASK_RISE_REG2, SN5S330_VCONN_ILIM); /* + * Unmask the CC1/CC2 OVP interrupt so we can print CC1/CC2 OVP events + */ + clr_flags(port, SN5S330_INT_MASK_RISE_REG2, SN5S330_CC1_CON); + clr_flags(port, SN5S330_INT_MASK_RISE_REG2, SN5S330_CC2_CON); + + /* * Don't proceed with the rest of initialization if we're sysjumping. * We would have already done this before. */ @@ -401,6 +407,12 @@ static int sn5s330_init(int port) return status; } + /* + * Unmask the CC1/CC2 OVP interrupt so we can print CC1/CC2 OVP events + */ + clr_flags(port, SN5S330_INT_MASK_RISE_REG2, SN5S330_CC1_CON); + clr_flags(port, SN5S330_INT_MASK_RISE_REG2, SN5S330_CC2_CON); + #if defined(CONFIG_USB_PD_VBUS_DETECT_PPC) && defined(CONFIG_USB_CHARGER) /* If PPC is being used to detect VBUS, enable VBUS interrupts. */ regval = ~SN5S330_VBUS_GOOD_MASK; @@ -627,6 +639,20 @@ static int sn5s330_vbus_source_enable(int port, int enable) return sn5s330_pp_fet_enable(port, SN5S330_PP1, !!enable); } +#ifdef CONFIG_USBC_PPC_SBU +static int sn5s330_set_sbu(int port, int enable) +{ + int rv; + + if (enable) + rv = set_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN); + else + rv = clr_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN); + + return rv; +} +#endif /* CONFIG_USBC_PPC_SBU */ + static void sn5s330_handle_interrupt(int port) { int attempt = 0; @@ -641,6 +667,8 @@ static void sn5s330_handle_interrupt(int port) { int rise = 0; int fall = 0; + int regval = 0; + int retries = 0; attempt++; @@ -689,26 +717,33 @@ static void sn5s330_handle_interrupt(int port) if (rise & SN5S330_VCONN_ILIM) CPRINTS("ppc p%d: VCONN OC!", port); + if (rise & SN5S330_CC1_CON || rise & SN5S330_CC2_CON) { + CPRINTS("ppc p%d: CC OVP!", port); + retries = 0; + do { + read_reg(port, SN5S330_INT_STATUS_REG3, + ®val); + if (regval & SN5S330_VBUS_GOOD) { + sn5s330_set_sbu(port, 1); + sn5s330_pp_fet_enable(port, + SN5S330_PP2, 1); + break; + } + retries++; + msleep(1); + } while (retries < 10); + + if (retries == 10) + CPRINTS("ppc p%d: Fail to release cc OVP." + , port); + } + /* Clear the interrupt sources. */ write_reg(port, SN5S330_INT_TRIP_RISE_REG2, rise); write_reg(port, SN5S330_INT_TRIP_FALL_REG2, fall); } } -#ifdef CONFIG_USBC_PPC_SBU -static int sn5s330_set_sbu(int port, int enable) -{ - int rv; - - if (enable) - rv = set_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN); - else - rv = clr_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN); - - return rv; -} -#endif /* CONFIG_USBC_PPC_SBU */ - static void sn5s330_irq_deferred(void) { int i; diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h index 263452a5a2..6211c9a06b 100644 --- a/driver/ppc/sn5s330.h +++ b/driver/ppc/sn5s330.h @@ -144,6 +144,15 @@ enum sn5s330_pp_idx { #define SN5S330_VCONN_ILIM (1 << 1) /* + * INT_MASK_RISE/FALL_EDGE2 + * + * The OV_CC1_CON/OV_CC2_CON bit indicates an over-voltage occurred on + * C_CC1/C_CC2. + */ +#define SN5S330_CC1_CON (1 << 2) +#define SN5S330_CC2_CON (1 << 3) + +/* * INT_MASK_RISE/FALL_EDGE_3 * * The VBUS_GOOD bit indicates VBUS has increased beyond a 4.0V threshold. |