summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2018-08-07 12:55:15 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-08-07 13:54:19 +0000
commitcbd826bd406036494ba0b02b9f5f031fd0ae0570 (patch)
treede76ccc3eab13b4917ad3c723d5369bfd2fc61de
parent938993b470ed698f9ea49755c42eeb9deb4dc92a (diff)
downloadchrome-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.c12
-rw-r--r--board/eve/board.h2
-rw-r--r--board/eve/build.mk1
-rw-r--r--board/eve/keyboard_legacy.c188
-rw-r--r--common/keyboard_8042.c2
-rw-r--r--include/keyboard_8042.h11
-rw-r--r--test/build.mk3
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)=