diff options
author | Jameson Thies <jthies@google.com> | 2022-07-29 19:56:20 +0000 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-08-16 15:50:08 +0000 |
commit | e273823c19f2f902a67ccbdee51489119bb28669 (patch) | |
tree | 51ad7d2f81af29187996073b9cb0885492181688 /common | |
parent | 2e68f3ee03f51fb0a3f8c0cad6868b2f1fb34a5a (diff) | |
download | chrome-ec-e273823c19f2f902a67ccbdee51489119bb28669.tar.gz |
TCMPV2: Add USB PD power button support in S0/S0ix/S3 states
Currently a USB PD power button can only be used wake a device which is
shutdown. To account for devices which use a USB PD power button and
cannot enable a HID interface, this CL adds USB PD power button support
to Suspend and On power states. When a device is either suspended or on,
a short USB PD power button press will simulate a 500ms power button
press and a long USB PD power button press will shutdown the device.
BUG=b:236022894
TEST=make try_build_boards, make runhosttests and zmake test
test-drivers. Also working interactively with a dock that supports
sending alerts on button presses.
BRANCH=None
Signed-off-by: Jameson Thies <jthies@google.com>
Change-Id: I3a8adaa01dbf07a03b0e1451d3a5af5d5f39c442
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3794615
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
Diffstat (limited to 'common')
-rw-r--r-- | common/power_button.c | 30 | ||||
-rw-r--r-- | common/usbc/usb_pd_dpm.c | 78 | ||||
-rw-r--r-- | common/usbc/usb_pd_timer.c | 7 |
3 files changed, 82 insertions, 33 deletions
diff --git a/common/power_button.c b/common/power_button.c index 9fd4cbdb36..aec4571cd7 100644 --- a/common/power_button.c +++ b/common/power_button.c @@ -200,6 +200,22 @@ void power_button_interrupt(enum gpio_signal signal) power_button.debounce_us); } +void power_button_simulate_press(int duration) +{ + ccprintf("Simulating %d ms %s press.\n", duration, power_button.name); + simulate_power_pressed = 1; + power_button_is_stable = 0; + hook_call_deferred(&power_button_change_deferred_data, 0); + + if (duration > 0) + msleep(duration); + + ccprintf("Simulating %s release.\n", power_button.name); + simulate_power_pressed = 0; + power_button_is_stable = 0; + hook_call_deferred(&power_button_change_deferred_data, 0); +} + /*****************************************************************************/ /* Console commands */ @@ -214,19 +230,7 @@ static int command_powerbtn(int argc, char **argv) return EC_ERROR_PARAM1; } - ccprintf("Simulating %d ms %s press.\n", ms, power_button.name); - simulate_power_pressed = 1; - power_button_is_stable = 0; - hook_call_deferred(&power_button_change_deferred_data, 0); - - if (ms > 0) - msleep(ms); - - ccprintf("Simulating %s release.\n", power_button.name); - simulate_power_pressed = 0; - power_button_is_stable = 0; - hook_call_deferred(&power_button_change_deferred_data, 0); - + power_button_simulate_press(ms); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn, "[msec]", diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c index 845bd89031..d3da5a89e5 100644 --- a/common/usbc/usb_pd_dpm.c +++ b/common/usbc/usb_pd_dpm.c @@ -16,6 +16,7 @@ #include "ec_commands.h" #include "hooks.h" #include "power.h" +#include "power_button.h" #include "system.h" #include "task.h" #include "tcpm/tcpm.h" @@ -521,6 +522,16 @@ void dpm_handle_alert(int port, uint32_t ado) static void dpm_run_pd_button_sm(int port) { +#ifdef CONFIG_AP_POWER_CONTROL + if (!IS_ENABLED(CONFIG_POWER_BUTTON_X86) && + !IS_ENABLED(CONFIG_CHIPSET_SC7180) && + !IS_ENABLED(CONFIG_CHIPSET_SC7280)) { + /* Insufficient chipset API support for USB PD power button. */ + DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED); + DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED); + return; + } + /* * Check for invalid flag combination. Alerts can only send a press or * release event at once and only one flag should be set. If press and @@ -532,7 +543,8 @@ static void dpm_run_pd_button_sm(int port) DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED)) { DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED | DPM_FLAG_PD_BUTTON_RELEASED); - pd_timer_disable(port, DPM_TIMER_PD_BUTTON_PRESS); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS); dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; return; } @@ -540,36 +552,64 @@ static void dpm_run_pd_button_sm(int port) switch (dpm[port].pd_button_state) { case DPM_PD_BUTTON_IDLE: if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED)) { - pd_timer_enable(port, DPM_TIMER_PD_BUTTON_PRESS, + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS, + CONFIG_USB_PD_SHORT_PRESS_MAX_MS * + MSEC); + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS, CONFIG_USB_PD_LONG_PRESS_MAX_MS * MSEC); dpm[port].pd_button_state = DPM_PD_BUTTON_PRESSED; } break; case DPM_PD_BUTTON_PRESSED: if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED)) { - pd_timer_enable(port, DPM_TIMER_PD_BUTTON_PRESS, + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS, + CONFIG_USB_PD_SHORT_PRESS_MAX_MS * + MSEC); + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS, CONFIG_USB_PD_LONG_PRESS_MAX_MS * MSEC); - } else if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED)) { - pd_timer_disable(port, DPM_TIMER_PD_BUTTON_PRESS); - dpm[port].pd_button_state = DPM_PD_BUTTON_RELEASED; - } else if (pd_timer_is_expired(port, - DPM_TIMER_PD_BUTTON_PRESS)) { - pd_timer_disable(port, DPM_TIMER_PD_BUTTON_PRESS); + } else if (pd_timer_is_expired( + port, DPM_TIMER_PD_BUTTON_LONG_PRESS)) { + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS); dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; - } - break; - case DPM_PD_BUTTON_RELEASED: -#ifdef CONFIG_AP_POWER_CONTROL - if (IS_ENABLED(CONFIG_POWER_BUTTON_X86) || - IS_ENABLED(CONFIG_CHIPSET_SC7180) || - IS_ENABLED(CONFIG_CHIPSET_SC7280)) { - if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + } else if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED)) { + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + /* + * Wake chipset on any button press when the + * system is off. + */ chipset_power_on(); + } else if (chipset_in_state( + CHIPSET_STATE_ANY_SUSPEND) || + chipset_in_state(CHIPSET_STATE_ON)) { + if (pd_timer_is_expired( + port, + DPM_TIMER_PD_BUTTON_SHORT_PRESS)) { + /* + * Shutdown chipset on long USB PD power + * button press. + */ + chipset_force_shutdown( + CHIPSET_SHUTDOWN_BUTTON); + } else { + /* + * Simulate a short power button press + * on short USB PD power button press. + * This will wake the system from + * suspend, or bring up the power UI + * when the system is on. + */ + power_button_simulate_press( + USB_PD_SHORT_BUTTON_PRESS_MS); + } + } + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS); + dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; } -#endif - dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; break; } +#endif /* CONFIG_AP_POWER_CONTROL */ /* After checking flags, clear them. */ DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED); diff --git a/common/usbc/usb_pd_timer.c b/common/usbc/usb_pd_timer.c index 83f1be0d29..b99ea6540c 100644 --- a/common/usbc/usb_pd_timer.c +++ b/common/usbc/usb_pd_timer.c @@ -52,6 +52,8 @@ static int count[MAX_PD_PORTS]; static int max_count[MAX_PD_PORTS]; __maybe_unused static __const_data const char *const pd_timer_names[] = { + [DPM_TIMER_PD_BUTTON_LONG_PRESS] = "DPM-PD_BUTTON_LONG_PRESS", + [DPM_TIMER_PD_BUTTON_SHORT_PRESS] = "DPM-PD_BUTTON_SHORT_PRESS", [PE_TIMER_BIST_CONT_MODE] = "PE-BIST_CONT_MODE", [PE_TIMER_CHUNKING_NOT_SUPPORTED] = "PE-CHUNKING_NOT_SUPPORTED", [PE_TIMER_DISCOVER_IDENTITY] = "PE-DISCOVER_IDENTITY", @@ -86,7 +88,6 @@ __maybe_unused static __const_data const char *const pd_timer_names[] = { [TC_TIMER_TIMEOUT] = "TC-TIMEOUT", [TC_TIMER_TRY_WAIT_DEBOUNCE] = "TC-TRY_WAIT_DEBOUNCE", [TC_TIMER_VBUS_DEBOUNCE] = "TC-VBUS_DEBOUNCE", - [DPM_TIMER_PD_BUTTON_PRESS] = "DPM-PD_BUTTON_PRESS", }; /***************************************************************************** @@ -170,6 +171,10 @@ void pd_timer_disable_range(int port, enum pd_timer_range range) enum pd_task_timer timer; switch (range) { + case DPM_TIMER_RANGE: + start = DPM_TIMER_START; + end = DPM_TIMER_END; + break; case PE_TIMER_RANGE: start = PE_TIMER_START; end = PE_TIMER_END; |