summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/tcpm/rt1718s.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/driver/tcpm/rt1718s.c b/driver/tcpm/rt1718s.c
index 175f471fe5..cd32f85da4 100644
--- a/driver/tcpm/rt1718s.c
+++ b/driver/tcpm/rt1718s.c
@@ -409,18 +409,38 @@ void rt1718s_vendor_defined_alert(int port)
if (rv)
return;
- if ((int1 & RT1718S_RT_INT1_INT_RX_FRS)) {
- atomic_or(&frs_flag[port], FLAG_FRS_RX_SIGNALLED);
- /* notify TCPM we got FRS signal */
- pd_got_frs_signal(port);
+ if ((int1 & RT1718S_RT_INT1_INT_RX_FRS) &&
+ frs_flag[port] & FLAG_FRS_ENABLED) {
+ /*
+ * 1. Sometimes we get Rx signalled even if the
+ * FRS is disabled, so filter it.
+ * 2. Only call pd_got_frs_signal when this is the first
+ * Rx interrupt for this FRS swap, and the FRS is
+ * enabled. The Rx interrupt may re-send when the
+ * sink voltage is 5V, and this will make us re-entry
+ * the FRS states.
+ * 3. When a FRS hub detached, RT1718S will
+ * raise FRS RX alert as well. In this case,
+ * we are unable to audit the errors in time,
+ * we will still enter the FRS AMS, but it will
+ * fail eventually, and back to CC open state.
+ */
+ if (!(frs_flag[port] & FLAG_FRS_RX_SIGNALLED)) {
+ atomic_or(&frs_flag[port],
+ FLAG_FRS_RX_SIGNALLED);
+ /* notify TCPM we got FRS signal */
+ pd_got_frs_signal(port);
+ }
}
if ((int1 & RT1718S_RT_INT1_INT_VBUS_FRS_LOW)) {
/*
- * VBUS_FRS_LOW alert could be sent multiple times,
- * filter it here.
+ * Only process if have had rx signalled.
+ * VBUS_FRS_LOW alert could be raised multiple times
+ * if VBUS 5V is glitched.
*/
- if (!(frs_flag[port] & FLAG_FRS_VBUS_VALID_FALL)) {
+ if ((frs_flag[port] & FLAG_FRS_RX_SIGNALLED) &&
+ !(frs_flag[port] & FLAG_FRS_VBUS_VALID_FALL)) {
atomic_or(&frs_flag[port],
FLAG_FRS_VBUS_VALID_FALL);
/*