summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajat Jain <rajatja@google.com>2020-02-20 18:17:21 -0800
committerCommit Bot <commit-bot@chromium.org>2020-04-21 21:32:51 +0000
commit9ca749eb1a57a7e8c705ec0f11ab992d8394cc37 (patch)
tree215e47e26787ddb8f9ffdb155ed3edfddebbd95a
parentd4105005da492f8e20619cad88fdb15d6dee098f (diff)
downloadchrome-ec-9ca749eb1a57a7e8c705ec0f11ab992d8394cc37.tar.gz
common/keyboard_vivaldi: New keyboard framework for custom layout
Vivaldi is a new keyboard that allows individual boards to have additional or different top row keys and/or to reorder those keys. The primary agenda of vivaldi is to allow customization of the top row keys. However, as a secondary objective, it also allows coreboot to send a keymap to the kernel, for only the keys that are actually present on the keyboard. As part of enabling vivaldi, another feature that get enabled is to start sending action codes instead of function codes for the top row of the keyboard. go/vivaldi-prd go/vivaldi-design go/vivaldi-fw-design With this patch, things remain unchanged for any boards that do not provide board_set_vivaldi_keybd_config(). For boards that do provide it: * EC begins to send action scancodes instead of function scancodes for the top row when top row keys are pressed. * EC responds to an EC command from the coreboot, that asks for the layout for the keyboard. Coreboot uses this to expose corresponding keycodes to the kernel. BUG=b:146501925 TEST=Check on Jinlon the (new) expected scancodes are output from EC. BRANCH=firmware-hatch-12672.B Signed-off-by: Rajat Jain <rajatja@google.com> Change-Id: I1f45ce6eee138a984f8d4caef1ec76c9538dd30b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2135566
-rw-r--r--board/eve/board.h1
-rw-r--r--board/rammus/board.h1
-rw-r--r--common/build.mk1
-rw-r--r--common/keyboard_vivaldi.c149
-rw-r--r--include/config.h20
-rw-r--r--include/keyboard_8042.h3
-rw-r--r--include/keyboard_8042_sharedlib.h3
-rw-r--r--test/test_config.h1
8 files changed, 178 insertions, 1 deletions
diff --git a/board/eve/board.h b/board/eve/board.h
index 8a46d74156..e271570a47 100644
--- a/board/eve/board.h
+++ b/board/eve/board.h
@@ -71,6 +71,7 @@
#define CONFIG_HOSTCMD_ESPI_VW_SLP_S4
#define CONFIG_KEYBOARD_BOARD_CONFIG
#define CONFIG_KEYBOARD_COL2_INVERTED
+#undef CONFIG_KEYBOARD_VIVALDI
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_REFRESH_ROW3
#define CONFIG_TABLET_MODE
diff --git a/board/rammus/board.h b/board/rammus/board.h
index 738db9c73c..24f9069c60 100644
--- a/board/rammus/board.h
+++ b/board/rammus/board.h
@@ -21,6 +21,7 @@
#define CONFIG_I2C
#define CONFIG_I2C_MASTER
#define CONFIG_KEYBOARD_COL2_INVERTED
+#undef CONFIG_KEYBOARD_VIVALDI
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_LED_COMMON
#define CONFIG_LID_SWITCH
diff --git a/common/build.mk b/common/build.mk
index c241a99550..11afd3e7e3 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -89,6 +89,7 @@ common-$(CONFIG_KEYBOARD_PROTOCOL_8042)+=keyboard_8042.o \
keyboard_8042_sharedlib.o
common-$(CONFIG_KEYBOARD_PROTOCOL_MKBP)+=keyboard_mkbp.o
common-$(CONFIG_KEYBOARD_TEST)+=keyboard_test.o
+common-$(CONFIG_KEYBOARD_VIVALDI)+=keyboard_vivaldi.o
common-$(CONFIG_LED_COMMON)+=led_common.o
common-$(CONFIG_LED_POLICY_STD)+=led_policy_std.o
common-$(CONFIG_LED_PWM)+=led_pwm.o
diff --git a/common/keyboard_vivaldi.c b/common/keyboard_vivaldi.c
new file mode 100644
index 0000000000..28c7dc4523
--- /dev/null
+++ b/common/keyboard_vivaldi.c
@@ -0,0 +1,149 @@
+/* Copyright 2020 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.
+ */
+
+/* Vivali Keyboard code for Chrome EC */
+
+#include "keyboard_8042_sharedlib.h"
+#include "keyboard_scan.h"
+#include "ec_commands.h"
+#include <host_command.h>
+#include <util.h>
+#include <hooks.h>
+
+/* Console output macros */
+#define CPUTS(outstr) cputs(CC_KEYBOARD, outstr)
+#define CPRINTS(format, args...) cprints(CC_KEYBOARD, format, ## args)
+
+/*
+ * Row Column info for Top row keys T1 - T15. This has been sourced from
+ * go/vivaldi-matrix (internal link for vivaldi scan matrix spec).
+ */
+static const struct key {
+ uint8_t row;
+ uint8_t col;
+} vivaldi_keys[] = {
+ {.row = 0, .col = 2}, /* T1 */
+ {.row = 3, .col = 2}, /* T2 */
+ {.row = 2, .col = 2}, /* T3 */
+ {.row = 1, .col = 2}, /* T4 */
+ {.row = 3, .col = 4}, /* T5 */
+ {.row = 2, .col = 4}, /* T6 */
+ {.row = 1, .col = 4}, /* T7 */
+ {.row = 2, .col = 9}, /* T8 */
+ {.row = 1, .col = 9}, /* T9 */
+ {.row = 0, .col = 4}, /* T10 */
+ {.row = 0, .col = 1}, /* T11 */
+ {.row = 1, .col = 5}, /* T12 */
+ {.row = 3, .col = 5}, /* T13 */
+ {.row = 0, .col = 9}, /* T14 */
+ {.row = 0, .col = 11}, /* T15 */
+};
+BUILD_ASSERT(ARRAY_SIZE(vivaldi_keys) == MAX_TOP_ROW_KEYS);
+
+/* Scancodes for top row action keys */
+static const uint16_t action_scancodes[] = {
+ [TK_BACK] = SCANCODE_BACK,
+ [TK_FORWARD] = SCANCODE_FORWARD,
+ [TK_REFRESH] = SCANCODE_REFRESH,
+ [TK_FULLSCREEN] = SCANCODE_FULLSCREEN,
+ [TK_OVERVIEW] = SCANCODE_OVERVIEW,
+ [TK_VOL_MUTE] = SCANCODE_VOLUME_MUTE,
+ [TK_VOL_DOWN] = SCANCODE_VOLUME_DOWN,
+ [TK_VOL_UP] = SCANCODE_VOLUME_UP,
+ [TK_PLAY_PAUSE] = SCANCODE_PLAY_PAUSE,
+ [TK_NEXT_TRACK] = SCANCODE_NEXT_TRACK,
+ [TK_PREV_TRACK] = SCANCODE_PREV_TRACK,
+ [TK_SNAPSHOT] = SCANCODE_SNAPSHOT,
+ [TK_BRIGHTNESS_DOWN] = SCANCODE_BRIGHTNESS_DOWN,
+ [TK_BRIGHTNESS_UP] = SCANCODE_BRIGHTNESS_UP,
+ [TK_KBD_BKLIGHT_DOWN] = SCANCODE_KBD_BKLIGHT_DOWN,
+ [TK_KBD_BKLIGHT_UP] = SCANCODE_KBD_BKLIGHT_UP,
+ [TK_PRIVACY_SCRN_TOGGLE] = SCANCODE_PRIVACY_SCRN_TOGGLE,
+};
+
+static const struct ec_response_keybd_config *vivaldi_keybd;
+
+static enum
+ec_status get_vivaldi_keybd_config(struct host_cmd_handler_args *args)
+{
+ struct ec_response_keybd_config *resp = args->response;
+
+ if (vivaldi_keybd && vivaldi_keybd->num_top_row_keys) {
+ memcpy(resp, vivaldi_keybd, sizeof(*resp));
+ args->response_size = sizeof(*resp);
+ return EC_RES_SUCCESS;
+ }
+ return EC_RES_ERROR;
+}
+DECLARE_HOST_COMMAND(EC_CMD_GET_KEYBD_CONFIG, get_vivaldi_keybd_config,
+ EC_VER_MASK(0));
+
+__overridable
+const struct ec_response_keybd_config *board_vivaldi_keybd_config(void)
+{
+ return NULL;
+}
+
+static void vivaldi_init(void)
+{
+ uint8_t i;
+
+ /* Allow the boards to change the keyboard config */
+ vivaldi_keybd = board_vivaldi_keybd_config();
+
+ if (!vivaldi_keybd || !vivaldi_keybd->num_top_row_keys) {
+ CPUTS("VIVALDI keybd disabled on board request");
+ return;
+ }
+
+ CPRINTS("VIVALDI: Num top row keys = %u",
+ vivaldi_keybd->num_top_row_keys);
+
+ if (vivaldi_keybd->num_top_row_keys > MAX_TOP_ROW_KEYS ||
+ vivaldi_keybd->num_top_row_keys < MIN_TOP_ROW_KEYS) {
+ CPRINTS("VIVALDI: Error! num_top_row_keys=%u, disabled vivaldi",
+ vivaldi_keybd->num_top_row_keys);
+ vivaldi_keybd = NULL;
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vivaldi_keys); i++) {
+
+ uint8_t row, col, *mask;
+ enum action_key key;
+
+ row = vivaldi_keys[i].row;
+ col = vivaldi_keys[i].col;
+
+ if (col >= KEYBOARD_COLS_MAX || row >= KEYBOARD_ROWS) {
+ CPRINTS("VIVALDI: Bad (row,col) for T-%u: (%u,%u)",
+ i, row, col);
+ ASSERT(false);
+ }
+
+ mask = &keyscan_config.actual_key_mask[col];
+
+ /*
+ * Potentially indexing past meaningful data,
+ * but we bounds check it below.
+ */
+ key = vivaldi_keybd->action_keys[i];
+
+ if (i < vivaldi_keybd->num_top_row_keys && key != TK_ABSENT) {
+
+ /* Enable the mask */
+ *mask |= BIT(row);
+
+ /* Populate the scancode */
+ set_scancode_set2(row, col, action_scancodes[key]);
+ CPRINTS("VIVALDI key-%u (r-%u, c-%u) = scancode-%X",
+ i, row, col, action_scancodes[key]);
+ } else {
+ /* Disable the mask */
+ *mask &= ~BIT(row);
+ }
+ }
+}
+DECLARE_HOOK(HOOK_INIT, vivaldi_init, HOOK_PRIO_DEFAULT);
diff --git a/include/config.h b/include/config.h
index 0c42772230..984204f5dc 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2367,6 +2367,17 @@
/* Compile code for 8042 keyboard protocol */
#undef CONFIG_KEYBOARD_PROTOCOL_8042
+/*
+ * Enable code for chromeos vivaldi keyboard (standard for new chromeos devices)
+ * This config only takes effect if CONFIG_KEYBOARD_PROTOCOL_8042 is selected. A
+ * chromeos device is Vivaldi compatible if the keyboard matrix complies with:
+ * go/vivaldi-matrix
+ * Vivaldi code enables:
+ * - A response to EC_CMD_GET_KEYBD_CONFIG command from coreboot
+ * - Boards can specify their custom layout for top keys.
+ */
+#define CONFIG_KEYBOARD_VIVALDI
+
/* Compile code for MKBP keyboard protocol */
#undef CONFIG_KEYBOARD_PROTOCOL_MKBP
@@ -5283,4 +5294,13 @@
#endif
#endif /* CONFIG_ONLINE_CALIB */
+/*
+ * Vivaldi keyboard code to be enabled only if board has selected
+ * CONFIG_KEYBOARD_PROTOCOL_8042 and not disabled CONFIG_KEYBOARD_VIVALDI
+ * explicitly
+ */
+#ifndef CONFIG_KEYBOARD_PROTOCOL_8042
+#undef CONFIG_KEYBOARD_VIVALDI
+#endif
+
#endif /* __CROS_EC_CONFIG_H */
diff --git a/include/keyboard_8042.h b/include/keyboard_8042.h
index 3c9e87897c..cc15d6aa7d 100644
--- a/include/keyboard_8042.h
+++ b/include/keyboard_8042.h
@@ -59,4 +59,7 @@ void send_aux_data_to_host(uint8_t data);
*/
void send_aux_data_to_device(uint8_t data);
+__override_proto
+const struct ec_response_keybd_config *board_vivaldi_keybd_config(void);
+
#endif /* __CROS_EC_KEYBOARD_8042_H */
diff --git a/include/keyboard_8042_sharedlib.h b/include/keyboard_8042_sharedlib.h
index ea773cc6f4..8abde3d1d5 100644
--- a/include/keyboard_8042_sharedlib.h
+++ b/include/keyboard_8042_sharedlib.h
@@ -135,9 +135,10 @@ enum scancode_values {
SCANCODE_BACK = 0xe038, /* e06a in codeset 1 */
SCANCODE_REFRESH = 0xe020, /* e067 in codeset 1 */
+ SCANCODE_FORWARD = 0xe030, /* e069 in codeset 1 */
SCANCODE_FULLSCREEN = 0xe01d, /* e011 in codeset 1 */
SCANCODE_OVERVIEW = 0xe024, /* e012 in codeset 1 */
- SCANCODE_SNIP = 0xe02d, /* e013 in codeset 1 */
+ SCANCODE_SNAPSHOT = 0xe02d, /* e013 in codeset 1 */
SCANCODE_BRIGHTNESS_DOWN = 0xe02c, /* e014 in codeset 1 */
SCANCODE_BRIGHTNESS_UP = 0xe035, /* e015 in codeset 1 */
SCANCODE_PRIVACY_SCRN_TOGGLE = 0xe03c, /* e016 in codeset 1 */
diff --git a/test/test_config.h b/test/test_config.h
index 621b1db46a..4e5f413b7a 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -269,6 +269,7 @@ int ncp15wb_calculate_temp(uint16_t adc);
#ifdef TEST_BUTTON
#define CONFIG_KEYBOARD_PROTOCOL_8042
+#undef CONFIG_KEYBOARD_VIVALDI
#define CONFIG_VOLUME_BUTTONS
#endif