summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2013-12-10 10:53:14 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-12-11 00:13:51 +0000
commitb38fd4500082e6f26a2a47ee7ddb1bd2a0f091c4 (patch)
tree0c3eeac4f9f90f98842915ad6d00715312f01724
parent96e034f366eacc4bfaed87685d4536dae1e1b91c (diff)
downloadchrome-ec-b38fd4500082e6f26a2a47ee7ddb1bd2a0f091c4.tar.gz
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 <yjlou@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/179451
-rw-r--r--board/nyan/board.c4
-rw-r--r--board/nyan/board.h3
-rw-r--r--power/tegra.c51
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 */