2 * Driver for the Cirrus EP93xx matrix keypad controller.
4 * Copyright (c) 2008 H Hartley Sweeten <hsweeten@visionengravers.com>
6 * Based on the pxa27x matrix keypad controller by Rodolfo Giometti.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 * The 3-key reset is triggered by pressing the 3 keys in
15 * Row 0, Columns 2, 4, and 7 at the same time. This action can
16 * be disabled by setting the EP93XX_KEYPAD_DISABLE_3_KEY flag.
18 * Normal operation for the matrix does not autorepeat the key press.
19 * This action can be enabled by setting the EP93XX_KEYPAD_AUTOREPEAT
23 #include <linux/platform_device.h>
24 #include <linux/interrupt.h>
25 #include <linux/input.h>
26 #include <linux/clk.h>
28 #include <mach/hardware.h>
29 #include <mach/gpio.h>
30 #include <mach/ep93xx_keypad.h>
33 * Keypad Interface Register offsets
35 #define KEY_INIT 0x00 /* Key Scan Initialization register */
36 #define KEY_DIAG 0x04 /* Key Scan Diagnostic register */
37 #define KEY_REG 0x08 /* Key Value Capture register */
39 /* Key Scan Initialization Register bit defines */
40 #define KEY_INIT_DBNC_MASK (0x00ff0000)
41 #define KEY_INIT_DBNC_SHIFT (16)
42 #define KEY_INIT_DIS3KY (1<<15)
43 #define KEY_INIT_DIAG (1<<14)
44 #define KEY_INIT_BACK (1<<13)
45 #define KEY_INIT_T2 (1<<12)
46 #define KEY_INIT_PRSCL_MASK (0x000003ff)
47 #define KEY_INIT_PRSCL_SHIFT (0)
49 /* Key Scan Diagnostic Register bit defines */
50 #define KEY_DIAG_MASK (0x0000003f)
51 #define KEY_DIAG_SHIFT (0)
53 /* Key Value Capture Register bit defines */
54 #define KEY_REG_K (1<<15)
55 #define KEY_REG_INT (1<<14)
56 #define KEY_REG_2KEYS (1<<13)
57 #define KEY_REG_1KEY (1<<12)
58 #define KEY_REG_KEY2_MASK (0x00000fc0)
59 #define KEY_REG_KEY2_SHIFT (6)
60 #define KEY_REG_KEY1_MASK (0x0000003f)
61 #define KEY_REG_KEY1_SHIFT (0)
63 #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off))
64 #define keypad_writel(v, off) __raw_writel((v), keypad->mmio_base + (off))
66 #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
68 struct ep93xx_keypad
{
69 struct ep93xx_keypad_platform_data
*pdata
;
72 struct input_dev
*input_dev
;
73 void __iomem
*mmio_base
;
81 unsigned int matrix_keycodes
[MAX_MATRIX_KEY_NUM
];
84 static void ep93xx_keypad_build_keycode(struct ep93xx_keypad
*keypad
)
86 struct ep93xx_keypad_platform_data
*pdata
= keypad
->pdata
;
87 struct input_dev
*input_dev
= keypad
->input_dev
;
90 for (i
= 0; i
< pdata
->matrix_key_map_size
; i
++) {
91 unsigned int key
= pdata
->matrix_key_map
[i
];
92 int row
= (key
>> 28) & 0xf;
93 int col
= (key
>> 24) & 0xf;
94 int code
= key
& 0xffffff;
96 keypad
->matrix_keycodes
[(row
<< 3) + col
] = code
;
97 __set_bit(code
, input_dev
->keybit
);
101 static irqreturn_t
ep93xx_keypad_irq_handler(int irq
, void *dev_id
)
103 struct ep93xx_keypad
*keypad
= dev_id
;
104 struct input_dev
*input_dev
= keypad
->input_dev
;
105 unsigned int status
= keypad_readl(KEY_REG
);
106 int keycode
, key1
, key2
;
108 keycode
= (status
& KEY_REG_KEY1_MASK
) >> KEY_REG_KEY1_SHIFT
;
109 key1
= keypad
->matrix_keycodes
[keycode
];
111 keycode
= (status
& KEY_REG_KEY2_MASK
) >> KEY_REG_KEY2_SHIFT
;
112 key2
= keypad
->matrix_keycodes
[keycode
];
114 if (status
& KEY_REG_2KEYS
) {
115 if (keypad
->key1
&& key1
!= keypad
->key1
&& key2
!= keypad
->key1
)
116 input_report_key(input_dev
, keypad
->key1
, 0);
118 if (keypad
->key2
&& key1
!= keypad
->key2
&& key2
!= keypad
->key2
)
119 input_report_key(input_dev
, keypad
->key2
, 0);
121 input_report_key(input_dev
, key1
, 1);
122 input_report_key(input_dev
, key2
, 1);
127 } else if (status
& KEY_REG_1KEY
) {
128 if (keypad
->key1
&& key1
!= keypad
->key1
)
129 input_report_key(input_dev
, keypad
->key1
, 0);
131 if (keypad
->key2
&& key1
!= keypad
->key2
)
132 input_report_key(input_dev
, keypad
->key2
, 0);
134 input_report_key(input_dev
, key1
, 1);
140 input_report_key(input_dev
, keypad
->key1
, 0);
141 input_report_key(input_dev
, keypad
->key2
, 0);
143 keypad
->key1
= keypad
->key2
= 0;
145 input_sync(input_dev
);
150 static void ep93xx_keypad_config(struct ep93xx_keypad
*keypad
)
152 struct ep93xx_keypad_platform_data
*pdata
= keypad
->pdata
;
153 unsigned int val
= 0;
155 clk_set_rate(keypad
->clk
, pdata
->flags
& EP93XX_KEYPAD_KDIV
);
157 if (pdata
->flags
& EP93XX_KEYPAD_DISABLE_3_KEY
)
158 val
|= KEY_INIT_DIS3KY
;
159 if (pdata
->flags
& EP93XX_KEYPAD_DIAG_MODE
)
160 val
|= KEY_INIT_DIAG
;
161 if (pdata
->flags
& EP93XX_KEYPAD_BACK_DRIVE
)
162 val
|= KEY_INIT_BACK
;
163 if (pdata
->flags
& EP93XX_KEYPAD_TEST_MODE
)
166 val
|= ((pdata
->debounce
<< KEY_INIT_DBNC_SHIFT
) & KEY_INIT_DBNC_MASK
);
168 val
|= ((pdata
->prescale
<< KEY_INIT_PRSCL_SHIFT
) & KEY_INIT_PRSCL_MASK
);
170 keypad_writel(val
, KEY_INIT
);
173 static int ep93xx_keypad_open(struct input_dev
*pdev
)
175 struct ep93xx_keypad
*keypad
= input_get_drvdata(pdev
);
177 if (!keypad
->enabled
) {
178 ep93xx_keypad_config(keypad
);
179 clk_enable(keypad
->clk
);
186 static void ep93xx_keypad_close(struct input_dev
*pdev
)
188 struct ep93xx_keypad
*keypad
= input_get_drvdata(pdev
);
190 if (keypad
->enabled
) {
191 clk_disable(keypad
->clk
);
199 * NOTE: I don't know if this is correct, or will work on the ep93xx.
201 * None of the existing ep93xx drivers have power management support.
202 * But, this is basically what the pxa27x_keypad driver does.
204 static int ep93xx_keypad_suspend(struct platform_device
*pdev
,
207 struct ep93xx_keypad
*keypad
= platform_get_drvdata(pdev
);
208 struct input_dev
*input_dev
= keypad
->input_dev
;
210 mutex_lock(&input_dev
->mutex
);
212 if (keypad
->enabled
) {
213 clk_disable(keypad
->clk
);
217 mutex_unlock(&input_dev
->mutex
);
219 if (device_may_wakeup(&pdev
->dev
))
220 enable_irq_wake(keypad
->irq
);
225 static int ep93xx_keypad_resume(struct platform_device
*pdev
)
227 struct ep93xx_keypad
*keypad
= platform_get_drvdata(pdev
);
228 struct input_dev
*input_dev
= keypad
->input_dev
;
230 if (device_may_wakeup(&pdev
->dev
))
231 disable_irq_wake(keypad
->irq
);
233 mutex_lock(&input_dev
->mutex
);
235 if (input_dev
->users
) {
236 if (!keypad
->enabled
) {
237 ep93xx_keypad_config(keypad
);
238 clk_enable(keypad
->clk
);
243 mutex_unlock(&input_dev
->mutex
);
247 #else /* !CONFIG_PM */
248 #define ep93xx_keypad_suspend NULL
249 #define ep93xx_keypad_resume NULL
250 #endif /* !CONFIG_PM */
252 static int __devinit
ep93xx_keypad_probe(struct platform_device
*pdev
)
254 struct ep93xx_keypad
*keypad
;
255 struct ep93xx_keypad_platform_data
*pdata
= pdev
->dev
.platform_data
;
256 struct input_dev
*input_dev
;
257 struct resource
*res
;
258 int irq
, err
, i
, gpio
;
261 !pdata
->matrix_key_rows
||
262 pdata
->matrix_key_rows
> MAX_MATRIX_KEY_ROWS
||
263 !pdata
->matrix_key_cols
||
264 pdata
->matrix_key_cols
> MAX_MATRIX_KEY_COLS
) {
265 dev_err(&pdev
->dev
, "invalid or missing platform data\n");
269 keypad
= kzalloc(sizeof(struct ep93xx_keypad
), GFP_KERNEL
);
271 dev_err(&pdev
->dev
, "failed to allocate driver data\n");
275 keypad
->pdata
= pdata
;
277 irq
= platform_get_irq(pdev
, 0);
279 dev_err(&pdev
->dev
, "failed to get keypad irq\n");
284 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
286 dev_err(&pdev
->dev
, "failed to get I/O memory\n");
291 res
= request_mem_region(res
->start
, resource_size(res
), pdev
->name
);
293 dev_err(&pdev
->dev
, "failed to request I/O memory\n");
298 keypad
->mmio_base
= ioremap(res
->start
, resource_size(res
));
299 if (keypad
->mmio_base
== NULL
) {
300 dev_err(&pdev
->dev
, "failed to remap I/O memory\n");
302 goto failed_free_mem
;
305 /* Request the needed GPIO's */
306 gpio
= EP93XX_GPIO_LINE_ROW0
;
307 for (i
= 0; i
< keypad
->pdata
->matrix_key_rows
; i
++, gpio
++) {
308 err
= gpio_request(gpio
, pdev
->name
);
310 dev_err(&pdev
->dev
, "failed to request gpio-%d\n",
312 goto failed_free_rows
;
316 gpio
= EP93XX_GPIO_LINE_COL0
;
317 for (i
= 0; i
< keypad
->pdata
->matrix_key_cols
; i
++, gpio
++) {
318 err
= gpio_request(gpio
, pdev
->name
);
320 dev_err(&pdev
->dev
, "failed to request gpio-%d\n",
322 goto failed_free_cols
;
326 keypad
->clk
= clk_get(&pdev
->dev
, "key_clk");
327 if (IS_ERR(keypad
->clk
)) {
328 dev_err(&pdev
->dev
, "failed to get keypad clock\n");
329 err
= PTR_ERR(keypad
->clk
);
333 /* Create and register the input driver */
334 input_dev
= input_allocate_device();
336 dev_err(&pdev
->dev
, "failed to allocate input device\n");
341 keypad
->input_dev
= input_dev
;
343 input_dev
->name
= pdev
->name
;
344 input_dev
->id
.bustype
= BUS_HOST
;
345 input_dev
->open
= ep93xx_keypad_open
;
346 input_dev
->close
= ep93xx_keypad_close
;
347 input_dev
->dev
.parent
= &pdev
->dev
;
348 input_dev
->keycode
= keypad
->matrix_keycodes
;
349 input_dev
->keycodesize
= sizeof(keypad
->matrix_keycodes
[0]);
350 input_dev
->keycodemax
= ARRAY_SIZE(keypad
->matrix_keycodes
);
352 input_set_drvdata(input_dev
, keypad
);
354 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
);
355 if (keypad
->pdata
->flags
& EP93XX_KEYPAD_AUTOREPEAT
)
356 input_dev
->evbit
[0] |= BIT_MASK(EV_REP
);
358 ep93xx_keypad_build_keycode(keypad
);
359 platform_set_drvdata(pdev
, keypad
);
361 err
= request_irq(irq
, ep93xx_keypad_irq_handler
, IRQF_DISABLED
,
364 dev_err(&pdev
->dev
, "failed to request IRQ\n");
365 goto failed_free_dev
;
370 /* Register the input device */
371 err
= input_register_device(input_dev
);
373 dev_err(&pdev
->dev
, "failed to register input device\n");
374 goto failed_free_irq
;
377 device_init_wakeup(&pdev
->dev
, 1);
383 platform_set_drvdata(pdev
, NULL
);
385 input_free_device(input_dev
);
387 clk_put(keypad
->clk
);
389 i
= keypad
->pdata
->matrix_key_cols
- 1;
390 gpio
= EP93XX_GPIO_LINE_COL0
+ i
;
392 for ( ; i
>= 0; i
--, gpio
--)
394 i
= keypad
->pdata
->matrix_key_rows
- 1;
395 gpio
= EP93XX_GPIO_LINE_ROW0
+ i
;
397 for ( ; i
>= 0; i
--, gpio
--)
399 iounmap(keypad
->mmio_base
);
401 release_mem_region(res
->start
, resource_size(res
));
407 static int __devexit
ep93xx_keypad_remove(struct platform_device
*pdev
)
409 struct ep93xx_keypad
*keypad
= platform_get_drvdata(pdev
);
410 struct resource
*res
;
413 free_irq(keypad
->irq
, pdev
);
415 platform_set_drvdata(pdev
, NULL
);
418 clk_disable(keypad
->clk
);
419 clk_put(keypad
->clk
);
421 input_unregister_device(keypad
->input_dev
);
423 i
= keypad
->pdata
->matrix_key_cols
- 1;
424 gpio
= EP93XX_GPIO_LINE_COL0
+ i
;
425 for ( ; i
>= 0; i
--, gpio
--)
428 i
= keypad
->pdata
->matrix_key_rows
- 1;
429 gpio
= EP93XX_GPIO_LINE_ROW0
+ i
;
430 for ( ; i
>= 0; i
--, gpio
--)
433 iounmap(keypad
->mmio_base
);
435 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
436 release_mem_region(res
->start
, resource_size(res
));
443 static struct platform_driver ep93xx_keypad_driver
= {
445 .name
= "ep93xx-keypad",
446 .owner
= THIS_MODULE
,
448 .probe
= ep93xx_keypad_probe
,
449 .remove
= __devexit_p(ep93xx_keypad_remove
),
450 .suspend
= ep93xx_keypad_suspend
,
451 .resume
= ep93xx_keypad_resume
,
454 static int __init
ep93xx_keypad_init(void)
456 return platform_driver_register(&ep93xx_keypad_driver
);
459 static void __exit
ep93xx_keypad_exit(void)
461 platform_driver_unregister(&ep93xx_keypad_driver
);
464 module_init(ep93xx_keypad_init
);
465 module_exit(ep93xx_keypad_exit
);
467 MODULE_LICENSE("GPL");
468 MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
469 MODULE_DESCRIPTION("EP93xx Matrix Keypad Controller");
470 MODULE_ALIAS("platform:ep93xx-keypad");