diff options
-rw-r--r-- | board/eve/board.c | 2 | ||||
-rw-r--r-- | board/poppy/board.c | 1 | ||||
-rw-r--r-- | board/reef/board.c | 1 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 6 | ||||
-rw-r--r-- | driver/tcpm/anx74xx.c | 70 | ||||
-rw-r--r-- | driver/tcpm/anx74xx.h | 4 |
6 files changed, 67 insertions, 17 deletions
diff --git a/board/eve/board.c b/board/eve/board.c index 338d982d7b..fc87d1d1dc 100644 --- a/board/eve/board.c +++ b/board/eve/board.c @@ -111,7 +111,6 @@ static void anx74xx_c0_cable_det_handler(void) task_set_event(TASK_ID_PD_C0, PD_EVENT_TCPC_RESET, 0); } DECLARE_DEFERRED(anx74xx_c0_cable_det_handler); -DECLARE_HOOK(HOOK_CHIPSET_RESUME, anx74xx_c0_cable_det_handler, HOOK_PRIO_LAST); static void anx74xx_c1_cable_det_handler(void) { @@ -131,7 +130,6 @@ static void anx74xx_c1_cable_det_handler(void) task_set_event(TASK_ID_PD_C1, PD_EVENT_TCPC_RESET, 0); } DECLARE_DEFERRED(anx74xx_c1_cable_det_handler); -DECLARE_HOOK(HOOK_CHIPSET_RESUME, anx74xx_c1_cable_det_handler, HOOK_PRIO_LAST); void anx74xx_cable_det_interrupt(enum gpio_signal signal) { diff --git a/board/poppy/board.c b/board/poppy/board.c index 40c6022dcb..b9b5875273 100644 --- a/board/poppy/board.c +++ b/board/poppy/board.c @@ -113,7 +113,6 @@ static void anx74xx_cable_det_handler(void) task_set_event(TASK_ID_PD_C0, PD_EVENT_TCPC_RESET, 0); } DECLARE_DEFERRED(anx74xx_cable_det_handler); -DECLARE_HOOK(HOOK_CHIPSET_RESUME, anx74xx_cable_det_handler, HOOK_PRIO_LAST); void anx74xx_cable_det_interrupt(enum gpio_signal signal) { diff --git a/board/reef/board.c b/board/reef/board.c index cbba33e83d..5db387f6b9 100644 --- a/board/reef/board.c +++ b/board/reef/board.c @@ -99,7 +99,6 @@ static void anx74xx_cable_det_handler(void) task_set_event(TASK_ID_PD_C0, PD_EVENT_TCPC_RESET, 0); } DECLARE_DEFERRED(anx74xx_cable_det_handler); -DECLARE_HOOK(HOOK_CHIPSET_RESUME, anx74xx_cable_det_handler, HOOK_PRIO_LAST); void anx74xx_cable_det_interrupt(enum gpio_signal signal) { diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index b92641e5c8..ee4ae31ab0 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1428,6 +1428,12 @@ void pd_update_dual_role_config(int port) set_state(port, PD_STATE_SRC_DISCONNECTED); tcpm_set_cc(port, TYPEC_CC_RP); } + +#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && \ + defined(CONFIG_USB_PD_TCPC_LOW_POWER) + /* When switching drp mode, make sure tcpc is out of standby mode */ + tcpm_set_drp_toggle(port, 0); +#endif } int pd_get_role(int port) diff --git a/driver/tcpm/anx74xx.c b/driver/tcpm/anx74xx.c index d9317abbb7..4a32fc4864 100644 --- a/driver/tcpm/anx74xx.c +++ b/driver/tcpm/anx74xx.c @@ -67,16 +67,56 @@ static void anx74xx_update_cable_det(int port, int mode) if (tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_0, ®)) return; - /* - * When ANX3429 needs to enter ANX74XX_STANDBY_MODE, Cable det pin - * shall be pulled low first by ANX3429`s register, in this way, - * for use case of E-mark cable only, EC can find cable det pin is - * pulled high again. - */ - if (mode == ANX74XX_STANDBY_MODE) - reg &= ~ANX74XX_REG_R_PIN_CABLE_DET; - else + if (mode == ANX74XX_STANDBY_MODE) { + int cc_reg; + + /* + * The ANX4329 enters standby mode by setting PWR_EN signal + * low. In addition, RESET_L must be set low to keep the ANX3429 + * in standby mode. + * + * Clearing bit 7 of ANX74XX_REG_ANALOG_CTRL_0 will cause the + * ANX3429 to clear the cable_det signal that goes from the + * ANX3429 to the EC. If this bit is cleared when a cable is + * attached then cable_det will go high once standby is entered. + * + * In some cases, such as when the chipset power state is + * S3/S5/G3 and a sink only adapter is connected to the port, + * this behavior is undesirable. The constant toggling between + * standby and normal mode means that effectively the ANX3429 is + * not in standby mode only consumes ~1 mW less than just + * remaining in normal mode. However when an E mark cable is + * connected, clearing bit 7 is required so that while the E + * mark cable configuration happens, the USB PD state machine + * will continue to wake up until the USB PD attach event can be + * regtistered. + * + * Therefore, the decision to clear bit 7 is based on the + * current CC status of the port. If the CC status is open for + * both CC lines OR if either CC line is showing Ra, then clear + * bit 7. Not clearing bit 7 has no impact for normal cables and + * prevents the constant toggle of standby<->normal when an + * adapter is connected that isn't allowed to attach. Clearing + * bit 7 when CC status reads Ra for either CC line allows the + * USB PD state machine to be woken until the attach event can + * happen. Note that in the case an E mark cable is connected + * and can't attach (i.e. sink only port <- Emark cable -> sink + * only adapter), then the ANX3429 will toggle indefinitely, + * until either the cable is removed, or the port drp status + * changes so the attach event can occur. + * . + */ + + /* Read CC status to see if cable_det bit should be cleared */ + if (tcpc_read(port, ANX74XX_REG_CC_STATUS, &cc_reg)) + return; + /* If open or either CC line is Ra, then clear cable_det */ + if (!cc_reg || (cc_reg & ANX74XX_CC_RA_MASK && + !(cc_reg & ANX74XX_CC_RD_MASK))) + reg &= ~ANX74XX_REG_R_PIN_CABLE_DET; + } else { reg |= ANX74XX_REG_R_PIN_CABLE_DET; + } tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_0, reg); #endif @@ -664,10 +704,14 @@ void anx74xx_handle_power_mode(int port, int mode) static int anx74xx_tcpc_drp_toggle(int port, int enable) { - if (!enable) - /* TODO: Switch to normal mode here (Issue 702277) */ - return EC_SUCCESS; - anx74xx_handle_power_mode(port, ANX74XX_STANDBY_MODE); + /* + * When using low power mode, this function is an entry to point to + * bring the ANX3429 in to or out of standby mode. DRP toggle is + * associated with the chip being in standby mode. + */ + anx74xx_handle_power_mode(port, enable ? ANX74XX_STANDBY_MODE : + ANX74XX_NORMAL_MODE); + return EC_SUCCESS; } #endif /* CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE && CONFIG_USB_PD_TCPC_LOW_POWER */ diff --git a/driver/tcpm/anx74xx.h b/driver/tcpm/anx74xx.h index 127af4e0b5..06720650bd 100644 --- a/driver/tcpm/anx74xx.h +++ b/driver/tcpm/anx74xx.h @@ -181,6 +181,10 @@ #define BIT_VALUE_OF_SNK_CC_DEFAULT 0x04 #define BIT_VALUE_OF_SNK_CC_1_P_5 0x08 #define BIT_VALUE_OF_SNK_CC_3_P_0 0x0C +#define ANX74XX_CC_RA_MASK (BIT_VALUE_OF_SRC_CC_RA | \ + (BIT_VALUE_OF_SRC_CC_RA << 4)) +#define ANX74XX_CC_RD_MASK (BIT_VALUE_OF_SRC_CC_RD | \ + (BIT_VALUE_OF_SRC_CC_RD << 4)) extern const struct tcpm_drv anx74xx_tcpm_drv; extern const struct usb_mux_driver anx74xx_tcpm_usb_mux_driver; |