diff options
Diffstat (limited to 'common/usbc/usb_tc_drp_acc_trysrc_sm.c')
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 32dff84fa1..c8bf4f589a 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -395,6 +395,11 @@ static struct type_c { * the state definitions. */ uint64_t pd_debounce; + /* + * Time to ignore Vbus absence due to external IC debounce detection + * logic immediately after a power role swap. + */ + uint64_t vbus_debounce_time; #ifdef CONFIG_USB_PD_TRY_SRC /* * Time a port shall wait before it can determine it is @@ -805,6 +810,16 @@ void tc_pr_swap_complete(int port, bool success) { TC_CLR_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS); + if (IS_ATTACHED_SNK(port)) { + /* + * Give the ADCs in the TCPC or PPC time to react following + * a PS_RDY message received during a SRC to SNK swap. + * Note: This is empirically determined, not strictly + * part of the USB PD spec. + */ + tc[port].vbus_debounce_time = get_time().val + PD_T_DEBOUNCE; + } + /* * AutoDischargeDisconnect was either turned off near the SNK->SRC * PR-Swap message or when we hit Safe0V on SRC->SNK PR-Swap. @@ -2192,8 +2207,12 @@ static void tc_attached_snk_run(const int port) */ if (!TC_CHK_FLAG(port, TC_FLAGS_POWER_OFF_SNK) && !TC_CHK_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS)) { - /* Detach detection */ - if (!pd_is_vbus_present(port)) { + /* + * Detach detection, but only after allowing for a debounce + * of the VBUS state. + */ + if ((tc[port].vbus_debounce_time < get_time().val) && + !pd_is_vbus_present(port)) { if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); |