input: kbd_matrix: implement stable poll period support
Implement a new stable-poll-period-ms property to specify a new (slower) polling rate for when the matrix is stable. The keyboard thread can eat up a surprisingly high amount of cpu cycles in busy waiting if the specific hardware implementation happen to have a particularly slow settle time, but high frequency polling is really only needed when debouncing. The new property allow slowing down the polling rate when the matrix is stable (either key pressed but none to be debounced or idle in the case of the gpio implementation with no interrupts), this allows reducing the overall cpu time taken by the keyboard scanning thread when keys are persistently pressed. Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit is contained in:
parent
410c8a57e0
commit
13a2f42d50
4 changed files with 33 additions and 5 deletions
|
|
@ -121,7 +121,7 @@ static __maybe_unused void gpio_kbd_matrix_idle_poll_handler(const struct device
|
|||
|
||||
if (gpio_kbd_matrix_read_row(dev) == 0) {
|
||||
k_work_reschedule(cfg->idle_poll_dwork,
|
||||
K_USEC(common->poll_period_us));
|
||||
K_USEC(common->stable_poll_period_us));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ static void gpio_kbd_matrix_set_detect_mode(const struct device *dev, bool enabl
|
|||
if (cfg->idle_poll_dwork != NULL) {
|
||||
if (enabled) {
|
||||
k_work_reschedule(cfg->idle_poll_dwork,
|
||||
K_USEC(common->poll_period_us));
|
||||
K_USEC(common->stable_poll_period_us));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,6 +264,19 @@ static k_timepoint_t input_kbd_matrix_poll_timeout(const struct device *dev)
|
|||
return sys_timepoint_calc(K_MSEC(cfg->poll_timeout_ms));
|
||||
}
|
||||
|
||||
static bool input_kbd_matrix_is_unstable(const struct device *dev)
|
||||
{
|
||||
const struct input_kbd_matrix_common_config *cfg = dev->config;
|
||||
|
||||
for (uint8_t c = 0; c < cfg->col_size; c++) {
|
||||
if (cfg->matrix_unstable_state[c] != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void input_kbd_matrix_poll(const struct device *dev)
|
||||
{
|
||||
const struct input_kbd_matrix_common_config *cfg = dev->config;
|
||||
|
|
@ -271,6 +284,7 @@ static void input_kbd_matrix_poll(const struct device *dev)
|
|||
uint32_t current_cycles;
|
||||
uint32_t cycles_diff;
|
||||
uint32_t wait_period_us;
|
||||
uint32_t poll_period_us;
|
||||
|
||||
poll_time_end = input_kbd_matrix_poll_timeout(dev);
|
||||
|
||||
|
|
@ -289,10 +303,14 @@ static void input_kbd_matrix_poll(const struct device *dev)
|
|||
*/
|
||||
current_cycles = k_cycle_get_32();
|
||||
cycles_diff = current_cycles - start_period_cycles;
|
||||
wait_period_us = cfg->poll_period_us - k_cyc_to_us_floor32(cycles_diff);
|
||||
|
||||
wait_period_us = CLAMP(wait_period_us,
|
||||
USEC_PER_MSEC, cfg->poll_period_us);
|
||||
if (input_kbd_matrix_is_unstable(dev)) {
|
||||
poll_period_us = cfg->poll_period_us;
|
||||
} else {
|
||||
poll_period_us = cfg->stable_poll_period_us;
|
||||
}
|
||||
wait_period_us = CLAMP(poll_period_us - k_cyc_to_us_floor32(cycles_diff),
|
||||
USEC_PER_MSEC, poll_period_us);
|
||||
|
||||
LOG_DBG("wait_period_us: %d", wait_period_us);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ properties:
|
|||
Defines the poll period in msecs between between matrix scans, set to 0
|
||||
to never exit poll mode. Defaults to 5ms if unspecified.
|
||||
|
||||
stable-poll-period-ms:
|
||||
type: int
|
||||
description: |
|
||||
Defines the poll period in msecs between matrix scans when the matrix is
|
||||
stable, defaults to poll-period-ms value if unspecified.
|
||||
|
||||
poll-timeout-ms:
|
||||
type: int
|
||||
default: 100
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ struct input_kbd_matrix_common_config {
|
|||
uint8_t row_size;
|
||||
uint8_t col_size;
|
||||
uint32_t poll_period_us;
|
||||
uint32_t stable_poll_period_us;
|
||||
uint32_t poll_timeout_ms;
|
||||
uint32_t debounce_down_us;
|
||||
uint32_t debounce_up_us;
|
||||
|
|
@ -192,6 +193,9 @@ struct input_kbd_matrix_common_config {
|
|||
.row_size = _row_size, \
|
||||
.col_size = _col_size, \
|
||||
.poll_period_us = DT_PROP(node_id, poll_period_ms) * USEC_PER_MSEC, \
|
||||
.stable_poll_period_us = DT_PROP_OR(node_id, stable_poll_period_ms, \
|
||||
DT_PROP(node_id, poll_period_ms)) * \
|
||||
USEC_PER_MSEC, \
|
||||
.poll_timeout_ms = DT_PROP(node_id, poll_timeout_ms), \
|
||||
.debounce_down_us = DT_PROP(node_id, debounce_down_ms) * USEC_PER_MSEC, \
|
||||
.debounce_up_us = DT_PROP(node_id, debounce_up_ms) * USEC_PER_MSEC, \
|
||||
|
|
|
|||
Loading…
Reference in a new issue