summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-04-01 10:56:33 -0700
committerChromeBot <chrome-bot@google.com>2013-04-02 14:12:57 -0700
commitbdd16f82069f9e07e9a9e3008c318d9581ce0664 (patch)
tree16287a843f975c9505636dcc13fbaef50cb08f9a
parent50c53c0d542d6fc3184db09a35196b4c702536c5 (diff)
downloadchrome-ec-bdd16f82069f9e07e9a9e3008c318d9581ce0664.tar.gz
Split lid switch code out of switch.c to its own file
This will allow ARM code to use the same lid switch code (in a subsequent CL). BUG=chrome-os-partner:18343 BRANCH=none TEST=open lid; system boots. close lid; system suspends. open lid; resumes. Change-Id: I83536a3ad24c4446dccf8a6b6e296756659070a8 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/47043 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--board/link/board.c6
-rw-r--r--board/link/board.h1
-rw-r--r--chip/lm4/switch.c152
-rw-r--r--common/build.mk1
-rw-r--r--common/keyboard_scan.c6
-rw-r--r--common/lid_switch.c126
-rw-r--r--common/x86_power.c4
-rw-r--r--include/hooks.h2
-rw-r--r--include/lid_switch.h27
-rw-r--r--include/switch.h18
10 files changed, 204 insertions, 139 deletions
diff --git a/board/link/board.c b/board/link/board.c
index 476be6dc79..9cc74646b0 100644
--- a/board/link/board.c
+++ b/board/link/board.c
@@ -9,6 +9,7 @@
#include "extpower.h"
#include "gpio.h"
#include "i2c.h"
+#include "lid_switch.h"
#include "lm4_adc.h"
#include "registers.h"
#include "switch.h"
@@ -18,9 +19,6 @@
#ifndef CONFIG_CHIPSET_X86
#define x86_power_interrupt NULL
#endif
-#ifndef CONFIG_TASK_SWITCH
-#define switch_interrupt NULL
-#endif
/* GPIO signal list. Must match order from enum gpio_signal. */
const struct gpio_info gpio_list[GPIO_COUNT] = {
@@ -28,7 +26,7 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"POWER_BUTTONn", LM4_GPIO_K, (1<<7), GPIO_INT_BOTH,
switch_interrupt},
{"LID_SWITCHn", LM4_GPIO_K, (1<<5), GPIO_INT_BOTH,
- switch_interrupt},
+ lid_interrupt},
/* Other inputs */
{"THERMAL_DATA_READYn", LM4_GPIO_B, (1<<4), 0, NULL},
{"AC_PRESENT", LM4_GPIO_H, (1<<3), GPIO_INT_BOTH,
diff --git a/board/link/board.h b/board/link/board.h
index f986f132a0..b789f9c13c 100644
--- a/board/link/board.h
+++ b/board/link/board.h
@@ -21,6 +21,7 @@
#define CONFIG_CONSOLE_CMDHELP
#define CONFIG_EXTPOWER_GPIO
#define CONFIG_KEYBOARD_PROTOCOL_8042
+#define CONFIG_LID_SWITCH
#define CONFIG_LPC
#define CONFIG_ONEWIRE
#define CONFIG_ONEWIRE_LED
diff --git a/chip/lm4/switch.c b/chip/lm4/switch.c
index 135e722783..e02489c806 100644
--- a/chip/lm4/switch.c
+++ b/chip/lm4/switch.c
@@ -14,6 +14,7 @@
#include "host_command.h"
#include "keyboard_protocol.h"
#include "keyboard_scan.h"
+#include "lid_switch.h"
#include "pwm.h"
#include "switch.h"
#include "system.h"
@@ -52,8 +53,6 @@
*/
#define PWRBTN_INITIAL_US (200 * MSEC)
-#define LID_DEBOUNCE_US (30 * MSEC) /* Debounce time for lid switch */
-
enum power_button_state {
/* Button up; state machine idle */
PWRBTN_STATE_IDLE = 0,
@@ -104,14 +103,12 @@ static const char * const state_names[] = {
static uint64_t tnext_state;
/*
- * Debounce timeouts for power button and lid switch. 0 means the signal is
- * stable (not being debounced).
+ * Debounce timeout for power button. 0 means the signal is stable (not being
+ * debounced).
*/
-static uint64_t tdebounce_lid;
static uint64_t tdebounce_pwr;
static uint8_t *memmap_switches;
-static int debounced_lid_open;
static int debounced_power_pressed;
static int simulate_power_pressed;
@@ -151,16 +148,6 @@ static void set_pwrbtn_to_pch(int high)
}
/**
- * Get raw lid switch state.
- *
- * @return 1 if lid is open, 0 if closed.
- */
-static int raw_lid_open(void)
-{
- return gpio_get_level(GPIO_LID_SWITCHn) ? 1 : 0;
-}
-
-/**
* Get raw power button signal state.
*
* @return 1 if power button is pressed, 0 if not pressed.
@@ -171,7 +158,7 @@ static int raw_power_button_pressed(void)
return 1;
/* Ignore power button if lid is closed */
- if (!raw_lid_open())
+ if (!lid_is_open())
return 0;
return gpio_get_level(GPIO_POWER_BUTTONn) ? 0 : 1;
@@ -180,13 +167,13 @@ static int raw_power_button_pressed(void)
static void update_backlight(void)
{
/* Only enable the backlight if the lid is open */
- if (gpio_get_level(GPIO_PCH_BKLTEN) && debounced_lid_open)
+ if (gpio_get_level(GPIO_PCH_BKLTEN) && lid_is_open())
gpio_set_level(GPIO_ENABLE_BACKLIGHT, 1);
else
gpio_set_level(GPIO_ENABLE_BACKLIGHT, 0);
/* Same with keyboard backlight */
- pwm_enable_keyboard_backlight(debounced_lid_open);
+ pwm_enable_keyboard_backlight(lid_is_open());
}
/**
@@ -227,51 +214,6 @@ static void power_button_released(uint64_t tnow)
}
/**
- * Handle lid open.
- */
-static void lid_switch_open(uint64_t tnow)
-{
- if (debounced_lid_open) {
- CPRINTF("[%T PB lid already open]\n");
- return;
- }
-
- CPRINTF("[%T PB lid open]\n");
- debounced_lid_open = 1;
- *memmap_switches |= EC_SWITCH_LID_OPEN;
- hook_notify(HOOK_LID_CHANGE);
- update_backlight();
- host_set_single_event(EC_HOST_EVENT_LID_OPEN);
-
- /* If the chipset is off, send a power button pulse to wake it up */
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
- chipset_exit_hard_off();
- set_pwrbtn_to_pch(0);
- pwrbtn_state = PWRBTN_STATE_LID_OPEN;
- tnext_state = tnow + PWRBTN_INITIAL_US;
- task_wake(TASK_ID_SWITCH);
- }
-}
-
-/**
- * Handle lid close.
- */
-static void lid_switch_close(uint64_t tnow)
-{
- if (!debounced_lid_open) {
- CPRINTF("[%T PB lid already closed]\n");
- return;
- }
-
- CPRINTF("[%T PB lid close]\n");
- debounced_lid_open = 0;
- *memmap_switches &= ~EC_SWITCH_LID_OPEN;
- hook_notify(HOOK_LID_CHANGE);
- update_backlight();
- host_set_single_event(EC_HOST_EVENT_LID_CLOSED);
-}
-
-/**
* Handle debounced power button changing state.
*/
static void power_button_changed(uint64_t tnow)
@@ -305,17 +247,6 @@ static void power_button_changed(uint64_t tnow)
}
/**
- * Handle debounced lid switch changing state.
- */
-static void lid_switch_changed(uint64_t tnow)
-{
- if (raw_lid_open())
- lid_switch_open(tnow);
- else
- lid_switch_close(tnow);
-}
-
-/**
* Set initial power button state.
*/
static void set_initial_pwrbtn_state(void)
@@ -367,11 +298,6 @@ static void set_initial_pwrbtn_state(void)
}
}
-int switch_get_lid_open(void)
-{
- return debounced_lid_open;
-}
-
int switch_get_write_protect(void)
{
return gpio_get_level(GPIO_WRITE_PROTECT);
@@ -505,7 +431,7 @@ void switch_task(void)
while (1) {
t = get_time().val;
- /* Handle debounce timeouts for power button and lid switch */
+ /* Handle debounce timeout for power button */
if (tdebounce_pwr && t >= tdebounce_pwr) {
tdebounce_pwr = 0;
@@ -520,11 +446,6 @@ void switch_task(void)
debounced_power_pressed)
power_button_changed(t);
}
- if (tdebounce_lid && t >= tdebounce_lid) {
- tdebounce_lid = 0;
- if (raw_lid_open() != debounced_lid_open)
- lid_switch_changed(t);
- }
/* Handle non-debounced switches */
update_other_switches();
@@ -539,8 +460,6 @@ void switch_task(void)
tsleep = -1;
if (tdebounce_pwr && tdebounce_pwr < tsleep)
tsleep = tdebounce_pwr;
- if (tdebounce_lid && tdebounce_lid < tsleep)
- tsleep = tdebounce_lid;
if (tnext_state && tnext_state < tsleep)
tsleep = tnext_state;
t = get_time().val;
@@ -569,34 +488,53 @@ static void switch_init(void)
/* Set up memory-mapped switch positions */
memmap_switches = host_get_memmap(EC_MEMMAP_SWITCHES);
*memmap_switches = 0;
- if (raw_lid_open()) {
- debounced_lid_open = 1;
+
+ if (lid_is_open())
*memmap_switches |= EC_SWITCH_LID_OPEN;
- }
+
update_other_switches();
update_backlight();
-
set_initial_pwrbtn_state();
/* Switch data is now present */
*host_get_memmap(EC_MEMMAP_SWITCHES_VERSION) = 1;
/* Enable interrupts, now that we've initialized */
- gpio_enable_interrupt(GPIO_LID_SWITCHn);
gpio_enable_interrupt(GPIO_POWER_BUTTONn);
gpio_enable_interrupt(GPIO_RECOVERYn);
gpio_enable_interrupt(GPIO_WRITE_PROTECT);
}
DECLARE_HOOK(HOOK_INIT, switch_init, HOOK_PRIO_DEFAULT);
+/**
+ * Handle switch changes based on lid event.
+ */
+static void switch_lid_change(void)
+{
+ update_backlight();
+
+ if (lid_is_open()) {
+ *memmap_switches |= EC_SWITCH_LID_OPEN;
+
+ /* If the chipset is off, pulse the power button to wake it. */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
+ chipset_exit_hard_off();
+ set_pwrbtn_to_pch(0);
+ pwrbtn_state = PWRBTN_STATE_LID_OPEN;
+ tnext_state = get_time().val + PWRBTN_INITIAL_US;
+ task_wake(TASK_ID_SWITCH);
+ }
+
+ } else {
+ *memmap_switches &= ~EC_SWITCH_LID_OPEN;
+ }
+}
+DECLARE_HOOK(HOOK_LID_CHANGE, switch_lid_change, HOOK_PRIO_DEFAULT);
+
void switch_interrupt(enum gpio_signal signal)
{
/* Reset debounce time for the changed signal */
switch (signal) {
- case GPIO_LID_SWITCHn:
- /* Reset lid debounce time */
- tdebounce_lid = get_time().val + LID_DEBOUNCE_US;
- break;
case GPIO_POWER_BUTTONn:
/* Reset power button debounce time */
tdebounce_pwr = get_time().val + PWRBTN_DEBOUNCE_US;
@@ -663,26 +601,6 @@ DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn,
"Simulate power button press",
NULL);
-static int command_lidopen(int argc, char **argv)
-{
- lid_switch_open(get_time().val);
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(lidopen, command_lidopen,
- NULL,
- "Simulate lid open",
- NULL);
-
-static int command_lidclose(int argc, char **argv)
-{
- lid_switch_close(get_time().val);
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(lidclose, command_lidclose,
- NULL,
- "Simulate lid close",
- NULL);
-
static int command_mmapinfo(int argc, char **argv)
{
uint8_t *memmap_switches = host_get_memmap(EC_MEMMAP_SWITCHES);
diff --git a/common/build.mk b/common/build.mk
index 4fba8d081e..d9bb745f9e 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -24,6 +24,7 @@ common-$(CONFIG_IR357x)+=ir357x.o
common-$(CONFIG_KEYBOARD_PROTOCOL_8042)+=keyboard_8042.o
common-$(CONFIG_KEYBOARD_PROTOCOL_MKBP)+=keyboard_mkbp.o
common-$(CONFIG_KEYBOARD_TEST)+=keyboard_test.o
+common-$(CONFIG_LID_SWITCH)+=lid_switch.o
common-$(CONFIG_LP5562)+=lp5562.o lp5562_battery_led.o
common-$(CONFIG_LPC)+=port80.o
common-$(CONFIG_ONEWIRE_LED)+=onewire_led.o
diff --git a/common/keyboard_scan.c b/common/keyboard_scan.c
index 7f17d8c237..2e28a1b809 100644
--- a/common/keyboard_scan.c
+++ b/common/keyboard_scan.c
@@ -13,6 +13,7 @@
#include "keyboard_protocol.h"
#include "keyboard_raw.h"
#include "keyboard_scan.h"
+#include "lid_switch.h"
#include "switch.h"
#include "system.h"
#include "task.h"
@@ -79,10 +80,9 @@ static int enable_scanning = 1; /* Must init to 1 for scanning at boot */
static int is_scanning_enabled(void)
{
-#ifdef BOARD_link
- /* TODO: should apply to ARM too, but need standard lid API */
+#ifdef CONFIG_LID_SWITCH
/* Scanning is never enabled when lid is closed */
- if (!switch_get_lid_open())
+ if (!lid_is_open())
return 0;
#endif
diff --git a/common/lid_switch.c b/common/lid_switch.c
new file mode 100644
index 0000000000..68c049e52c
--- /dev/null
+++ b/common/lid_switch.c
@@ -0,0 +1,126 @@
+/* Copyright (c) 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.
+ */
+
+/* Lid switch module for Chrome EC */
+
+#include "common.h"
+#include "console.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "host_command.h"
+#include "timer.h"
+#include "util.h"
+
+/* Console output macros */
+#define CPUTS(outstr) cputs(CC_SWITCH, outstr)
+#define CPRINTF(format, args...) cprintf(CC_SWITCH, format, ## args)
+
+#define LID_DEBOUNCE_US (30 * MSEC) /* Debounce time for lid switch */
+
+static int debounced_lid_open; /* Debounced lid state */
+
+/**
+ * Get raw lid switch state.
+ *
+ * @return 1 if lid is open, 0 if closed.
+ */
+static int raw_lid_open(void)
+{
+ return gpio_get_level(GPIO_LID_SWITCHn) ? 1 : 0;
+}
+
+/**
+ * Handle lid open.
+ */
+static void lid_switch_open(void)
+{
+ if (debounced_lid_open) {
+ CPRINTF("[%T lid already open]\n");
+ return;
+ }
+
+ CPRINTF("[%T lid open]\n");
+ debounced_lid_open = 1;
+ hook_notify(HOOK_LID_CHANGE);
+ host_set_single_event(EC_HOST_EVENT_LID_OPEN);
+}
+
+/**
+ * Handle lid close.
+ */
+static void lid_switch_close(void)
+{
+ if (!debounced_lid_open) {
+ CPRINTF("[%T lid already closed]\n");
+ return;
+ }
+
+ CPRINTF("[%T lid close]\n");
+ debounced_lid_open = 0;
+ hook_notify(HOOK_LID_CHANGE);
+ host_set_single_event(EC_HOST_EVENT_LID_CLOSED);
+}
+
+int lid_is_open(void)
+{
+ return debounced_lid_open;
+}
+
+/**
+ * Lid switch initialization code
+ */
+static void lid_init(void)
+{
+ if (raw_lid_open())
+ debounced_lid_open = 1;
+
+ /* Enable interrupts, now that we've initialized */
+ gpio_enable_interrupt(GPIO_LID_SWITCHn);
+}
+DECLARE_HOOK(HOOK_INIT, lid_init, HOOK_PRIO_INIT_LID);
+
+/**
+ * Handle debounced lid switch changing state.
+ */
+static void lid_change_deferred(void)
+{
+ const int new_open = raw_lid_open();
+
+ /* If lid hasn't changed state, nothing to do */
+ if (new_open == debounced_lid_open)
+ return;
+
+ if (new_open)
+ lid_switch_open();
+ else
+ lid_switch_close();
+}
+DECLARE_DEFERRED(lid_change_deferred);
+
+void lid_interrupt(enum gpio_signal signal)
+{
+ /* Reset lid debounce time */
+ hook_call_deferred(lid_change_deferred, LID_DEBOUNCE_US);
+}
+
+static int command_lidopen(int argc, char **argv)
+{
+ lid_switch_open();
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(lidopen, command_lidopen,
+ NULL,
+ "Simulate lid open",
+ NULL);
+
+static int command_lidclose(int argc, char **argv)
+{
+ lid_switch_close();
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(lidclose, command_lidclose,
+ NULL,
+ "Simulate lid close",
+ NULL);
diff --git a/common/x86_power.c b/common/x86_power.c
index 6320b2e836..689229e5e5 100644
--- a/common/x86_power.c
+++ b/common/x86_power.c
@@ -12,6 +12,7 @@
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
+#include "lid_switch.h"
#include "switch.h"
#include "system.h"
#include "task.h"
@@ -487,8 +488,7 @@ void chipset_task(void)
* power usage. If lid is open, take touchscreen out
* of reset so it can wake the processor.
*/
- gpio_set_level(GPIO_TOUCHSCREEN_RESETn,
- switch_get_lid_open());
+ gpio_set_level(GPIO_TOUCHSCREEN_RESETn, lid_is_open());
/* Check for state transitions */
if (!have_all_in_signals(IN_PGOOD_S3)) {
diff --git a/include/hooks.h b/include/hooks.h
index 6a6bd797cc..71939d05da 100644
--- a/include/hooks.h
+++ b/include/hooks.h
@@ -21,6 +21,8 @@ enum hook_priority {
HOOK_PRIO_INIT_LPC = HOOK_PRIO_FIRST + 1,
/* Chipset inits before modules which need to know its initial state. */
HOOK_PRIO_INIT_CHIPSET = HOOK_PRIO_FIRST + 2,
+ /* Lid switch inits before power button */
+ HOOK_PRIO_INIT_LID = HOOK_PRIO_FIRST + 3,
};
enum hook_type {
diff --git a/include/lid_switch.h b/include/lid_switch.h
new file mode 100644
index 0000000000..1bbb34cae2
--- /dev/null
+++ b/include/lid_switch.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 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.
+ */
+
+/* Lid switch API for Chrome EC */
+
+#ifndef __CROS_EC_LID_SWITCH_H
+#define __CROS_EC_LID_SWITCH_H
+
+#include "common.h"
+
+/**
+ * Return non-zero if lid is open.
+ *
+ * Uses the debounced lid state, not the raw signal from the GPIO.
+ */
+int lid_is_open(void);
+
+/**
+ * Interrupt handler for lid switch.
+ *
+ * @param signal Signal which triggered the interrupt.
+ */
+void lid_interrupt(enum gpio_signal signal);
+
+#endif /* __CROS_EC_LID_SWITCH_H */
diff --git a/include/switch.h b/include/switch.h
index ffb8eaee7b..e86711ca49 100644
--- a/include/switch.h
+++ b/include/switch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 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.
*/
@@ -11,24 +11,16 @@
#include "common.h"
#include "gpio.h"
+#ifdef CONFIG_TASK_SWITCH
/**
* Interrupt handler for switch inputs.
*
* @param signal Signal which triggered the interrupt.
*/
void switch_interrupt(enum gpio_signal signal);
-
-/**
- * Switch task.
- */
-void switch_task(void);
-
-/**
- * Return non-zero if lid is open.
- *
- * Uses the debounced lid state, not the raw signal from the GPIO.
- */
-int switch_get_lid_open(void);
+#else
+#define switch_interrupt NULL
+#endif /* CONFIG_TASK_SWITCH */
/**
* Return non-zero if write protect signal is asserted.