Version:  2.0.40 2.2.26 2.4.37 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5

Linux/drivers/input/keyboard/imx_keypad.c

  1 /*
  2  * Driver for the IMX keypad port.
  3  * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
  4  *
  5  * This program is free software; you can redistribute it and/or modify
  6  * it under the terms of the GNU General Public License version 2 as
  7  * published by the Free Software Foundation.
  8  */
  9 
 10 #include <linux/clk.h>
 11 #include <linux/delay.h>
 12 #include <linux/device.h>
 13 #include <linux/err.h>
 14 #include <linux/input/matrix_keypad.h>
 15 #include <linux/interrupt.h>
 16 #include <linux/io.h>
 17 #include <linux/jiffies.h>
 18 #include <linux/kernel.h>
 19 #include <linux/module.h>
 20 #include <linux/of.h>
 21 #include <linux/platform_device.h>
 22 #include <linux/slab.h>
 23 #include <linux/timer.h>
 24 
 25 /*
 26  * Keypad Controller registers (halfword)
 27  */
 28 #define KPCR            0x00 /* Keypad Control Register */
 29 
 30 #define KPSR            0x02 /* Keypad Status Register */
 31 #define KBD_STAT_KPKD   (0x1 << 0) /* Key Press Interrupt Status bit (w1c) */
 32 #define KBD_STAT_KPKR   (0x1 << 1) /* Key Release Interrupt Status bit (w1c) */
 33 #define KBD_STAT_KDSC   (0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/
 34 #define KBD_STAT_KRSS   (0x1 << 3) /* Key Release Synch Status bit (w1c)*/
 35 #define KBD_STAT_KDIE   (0x1 << 8) /* Key Depress Interrupt Enable Status bit */
 36 #define KBD_STAT_KRIE   (0x1 << 9) /* Key Release Interrupt Enable */
 37 #define KBD_STAT_KPPEN  (0x1 << 10) /* Keypad Clock Enable */
 38 
 39 #define KDDR            0x04 /* Keypad Data Direction Register */
 40 #define KPDR            0x06 /* Keypad Data Register */
 41 
 42 #define MAX_MATRIX_KEY_ROWS     8
 43 #define MAX_MATRIX_KEY_COLS     8
 44 #define MATRIX_ROW_SHIFT        3
 45 
 46 #define MAX_MATRIX_KEY_NUM      (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
 47 
 48 struct imx_keypad {
 49 
 50         struct clk *clk;
 51         struct input_dev *input_dev;
 52         void __iomem *mmio_base;
 53 
 54         int                     irq;
 55         struct timer_list       check_matrix_timer;
 56 
 57         /*
 58          * The matrix is stable only if no changes are detected after
 59          * IMX_KEYPAD_SCANS_FOR_STABILITY scans
 60          */
 61 #define IMX_KEYPAD_SCANS_FOR_STABILITY 3
 62         int                     stable_count;
 63 
 64         bool                    enabled;
 65 
 66         /* Masks for enabled rows/cols */
 67         unsigned short          rows_en_mask;
 68         unsigned short          cols_en_mask;
 69 
 70         unsigned short          keycodes[MAX_MATRIX_KEY_NUM];
 71 
 72         /*
 73          * Matrix states:
 74          * -stable: achieved after a complete debounce process.
 75          * -unstable: used in the debouncing process.
 76          */
 77         unsigned short          matrix_stable_state[MAX_MATRIX_KEY_COLS];
 78         unsigned short          matrix_unstable_state[MAX_MATRIX_KEY_COLS];
 79 };
 80 
 81 /* Scan the matrix and return the new state in *matrix_volatile_state. */
 82 static void imx_keypad_scan_matrix(struct imx_keypad *keypad,
 83                                   unsigned short *matrix_volatile_state)
 84 {
 85         int col;
 86         unsigned short reg_val;
 87 
 88         for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
 89                 if ((keypad->cols_en_mask & (1 << col)) == 0)
 90                         continue;
 91                 /*
 92                  * Discharge keypad capacitance:
 93                  * 2. write 1s on column data.
 94                  * 3. configure columns as totem-pole to discharge capacitance.
 95                  * 4. configure columns as open-drain.
 96                  */
 97                 reg_val = readw(keypad->mmio_base + KPDR);
 98                 reg_val |= 0xff00;
 99                 writew(reg_val, keypad->mmio_base + KPDR);
100 
101                 reg_val = readw(keypad->mmio_base + KPCR);
102                 reg_val &= ~((keypad->cols_en_mask & 0xff) << 8);
103                 writew(reg_val, keypad->mmio_base + KPCR);
104 
105                 udelay(2);
106 
107                 reg_val = readw(keypad->mmio_base + KPCR);
108                 reg_val |= (keypad->cols_en_mask & 0xff) << 8;
109                 writew(reg_val, keypad->mmio_base + KPCR);
110 
111                 /*
112                  * 5. Write a single column to 0, others to 1.
113                  * 6. Sample row inputs and save data.
114                  * 7. Repeat steps 2 - 6 for remaining columns.
115                  */
116                 reg_val = readw(keypad->mmio_base + KPDR);
117                 reg_val &= ~(1 << (8 + col));
118                 writew(reg_val, keypad->mmio_base + KPDR);
119 
120                 /*
121                  * Delay added to avoid propagating the 0 from column to row
122                  * when scanning.
123                  */
124                 udelay(5);
125 
126                 /*
127                  * 1s in matrix_volatile_state[col] means key pressures
128                  * throw data from non enabled rows.
129                  */
130                 reg_val = readw(keypad->mmio_base + KPDR);
131                 matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask;
132         }
133 
134         /*
135          * Return in standby mode:
136          * 9. write 0s to columns
137          */
138         reg_val = readw(keypad->mmio_base + KPDR);
139         reg_val &= 0x00ff;
140         writew(reg_val, keypad->mmio_base + KPDR);
141 }
142 
143 /*
144  * Compare the new matrix state (volatile) with the stable one stored in
145  * keypad->matrix_stable_state and fire events if changes are detected.
146  */
147 static void imx_keypad_fire_events(struct imx_keypad *keypad,
148                                    unsigned short *matrix_volatile_state)
149 {
150         struct input_dev *input_dev = keypad->input_dev;
151         int row, col;
152 
153         for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
154                 unsigned short bits_changed;
155                 int code;
156 
157                 if ((keypad->cols_en_mask & (1 << col)) == 0)
158                         continue; /* Column is not enabled */
159 
160                 bits_changed = keypad->matrix_stable_state[col] ^
161                                                 matrix_volatile_state[col];
162 
163                 if (bits_changed == 0)
164                         continue; /* Column does not contain changes */
165 
166                 for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) {
167                         if ((keypad->rows_en_mask & (1 << row)) == 0)
168                                 continue; /* Row is not enabled */
169                         if ((bits_changed & (1 << row)) == 0)
170                                 continue; /* Row does not contain changes */
171 
172                         code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
173                         input_event(input_dev, EV_MSC, MSC_SCAN, code);
174                         input_report_key(input_dev, keypad->keycodes[code],
175                                 matrix_volatile_state[col] & (1 << row));
176                         dev_dbg(&input_dev->dev, "Event code: %d, val: %d",
177                                 keypad->keycodes[code],
178                                 matrix_volatile_state[col] & (1 << row));
179                 }
180         }
181         input_sync(input_dev);
182 }
183 
184 /*
185  * imx_keypad_check_for_events is the timer handler.
186  */
187 static void imx_keypad_check_for_events(unsigned long data)
188 {
189         struct imx_keypad *keypad = (struct imx_keypad *) data;
190         unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS];
191         unsigned short reg_val;
192         bool state_changed, is_zero_matrix;
193         int i;
194 
195         memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state));
196 
197         imx_keypad_scan_matrix(keypad, matrix_volatile_state);
198 
199         state_changed = false;
200         for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) {
201                 if ((keypad->cols_en_mask & (1 << i)) == 0)
202                         continue;
203 
204                 if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) {
205                         state_changed = true;
206                         break;
207                 }
208         }
209 
210         /*
211          * If the matrix state is changed from the previous scan
212          *   (Re)Begin the debouncing process, saving the new state in
213          *    keypad->matrix_unstable_state.
214          * else
215          *   Increase the count of number of scans with a stable state.
216          */
217         if (state_changed) {
218                 memcpy(keypad->matrix_unstable_state, matrix_volatile_state,
219                         sizeof(matrix_volatile_state));
220                 keypad->stable_count = 0;
221         } else
222                 keypad->stable_count++;
223 
224         /*
225          * If the matrix is not as stable as we want reschedule scan
226          * in the near future.
227          */
228         if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) {
229                 mod_timer(&keypad->check_matrix_timer,
230                           jiffies + msecs_to_jiffies(10));
231                 return;
232         }
233 
234         /*
235          * If the matrix state is stable, fire the events and save the new
236          * stable state. Note, if the matrix is kept stable for longer
237          * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all
238          * events have already been generated.
239          */
240         if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) {
241                 imx_keypad_fire_events(keypad, matrix_volatile_state);
242 
243                 memcpy(keypad->matrix_stable_state, matrix_volatile_state,
244                         sizeof(matrix_volatile_state));
245         }
246 
247         is_zero_matrix = true;
248         for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) {
249                 if (matrix_volatile_state[i] != 0) {
250                         is_zero_matrix = false;
251                         break;
252                 }
253         }
254 
255 
256         if (is_zero_matrix) {
257                 /*
258                  * All keys have been released. Enable only the KDI
259                  * interrupt for future key presses (clear the KDI
260                  * status bit and its sync chain before that).
261                  */
262                 reg_val = readw(keypad->mmio_base + KPSR);
263                 reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC;
264                 writew(reg_val, keypad->mmio_base + KPSR);
265 
266                 reg_val = readw(keypad->mmio_base + KPSR);
267                 reg_val |= KBD_STAT_KDIE;
268                 reg_val &= ~KBD_STAT_KRIE;
269                 writew(reg_val, keypad->mmio_base + KPSR);
270         } else {
271                 /*
272                  * Some keys are still pressed. Schedule a rescan in
273                  * attempt to detect multiple key presses and enable
274                  * the KRI interrupt to react quickly to key release
275                  * event.
276                  */
277                 mod_timer(&keypad->check_matrix_timer,
278                           jiffies + msecs_to_jiffies(60));
279 
280                 reg_val = readw(keypad->mmio_base + KPSR);
281                 reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS;
282                 writew(reg_val, keypad->mmio_base + KPSR);
283 
284                 reg_val = readw(keypad->mmio_base + KPSR);
285                 reg_val |= KBD_STAT_KRIE;
286                 reg_val &= ~KBD_STAT_KDIE;
287                 writew(reg_val, keypad->mmio_base + KPSR);
288         }
289 }
290 
291 static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id)
292 {
293         struct imx_keypad *keypad = dev_id;
294         unsigned short reg_val;
295 
296         reg_val = readw(keypad->mmio_base + KPSR);
297 
298         /* Disable both interrupt types */
299         reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE);
300         /* Clear interrupts status bits */
301         reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
302         writew(reg_val, keypad->mmio_base + KPSR);
303 
304         if (keypad->enabled) {
305                 /* The matrix is supposed to be changed */
306                 keypad->stable_count = 0;
307 
308                 /* Schedule the scanning procedure near in the future */
309                 mod_timer(&keypad->check_matrix_timer,
310                           jiffies + msecs_to_jiffies(2));
311         }
312 
313         return IRQ_HANDLED;
314 }
315 
316 static void imx_keypad_config(struct imx_keypad *keypad)
317 {
318         unsigned short reg_val;
319 
320         /*
321          * Include enabled rows in interrupt generation (KPCR[7:0])
322          * Configure keypad columns as open-drain (KPCR[15:8])
323          */
324         reg_val = readw(keypad->mmio_base + KPCR);
325         reg_val |= keypad->rows_en_mask & 0xff;         /* rows */
326         reg_val |= (keypad->cols_en_mask & 0xff) << 8;  /* cols */
327         writew(reg_val, keypad->mmio_base + KPCR);
328 
329         /* Write 0's to KPDR[15:8] (Colums) */
330         reg_val = readw(keypad->mmio_base + KPDR);
331         reg_val &= 0x00ff;
332         writew(reg_val, keypad->mmio_base + KPDR);
333 
334         /* Configure columns as output, rows as input (KDDR[15:0]) */
335         writew(0xff00, keypad->mmio_base + KDDR);
336 
337         /*
338          * Clear Key Depress and Key Release status bit.
339          * Clear both synchronizer chain.
340          */
341         reg_val = readw(keypad->mmio_base + KPSR);
342         reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD |
343                    KBD_STAT_KDSC | KBD_STAT_KRSS;
344         writew(reg_val, keypad->mmio_base + KPSR);
345 
346         /* Enable KDI and disable KRI (avoid false release events). */
347         reg_val |= KBD_STAT_KDIE;
348         reg_val &= ~KBD_STAT_KRIE;
349         writew(reg_val, keypad->mmio_base + KPSR);
350 }
351 
352 static void imx_keypad_inhibit(struct imx_keypad *keypad)
353 {
354         unsigned short reg_val;
355 
356         /* Inhibit KDI and KRI interrupts. */
357         reg_val = readw(keypad->mmio_base + KPSR);
358         reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE);
359         reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
360         writew(reg_val, keypad->mmio_base + KPSR);
361 
362         /* Colums as open drain and disable all rows */
363         reg_val = (keypad->cols_en_mask & 0xff) << 8;
364         writew(reg_val, keypad->mmio_base + KPCR);
365 }
366 
367 static void imx_keypad_close(struct input_dev *dev)
368 {
369         struct imx_keypad *keypad = input_get_drvdata(dev);
370 
371         dev_dbg(&dev->dev, ">%s\n", __func__);
372 
373         /* Mark keypad as being inactive */
374         keypad->enabled = false;
375         synchronize_irq(keypad->irq);
376         del_timer_sync(&keypad->check_matrix_timer);
377 
378         imx_keypad_inhibit(keypad);
379 
380         /* Disable clock unit */
381         clk_disable_unprepare(keypad->clk);
382 }
383 
384 static int imx_keypad_open(struct input_dev *dev)
385 {
386         struct imx_keypad *keypad = input_get_drvdata(dev);
387         int error;
388 
389         dev_dbg(&dev->dev, ">%s\n", __func__);
390 
391         /* Enable the kpp clock */
392         error = clk_prepare_enable(keypad->clk);
393         if (error)
394                 return error;
395 
396         /* We became active from now */
397         keypad->enabled = true;
398 
399         imx_keypad_config(keypad);
400 
401         /* Sanity control, not all the rows must be actived now. */
402         if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) {
403                 dev_err(&dev->dev,
404                         "too many keys pressed, control pins initialisation\n");
405                 goto open_err;
406         }
407 
408         return 0;
409 
410 open_err:
411         imx_keypad_close(dev);
412         return -EIO;
413 }
414 
415 #ifdef CONFIG_OF
416 static const struct of_device_id imx_keypad_of_match[] = {
417         { .compatible = "fsl,imx21-kpp", },
418         { /* sentinel */ }
419 };
420 MODULE_DEVICE_TABLE(of, imx_keypad_of_match);
421 #endif
422 
423 static int imx_keypad_probe(struct platform_device *pdev)
424 {
425         const struct matrix_keymap_data *keymap_data =
426                         dev_get_platdata(&pdev->dev);
427         struct imx_keypad *keypad;
428         struct input_dev *input_dev;
429         struct resource *res;
430         int irq, error, i, row, col;
431 
432         if (!keymap_data && !pdev->dev.of_node) {
433                 dev_err(&pdev->dev, "no keymap defined\n");
434                 return -EINVAL;
435         }
436 
437         irq = platform_get_irq(pdev, 0);
438         if (irq < 0) {
439                 dev_err(&pdev->dev, "no irq defined in platform data\n");
440                 return irq;
441         }
442 
443         input_dev = devm_input_allocate_device(&pdev->dev);
444         if (!input_dev) {
445                 dev_err(&pdev->dev, "failed to allocate the input device\n");
446                 return -ENOMEM;
447         }
448 
449         keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
450         if (!keypad) {
451                 dev_err(&pdev->dev, "not enough memory for driver data\n");
452                 return -ENOMEM;
453         }
454 
455         keypad->input_dev = input_dev;
456         keypad->irq = irq;
457         keypad->stable_count = 0;
458 
459         setup_timer(&keypad->check_matrix_timer,
460                     imx_keypad_check_for_events, (unsigned long) keypad);
461 
462         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
463         keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res);
464         if (IS_ERR(keypad->mmio_base))
465                 return PTR_ERR(keypad->mmio_base);
466 
467         keypad->clk = devm_clk_get(&pdev->dev, NULL);
468         if (IS_ERR(keypad->clk)) {
469                 dev_err(&pdev->dev, "failed to get keypad clock\n");
470                 return PTR_ERR(keypad->clk);
471         }
472 
473         /* Init the Input device */
474         input_dev->name = pdev->name;
475         input_dev->id.bustype = BUS_HOST;
476         input_dev->dev.parent = &pdev->dev;
477         input_dev->open = imx_keypad_open;
478         input_dev->close = imx_keypad_close;
479 
480         error = matrix_keypad_build_keymap(keymap_data, NULL,
481                                            MAX_MATRIX_KEY_ROWS,
482                                            MAX_MATRIX_KEY_COLS,
483                                            keypad->keycodes, input_dev);
484         if (error) {
485                 dev_err(&pdev->dev, "failed to build keymap\n");
486                 return error;
487         }
488 
489         /* Search for rows and cols enabled */
490         for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) {
491                 for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
492                         i = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
493                         if (keypad->keycodes[i] != KEY_RESERVED) {
494                                 keypad->rows_en_mask |= 1 << row;
495                                 keypad->cols_en_mask |= 1 << col;
496                         }
497                 }
498         }
499         dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask);
500         dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask);
501 
502         __set_bit(EV_REP, input_dev->evbit);
503         input_set_capability(input_dev, EV_MSC, MSC_SCAN);
504         input_set_drvdata(input_dev, keypad);
505 
506         /* Ensure that the keypad will stay dormant until opened */
507         error = clk_prepare_enable(keypad->clk);
508         if (error)
509                 return error;
510         imx_keypad_inhibit(keypad);
511         clk_disable_unprepare(keypad->clk);
512 
513         error = devm_request_irq(&pdev->dev, irq, imx_keypad_irq_handler, 0,
514                             pdev->name, keypad);
515         if (error) {
516                 dev_err(&pdev->dev, "failed to request IRQ\n");
517                 return error;
518         }
519 
520         /* Register the input device */
521         error = input_register_device(input_dev);
522         if (error) {
523                 dev_err(&pdev->dev, "failed to register input device\n");
524                 return error;
525         }
526 
527         platform_set_drvdata(pdev, keypad);
528         device_init_wakeup(&pdev->dev, 1);
529 
530         return 0;
531 }
532 
533 static int __maybe_unused imx_kbd_suspend(struct device *dev)
534 {
535         struct platform_device *pdev = to_platform_device(dev);
536         struct imx_keypad *kbd = platform_get_drvdata(pdev);
537         struct input_dev *input_dev = kbd->input_dev;
538 
539         /* imx kbd can wake up system even clock is disabled */
540         mutex_lock(&input_dev->mutex);
541 
542         if (input_dev->users)
543                 clk_disable_unprepare(kbd->clk);
544 
545         mutex_unlock(&input_dev->mutex);
546 
547         if (device_may_wakeup(&pdev->dev))
548                 enable_irq_wake(kbd->irq);
549 
550         return 0;
551 }
552 
553 static int __maybe_unused imx_kbd_resume(struct device *dev)
554 {
555         struct platform_device *pdev = to_platform_device(dev);
556         struct imx_keypad *kbd = platform_get_drvdata(pdev);
557         struct input_dev *input_dev = kbd->input_dev;
558         int ret = 0;
559 
560         if (device_may_wakeup(&pdev->dev))
561                 disable_irq_wake(kbd->irq);
562 
563         mutex_lock(&input_dev->mutex);
564 
565         if (input_dev->users) {
566                 ret = clk_prepare_enable(kbd->clk);
567                 if (ret)
568                         goto err_clk;
569         }
570 
571 err_clk:
572         mutex_unlock(&input_dev->mutex);
573 
574         return ret;
575 }
576 
577 static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume);
578 
579 static struct platform_driver imx_keypad_driver = {
580         .driver         = {
581                 .name   = "imx-keypad",
582                 .pm     = &imx_kbd_pm_ops,
583                 .of_match_table = of_match_ptr(imx_keypad_of_match),
584         },
585         .probe          = imx_keypad_probe,
586 };
587 module_platform_driver(imx_keypad_driver);
588 
589 MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
590 MODULE_DESCRIPTION("IMX Keypad Port Driver");
591 MODULE_LICENSE("GPL v2");
592 MODULE_ALIAS("platform:imx-keypad");
593 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us