| ======================= |
| Matrix Keypad (KMATRIX) |
| ======================= |
| |
| **What is a Keypad?** |
| A keypad is a small keyboard with a limited set of keys, typically |
| arranged in a matrix. It is commonly used for numeric input, access |
| control, or simple user interfaces. |
| |
| For example, a typical 12-key numeric keypad looks like this: |
| |
| .. image:: images/keypad-example.png |
| :alt: Example of a 12-key matrix keypad |
| :align: center |
| :width: 200px |
| |
| **Purpose**. The KMATRIX driver provides a generic keypad |
| implementation for boards that expose a switch matrix through GPIOs. |
| It periodically scans rows and columns, detects state changes with a |
| simple debounce, and emits keyboard events through the common keyboard |
| upper-half. This makes the device available as a character driver |
| (e.g., ``/dev/keypad0``) using the standard keyboard |
| interfaces. |
| |
| **Why Polling**. This first version uses polling to be broadly usable |
| on any board with available GPIOs, without requiring per-board IRQ |
| wiring, pin interrupt capabilities, or expander-specific interrupt |
| support. Polling also simplifies early bring-up and makes the driver |
| predictable while the keymap and GPIO configuration are validated. |
| Future iterations are expected to add interrupt-driven scanning and |
| I2C expander variants; the GPIO polling path remains a good baseline |
| and fallback. |
| |
| **Driver Overview**. The KMATRIX lower-half scans the matrix and calls |
| ``keyboard_event()`` when it detects a press or release. The keyboard |
| upper-half registers the character device at the requested ``devpath`` |
| and stores events in a circular buffer. Applications read |
| ``struct keyboard_event_s`` from the device or use the optional |
| kbd-codec layer. |
| |
| **Board Support**. To support KMATRIX, a board must provide: |
| |
| #. **GPIO Definitions** |
| |
| - Define the row and column GPIOs (arrays of pins). |
| - Provide a keymap array indexed by ``row * ncols + col``. |
| |
| #. **Configuration Callbacks** |
| |
| - ``config_row(pin)``: Configure a row GPIO as output. |
| - ``config_col(pin)``: Configure a column GPIO as input with pull-up |
| or pull-down consistent with the wiring. |
| - ``row_set(pin, active)``: Drive a row active/inactive. For the |
| STM32F4Discovery example, rows are driven low to activate. |
| - ``col_get(pin)``: Read a column and return ``true`` when pressed. |
| |
| #. **Registration Hook** |
| |
| - Implement ``board_kmatrix_initialize(const char *devpath)`` to |
| call ``kmatrix_register(&config, devpath)``. |
| - Invoke the board hook during bring-up (for example, |
| ``board_kmatrix_initialize("/dev/keypad0")``). |
| |
| **Reference Implementation (STM32F4Discovery)**. The current reference |
| is in ``boards/arm/common/stm32/src/stm32_kmatrix_gpio.c``: |
| |
| - Rows: ``BOARD_KMATRIX_ROW0..3`` (outputs) |
| - Columns: ``BOARD_KMATRIX_COL0..2`` (inputs with pull-up) |
| - Keymap: 4x3 phone keypad layout |
| - Callbacks: ``km_stm32_config_row``, ``km_stm32_config_col``, |
| ``km_stm32_row_set``, ``km_stm32_col_get`` |
| - Registration: ``board_kmatrix_initialize()`` calls |
| ``kmatrix_register()`` |
| |
| **Data Path Summary**. |
| |
| - Board calls ``board_kmatrix_initialize("/dev/keypad0")`` |
| - ``kmatrix_register()`` configures GPIOs and calls |
| ``keyboard_register(&lower, devpath, buflen)`` |
| - The upper-half registers the device node at ``devpath`` |
| - ``kmatrix_scan_worker()`` calls ``keyboard_event()`` on press/release |
| - Applications read events from the device node |
| |