On Tue, Nov 05, 2024 at 02:03:22PM +0100, Markus Burri wrote: > For a setup where the matrix keypad is connected over a slow interface > (e.g. a gpio-expansion over i2c), the scan can take a longer time to read. > > Interrupts need to be disabled during scan. And therefore changes in this > period are not detected. > To improve this situation, scan the matrix again if the row state changed > during interrupts disabled. And what if the state changes yet again during the 2nd scan attempt? > > Signed-off-by: Markus Burri <markus.burri@xxxxxx> > --- > drivers/input/keyboard/matrix_keypad.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c > index 46873b8..93c8404 100644 > --- a/drivers/input/keyboard/matrix_keypad.c > +++ b/drivers/input/keyboard/matrix_keypad.c > @@ -126,6 +126,10 @@ static void matrix_keypad_scan(struct work_struct *work) > const unsigned short *keycodes = input_dev->keycode; > uint32_t new_state[MATRIX_MAX_COLS]; > int row, col, code; > + u32 init_row_state, new_row_state; > + > + /* read initial row state to detect changes between scan */ > + init_row_state = read_row_state(keypad); > > /* de-activate all columns for scanning */ > activate_all_cols(keypad, false); > @@ -174,6 +178,19 @@ static void matrix_keypad_scan(struct work_struct *work) > keypad->scan_pending = false; > enable_row_irqs(keypad); > spin_unlock_irq(&keypad->lock); > + > + /* read new row state and detect if value has changed */ > + new_row_state = read_row_state(keypad); > + if (init_row_state != new_row_state) { > + spin_lock_irq(&keypad->lock); > + if (likely(!keypad->scan_pending && !keypad->stopped)) { > + disable_row_irqs(keypad); > + keypad->scan_pending = true; > + schedule_delayed_work(&keypad->work, > + msecs_to_jiffies(keypad->debounce_ms)); > + } > + spin_unlock_irq(&keypad->lock); > + } > } > > static irqreturn_t matrix_keypad_interrupt(int irq, void *id) > -- > 2.39.5 > -- Dmitry