diff options
Diffstat (limited to 'common/power_button.c')
-rw-r--r-- | common/power_button.c | 227 |
1 files changed, 0 insertions, 227 deletions
diff --git a/common/power_button.c b/common/power_button.c deleted file mode 100644 index 1ac3893492..0000000000 --- a/common/power_button.c +++ /dev/null @@ -1,227 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Power button module for Chrome EC */ - -#include "button.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "keyboard_scan.h" -#include "lid_switch.h" -#include "power_button.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_SWITCH, outstr) -#define CPRINTS(format, args...) cprints(CC_SWITCH, format, ## args) - -/* By default the power button is active low */ -#ifndef CONFIG_POWER_BUTTON_FLAGS -#define CONFIG_POWER_BUTTON_FLAGS 0 -#endif - -static int debounced_power_pressed; /* Debounced power button state */ -static int simulate_power_pressed; -static volatile int power_button_is_stable = 1; - -static const struct button_config power_button = { - .name = "power button", - .gpio = GPIO_POWER_BUTTON_L, - .debounce_us = BUTTON_DEBOUNCE_US, - .flags = CONFIG_POWER_BUTTON_FLAGS, -}; - -int power_button_signal_asserted(void) -{ - return !!(gpio_get_level(power_button.gpio) - == (power_button.flags & BUTTON_FLAG_ACTIVE_HIGH) ? 1 : 0); -} - -/** - * Get raw power button signal state. - * - * @return 1 if power button is pressed, 0 if not pressed. - */ -static int raw_power_button_pressed(void) -{ - if (simulate_power_pressed) - return 1; - -#ifndef CONFIG_POWER_BUTTON_IGNORE_LID - /* - * Always indicate power button released if the lid is closed. - * This prevents waking the system if the device is squashed enough to - * press the power button through the closed lid. - */ - if (!lid_is_open()) - return 0; -#endif - - return power_button_signal_asserted(); -} - -int power_button_is_pressed(void) -{ - return debounced_power_pressed; -} - -int power_button_wait_for_release(int timeout_us) -{ - timestamp_t deadline; - timestamp_t now = get_time(); - - deadline.val = now.val + timeout_us; - - while (!power_button_is_stable || power_button_is_pressed()) { - now = get_time(); - if (timeout_us >= 0 && timestamp_expired(deadline, &now)) { - CPRINTS("%s not released in time", power_button.name); - return EC_ERROR_TIMEOUT; - } - /* - * We use task_wait_event() instead of usleep() here. It will - * be woken up immediately if the power button is debouned and - * changed. However, it is not guaranteed, like the cases that - * the power button is debounced but not changed, or the power - * button has not been debounced. - */ - task_wait_event(MIN(power_button.debounce_us, - deadline.val - now.val)); - } - - CPRINTS("%s released in time", power_button.name); - return EC_SUCCESS; -} - -/** - * Handle power button initialization. - */ -static void power_button_init(void) -{ - if (raw_power_button_pressed()) - debounced_power_pressed = 1; - - /* Enable interrupts, now that we've initialized */ - gpio_enable_interrupt(power_button.gpio); -} -DECLARE_HOOK(HOOK_INIT, power_button_init, HOOK_PRIO_INIT_POWER_BUTTON); - -#ifdef CONFIG_POWER_BUTTON_INIT_IDLE -/* - * Set/clear AP_IDLE flag. It's set when the system gracefully shuts down and - * it's cleared when the system boots up. The result is the system tries to - * go back to the previous state upon AC plug-in. If the system uncleanly - * shuts down, it boots immediately. If the system shuts down gracefully, - * it'll stay at S5 and wait for power button press. - */ -static void pb_chipset_startup(void) -{ - chip_save_reset_flags(chip_read_reset_flags() & ~EC_RESET_FLAG_AP_IDLE); - system_clear_reset_flags(EC_RESET_FLAG_AP_IDLE); - CPRINTS("Cleared AP_IDLE flag"); -} -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pb_chipset_startup, HOOK_PRIO_DEFAULT); - -static void pb_chipset_shutdown(void) -{ - chip_save_reset_flags(chip_read_reset_flags() | EC_RESET_FLAG_AP_IDLE); - system_set_reset_flags(EC_RESET_FLAG_AP_IDLE); - CPRINTS("Saved AP_IDLE flag"); -} -DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pb_chipset_shutdown, - /* - * Slightly higher than handle_pending_reboot because - * it may clear AP_IDLE flag. - */ - HOOK_PRIO_DEFAULT - 1); -#endif - -/** - * Handle debounced power button changing state. - */ -static void power_button_change_deferred(void) -{ - const int new_pressed = raw_power_button_pressed(); - - /* Re-enable keyboard scanning if power button is no longer pressed */ - if (!new_pressed) - keyboard_scan_enable(1, KB_SCAN_DISABLE_POWER_BUTTON); - - /* If power button hasn't changed state, nothing to do */ - if (new_pressed == debounced_power_pressed) { - power_button_is_stable = 1; - return; - } - - debounced_power_pressed = new_pressed; - power_button_is_stable = 1; - - CPRINTS("%s %s", - power_button.name, new_pressed ? "pressed" : "released"); - - /* Call hooks */ - hook_notify(HOOK_POWER_BUTTON_CHANGE); - - /* Notify host if power button has been pressed */ - if (new_pressed) - host_set_single_event(EC_HOST_EVENT_POWER_BUTTON); -} -DECLARE_DEFERRED(power_button_change_deferred); - -void power_button_interrupt(enum gpio_signal signal) -{ - /* - * If power button is pressed, disable the matrix scan as soon as - * possible to reduce the risk of false-reboot triggered by those keys - * on the same column with refresh key. - */ - if (raw_power_button_pressed()) - keyboard_scan_enable(0, KB_SCAN_DISABLE_POWER_BUTTON); - - /* Reset power button debounce time */ - power_button_is_stable = 0; - hook_call_deferred(&power_button_change_deferred_data, - power_button.debounce_us); -} - -/*****************************************************************************/ -/* Console commands */ - -static int command_powerbtn(int argc, char **argv) -{ - int ms = 200; /* Press duration in ms */ - char *e; - - if (argc > 1) { - ms = strtoi(argv[1], &e, 0); - if (*e) - 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); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn, - "[msec]", - "Simulate power button press"); - |