diff options
author | Eric Herrmann <eherrmann@chromium.org> | 2020-06-19 15:09:19 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-07-07 02:37:04 +0000 |
commit | cc860070deeacc8ba9eccf1a3d42df7f1d8e07f9 (patch) | |
tree | 423274851d912055c90cc158e6567ed374d236e0 /driver | |
parent | d78be7717692f0a18583ce5e88a0efd249c8f61b (diff) | |
download | chrome-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.h | 2 | ||||
-rw-r--r-- | driver/tcpm/tusb422.c | 53 | ||||
-rw-r--r-- | driver/tcpm/tusb422.h | 12 |
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, ®val); + 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) */ |