diff options
author | Randall Spangler <rspangler@chromium.org> | 2013-04-01 10:56:33 -0700 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-04-02 14:12:57 -0700 |
commit | bdd16f82069f9e07e9a9e3008c318d9581ce0664 (patch) | |
tree | 16287a843f975c9505636dcc13fbaef50cb08f9a | |
parent | 50c53c0d542d6fc3184db09a35196b4c702536c5 (diff) | |
download | chrome-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.c | 6 | ||||
-rw-r--r-- | board/link/board.h | 1 | ||||
-rw-r--r-- | chip/lm4/switch.c | 152 | ||||
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/keyboard_scan.c | 6 | ||||
-rw-r--r-- | common/lid_switch.c | 126 | ||||
-rw-r--r-- | common/x86_power.c | 4 | ||||
-rw-r--r-- | include/hooks.h | 2 | ||||
-rw-r--r-- | include/lid_switch.h | 27 | ||||
-rw-r--r-- | include/switch.h | 18 |
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. |