]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/input/keyboard/nomadik-ske-keypad.c
Merge branches 'iommu/fixes', 'dma-debug', 'x86/amd', 'x86/vt-d', 'arm/tegra' and...
[karo-tx-linux.git] / drivers / input / keyboard / nomadik-ske-keypad.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2010
3  *
4  * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
5  * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
6  *
7  * License terms:GNU General Public License (GPL) version 2
8  *
9  * Keypad controller driver for the SKE (Scroll Key Encoder) module used in
10  * the Nomadik 8815 and Ux500 platforms.
11  */
12
13 #include <linux/platform_device.h>
14 #include <linux/interrupt.h>
15 #include <linux/spinlock.h>
16 #include <linux/io.h>
17 #include <linux/delay.h>
18 #include <linux/input.h>
19 #include <linux/slab.h>
20 #include <linux/clk.h>
21 #include <linux/module.h>
22
23 #include <linux/platform_data/keypad-nomadik-ske.h>
24
25 /* SKE_CR bits */
26 #define SKE_KPMLT       (0x1 << 6)
27 #define SKE_KPCN        (0x7 << 3)
28 #define SKE_KPASEN      (0x1 << 2)
29 #define SKE_KPASON      (0x1 << 7)
30
31 /* SKE_IMSC bits */
32 #define SKE_KPIMA       (0x1 << 2)
33
34 /* SKE_ICR bits */
35 #define SKE_KPICS       (0x1 << 3)
36 #define SKE_KPICA       (0x1 << 2)
37
38 /* SKE_RIS bits */
39 #define SKE_KPRISA      (0x1 << 2)
40
41 #define SKE_KEYPAD_ROW_SHIFT    3
42 #define SKE_KPD_NUM_ROWS        8
43 #define SKE_KPD_NUM_COLS        8
44
45 /* keypad auto scan registers */
46 #define SKE_ASR0        0x20
47 #define SKE_ASR1        0x24
48 #define SKE_ASR2        0x28
49 #define SKE_ASR3        0x2C
50
51 #define SKE_NUM_ASRX_REGISTERS  (4)
52 #define KEY_PRESSED_DELAY       10
53
54 /**
55  * struct ske_keypad  - data structure used by keypad driver
56  * @irq:        irq no
57  * @reg_base:   ske regsiters base address
58  * @input:      pointer to input device object
59  * @board:      keypad platform device
60  * @keymap:     matrix scan code table for keycodes
61  * @clk:        clock structure pointer
62  */
63 struct ske_keypad {
64         int irq;
65         void __iomem *reg_base;
66         struct input_dev *input;
67         const struct ske_keypad_platform_data *board;
68         unsigned short keymap[SKE_KPD_NUM_ROWS * SKE_KPD_NUM_COLS];
69         struct clk *clk;
70         spinlock_t ske_keypad_lock;
71 };
72
73 static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr,
74                 u8 mask, u8 data)
75 {
76         u32 ret;
77
78         spin_lock(&keypad->ske_keypad_lock);
79
80         ret = readl(keypad->reg_base + addr);
81         ret &= ~mask;
82         ret |= data;
83         writel(ret, keypad->reg_base + addr);
84
85         spin_unlock(&keypad->ske_keypad_lock);
86 }
87
88 /*
89  * ske_keypad_chip_init: init keypad controller configuration
90  *
91  * Enable Multi key press detection, auto scan mode
92  */
93 static int __init ske_keypad_chip_init(struct ske_keypad *keypad)
94 {
95         u32 value;
96         int timeout = keypad->board->debounce_ms;
97
98         /* check SKE_RIS to be 0 */
99         while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--)
100                 cpu_relax();
101
102         if (!timeout)
103                 return -EINVAL;
104
105         /*
106          * set debounce value
107          * keypad dbounce is configured in DBCR[15:8]
108          * dbounce value in steps of 32/32.768 ms
109          */
110         spin_lock(&keypad->ske_keypad_lock);
111         value = readl(keypad->reg_base + SKE_DBCR);
112         value = value & 0xff;
113         value |= ((keypad->board->debounce_ms * 32000)/32768) << 8;
114         writel(value, keypad->reg_base + SKE_DBCR);
115         spin_unlock(&keypad->ske_keypad_lock);
116
117         /* enable multi key detection */
118         ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPMLT);
119
120         /*
121          * set up the number of columns
122          * KPCN[5:3] defines no. of keypad columns to be auto scanned
123          */
124         value = (keypad->board->kcol - 1) << 3;
125         ske_keypad_set_bits(keypad, SKE_CR, SKE_KPCN, value);
126
127         /* clear keypad interrupt for auto(and pending SW) scans */
128         ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA | SKE_KPICS);
129
130         /* un-mask keypad interrupts */
131         ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
132
133         /* enable automatic scan */
134         ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPASEN);
135
136         return 0;
137 }
138
139 static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col)
140 {
141         int row = 0, code, pos;
142         struct input_dev *input = keypad->input;
143         u32 ske_ris;
144         int key_pressed;
145         int num_of_rows;
146
147         /* find out the row */
148         num_of_rows = hweight8(status);
149         do {
150                 pos = __ffs(status);
151                 row = pos;
152                 status &= ~(1 << pos);
153
154                 code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
155                 ske_ris = readl(keypad->reg_base + SKE_RIS);
156                 key_pressed = ske_ris & SKE_KPRISA;
157
158                 input_event(input, EV_MSC, MSC_SCAN, code);
159                 input_report_key(input, keypad->keymap[code], key_pressed);
160                 input_sync(input);
161                 num_of_rows--;
162         } while (num_of_rows);
163 }
164
165 static void ske_keypad_read_data(struct ske_keypad *keypad)
166 {
167         u8 status;
168         int col = 0;
169         int ske_asr, i;
170
171         /*
172          * Read the auto scan registers
173          *
174          * Each SKE_ASRx (x=0 to x=3) contains two row values.
175          * lower byte contains row value for column 2*x,
176          * upper byte contains row value for column 2*x + 1
177          */
178         for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) {
179                 ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i));
180                 if (!ske_asr)
181                         continue;
182
183                 /* now that ASRx is zero, find out the coloumn x and row y */
184                 status = ske_asr & 0xff;
185                 if (status) {
186                         col = i * 2;
187                         ske_keypad_report(keypad, status, col);
188                 }
189                 status = (ske_asr & 0xff00) >> 8;
190                 if (status) {
191                         col = (i * 2) + 1;
192                         ske_keypad_report(keypad, status, col);
193                 }
194         }
195 }
196
197 static irqreturn_t ske_keypad_irq(int irq, void *dev_id)
198 {
199         struct ske_keypad *keypad = dev_id;
200         int timeout = keypad->board->debounce_ms;
201
202         /* disable auto scan interrupt; mask the interrupt generated */
203         ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0);
204         ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA);
205
206         while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --timeout)
207                 cpu_relax();
208
209         /* SKEx registers are stable and can be read */
210         ske_keypad_read_data(keypad);
211
212         /* wait until raw interrupt is clear */
213         while ((readl(keypad->reg_base + SKE_RIS)) && --timeout)
214                 msleep(KEY_PRESSED_DELAY);
215
216         /* enable auto scan interrupts */
217         ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
218
219         return IRQ_HANDLED;
220 }
221
222 static int __init ske_keypad_probe(struct platform_device *pdev)
223 {
224         const struct ske_keypad_platform_data *plat = pdev->dev.platform_data;
225         struct ske_keypad *keypad;
226         struct input_dev *input;
227         struct resource *res;
228         int irq;
229         int error;
230
231         if (!plat) {
232                 dev_err(&pdev->dev, "invalid keypad platform data\n");
233                 return -EINVAL;
234         }
235
236         irq = platform_get_irq(pdev, 0);
237         if (irq < 0) {
238                 dev_err(&pdev->dev, "failed to get keypad irq\n");
239                 return -EINVAL;
240         }
241
242         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
243         if (!res) {
244                 dev_err(&pdev->dev, "missing platform resources\n");
245                 return -EINVAL;
246         }
247
248         keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL);
249         input = input_allocate_device();
250         if (!keypad || !input) {
251                 dev_err(&pdev->dev, "failed to allocate keypad memory\n");
252                 error = -ENOMEM;
253                 goto err_free_mem;
254         }
255
256         keypad->irq = irq;
257         keypad->board = plat;
258         keypad->input = input;
259         spin_lock_init(&keypad->ske_keypad_lock);
260
261         if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
262                 dev_err(&pdev->dev, "failed to request I/O memory\n");
263                 error = -EBUSY;
264                 goto err_free_mem;
265         }
266
267         keypad->reg_base = ioremap(res->start, resource_size(res));
268         if (!keypad->reg_base) {
269                 dev_err(&pdev->dev, "failed to remap I/O memory\n");
270                 error = -ENXIO;
271                 goto err_free_mem_region;
272         }
273
274         keypad->clk = clk_get(&pdev->dev, NULL);
275         if (IS_ERR(keypad->clk)) {
276                 dev_err(&pdev->dev, "failed to get clk\n");
277                 error = PTR_ERR(keypad->clk);
278                 goto err_iounmap;
279         }
280
281         input->id.bustype = BUS_HOST;
282         input->name = "ux500-ske-keypad";
283         input->dev.parent = &pdev->dev;
284
285         error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
286                                            SKE_KPD_NUM_ROWS, SKE_KPD_NUM_COLS,
287                                            keypad->keymap, input);
288         if (error) {
289                 dev_err(&pdev->dev, "Failed to build keymap\n");
290                 goto err_iounmap;
291         }
292
293         input_set_capability(input, EV_MSC, MSC_SCAN);
294         if (!plat->no_autorepeat)
295                 __set_bit(EV_REP, input->evbit);
296
297         clk_enable(keypad->clk);
298
299         /* go through board initialization helpers */
300         if (keypad->board->init)
301                 keypad->board->init();
302
303         error = ske_keypad_chip_init(keypad);
304         if (error) {
305                 dev_err(&pdev->dev, "unable to init keypad hardware\n");
306                 goto err_clk_disable;
307         }
308
309         error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq,
310                                      IRQF_ONESHOT, "ske-keypad", keypad);
311         if (error) {
312                 dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq);
313                 goto err_clk_disable;
314         }
315
316         error = input_register_device(input);
317         if (error) {
318                 dev_err(&pdev->dev,
319                                 "unable to register input device: %d\n", error);
320                 goto err_free_irq;
321         }
322
323         if (plat->wakeup_enable)
324                 device_init_wakeup(&pdev->dev, true);
325
326         platform_set_drvdata(pdev, keypad);
327
328         return 0;
329
330 err_free_irq:
331         free_irq(keypad->irq, keypad);
332 err_clk_disable:
333         clk_disable(keypad->clk);
334         clk_put(keypad->clk);
335 err_iounmap:
336         iounmap(keypad->reg_base);
337 err_free_mem_region:
338         release_mem_region(res->start, resource_size(res));
339 err_free_mem:
340         input_free_device(input);
341         kfree(keypad);
342         return error;
343 }
344
345 static int __devexit ske_keypad_remove(struct platform_device *pdev)
346 {
347         struct ske_keypad *keypad = platform_get_drvdata(pdev);
348         struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
349
350         free_irq(keypad->irq, keypad);
351
352         input_unregister_device(keypad->input);
353
354         clk_disable(keypad->clk);
355         clk_put(keypad->clk);
356
357         if (keypad->board->exit)
358                 keypad->board->exit();
359
360         iounmap(keypad->reg_base);
361         release_mem_region(res->start, resource_size(res));
362         kfree(keypad);
363
364         return 0;
365 }
366
367 #ifdef CONFIG_PM_SLEEP
368 static int ske_keypad_suspend(struct device *dev)
369 {
370         struct platform_device *pdev = to_platform_device(dev);
371         struct ske_keypad *keypad = platform_get_drvdata(pdev);
372         int irq = platform_get_irq(pdev, 0);
373
374         if (device_may_wakeup(dev))
375                 enable_irq_wake(irq);
376         else
377                 ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0);
378
379         return 0;
380 }
381
382 static int ske_keypad_resume(struct device *dev)
383 {
384         struct platform_device *pdev = to_platform_device(dev);
385         struct ske_keypad *keypad = platform_get_drvdata(pdev);
386         int irq = platform_get_irq(pdev, 0);
387
388         if (device_may_wakeup(dev))
389                 disable_irq_wake(irq);
390         else
391                 ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
392
393         return 0;
394 }
395 #endif
396
397 static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops,
398                          ske_keypad_suspend, ske_keypad_resume);
399
400 static struct platform_driver ske_keypad_driver = {
401         .driver = {
402                 .name = "nmk-ske-keypad",
403                 .owner  = THIS_MODULE,
404                 .pm = &ske_keypad_dev_pm_ops,
405         },
406         .remove = __devexit_p(ske_keypad_remove),
407 };
408
409 static int __init ske_keypad_init(void)
410 {
411         return platform_driver_probe(&ske_keypad_driver, ske_keypad_probe);
412 }
413 module_init(ske_keypad_init);
414
415 static void __exit ske_keypad_exit(void)
416 {
417         platform_driver_unregister(&ske_keypad_driver);
418 }
419 module_exit(ske_keypad_exit);
420
421 MODULE_LICENSE("GPL v2");
422 MODULE_AUTHOR("Naveen Kumar <naveen.gaddipati@stericsson.com> / Sundar Iyer <sundar.iyer@stericsson.com>");
423 MODULE_DESCRIPTION("Nomadik Scroll-Key-Encoder Keypad Driver");
424 MODULE_ALIAS("platform:nomadik-ske-keypad");