input: kbd_matrix: add a input_kbd_matrix_drive_column_hook option

Add an option to call an application specific hook when setting the
column to scan. This makes it possible to handle application specific
quirks.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit is contained in:
Fabio Baltieri 2023-11-21 14:48:48 +00:00 committed by Fabio Baltieri
parent 9e4b57398f
commit 76791cd708
3 changed files with 37 additions and 3 deletions

View file

@ -20,4 +20,11 @@ config INPUT_KBD_MATRIX_16_BIT_ROW
Use a 16 bit type for the internal structure, allow using a matrix
with up to 16 rows if the driver supports it.
config INPUT_KBD_DRIVE_COLUMN_HOOK
bool
help
Call an application specific hook after the driver specific
drive_column implementation. The application must implement the
input_kbd_matrix_drive_column_hook function.
endif # INPUT_KBD_MATRIX

View file

@ -68,6 +68,18 @@ static bool input_kbd_matrix_ghosting(const struct device *dev)
return false;
}
static void input_kbd_matrix_drive_column(const struct device *dev, int col)
{
const struct input_kbd_matrix_common_config *cfg = dev->config;
const struct input_kbd_matrix_api *api = cfg->api;
api->drive_column(dev, col);
#ifdef CONFIG_INPUT_KBD_DRIVE_COLUMN_HOOK
input_kbd_matrix_drive_column_hook(dev, col);
#endif
}
static bool input_kbd_matrix_scan(const struct device *dev)
{
const struct input_kbd_matrix_common_config *cfg = dev->config;
@ -76,7 +88,7 @@ static bool input_kbd_matrix_scan(const struct device *dev)
kbd_row_t key_event = 0U;
for (int col = 0; col < cfg->col_size; col++) {
api->drive_column(dev, col);
input_kbd_matrix_drive_column(dev, col);
/* Allow the matrix to stabilize before reading it */
k_busy_wait(cfg->settle_time_us);
@ -86,7 +98,7 @@ static bool input_kbd_matrix_scan(const struct device *dev)
key_event |= row;
}
api->drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE);
input_kbd_matrix_drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE);
return key_event != 0U;
}
@ -260,7 +272,7 @@ static void input_kbd_matrix_polling_thread(void *arg1, void *unused2, void *unu
ARG_UNUSED(unused3);
while (true) {
api->drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL);
input_kbd_matrix_drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL);
api->set_detect_mode(dev, true);
k_sem_take(&data->poll_lock, K_FOREVER);

View file

@ -238,6 +238,21 @@ struct input_kbd_matrix_common_data {
*/
void input_kbd_matrix_poll_start(const struct device *dev);
#ifdef CONFIG_INPUT_KBD_DRIVE_COLUMN_HOOK
/**
* @brief Drive column hook
*
* This can be implemented by the application to handle column selection
* quirks. Called after the driver specific drive_column function.
*
* @param dev Keyboard matrix device instance.
* @param col The column to drive, or
* @ref INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE or
* @ref INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL.
*/
void input_kbd_matrix_drive_column_hook(const struct device *dev, int col);
#endif
/**
* @brief Common function to initialize a keyboard matrix device at init time.
*