summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/eve/board.c2
-rw-r--r--board/poppy/board.c1
-rw-r--r--board/reef/board.c1
-rw-r--r--common/usb_pd_protocol.c6
-rw-r--r--driver/tcpm/anx74xx.c70
-rw-r--r--driver/tcpm/anx74xx.h4
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, &reg))
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;