summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorEric Herrmann <eherrmann@chromium.org>2020-06-19 15:09:19 -0700
committerCommit Bot <commit-bot@chromium.org>2020-07-07 02:37:04 +0000
commitcc860070deeacc8ba9eccf1a3d42df7f1d8e07f9 (patch)
tree423274851d912055c90cc158e6567ed374d236e0 /driver
parentd78be7717692f0a18583ce5e88a0efd249c8f61b (diff)
downloadchrome-ec-cc860070deeacc8ba9eccf1a3d42df7f1d8e07f9.tar.gz
TUSB422: Add support for FRS
The TUSB422 does not officially support FRS. support is being added to workaround bugs in the SYV682. BUG=b:148144711 TEST=Check that FRS is signaled to the TCPM from the TUSB422 driver when CONFIG_USB_PD_FRS_TCPC is set TEST=make buildall BRANCH=none Change-Id: I4c8fefbf0f01b327f345d4b4f09b6c422aaa2e5d Signed-off-by: Eric Herrmann <eherrmann@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2278354 Reviewed-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r--driver/tcpm/tcpci.h2
-rw-r--r--driver/tcpm/tusb422.c53
-rw-r--r--driver/tcpm/tusb422.h12
3 files changed, 62 insertions, 5 deletions
diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h
index d728b55332..b19aca60a3 100644
--- a/driver/tcpm/tcpci.h
+++ b/driver/tcpm/tcpci.h
@@ -42,6 +42,8 @@
TCPC_REG_ALERT_TX_FAILED)
#define TCPC_REG_ALERT_MASK 0x12
+#define TCPC_REG_ALERT_MASK_VENDOR_DEF BIT(15)
+
#define TCPC_REG_POWER_STATUS_MASK 0x14
#define TCPC_REG_FAULT_STATUS_MASK 0x15
#define TCPC_REG_EXT_STATUS_MASK 0x16
diff --git a/driver/tcpm/tusb422.c b/driver/tcpm/tusb422.c
index a301a27651..3ab95c9721 100644
--- a/driver/tcpm/tusb422.c
+++ b/driver/tcpm/tusb422.c
@@ -39,10 +39,25 @@ enum vbus_and_vconn_control_mask {
INT_VBUSDIS_DISABLE = BIT(2),
};
+/* The TUSB422 cannot drive an FRS GPIO, but can detect FRS */
+static int tusb422_set_frs_enable(int port, int enable)
+{
+ return tcpc_update8(port, TUSB422_REG_PHY_BMC_RX_CTRL,
+ TUSB422_REG_PHY_BMC_RX_CTRL_FRS_RX_EN,
+ enable ? MASK_SET : MASK_CLR);
+}
+
static int tusb422_tcpci_tcpm_init(int port)
{
- int rv = tcpci_tcpm_init(port);
+ int rv;
+ /* TUSB422 has a vendor-defined register reset */
+ rv = tcpc_update8(port, TUSB422_REG_CC_GEN_CTRL,
+ TUSB422_REG_CC_GEN_CTRL_GLOBAL_SW_RST, MASK_SET);
+ if (rv)
+ return rv;
+
+ rv = tcpci_tcpm_init(port);
if (rv)
return rv;
@@ -68,18 +83,26 @@ static int tusb422_tcpci_tcpm_init(int port)
tcpc_write(port, TUSB422_REG_VBUS_AND_VCONN_CONTROL,
INT_VBUSDIS_DISABLE);
}
-
+ if (IS_ENABLED(CONFIG_USB_PD_FRS_TCPC)) {
+ /* Disable FRS detection, and enable the FRS detection alert */
+ tusb422_set_frs_enable(port, 0);
+ tcpc_update16(port, TCPC_REG_ALERT_MASK,
+ TCPC_REG_ALERT_MASK_VENDOR_DEF, MASK_SET);
+ tcpc_update8(port, TUSB422_REG_VENDOR_INTERRUPTS_MASK,
+ TUSB422_REG_VENDOR_INTERRUPTS_MASK_FRS_RX,
+ MASK_SET);
+ }
/*
* VBUS detection is supposed to be enabled by default, however the
* TUSB422 has this disabled following reset.
*/
/* Enable VBUS detection */
- return tcpc_write16(port, TCPC_REG_COMMAND, 0x33);
+ return tcpc_write16(port, TCPC_REG_COMMAND,
+ TCPC_REG_COMMAND_ENABLE_VBUS_DETECT);
}
static int tusb422_tcpm_set_cc(int port, int pull)
{
-
/*
* Enable AutoDischargeDisconnect to keep TUSB422 in active mode through
* this transition. Note that the configuration keeps the TCPC from
@@ -108,6 +131,23 @@ static int tusb422_tcpc_drp_toggle(int port)
}
#endif
+static void tusb422_tcpci_tcpc_alert(int port)
+{
+ if (IS_ENABLED(CONFIG_USB_PD_FRS_TCPC)) {
+ int regval;
+
+ /* FRS detection is a vendor defined alert */
+ tcpc_read(port, TUSB422_REG_VENDOR_INTERRUPTS_STATUS, &regval);
+ if (regval & TUSB422_REG_VENDOR_INTERRUPTS_STATUS_FRS_RX) {
+ tusb422_set_frs_enable(port, 0);
+ tcpc_write(port, TUSB422_REG_VENDOR_INTERRUPTS_STATUS,
+ regval);
+ pd_got_frs_signal(port);
+ }
+ }
+ tcpci_tcpc_alert(port);
+}
+
const struct tcpm_drv tusb422_tcpm_drv = {
.init = &tusb422_tcpci_tcpm_init,
.release = &tcpci_tcpm_release,
@@ -123,7 +163,7 @@ const struct tcpm_drv tusb422_tcpm_drv = {
.set_rx_enable = &tcpci_tcpm_set_rx_enable,
.get_message_raw = &tcpci_tcpm_get_message_raw,
.transmit = &tcpci_tcpm_transmit,
- .tcpc_alert = &tcpci_tcpc_alert,
+ .tcpc_alert = &tusb422_tcpci_tcpc_alert,
#ifdef CONFIG_USB_PD_DISCHARGE_TCPC
.tcpc_discharge_vbus = &tcpci_tcpc_discharge_vbus,
#endif
@@ -140,4 +180,7 @@ const struct tcpm_drv tusb422_tcpm_drv = {
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
.enter_low_power_mode = &tcpci_enter_low_power_mode,
#endif
+#ifdef CONFIG_USB_PD_FRS_TCPC
+ .set_frs_enable = &tusb422_set_frs_enable,
+#endif
};
diff --git a/driver/tcpm/tusb422.h b/driver/tcpm/tusb422.h
index 52d0a079d6..54ae0c7e02 100644
--- a/driver/tcpm/tusb422.h
+++ b/driver/tcpm/tusb422.h
@@ -11,6 +11,18 @@
/* I2C interface */
#define TUSB422_I2C_ADDR_FLAGS 0x20
+#define TUSB422_REG_VENDOR_INTERRUPTS_STATUS 0x90
+#define TUSB422_REG_VENDOR_INTERRUPTS_STATUS_FRS_RX BIT(0)
+
+#define TUSB422_REG_VENDOR_INTERRUPTS_MASK 0x92
+#define TUSB422_REG_VENDOR_INTERRUPTS_MASK_FRS_RX BIT(0)
+
+#define TUSB422_REG_CC_GEN_CTRL 0x94
+#define TUSB422_REG_CC_GEN_CTRL_GLOBAL_SW_RST BIT(5)
+
+#define TUSB422_REG_PHY_BMC_RX_CTRL 0x96
+#define TUSB422_REG_PHY_BMC_RX_CTRL_FRS_RX_EN BIT(3)
+
extern const struct tcpm_drv tusb422_tcpm_drv;
#endif /* defined(__CROS_EC_USB_PD_TCPM_TUSB422_H) */