summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJameson Thies <jthies@google.com>2022-07-29 19:56:20 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-08-16 15:50:08 +0000
commite273823c19f2f902a67ccbdee51489119bb28669 (patch)
tree51ad7d2f81af29187996073b9cb0885492181688 /common
parent2e68f3ee03f51fb0a3f8c0cad6868b2f1fb34a5a (diff)
downloadchrome-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.c30
-rw-r--r--common/usbc/usb_pd_dpm.c78
-rw-r--r--common/usbc/usb_pd_timer.c7
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;