diff options
author | Ting Shen <phoenixshen@google.com> | 2020-10-30 16:46:55 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-11-10 07:56:46 +0000 |
commit | decb6363e9ca50b0c15f9073872af28ba54e726a (patch) | |
tree | 47d458422726fd489a256989118fe5318be0c938 /chip/stm32 | |
parent | 6bc9bb622a31845277d5513fa80fb6766ee68f6c (diff) | |
download | chrome-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/stm32')
-rw-r--r-- | chip/stm32/usb_hid_keyboard.c | 113 |
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); |