summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/lm4/power_button.c14
-rw-r--r--common/keyboard.c46
-rw-r--r--common/x86_power.c6
-rw-r--r--include/keyboard.h5
-rw-r--r--include/x86_power.h4
5 files changed, 64 insertions, 11 deletions
diff --git a/chip/lm4/power_button.c b/chip/lm4/power_button.c
index 79e7c58f11..7023435fd7 100644
--- a/chip/lm4/power_button.c
+++ b/chip/lm4/power_button.c
@@ -7,6 +7,7 @@
#include "console.h"
#include "gpio.h"
+#include "keyboard.h"
#include "power_button.h"
#include "task.h"
#include "timer.h"
@@ -63,6 +64,11 @@ static void lid_switch_isr(void)
* PWRBTN# --- --------- ----
* to PCH |__| |___________|
* t0 t1 held down
+ *
+ * scan code | |
+ * to host v v
+ * @S0 make code break code
+ *
*/
static void set_pwrbtn_to_pch(int high)
{
@@ -124,15 +130,11 @@ static void power_button_isr(void)
if (!gpio_get_level(GPIO_POWER_BUTTONn)) {
/* pressed */
pwrbtn_sm_start();
- /* TODO: implement after chip/lm4/x86_power.c is completed. */
- /* if system is in S5, power_on_system()
- * elif system is in S3, resume_system()
- * else S0 i8042_send_host(make_code); */
+ keyboard_set_power_button(1);
} else {
/* released */
pwrbtn_sm_stop();
- /* TODO: implement after chip/lm4/x86_power.c is completed. */
- /* if system in S0, i8042_send_host(break_code); */
+ keyboard_set_power_button(0);
}
}
diff --git a/common/keyboard.c b/common/keyboard.c
index 0c90458db9..d854e860b3 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -13,6 +13,8 @@
#include "timer.h"
#include "uart.h"
#include "util.h"
+#include "x86_power.h"
+
#define KEYBOARD_DEBUG 1
@@ -36,6 +38,7 @@ static uint8_t controller_ram[0x20] = {
I8042_XLATE | I8042_AUX_DIS | I8042_KBD_DIS,
/* 0x01 - 0x1f are controller RAM */
};
+static int power_button_pressed = 0;
/*
* Scancode settings
@@ -106,6 +109,17 @@ static uint16_t scancode_set2[CROS_ROW_NUM][CROS_COL_NUM] = {
};
+/* change to set 1 if the I8042_XLATE flag is set. */
+static enum scancode_set_list acting_code_set(enum scancode_set_list set) {
+ if (controller_ram[0] & I8042_XLATE) {
+ /* If the keyboard translation is enabled,
+ * then always generates set 1. */
+ return SCANCODE_SET_1;
+ }
+ return set;
+}
+
+
static enum ec_error_list matrix_callback(
int8_t row, int8_t col, int8_t pressed,
enum scancode_set_list code_set, uint8_t *scan_code, int32_t* len) {
@@ -122,11 +136,7 @@ static enum ec_error_list matrix_callback(
*len = 0;
- if (controller_ram[0] & I8042_XLATE) {
- /* If the keyboard translation is enabled,
- * then always generates set 1. */
- code_set = SCANCODE_SET_1;
- }
+ code_set = acting_code_set(code_set);
switch (code_set) {
case SCANCODE_SET_1:
@@ -516,6 +526,32 @@ int handle_keyboard_command(uint8_t command, uint8_t *output) {
}
+void keyboard_set_power_button(int pressed)
+{
+ enum scancode_set_list code_set;
+ enum ec_error_list ret;
+ 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;
+
+ if (x86_power_in_S0()) {
+ code_set = acting_code_set(scancode_set);
+ ret = i8042_send_to_host(
+ (code_set == SCANCODE_SET_2 && !pressed) ? 3 : 2,
+ code[code_set - SCANCODE_SET_1][pressed]);
+ ASSERT(ret == EC_SUCCESS);
+ }
+}
+
+
static int command_codeset(int argc, char **argv)
{
int set;
diff --git a/common/x86_power.c b/common/x86_power.c
index a911ae436b..d587897d8a 100644
--- a/common/x86_power.c
+++ b/common/x86_power.c
@@ -206,6 +206,12 @@ int x86_power_init(void)
}
/*****************************************************************************/
+int x86_power_in_S0(void) {
+ return state == X86_S0;
+}
+
+
+/*****************************************************************************/
/* Task function */
void x86_power_task(void)
diff --git a/include/keyboard.h b/include/keyboard.h
index 98394e63c7..b00ebfe05e 100644
--- a/include/keyboard.h
+++ b/include/keyboard.h
@@ -50,6 +50,11 @@ int handle_keyboard_data(uint8_t data, uint8_t *output);
int handle_keyboard_command(uint8_t command, uint8_t *output);
+/* Send make/break code of power button to host.
+ */
+void keyboard_set_power_button(int pressed);
+
+
/* Register the board-specific keyboard matrix translation function.
* The callback function accepts col/row and returns the scan code.
*
diff --git a/include/x86_power.h b/include/x86_power.h
index ce28e1b571..2c2ff16357 100644
--- a/include/x86_power.h
+++ b/include/x86_power.h
@@ -17,4 +17,8 @@ int x86_power_init(void);
/* Interrupt handler for input GPIOs */
void x86_power_interrupt(enum gpio_signal signal);
+/* Returns true if the system is in S0. */
+int x86_power_in_S0(void);
+
+
#endif /* __CROS_EC_X86_POWER_H */