From 8622208a85c65dcac4ef3a8d3dcd1956c3f01b1c Mon Sep 17 00:00:00 2001 From: Jorge Guzman Date: Thu, 30 Jul 2026 15:33:33 -0300 Subject: [PATCH] drivers/input: report special keys from the keyboard matrix The matrix driver reported every key with KEYBOARD_PRESS and KEYBOARD_RELEASE, so a board whose matrix has arrows or function keys had no way to say so: the keycode ranges overlap the character range, and the event type is what tells them apart. A keymap entry is a uint32_t, so wrap the entry in KMATRIX_SPECIAL() to declare that it holds a value from enum kbd_keycode_e. Existing keymaps hold characters and are unaffected. While here, drop the cast that truncated the keycode to sixteen bits, and default the device to /dev/kbd0. Applications look for a keyboard under that name, and /dev/keypad0 kept the matrix out of reach of every one of them. Signed-off-by: Jorge Guzman --- drivers/input/kmatrix.c | 24 ++++++++++++++++++++---- include/nuttx/input/kmatrix.h | 21 ++++++++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/input/kmatrix.c b/drivers/input/kmatrix.c index d04e7650583..57cb33b0f7f 100644 --- a/drivers/input/kmatrix.c +++ b/drivers/input/kmatrix.c @@ -175,6 +175,7 @@ static void kmatrix_scan_worker(FAR void *arg) bool pressed; bool old_state; uint32_t keycode; + uint32_t type; int ret; ret = nxmutex_lock(&priv->lock); @@ -212,13 +213,28 @@ static void kmatrix_scan_worker(FAR void *arg) kmatrix_set_state(priv, row, col, pressed); kmatrix_reset_debounce(priv, row, col); - /* Generate keyboard event */ + /* Generate keyboard event. A keymap entry wrapped in + * KMATRIX_SPECIAL() is a keycode rather than a character, + * and has to be reported with a SPEC event type: the two + * ranges overlap, so the type is the only way the + * application can tell them apart. + */ keycode = priv->config->keymap[ row * priv->config->ncols + col]; - keyboard_event(&priv->lower, (uint16_t)keycode, - pressed ? KEYBOARD_PRESS : - KEYBOARD_RELEASE); + + if ((keycode & KMATRIX_SPECIAL_FLAG) != 0) + { + keycode &= ~KMATRIX_SPECIAL_FLAG; + type = pressed ? KEYBOARD_SPECPRESS : + KEYBOARD_SPECREL; + } + else + { + type = pressed ? KEYBOARD_PRESS : KEYBOARD_RELEASE; + } + + keyboard_event(&priv->lower, keycode, type); iinfo("Key [%d,%d]: %s (code %lu)\n", row, col, pressed ? "PRESS" : "RELEASE", diff --git a/include/nuttx/input/kmatrix.h b/include/nuttx/input/kmatrix.h index cec15acfddd..6efa81054ae 100644 --- a/include/nuttx/input/kmatrix.h +++ b/include/nuttx/input/kmatrix.h @@ -35,6 +35,21 @@ * Pre-processor Definitions ****************************************************************************/ +/* A keymap entry is normally the character that the key produces. Wrap it + * in KMATRIX_SPECIAL() instead to declare that the entry is a value from + * enum kbd_keycode_e, so that the key is reported as a special key rather + * than as the character that happens to share its value: + * + * static const uint32_t g_keymap[] = + * { + * '1', '2', '3', + * KMATRIX_SPECIAL(KEYCODE_UP), KMATRIX_SPECIAL(KEYCODE_DOWN), '0', + * }; + */ + +#define KMATRIX_SPECIAL_FLAG (UINT32_C(1) << 31) +#define KMATRIX_SPECIAL(k) ((k) | KMATRIX_SPECIAL_FLAG) + /**************************************************************************** * Public Types ****************************************************************************/ @@ -91,12 +106,12 @@ extern "C" * * Description: * Configure and register a keyboard matrix device. This will create the - * /dev/keypadN device node and enable keyboard scanning. + * /dev/kbdN device node and enable keyboard scanning. * * Input Parameters: * config - The keyboard matrix configuration. This structure is not * copied; it must persist for the lifetime of the driver. - * devpath - The device path for the /dev/keypadN device. + * devpath - The device path for the /dev/kbdN device. * * Returned Value: * Zero is returned on success. Otherwise, a negated errno value is @@ -125,7 +140,7 @@ struct ioexpander_dev_s; * ioe_dev - IO expander device (from mcp23x08_initialize or * pca9538_initialize) * config - The keyboard matrix configuration (with callbacks set) - * devpath - The device path for the /dev/keypadN device + * devpath - The device path for the /dev/kbdN device * * Returned Value: * Zero is returned on success. Otherwise, a negated errno value is