diff options
author | Eric Yilun Lin <yllin@chromium.org> | 2022-06-07 14:02:49 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-06-28 06:12:49 +0000 |
commit | 8e548d618e4caf5f591d9daa1693bd578dd152bf (patch) | |
tree | a27e7e4225b77941fcf21728668c148aeab0c27e /driver/tcpm/anx7447.c | |
parent | c7b6f74a6543e32ae78f888dd21ef76bad723764 (diff) | |
download | chrome-ec-8e548d618e4caf5f591d9daa1693bd578dd152bf.tar.gz |
anx7447: delay FRS_DATA deassertion to PPC
This CL delay the dassertion of FRS_EN output to the PPC.
Some PPCs need the FRS_EN pin to stay asserted until the
VBUS dropped to a threshold under 5V to successfully source.
However, on some hubs with a larger cap, the VBUS might take
more than 10 ms. This workaround is to delay the FRS_EN
deassertion to PPC for 30 ms, which should be enough for
most cases.
BUG=b:223087277
TEST=tested on a hub with large cap under 5V cases
BRANCH=none
Change-Id: I23faca31c9922762164c028b7269ca41a93bf6ca
Signed-off-by: Eric Yilun Lin <yllin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3692646
Reviewed-by: Ting Shen <phoenixshen@chromium.org>
Tested-by: Eric Yilun Lin <yllin@google.com>
Commit-Queue: Eric Yilun Lin <yllin@google.com>
Diffstat (limited to 'driver/tcpm/anx7447.c')
-rw-r--r-- | driver/tcpm/anx7447.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c index 8e19f6ee90..ae21b6e263 100644 --- a/driver/tcpm/anx7447.c +++ b/driver/tcpm/anx7447.c @@ -36,6 +36,11 @@ static int anx7447_mux_set(const struct usb_mux *me, mux_state_t mux_state, static struct anx_state anx[CONFIG_USB_PD_PORT_MAX_COUNT]; static struct anx_usb_mux mux[CONFIG_USB_PD_PORT_MAX_COUNT]; +#ifdef CONFIG_USB_PD_FRS_TCPC +/* an array to indicate which port is waiting for FRS disablement. */ +static bool anx_frs_dis[CONFIG_USB_PD_PORT_MAX_COUNT]; +#endif /* CONFIG_USB_PD_FRS_TCPC */ + /* * ANX7447 has two co-existence I2C addresses, TCPC address and * SPI address. The registers of TCPC address are partly compliant @@ -492,6 +497,22 @@ static void anx7447_tcpc_alert(int port) } #ifdef CONFIG_USB_PD_FRS_TCPC +static void anx7447_disable_frs_deferred(void) +{ + int i, val; + + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (!anx_frs_dis[i]) + continue; + + anx_frs_dis[i] = false; + anx7447_reg_read(i, ANX7447_REG_ADDR_GPIO_CTRL_1, &val); + val &= ~ANX7447_ADDR_GPIO_CTRL_1_FRS_EN_DATA; + anx7447_reg_write(i, ANX7447_REG_ADDR_GPIO_CTRL_1, val); + } +} +DECLARE_DEFERRED(anx7447_disable_frs_deferred); + static int anx7447_set_frs_enable(int port, int enable) { int val; @@ -500,14 +521,25 @@ static int anx7447_set_frs_enable(int port, int enable) ANX7447_FRSWAP_DETECT_ENABLE, enable ? MASK_SET : MASK_CLR)); + if (!enable) { + /* + * b/223087277#comment52: delay to disable FRS output to the + * PPC. Some PPCs need the FRS_EN pin to stay asserted until the + * VBUS dropped to a threshold under 5V to successfully source. + * However, on some hubs with a larger cap, the VBUS might take + * more than 10 ms. This workaround is to delay the FRS_EN + * deassertion to PPC for 30 ms, which should be enough for + * most cases. + */ + anx_frs_dis[port] = true; + hook_call_deferred(&anx7447_disable_frs_deferred_data, + 30 * MSEC); + return EC_SUCCESS; + } + RETURN_ERROR( anx7447_reg_read(port, ANX7447_REG_ADDR_GPIO_CTRL_1, &val)); - - if (enable) - val |= ANX7447_ADDR_GPIO_CTRL_1_FRS_EN_DATA; - else - val &= ~ANX7447_ADDR_GPIO_CTRL_1_FRS_EN_DATA; - + val |= ANX7447_ADDR_GPIO_CTRL_1_FRS_EN_DATA; RETURN_ERROR( anx7447_reg_write(port, ANX7447_REG_ADDR_GPIO_CTRL_1, val)); return EC_SUCCESS; |