This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 59101fa206a5936c77ca5117327d04c9e9638f33
Author: Jorge Guzman <[email protected]>
AuthorDate: Thu Jul 30 15:33:33 2026 -0300

    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 <[email protected]>
---
 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

Reply via email to