]> err.no Git - linux-2.6/blob - drivers/input/keyboard/pxa27x_keypad.c
Input: pxa27x_keypad - introduce driver structure and use KEY() to define matrix...
[linux-2.6] / drivers / input / keyboard / pxa27x_keypad.c
1 /*
2  * linux/drivers/input/keyboard/pxa27x_keypad.c
3  *
4  * Driver for the pxa27x matrix keyboard controller.
5  *
6  * Created:     Feb 22, 2007
7  * Author:      Rodolfo Giometti <giometti@linux.it>
8  *
9  * Based on a previous implementations by Kevin O'Connor
10  * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and
11  * on some suggestions by Nicolas Pitre <nico@cam.org>.
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2 as
15  * published by the Free Software Foundation.
16  */
17
18
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/interrupt.h>
23 #include <linux/input.h>
24 #include <linux/device.h>
25 #include <linux/platform_device.h>
26 #include <linux/clk.h>
27 #include <linux/err.h>
28
29 #include <asm/mach-types.h>
30 #include <asm/mach/arch.h>
31 #include <asm/mach/map.h>
32
33 #include <asm/arch/hardware.h>
34 #include <asm/arch/pxa-regs.h>
35 #include <asm/arch/irqs.h>
36 #include <asm/arch/pxa27x_keypad.h>
37
38 #define DRIVER_NAME             "pxa27x-keypad"
39
40 #define KPAS_MUKP(n)            (((n) >> 26) & 0x1f)
41 #define KPAS_RP(n)              (((n) >> 4) & 0xf)
42 #define KPAS_CP(n)              ((n) & 0xf)
43
44 #define KPASMKP_MKC_MASK        (0xff)
45
46 #define MAX_MATRIX_KEY_NUM      (8 * 8)
47
48 struct pxa27x_keypad {
49         struct pxa27x_keypad_platform_data *pdata;
50
51         struct clk *clk;
52         struct input_dev *input_dev;
53
54         /* matrix key code map */
55         unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
56
57         /* state row bits of each column scan */
58         uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
59 };
60
61 static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
62 {
63         struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
64         struct input_dev *input_dev = keypad->input_dev;
65         unsigned int *key;
66         int i;
67
68         key = &pdata->matrix_key_map[0];
69         for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
70                 int row = ((*key) >> 28) & 0xf;
71                 int col = ((*key) >> 24) & 0xf;
72                 int code = (*key) & 0xffffff;
73
74                 keypad->matrix_keycodes[(row << 3) + col] = code;
75                 set_bit(code, input_dev->keybit);
76         }
77 }
78
79 static inline unsigned int lookup_matrix_keycode(
80                 struct pxa27x_keypad *keypad, int row, int col)
81 {
82         return keypad->matrix_keycodes[(row << 3) + col];
83 }
84
85 static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
86 {
87         struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
88         int row, col, num_keys_pressed = 0;
89         uint32_t new_state[MAX_MATRIX_KEY_COLS];
90         uint32_t kpas = KPAS;
91
92         num_keys_pressed = KPAS_MUKP(kpas);
93
94         memset(new_state, 0, sizeof(new_state));
95
96         if (num_keys_pressed == 0)
97                 goto scan;
98
99         if (num_keys_pressed == 1) {
100                 col = KPAS_CP(kpas);
101                 row = KPAS_RP(kpas);
102
103                 /* if invalid row/col, treat as no key pressed */
104                 if (col >= pdata->matrix_key_cols ||
105                     row >= pdata->matrix_key_rows)
106                         goto scan;
107
108                 new_state[col] = (1 << row);
109                 goto scan;
110         }
111
112         if (num_keys_pressed > 1) {
113                 uint32_t kpasmkp0 = KPASMKP0;
114                 uint32_t kpasmkp1 = KPASMKP1;
115                 uint32_t kpasmkp2 = KPASMKP2;
116                 uint32_t kpasmkp3 = KPASMKP3;
117
118                 new_state[0] = kpasmkp0 & KPASMKP_MKC_MASK;
119                 new_state[1] = (kpasmkp0 >> 16) & KPASMKP_MKC_MASK;
120                 new_state[2] = kpasmkp1 & KPASMKP_MKC_MASK;
121                 new_state[3] = (kpasmkp1 >> 16) & KPASMKP_MKC_MASK;
122                 new_state[4] = kpasmkp2 & KPASMKP_MKC_MASK;
123                 new_state[5] = (kpasmkp2 >> 16) & KPASMKP_MKC_MASK;
124                 new_state[6] = kpasmkp3 & KPASMKP_MKC_MASK;
125                 new_state[7] = (kpasmkp3 >> 16) & KPASMKP_MKC_MASK;
126         }
127 scan:
128         for (col = 0; col < pdata->matrix_key_cols; col++) {
129                 uint32_t bits_changed;
130
131                 bits_changed = keypad->matrix_key_state[col] ^ new_state[col];
132                 if (bits_changed == 0)
133                         continue;
134
135                 for (row = 0; row < pdata->matrix_key_rows; row++) {
136                         if ((bits_changed & (1 << row)) == 0)
137                                 continue;
138
139                         input_report_key(keypad->input_dev,
140                                 lookup_matrix_keycode(keypad, row, col),
141                                 new_state[col] & (1 << row));
142                 }
143         }
144         input_sync(keypad->input_dev);
145         memcpy(keypad->matrix_key_state, new_state, sizeof(new_state));
146 }
147
148 static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
149 {
150         struct pxa27x_keypad *keypad = dev_id;
151         struct input_dev *input_dev = keypad->input_dev;
152         unsigned long kpc = KPC;
153         int rel;
154
155         if (kpc & KPC_DI) {
156                 unsigned long kpdk = KPDK;
157
158                 if (!(kpdk & KPDK_DKP)) {
159                         /* better luck next time */
160                 } else if (kpc & KPC_REE0) {
161                         unsigned long kprec = KPREC;
162                         KPREC = 0x7f;
163
164                         if (kprec & KPREC_OF0)
165                                 rel = (kprec & 0xff) + 0x7f;
166                         else if (kprec & KPREC_UF0)
167                                 rel = (kprec & 0xff) - 0x7f - 0xff;
168                         else
169                                 rel = (kprec & 0xff) - 0x7f;
170
171                         if (rel) {
172                                 input_report_rel(input_dev, REL_WHEEL, rel);
173                                 input_sync(input_dev);
174                         }
175                 }
176         }
177
178         if (kpc & KPC_MI)
179                 pxa27x_keypad_scan_matrix(keypad);
180
181         return IRQ_HANDLED;
182 }
183
184 static int pxa27x_keypad_open(struct input_dev *dev)
185 {
186         struct pxa27x_keypad *keypad = input_get_drvdata(dev);
187
188         /* Set keypad control register */
189         KPC |= (KPC_ASACT |
190                 KPC_MS_ALL |
191                 (2 << 6) | KPC_REE0 | KPC_DK_DEB_SEL |
192                 KPC_ME | KPC_MIE | KPC_DE | KPC_DIE);
193
194         KPC &= ~KPC_AS;         /* disable automatic scan */
195         KPC &= ~KPC_IMKP;       /* do not ignore multiple keypresses */
196
197         /* Set rotary count to mid-point value */
198         KPREC = 0x7F;
199
200         /* Enable unit clock */
201         clk_enable(keypad->clk);
202
203         return 0;
204 }
205
206 static void pxa27x_keypad_close(struct input_dev *dev)
207 {
208         struct pxa27x_keypad *keypad = input_get_drvdata(dev);
209
210         /* Disable clock unit */
211         clk_disable(keypad->clk);
212 }
213
214 #ifdef CONFIG_PM
215 static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state)
216 {
217         struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
218         struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
219
220         /* Save controller status */
221         pdata->reg_kpc = KPC;
222         pdata->reg_kprec = KPREC;
223
224         return 0;
225 }
226
227 static int pxa27x_keypad_resume(struct platform_device *pdev)
228 {
229         struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
230         struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
231         struct input_dev *input_dev = keypad->input_dev;
232
233         mutex_lock(&input_dev->mutex);
234
235         if (input_dev->users) {
236                 /* Restore controller status */
237                 KPC = pdata->reg_kpc;
238                 KPREC = pdata->reg_kprec;
239
240                 /* Enable unit clock */
241                 clk_enable(keypad->clk);
242         }
243
244         mutex_unlock(&input_dev->mutex);
245
246         return 0;
247 }
248 #else
249 #define pxa27x_keypad_suspend   NULL
250 #define pxa27x_keypad_resume    NULL
251 #endif
252
253 static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
254 {
255         struct pxa27x_keypad *keypad;
256         struct input_dev *input_dev;
257         int col, error;
258
259         keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
260         if (keypad == NULL) {
261                 dev_err(&pdev->dev, "failed to allocate driver data\n");
262                 return -ENOMEM;
263         }
264
265         keypad->pdata = pdev->dev.platform_data;
266         if (keypad->pdata == NULL) {
267                 dev_err(&pdev->dev, "no platform data defined\n");
268                 error = -EINVAL;
269                 goto failed_free;
270         }
271
272         keypad->clk = clk_get(&pdev->dev, "KBDCLK");
273         if (IS_ERR(keypad->clk)) {
274                 dev_err(&pdev->dev, "failed to get keypad clock\n");
275                 error = PTR_ERR(keypad->clk);
276                 goto failed_free;
277         }
278
279         /* Create and register the input driver. */
280         input_dev = input_allocate_device();
281         if (!input_dev) {
282                 dev_err(&pdev->dev, "failed to allocate input device\n");
283                 error = -ENOMEM;
284                 goto failed_put_clk;
285         }
286
287         input_dev->name = DRIVER_NAME;
288         input_dev->id.bustype = BUS_HOST;
289         input_dev->open = pxa27x_keypad_open;
290         input_dev->close = pxa27x_keypad_close;
291         input_dev->dev.parent = &pdev->dev;
292
293         keypad->input_dev = input_dev;
294         input_set_drvdata(input_dev, keypad);
295
296         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
297                 BIT_MASK(EV_REL);
298         input_dev->relbit[BIT_WORD(REL_WHEEL)] = BIT_MASK(REL_WHEEL);
299
300         pxa27x_keypad_build_keycode(keypad);
301
302         error = request_irq(IRQ_KEYPAD, pxa27x_keypad_irq_handler, IRQF_DISABLED,
303                             DRIVER_NAME, keypad);
304         if (error) {
305                 printk(KERN_ERR "Cannot request keypad IRQ\n");
306                 goto err_free_dev;
307         }
308
309         platform_set_drvdata(pdev, keypad);
310
311         /* Register the input device */
312         error = input_register_device(input_dev);
313         if (error)
314                 goto err_free_irq;
315
316         /*
317          * Store rows/cols info into keyboard registers.
318          */
319
320         KPC |= (keypad->pdata->matrix_key_rows - 1) << 26;
321         KPC |= (keypad->pdata->matrix_key_cols - 1) << 23;
322
323         for (col = 0; col < keypad->pdata->matrix_key_cols; col++)
324                 KPC |= KPC_MS0 << col;
325
326         return 0;
327
328  err_free_irq:
329         platform_set_drvdata(pdev, NULL);
330         free_irq(IRQ_KEYPAD, pdev);
331  err_free_dev:
332         input_free_device(input_dev);
333 failed_put_clk:
334         clk_put(keypad->clk);
335 failed_free:
336         kfree(keypad);
337         return error;
338 }
339
340 static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
341 {
342         struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
343
344         free_irq(IRQ_KEYPAD, pdev);
345
346         clk_disable(keypad->clk);
347         clk_put(keypad->clk);
348
349         input_unregister_device(keypad->input_dev);
350
351         platform_set_drvdata(pdev, NULL);
352         kfree(keypad);
353         return 0;
354 }
355
356 static struct platform_driver pxa27x_keypad_driver = {
357         .probe          = pxa27x_keypad_probe,
358         .remove         = __devexit_p(pxa27x_keypad_remove),
359         .suspend        = pxa27x_keypad_suspend,
360         .resume         = pxa27x_keypad_resume,
361         .driver         = {
362                 .name   = DRIVER_NAME,
363         },
364 };
365
366 static int __init pxa27x_keypad_init(void)
367 {
368         return platform_driver_register(&pxa27x_keypad_driver);
369 }
370
371 static void __exit pxa27x_keypad_exit(void)
372 {
373         platform_driver_unregister(&pxa27x_keypad_driver);
374 }
375
376 module_init(pxa27x_keypad_init);
377 module_exit(pxa27x_keypad_exit);
378
379 MODULE_DESCRIPTION("PXA27x Keypad Controller Driver");
380 MODULE_LICENSE("GPL");