diff options
author | Hung-Te Lin <hungte@chromium.org> | 2018-08-07 12:55:15 +0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2018-08-07 13:54:19 +0000 |
commit | cbd826bd406036494ba0b02b9f5f031fd0ae0570 (patch) | |
tree | de76ccc3eab13b4917ad3c723d5369bfd2fc61de | |
parent | 938993b470ed698f9ea49755c42eeb9deb4dc92a (diff) | |
download | chrome-ec-cbd826bd406036494ba0b02b9f5f031fd0ae0570.tar.gz |
eve: Support dynamic mapping for legacy layout.
For Eve, we want to enable dynamic mapping with few layout changes:
1. Map ASSIST to WIN(Left) since it's having a similar location.
2. Map MENU to APP.
3. Map SEARCH to Fn.
4. When Fn is hold, remap F1~F10 to similar functions as in Chrome OS.
5. (Chrome OS shortcuts) Fn+.=Ins, Fn+BS=Del, Fn+Alt=CapsLock
6. (Keys not for ChromeOS) Fn+B=Break, FN+P=Pause
BUG=b:72200093
BRANCH=eve
TEST=Builds and boot properly.
Change-Id: I0b02c709c780b468bc9bd70c053e85a07733ac50
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1164726
-rw-r--r-- | board/eve/board.c | 12 | ||||
-rw-r--r-- | board/eve/board.h | 2 | ||||
-rw-r--r-- | board/eve/build.mk | 1 | ||||
-rw-r--r-- | board/eve/keyboard_legacy.c | 188 | ||||
-rw-r--r-- | common/keyboard_8042.c | 2 | ||||
-rw-r--r-- | include/keyboard_8042.h | 11 | ||||
-rw-r--r-- | test/build.mk | 3 |
7 files changed, 218 insertions, 1 deletions
diff --git a/board/eve/board.c b/board/eve/board.c index 725da656c7..565a333833 100644 --- a/board/eve/board.c +++ b/board/eve/board.c @@ -60,6 +60,13 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) +/* + * Initialize keyboard mapping type. + * If CONFIG_KEYBOARD_DYNAMIC_MAPPING is set, a different implementation will + * be provided in keyboard_legacy.c. + */ +__attribute__((weak)) void board_init_keyboard_mapping(int reset) {} + static void tcpc_alert_event(enum gpio_signal signal) { if ((signal == GPIO_USB_C0_PD_INT_ODL) && @@ -505,6 +512,8 @@ static void board_init(void) scancode_set2[3][9] = 0xe007; } #endif + + board_init_keyboard_mapping(0); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); @@ -686,6 +695,7 @@ static void board_chipset_startup(void) /* Enable Trackpad */ gpio_set_level(GPIO_TRACKPAD_SHDN_L, 1); hook_call_deferred(&enable_input_devices_data, 0); + board_init_keyboard_mapping(0); } DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); @@ -697,6 +707,7 @@ static void board_chipset_shutdown(void) dsp_wake_enable(0); gpio_set_level(GPIO_TRACKPAD_SHDN_L, 0); hook_call_deferred(&enable_input_devices_data, 0); + board_init_keyboard_mapping(0); } DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT); @@ -727,6 +738,7 @@ DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); static void board_chipset_reset(void) { board_report_pmic_fault("CHIPSET RESET"); + board_init_keyboard_mapping(1); } DECLARE_HOOK(HOOK_CHIPSET_RESET, board_chipset_reset, HOOK_PRIO_DEFAULT); diff --git a/board/eve/board.h b/board/eve/board.h index 05cdba3cdb..794b1421ee 100644 --- a/board/eve/board.h +++ b/board/eve/board.h @@ -76,6 +76,7 @@ #define CONFIG_KEYBOARD_COL2_INVERTED #define CONFIG_KEYBOARD_PROTOCOL_8042 #define CONFIG_KEYBOARD_SCANCODE_MUTABLE +#define CONFIG_KEYBOARD_DYNAMIC_MAPPING #define CONFIG_TABLET_MODE #undef CONFIG_PECI @@ -311,6 +312,7 @@ void board_set_tcpc_power_mode(int port, int mode); void board_tcpc_init(void); void led_register_double_tap(void); void board_update_ac_status(void); +void board_init_keyboard_mapping(int reset); /* Sensors without hardware FIFO are in forced mode */ #define CONFIG_ACCEL_FORCE_MODE_MASK ((1 << LID_ACCEL) | (1 << LID_LIGHT)) diff --git a/board/eve/build.mk b/board/eve/build.mk index f47b5d9caf..8b621d862c 100644 --- a/board/eve/build.mk +++ b/board/eve/build.mk @@ -12,3 +12,4 @@ CHIP_VARIANT:=npcx5m6g board-y=board.o led.o board-$(CONFIG_BATTERY_SMART)+=battery.o board-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o +board-$(CONFIG_KEYBOARD_DYNAMIC_MAPPING)+=keyboard_legacy.o diff --git a/board/eve/keyboard_legacy.c b/board/eve/keyboard_legacy.c new file mode 100644 index 0000000000..bb6ee5ac30 --- /dev/null +++ b/board/eve/keyboard_legacy.c @@ -0,0 +1,188 @@ +/* Copyright 2018 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. + */ + +/* Eve board-specific keyboard configuration for legacy mode */ + +#include "board_config.h" +#include "chipset.h" +#include "keyboard_8042.h" +#include "keyboard_protocol.h" +#include "util.h" + +/** + * Special make codes for keys to handle directly. Make code in all code sets + * should not start with 0xf0 so we can use that to encode special values. + */ +#define MK_PAUSE 0xf001 +#define MK_CBREAK 0xf002 +#define MK_DIM 0xf003 +#define MK_BRIGHT 0xf004 + +/* Use SEARCH (before translate) as Fn key. */ +static const struct makecode_entry makecode_fn_key = { + .set1 = 0xe05b, .set2 = 0xe01f }; + +static const struct makecode_translate_entry legacy_mapping[] = { + /* from[set1,set2], to[set1,set2] */ + { {0xe058, 0xe007}, {0xe05b, 0xe020} }, /* ASSIST => SEARCH(Win) */ + { {0x005d, 0x002f}, {0xe05d, 0xe02f} }, /* MENU => APP */ +}; + +/* Alternate mapping when Fn is pressed. */ +static const struct makecode_translate_entry legacy_fn_mapping[] = { + /* from[set1,set2], to[set1,set2] */ + {{0x003b, 0x0005}, {0xe06a, 0xe038}}, /* F1 => Browser Back */ + {{0x003c, 0x0006}, {0xe067, 0xe020}}, /* F2 => Browser Refresh */ + {{0x003d, 0x0004}, {0x0057, 0x0078}}, /* F3 => Full Screen */ + {{0x003e, 0x000c}, {0xe037, 0xe07c}}, /* F4 => Print Screen */ + {{0x003f, 0x0003}, {MK_DIM, MK_DIM}}, /* F5 => Dim Screen */ + {{0x0040, 0x000b}, {MK_BRIGHT, MK_BRIGHT}}, /* F6 => Brighten */ + {{0x0041, 0x0083}, {0xe022, 0xe034}}, /* F7 => Play/Pause */ + {{0x0042, 0x000a}, {0xe020, 0xe023}}, /* F8 => Mute */ + {{0x0043, 0x0001}, {0xe02e, 0xe021}}, /* F9 => Vol Down */ + {{0x0044, 0x0009}, {0xe030, 0xe032}}, /* F10 => Vol Up */ + + {{0x0038, 0x0011}, {0x003a, 0x0058}}, /* LAlt => Caps Lock */ + {{0x0034, 0x0049}, {0xe052, 0xe070}}, /* Dot(.) => Insert */ + {{0x000e, 0x0066}, {0xe053, 0xe071}}, /* BackSpace => Delete */ + + {{0x0019, 0x004d}, {MK_PAUSE, MK_PAUSE}}, /* P => Pause */ + {{0x0030, 0x0032}, {MK_CBREAK, MK_CBREAK}}, /* B => Ctrl-Break */ + + {{0xe048, 0xe075}, {0xe049, 0xe07d}}, /* Up => Page Up */ + {{0xe050, 0xe072}, {0xe051, 0xe07a}}, /* Down => Page Down */ + {{0xe04b, 0xe06b}, {0xe047, 0xe06c}}, /* Left => Home */ + {{0xe04d, 0xe074}, {0xe04f, 0xe069}}, /* Right => End */ +}; + +static const char pause_key_scancode_set1[] = { + 0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5 +}; + +static const char pause_key_scancode_set2[] = { + 0xe1, 0x14, 0x77, 0xe1, 0xf0, 0x14, 0xf0, 0x77 +}; + +static const char cbreak_key_scancode_set1[] = { + 0xe0, 0x46, 0xe0, 0xc6 +}; + +static const char cbreak_key_scancode_set2[] = { + 0xe0, 0x7e, 0xe0, 0xf0, 0x7e +}; + +struct mk_entry { + int len; + const char *data; +}; + +struct mk_data { + struct mk_entry make_set1, make_set2, break_set1, break_set2; +}; + +/* PAUSE and CBREAK do not have 8042 break code. */ +static const struct mk_data mk_pause = { + {ARRAY_SIZE(pause_key_scancode_set1), + ARRAY_BEGIN(pause_key_scancode_set1)}, + {ARRAY_SIZE(pause_key_scancode_set2), + ARRAY_BEGIN(pause_key_scancode_set2)}, +}; + +static const const struct mk_data mk_cbreak = { + {ARRAY_SIZE(cbreak_key_scancode_set1), + ARRAY_BEGIN(cbreak_key_scancode_set1)}, + {ARRAY_SIZE(cbreak_key_scancode_set2), + ARRAY_BEGIN(cbreak_key_scancode_set2)}, +}; + +/* Indicate if the mapping is KEYBOARD_MAPPING_LEGACY. */ +static int is_legacy_mapping; + +/* Indicate if Fn key is already pressed. */ +static int fn_pressed; + +/* Override the board_init_keyboard_mapping in board.c */ +void board_init_keyboard_mapping(int reset) +{ + if (reset && chipset_in_state(CHIPSET_STATE_SUSPEND)) + return; + keyboard_select_mapping(KEYBOARD_MAPPING_DEFAULT); +} + +/* Callback when the mapping is changed (keyboard_select_mapping called). */ +void keyboard_board_mapping_changed(enum keyboard_mapping_type new_mapping) +{ + is_legacy_mapping = (new_mapping == KEYBOARD_MAPPING_LEGACY); +} + +static void process_mk_data(const struct mk_entry *make_code, + const struct mk_entry *break_code, + int8_t pressed) +{ + if (pressed) { + if (make_code->len) + i8042_send_to_host(make_code->len, make_code->data); + } else { + if (break_code->len) + i8042_send_to_host(break_code->len, break_code->data); + } +} + + +static void process_mk(const struct mk_data *data, int8_t pressed, + enum scancode_set_list code_set) +{ + if (code_set == SCANCODE_SET_1) { + process_mk_data(&data->make_set1, &data->break_set1, pressed); + } else if (code_set == SCANCODE_SET_2) { + process_mk_data(&data->make_set2, &data->break_set2, pressed); + } +} + +/* Translate legacy keys */ +uint16_t keyboard_board_translate(uint16_t make_code, int8_t pressed, + enum scancode_set_list code_set) +{ + if (!is_legacy_mapping) + return make_code; + + /* Fn must be processed because Fn makecode conflicts with Win. */ + if (makecode_match(make_code, code_set, &makecode_fn_key)) { + fn_pressed = pressed; + /** + * TODO(hungte): If we press Fn, X, (triggers an Fn+X make) then + * release Fn, X, then it'll trigger a X break instead of Fn+X + * break. This is a known issue and should be fixed. + */ + return 0; + } + + make_code = makecode_translate( + make_code, code_set, ARRAY_BEGIN(legacy_mapping), + ARRAY_SIZE(legacy_mapping)); + if (!fn_pressed) + return make_code; + + make_code = makecode_translate( + make_code, code_set, ARRAY_BEGIN(legacy_fn_mapping), + ARRAY_SIZE(legacy_fn_mapping)); + switch (make_code) { + case MK_PAUSE: + process_mk(&mk_pause, pressed, code_set); + return 0; + + case MK_CBREAK: + process_mk(&mk_cbreak, pressed, code_set); + return 0; + + case MK_DIM: + /* TODO(hungte): Complete how to dim screen. */ + return 0; + case MK_BRIGHT: + /* TODO(hungte): Complete how to brighten screen. */ + return 0; + } + return make_code; +} diff --git a/common/keyboard_8042.c b/common/keyboard_8042.c index 79a2188859..303515b6dd 100644 --- a/common/keyboard_8042.c +++ b/common/keyboard_8042.c @@ -266,7 +266,7 @@ static void keyboard_enable_irq(int enable) * @param len Number of bytes to send to the host * @param to_host Data to send */ -static void i8042_send_to_host(int len, const uint8_t *bytes) +void i8042_send_to_host(int len, const uint8_t *bytes) { int i; diff --git a/include/keyboard_8042.h b/include/keyboard_8042.h index ee07f1d81d..e43ceb1164 100644 --- a/include/keyboard_8042.h +++ b/include/keyboard_8042.h @@ -30,6 +30,17 @@ void button_state_changed(enum keyboard_button_type button, int is_pressed); */ void keyboard_host_write(int data, int is_cmd); +/** + * Send a scan code to the host. + * + * The EC lib will push the scan code bytes to host via port 0x60 and assert + * the IBF flag to trigger an interrupt. The EC lib must queue them if the + * host cannot read the previous byte away in time. + * + * @param len Number of bytes to send to the host + * @param bytes Data to send + */ +void i8042_send_to_host(int len, const uint8_t *bytes); /* Utilities for scan code and make code. */ diff --git a/test/build.mk b/test/build.mk index b92e263e8f..e263f2b8b8 100644 --- a/test/build.mk +++ b/test/build.mk @@ -25,6 +25,9 @@ test-list-$(BOARD_LLAMA)= # So does Cr50 test-list-$(BOARD_CR50)= +# So does Eve +test-list-$(BOARD_EVE)= + # For some tests, we are running out of RAM. Disable them for now. test-list-$(BOARD_GLADOS_PD)= test-list-$(BOARD_CHELL_PD)= |