diff options
author | Aseda Aboagye <aaboagye@google.com> | 2018-08-23 01:10:14 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2018-09-01 00:34:44 +0000 |
commit | 6926dc4b01898e58475dcec6b47708b4ccb663f6 (patch) | |
tree | 59a64dad818044d54cbb06173e5fca4b59ec2bb1 | |
parent | 4e9dac68e7da256437101a0e45e9b9a9ec4c4cab (diff) | |
download | chrome-ec-6926dc4b01898e58475dcec6b47708b4ccb663f6.tar.gz |
USB PD: Defer entering LPM by 5 seconds at init.
When the EC boots up from a charger being plugged in, the TCPC may
briefly report that there is nothing connected to it via sampling its CC
lines. Our PD state machine would decide to put the TCPC into "low
power mode" by setting the dual-role auto toggle functionality. The
port is deemed not connected at this point and shortly after, charge
manager may choose a charge port of "none" and cut off the VBUS coming
into the system. This is especially problematic in the deeply
discharged battery case as it would result in a charger being physically
plugged into the port, but not actually charging the battery.
This commit simply adds a delay of 5 seconds before allowing a port to
enter it's auto toggle mode. This gives the state machine a chance to
continuously poll the CC lines during which the TCPC actually reports
that there is a partner plugged into the port and begin the discovery.
BUG=b:112954174
BRANCH=nocturne
TEST=Flash nocturne; cutoff battery, plug in AC, verify that VBUS is not
dropped from the system.
Change-Id: I7cb897ec442fd42b96a397f74bbc206a705d2df8
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1187342
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Nick Vaccaro <nvaccaro@google.com>
Commit-Queue: Aseda Aboagye <aaboagye@chromium.org>
(cherry picked from commit 8e9854feab750c3c5ae5a9f12d0f93f5e62aff65)
Reviewed-on: https://chromium-review.googlesource.com/1200266
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index e165523676..0e879b05cb 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -2328,6 +2328,16 @@ static int pd_restart_tcpc(int port) } #endif +#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE +#define DRP_AUTO_TOGGLE_ALLOWED_DELAY_US (5 * SECOND) +static uint8_t auto_toggle_allowed; +static void allow_drp_auto_toggle(void) +{ + auto_toggle_allowed = 1; +} +DECLARE_DEFERRED(allow_drp_auto_toggle); +#endif /* CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE */ + void pd_task(void *u) { int head; @@ -2481,6 +2491,17 @@ void pd_task(void *u) typec_set_input_current_limit(port, 0, 0); charge_manager_update_dualrole(port, CAP_UNKNOWN); #endif +#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE + /* + * Delay entering PD_STATE_DRP_AUTO_TOGGLE by + * DRP_AUTO_TOGGLE_ALLOWED_DELAY_US, such that we don't dismiss a + * charger from being detected as a source. Otherwise, shortly after + * init, we may think that nothing is connected and remain in the auto + * toggle state and never charge our battery. + */ + hook_call_deferred(&allow_drp_auto_toggle_data, + DRP_AUTO_TOGGLE_ALLOWED_DELAY_US); +#endif /* CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE */ while (1) { #ifdef CONFIG_USB_PD_REV30 @@ -2608,9 +2629,10 @@ void pd_task(void *u) #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE /* * Attempt TCPC auto DRP toggle if it is - * not already auto toggling and not try.src + * allowed, not already auto toggling, and not try.src */ if (auto_toggle_supported && + auto_toggle_allowed && !(pd[port].flags & PD_FLAGS_TCPC_DRP_TOGGLE) && !(pd[port].flags & PD_FLAGS_TRY_SRC) && (cc1 == TYPEC_CC_VOLT_OPEN && @@ -3094,9 +3116,10 @@ void pd_task(void *u) #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE /* * Attempt TCPC auto DRP toggle if it is - * not already auto toggling and not try.src + * allowed, not already auto toggling, and not try.src */ if (auto_toggle_supported && + auto_toggle_allowed && !(pd[port].flags & PD_FLAGS_TCPC_DRP_TOGGLE) && !(pd[port].flags & PD_FLAGS_TRY_SRC) && (cc1 == TYPEC_CC_VOLT_OPEN && |