summaryrefslogtreecommitdiff
path: root/common/button.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /common/button.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-factory-cherry-14455.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
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) */