Lines Matching +full:inactive +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0-only
11 #include <linux/delay.h>
30 /* key debounce interval in milli-second */
52 * HiZ when de-activated to cause minmal side effect when scanning other
54 * driven with the inactive value.
59 gpiod_direction_output(keypad->col_gpios[col], 1);
61 gpiod_set_value_cansleep(keypad->col_gpios[col], 0);
62 if (!keypad->drive_inactive_cols)
63 gpiod_direction_input(keypad->col_gpios[col]);
71 if (on && keypad->col_scan_delay_us)
72 fsleep(keypad->col_scan_delay_us);
79 for (col = 0; col < keypad->num_col_gpios; col++)
82 if (on && keypad->all_cols_on_delay_us)
83 fsleep(keypad->all_cols_on_delay_us);
88 return gpiod_get_value_cansleep(keypad->row_gpios[row]);
95 for (i = 0; i < keypad->num_row_gpios; i++)
96 enable_irq(keypad->row_irqs[i]);
103 for (i = 0; i < keypad->num_row_gpios; i++)
104 disable_irq_nosync(keypad->row_irqs[i]);
112 for (row = 0; row < keypad->num_row_gpios; row++)
124 struct input_dev *input_dev = keypad->input_dev;
125 const unsigned short *keycodes = input_dev->keycode;
133 /* de-activate all columns for scanning */
138 for (row = 0; row < keypad->num_row_gpios; row++)
139 gpiod_direction_input(keypad->row_gpios[row]);
142 for (col = 0; col < keypad->num_col_gpios; col++) {
151 for (col = 0; col < keypad->num_col_gpios; col++) {
154 bits_changed = keypad->last_key_state[col] ^ new_state[col];
158 for (row = 0; row < keypad->num_row_gpios; row++) {
162 code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
171 memcpy(keypad->last_key_state, new_state, sizeof(new_state));
176 scoped_guard(spinlock_irq, &keypad->lock) {
177 keypad->scan_pending = false;
184 guard(spinlock_irq)(&keypad->lock);
185 if (unlikely(keypad->scan_pending || keypad->stopped))
188 keypad->scan_pending = true;
189 schedule_delayed_work(&keypad->work,
190 msecs_to_jiffies(keypad->debounce_ms));
198 guard(spinlock_irqsave)(&keypad->lock);
205 if (unlikely(keypad->scan_pending || keypad->stopped))
209 keypad->scan_pending = true;
210 schedule_delayed_work(&keypad->work,
211 msecs_to_jiffies(keypad->debounce_ms));
221 keypad->stopped = false;
228 schedule_delayed_work(&keypad->work, 0);
237 scoped_guard(spinlock_irq, &keypad->lock) {
238 keypad->stopped = true;
241 flush_delayed_work(&keypad->work);
253 for_each_clear_bit(i, keypad->wakeup_enabled_irqs,
254 keypad->num_row_gpios)
255 if (enable_irq_wake(keypad->row_irqs[i]) == 0)
256 __set_bit(i, keypad->wakeup_enabled_irqs);
263 for_each_set_bit(i, keypad->wakeup_enabled_irqs,
264 keypad->num_row_gpios) {
265 disable_irq_wake(keypad->row_irqs[i]);
266 __clear_bit(i, keypad->wakeup_enabled_irqs);
275 matrix_keypad_stop(keypad->input_dev);
277 if (device_may_wakeup(&pdev->dev))
288 if (device_may_wakeup(&pdev->dev))
291 matrix_keypad_start(keypad->input_dev);
307 nrow = gpiod_count(&pdev->dev, "row");
308 ncol = gpiod_count(&pdev->dev, "col");
310 dev_err(&pdev->dev, "missing row or column GPIOs\n");
311 return -EINVAL;
314 keypad->num_row_gpios = nrow;
315 keypad->num_col_gpios = ncol;
317 active_low = device_property_read_bool(&pdev->dev, "gpio-activelow");
320 for (i = 0; i < keypad->num_col_gpios; i++) {
321 keypad->col_gpios[i] = devm_gpiod_get_index(&pdev->dev, "col",
323 err = PTR_ERR_OR_ZERO(keypad->col_gpios[i]);
325 dev_err(&pdev->dev,
331 gpiod_set_consumer_name(keypad->col_gpios[i], "matrix_kbd_col");
333 if (active_low ^ gpiod_is_active_low(keypad->col_gpios[i]))
334 gpiod_toggle_active_low(keypad->col_gpios[i]);
336 gpiod_direction_output(keypad->col_gpios[i], 1);
339 for (i = 0; i < keypad->num_row_gpios; i++) {
340 keypad->row_gpios[i] = devm_gpiod_get_index(&pdev->dev, "row",
342 err = PTR_ERR_OR_ZERO(keypad->row_gpios[i]);
344 dev_err(&pdev->dev,
350 gpiod_set_consumer_name(keypad->row_gpios[i], "matrix_kbd_row");
352 if (active_low ^ gpiod_is_active_low(keypad->row_gpios[i]))
353 gpiod_toggle_active_low(keypad->row_gpios[i]);
366 for (i = 0; i < keypad->num_row_gpios; i++) {
367 irq = gpiod_to_irq(keypad->row_gpios[i]);
370 dev_err(&pdev->dev,
376 err = devm_request_any_context_irq(&pdev->dev, irq,
380 "matrix-keypad", keypad);
382 dev_err(&pdev->dev,
388 keypad->row_irqs[i] = irq;
391 /* initialized as disabled - enabled by input->open */
404 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
406 return -ENOMEM;
408 input_dev = devm_input_allocate_device(&pdev->dev);
410 return -ENOMEM;
412 keypad->input_dev = input_dev;
413 keypad->stopped = true;
414 INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
415 spin_lock_init(&keypad->lock);
417 keypad->drive_inactive_cols =
418 device_property_read_bool(&pdev->dev, "drive-inactive-cols");
419 device_property_read_u32(&pdev->dev, "debounce-delay-ms",
420 &keypad->debounce_ms);
421 device_property_read_u32(&pdev->dev, "col-scan-delay-us",
422 &keypad->col_scan_delay_us);
423 device_property_read_u32(&pdev->dev, "all-cols-on-delay-us",
424 &keypad->all_cols_on_delay_us);
430 keypad->row_shift = get_count_order(keypad->num_col_gpios);
436 input_dev->name = pdev->name;
437 input_dev->id.bustype = BUS_HOST;
438 input_dev->open = matrix_keypad_start;
439 input_dev->close = matrix_keypad_stop;
442 keypad->num_row_gpios,
443 keypad->num_col_gpios,
446 dev_err(&pdev->dev, "failed to build keymap\n");
447 return -ENOMEM;
450 if (!device_property_read_bool(&pdev->dev, "linux,no-autorepeat"))
451 __set_bit(EV_REP, input_dev->evbit);
456 err = input_register_device(keypad->input_dev);
460 wakeup = device_property_read_bool(&pdev->dev, "wakeup-source") ||
462 device_property_read_bool(&pdev->dev, "linux,wakeup");
463 device_init_wakeup(&pdev->dev, wakeup);
472 { .compatible = "gpio-matrix-keypad" },
481 .name = "matrix-keypad",
491 MODULE_ALIAS("platform:matrix-keypad");