mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
Split out power button code from switch.c
The power button code is platform-independent. This change splits the code out of the LM4 switch.c module so that a subseqent change to STM32 platforms can start using it. BUG=chrome-os-partner:18945 BRANCH=none TEST=manual 1. Power+refresh+esc goes to recovery mode, 2. Press power button at recovery screen turns off. 3. With system off, power button turns system on. 4. Press power button for a second; screen locks. 5. Press power button while typing; blocks keystrokes while it's pressed. 6. Hold power button down for 8 sec; system forced to shutdown. 7. From EC console, with system on: hostevent clear hostevent -> event 0x04 is clear press power button hostevent -> event 0x04 is set 8. From EC console, with system off: powerbtn -> system turns on powerbtn 5000 -> system turns off, just like power button was held for 5 sec Change-Id: If2a9b02514a201e1d03c857d128e2ccab51a16ef Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/49217 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
committed by
ChromeBot
parent
b4b2c6ae70
commit
45bc5c1a21
@@ -14,6 +14,7 @@
|
||||
#include "lid_switch.h"
|
||||
#include "lm4_adc.h"
|
||||
#include "peci.h"
|
||||
#include "power_button.h"
|
||||
#include "registers.h"
|
||||
#include "switch.h"
|
||||
#include "temp_sensor.h"
|
||||
@@ -26,7 +27,7 @@
|
||||
const struct gpio_info gpio_list[GPIO_COUNT] = {
|
||||
/* Inputs with interrupt handlers are first for efficiency */
|
||||
{"POWER_BUTTON_L", LM4_GPIO_K, (1<<7), GPIO_INT_BOTH,
|
||||
switch_interrupt},
|
||||
power_button_interrupt},
|
||||
{"LID_OPEN", LM4_GPIO_K, (1<<5), GPIO_INT_BOTH,
|
||||
lid_interrupt},
|
||||
/* Other inputs */
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define CONFIG_ONEWIRE
|
||||
#define CONFIG_ONEWIRE_LED
|
||||
#define CONFIG_PECI
|
||||
#define CONFIG_POWER_BUTTON
|
||||
#define CONFIG_PWM
|
||||
#define CONFIG_TEMP_SENSOR
|
||||
#define CONFIG_TMP006
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "keyboard_protocol.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "lid_switch.h"
|
||||
#include "power_button.h"
|
||||
#include "pwm.h"
|
||||
#include "switch.h"
|
||||
#include "system.h"
|
||||
@@ -43,7 +44,6 @@
|
||||
* @S0 make code break code
|
||||
*/
|
||||
/* TODO: link to full power button / lid switch state machine description. */
|
||||
#define PWRBTN_DEBOUNCE_US (30 * MSEC) /* Debounce time for power button */
|
||||
#define PWRBTN_DELAY_T0 (32 * MSEC) /* 32ms (PCH requires >16ms) */
|
||||
#define PWRBTN_DELAY_T1 (4 * SECOND - PWRBTN_DELAY_T0) /* 4 secs - t0 */
|
||||
/*
|
||||
@@ -109,8 +109,6 @@ static uint64_t tnext_state;
|
||||
static uint64_t tdebounce_pwr;
|
||||
|
||||
static uint8_t *memmap_switches;
|
||||
static int debounced_power_pressed;
|
||||
static int simulate_power_pressed;
|
||||
|
||||
/**
|
||||
* Update status of non-debounced switches.
|
||||
@@ -147,23 +145,6 @@ static void set_pwrbtn_to_pch(int high)
|
||||
gpio_set_level(GPIO_PCH_PWRBTN_L, high);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw power button signal state.
|
||||
*
|
||||
* @return 1 if power button is pressed, 0 if not pressed.
|
||||
*/
|
||||
static int raw_power_button_pressed(void)
|
||||
{
|
||||
if (simulate_power_pressed)
|
||||
return 1;
|
||||
|
||||
/* Ignore power button if lid is closed */
|
||||
if (!lid_is_open())
|
||||
return 0;
|
||||
|
||||
return gpio_get_level(GPIO_POWER_BUTTON_L) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void update_backlight(void)
|
||||
{
|
||||
/* Only enable the backlight if the lid is open */
|
||||
@@ -181,20 +162,10 @@ static void update_backlight(void)
|
||||
*/
|
||||
static void power_button_pressed(uint64_t tnow)
|
||||
{
|
||||
if (debounced_power_pressed == 1) {
|
||||
CPRINTF("[%T PB already pressed]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CPRINTF("[%T PB pressed]\n");
|
||||
debounced_power_pressed = 1;
|
||||
pwrbtn_state = PWRBTN_STATE_PRESSED;
|
||||
tnext_state = tnow;
|
||||
*memmap_switches |= EC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
#ifdef HAS_TASK_KEYPROTO
|
||||
keyboard_set_power_button(1);
|
||||
#endif
|
||||
host_set_single_event(EC_HOST_EVENT_POWER_BUTTON);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,52 +173,10 @@ static void power_button_pressed(uint64_t tnow)
|
||||
*/
|
||||
static void power_button_released(uint64_t tnow)
|
||||
{
|
||||
if (debounced_power_pressed == 0) {
|
||||
CPRINTF("[%T PB already released]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CPRINTF("[%T PB released]\n");
|
||||
debounced_power_pressed = 0;
|
||||
pwrbtn_state = PWRBTN_STATE_RELEASED;
|
||||
tnext_state = tnow;
|
||||
*memmap_switches &= ~EC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
#ifdef HAS_TASK_KEYPROTO
|
||||
keyboard_set_power_button(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle debounced power button changing state.
|
||||
*/
|
||||
static void power_button_changed(uint64_t tnow)
|
||||
{
|
||||
if (pwrbtn_state == PWRBTN_STATE_BOOT_KB_RESET ||
|
||||
pwrbtn_state == PWRBTN_STATE_INIT_ON ||
|
||||
pwrbtn_state == PWRBTN_STATE_LID_OPEN ||
|
||||
pwrbtn_state == PWRBTN_STATE_WAS_OFF) {
|
||||
/* Ignore all power button changes during an initial pulse */
|
||||
CPRINTF("[%T PB ignoring change]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (raw_power_button_pressed()) {
|
||||
/* Power button pressed */
|
||||
power_button_pressed(tnow);
|
||||
} else {
|
||||
/* Power button released */
|
||||
if (pwrbtn_state == PWRBTN_STATE_EAT_RELEASE) {
|
||||
/*
|
||||
* Ignore the first power button release if we already
|
||||
* told the PCH the power button was released.
|
||||
*/
|
||||
CPRINTF("[%T PB ignoring release]\n");
|
||||
pwrbtn_state = PWRBTN_STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
power_button_released(tnow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,16 +186,13 @@ static void set_initial_pwrbtn_state(void)
|
||||
{
|
||||
uint32_t reset_flags = system_get_reset_flags();
|
||||
|
||||
/* Set debounced power button state to initial button state */
|
||||
debounced_power_pressed = raw_power_button_pressed();
|
||||
|
||||
if (system_jumped_to_this_image() &&
|
||||
chipset_in_state(CHIPSET_STATE_ON)) {
|
||||
/*
|
||||
* Jumped to this image while the chipset was already on, so
|
||||
* simply reflect the actual power button state.
|
||||
*/
|
||||
if (debounced_power_pressed) {
|
||||
if (power_button_is_pressed()) {
|
||||
*memmap_switches |= EC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
CPRINTF("[%T PB init-jumped-held]\n");
|
||||
set_pwrbtn_to_pch(0);
|
||||
@@ -288,7 +214,7 @@ static void set_initial_pwrbtn_state(void)
|
||||
*/
|
||||
CPRINTF("[%T PB init-off]\n");
|
||||
set_pwrbtn_to_pch(1);
|
||||
if (debounced_power_pressed)
|
||||
if (power_button_is_pressed())
|
||||
pwrbtn_state = PWRBTN_STATE_EAT_RELEASE;
|
||||
else
|
||||
pwrbtn_state = PWRBTN_STATE_IDLE;
|
||||
@@ -386,7 +312,7 @@ static void state_machine(uint64_t tnow)
|
||||
set_pwrbtn_to_pch(0);
|
||||
tnext_state = get_time().val + PWRBTN_INITIAL_US;
|
||||
|
||||
if (debounced_power_pressed) {
|
||||
if (power_button_is_pressed()) {
|
||||
*memmap_switches |= EC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
|
||||
if (system_get_reset_flags() & RESET_FLAG_RESET_PIN)
|
||||
@@ -405,7 +331,7 @@ static void state_machine(uint64_t tnow)
|
||||
* recovery combination doesn't cause the chipset to shut back
|
||||
* down. */
|
||||
set_pwrbtn_to_pch(1);
|
||||
if (raw_power_button_pressed())
|
||||
if (power_button_is_pressed())
|
||||
pwrbtn_state = PWRBTN_STATE_EAT_RELEASE;
|
||||
else
|
||||
pwrbtn_state = PWRBTN_STATE_IDLE;
|
||||
@@ -413,7 +339,7 @@ static void state_machine(uint64_t tnow)
|
||||
case PWRBTN_STATE_WAS_OFF:
|
||||
/* Done stretching initial power button signal, so show the
|
||||
* true power button state to the PCH. */
|
||||
if (raw_power_button_pressed()) {
|
||||
if (power_button_is_pressed()) {
|
||||
/* User is still holding the power button */
|
||||
pwrbtn_state = PWRBTN_STATE_HELD;
|
||||
} else {
|
||||
@@ -437,22 +363,6 @@ void switch_task(void)
|
||||
while (1) {
|
||||
t = get_time().val;
|
||||
|
||||
/* Handle debounce timeout for power button */
|
||||
if (tdebounce_pwr && t >= tdebounce_pwr) {
|
||||
tdebounce_pwr = 0;
|
||||
|
||||
/*
|
||||
* Re-enable keyboard scanning if the power button is
|
||||
* no longer pressed.
|
||||
*/
|
||||
if (!raw_power_button_pressed())
|
||||
keyboard_scan_enable(1);
|
||||
|
||||
if (raw_power_button_pressed() !=
|
||||
debounced_power_pressed)
|
||||
power_button_changed(t);
|
||||
}
|
||||
|
||||
/* Handle non-debounced switches */
|
||||
update_other_switches();
|
||||
|
||||
@@ -537,22 +447,47 @@ static void switch_lid_change(void)
|
||||
}
|
||||
DECLARE_HOOK(HOOK_LID_CHANGE, switch_lid_change, HOOK_PRIO_DEFAULT);
|
||||
|
||||
/**
|
||||
* Handle debounced power button changing state.
|
||||
*/
|
||||
static void power_button_changed(void)
|
||||
{
|
||||
if (pwrbtn_state == PWRBTN_STATE_BOOT_KB_RESET ||
|
||||
pwrbtn_state == PWRBTN_STATE_INIT_ON ||
|
||||
pwrbtn_state == PWRBTN_STATE_LID_OPEN ||
|
||||
pwrbtn_state == PWRBTN_STATE_WAS_OFF) {
|
||||
/* Ignore all power button changes during an initial pulse */
|
||||
CPRINTF("[%T PB ignoring change]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (power_button_is_pressed()) {
|
||||
/* Power button pressed */
|
||||
power_button_pressed(get_time().val);
|
||||
} else {
|
||||
/* Power button released */
|
||||
if (pwrbtn_state == PWRBTN_STATE_EAT_RELEASE) {
|
||||
/*
|
||||
* Ignore the first power button release if we already
|
||||
* told the PCH the power button was released.
|
||||
*/
|
||||
CPRINTF("[%T PB ignoring release]\n");
|
||||
pwrbtn_state = PWRBTN_STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
power_button_released(get_time().val);
|
||||
}
|
||||
|
||||
/* Wake the switch task */
|
||||
task_wake(TASK_ID_SWITCH);
|
||||
}
|
||||
DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT);
|
||||
|
||||
void switch_interrupt(enum gpio_signal signal)
|
||||
{
|
||||
/* Reset debounce time for the changed signal */
|
||||
switch (signal) {
|
||||
case GPIO_POWER_BUTTON_L:
|
||||
/* Reset power button debounce time */
|
||||
tdebounce_pwr = get_time().val + PWRBTN_DEBOUNCE_US;
|
||||
if (raw_power_button_pressed()) {
|
||||
/*
|
||||
* Disable the matrix scan as soon as possible to
|
||||
* reduce the risk of false-reboot triggered by those
|
||||
* keys on the same column with refresh key.
|
||||
*/
|
||||
keyboard_scan_enable(0);
|
||||
}
|
||||
break;
|
||||
case GPIO_PCH_BKLTEN:
|
||||
update_backlight();
|
||||
break;
|
||||
@@ -574,39 +509,6 @@ void switch_interrupt(enum gpio_signal signal)
|
||||
task_wake(TASK_ID_SWITCH);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Console commands */
|
||||
|
||||
static int command_powerbtn(int argc, char **argv)
|
||||
{
|
||||
int ms = PWRBTN_INITIAL_US / MSEC; /* Press duration in ms */
|
||||
char *e;
|
||||
|
||||
if (argc > 1) {
|
||||
ms = strtoi(argv[1], &e, 0);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM1;
|
||||
}
|
||||
|
||||
ccprintf("Simulating %d ms power button press.\n", ms);
|
||||
simulate_power_pressed = 1;
|
||||
tdebounce_pwr = get_time().val + PWRBTN_DEBOUNCE_US;
|
||||
task_wake(TASK_ID_SWITCH);
|
||||
|
||||
msleep(ms);
|
||||
|
||||
ccprintf("Simulating power button release.\n");
|
||||
simulate_power_pressed = 0;
|
||||
tdebounce_pwr = get_time().val + PWRBTN_DEBOUNCE_US;
|
||||
task_wake(TASK_ID_SWITCH);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn,
|
||||
"[msec]",
|
||||
"Simulate power button press",
|
||||
NULL);
|
||||
|
||||
static int command_mmapinfo(int argc, char **argv)
|
||||
{
|
||||
uint8_t *memmap_switches = host_get_memmap(EC_MEMMAP_SWITCHES);
|
||||
|
||||
@@ -30,6 +30,7 @@ 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
|
||||
common-$(CONFIG_POWER_BUTTON)+=power_button.o
|
||||
common-$(CONFIG_PSTORE)+=pstore_commands.o
|
||||
common-$(CONFIG_SMART_BATTERY)+=smart_battery.o smart_battery_stub.o
|
||||
common-$(HAS_TASK_CHIPSET)+=chipset.o
|
||||
|
||||
@@ -42,6 +42,7 @@ static const struct hook_ptrs hook_list[] = {
|
||||
{__hooks_chipset_shutdown, __hooks_chipset_shutdown_end},
|
||||
{__hooks_ac_change, __hooks_ac_change_end},
|
||||
{__hooks_lid_change, __hooks_lid_change_end},
|
||||
{__hooks_pwrbtn_change, __hooks_pwrbtn_change_end},
|
||||
{__hooks_tick, __hooks_tick_end},
|
||||
{__hooks_second, __hooks_second_end},
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "keyboard_protocol.h"
|
||||
#include "lightbar.h"
|
||||
#include "lpc.h"
|
||||
#include "power_button.h"
|
||||
#include "queue.h"
|
||||
#include "registers.h"
|
||||
#include "shared_mem.h"
|
||||
@@ -831,34 +832,6 @@ static void keyboard_special(uint16_t k)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyboard_set_power_button(int pressed)
|
||||
{
|
||||
enum scancode_set_list code_set;
|
||||
uint8_t code[2][2][3] = {
|
||||
{ /* set 1 */
|
||||
{0xe0, 0xde}, /* break */
|
||||
{0xe0, 0x5e}, /* make */
|
||||
}, { /* set 2 */
|
||||
{0xe0, 0xf0, 0x37}, /* break */
|
||||
{0xe0, 0x37}, /* make */
|
||||
}
|
||||
};
|
||||
|
||||
power_button_pressed = pressed;
|
||||
|
||||
/* Only send the scan code if main chipset is fully awake */
|
||||
if (!chipset_in_state(CHIPSET_STATE_ON))
|
||||
return;
|
||||
|
||||
code_set = acting_code_set(scancode_set);
|
||||
if (keystroke_enabled) {
|
||||
i8042_send_to_host(
|
||||
(code_set == SCANCODE_SET_2 && !pressed) ? 3 : 2,
|
||||
code[code_set - SCANCODE_SET_1][pressed]);
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_protocol_task(void)
|
||||
{
|
||||
int wait = -1;
|
||||
@@ -1097,3 +1070,36 @@ static void keyboard_restore_state(void)
|
||||
}
|
||||
}
|
||||
DECLARE_HOOK(HOOK_INIT, keyboard_restore_state, HOOK_PRIO_DEFAULT);
|
||||
|
||||
/**
|
||||
* Handle power button changing state.
|
||||
*/
|
||||
static void keyboard_power_button(void)
|
||||
{
|
||||
enum scancode_set_list code_set;
|
||||
uint8_t code[2][2][3] = {
|
||||
{ /* set 1 */
|
||||
{0xe0, 0xde}, /* break */
|
||||
{0xe0, 0x5e}, /* make */
|
||||
}, { /* set 2 */
|
||||
{0xe0, 0xf0, 0x37}, /* break */
|
||||
{0xe0, 0x37}, /* make */
|
||||
}
|
||||
};
|
||||
|
||||
power_button_pressed = power_button_is_pressed();
|
||||
|
||||
/*
|
||||
* Only send the scan code if main chipset is fully awake and
|
||||
* keystrokes are enabled.
|
||||
*/
|
||||
if (!chipset_in_state(CHIPSET_STATE_ON) || !keystroke_enabled)
|
||||
return;
|
||||
|
||||
code_set = acting_code_set(scancode_set);
|
||||
i8042_send_to_host(
|
||||
(code_set == SCANCODE_SET_2 && !power_button_pressed) ? 3 : 2,
|
||||
code[code_set - SCANCODE_SET_1][power_button_pressed]);
|
||||
}
|
||||
DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, keyboard_power_button,
|
||||
HOOK_PRIO_DEFAULT);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "host_command.h"
|
||||
#include "lid_switch.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
135
common/power_button.c
Normal file
135
common/power_button.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/* Power button module for Chrome EC */
|
||||
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "host_command.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "lid_switch.h"
|
||||
#include "power_button.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 PWRBTN_DEBOUNCE_US (30 * MSEC) /* Debounce time for power button */
|
||||
|
||||
static int debounced_power_pressed; /* Debounced power button state */
|
||||
static int simulate_power_pressed;
|
||||
|
||||
/**
|
||||
* Get raw power button signal state.
|
||||
*
|
||||
* @return 1 if power button is pressed, 0 if not pressed.
|
||||
*/
|
||||
static int raw_power_button_pressed(void)
|
||||
{
|
||||
if (simulate_power_pressed)
|
||||
return 1;
|
||||
|
||||
/* Ignore power button if lid is closed */
|
||||
if (!lid_is_open())
|
||||
return 0;
|
||||
|
||||
return gpio_get_level(GPIO_POWER_BUTTON_L) ? 0 : 1;
|
||||
}
|
||||
|
||||
int power_button_is_pressed(void)
|
||||
{
|
||||
return debounced_power_pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle power button initialization.
|
||||
*/
|
||||
static void power_button_init(void)
|
||||
{
|
||||
if (raw_power_button_pressed())
|
||||
debounced_power_pressed = 1;
|
||||
|
||||
/* Enable interrupts, now that we've initialized */
|
||||
gpio_enable_interrupt(GPIO_POWER_BUTTON_L);
|
||||
}
|
||||
DECLARE_HOOK(HOOK_INIT, power_button_init, HOOK_PRIO_INIT_POWER_BUTTON);
|
||||
|
||||
/**
|
||||
* Handle debounced power button changing state.
|
||||
*/
|
||||
static void power_button_change_deferred(void)
|
||||
{
|
||||
const int new_pressed = raw_power_button_pressed();
|
||||
|
||||
/* If power button hasn't changed state, nothing to do */
|
||||
if (new_pressed == debounced_power_pressed)
|
||||
return;
|
||||
|
||||
debounced_power_pressed = new_pressed;
|
||||
|
||||
CPRINTF("[%T power button %s]\n", new_pressed ? "pressed" : "released");
|
||||
|
||||
/* Re-enable keyboard scanning if power button is no longer pressed */
|
||||
if (!new_pressed)
|
||||
keyboard_scan_enable(1);
|
||||
|
||||
/* Call hooks */
|
||||
hook_notify(HOOK_POWER_BUTTON_CHANGE);
|
||||
|
||||
/* Notify host if power button has been pressed */
|
||||
if (new_pressed)
|
||||
host_set_single_event(EC_HOST_EVENT_POWER_BUTTON);
|
||||
}
|
||||
DECLARE_DEFERRED(power_button_change_deferred);
|
||||
|
||||
void power_button_interrupt(enum gpio_signal signal)
|
||||
{
|
||||
/*
|
||||
* If power button is pressed, disable the matrix scan as soon as
|
||||
* possible to reduce the risk of false-reboot triggered by those keys
|
||||
* on the same column with refresh key.
|
||||
*/
|
||||
if (raw_power_button_pressed())
|
||||
keyboard_scan_enable(0);
|
||||
|
||||
/* Reset power button debounce time */
|
||||
hook_call_deferred(power_button_change_deferred, PWRBTN_DEBOUNCE_US);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Console commands */
|
||||
|
||||
static int command_powerbtn(int argc, char **argv)
|
||||
{
|
||||
int ms = 200; /* Press duration in ms */
|
||||
char *e;
|
||||
|
||||
if (argc > 1) {
|
||||
ms = strtoi(argv[1], &e, 0);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM1;
|
||||
}
|
||||
|
||||
ccprintf("Simulating %d ms power button press.\n", ms);
|
||||
simulate_power_pressed = 1;
|
||||
hook_call_deferred(power_button_change_deferred, 0);
|
||||
|
||||
msleep(ms);
|
||||
|
||||
ccprintf("Simulating power button release.\n");
|
||||
simulate_power_pressed = 0;
|
||||
hook_call_deferred(power_button_change_deferred, 0);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn,
|
||||
"[msec]",
|
||||
"Simulate power button press",
|
||||
NULL);
|
||||
|
||||
@@ -96,6 +96,10 @@ SECTIONS
|
||||
*(.rodata.HOOK_LID_CHANGE)
|
||||
__hooks_lid_change_end = .;
|
||||
|
||||
__hooks_pwrbtn_change = .;
|
||||
*(.rodata.HOOK_POWER_BUTTON_CHANGE)
|
||||
__hooks_pwrbtn_change_end = .;
|
||||
|
||||
__hooks_tick = .;
|
||||
*(.rodata.HOOK_TICK)
|
||||
__hooks_tick_end = .;
|
||||
|
||||
@@ -38,6 +38,8 @@ extern const struct hook_data __hooks_ac_change[];
|
||||
extern const struct hook_data __hooks_ac_change_end[];
|
||||
extern const struct hook_data __hooks_lid_change[];
|
||||
extern const struct hook_data __hooks_lid_change_end[];
|
||||
extern const struct hook_data __hooks_pwrbtn_change[];
|
||||
extern const struct hook_data __hooks_pwrbtn_change_end[];
|
||||
extern const struct hook_data __hooks_tick[];
|
||||
extern const struct hook_data __hooks_tick_end[];
|
||||
extern const struct hook_data __hooks_second[];
|
||||
|
||||
@@ -25,6 +25,8 @@ enum hook_priority {
|
||||
HOOK_PRIO_INIT_CHIPSET = HOOK_PRIO_FIRST + 2,
|
||||
/* Lid switch inits before power button */
|
||||
HOOK_PRIO_INIT_LID = HOOK_PRIO_FIRST + 3,
|
||||
/* Power button inits before chipset and switch */
|
||||
HOOK_PRIO_INIT_POWER_BUTTON = HOOK_PRIO_FIRST + 4,
|
||||
};
|
||||
|
||||
enum hook_type {
|
||||
@@ -105,6 +107,14 @@ enum hook_type {
|
||||
*/
|
||||
HOOK_LID_CHANGE,
|
||||
|
||||
/*
|
||||
* Power button pressed or released. Based on debounced power button
|
||||
* state, not raw GPIO input.
|
||||
*
|
||||
* Hook routines are called from the chipset task.
|
||||
*/
|
||||
HOOK_POWER_BUTTON_CHANGE,
|
||||
|
||||
/*
|
||||
* Periodic tick, every HOOK_TICK_INTERVAL.
|
||||
*
|
||||
|
||||
@@ -27,9 +27,4 @@ void keyboard_host_write(int data, int is_cmd);
|
||||
*/
|
||||
void keyboard_state_changed(int row, int col, int is_pressed);
|
||||
|
||||
/**
|
||||
* Send make/break code of power button to host.
|
||||
*/
|
||||
void keyboard_set_power_button(int pressed);
|
||||
|
||||
#endif /* __CROS_EC_KEYBOARD_8042_H */
|
||||
|
||||
27
include/power_button.h
Normal file
27
include/power_button.h
Normal file
@@ -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.
|
||||
*/
|
||||
|
||||
/* Power button API for Chrome EC */
|
||||
|
||||
#ifndef __CROS_EC_POWER_BUTTON_H
|
||||
#define __CROS_EC_POWER_BUTTON_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Return non-zero if power button is pressed.
|
||||
*
|
||||
* Uses the debounced button state, not the raw signal from the GPIO.
|
||||
*/
|
||||
int power_button_is_pressed(void);
|
||||
|
||||
/**
|
||||
* Interrupt handler for power button.
|
||||
*
|
||||
* @param signal Signal which triggered the interrupt.
|
||||
*/
|
||||
void power_button_interrupt(enum gpio_signal signal);
|
||||
|
||||
#endif /* __CROS_EC_POWER_BUTTON_H */
|
||||
Reference in New Issue
Block a user