summaryrefslogtreecommitdiff
path: root/common/button.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/button.c')
-rw-r--r--common/button.c892
1 files changed, 0 insertions, 892 deletions
diff --git a/common/button.c b/common/button.c
deleted file mode 100644
index 03bdb1234f..0000000000
--- a/common/button.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/* Copyright 2014 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.
- */
-
-/* Button module for Chrome EC */
-
-#include "atomic.h"
-#include "button.h"
-#include "chipset.h"
-#include "common.h"
-#include "compile_time_macros.h"
-#include "console.h"
-#include "gpio.h"
-#include "host_command.h"
-#include "hooks.h"
-#include "keyboard_protocol.h"
-#include "led_common.h"
-#include "mkbp_input_devices.h"
-#include "power_button.h"
-#include "system.h"
-#include "timer.h"
-#include "util.h"
-#include "watchdog.h"
-
-/* Console output macro */
-#define CPRINTS(format, args...) cprints(CC_SWITCH, format, ## args)
-
-struct button_state_t {
- uint64_t debounce_time;
- int debounced_pressed;
-};
-
-static struct button_state_t __bss_slow state[BUTTON_COUNT];
-
-static uint64_t __bss_slow next_deferred_time;
-
-#if defined(CONFIG_CMD_BUTTON) || defined(CONFIG_HOSTCMD_BUTTON)
-#define CONFIG_SIMULATED_BUTTON
-#endif
-
-#ifdef CONFIG_SIMULATED_BUTTON
-/* Bitmask to keep track of simulated state of each button.
- * Bit numbers are aligned to enum button.
- */
-static int sim_button_state;
-
-/*
- * Flip state of associated button type in sim_button_state bitmask.
- * In bitmask, if bit is 1, button is pressed. If bit is 0, button is
- * released.
- *
- * Returns the appropriate GPIO value based on table below:
- * +----------+--------+--------+
- * | state | active | return |
- * +----------+--------+--------+
- * | pressed | high | 1 |
- * | pressed | low | 0 |
- * | released | high | 0 |
- * | released | low | 1 |
- * +----------+--------+--------+
- */
-static int simulated_button_pressed(const struct button_config *button)
-{
- return !!(sim_button_state & BIT(button->type));
-}
-#endif
-
-/*
- * Whether a button is currently pressed.
- */
-static int raw_button_pressed(const struct button_config *button)
-{
- int physical_value = 0;
- int simulated_value = 0;
- if (!(button->flags & BUTTON_FLAG_DISABLED)) {
- if (IS_ENABLED(CONFIG_ADC_BUTTONS) &&
- button_is_adc_detected(button->gpio)) {
- physical_value =
- adc_to_physical_value(button->gpio);
- } else {
- physical_value = (!!gpio_get_level(button->gpio) ==
- !!(button->flags & BUTTON_FLAG_ACTIVE_HIGH));
- }
-#ifdef CONFIG_SIMULATED_BUTTON
- simulated_value = simulated_button_pressed(button);
-#endif
- }
-
- return (simulated_value || physical_value);
-}
-
-#ifdef CONFIG_BUTTON_TRIGGERED_RECOVERY
-
-#ifdef CONFIG_LED_COMMON
-static void button_blink_hw_reinit_led(void)
-{
- int led_state = LED_STATE_ON;
- timestamp_t deadline;
- timestamp_t now = get_time();
-
- /* Blink LED for 3 seconds. */
- deadline.val = now.val + (3 * SECOND);
-
- while (!timestamp_expired(deadline, &now)) {
- led_control(EC_LED_ID_RECOVERY_HW_REINIT_LED, led_state);
- led_state = !led_state;
- watchdog_reload();
- msleep(100);
- now = get_time();
- }
-
- /* Reset LED to default state. */
- led_control(EC_LED_ID_RECOVERY_HW_REINIT_LED, LED_STATE_RESET);
-}
-#endif
-
-/*
- * Whether recovery button (or combination of equivalent buttons) is pressed
- * If a dedicated recovery button is used, any of the buttons can be pressed,
- * otherwise, all the buttons must be pressed.
- */
-static int is_recovery_button_pressed(void)
-{
- int i, pressed;
- for (i = 0; i < recovery_buttons_count; i++) {
- pressed = raw_button_pressed(recovery_buttons[i]);
- if (IS_ENABLED(CONFIG_DEDICATED_RECOVERY_BUTTON)) {
- if (pressed)
- return 1;
- } else {
- if (!pressed)
- return 0;
- }
- }
- return IS_ENABLED(CONFIG_DEDICATED_RECOVERY_BUTTON) ? 0 : 1;
-}
-
-/*
- * If the EC is reset and recovery is requested, then check if HW_REINIT is
- * requested as well. Since the EC reset occurs after volup+voldn+power buttons
- * are held down for 10 seconds, check the state of these buttons for 20 more
- * seconds. If they are still held down all this time, then set host event to
- * indicate HW_REINIT is requested. Also, make sure watchdog is reloaded in
- * order to prevent watchdog from resetting the EC.
- */
-static void button_check_hw_reinit_required(void)
-{
- timestamp_t deadline;
- timestamp_t now = get_time();
-#ifdef CONFIG_LED_COMMON
- uint8_t led_on = 0;
-#endif
-
- deadline.val = now.val + (20 * SECOND);
-
- CPRINTS("Checking for HW_REINIT request");
-
- while (!timestamp_expired(deadline, &now)) {
- if (!is_recovery_button_pressed() ||
- !power_button_signal_asserted()) {
- CPRINTS("No HW_REINIT request");
-#ifdef CONFIG_LED_COMMON
- if (led_on)
- led_control(EC_LED_ID_RECOVERY_HW_REINIT_LED,
- LED_STATE_RESET);
-#endif
- return;
- }
-
-#ifdef CONFIG_LED_COMMON
- if (!led_on) {
- led_control(EC_LED_ID_RECOVERY_HW_REINIT_LED,
- LED_STATE_ON);
- led_on = 1;
- }
-#endif
-
- now = get_time();
- watchdog_reload();
- }
-
- CPRINTS("HW_REINIT requested");
- host_set_single_event(EC_HOST_EVENT_KEYBOARD_RECOVERY_HW_REINIT);
-
-#ifdef CONFIG_LED_COMMON
- button_blink_hw_reinit_led();
-#endif
-}
-
-static int is_recovery_boot(void)
-{
- if (system_jumped_to_this_image())
- return 0;
- if (!(system_get_reset_flags() &
- (EC_RESET_FLAG_RESET_PIN | EC_RESET_FLAG_POWER_ON)))
- return 0;
- if (!is_recovery_button_pressed())
- return 0;
- return 1;
-}
-#endif /* CONFIG_BUTTON_TRIGGERED_RECOVERY */
-
-static void button_reset(enum button button_type,
- const struct button_config *button)
-{
- state[button_type].debounced_pressed = raw_button_pressed(button);
- state[button_type].debounce_time = 0;
- gpio_enable_interrupt(button->gpio);
-}
-
-/*
- * Button initialization.
- */
-void button_init(void)
-{
- int i;
-
- CPRINTS("init buttons");
- next_deferred_time = 0;
- for (i = 0; i < BUTTON_COUNT; i++)
- button_reset(i, &buttons[i]);
-
-#ifdef CONFIG_BUTTON_TRIGGERED_RECOVERY
- if (is_recovery_boot()) {
- system_clear_reset_flags(EC_RESET_FLAG_AP_OFF);
- host_set_single_event(EC_HOST_EVENT_KEYBOARD_RECOVERY);
- button_check_hw_reinit_required();
- }
-#endif /* defined(CONFIG_BUTTON_TRIGGERED_RECOVERY) */
-}
-
-#ifdef CONFIG_BUTTONS_RUNTIME_CONFIG
-int button_reassign_gpio(enum button button_type, enum gpio_signal gpio)
-{
- if (button_type >= BUTTON_COUNT)
- return EC_ERROR_INVAL;
-
- /* Disable currently assigned interrupt */
- gpio_disable_interrupt(buttons[button_type].gpio);
-
- /* Reconfigure GPIO and enable the new interrupt */
- buttons[button_type].gpio = gpio;
- button_reset(button_type, &buttons[button_type]);
-
- return EC_SUCCESS;
-}
-
-int button_disable_gpio(enum button button_type)
-{
- if (button_type >= BUTTON_COUNT)
- return EC_ERROR_INVAL;
-
- /* Disable GPIO interrupt */
- gpio_disable_interrupt(buttons[button_type].gpio);
- /* Mark button as disabled */
- buttons[button_type].flags |= BUTTON_FLAG_DISABLED;
-
- return EC_SUCCESS;
-}
-#endif
-
-
-/*
- * Handle debounced button changing state.
- */
-
-static void button_change_deferred(void);
-DECLARE_DEFERRED(button_change_deferred);
-
-#ifdef CONFIG_EMULATED_SYSRQ
-static void debug_mode_handle(void);
-DECLARE_DEFERRED(debug_mode_handle);
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, debug_mode_handle, HOOK_PRIO_LAST);
-#endif
-
-static void button_change_deferred(void)
-{
- int i;
- int new_pressed;
- uint64_t soonest_debounce_time = 0;
- uint64_t time_now = get_time().val;
-
- for (i = 0; i < BUTTON_COUNT; i++) {
- /* Skip this button if we are not waiting to debounce */
- if (state[i].debounce_time == 0)
- continue;
-
- if (state[i].debounce_time <= time_now) {
- /* Check if the state has changed */
- new_pressed = raw_button_pressed(&buttons[i]);
- if (state[i].debounced_pressed != new_pressed) {
- state[i].debounced_pressed = new_pressed;
-#ifdef CONFIG_EMULATED_SYSRQ
- /*
- * Calling deferred function for handling debug
- * mode so that button change processing is not
- * delayed.
- */
-#ifdef CONFIG_DEDICATED_RECOVERY_BUTTON
- /*
- * Only the direct signal is used for sysrq.
- * H1_EC_RECOVERY_BTN_ODL doesn't reflect the
- * true state of the recovery button.
- */
- if (i == BUTTON_RECOVERY)
-#endif
- hook_call_deferred(
- &debug_mode_handle_data, 0);
-#endif
- CPRINTS("Button '%s' was %s",
- buttons[i].name, new_pressed ?
- "pressed" : "released");
- if (IS_ENABLED(CONFIG_MKBP_INPUT_DEVICES)) {
- mkbp_button_update(buttons[i].type,
- new_pressed);
- } else if (IS_ENABLED(HAS_TASK_KEYPROTO)) {
- keyboard_update_button(buttons[i].type,
- new_pressed);
- }
- }
-
- /* Clear the debounce time to stop checking it */
- state[i].debounce_time = 0;
- } else {
- /*
- * Make sure the next deferred call happens on or before
- * each button needs it.
- */
- soonest_debounce_time = (soonest_debounce_time == 0) ?
- state[i].debounce_time :
- MIN(soonest_debounce_time,
- state[i].debounce_time);
- }
- }
-
- if (soonest_debounce_time != 0) {
- next_deferred_time = soonest_debounce_time;
- hook_call_deferred(&button_change_deferred_data,
- next_deferred_time - time_now);
- }
-}
-
-/*
- * Handle a button interrupt.
- */
-void button_interrupt(enum gpio_signal signal)
-{
- int i;
- uint64_t time_now = get_time().val;
-
- for (i = 0; i < BUTTON_COUNT; i++) {
- if (buttons[i].gpio != signal ||
- (buttons[i].flags & BUTTON_FLAG_DISABLED))
- continue;
-
- state[i].debounce_time = time_now + buttons[i].debounce_us;
- if (next_deferred_time <= time_now ||
- next_deferred_time > state[i].debounce_time) {
- next_deferred_time = state[i].debounce_time;
- hook_call_deferred(&button_change_deferred_data,
- next_deferred_time - time_now);
- }
- break;
- }
-}
-
-#ifdef CONFIG_SIMULATED_BUTTON
-static int button_present(enum keyboard_button_type type)
-{
- int i;
-
- for (i = 0; i < BUTTON_COUNT; i++)
- if (buttons[i].type == type)
- break;
-
- return i;
-}
-
-static void button_interrupt_simulate(int button)
-{
- button_interrupt(buttons[button].gpio);
-}
-
-static void simulate_button_release_deferred(void)
-{
- int button_idx;
-
- /* Release the button */
- for (button_idx = 0; button_idx < BUTTON_COUNT; button_idx++) {
- /* Check state for button pressed */
- if (sim_button_state & BIT(buttons[button_idx].type)) {
- /* Set state of the button as released */
- atomic_clear_bits(&sim_button_state,
- BIT(buttons[button_idx].type));
-
- button_interrupt_simulate(button_idx);
- }
- }
-}
-DECLARE_DEFERRED(simulate_button_release_deferred);
-
-static void simulate_button(uint32_t button_mask, int press_ms)
-{
- int button_idx;
-
- /* Press the button */
- for (button_idx = 0; button_idx < BUTTON_COUNT; button_idx++) {
- if (button_mask & BIT(button_idx)) {
- /* Set state of the button as pressed */
- atomic_or(&sim_button_state,
- BIT(buttons[button_idx].type));
-
- button_interrupt_simulate(button_idx);
- }
- }
-
- /* Defer the button release for specified duration */
- hook_call_deferred(&simulate_button_release_deferred_data,
- press_ms * MSEC);
-}
-#endif /* #ifdef CONFIG_SIMULATED_BUTTON */
-
-#ifdef CONFIG_CMD_BUTTON
-static int console_command_button(int argc, char **argv)
-{
- int press_ms = 50;
- char *e;
- int argv_idx;
- int button = BUTTON_COUNT;
- uint32_t button_mask = 0;
-
- if (argc < 2)
- return EC_ERROR_PARAM_COUNT;
-
- for (argv_idx = 1; argv_idx < argc; argv_idx++) {
- if (!strcasecmp(argv[argv_idx], "vup"))
- button = button_present(KEYBOARD_BUTTON_VOLUME_UP);
- else if (!strcasecmp(argv[argv_idx], "vdown"))
- button = button_present(KEYBOARD_BUTTON_VOLUME_DOWN);
- else if (!strcasecmp(argv[argv_idx], "rec"))
- button = button_present(KEYBOARD_BUTTON_RECOVERY);
- else {
- /* If last parameter check if it is an integer. */
- if (argv_idx == argc - 1) {
- press_ms = strtoi(argv[argv_idx], &e, 0);
- /* If integer, break out of the loop. */
- if (!*e)
- break;
- }
- button = BUTTON_COUNT;
- }
-
- if (button == BUTTON_COUNT)
- return EC_ERROR_PARAM1 + argv_idx - 1;
-
- button_mask |= BIT(button);
- }
-
- if (!button_mask)
- return EC_SUCCESS;
-
- simulate_button(button_mask, press_ms);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(button, console_command_button,
- "vup|vdown|rec msec",
- "Simulate button press");
-#endif /* CONFIG_CMD_BUTTON */
-
-#ifdef CONFIG_HOSTCMD_BUTTON
-static enum ec_status host_command_button(struct host_cmd_handler_args *args)
-{
- const struct ec_params_button *p = args->params;
- int idx;
- uint32_t button_mask = 0;
-
- /* Only available on unlocked systems */
- if (system_is_locked())
- return EC_RES_ACCESS_DENIED;
-
- for (idx = 0; idx < KEYBOARD_BUTTON_COUNT; idx++) {
- if (p->btn_mask & BIT(idx))
- button_mask |= BIT(button_present(idx));
- }
-
- simulate_button(button_mask, p->press_ms);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_BUTTON, host_command_button, EC_VER_MASK(0));
-
-#endif /* CONFIG_HOSTCMD_BUTTON */
-
-
-#ifdef CONFIG_EMULATED_SYSRQ
-
-#ifdef CONFIG_DEDICATED_RECOVERY_BUTTON
-
-/*
- * Simplified sysrq handler
- *
- * In simplified sysrq, user can
- * - press and release recovery button to send one sysrq event to the host
- * - press and hold recovery button for 4 seconds to reset the AP (warm reset)
- */
-static void debug_mode_handle(void)
-{
- static int recovery_button_pressed = 0;
-
- if (!recovery_button_pressed) {
- if (is_recovery_button_pressed()) {
- /* User pressed recovery button. Wait for 4 seconds
- * to see if warm reset is requested. */
- recovery_button_pressed = 1;
- hook_call_deferred(&debug_mode_handle_data, 4 * SECOND);
- }
- } else {
- /* We come here when recovery button is released or when
- * 4 sec elapsed with recovery button still pressed. */
- if (!is_recovery_button_pressed()) {
- /* Cancel pending timer */
- hook_call_deferred(&debug_mode_handle_data, -1);
- host_send_sysrq('x');
- CPRINTS("DEBUG MODE: sysrq-x sent");
- } else {
- chipset_reset(CHIPSET_RESET_DBG_WARM_REBOOT);
- CPRINTS("DEBUG MODE: Warm reset triggered");
- }
- recovery_button_pressed = 0;
- }
-}
-
-#else /* CONFIG_DEDICATED_RECOVERY_BUTTON */
-
-enum debug_state {
- STATE_DEBUG_NONE,
- STATE_DEBUG_CHECK,
- STATE_STAGING,
- STATE_DEBUG_MODE_ACTIVE,
- STATE_SYSRQ_PATH,
- STATE_WARM_RESET_PATH,
- STATE_SYSRQ_EXEC,
- STATE_WARM_RESET_EXEC,
-};
-
-#define DEBUG_BTN_POWER BIT(0)
-#define DEBUG_BTN_VOL_UP BIT(1)
-#define DEBUG_BTN_VOL_DN BIT(2)
-#define DEBUG_TIMEOUT (10 * SECOND)
-
-static enum debug_state curr_debug_state = STATE_DEBUG_NONE;
-static enum debug_state next_debug_state = STATE_DEBUG_NONE;
-static timestamp_t debug_state_deadline;
-static int debug_button_hit_count;
-
-static int debug_button_mask(void)
-{
- int mask = 0;
-
- /* Get power button state */
- if (power_button_is_pressed())
- mask |= DEBUG_BTN_POWER;
-
- /* Get volume up state */
- if (state[BUTTON_VOLUME_UP].debounced_pressed)
- mask |= DEBUG_BTN_VOL_UP;
-
- /* Get volume down state */
- if (state[BUTTON_VOLUME_DOWN].debounced_pressed)
- mask |= DEBUG_BTN_VOL_DN;
-
- return mask;
-}
-
-static int debug_button_pressed(int mask)
-{
- return debug_button_mask() == mask;
-}
-
-#ifdef CONFIG_LED_COMMON
-static int debug_mode_blink_led(void)
-{
- return ((curr_debug_state != STATE_DEBUG_NONE) &&
- (curr_debug_state != STATE_DEBUG_CHECK));
-}
-#endif
-
-static void debug_mode_transition(enum debug_state next_state)
-{
- timestamp_t now = get_time();
-#ifdef CONFIG_LED_COMMON
- int curr_blink_state = debug_mode_blink_led();
-#endif
-
- /* Cancel any deferred calls. */
- hook_call_deferred(&debug_mode_handle_data, -1);
-
- /* Update current debug mode state. */
- curr_debug_state = next_state;
-
- /* Set deadline to 10seconds from current time. */
- debug_state_deadline.val = now.val + DEBUG_TIMEOUT;
-
- switch (curr_debug_state) {
- case STATE_DEBUG_NONE:
- /*
- * Nothing is done here since some states can transition to
- * STATE_DEBUG_NONE in this function. Wait until all other
- * states are evaluated to take the action for STATE_NONE.
- */
- break;
- case STATE_DEBUG_CHECK:
- case STATE_STAGING:
- break;
- case STATE_DEBUG_MODE_ACTIVE:
- debug_button_hit_count = 0;
- break;
- case STATE_SYSRQ_PATH:
- /*
- * Increment debug_button_hit_count and ensure it does not go
- * past 3. If it exceeds the limit transition to STATE_NONE.
- */
- debug_button_hit_count++;
- if (debug_button_hit_count == 4)
- curr_debug_state = STATE_DEBUG_NONE;
- break;
- case STATE_WARM_RESET_PATH:
- break;
- case STATE_SYSRQ_EXEC:
- /*
- * Depending upon debug_button_hit_count, send appropriate
- * number of sysrq events to host and transition to STATE_NONE.
- */
- while (debug_button_hit_count) {
- host_send_sysrq('x');
- CPRINTS("DEBUG MODE: sysrq-x sent");
- debug_button_hit_count--;
- }
- curr_debug_state = STATE_DEBUG_NONE;
- break;
- case STATE_WARM_RESET_EXEC:
- /* Warm reset the host and transition to STATE_NONE. */
- chipset_reset(CHIPSET_RESET_DBG_WARM_REBOOT);
- CPRINTS("DEBUG MODE: Warm reset triggered");
- curr_debug_state = STATE_DEBUG_NONE;
- break;
- default:
- curr_debug_state = STATE_DEBUG_NONE;
- }
-
- if (curr_debug_state != STATE_DEBUG_NONE) {
- /*
- * Schedule a deferred call after DEBUG_TIMEOUT to check for
- * button state if it does not change during the timeout
- * duration.
- */
- hook_call_deferred(&debug_mode_handle_data, DEBUG_TIMEOUT);
- return;
- }
-
- /* If state machine reached initial state, reset all variables. */
- CPRINTS("DEBUG MODE: Exit!");
- next_debug_state = STATE_DEBUG_NONE;
- debug_state_deadline.val = 0;
- debug_button_hit_count = 0;
-#ifdef CONFIG_LED_COMMON
- if (curr_blink_state)
- led_control(EC_LED_ID_SYSRQ_DEBUG_LED, LED_STATE_RESET);
-#endif
-}
-
-static void debug_mode_handle(void)
-{
- int mask;
-
- switch (curr_debug_state) {
- case STATE_DEBUG_NONE:
- /*
- * If user pressed Vup+Vdn, check for next 10 seconds to see if
- * user keeps holding the keys.
- */
- if (debug_button_pressed(DEBUG_BTN_VOL_UP | DEBUG_BTN_VOL_DN))
- debug_mode_transition(STATE_DEBUG_CHECK);
- break;
- case STATE_DEBUG_CHECK:
- /*
- * If no key is pressed or any key combo other than Vup+Vdn is
- * held, then quit debug check mode.
- */
- if (!debug_button_pressed(DEBUG_BTN_VOL_UP | DEBUG_BTN_VOL_DN))
- debug_mode_transition(STATE_DEBUG_NONE);
- else if (timestamp_expired(debug_state_deadline, NULL)) {
- /*
- * If Vup+Vdn are held down for 10 seconds, then its
- * time to enter debug mode.
- */
- CPRINTS("DEBUG MODE: Active!");
- next_debug_state = STATE_DEBUG_MODE_ACTIVE;
- debug_mode_transition(STATE_STAGING);
- }
- break;
- case STATE_STAGING:
- mask = debug_button_mask();
-
- /* If no button is pressed, transition to next state. */
- if (!mask) {
- debug_mode_transition(next_debug_state);
- return;
- }
-
- /* Exit debug mode if keys are stuck for > 10 seconds. */
- if (timestamp_expired(debug_state_deadline, NULL))
- debug_mode_transition(STATE_DEBUG_NONE);
- else {
- timestamp_t now = get_time();
-
- /*
- * Schedule a deferred call in case timeout hasn't
- * occurred yet.
- */
- hook_call_deferred(&debug_mode_handle_data,
- (debug_state_deadline.val - now.val));
- }
-
- break;
- case STATE_DEBUG_MODE_ACTIVE:
- mask = debug_button_mask();
-
- /*
- * Continue in this state if button is not pressed and timeout
- * has not occurred.
- */
- if (!mask && !timestamp_expired(debug_state_deadline, NULL))
- return;
-
- /* Exit debug mode if valid buttons are not pressed. */
- if ((mask != DEBUG_BTN_VOL_UP) && (mask != DEBUG_BTN_VOL_DN)) {
- debug_mode_transition(STATE_DEBUG_NONE);
- return;
- }
-
- /*
- * Transition to STAGING state with next state set to:
- * 1. SYSRQ_PATH : If Vup was pressed.
- * 2. WARM_RESET_PATH: If Vdn was pressed.
- */
- if (mask == DEBUG_BTN_VOL_UP)
- next_debug_state = STATE_SYSRQ_PATH;
- else
- next_debug_state = STATE_WARM_RESET_PATH;
-
- debug_mode_transition(STATE_STAGING);
- break;
- case STATE_SYSRQ_PATH:
- mask = debug_button_mask();
-
- /*
- * Continue in this state if button is not pressed and timeout
- * has not occurred.
- */
- if (!mask && !timestamp_expired(debug_state_deadline, NULL))
- return;
-
- /* Exit debug mode if valid buttons are not pressed. */
- if ((mask != DEBUG_BTN_VOL_UP) && (mask != DEBUG_BTN_VOL_DN)) {
- debug_mode_transition(STATE_DEBUG_NONE);
- return;
- }
-
- if (mask == DEBUG_BTN_VOL_UP) {
- /*
- * Else transition to STAGING state with next state set
- * to SYSRQ_PATH.
- */
- next_debug_state = STATE_SYSRQ_PATH;
- } else {
- /*
- * Else if Vdn is pressed, transition to STAGING with
- * next state set to SYSRQ_EXEC.
- */
- next_debug_state = STATE_SYSRQ_EXEC;
- }
- debug_mode_transition(STATE_STAGING);
- break;
- case STATE_WARM_RESET_PATH:
- mask = debug_button_mask();
-
- /*
- * Continue in this state if button is not pressed and timeout
- * has not occurred.
- */
- if (!mask && !timestamp_expired(debug_state_deadline, NULL))
- return;
-
- /* Exit debug mode if valid buttons are not pressed. */
- if (mask != DEBUG_BTN_VOL_UP) {
- debug_mode_transition(STATE_DEBUG_NONE);
- return;
- }
-
- next_debug_state = STATE_WARM_RESET_EXEC;
- debug_mode_transition(STATE_STAGING);
- break;
- case STATE_SYSRQ_EXEC:
- case STATE_WARM_RESET_EXEC:
- default:
- debug_mode_transition(STATE_DEBUG_NONE);
- break;
- }
-}
-
-#ifdef CONFIG_LED_COMMON
-static void debug_led_tick(void)
-{
- static int led_state = LED_STATE_OFF;
-
- if (debug_mode_blink_led()) {
- led_state = !led_state;
- led_control(EC_LED_ID_SYSRQ_DEBUG_LED, led_state);
- }
-}
-DECLARE_HOOK(HOOK_TICK, debug_led_tick, HOOK_PRIO_DEFAULT);
-#endif /* CONFIG_LED_COMMON */
-
-#endif /* !CONFIG_DEDICATED_RECOVERY_BUTTON */
-#endif /* CONFIG_EMULATED_SYSRQ */
-
-#ifndef CONFIG_BUTTONS_RUNTIME_CONFIG
-const struct button_config buttons[BUTTON_COUNT] = {
-#else
-struct button_config buttons[BUTTON_COUNT] = {
-#endif
-#ifdef CONFIG_VOLUME_BUTTONS
- [BUTTON_VOLUME_UP] = {
- .name = "Volume Up",
- .type = KEYBOARD_BUTTON_VOLUME_UP,
- .gpio = GPIO_VOLUME_UP_L,
- .debounce_us = BUTTON_DEBOUNCE_US,
- .flags = 0,
- },
-
- [BUTTON_VOLUME_DOWN] = {
- .name = "Volume Down",
- .type = KEYBOARD_BUTTON_VOLUME_DOWN,
- .gpio = GPIO_VOLUME_DOWN_L,
- .debounce_us = BUTTON_DEBOUNCE_US,
- .flags = 0,
- },
-
-#endif
-#if defined(CONFIG_DEDICATED_RECOVERY_BUTTON)
- [BUTTON_RECOVERY] = {
- .name = "Recovery",
- .type = KEYBOARD_BUTTON_RECOVERY,
- .gpio = GPIO_RECOVERY_L,
- .debounce_us = BUTTON_DEBOUNCE_US,
- .flags = 0,
- },
-#ifdef CONFIG_DEDICATED_RECOVERY_BUTTON_2
- [BUTTON_RECOVERY_2] = {
- .name = "Recovery2",
- .type = KEYBOARD_BUTTON_RECOVERY,
- .gpio = GPIO_RECOVERY_L_2,
- .debounce_us = BUTTON_DEBOUNCE_US,
- .flags = 0,
- }
-#endif /* defined(CONFIG_DEDICATED_RECOVERY_BUTTON_2) */
-#endif /* defined(CONFIG_DEDICATED_RECOVERY_BUTTON) */
-};
-
-#ifdef CONFIG_BUTTON_TRIGGERED_RECOVERY
-/*
- * Prefer the dedicated recovery button over the volume buttons if
- * both are present.
- */
-const struct button_config *recovery_buttons[] = {
-#ifdef CONFIG_DEDICATED_RECOVERY_BUTTON
- &buttons[BUTTON_RECOVERY],
-
-#ifdef CONFIG_DEDICATED_RECOVERY_BUTTON_2
- &buttons[BUTTON_RECOVERY_2],
-#endif /* defined(CONFIG_BUTTON_TRIGGERED_RECOVERY_2) */
-
-#elif defined(CONFIG_VOLUME_BUTTONS)
- &buttons[BUTTON_VOLUME_DOWN],
- &buttons[BUTTON_VOLUME_UP],
-#endif /* defined(CONFIG_VOLUME_BUTTONS) */
-};
-const int recovery_buttons_count = ARRAY_SIZE(recovery_buttons);
-#endif /* defined(CONFIG_BUTTON_TRIGGERED_RECOVERY) */