diff options
author | Diana Z <dzigterman@chromium.org> | 2021-02-24 17:02:52 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-03-16 21:36:15 +0000 |
commit | 91ad865eaf32295240b62b5fbbd402c2023c187c (patch) | |
tree | 8356a43777aa5384ff60e9e894206e17c041b6be /common/usbc/usb_tc_drp_acc_trysrc_sm.c | |
parent | 657c9f952da217d18e55fb139e5e59f3cd58c670 (diff) | |
download | chrome-ec-91ad865eaf32295240b62b5fbbd402c2023c187c.tar.gz |
TCPMv2: Debounce Vbus loss when FRS is enabled
A hub may send a Fast Role Swap signal when Vbus is less than vSafe5V,
so allow a 5ms debounce after Vbus loss for the signal to come in before
we declare the connection detached.
BRANCH=None
BUG=b:180453483
TEST=on voxel, confirm FRS behaves normally
Signed-off-by: Diana Z <dzigterman@chromium.org>
Change-Id: If56106660c0a2bf82e28b91129bc9dd367ebc8fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2718838
Tested-by: Eric Herrmann <eherrmann@chromium.org>
Reviewed-by: Eric Herrmann <eherrmann@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'common/usbc/usb_tc_drp_acc_trysrc_sm.c')
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 58fc085a61..50211feacf 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -2427,6 +2427,46 @@ static void tc_attached_snk_entry(const int port) tcpm_debug_accessory(port, 1); } +/* + * Check whether Vbus has been removed on this port, accounting for some Vbus + * debounce if FRS is enabled. + * + * Returns true if a new state was set and the calling run should exit. + */ +static bool tc_snk_check_vbus_removed(const int port) +{ + if (IS_ENABLED(CONFIG_USB_PD_FRS)) { + /* + * Debounce Vbus presence when FRS is enabled. Note that we may + * lose Vbus before the FRS signal comes in to let us know + * we're PR swapping, but we must still transition to unattached + * within tSinkDisconnect. + * + * We may safely re-use the Vbus debounce timer here + * since a PR swap would no longer be in progress when Vbus + * removal is checked. + */ + if (pd_check_vbus_level(port, VBUS_REMOVED)) { + if (pd_timer_is_disabled(port, + TC_TIMER_VBUS_DEBOUNCE)) { + pd_timer_enable(port, TC_TIMER_VBUS_DEBOUNCE, + PD_T_FRS_VBUS_DEBOUNCE); + } else if (pd_timer_is_expired(port, + TC_TIMER_VBUS_DEBOUNCE)) { + set_state_tc(port, TC_UNATTACHED_SNK); + return true; + } + } else { + pd_timer_disable(port, TC_TIMER_VBUS_DEBOUNCE); + } + } else if (pd_check_vbus_level(port, VBUS_REMOVED)) { + set_state_tc(port, TC_UNATTACHED_SNK); + return true; + } + + return false; +} + static void tc_attached_snk_run(const int port) { #ifdef CONFIG_USB_PE_SM @@ -2465,6 +2505,7 @@ static void tc_attached_snk_run(const int port) pd_timer_is_expired(port, TC_TIMER_VBUS_DEBOUNCE)) { /* PR Swap is no longer in progress */ TC_CLR_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS); + pd_timer_disable(port, TC_TIMER_VBUS_DEBOUNCE); /* * AutoDischargeDisconnect was turned off when we @@ -2485,10 +2526,8 @@ static void tc_attached_snk_run(const int port) /* * Detach detection */ - if (pd_check_vbus_level(port, VBUS_REMOVED)) { - set_state_tc(port, TC_UNATTACHED_SNK); + if (tc_snk_check_vbus_removed(port)) return; - } if (!pe_is_explicit_contract(port)) sink_power_sub_states(port); @@ -2577,10 +2616,8 @@ static void tc_attached_snk_run(const int port) #else /* CONFIG_USB_PE_SM */ /* Detach detection */ - if (pd_check_vbus_level(port, VBUS_REMOVED)) { - set_state_tc(port, TC_UNATTACHED_SNK); + if (tc_snk_check_vbus_removed(port)) return; - } /* Run Sink Power Sub-State */ sink_power_sub_states(port); |