]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/input/keyboard/tc3589x-keypad.c
Merge tag 'xtensa-20170507' of git://github.com/jcmvbkbc/linux-xtensa
[karo-tx-linux.git] / drivers / input / keyboard / tc3589x-keypad.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2010
3  *
4  * Author: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com>
5  * Author: Sundar Iyer <sundar.iyer@stericsson.com>
6  *
7  * License Terms: GNU General Public License, version 2
8  *
9  * TC35893 MFD Keypad Controller driver
10  */
11
12 #include <linux/module.h>
13 #include <linux/interrupt.h>
14 #include <linux/input.h>
15 #include <linux/platform_device.h>
16 #include <linux/input/matrix_keypad.h>
17 #include <linux/i2c.h>
18 #include <linux/slab.h>
19 #include <linux/mfd/tc3589x.h>
20 #include <linux/device.h>
21
22 /* Maximum supported keypad matrix row/columns size */
23 #define TC3589x_MAX_KPROW               8
24 #define TC3589x_MAX_KPCOL               12
25
26 /* keypad related Constants */
27 #define TC3589x_MAX_DEBOUNCE_SETTLE     0xFF
28 #define DEDICATED_KEY_VAL               0xFF
29
30 /* Pull up/down masks */
31 #define TC3589x_NO_PULL_MASK            0x0
32 #define TC3589x_PULL_DOWN_MASK          0x1
33 #define TC3589x_PULL_UP_MASK            0x2
34 #define TC3589x_PULLUP_ALL_MASK         0xAA
35 #define TC3589x_IO_PULL_VAL(index, mask)        ((mask)<<((index)%4)*2)
36
37 /* Bit masks for IOCFG register */
38 #define IOCFG_BALLCFG           0x01
39 #define IOCFG_IG                0x08
40
41 #define KP_EVCODE_COL_MASK      0x0F
42 #define KP_EVCODE_ROW_MASK      0x70
43 #define KP_RELEASE_EVT_MASK     0x80
44
45 #define KP_ROW_SHIFT            4
46
47 #define KP_NO_VALID_KEY_MASK    0x7F
48
49 /* bit masks for RESTCTRL register */
50 #define TC3589x_KBDRST          0x2
51 #define TC3589x_IRQRST          0x10
52 #define TC3589x_RESET_ALL       0x1B
53
54 /* KBDMFS register bit mask */
55 #define TC3589x_KBDMFS_EN       0x1
56
57 /* CLKEN register bitmask */
58 #define KPD_CLK_EN              0x1
59
60 /* RSTINTCLR register bit mask */
61 #define IRQ_CLEAR               0x1
62
63 /* bit masks for keyboard interrupts*/
64 #define TC3589x_EVT_LOSS_INT    0x8
65 #define TC3589x_EVT_INT         0x4
66 #define TC3589x_KBD_LOSS_INT    0x2
67 #define TC3589x_KBD_INT         0x1
68
69 /* bit masks for keyboard interrupt clear*/
70 #define TC3589x_EVT_INT_CLR     0x2
71 #define TC3589x_KBD_INT_CLR     0x1
72
73 /**
74  * struct tc35893_keypad_platform_data - platform specific keypad data
75  * @keymap_data:        matrix scan code table for keycodes
76  * @krow:               mask for available rows, value is 0xFF
77  * @kcol:               mask for available columns, value is 0xFF
78  * @debounce_period:    platform specific debounce time
79  * @settle_time:        platform specific settle down time
80  * @irqtype:            type of interrupt, falling or rising edge
81  * @enable_wakeup:      specifies if keypad event can wake up system from sleep
82  * @no_autorepeat:      flag for auto repetition
83  */
84 struct tc3589x_keypad_platform_data {
85         const struct matrix_keymap_data *keymap_data;
86         u8                      krow;
87         u8                      kcol;
88         u8                      debounce_period;
89         u8                      settle_time;
90         unsigned long           irqtype;
91         bool                    enable_wakeup;
92         bool                    no_autorepeat;
93 };
94
95 /**
96  * struct tc_keypad - data structure used by keypad driver
97  * @tc3589x:    pointer to tc35893
98  * @input:      pointer to input device object
99  * @board:      keypad platform device
100  * @krow:       number of rows
101  * @kcol:       number of columns
102  * @keymap:     matrix scan code table for keycodes
103  * @keypad_stopped: holds keypad status
104  */
105 struct tc_keypad {
106         struct tc3589x *tc3589x;
107         struct input_dev *input;
108         const struct tc3589x_keypad_platform_data *board;
109         unsigned int krow;
110         unsigned int kcol;
111         unsigned short *keymap;
112         bool keypad_stopped;
113 };
114
115 static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad)
116 {
117         int ret;
118         struct tc3589x *tc3589x = keypad->tc3589x;
119         const struct tc3589x_keypad_platform_data *board = keypad->board;
120
121         /* validate platform configuration */
122         if (board->kcol > TC3589x_MAX_KPCOL || board->krow > TC3589x_MAX_KPROW)
123                 return -EINVAL;
124
125         /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */
126         ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE,
127                         (board->krow << KP_ROW_SHIFT) | board->kcol);
128         if (ret < 0)
129                 return ret;
130
131         /* configure dedicated key config, no dedicated key selected */
132         ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_LSB, DEDICATED_KEY_VAL);
133         if (ret < 0)
134                 return ret;
135
136         ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_MSB, DEDICATED_KEY_VAL);
137         if (ret < 0)
138                 return ret;
139
140         /* Configure settle time */
141         ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG,
142                                 board->settle_time);
143         if (ret < 0)
144                 return ret;
145
146         /* Configure debounce time */
147         ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE,
148                                 board->debounce_period);
149         if (ret < 0)
150                 return ret;
151
152         /* Start of initialise keypad GPIOs */
153         ret = tc3589x_set_bits(tc3589x, TC3589x_IOCFG, 0x0, IOCFG_IG);
154         if (ret < 0)
155                 return ret;
156
157         /* Configure pull-up resistors for all row GPIOs */
158         ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_LSB,
159                                         TC3589x_PULLUP_ALL_MASK);
160         if (ret < 0)
161                 return ret;
162
163         ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_MSB,
164                                         TC3589x_PULLUP_ALL_MASK);
165         if (ret < 0)
166                 return ret;
167
168         /* Configure pull-up resistors for all column GPIOs */
169         ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_LSB,
170                         TC3589x_PULLUP_ALL_MASK);
171         if (ret < 0)
172                 return ret;
173
174         ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_MSB,
175                         TC3589x_PULLUP_ALL_MASK);
176         if (ret < 0)
177                 return ret;
178
179         ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG2_LSB,
180                         TC3589x_PULLUP_ALL_MASK);
181
182         return ret;
183 }
184
185 #define TC35893_DATA_REGS               4
186 #define TC35893_KEYCODE_FIFO_EMPTY      0x7f
187 #define TC35893_KEYCODE_FIFO_CLEAR      0xff
188 #define TC35893_KEYPAD_ROW_SHIFT        0x3
189
190 static irqreturn_t tc3589x_keypad_irq(int irq, void *dev)
191 {
192         struct tc_keypad *keypad = dev;
193         struct tc3589x *tc3589x = keypad->tc3589x;
194         u8 i, row_index, col_index, kbd_code, up;
195         u8 code;
196
197         for (i = 0; i < TC35893_DATA_REGS * 2; i++) {
198                 kbd_code = tc3589x_reg_read(tc3589x, TC3589x_EVTCODE_FIFO);
199
200                 /* loop till fifo is empty and no more keys are pressed */
201                 if (kbd_code == TC35893_KEYCODE_FIFO_EMPTY ||
202                                 kbd_code == TC35893_KEYCODE_FIFO_CLEAR)
203                         continue;
204
205                 /* valid key is found */
206                 col_index = kbd_code & KP_EVCODE_COL_MASK;
207                 row_index = (kbd_code & KP_EVCODE_ROW_MASK) >> KP_ROW_SHIFT;
208                 code = MATRIX_SCAN_CODE(row_index, col_index,
209                                                 TC35893_KEYPAD_ROW_SHIFT);
210                 up = kbd_code & KP_RELEASE_EVT_MASK;
211
212                 input_event(keypad->input, EV_MSC, MSC_SCAN, code);
213                 input_report_key(keypad->input, keypad->keymap[code], !up);
214                 input_sync(keypad->input);
215         }
216
217         /* clear IRQ */
218         tc3589x_set_bits(tc3589x, TC3589x_KBDIC,
219                         0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR);
220         /* enable IRQ */
221         tc3589x_set_bits(tc3589x, TC3589x_KBDMSK,
222                         0x0, TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT);
223
224         return IRQ_HANDLED;
225 }
226
227 static int tc3589x_keypad_enable(struct tc_keypad *keypad)
228 {
229         struct tc3589x *tc3589x = keypad->tc3589x;
230         int ret;
231
232         /* pull the keypad module out of reset */
233         ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x0);
234         if (ret < 0)
235                 return ret;
236
237         /* configure KBDMFS */
238         ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMFS, 0x0, TC3589x_KBDMFS_EN);
239         if (ret < 0)
240                 return ret;
241
242         /* enable the keypad clock */
243         ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x0, KPD_CLK_EN);
244         if (ret < 0)
245                 return ret;
246
247         /* clear pending IRQs */
248         ret =  tc3589x_set_bits(tc3589x, TC3589x_RSTINTCLR, 0x0, 0x1);
249         if (ret < 0)
250                 return ret;
251
252         /* enable the IRQs */
253         ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 0x0,
254                                         TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT);
255         if (ret < 0)
256                 return ret;
257
258         keypad->keypad_stopped = false;
259
260         return ret;
261 }
262
263 static int tc3589x_keypad_disable(struct tc_keypad *keypad)
264 {
265         struct tc3589x *tc3589x = keypad->tc3589x;
266         int ret;
267
268         /* clear IRQ */
269         ret = tc3589x_set_bits(tc3589x, TC3589x_KBDIC,
270                         0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR);
271         if (ret < 0)
272                 return ret;
273
274         /* disable all interrupts */
275         ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK,
276                         ~(TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT), 0x0);
277         if (ret < 0)
278                 return ret;
279
280         /* disable the keypad module */
281         ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x1, 0x0);
282         if (ret < 0)
283                 return ret;
284
285         /* put the keypad module into reset */
286         ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x1);
287
288         keypad->keypad_stopped = true;
289
290         return ret;
291 }
292
293 static int tc3589x_keypad_open(struct input_dev *input)
294 {
295         int error;
296         struct tc_keypad *keypad = input_get_drvdata(input);
297
298         /* enable the keypad module */
299         error = tc3589x_keypad_enable(keypad);
300         if (error < 0) {
301                 dev_err(&input->dev, "failed to enable keypad module\n");
302                 return error;
303         }
304
305         error = tc3589x_keypad_init_key_hardware(keypad);
306         if (error < 0) {
307                 dev_err(&input->dev, "failed to configure keypad module\n");
308                 return error;
309         }
310
311         return 0;
312 }
313
314 static void tc3589x_keypad_close(struct input_dev *input)
315 {
316         struct tc_keypad *keypad = input_get_drvdata(input);
317
318         /* disable the keypad module */
319         tc3589x_keypad_disable(keypad);
320 }
321
322 static const struct tc3589x_keypad_platform_data *
323 tc3589x_keypad_of_probe(struct device *dev)
324 {
325         struct device_node *np = dev->of_node;
326         struct tc3589x_keypad_platform_data *plat;
327         u32 cols, rows;
328         u32 debounce_ms;
329         int proplen;
330
331         if (!np)
332                 return ERR_PTR(-ENODEV);
333
334         plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
335         if (!plat)
336                 return ERR_PTR(-ENOMEM);
337
338         of_property_read_u32(np, "keypad,num-columns", &cols);
339         of_property_read_u32(np, "keypad,num-rows", &rows);
340         plat->kcol = (u8) cols;
341         plat->krow = (u8) rows;
342         if (!plat->krow || !plat->kcol ||
343              plat->krow > TC_KPD_ROWS || plat->kcol > TC_KPD_COLUMNS) {
344                 dev_err(dev,
345                         "keypad columns/rows not properly specified (%ux%u)\n",
346                         plat->kcol, plat->krow);
347                 return ERR_PTR(-EINVAL);
348         }
349
350         if (!of_get_property(np, "linux,keymap", &proplen)) {
351                 dev_err(dev, "property linux,keymap not found\n");
352                 return ERR_PTR(-ENOENT);
353         }
354
355         plat->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat");
356
357         plat->enable_wakeup = of_property_read_bool(np, "wakeup-source") ||
358                               /* legacy name */
359                               of_property_read_bool(np, "linux,wakeup");
360
361         /* The custom delay format is ms/16 */
362         of_property_read_u32(np, "debounce-delay-ms", &debounce_ms);
363         if (debounce_ms)
364                 plat->debounce_period = debounce_ms * 16;
365         else
366                 plat->debounce_period = TC_KPD_DEBOUNCE_PERIOD;
367
368         plat->settle_time = TC_KPD_SETTLE_TIME;
369         /* FIXME: should be property of the IRQ resource? */
370         plat->irqtype = IRQF_TRIGGER_FALLING;
371
372         return plat;
373 }
374
375 static int tc3589x_keypad_probe(struct platform_device *pdev)
376 {
377         struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
378         struct tc_keypad *keypad;
379         struct input_dev *input;
380         const struct tc3589x_keypad_platform_data *plat;
381         int error, irq;
382
383         plat = tc3589x_keypad_of_probe(&pdev->dev);
384         if (IS_ERR(plat)) {
385                 dev_err(&pdev->dev, "invalid keypad platform data\n");
386                 return PTR_ERR(plat);
387         }
388
389         irq = platform_get_irq(pdev, 0);
390         if (irq < 0)
391                 return irq;
392
393         keypad = devm_kzalloc(&pdev->dev, sizeof(struct tc_keypad),
394                               GFP_KERNEL);
395         if (!keypad)
396                 return -ENOMEM;
397
398         input = devm_input_allocate_device(&pdev->dev);
399         if (!input) {
400                 dev_err(&pdev->dev, "failed to allocate input device\n");
401                 return -ENOMEM;
402         }
403
404         keypad->board = plat;
405         keypad->input = input;
406         keypad->tc3589x = tc3589x;
407
408         input->id.bustype = BUS_I2C;
409         input->name = pdev->name;
410         input->dev.parent = &pdev->dev;
411
412         input->open = tc3589x_keypad_open;
413         input->close = tc3589x_keypad_close;
414
415         error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
416                                            TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL,
417                                            NULL, input);
418         if (error) {
419                 dev_err(&pdev->dev, "Failed to build keymap\n");
420                 return error;
421         }
422
423         keypad->keymap = input->keycode;
424
425         input_set_capability(input, EV_MSC, MSC_SCAN);
426         if (!plat->no_autorepeat)
427                 __set_bit(EV_REP, input->evbit);
428
429         input_set_drvdata(input, keypad);
430
431         tc3589x_keypad_disable(keypad);
432
433         error = devm_request_threaded_irq(&pdev->dev, irq,
434                                           NULL, tc3589x_keypad_irq,
435                                           plat->irqtype | IRQF_ONESHOT,
436                                           "tc3589x-keypad", keypad);
437         if (error) {
438                 dev_err(&pdev->dev,
439                                 "Could not allocate irq %d,error %d\n",
440                                 irq, error);
441                 return error;
442         }
443
444         error = input_register_device(input);
445         if (error) {
446                 dev_err(&pdev->dev, "Could not register input device\n");
447                 return error;
448         }
449
450         /* let platform decide if keypad is a wakeup source or not */
451         device_init_wakeup(&pdev->dev, plat->enable_wakeup);
452         device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup);
453
454         platform_set_drvdata(pdev, keypad);
455
456         return 0;
457 }
458
459 #ifdef CONFIG_PM_SLEEP
460 static int tc3589x_keypad_suspend(struct device *dev)
461 {
462         struct platform_device *pdev = to_platform_device(dev);
463         struct tc_keypad *keypad = platform_get_drvdata(pdev);
464         int irq = platform_get_irq(pdev, 0);
465
466         /* keypad is already off; we do nothing */
467         if (keypad->keypad_stopped)
468                 return 0;
469
470         /* if device is not a wakeup source, disable it for powersave */
471         if (!device_may_wakeup(&pdev->dev))
472                 tc3589x_keypad_disable(keypad);
473         else
474                 enable_irq_wake(irq);
475
476         return 0;
477 }
478
479 static int tc3589x_keypad_resume(struct device *dev)
480 {
481         struct platform_device *pdev = to_platform_device(dev);
482         struct tc_keypad *keypad = platform_get_drvdata(pdev);
483         int irq = platform_get_irq(pdev, 0);
484
485         if (!keypad->keypad_stopped)
486                 return 0;
487
488         /* enable the device to resume normal operations */
489         if (!device_may_wakeup(&pdev->dev))
490                 tc3589x_keypad_enable(keypad);
491         else
492                 disable_irq_wake(irq);
493
494         return 0;
495 }
496 #endif
497
498 static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops,
499                          tc3589x_keypad_suspend, tc3589x_keypad_resume);
500
501 static struct platform_driver tc3589x_keypad_driver = {
502         .driver = {
503                 .name   = "tc3589x-keypad",
504                 .pm     = &tc3589x_keypad_dev_pm_ops,
505         },
506         .probe  = tc3589x_keypad_probe,
507 };
508 module_platform_driver(tc3589x_keypad_driver);
509
510 MODULE_LICENSE("GPL v2");
511 MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer");
512 MODULE_DESCRIPTION("TC35893 Keypad Driver");
513 MODULE_ALIAS("platform:tc3589x-keypad");