/* * NOTE: If drive_inactive_cols is false, then the GPIO has to be put into * HiZ when de-activated to cause minmal side effect when scanning other * columns. In that case it is configured here to be input, otherwise it is * driven with the inactive value.
*/ staticvoid __activate_col(struct matrix_keypad *keypad, int col, bool on)
{ if (on) {
gpiod_direction_output(keypad->col_gpios[col], 1);
} else {
gpiod_set_value_cansleep(keypad->col_gpios[col], 0); if (!keypad->drive_inactive_cols)
gpiod_direction_input(keypad->col_gpios[col]);
}
}
/* read new row state and detect if value has changed */
new_row_state = read_row_state(keypad); if (init_row_state != new_row_state) {
guard(spinlock_irq)(&keypad->lock); if (unlikely(keypad->scan_pending || keypad->stopped)) return;
disable_row_irqs(keypad);
keypad->scan_pending = true;
schedule_delayed_work(&keypad->work,
msecs_to_jiffies(keypad->debounce_ms));
}
}
/* * See if another IRQ beaten us to it and scheduled the * scan already. In that case we should not try to * disable IRQs again.
*/ if (unlikely(keypad->scan_pending || keypad->stopped)) goto out;
/* * Schedule an immediate key scan to capture current key state; * columns will be activated and IRQs be enabled after the scan.
*/
schedule_delayed_work(&keypad->work, 0);
/* initialize strobe lines as outputs, activated */ for (i = 0; i < keypad->num_col_gpios; i++) {
keypad->col_gpios[i] = devm_gpiod_get_index(&pdev->dev, "col",
i, GPIOD_ASIS);
err = PTR_ERR_OR_ZERO(keypad->col_gpios[i]); if (err) {
dev_err(&pdev->dev, "failed to request GPIO for COL%d: %d\n",
i, err); return err;
}
for (i = 0; i < keypad->num_row_gpios; i++) {
keypad->row_gpios[i] = devm_gpiod_get_index(&pdev->dev, "row",
i, GPIOD_IN);
err = PTR_ERR_OR_ZERO(keypad->row_gpios[i]); if (err) {
dev_err(&pdev->dev, "failed to request GPIO for ROW%d: %d\n",
i, err); return err;
}
if (active_low ^ gpiod_is_active_low(keypad->row_gpios[i]))
gpiod_toggle_active_low(keypad->row_gpios[i]);
}
return 0;
}
staticint matrix_keypad_setup_interrupts(struct platform_device *pdev, struct matrix_keypad *keypad)
{ int err; int irq; int i;
for (i = 0; i < keypad->num_row_gpios; i++) {
irq = gpiod_to_irq(keypad->row_gpios[i]); if (irq < 0) {
err = irq;
dev_err(&pdev->dev, "Unable to convert GPIO line %i to irq: %d\n",
i, err); return err;
}
err = devm_request_any_context_irq(&pdev->dev, irq,
matrix_keypad_interrupt,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING, "matrix-keypad", keypad); if (err < 0) {
dev_err(&pdev->dev, "Unable to acquire interrupt for row %i: %d\n",
i, err); return err;
}
keypad->row_irqs[i] = irq;
}
/* initialized as disabled - enabled by input->open */
disable_row_irqs(keypad);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.