Skip to content

Commit 4307882

Browse files
committed
input: kbd_matrix: add actual key mask runtime control
Add an option to enable a input_kbd_matrix_actual_key_mask_set API to enable or disable keys dynamically in the mask. This can be useful if the exact key mask is determined in runtime and the device is using a single firmware for multiple matrix configurations. Signed-off-by: Fabio Baltieri <[email protected]>
1 parent 250d50e commit 4307882

File tree

5 files changed

+95
-3
lines changed

5 files changed

+95
-3
lines changed

drivers/input/Kconfig.kbd_matrix

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ config INPUT_KBD_MATRIX_16_BIT_ROW
2727
Use a 16 bit type for the internal structure, allow using a matrix
2828
with up to 16 rows if the driver supports it.
2929

30+
config INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC
31+
bool "Allow runtime changes to the actual key mask"
32+
help
33+
If enabled, the actual key mask data is stored in RAM, and a
34+
input_kbd_matrix_actual_key_mask_set() function is available to
35+
change the content at runtime.
36+
3037
config INPUT_SHELL_KBD_MATRIX_STATE
3138
bool "Input kbd_matrix_state shell command"
3239
depends on INPUT_SHELL

drivers/input/input_kbd_matrix.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,19 @@ int input_kbd_matrix_common_init(const struct device *dev)
323323

324324
return 0;
325325
}
326+
327+
#if CONFIG_INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC
328+
int input_kbd_matrix_actual_key_mask_set(const struct device *dev,
329+
uint8_t row, uint8_t col, bool enabled)
330+
{
331+
const struct input_kbd_matrix_common_config *cfg = dev->config;
332+
333+
if (row >= cfg->row_size || col >= cfg->col_size) {
334+
return -EINVAL;
335+
}
336+
337+
WRITE_BIT(cfg->actual_key_mask[col], row, enabled);
338+
339+
return 0;
340+
}
341+
#endif

include/zephyr/input/input_kbd_matrix.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,31 @@ typedef uint8_t kbd_row_t;
3838
#define PRIkbdrow "%02x"
3939
#endif
4040

41+
#if CONFIG_INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC
42+
#define INPUT_KBD_ACTUAL_KEY_MASK_CONST
43+
/**
44+
* @brief Enables or disables a specific row, column combination in the actual
45+
* key mask.
46+
*
47+
* This allows enabling or disabling spcific row, column combination in the
48+
* actual key mask in runtime. It can be useful if some of the keys are not
49+
* present in some configuration, and the specific configuration is determined
50+
* in runtime. Requires CONFIG_INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC=y.
51+
*
52+
* @param dev Pointer to the keyboard matrix device.
53+
* @param row The matrix row to enable or disable.
54+
* @param col The matrix column to enable or disable.
55+
* @param enabled Whether the specificied row, col has to be enabled or disabled.
56+
*
57+
* @retval 0 If the change is successful.
58+
* @retval -errno Negative errno if row or col are out of range for the device.
59+
*/
60+
int input_kbd_matrix_actual_key_mask_set(const struct device *dev,
61+
uint8_t row, uint8_t col, bool enabled);
62+
#else
63+
#define INPUT_KBD_ACTUAL_KEY_MASK_CONST const
64+
#endif
65+
4166
/** Maximum number of rows */
4267
#define INPUT_KBD_MATRIX_ROW_BITS NUM_BITS(kbd_row_t)
4368

@@ -90,7 +115,7 @@ struct input_kbd_matrix_common_config {
90115
uint32_t debounce_up_us;
91116
uint32_t settle_time_us;
92117
bool ghostkey_check;
93-
const kbd_row_t *actual_key_mask;
118+
INPUT_KBD_ACTUAL_KEY_MASK_CONST kbd_row_t *actual_key_mask;
94119

95120
/* extra data pointers */
96121
kbd_row_t *matrix_stable_state;
@@ -114,8 +139,9 @@ struct input_kbd_matrix_common_config {
114139
IF_ENABLED(DT_NODE_HAS_PROP(node_id, actual_key_mask), ( \
115140
BUILD_ASSERT(DT_PROP_LEN(node_id, actual_key_mask) == _col_size, \
116141
"actual-key-mask size does not match the number of columns"); \
117-
static const kbd_row_t INPUT_KBD_MATRIX_DATA_NAME(node_id, actual_key_mask)[_col_size] = \
118-
DT_PROP(node_id, actual_key_mask); \
142+
static INPUT_KBD_ACTUAL_KEY_MASK_CONST kbd_row_t \
143+
INPUT_KBD_MATRIX_DATA_NAME(node_id, actual_key_mask)[_col_size] = \
144+
DT_PROP(node_id, actual_key_mask); \
119145
)) \
120146
static kbd_row_t INPUT_KBD_MATRIX_DATA_NAME(node_id, stable_state)[_col_size]; \
121147
static kbd_row_t INPUT_KBD_MATRIX_DATA_NAME(node_id, unstable_state)[_col_size]; \

tests/drivers/input/kbd_matrix/src/main.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,45 @@ ZTEST(kbd_scan, test_kbd_actual_keymap)
374374
kbd_scan_wait_for_idle();
375375
assert_no_new_events();
376376
}
377+
378+
ZTEST(kbd_scan, test_kbd_actual_key_map_set)
379+
{
380+
#if CONFIG_INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC
381+
kbd_row_t mask[4] = {0x00, 0xff, 0x00, 0x00};
382+
const struct input_kbd_matrix_common_config cfg = {
383+
.row_size = 3,
384+
.col_size = 4,
385+
.actual_key_mask = mask,
386+
};
387+
const struct device fake_dev = {
388+
.config = &cfg,
389+
};
390+
int ret;
391+
392+
ret = input_kbd_matrix_actual_key_mask_set(&fake_dev, 0, 0, true);
393+
zassert_equal(ret, 0);
394+
zassert_equal(mask[0], 0x01);
395+
396+
ret = input_kbd_matrix_actual_key_mask_set(&fake_dev, 2, 1, false);
397+
zassert_equal(ret, 0);
398+
zassert_equal(mask[1], 0xfb);
399+
400+
ret = input_kbd_matrix_actual_key_mask_set(&fake_dev, 2, 3, true);
401+
zassert_equal(ret, 0);
402+
zassert_equal(mask[3], 0x04);
403+
404+
ret = input_kbd_matrix_actual_key_mask_set(&fake_dev, 3, 0, true);
405+
zassert_equal(ret, -EINVAL);
406+
407+
ret = input_kbd_matrix_actual_key_mask_set(&fake_dev, 0, 4, true);
408+
zassert_equal(ret, -EINVAL);
409+
410+
zassert_equal(memcmp(mask, (uint8_t[]){0x01, 0xfb, 0x00, 0x04}, 4), 0);
411+
#else
412+
ztest_test_skip();
413+
#endif
414+
}
415+
377416
static void *kbd_scan_setup(void)
378417
{
379418
const struct input_kbd_matrix_common_config *cfg = test_dev->config;

tests/drivers/input/kbd_matrix/testcase.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ tests:
1717
input.input_kbd_matrix.actual_key_mask:
1818
extra_args:
1919
- EXTRA_DTC_OVERLAY_FILE=actual-key-mask.overlay
20+
input.input_kbd_matrix.actual_key_mask_dynamic:
21+
extra_args:
22+
- EXTRA_DTC_OVERLAY_FILE=actual-key-mask.overlay
23+
- CONFIG_INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC=y
2024
input.input_kbd_matrix.row_16_bit:
2125
extra_args:
2226
- CONFIG_INPUT_KBD_MATRIX_16_BIT_ROW=y

0 commit comments

Comments
 (0)