summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorTing Shen <phoenixshen@google.com>2020-10-30 16:46:55 +0800
committerCommit Bot <commit-bot@chromium.org>2020-11-10 07:56:46 +0000
commitdecb6363e9ca50b0c15f9073872af28ba54e726a (patch)
tree47d458422726fd489a256989118fe5318be0c938 /chip
parent6bc9bb622a31845277d5513fa80fb6766ee68f6c (diff)
downloadchrome-ec-decb6363e9ca50b0c15f9073872af28ba54e726a.tar.gz
hammer: support vivaldi keyboard
This CL implements vivald function row config for hammer keyboard. If CONFIG_USB_HID_KEYBOARD_VIVALDI defined, STM32 HID keyboard now returns an extra 32-bit data represents the status of action keys. Additionally, if board_vivaldi_keybd_config returns a non-null pointer, driver will convert function keys to action key according to the given config. BUG=b:171156337 TEST=verify keycode is correct in `evtest` BRANCH=none Signed-off-by: Ting Shen <phoenixshen@google.com> Change-Id: Ide3289fd2c1bb8859a74e97134e6113441cfb967 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2508848 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org> Commit-Queue: Ting Shen <phoenixshen@chromium.org> Tested-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/stm32/usb_hid_keyboard.c113
1 files changed, 112 insertions, 1 deletions
diff --git a/chip/stm32/usb_hid_keyboard.c b/chip/stm32/usb_hid_keyboard.c
index a0b1a1d317..fb70e60e61 100644
--- a/chip/stm32/usb_hid_keyboard.c
+++ b/chip/stm32/usb_hid_keyboard.c
@@ -69,6 +69,9 @@ struct usb_hid_keyboard_report {
/* Assistant/tablet mode switch bitmask */
uint8_t extra;
#endif
+#ifdef CONFIG_USB_HID_KEYBOARD_VIVALDI
+ uint32_t top_row; /* bitmap of top row action keys */
+#endif
} __packed;
struct usb_hid_keyboard_output_report {
@@ -105,6 +108,12 @@ struct usb_hid_keyboard_output_report {
#define HID_KEYBOARD_MODIFIER_LOW 0xe0
#define HID_KEYBOARD_MODIFIER_HIGH 0xe7
+/* Supported function key range */
+#define HID_F1 0x3a
+#define HID_F12 0x45
+#define HID_F13 0x68
+#define HID_F15 0x6a
+
/* Special keys/switches */
#define HID_KEYBOARD_EXTRA_LOW 0xf0
#define HID_KEYBOARD_ASSISTANT_KEY 0xf0
@@ -197,6 +206,38 @@ const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID_KEYBOARD, 02) = {
0x29, 0xa4, /* Usage Maximum (164) */ \
0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */
+#define KEYBOARD_TOP_ROW_DESC \
+ /* Modifiers */ \
+ 0x05, 0x0C, /* Consumer Page */ \
+ 0x0A, 0x24, 0x02, /* AC Back (0x224) */ \
+ 0x0A, 0x25, 0x02, /* AC Forward (0x225) */ \
+ 0x0A, 0x27, 0x02, /* AC Refresh (0x227) */ \
+ 0x0A, 0x32, 0x02, /* AC View Toggle (0x232) */ \
+ 0x0A, 0x9F, 0x02, /* AC Desktop Show All windows (0x29F) */ \
+ 0x09, 0x70, /* Display Brightness Decrement (0x70) */ \
+ 0x09, 0x6F, /* Display Brightness Increment (0x6F) */ \
+ 0x09, 0xE2, /* Mute (0xE2) */ \
+ 0x09, 0xEA, /* Volume Decrement (0xEA) */ \
+ 0x09, 0xE9, /* Volume Increment (0xE9) */ \
+ 0x0B, 0x46, 0x00, 0x07, 0x00, /* PrintScreen (Page 0x7, Usage 0x46) */ \
+ 0x0A, 0xD0, 0x02, /* Privacy Screen Toggle (0x2D0) */ \
+ 0x09, 0x7A, /* Keyboard Brightness Decrement (0x7A) */ \
+ 0x09, 0x79, /* Keyboard Brightness Increment (0x79)*/ \
+ 0x09, 0xCD, /* Play / Pause (0xCD) */ \
+ 0x09, 0xB5, /* Scan Next Track (0xB5) */ \
+ 0x09, 0xB6, /* Scan Previous Track (0xB6) */ \
+ 0x09, 0x32, /* Sleep (0x32) */ \
+ 0x15, 0x00, /* Logical Minimum (0) */ \
+ 0x25, 0x01, /* Logical Maximum (1) */ \
+ 0x75, 0x01, /* Report Size (1) */ \
+ 0x95, 0x12, /* Report Count (18) */ \
+ 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */ \
+ \
+ /* 14-bit padding */ \
+ 0x95, 0x0E, /* Report Count (14) */ \
+ 0x75, 0x01, /* Report Size (1) */ \
+ 0x81, 0x01, /* Input (Constant), ;1-bit padding */
+
/*
* Vendor-defined Usage Page 0xffd1:
* - 0x18: Assistant key
@@ -273,6 +314,9 @@ static const uint8_t report_desc[] = {
KEYBOARD_VENDOR_DESC
#endif
+#ifdef CONFIG_USB_HID_KEYBOARD_VIVALDI
+ KEYBOARD_TOP_ROW_DESC
+#endif
0xC0 /* End Collection */
};
@@ -288,6 +332,9 @@ static const uint8_t report_desc_with_backlight[] = {
KEYBOARD_VENDOR_DESC
#endif
+#ifdef CONFIG_USB_HID_KEYBOARD_VIVALDI
+ KEYBOARD_TOP_ROW_DESC
+#endif
KEYBOARD_BACKLIGHT_DESC
0xC0 /* End Collection */
@@ -489,6 +536,59 @@ void keyboard_clear_buffer(void)
write_keyboard_report();
}
+/* mapping from action_key to bit mask of usb_hid_keyboard_report.top_row */
+static const uint32_t action_key_mapping[] = {
+ [TK_BACK] = BIT(0),
+ [TK_FORWARD] = BIT(1),
+ [TK_REFRESH] = BIT(2),
+ [TK_FULLSCREEN] = BIT(3),
+ [TK_OVERVIEW] = BIT(4),
+ [TK_BRIGHTNESS_DOWN] = BIT(5),
+ [TK_BRIGHTNESS_UP] = BIT(6),
+ [TK_VOL_MUTE] = BIT(7),
+ [TK_VOL_DOWN] = BIT(8),
+ [TK_VOL_UP] = BIT(9),
+ [TK_SNAPSHOT] = BIT(10),
+ [TK_PRIVACY_SCRN_TOGGLE] = BIT(11),
+ [TK_KBD_BKLIGHT_DOWN] = BIT(12),
+ [TK_KBD_BKLIGHT_UP] = BIT(13),
+ [TK_PLAY_PAUSE] = BIT(14),
+ [TK_NEXT_TRACK] = BIT(15),
+ [TK_PREV_TRACK] = BIT(16),
+};
+
+/*
+ * Convert a function key to the bit mask of corresponding action key.
+ *
+ * Return 0 if no need to map (not a function key or vivaldi not enabled)
+ */
+static uint32_t maybe_convert_function_key(int keycode)
+{
+ const struct ec_response_keybd_config *config =
+ board_vivaldi_keybd_config();
+ /* zero-based function key index (e.g. F1 -> 0) */
+ int index;
+
+ if (!IS_ENABLED(CONFIG_USB_HID_KEYBOARD_VIVALDI) || !config)
+ return 0;
+
+ if (IN_RANGE(keycode, HID_F1, HID_F12 + 1))
+ index = keycode - HID_F1;
+ else if (IN_RANGE(keycode, HID_F13, HID_F15 + 1))
+ index = keycode - HID_F13 + 12;
+ else
+ return 0; /* not a function key */
+
+ /* convert F13 to Sleep */
+ if (index == 12 && (config->capabilities & KEYBD_CAP_SCRNLOCK_KEY))
+ return BIT(17);
+
+ if (index >= config->num_top_row_keys ||
+ config->action_keys[index] == TK_ABSENT)
+ return 0; /* not mapped */
+ return action_key_mapping[config->action_keys[index]];
+}
+
static void keyboard_process_queue(void)
{
int i;
@@ -541,6 +641,8 @@ static void keyboard_process_queue(void)
* dropping keys that are too old.
*/
while (queue_count(&key_queue) > 0) {
+ uint32_t action_key_mask;
+
queue_peek_units(&key_queue, &ev, 0, 1);
if (keyboard_debug)
CPRINTF(" =%02x/%d %d %d\n", ev.keycode, ev.keycode,
@@ -552,7 +654,16 @@ static void keyboard_process_queue(void)
queue_advance_head(&key_queue, 1);
- if (ev.keycode >= HID_KEYBOARD_EXTRA_LOW &&
+ action_key_mask = maybe_convert_function_key(ev.keycode);
+ if (action_key_mask) {
+#ifdef CONFIG_USB_HID_KEYBOARD_VIVALDI
+ if (ev.pressed)
+ report.top_row |= action_key_mask;
+ else
+ report.top_row &= ~action_key_mask;
+ valid = 1;
+#endif
+ } else if (ev.keycode >= HID_KEYBOARD_EXTRA_LOW &&
ev.keycode <= HID_KEYBOARD_EXTRA_HIGH) {
#ifdef HID_KEYBOARD_EXTRA_FIELD
mask = 0x01 << (ev.keycode - HID_KEYBOARD_EXTRA_LOW);