]> Pileus Git - ~andy/linux/blob - drivers/input/keyboard/pxa27x_keypad.c
e9d4e227a009a4cb8a7481864b31f7695970a052
[~andy/linux] / 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 KPC_MKRN(n)     ((((n) & 0x7) - 1) << 26) /* matrix key row number */
41 #define KPC_MKCN(n)     ((((n) & 0x7) - 1) << 23) /* matrix key column number */
42 #define KPC_DKN(n)      ((((n) & 0x7) - 1) << 6)  /* direct key number */
43
44 #define KPAS_MUKP(n)            (((n) >> 26) & 0x1f)
45 #define KPAS_RP(n)              (((n) >> 4) & 0xf)
46 #define KPAS_CP(n)              ((n) & 0xf)
47
48 #define KPASMKP_MKC_MASK        (0xff)
49
50 #define MAX_MATRIX_KEY_NUM      (8 * 8)
51
52 struct pxa27x_keypad {
53         struct pxa27x_keypad_platform_data *pdata;
54
55         struct clk *clk;
56         struct input_dev *input_dev;
57
58         /* matrix key code map */
59         unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
60
61         /* state row bits of each column scan */
62         uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
63 };
64
65 static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
66 {
67         struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
68         struct input_dev *input_dev = keypad->input_dev;
69         unsigned int *key;
70         int i;
71
72         key = &pdata->matrix_key_map[0];
73         for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
74                 int row = ((*key) >> 28) & 0xf;
75                 int col = ((*key) >> 24) & 0xf;
76                 int code = (*key) & 0xffffff;
77
78                 keypad->matrix_keycodes[(row << 3) + col] = code;
79                 set_bit(code, input_dev->keybit);
80         }
81 }
82
83 static inline unsigned int lookup_matrix_keycode(
84                 struct pxa27x_keypad *keypad, int row, int col)
85 {
86         return keypad->matrix_keycodes[(row << 3) + col];
87 }
88
89 static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
90 {
91         struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
92         int row, col, num_keys_pressed = 0;
93         uint32_t new_state[MAX_MATRIX_KEY_COLS];
94         uint32_t kpas = KPAS;
95
96         num_keys_pressed = KPAS_MUKP(kpas);
97
98         memset(new_state, 0, sizeof(new_state));
99
100         if (num_keys_pressed == 0)
101                 goto scan;
102
103         if (num_keys_pressed == 1) {
104                 col = KPAS_CP(kpas);
105                 row = KPAS_RP(kpas);
106
107                 /* if invalid row/col, treat as no key pressed */
108                 if (col >= pdata->matrix_key_cols ||
109                     row >= pdata->matrix_key_rows)
110                         goto scan;
111
112                 new_state[col] = (1 << row);
113                 goto scan;
114         }
115
116         if (num_keys_pressed > 1) {
117                 uint32_t kpasmkp0 = KPASMKP0;
118                 uint32_t kpasmkp1 = KPASMKP1;
119                 uint32_t kpasmkp2 = KPASMKP2;
120                 uint32_t kpasmkp3 = KPASMKP3;
121
122                 new_state[0] = kpasmkp0 & KPASMKP_MKC_MASK;
123                 new_state[1] = (kpasmkp0 >> 16) & KPASMKP_MKC_MASK;
124                 new_state[2] = kpasmkp1 & KPASMKP_MKC_MASK;
125                 new_state[3] = (kpasmkp1 >> 16) & KPASMKP_MKC_MASK;
126                 new_state[4] = kpasmkp2 & KPASMKP_MKC_MASK;
127                 new_state[5] = (kpasmkp2 >> 16) & KPASMKP_MKC_MASK;
128                 new_state[6] = kpasmkp3 & KPASMKP_MKC_MASK;
129                 new_state[7] = (kpasmkp3 >> 16) & KPASMKP_MKC_MASK;
130         }
131 scan:
132         for (col = 0; col < pdata->matrix_key_cols; col++) {
133                 uint32_t bits_changed;
134
135                 bits_changed = keypad->matrix_key_state[col] ^ new_state[col];
136                 if (bits_changed == 0)
137                         continue;
138
139                 for (row = 0; row < pdata->matrix_key_rows; row++) {
140                         if ((bits_changed & (1 << row)) == 0)
141                                 continue;
142
143                         input_report_key(keypad->input_dev,
144                                 lookup_matrix_keycode(keypad, row, col),
145                                 new_state[col] & (1 << row));
146                 }
147         }
148         input_sync(keypad->input_dev);
149         memcpy(keypad->matrix_key_state, new_state, sizeof(new_state));
150 }
151
152 #define DEFAULT_KPREC   (0x007f007f)
153
154 static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
155 {
156         struct pxa27x_keypad *keypad = dev_id;
157         struct input_dev *input_dev = keypad->input_dev;
158         unsigned long kpc = KPC;
159         int rel;
160
161         if (kpc & KPC_DI) {
162                 unsigned long kpdk = KPDK;
163
164                 if (!(kpdk & KPDK_DKP)) {
165                         /* better luck next time */
166                 } else if (kpc & KPC_REE0) {
167                         unsigned long kprec = KPREC;
168                         KPREC = 0x7f;
169
170                         if (kprec & KPREC_OF0)
171                                 rel = (kprec & 0xff) + 0x7f;
172                         else if (kprec & KPREC_UF0)
173                                 rel = (kprec & 0xff) - 0x7f - 0xff;
174                         else
175                                 rel = (kprec & 0xff) - 0x7f;
176
177                         if (rel) {
178                                 input_report_rel(input_dev, REL_WHEEL, rel);
179                                 input_sync(input_dev);
180                         }
181                 }
182         }
183
184         if (kpc & KPC_MI)
185                 pxa27x_keypad_scan_matrix(keypad);
186
187         return IRQ_HANDLED;
188 }
189
190 static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
191 {
192         struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
193         unsigned long kpc = 0;
194
195         /* enable matrix keys with automatic scan */
196         if (pdata->matrix_key_rows && pdata->matrix_key_cols) {
197                 kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL;
198                 kpc |= KPC_MKRN(pdata->matrix_key_rows) |
199                        KPC_MKCN(pdata->matrix_key_cols);
200         }
201
202         /* FIXME: hardcoded to enable rotary 0 _only_ */
203         kpc |= KPC_DKN(2) | KPC_REE0 | KPC_DI | KPC_DIE;
204
205         KPC = kpc;
206         KPREC = DEFAULT_KPREC;
207 }
208
209 static int pxa27x_keypad_open(struct input_dev *dev)
210 {
211         struct pxa27x_keypad *keypad = input_get_drvdata(dev);
212
213         /* Enable unit clock */
214         clk_enable(keypad->clk);
215         pxa27x_keypad_config(keypad);
216
217         return 0;
218 }
219
220 static void pxa27x_keypad_close(struct input_dev *dev)
221 {
222         struct pxa27x_keypad *keypad = input_get_drvdata(dev);
223
224         /* Disable clock unit */
225         clk_disable(keypad->clk);
226 }
227
228 #ifdef CONFIG_PM
229 static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state)
230 {
231         struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
232
233         clk_disable(keypad->clk);
234         return 0;
235 }
236
237 static int pxa27x_keypad_resume(struct platform_device *pdev)
238 {
239         struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
240         struct input_dev *input_dev = keypad->input_dev;
241
242         mutex_lock(&input_dev->mutex);
243
244         if (input_dev->users) {
245                 /* Enable unit clock */
246                 clk_enable(keypad->clk);
247                 pxa27x_keypad_config(keypad);
248         }
249
250         mutex_unlock(&input_dev->mutex);
251
252         return 0;
253 }
254 #else
255 #define pxa27x_keypad_suspend   NULL
256 #define pxa27x_keypad_resume    NULL
257 #endif
258
259 static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
260 {
261         struct pxa27x_keypad *keypad;
262         struct input_dev *input_dev;
263         int error;
264
265         keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
266         if (keypad == NULL) {
267                 dev_err(&pdev->dev, "failed to allocate driver data\n");
268                 return -ENOMEM;
269         }
270
271         keypad->pdata = pdev->dev.platform_data;
272         if (keypad->pdata == NULL) {
273                 dev_err(&pdev->dev, "no platform data defined\n");
274                 error = -EINVAL;
275                 goto failed_free;
276         }
277
278         keypad->clk = clk_get(&pdev->dev, "KBDCLK");
279         if (IS_ERR(keypad->clk)) {
280                 dev_err(&pdev->dev, "failed to get keypad clock\n");
281                 error = PTR_ERR(keypad->clk);
282                 goto failed_free;
283         }
284
285         /* Create and register the input driver. */
286         input_dev = input_allocate_device();
287         if (!input_dev) {
288                 dev_err(&pdev->dev, "failed to allocate input device\n");
289                 error = -ENOMEM;
290                 goto failed_put_clk;
291         }
292
293         input_dev->name = DRIVER_NAME;
294         input_dev->id.bustype = BUS_HOST;
295         input_dev->open = pxa27x_keypad_open;
296         input_dev->close = pxa27x_keypad_close;
297         input_dev->dev.parent = &pdev->dev;
298
299         keypad->input_dev = input_dev;
300         input_set_drvdata(input_dev, keypad);
301
302         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
303                 BIT_MASK(EV_REL);
304         input_dev->relbit[BIT_WORD(REL_WHEEL)] = BIT_MASK(REL_WHEEL);
305
306         pxa27x_keypad_build_keycode(keypad);
307
308         error = request_irq(IRQ_KEYPAD, pxa27x_keypad_irq_handler, IRQF_DISABLED,
309                             DRIVER_NAME, keypad);
310         if (error) {
311                 printk(KERN_ERR "Cannot request keypad IRQ\n");
312                 goto err_free_dev;
313         }
314
315         platform_set_drvdata(pdev, keypad);
316
317         /* Register the input device */
318         error = input_register_device(input_dev);
319         if (error)
320                 goto err_free_irq;
321
322         return 0;
323
324  err_free_irq:
325         platform_set_drvdata(pdev, NULL);
326         free_irq(IRQ_KEYPAD, pdev);
327  err_free_dev:
328         input_free_device(input_dev);
329 failed_put_clk:
330         clk_put(keypad->clk);
331 failed_free:
332         kfree(keypad);
333         return error;
334 }
335
336 static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
337 {
338         struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
339
340         free_irq(IRQ_KEYPAD, pdev);
341
342         clk_disable(keypad->clk);
343         clk_put(keypad->clk);
344
345         input_unregister_device(keypad->input_dev);
346
347         platform_set_drvdata(pdev, NULL);
348         kfree(keypad);
349         return 0;
350 }
351
352 static struct platform_driver pxa27x_keypad_driver = {
353         .probe          = pxa27x_keypad_probe,
354         .remove         = __devexit_p(pxa27x_keypad_remove),
355         .suspend        = pxa27x_keypad_suspend,
356         .resume         = pxa27x_keypad_resume,
357         .driver         = {
358                 .name   = DRIVER_NAME,
359         },
360 };
361
362 static int __init pxa27x_keypad_init(void)
363 {
364         return platform_driver_register(&pxa27x_keypad_driver);
365 }
366
367 static void __exit pxa27x_keypad_exit(void)
368 {
369         platform_driver_unregister(&pxa27x_keypad_driver);
370 }
371
372 module_init(pxa27x_keypad_init);
373 module_exit(pxa27x_keypad_exit);
374
375 MODULE_DESCRIPTION("PXA27x Keypad Controller Driver");
376 MODULE_LICENSE("GPL");