From b38fd4500082e6f26a2a47ee7ddb1bd2a0f091c4 Mon Sep 17 00:00:00 2001 From: Louis Yung-Chieh Lo Date: Tue, 10 Dec 2013 10:53:14 -0800 Subject: nyan: re-factor power button to use common/power_button.c This is the first step of tegra power state re-factoring. Move the power button logic to common/power_button.c. Also, the GPIO KB_PWR_ON_L is renamed to POWER_BUTTON_L. BUG=None BRANCH=nyan TEST=tested on nyan rev 3.12, reboot: PASS, power on 2 power off / power on: PASS, power on 5 lid close / power off / lid open: PASS, power on 3 button on / off: PASS, ending loop 3, power on 4 power off / button on: PASS, ending loop 4, power on 4 button off / power on: PASS, ending loop 3, power on 5 button off / lid open: PASS, ending loop 3, power on 3 Change-Id: If07806b9c11cdba2b478a9a74d2b75be1d9f7acf Signed-off-by: Louis Yung-Chieh Lo Reviewed-on: https://chromium-review.googlesource.com/179451 --- board/nyan/board.c | 4 +++- board/nyan/board.h | 3 ++- power/tegra.c | 51 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/board/nyan/board.c b/board/nyan/board.c index 29c35045fc..6744d0d765 100644 --- a/board/nyan/board.c +++ b/board/nyan/board.c @@ -13,6 +13,7 @@ #include "keyboard_raw.h" #include "lid_switch.h" #include "pmu_tpschrome.h" +#include "power_button.h" #include "pwm.h" #include "pwm_chip.h" #include "registers.h" @@ -27,7 +28,8 @@ /* GPIO signal list. Must match order from enum gpio_signal. */ const struct gpio_info gpio_list[] = { /* Inputs with interrupt handlers are first for efficiency */ - {"KB_PWR_ON_L", GPIO_B, (1<<5), GPIO_INT_BOTH, power_interrupt}, + {"POWER_BUTTON_L", GPIO_B, (1<<5), GPIO_INT_BOTH, + power_button_interrupt}, {"XPSHOLD", GPIO_A, (1<<3), GPIO_INT_BOTH, power_interrupt}, {"LID_OPEN", GPIO_C, (1<<13), GPIO_INT_BOTH, lid_interrupt}, {"SUSPEND_L", GPIO_C, (1<<7), GPIO_KB_INPUT, power_interrupt}, diff --git a/board/nyan/board.h b/board/nyan/board.h index 57483b20d0..e51960e07d 100644 --- a/board/nyan/board.h +++ b/board/nyan/board.h @@ -19,6 +19,7 @@ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_SPI #define CONFIG_PWM +#define CONFIG_POWER_BUTTON #ifndef __ASSEMBLER__ @@ -39,7 +40,7 @@ /* GPIO signal list */ enum gpio_signal { /* Inputs with interrupt handlers are first for efficiency */ - GPIO_KB_PWR_ON_L = 0, + GPIO_POWER_BUTTON_L = 0, GPIO_SOC1V8_XPSHOLD, GPIO_LID_OPEN, GPIO_SUSPEND_L, diff --git a/power/tegra.c b/power/tegra.c index 9b44d39f56..e865011bc3 100644 --- a/power/tegra.c +++ b/power/tegra.c @@ -31,6 +31,7 @@ #include "hooks.h" #include "lid_switch.h" #include "keyboard_scan.h" +#include "power_button.h" #include "power_led.h" #include "pmu_tpschrome.h" #include "system.h" @@ -71,9 +72,6 @@ /* Maximum delay after power button press before we deassert GPIO_PMIC_PWRON */ #define DELAY_RELEASE_PWRON SECOND /* 1s */ -/* debounce time to prevent accidental power-on after keyboard power off */ -#define KB_PWR_ON_DEBOUNCE 250 /* 250us */ - /* * nyan's GPIO_SOC1V8_XPSHOLD will go low for ~20ms after initial high. * XPSHOLD_DEBOUNCE is used to wait this long, then check the signal again. @@ -186,10 +184,8 @@ static int check_for_power_off_event(void) /* * Check for power button press. */ - if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) { - udelay(KB_PWR_ON_DEBOUNCE); - if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) - pressed = 1; + if (power_button_is_pressed()) { + pressed = 1; } else if (power_request == POWER_REQ_OFF) { power_request = POWER_REQ_NONE; return 4; /* return non-zero for shudown down */ @@ -295,7 +291,6 @@ DECLARE_HOOK(HOOK_LID_CHANGE, tegra_lid_event, HOOK_PRIO_DEFAULT); static int tegra_power_init(void) { /* Enable interrupts for our GPIOs */ - gpio_enable_interrupt(GPIO_KB_PWR_ON_L); gpio_enable_interrupt(GPIO_SOC1V8_XPSHOLD); gpio_enable_interrupt(GPIO_SUSPEND_L); @@ -407,10 +402,8 @@ static int check_for_power_on_event(void) } /* check for power button press */ - if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) { - udelay(KB_PWR_ON_DEBOUNCE); - if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) - return 4; + if (power_button_is_pressed()) { + return 4; } if (power_request == POWER_REQ_ON) { @@ -453,20 +446,31 @@ static int power_on(void) /** * Wait for the power button to be released * - * @return 0 if ok, -1 if power button failed to release + * @param timeout_us Timeout in microseconds, or -1 to wait forever + * @return EC_SUCCESS if ok, or + * EC_ERROR_TIMEOUT if power button failed to release */ static int wait_for_power_button_release(unsigned int timeout_us) { - /* wait for Power button release */ - wait_in_signal(GPIO_KB_PWR_ON_L, 1, timeout_us); + timestamp_t deadline; + timestamp_t now = get_time(); - udelay(KB_PWR_ON_DEBOUNCE); - if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) { - CPRINTF("[%T power button not released in time]\n"); - return -1; + deadline.val = now.val + timeout_us; + + while (power_button_is_pressed()) { + now = get_time(); + if (timeout_us < 0) { + task_wait_event(-1); + } else if (timestamp_expired(deadline, &now) || + (task_wait_event(deadline.val - now.val) == + TASK_EVENT_TIMER)) { + CPRINTF("[%T power button not released in time]\n"); + return EC_ERROR_TIMEOUT; + } } + CPRINTF("[%T power button released]\n"); - return 0; + return EC_SUCCESS; } /** @@ -589,6 +593,13 @@ void chipset_task(void) } } +static void powerbtn_tegra_changed(void) +{ + task_wake(TASK_ID_CHIPSET); +} +DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, powerbtn_tegra_changed, + HOOK_PRIO_DEFAULT); + /*****************************************************************************/ /* Console debug command */ -- cgit v1.2.1