diff options
author | Ting Shen <phoenixshen@google.com> | 2022-02-15 18:02:59 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-03-16 10:35:23 +0000 |
commit | c06b595f531bb71ee393e6220caba24805aacfd9 (patch) | |
tree | f0e5fffd6bba5ddd1c7372c6d42668f1732f0023 | |
parent | 5316d650135ef6009b2476276ffdd6e4dee42f72 (diff) | |
download | chrome-ec-c06b595f531bb71ee393e6220caba24805aacfd9.tar.gz |
ppc/rt1739: implement FRS
Implement the set_frs_enable function for rt1739 driver.
BUG=b:218982792
TEST=On Krabby, manually verify that PD state enters FRS mode
BRANCH=none
Signed-off-by: Ting Shen <phoenixshen@google.com>
Change-Id: Ia1ef13ded6f25bc08a9d3d593c1201b2bf15b232
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3463086
Reviewed-by: Eric Yilun Lin <yllin@google.com>
Commit-Queue: Ting Shen <phoenixshen@chromium.org>
Tested-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r-- | driver/ppc/rt1739.c | 51 | ||||
-rw-r--r-- | driver/ppc/rt1739.h | 8 |
2 files changed, 51 insertions, 8 deletions
diff --git a/driver/ppc/rt1739.c b/driver/ppc/rt1739.c index 14d1242fe9..f12d0b3ab0 100644 --- a/driver/ppc/rt1739.c +++ b/driver/ppc/rt1739.c @@ -10,6 +10,7 @@ #include "console.h" #include "driver/ppc/rt1739.h" #include "driver/tcpm/tcpci.h" +#include "gpio.h" #include "hooks.h" #include "usbc_ppc.h" #include "util.h" @@ -20,6 +21,7 @@ #endif #define RT1739_FLAGS_SOURCE_ENABLED BIT(0) +#define RT1739_FLAGS_FRS_ENABLED BIT(1) static atomic_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) @@ -191,6 +193,34 @@ static int rt1739_workaround(int port) return EC_SUCCESS; } +static int rt1739_set_frs_enable(int port, int enable) +{ + /* Enable FRS RX detect */ + RETURN_ERROR(update_reg(port, RT1739_REG_CC_FRS_CTRL1, + RT1739_FRS_RX_EN, + enable ? MASK_SET : MASK_CLR)); + + /* + * To enable FRS, turn on FRS_RX interrupt and disable + * all other interrupts (currently bc1.2 only). + * + * When interrupt triggered, we can always assume it's a FRS + * event without spending extra time to read the flags. + */ + RETURN_ERROR(update_reg(port, RT1739_REG_INT_MASK5, + RT1739_BC12_SNK_DONE_MASK, + enable ? MASK_CLR : MASK_SET)); + RETURN_ERROR(update_reg(port, RT1739_REG_INT_MASK4, + RT1739_FRS_RX_MASK, + enable ? MASK_SET : MASK_CLR)); + if (enable) + atomic_or(&flags[port], RT1739_FLAGS_FRS_ENABLED); + else + atomic_clear_bits(&flags[port], RT1739_FLAGS_FRS_ENABLED); + + return EC_SUCCESS; +} + static int rt1739_init(int port) { atomic_clear(&flags[port]); @@ -201,9 +231,7 @@ static int rt1739_init(int port) RT1739_OT_EN | RT1739_SHUTDOWN_OFF)); RETURN_ERROR(rt1739_workaround(port)); - RETURN_ERROR(update_reg(port, RT1739_REG_INT_MASK5, - RT1739_BC12_SNK_DONE_MASK, - MASK_SET)); + RETURN_ERROR(rt1739_set_frs_enable(port, false)); RETURN_ERROR(update_reg(port, RT1739_REG_VBUS_DET_EN, RT1739_VBUS_PRESENT_EN, MASK_SET)); @@ -334,7 +362,7 @@ void rt1739_deferred_interrupt(void) atomic_t current = atomic_clear(&pending_events); for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port) { - int reg; + int event4, event5; if (!(current & BIT(port))) continue; @@ -342,20 +370,27 @@ void rt1739_deferred_interrupt(void) if (ppc_chips[port].drv != &rt1739_ppc_drv) continue; - if (read_reg(port, RT1739_REG_INT_EVENT5, ®)) + if (read_reg(port, RT1739_REG_INT_EVENT4, &event4)) + continue; + if (read_reg(port, RT1739_REG_INT_EVENT5, &event5)) continue; - if (reg & RT1739_BC12_SNK_DONE_INT) + if (event5 & RT1739_BC12_SNK_DONE_INT) task_set_event(USB_CHG_PORT_TO_TASK_ID(port), USB_CHG_EVENT_BC12); - write_reg(port, RT1739_REG_INT_EVENT5, reg); + /* write to clear EVENT4 since FRS interrupt has been handled */ + write_reg(port, RT1739_REG_INT_EVENT4, event4); + write_reg(port, RT1739_REG_INT_EVENT5, event5); } } DECLARE_DEFERRED(rt1739_deferred_interrupt); void rt1739_interrupt(int port) { + if (flags[port] & RT1739_FLAGS_FRS_ENABLED) + pd_got_frs_signal(port); + atomic_or(&pending_events, BIT(port)); hook_call_deferred(&rt1739_deferred_interrupt_data, 0); } @@ -378,7 +413,7 @@ const struct ppc_drv rt1739_ppc_drv = { .set_vconn = &rt1739_set_vconn, #endif #ifdef CONFIG_USB_PD_FRS_PPC - /* TODO: not implemented */ + .set_frs_enable = &rt1739_set_frs_enable, #endif }; diff --git a/driver/ppc/rt1739.h b/driver/ppc/rt1739.h index 474c390255..ed16942ec1 100644 --- a/driver/ppc/rt1739.h +++ b/driver/ppc/rt1739.h @@ -23,9 +23,14 @@ #define RT1739_REG_SW_RESET 0x04 #define RT1739_SW_RESET BIT(0) +#define RT1739_REG_INT_MASK4 0x0C +#define RT1739_FRS_RX_MASK BIT(4) + #define RT1739_REG_INT_MASK5 0x0D #define RT1739_BC12_SNK_DONE_MASK BIT(0) +#define RT1739_REG_INT_EVENT4 0x14 + #define RT1739_REG_INT_EVENT5 0x15 #define RT1739_BC12_SNK_DONE_INT BIT(0) @@ -81,6 +86,9 @@ #define RT1739_VBUS_SAFE0V_EN BIT(1) #define RT1739_VBUS_PRESENT_EN BIT(0) +#define RT1739_REG_CC_FRS_CTRL1 0x2D +#define RT1739_FRS_RX_EN BIT(1) + #define RT1739_REG_VCONN_CTRL1 0x31 #define RT1739_VCONN_ORIENT BIT(1) #define RT1739_VCONN_EN BIT(0) |