1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * GPIO driven matrix keyboard driver |
4 | * |
5 | * Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com> |
6 | * |
7 | * Based on corgikbd.c |
8 | */ |
9 | |
10 | #include <linux/types.h> |
11 | #include <linux/delay.h> |
12 | #include <linux/gpio/consumer.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/input.h> |
15 | #include <linux/irq.h> |
16 | #include <linux/interrupt.h> |
17 | #include <linux/jiffies.h> |
18 | #include <linux/module.h> |
19 | #include <linux/gpio.h> |
20 | #include <linux/input/matrix_keypad.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/of.h> |
23 | #include <linux/of_gpio.h> |
24 | #include <linux/of_platform.h> |
25 | |
26 | struct matrix_keypad { |
27 | const struct matrix_keypad_platform_data *pdata; |
28 | struct input_dev *input_dev; |
29 | unsigned int row_shift; |
30 | |
31 | DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); |
32 | |
33 | uint32_t last_key_state[MATRIX_MAX_COLS]; |
34 | struct delayed_work work; |
35 | spinlock_t lock; |
36 | bool scan_pending; |
37 | bool stopped; |
38 | bool gpio_all_disabled; |
39 | }; |
40 | |
41 | /* |
42 | * NOTE: If drive_inactive_cols is false, then the GPIO has to be put into |
43 | * HiZ when de-activated to cause minmal side effect when scanning other |
44 | * columns. In that case it is configured here to be input, otherwise it is |
45 | * driven with the inactive value. |
46 | */ |
47 | static void __activate_col(const struct matrix_keypad_platform_data *pdata, |
48 | int col, bool on) |
49 | { |
50 | bool level_on = !pdata->active_low; |
51 | |
52 | if (on) { |
53 | gpio_direction_output(gpio: pdata->col_gpios[col], value: level_on); |
54 | } else { |
55 | gpio_set_value_cansleep(gpio: pdata->col_gpios[col], value: !level_on); |
56 | if (!pdata->drive_inactive_cols) |
57 | gpio_direction_input(gpio: pdata->col_gpios[col]); |
58 | } |
59 | } |
60 | |
61 | static void activate_col(const struct matrix_keypad_platform_data *pdata, |
62 | int col, bool on) |
63 | { |
64 | __activate_col(pdata, col, on); |
65 | |
66 | if (on && pdata->col_scan_delay_us) |
67 | udelay(pdata->col_scan_delay_us); |
68 | } |
69 | |
70 | static void activate_all_cols(const struct matrix_keypad_platform_data *pdata, |
71 | bool on) |
72 | { |
73 | int col; |
74 | |
75 | for (col = 0; col < pdata->num_col_gpios; col++) |
76 | __activate_col(pdata, col, on); |
77 | } |
78 | |
79 | static bool row_asserted(const struct matrix_keypad_platform_data *pdata, |
80 | int row) |
81 | { |
82 | return gpio_get_value_cansleep(gpio: pdata->row_gpios[row]) ? |
83 | !pdata->active_low : pdata->active_low; |
84 | } |
85 | |
86 | static void enable_row_irqs(struct matrix_keypad *keypad) |
87 | { |
88 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
89 | int i; |
90 | |
91 | if (pdata->clustered_irq > 0) |
92 | enable_irq(irq: pdata->clustered_irq); |
93 | else { |
94 | for (i = 0; i < pdata->num_row_gpios; i++) |
95 | enable_irq(irq: gpio_to_irq(gpio: pdata->row_gpios[i])); |
96 | } |
97 | } |
98 | |
99 | static void disable_row_irqs(struct matrix_keypad *keypad) |
100 | { |
101 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
102 | int i; |
103 | |
104 | if (pdata->clustered_irq > 0) |
105 | disable_irq_nosync(irq: pdata->clustered_irq); |
106 | else { |
107 | for (i = 0; i < pdata->num_row_gpios; i++) |
108 | disable_irq_nosync(irq: gpio_to_irq(gpio: pdata->row_gpios[i])); |
109 | } |
110 | } |
111 | |
112 | /* |
113 | * This gets the keys from keyboard and reports it to input subsystem |
114 | */ |
115 | static void matrix_keypad_scan(struct work_struct *work) |
116 | { |
117 | struct matrix_keypad *keypad = |
118 | container_of(work, struct matrix_keypad, work.work); |
119 | struct input_dev *input_dev = keypad->input_dev; |
120 | const unsigned short *keycodes = input_dev->keycode; |
121 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
122 | uint32_t new_state[MATRIX_MAX_COLS]; |
123 | int row, col, code; |
124 | |
125 | /* de-activate all columns for scanning */ |
126 | activate_all_cols(pdata, on: false); |
127 | |
128 | memset(new_state, 0, sizeof(new_state)); |
129 | |
130 | for (row = 0; row < pdata->num_row_gpios; row++) |
131 | gpio_direction_input(gpio: pdata->row_gpios[row]); |
132 | |
133 | /* assert each column and read the row status out */ |
134 | for (col = 0; col < pdata->num_col_gpios; col++) { |
135 | |
136 | activate_col(pdata, col, on: true); |
137 | |
138 | for (row = 0; row < pdata->num_row_gpios; row++) |
139 | new_state[col] |= |
140 | row_asserted(pdata, row) ? (1 << row) : 0; |
141 | |
142 | activate_col(pdata, col, on: false); |
143 | } |
144 | |
145 | for (col = 0; col < pdata->num_col_gpios; col++) { |
146 | uint32_t bits_changed; |
147 | |
148 | bits_changed = keypad->last_key_state[col] ^ new_state[col]; |
149 | if (bits_changed == 0) |
150 | continue; |
151 | |
152 | for (row = 0; row < pdata->num_row_gpios; row++) { |
153 | if ((bits_changed & (1 << row)) == 0) |
154 | continue; |
155 | |
156 | code = MATRIX_SCAN_CODE(row, col, keypad->row_shift); |
157 | input_event(dev: input_dev, EV_MSC, MSC_SCAN, value: code); |
158 | input_report_key(dev: input_dev, |
159 | code: keycodes[code], |
160 | value: new_state[col] & (1 << row)); |
161 | } |
162 | } |
163 | input_sync(dev: input_dev); |
164 | |
165 | memcpy(keypad->last_key_state, new_state, sizeof(new_state)); |
166 | |
167 | activate_all_cols(pdata, on: true); |
168 | |
169 | /* Enable IRQs again */ |
170 | spin_lock_irq(lock: &keypad->lock); |
171 | keypad->scan_pending = false; |
172 | enable_row_irqs(keypad); |
173 | spin_unlock_irq(lock: &keypad->lock); |
174 | } |
175 | |
176 | static irqreturn_t matrix_keypad_interrupt(int irq, void *id) |
177 | { |
178 | struct matrix_keypad *keypad = id; |
179 | unsigned long flags; |
180 | |
181 | spin_lock_irqsave(&keypad->lock, flags); |
182 | |
183 | /* |
184 | * See if another IRQ beaten us to it and scheduled the |
185 | * scan already. In that case we should not try to |
186 | * disable IRQs again. |
187 | */ |
188 | if (unlikely(keypad->scan_pending || keypad->stopped)) |
189 | goto out; |
190 | |
191 | disable_row_irqs(keypad); |
192 | keypad->scan_pending = true; |
193 | schedule_delayed_work(dwork: &keypad->work, |
194 | delay: msecs_to_jiffies(m: keypad->pdata->debounce_ms)); |
195 | |
196 | out: |
197 | spin_unlock_irqrestore(lock: &keypad->lock, flags); |
198 | return IRQ_HANDLED; |
199 | } |
200 | |
201 | static int matrix_keypad_start(struct input_dev *dev) |
202 | { |
203 | struct matrix_keypad *keypad = input_get_drvdata(dev); |
204 | |
205 | keypad->stopped = false; |
206 | mb(); |
207 | |
208 | /* |
209 | * Schedule an immediate key scan to capture current key state; |
210 | * columns will be activated and IRQs be enabled after the scan. |
211 | */ |
212 | schedule_delayed_work(dwork: &keypad->work, delay: 0); |
213 | |
214 | return 0; |
215 | } |
216 | |
217 | static void matrix_keypad_stop(struct input_dev *dev) |
218 | { |
219 | struct matrix_keypad *keypad = input_get_drvdata(dev); |
220 | |
221 | spin_lock_irq(lock: &keypad->lock); |
222 | keypad->stopped = true; |
223 | spin_unlock_irq(lock: &keypad->lock); |
224 | |
225 | flush_delayed_work(dwork: &keypad->work); |
226 | /* |
227 | * matrix_keypad_scan() will leave IRQs enabled; |
228 | * we should disable them now. |
229 | */ |
230 | disable_row_irqs(keypad); |
231 | } |
232 | |
233 | static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) |
234 | { |
235 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
236 | unsigned int gpio; |
237 | int i; |
238 | |
239 | if (pdata->clustered_irq > 0) { |
240 | if (enable_irq_wake(irq: pdata->clustered_irq) == 0) |
241 | keypad->gpio_all_disabled = true; |
242 | } else { |
243 | |
244 | for (i = 0; i < pdata->num_row_gpios; i++) { |
245 | if (!test_bit(i, keypad->disabled_gpios)) { |
246 | gpio = pdata->row_gpios[i]; |
247 | |
248 | if (enable_irq_wake(irq: gpio_to_irq(gpio)) == 0) |
249 | __set_bit(i, keypad->disabled_gpios); |
250 | } |
251 | } |
252 | } |
253 | } |
254 | |
255 | static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad) |
256 | { |
257 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
258 | unsigned int gpio; |
259 | int i; |
260 | |
261 | if (pdata->clustered_irq > 0) { |
262 | if (keypad->gpio_all_disabled) { |
263 | disable_irq_wake(irq: pdata->clustered_irq); |
264 | keypad->gpio_all_disabled = false; |
265 | } |
266 | } else { |
267 | for (i = 0; i < pdata->num_row_gpios; i++) { |
268 | if (test_and_clear_bit(nr: i, addr: keypad->disabled_gpios)) { |
269 | gpio = pdata->row_gpios[i]; |
270 | disable_irq_wake(irq: gpio_to_irq(gpio)); |
271 | } |
272 | } |
273 | } |
274 | } |
275 | |
276 | static int matrix_keypad_suspend(struct device *dev) |
277 | { |
278 | struct platform_device *pdev = to_platform_device(dev); |
279 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
280 | |
281 | matrix_keypad_stop(dev: keypad->input_dev); |
282 | |
283 | if (device_may_wakeup(dev: &pdev->dev)) |
284 | matrix_keypad_enable_wakeup(keypad); |
285 | |
286 | return 0; |
287 | } |
288 | |
289 | static int matrix_keypad_resume(struct device *dev) |
290 | { |
291 | struct platform_device *pdev = to_platform_device(dev); |
292 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
293 | |
294 | if (device_may_wakeup(dev: &pdev->dev)) |
295 | matrix_keypad_disable_wakeup(keypad); |
296 | |
297 | matrix_keypad_start(dev: keypad->input_dev); |
298 | |
299 | return 0; |
300 | } |
301 | |
302 | static DEFINE_SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, |
303 | matrix_keypad_suspend, matrix_keypad_resume); |
304 | |
305 | static int matrix_keypad_init_gpio(struct platform_device *pdev, |
306 | struct matrix_keypad *keypad) |
307 | { |
308 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
309 | int i, err; |
310 | |
311 | /* initialized strobe lines as outputs, activated */ |
312 | for (i = 0; i < pdata->num_col_gpios; i++) { |
313 | err = gpio_request(gpio: pdata->col_gpios[i], label: "matrix_kbd_col" ); |
314 | if (err) { |
315 | dev_err(&pdev->dev, |
316 | "failed to request GPIO%d for COL%d\n" , |
317 | pdata->col_gpios[i], i); |
318 | goto err_free_cols; |
319 | } |
320 | |
321 | gpio_direction_output(gpio: pdata->col_gpios[i], value: !pdata->active_low); |
322 | } |
323 | |
324 | for (i = 0; i < pdata->num_row_gpios; i++) { |
325 | err = gpio_request(gpio: pdata->row_gpios[i], label: "matrix_kbd_row" ); |
326 | if (err) { |
327 | dev_err(&pdev->dev, |
328 | "failed to request GPIO%d for ROW%d\n" , |
329 | pdata->row_gpios[i], i); |
330 | goto err_free_rows; |
331 | } |
332 | |
333 | gpio_direction_input(gpio: pdata->row_gpios[i]); |
334 | } |
335 | |
336 | if (pdata->clustered_irq > 0) { |
337 | err = request_any_context_irq(irq: pdata->clustered_irq, |
338 | handler: matrix_keypad_interrupt, |
339 | flags: pdata->clustered_irq_flags, |
340 | name: "matrix-keypad" , dev_id: keypad); |
341 | if (err < 0) { |
342 | dev_err(&pdev->dev, |
343 | "Unable to acquire clustered interrupt\n" ); |
344 | goto err_free_rows; |
345 | } |
346 | } else { |
347 | for (i = 0; i < pdata->num_row_gpios; i++) { |
348 | err = request_any_context_irq( |
349 | irq: gpio_to_irq(gpio: pdata->row_gpios[i]), |
350 | handler: matrix_keypad_interrupt, |
351 | IRQF_TRIGGER_RISING | |
352 | IRQF_TRIGGER_FALLING, |
353 | name: "matrix-keypad" , dev_id: keypad); |
354 | if (err < 0) { |
355 | dev_err(&pdev->dev, |
356 | "Unable to acquire interrupt for GPIO line %i\n" , |
357 | pdata->row_gpios[i]); |
358 | goto err_free_irqs; |
359 | } |
360 | } |
361 | } |
362 | |
363 | /* initialized as disabled - enabled by input->open */ |
364 | disable_row_irqs(keypad); |
365 | return 0; |
366 | |
367 | err_free_irqs: |
368 | while (--i >= 0) |
369 | free_irq(gpio_to_irq(gpio: pdata->row_gpios[i]), keypad); |
370 | i = pdata->num_row_gpios; |
371 | err_free_rows: |
372 | while (--i >= 0) |
373 | gpio_free(gpio: pdata->row_gpios[i]); |
374 | i = pdata->num_col_gpios; |
375 | err_free_cols: |
376 | while (--i >= 0) |
377 | gpio_free(gpio: pdata->col_gpios[i]); |
378 | |
379 | return err; |
380 | } |
381 | |
382 | static void matrix_keypad_free_gpio(struct matrix_keypad *keypad) |
383 | { |
384 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
385 | int i; |
386 | |
387 | if (pdata->clustered_irq > 0) { |
388 | free_irq(pdata->clustered_irq, keypad); |
389 | } else { |
390 | for (i = 0; i < pdata->num_row_gpios; i++) |
391 | free_irq(gpio_to_irq(gpio: pdata->row_gpios[i]), keypad); |
392 | } |
393 | |
394 | for (i = 0; i < pdata->num_row_gpios; i++) |
395 | gpio_free(gpio: pdata->row_gpios[i]); |
396 | |
397 | for (i = 0; i < pdata->num_col_gpios; i++) |
398 | gpio_free(gpio: pdata->col_gpios[i]); |
399 | } |
400 | |
401 | #ifdef CONFIG_OF |
402 | static struct matrix_keypad_platform_data * |
403 | matrix_keypad_parse_dt(struct device *dev) |
404 | { |
405 | struct matrix_keypad_platform_data *pdata; |
406 | struct device_node *np = dev->of_node; |
407 | unsigned int *gpios; |
408 | int ret, i, nrow, ncol; |
409 | |
410 | if (!np) { |
411 | dev_err(dev, "device lacks DT data\n" ); |
412 | return ERR_PTR(error: -ENODEV); |
413 | } |
414 | |
415 | pdata = devm_kzalloc(dev, size: sizeof(*pdata), GFP_KERNEL); |
416 | if (!pdata) { |
417 | dev_err(dev, "could not allocate memory for platform data\n" ); |
418 | return ERR_PTR(error: -ENOMEM); |
419 | } |
420 | |
421 | pdata->num_row_gpios = nrow = gpiod_count(dev, con_id: "row" ); |
422 | pdata->num_col_gpios = ncol = gpiod_count(dev, con_id: "col" ); |
423 | if (nrow < 0 || ncol < 0) { |
424 | dev_err(dev, "number of keypad rows/columns not specified\n" ); |
425 | return ERR_PTR(error: -EINVAL); |
426 | } |
427 | |
428 | pdata->no_autorepeat = of_property_read_bool(np, propname: "linux,no-autorepeat" ); |
429 | |
430 | pdata->wakeup = of_property_read_bool(np, propname: "wakeup-source" ) || |
431 | of_property_read_bool(np, propname: "linux,wakeup" ); /* legacy */ |
432 | |
433 | pdata->active_low = of_property_read_bool(np, propname: "gpio-activelow" ); |
434 | |
435 | pdata->drive_inactive_cols = |
436 | of_property_read_bool(np, propname: "drive-inactive-cols" ); |
437 | |
438 | of_property_read_u32(np, propname: "debounce-delay-ms" , out_value: &pdata->debounce_ms); |
439 | of_property_read_u32(np, propname: "col-scan-delay-us" , |
440 | out_value: &pdata->col_scan_delay_us); |
441 | |
442 | gpios = devm_kcalloc(dev, |
443 | n: pdata->num_row_gpios + pdata->num_col_gpios, |
444 | size: sizeof(unsigned int), |
445 | GFP_KERNEL); |
446 | if (!gpios) { |
447 | dev_err(dev, "could not allocate memory for gpios\n" ); |
448 | return ERR_PTR(error: -ENOMEM); |
449 | } |
450 | |
451 | for (i = 0; i < nrow; i++) { |
452 | ret = of_get_named_gpio(np, list_name: "row-gpios" , index: i); |
453 | if (ret < 0) |
454 | return ERR_PTR(error: ret); |
455 | gpios[i] = ret; |
456 | } |
457 | |
458 | for (i = 0; i < ncol; i++) { |
459 | ret = of_get_named_gpio(np, list_name: "col-gpios" , index: i); |
460 | if (ret < 0) |
461 | return ERR_PTR(error: ret); |
462 | gpios[nrow + i] = ret; |
463 | } |
464 | |
465 | pdata->row_gpios = gpios; |
466 | pdata->col_gpios = &gpios[pdata->num_row_gpios]; |
467 | |
468 | return pdata; |
469 | } |
470 | #else |
471 | static inline struct matrix_keypad_platform_data * |
472 | matrix_keypad_parse_dt(struct device *dev) |
473 | { |
474 | dev_err(dev, "no platform data defined\n" ); |
475 | |
476 | return ERR_PTR(-EINVAL); |
477 | } |
478 | #endif |
479 | |
480 | static int matrix_keypad_probe(struct platform_device *pdev) |
481 | { |
482 | const struct matrix_keypad_platform_data *pdata; |
483 | struct matrix_keypad *keypad; |
484 | struct input_dev *input_dev; |
485 | int err; |
486 | |
487 | pdata = dev_get_platdata(dev: &pdev->dev); |
488 | if (!pdata) { |
489 | pdata = matrix_keypad_parse_dt(dev: &pdev->dev); |
490 | if (IS_ERR(ptr: pdata)) |
491 | return PTR_ERR(ptr: pdata); |
492 | } else if (!pdata->keymap_data) { |
493 | dev_err(&pdev->dev, "no keymap data defined\n" ); |
494 | return -EINVAL; |
495 | } |
496 | |
497 | keypad = kzalloc(size: sizeof(struct matrix_keypad), GFP_KERNEL); |
498 | input_dev = input_allocate_device(); |
499 | if (!keypad || !input_dev) { |
500 | err = -ENOMEM; |
501 | goto err_free_mem; |
502 | } |
503 | |
504 | keypad->input_dev = input_dev; |
505 | keypad->pdata = pdata; |
506 | keypad->row_shift = get_count_order(count: pdata->num_col_gpios); |
507 | keypad->stopped = true; |
508 | INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); |
509 | spin_lock_init(&keypad->lock); |
510 | |
511 | input_dev->name = pdev->name; |
512 | input_dev->id.bustype = BUS_HOST; |
513 | input_dev->dev.parent = &pdev->dev; |
514 | input_dev->open = matrix_keypad_start; |
515 | input_dev->close = matrix_keypad_stop; |
516 | |
517 | err = matrix_keypad_build_keymap(keymap_data: pdata->keymap_data, NULL, |
518 | rows: pdata->num_row_gpios, |
519 | cols: pdata->num_col_gpios, |
520 | NULL, input_dev); |
521 | if (err) { |
522 | dev_err(&pdev->dev, "failed to build keymap\n" ); |
523 | goto err_free_mem; |
524 | } |
525 | |
526 | if (!pdata->no_autorepeat) |
527 | __set_bit(EV_REP, input_dev->evbit); |
528 | input_set_capability(dev: input_dev, EV_MSC, MSC_SCAN); |
529 | input_set_drvdata(dev: input_dev, data: keypad); |
530 | |
531 | err = matrix_keypad_init_gpio(pdev, keypad); |
532 | if (err) |
533 | goto err_free_mem; |
534 | |
535 | err = input_register_device(keypad->input_dev); |
536 | if (err) |
537 | goto err_free_gpio; |
538 | |
539 | device_init_wakeup(dev: &pdev->dev, enable: pdata->wakeup); |
540 | platform_set_drvdata(pdev, data: keypad); |
541 | |
542 | return 0; |
543 | |
544 | err_free_gpio: |
545 | matrix_keypad_free_gpio(keypad); |
546 | err_free_mem: |
547 | input_free_device(dev: input_dev); |
548 | kfree(objp: keypad); |
549 | return err; |
550 | } |
551 | |
552 | static int matrix_keypad_remove(struct platform_device *pdev) |
553 | { |
554 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
555 | |
556 | matrix_keypad_free_gpio(keypad); |
557 | input_unregister_device(keypad->input_dev); |
558 | kfree(objp: keypad); |
559 | |
560 | return 0; |
561 | } |
562 | |
563 | #ifdef CONFIG_OF |
564 | static const struct of_device_id matrix_keypad_dt_match[] = { |
565 | { .compatible = "gpio-matrix-keypad" }, |
566 | { } |
567 | }; |
568 | MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match); |
569 | #endif |
570 | |
571 | static struct platform_driver matrix_keypad_driver = { |
572 | .probe = matrix_keypad_probe, |
573 | .remove = matrix_keypad_remove, |
574 | .driver = { |
575 | .name = "matrix-keypad" , |
576 | .pm = pm_sleep_ptr(&matrix_keypad_pm_ops), |
577 | .of_match_table = of_match_ptr(matrix_keypad_dt_match), |
578 | }, |
579 | }; |
580 | module_platform_driver(matrix_keypad_driver); |
581 | |
582 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>" ); |
583 | MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver" ); |
584 | MODULE_LICENSE("GPL v2" ); |
585 | MODULE_ALIAS("platform:matrix-keypad" ); |
586 | |