From 297faf71d0890e19bdcc39097cb1e8ed93db07fb Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sat, 20 Jan 2024 00:02:26 +0000 Subject: [PATCH] input: add two input to hid code translation functions Add a pair of functions to translate from input events to hid codes, mapping most of the current hid codes defined in zephyr/usb/class/hid.h. Use a sparse table for the mapping, which takes advantage of the fact that code 0 is reserved. Inspired by the linux equivalent hid to input map: https://elixir.bootlin.com/linux/latest/source/drivers/hid/hid-input.c#L27 Signed-off-by: Fabio Baltieri --- include/zephyr/input/input_hid.h | 42 +++++++++ subsys/input/CMakeLists.txt | 1 + subsys/input/input_hid.c | 148 +++++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 include/zephyr/input/input_hid.h create mode 100644 subsys/input/input_hid.c diff --git a/include/zephyr/input/input_hid.h b/include/zephyr/input/input_hid.h new file mode 100644 index 00000000000..2a89dde0530 --- /dev/null +++ b/include/zephyr/input/input_hid.h @@ -0,0 +1,42 @@ +/* + * Copyright 2024 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_INPUT_HID_H_ +#define ZEPHYR_INCLUDE_INPUT_HID_H_ + +/** + * @addtogroup input_interface + * @{ + */ + +/** + * @brief Convert an input code to HID code. + * + * Takes an input code as input and returns the corresponding HID code as + * output. The return value is -1 if the code is not found, if found it can + * safely be casted to a uint8_t type. + * + * @param input_code Event code (see @ref INPUT_KEY_CODES). + * @retval the HID code corresponding to the input code. + * @retval -1 if there's no HID code for the specified input code. + */ +int16_t input_to_hid_code(uint16_t input_code); + +/** + * @brief Convert an input code to HID modifier. + * + * Takes an input code as input and returns the corresponding HID modifier as + * output or 0. + * + * @param input_code Event code (see @ref INPUT_KEY_CODES). + * @retval the HID modifier corresponding to the input code. + * @retval 0 if there's no HID modifier for the specified input code. + */ +uint8_t input_to_hid_modifier(uint16_t input_code); + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_INPUT_HID_H_ */ diff --git a/subsys/input/CMakeLists.txt b/subsys/input/CMakeLists.txt index 99b31351399..f536787d1ea 100644 --- a/subsys/input/CMakeLists.txt +++ b/subsys/input/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() zephyr_library_sources(input.c) +zephyr_library_sources(input_hid.c) zephyr_library_sources(input_utils.c) zephyr_library_sources_ifdef(CONFIG_INPUT_KEYMAP input_keymap.c) diff --git a/subsys/input/input_hid.c b/subsys/input/input_hid.c new file mode 100644 index 00000000000..6ace46eb1a1 --- /dev/null +++ b/subsys/input/input_hid.c @@ -0,0 +1,148 @@ +/* + * Copyright 2024 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +static uint8_t input_to_hid_map[] = { + [INPUT_KEY_A] = HID_KEY_A, + [INPUT_KEY_B] = HID_KEY_B, + [INPUT_KEY_C] = HID_KEY_C, + [INPUT_KEY_D] = HID_KEY_D, + [INPUT_KEY_E] = HID_KEY_E, + [INPUT_KEY_F] = HID_KEY_F, + [INPUT_KEY_G] = HID_KEY_G, + [INPUT_KEY_H] = HID_KEY_H, + [INPUT_KEY_I] = HID_KEY_I, + [INPUT_KEY_J] = HID_KEY_J, + [INPUT_KEY_K] = HID_KEY_K, + [INPUT_KEY_L] = HID_KEY_L, + [INPUT_KEY_M] = HID_KEY_M, + [INPUT_KEY_N] = HID_KEY_N, + [INPUT_KEY_O] = HID_KEY_O, + [INPUT_KEY_P] = HID_KEY_P, + [INPUT_KEY_Q] = HID_KEY_Q, + [INPUT_KEY_R] = HID_KEY_R, + [INPUT_KEY_S] = HID_KEY_S, + [INPUT_KEY_T] = HID_KEY_T, + [INPUT_KEY_U] = HID_KEY_U, + [INPUT_KEY_V] = HID_KEY_V, + [INPUT_KEY_W] = HID_KEY_W, + [INPUT_KEY_X] = HID_KEY_X, + [INPUT_KEY_Y] = HID_KEY_Y, + [INPUT_KEY_Z] = HID_KEY_Z, + [INPUT_KEY_1] = HID_KEY_1, + [INPUT_KEY_2] = HID_KEY_2, + [INPUT_KEY_3] = HID_KEY_3, + [INPUT_KEY_4] = HID_KEY_4, + [INPUT_KEY_5] = HID_KEY_5, + [INPUT_KEY_6] = HID_KEY_6, + [INPUT_KEY_7] = HID_KEY_7, + [INPUT_KEY_8] = HID_KEY_8, + [INPUT_KEY_9] = HID_KEY_9, + [INPUT_KEY_0] = HID_KEY_0, + [INPUT_KEY_ENTER] = HID_KEY_ENTER, + [INPUT_KEY_ESC] = HID_KEY_ESC, + [INPUT_KEY_BACKSPACE] = HID_KEY_BACKSPACE, + [INPUT_KEY_TAB] = HID_KEY_TAB, + [INPUT_KEY_SPACE] = HID_KEY_SPACE, + [INPUT_KEY_MINUS] = HID_KEY_MINUS, + [INPUT_KEY_EQUAL] = HID_KEY_EQUAL, + [INPUT_KEY_LEFTBRACE] = HID_KEY_LEFTBRACE, + [INPUT_KEY_RIGHTBRACE] = HID_KEY_RIGHTBRACE, + [INPUT_KEY_BACKSLASH] = HID_KEY_BACKSLASH, + [INPUT_KEY_SEMICOLON] = HID_KEY_SEMICOLON, + [INPUT_KEY_APOSTROPHE] = HID_KEY_APOSTROPHE, + [INPUT_KEY_GRAVE] = HID_KEY_GRAVE, + [INPUT_KEY_COMMA] = HID_KEY_COMMA, + [INPUT_KEY_DOT] = HID_KEY_DOT, + [INPUT_KEY_SLASH] = HID_KEY_SLASH, + [INPUT_KEY_CAPSLOCK] = HID_KEY_CAPSLOCK, + [INPUT_KEY_F1] = HID_KEY_F1, + [INPUT_KEY_F2] = HID_KEY_F2, + [INPUT_KEY_F3] = HID_KEY_F3, + [INPUT_KEY_F4] = HID_KEY_F4, + [INPUT_KEY_F5] = HID_KEY_F5, + [INPUT_KEY_F6] = HID_KEY_F6, + [INPUT_KEY_F7] = HID_KEY_F7, + [INPUT_KEY_F8] = HID_KEY_F8, + [INPUT_KEY_F9] = HID_KEY_F9, + [INPUT_KEY_F10] = HID_KEY_F10, + [INPUT_KEY_F11] = HID_KEY_F11, + [INPUT_KEY_F12] = HID_KEY_F12, + [INPUT_KEY_SYSRQ] = HID_KEY_SYSRQ, + [INPUT_KEY_SCROLLLOCK] = HID_KEY_SCROLLLOCK, + [INPUT_KEY_PAUSE] = HID_KEY_PAUSE, + [INPUT_KEY_INSERT] = HID_KEY_INSERT, + [INPUT_KEY_HOME] = HID_KEY_HOME, + [INPUT_KEY_PAGEUP] = HID_KEY_PAGEUP, + [INPUT_KEY_DELETE] = HID_KEY_DELETE, + [INPUT_KEY_END] = HID_KEY_END, + [INPUT_KEY_PAGEDOWN] = HID_KEY_PAGEDOWN, + [INPUT_KEY_RIGHT] = HID_KEY_RIGHT, + [INPUT_KEY_LEFT] = HID_KEY_LEFT, + [INPUT_KEY_DOWN] = HID_KEY_DOWN, + [INPUT_KEY_UP] = HID_KEY_UP, + [INPUT_KEY_NUMLOCK] = HID_KEY_NUMLOCK, + [INPUT_KEY_KPSLASH] = HID_KEY_KPSLASH, + [INPUT_KEY_KPASTERISK] = HID_KEY_KPASTERISK, + [INPUT_KEY_KPMINUS] = HID_KEY_KPMINUS, + [INPUT_KEY_KPPLUS] = HID_KEY_KPPLUS, + [INPUT_KEY_KPENTER] = HID_KEY_KPENTER, + [INPUT_KEY_KP1] = HID_KEY_KP_1, + [INPUT_KEY_KP2] = HID_KEY_KP_2, + [INPUT_KEY_KP3] = HID_KEY_KP_3, + [INPUT_KEY_KP4] = HID_KEY_KP_4, + [INPUT_KEY_KP5] = HID_KEY_KP_5, + [INPUT_KEY_KP6] = HID_KEY_KP_6, + [INPUT_KEY_KP7] = HID_KEY_KP_7, + [INPUT_KEY_KP8] = HID_KEY_KP_8, + [INPUT_KEY_KP9] = HID_KEY_KP_9, + [INPUT_KEY_KP0] = HID_KEY_KP_0, +}; + +int16_t input_to_hid_code(uint16_t input_code) +{ + uint8_t hid_code; + + if (input_code >= ARRAY_SIZE(input_to_hid_map)) { + return -1; + } + + hid_code = input_to_hid_map[input_code]; + + if (hid_code == 0) { + return -1; + } + + return hid_code; +} + +uint8_t input_to_hid_modifier(uint16_t input_code) +{ + switch (input_code) { + case INPUT_KEY_LEFTCTRL: + return HID_KBD_MODIFIER_LEFT_CTRL; + case INPUT_KEY_LEFTSHIFT: + return HID_KBD_MODIFIER_LEFT_SHIFT; + case INPUT_KEY_LEFTALT: + return HID_KBD_MODIFIER_LEFT_ALT; + case INPUT_KEY_LEFTMETA: + return HID_KBD_MODIFIER_LEFT_UI; + case INPUT_KEY_RIGHTCTRL: + return HID_KBD_MODIFIER_RIGHT_CTRL; + case INPUT_KEY_RIGHTSHIFT: + return HID_KBD_MODIFIER_RIGHT_SHIFT; + case INPUT_KEY_RIGHTALT: + return HID_KBD_MODIFIER_RIGHT_ALT; + case INPUT_KEY_RIGHTMETA: + return HID_KBD_MODIFIER_RIGHT_UI; + default: + return HID_KBD_MODIFIER_NONE; + } +}