summaryrefslogtreecommitdiff
path: root/driver/tcpm/anx7447.c
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2022-06-07 14:02:49 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-06-28 06:12:49 +0000
commit8e548d618e4caf5f591d9daa1693bd578dd152bf (patch)
treea27e7e4225b77941fcf21728668c148aeab0c27e /driver/tcpm/anx7447.c
parentc7b6f74a6543e32ae78f888dd21ef76bad723764 (diff)
downloadchrome-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.c44
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;