|
|
@ -125,6 +125,7 @@ static int kscan_gpio_config_interrupts(struct device **devices, |
|
|
|
} \
|
|
|
|
} \
|
|
|
|
static int kscan_gpio_read_##n(struct device *dev) \
|
|
|
|
static int kscan_gpio_read_##n(struct device *dev) \
|
|
|
|
{ \
|
|
|
|
{ \
|
|
|
|
|
|
|
|
bool submit_follow_up_read = false; \
|
|
|
|
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
|
|
|
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
|
|
|
static bool read_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
|
|
|
static bool read_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
|
|
|
LOG_DBG("Scanning the matrix for updated state"); \
|
|
|
|
LOG_DBG("Scanning the matrix for updated state"); \
|
|
|
@ -155,6 +156,8 @@ static int kscan_gpio_config_interrupts(struct device **devices, |
|
|
|
for (int c = 0; c < INST_MATRIX_COLS(n); c++) \
|
|
|
|
for (int c = 0; c < INST_MATRIX_COLS(n); c++) \
|
|
|
|
{ \
|
|
|
|
{ \
|
|
|
|
bool pressed = read_state[r][c]; \
|
|
|
|
bool pressed = read_state[r][c]; \
|
|
|
|
|
|
|
|
/* Follow up reads needed because further interrupts won't fire on already tripped input GPIO pins */ \
|
|
|
|
|
|
|
|
submit_follow_up_read = (submit_follow_up_read || pressed); \
|
|
|
|
if (pressed != data->matrix_state[r][c]) \
|
|
|
|
if (pressed != data->matrix_state[r][c]) \
|
|
|
|
{ \
|
|
|
|
{ \
|
|
|
|
LOG_DBG("Sending event at %d,%d state %s", \
|
|
|
|
LOG_DBG("Sending event at %d,%d state %s", \
|
|
|
@ -164,6 +167,13 @@ static int kscan_gpio_config_interrupts(struct device **devices, |
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
|
|
|
|
if (submit_follow_up_read) { \
|
|
|
|
|
|
|
|
COND_CODE_0(DT_INST_PROP(n, debounce_period), \
|
|
|
|
|
|
|
|
({ k_work_submit(&data->work); }), \
|
|
|
|
|
|
|
|
({ \
|
|
|
|
|
|
|
|
k_delayed_work_cancel(&data->work); \
|
|
|
|
|
|
|
|
k_delayed_work_submit(&data->work, K_MSEC(1)); })) \
|
|
|
|
|
|
|
|
} \
|
|
|
|
return 0; \
|
|
|
|
return 0; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
static void kscan_gpio_work_handler_##n(struct k_work *work) \
|
|
|
|
static void kscan_gpio_work_handler_##n(struct k_work *work) \
|
|
|
@ -179,9 +189,9 @@ static int kscan_gpio_config_interrupts(struct device **devices, |
|
|
|
CONTAINER_OF(cb, struct kscan_gpio_irq_callback_##n, callback); \
|
|
|
|
CONTAINER_OF(cb, struct kscan_gpio_irq_callback_##n, callback); \
|
|
|
|
COND_CODE_0(DT_INST_PROP(n, debounce_period), \
|
|
|
|
COND_CODE_0(DT_INST_PROP(n, debounce_period), \
|
|
|
|
({ k_work_submit(data->work); }), \
|
|
|
|
({ k_work_submit(data->work); }), \
|
|
|
|
({ \
|
|
|
|
({ \
|
|
|
|
k_delayed_work_cancel(data->work); \
|
|
|
|
k_delayed_work_cancel(data->work); \
|
|
|
|
k_delayed_work_submit(data->work, K_MSEC(DT_INST_PROP(n, debounce_period))); })) \
|
|
|
|
k_delayed_work_submit(data->work, K_MSEC(DT_INST_PROP(n, debounce_period))); })) \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
static struct kscan_gpio_data_##n kscan_gpio_data_##n = { \
|
|
|
|
static struct kscan_gpio_data_##n kscan_gpio_data_##n = { \
|
|
|
|
.rows = { [INST_MATRIX_ROWS(n)-1] = NULL}, \
|
|
|
|
.rows = { [INST_MATRIX_ROWS(n)-1] = NULL}, \
|
|
|
|