diff options
-rw-r--r-- | chip/lm4/power_button.c | 14 | ||||
-rw-r--r-- | common/keyboard.c | 46 | ||||
-rw-r--r-- | common/x86_power.c | 6 | ||||
-rw-r--r-- | include/keyboard.h | 5 | ||||
-rw-r--r-- | include/x86_power.h | 4 |
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 */ |