diff options
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/Kconfig | 33 | ||||
-rw-r--r-- | drivers/input/keyboard/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/adp5588-keys.c | 6 | ||||
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 309 | ||||
-rw-r--r-- | drivers/input/keyboard/ep93xx_keypad.c | 40 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 318 | ||||
-rw-r--r-- | drivers/input/keyboard/imx_keypad.c | 594 | ||||
-rw-r--r-- | drivers/input/keyboard/qt2160.c | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/sh_keysc.c | 145 |
9 files changed, 1198 insertions, 250 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 02c836e11813..64c102355f53 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -35,10 +35,10 @@ config KEYBOARD_ADP5520 | |||
35 | be called adp5520-keys. | 35 | be called adp5520-keys. |
36 | 36 | ||
37 | config KEYBOARD_ADP5588 | 37 | config KEYBOARD_ADP5588 |
38 | tristate "ADP5588 I2C QWERTY Keypad and IO Expander" | 38 | tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander" |
39 | depends on I2C | 39 | depends on I2C |
40 | help | 40 | help |
41 | Say Y here if you want to use a ADP5588 attached to your | 41 | Say Y here if you want to use a ADP5588/87 attached to your |
42 | system I2C bus. | 42 | system I2C bus. |
43 | 43 | ||
44 | To compile this driver as a module, choose M here: the | 44 | To compile this driver as a module, choose M here: the |
@@ -144,13 +144,15 @@ config KEYBOARD_BFIN | |||
144 | module will be called bf54x-keys. | 144 | module will be called bf54x-keys. |
145 | 145 | ||
146 | config KEYBOARD_CORGI | 146 | config KEYBOARD_CORGI |
147 | tristate "Corgi keyboard" | 147 | tristate "Corgi keyboard (deprecated)" |
148 | depends on PXA_SHARPSL | 148 | depends on PXA_SHARPSL |
149 | default y | ||
150 | help | 149 | help |
151 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx | 150 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx |
152 | series of PDAs. | 151 | series of PDAs. |
153 | 152 | ||
153 | This driver is now deprecated, use generic GPIO based matrix | ||
154 | keyboard driver instead. | ||
155 | |||
154 | To compile this driver as a module, choose M here: the | 156 | To compile this driver as a module, choose M here: the |
155 | module will be called corgikbd. | 157 | module will be called corgikbd. |
156 | 158 | ||
@@ -292,6 +294,15 @@ config KEYBOARD_MAX7359 | |||
292 | To compile this driver as a module, choose M here: the | 294 | To compile this driver as a module, choose M here: the |
293 | module will be called max7359_keypad. | 295 | module will be called max7359_keypad. |
294 | 296 | ||
297 | config KEYBOARD_IMX | ||
298 | tristate "IMX keypad support" | ||
299 | depends on ARCH_MXC | ||
300 | help | ||
301 | Enable support for IMX keypad port. | ||
302 | |||
303 | To compile this driver as a module, choose M here: the | ||
304 | module will be called imx_keypad. | ||
305 | |||
295 | config KEYBOARD_NEWTON | 306 | config KEYBOARD_NEWTON |
296 | tristate "Newton keyboard" | 307 | tristate "Newton keyboard" |
297 | select SERIO | 308 | select SERIO |
@@ -329,13 +340,15 @@ config KEYBOARD_PXA930_ROTARY | |||
329 | module will be called pxa930_rotary. | 340 | module will be called pxa930_rotary. |
330 | 341 | ||
331 | config KEYBOARD_SPITZ | 342 | config KEYBOARD_SPITZ |
332 | tristate "Spitz keyboard" | 343 | tristate "Spitz keyboard (deprecated)" |
333 | depends on PXA_SHARPSL | 344 | depends on PXA_SHARPSL |
334 | default y | ||
335 | help | 345 | help |
336 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, | 346 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, |
337 | SL-C3000 and Sl-C3100 series of PDAs. | 347 | SL-C3000 and Sl-C3100 series of PDAs. |
338 | 348 | ||
349 | This driver is now deprecated, use generic GPIO based matrix | ||
350 | keyboard driver instead. | ||
351 | |||
339 | To compile this driver as a module, choose M here: the | 352 | To compile this driver as a module, choose M here: the |
340 | module will be called spitzkbd. | 353 | module will be called spitzkbd. |
341 | 354 | ||
@@ -363,7 +376,7 @@ config KEYBOARD_SUNKBD | |||
363 | 376 | ||
364 | config KEYBOARD_SH_KEYSC | 377 | config KEYBOARD_SH_KEYSC |
365 | tristate "SuperH KEYSC keypad support" | 378 | tristate "SuperH KEYSC keypad support" |
366 | depends on SUPERH | 379 | depends on SUPERH || ARCH_SHMOBILE |
367 | help | 380 | help |
368 | Say Y here if you want to use a keypad attached to the KEYSC block | 381 | Say Y here if you want to use a keypad attached to the KEYSC block |
369 | on SuperH processors such as sh7722 and sh7343. | 382 | on SuperH processors such as sh7722 and sh7343. |
@@ -402,12 +415,14 @@ config KEYBOARD_TWL4030 | |||
402 | module will be called twl4030_keypad. | 415 | module will be called twl4030_keypad. |
403 | 416 | ||
404 | config KEYBOARD_TOSA | 417 | config KEYBOARD_TOSA |
405 | tristate "Tosa keyboard" | 418 | tristate "Tosa keyboard (deprecated)" |
406 | depends on MACH_TOSA | 419 | depends on MACH_TOSA |
407 | default y | ||
408 | help | 420 | help |
409 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) | 421 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) |
410 | 422 | ||
423 | This driver is now deprecated, use generic GPIO based matrix | ||
424 | keyboard driver instead. | ||
425 | |||
411 | To compile this driver as a module, choose M here: the | 426 | To compile this driver as a module, choose M here: the |
412 | module will be called tosakbd. | 427 | module will be called tosakbd. |
413 | 428 | ||
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 78654ef65206..706c6b5ed5f4 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | |||
17 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 17 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
20 | obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o | ||
20 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | 21 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o |
21 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | 22 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o |
22 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | 23 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 1edb596d927b..b5142d2d5112 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/input/keyboard/adp5588_keys.c | 2 | * File: drivers/input/keyboard/adp5588_keys.c |
3 | * Description: keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander | 3 | * Description: keypad driver for ADP5588 and ADP5587 |
4 | * I2C QWERTY Keypad and IO Expander | ||
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
5 | * | 6 | * |
6 | * Copyright (C) 2008-2009 Analog Devices Inc. | 7 | * Copyright (C) 2008-2009 Analog Devices Inc. |
@@ -327,6 +328,7 @@ static const struct dev_pm_ops adp5588_dev_pm_ops = { | |||
327 | 328 | ||
328 | static const struct i2c_device_id adp5588_id[] = { | 329 | static const struct i2c_device_id adp5588_id[] = { |
329 | { KBUILD_MODNAME, 0 }, | 330 | { KBUILD_MODNAME, 0 }, |
331 | { "adp5587-keys", 0 }, | ||
330 | { } | 332 | { } |
331 | }; | 333 | }; |
332 | MODULE_DEVICE_TABLE(i2c, adp5588_id); | 334 | MODULE_DEVICE_TABLE(i2c, adp5588_id); |
@@ -357,5 +359,5 @@ module_exit(adp5588_exit); | |||
357 | 359 | ||
358 | MODULE_LICENSE("GPL"); | 360 | MODULE_LICENSE("GPL"); |
359 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 361 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
360 | MODULE_DESCRIPTION("ADP5588 Keypad driver"); | 362 | MODULE_DESCRIPTION("ADP5588/87 Keypad driver"); |
361 | MODULE_ALIAS("platform:adp5588-keys"); | 363 | MODULE_ALIAS("platform:adp5588-keys"); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 7b4056292eaf..d358ef8623f4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -40,26 +40,26 @@ module_param_named(set, atkbd_set, int, 0); | |||
40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); | 40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); |
41 | 41 | ||
42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) | 42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) |
43 | static int atkbd_reset; | 43 | static bool atkbd_reset; |
44 | #else | 44 | #else |
45 | static int atkbd_reset = 1; | 45 | static bool atkbd_reset = true; |
46 | #endif | 46 | #endif |
47 | module_param_named(reset, atkbd_reset, bool, 0); | 47 | module_param_named(reset, atkbd_reset, bool, 0); |
48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); | 48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); |
49 | 49 | ||
50 | static int atkbd_softrepeat; | 50 | static bool atkbd_softrepeat; |
51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); | 51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); |
52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); | 52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); |
53 | 53 | ||
54 | static int atkbd_softraw = 1; | 54 | static bool atkbd_softraw = true; |
55 | module_param_named(softraw, atkbd_softraw, bool, 0); | 55 | module_param_named(softraw, atkbd_softraw, bool, 0); |
56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); | 56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); |
57 | 57 | ||
58 | static int atkbd_scroll; | 58 | static bool atkbd_scroll; |
59 | module_param_named(scroll, atkbd_scroll, bool, 0); | 59 | module_param_named(scroll, atkbd_scroll, bool, 0); |
60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); | 60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); |
61 | 61 | ||
62 | static int atkbd_extra; | 62 | static bool atkbd_extra; |
63 | module_param_named(extra, atkbd_extra, bool, 0); | 63 | module_param_named(extra, atkbd_extra, bool, 0); |
64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); | 64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); |
65 | 65 | ||
@@ -153,16 +153,16 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
153 | #define ATKBD_RET_HANGEUL 0xf2 | 153 | #define ATKBD_RET_HANGEUL 0xf2 |
154 | #define ATKBD_RET_ERR 0xff | 154 | #define ATKBD_RET_ERR 0xff |
155 | 155 | ||
156 | #define ATKBD_KEY_UNKNOWN 0 | 156 | #define ATKBD_KEY_UNKNOWN 0 |
157 | #define ATKBD_KEY_NULL 255 | 157 | #define ATKBD_KEY_NULL 255 |
158 | 158 | ||
159 | #define ATKBD_SCR_1 254 | 159 | #define ATKBD_SCR_1 0xfffe |
160 | #define ATKBD_SCR_2 253 | 160 | #define ATKBD_SCR_2 0xfffd |
161 | #define ATKBD_SCR_4 252 | 161 | #define ATKBD_SCR_4 0xfffc |
162 | #define ATKBD_SCR_8 251 | 162 | #define ATKBD_SCR_8 0xfffb |
163 | #define ATKBD_SCR_CLICK 250 | 163 | #define ATKBD_SCR_CLICK 0xfffa |
164 | #define ATKBD_SCR_LEFT 249 | 164 | #define ATKBD_SCR_LEFT 0xfff9 |
165 | #define ATKBD_SCR_RIGHT 248 | 165 | #define ATKBD_SCR_RIGHT 0xfff8 |
166 | 166 | ||
167 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT | 167 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT |
168 | 168 | ||
@@ -177,7 +177,7 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
177 | #define ATKBD_XL_HANJA 0x20 | 177 | #define ATKBD_XL_HANJA 0x20 |
178 | 178 | ||
179 | static const struct { | 179 | static const struct { |
180 | unsigned char keycode; | 180 | unsigned short keycode; |
181 | unsigned char set2; | 181 | unsigned char set2; |
182 | } atkbd_scroll_keys[] = { | 182 | } atkbd_scroll_keys[] = { |
183 | { ATKBD_SCR_1, 0xc5 }, | 183 | { ATKBD_SCR_1, 0xc5 }, |
@@ -206,18 +206,18 @@ struct atkbd { | |||
206 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; | 206 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; |
207 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); | 207 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); |
208 | unsigned char set; | 208 | unsigned char set; |
209 | unsigned char translated; | 209 | bool translated; |
210 | unsigned char extra; | 210 | bool extra; |
211 | unsigned char write; | 211 | bool write; |
212 | unsigned char softrepeat; | 212 | bool softrepeat; |
213 | unsigned char softraw; | 213 | bool softraw; |
214 | unsigned char scroll; | 214 | bool scroll; |
215 | unsigned char enabled; | 215 | bool enabled; |
216 | 216 | ||
217 | /* Accessed only from interrupt */ | 217 | /* Accessed only from interrupt */ |
218 | unsigned char emul; | 218 | unsigned char emul; |
219 | unsigned char resend; | 219 | bool resend; |
220 | unsigned char release; | 220 | bool release; |
221 | unsigned long xl_bit; | 221 | unsigned long xl_bit; |
222 | unsigned int last; | 222 | unsigned int last; |
223 | unsigned long time; | 223 | unsigned long time; |
@@ -301,18 +301,18 @@ static const unsigned int xl_table[] = { | |||
301 | * Checks if we should mangle the scancode to extract 'release' bit | 301 | * Checks if we should mangle the scancode to extract 'release' bit |
302 | * in translated mode. | 302 | * in translated mode. |
303 | */ | 303 | */ |
304 | static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code) | 304 | static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code) |
305 | { | 305 | { |
306 | int i; | 306 | int i; |
307 | 307 | ||
308 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) | 308 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) |
309 | return 0; | 309 | return false; |
310 | 310 | ||
311 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) | 311 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) |
312 | if (code == xl_table[i]) | 312 | if (code == xl_table[i]) |
313 | return test_bit(i, &xl_bit); | 313 | return test_bit(i, &xl_bit); |
314 | 314 | ||
315 | return 1; | 315 | return true; |
316 | } | 316 | } |
317 | 317 | ||
318 | /* | 318 | /* |
@@ -359,7 +359,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code | |||
359 | */ | 359 | */ |
360 | 360 | ||
361 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | 361 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, |
362 | unsigned int flags) | 362 | unsigned int flags) |
363 | { | 363 | { |
364 | struct atkbd *atkbd = serio_get_drvdata(serio); | 364 | struct atkbd *atkbd = serio_get_drvdata(serio); |
365 | struct input_dev *dev = atkbd->dev; | 365 | struct input_dev *dev = atkbd->dev; |
@@ -368,20 +368,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
368 | int value; | 368 | int value; |
369 | unsigned short keycode; | 369 | unsigned short keycode; |
370 | 370 | ||
371 | #ifdef ATKBD_DEBUG | 371 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); |
372 | printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); | ||
373 | #endif | ||
374 | 372 | ||
375 | #if !defined(__i386__) && !defined (__x86_64__) | 373 | #if !defined(__i386__) && !defined (__x86_64__) |
376 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { | 374 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { |
377 | printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags); | 375 | dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); |
378 | serio_write(serio, ATKBD_CMD_RESEND); | 376 | serio_write(serio, ATKBD_CMD_RESEND); |
379 | atkbd->resend = 1; | 377 | atkbd->resend = true; |
380 | goto out; | 378 | goto out; |
381 | } | 379 | } |
382 | 380 | ||
383 | if (!flags && data == ATKBD_RET_ACK) | 381 | if (!flags && data == ATKBD_RET_ACK) |
384 | atkbd->resend = 0; | 382 | atkbd->resend = false; |
385 | #endif | 383 | #endif |
386 | 384 | ||
387 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) | 385 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) |
@@ -412,32 +410,32 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
412 | } | 410 | } |
413 | 411 | ||
414 | switch (code) { | 412 | switch (code) { |
415 | case ATKBD_RET_BAT: | 413 | case ATKBD_RET_BAT: |
416 | atkbd->enabled = 0; | 414 | atkbd->enabled = false; |
417 | serio_reconnect(atkbd->ps2dev.serio); | 415 | serio_reconnect(atkbd->ps2dev.serio); |
418 | goto out; | 416 | goto out; |
419 | case ATKBD_RET_EMUL0: | 417 | case ATKBD_RET_EMUL0: |
420 | atkbd->emul = 1; | 418 | atkbd->emul = 1; |
421 | goto out; | 419 | goto out; |
422 | case ATKBD_RET_EMUL1: | 420 | case ATKBD_RET_EMUL1: |
423 | atkbd->emul = 2; | 421 | atkbd->emul = 2; |
424 | goto out; | 422 | goto out; |
425 | case ATKBD_RET_RELEASE: | 423 | case ATKBD_RET_RELEASE: |
426 | atkbd->release = 1; | 424 | atkbd->release = true; |
427 | goto out; | 425 | goto out; |
428 | case ATKBD_RET_ACK: | 426 | case ATKBD_RET_ACK: |
429 | case ATKBD_RET_NAK: | 427 | case ATKBD_RET_NAK: |
430 | if (printk_ratelimit()) | 428 | if (printk_ratelimit()) |
431 | printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " | 429 | dev_warn(&serio->dev, |
432 | "Some program might be trying access hardware directly.\n", | 430 | "Spurious %s on %s. " |
433 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | 431 | "Some program might be trying access hardware directly.\n", |
434 | goto out; | 432 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); |
435 | case ATKBD_RET_ERR: | 433 | goto out; |
436 | atkbd->err_count++; | 434 | case ATKBD_RET_ERR: |
437 | #ifdef ATKBD_DEBUG | 435 | atkbd->err_count++; |
438 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); | 436 | dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", |
439 | #endif | 437 | serio->phys); |
440 | goto out; | 438 | goto out; |
441 | } | 439 | } |
442 | 440 | ||
443 | code = atkbd_compat_scancode(atkbd, code); | 441 | code = atkbd_compat_scancode(atkbd, code); |
@@ -451,71 +449,72 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
451 | input_event(dev, EV_MSC, MSC_SCAN, code); | 449 | input_event(dev, EV_MSC, MSC_SCAN, code); |
452 | 450 | ||
453 | switch (keycode) { | 451 | switch (keycode) { |
454 | case ATKBD_KEY_NULL: | 452 | case ATKBD_KEY_NULL: |
455 | break; | 453 | break; |
456 | case ATKBD_KEY_UNKNOWN: | 454 | case ATKBD_KEY_UNKNOWN: |
457 | printk(KERN_WARNING | 455 | dev_warn(&serio->dev, |
458 | "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", | 456 | "Unknown key %s (%s set %d, code %#x on %s).\n", |
459 | atkbd->release ? "released" : "pressed", | 457 | atkbd->release ? "released" : "pressed", |
460 | atkbd->translated ? "translated" : "raw", | 458 | atkbd->translated ? "translated" : "raw", |
461 | atkbd->set, code, serio->phys); | 459 | atkbd->set, code, serio->phys); |
462 | printk(KERN_WARNING | 460 | dev_warn(&serio->dev, |
463 | "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", | 461 | "Use 'setkeycodes %s%02x <keycode>' to make it known.\n", |
464 | code & 0x80 ? "e0" : "", code & 0x7f); | 462 | code & 0x80 ? "e0" : "", code & 0x7f); |
465 | input_sync(dev); | 463 | input_sync(dev); |
466 | break; | 464 | break; |
467 | case ATKBD_SCR_1: | 465 | case ATKBD_SCR_1: |
468 | scroll = 1 - atkbd->release * 2; | 466 | scroll = 1; |
469 | break; | 467 | break; |
470 | case ATKBD_SCR_2: | 468 | case ATKBD_SCR_2: |
471 | scroll = 2 - atkbd->release * 4; | 469 | scroll = 2; |
472 | break; | 470 | break; |
473 | case ATKBD_SCR_4: | 471 | case ATKBD_SCR_4: |
474 | scroll = 4 - atkbd->release * 8; | 472 | scroll = 4; |
475 | break; | 473 | break; |
476 | case ATKBD_SCR_8: | 474 | case ATKBD_SCR_8: |
477 | scroll = 8 - atkbd->release * 16; | 475 | scroll = 8; |
478 | break; | 476 | break; |
479 | case ATKBD_SCR_CLICK: | 477 | case ATKBD_SCR_CLICK: |
480 | click = !atkbd->release; | 478 | click = !atkbd->release; |
481 | break; | 479 | break; |
482 | case ATKBD_SCR_LEFT: | 480 | case ATKBD_SCR_LEFT: |
483 | hscroll = -1; | 481 | hscroll = -1; |
484 | break; | 482 | break; |
485 | case ATKBD_SCR_RIGHT: | 483 | case ATKBD_SCR_RIGHT: |
486 | hscroll = 1; | 484 | hscroll = 1; |
487 | break; | 485 | break; |
488 | default: | 486 | default: |
489 | if (atkbd->release) { | 487 | if (atkbd->release) { |
490 | value = 0; | 488 | value = 0; |
491 | atkbd->last = 0; | 489 | atkbd->last = 0; |
492 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { | 490 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { |
493 | /* Workaround Toshiba laptop multiple keypress */ | 491 | /* Workaround Toshiba laptop multiple keypress */ |
494 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; | 492 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; |
495 | } else { | 493 | } else { |
496 | value = 1; | 494 | value = 1; |
497 | atkbd->last = code; | 495 | atkbd->last = code; |
498 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; | 496 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; |
499 | } | 497 | } |
500 | 498 | ||
501 | input_event(dev, EV_KEY, keycode, value); | 499 | input_event(dev, EV_KEY, keycode, value); |
502 | input_sync(dev); | 500 | input_sync(dev); |
503 | 501 | ||
504 | if (value && test_bit(code, atkbd->force_release_mask)) { | 502 | if (value && test_bit(code, atkbd->force_release_mask)) { |
505 | input_report_key(dev, keycode, 0); | 503 | input_report_key(dev, keycode, 0); |
506 | input_sync(dev); | 504 | input_sync(dev); |
507 | } | 505 | } |
508 | } | 506 | } |
509 | 507 | ||
510 | if (atkbd->scroll) { | 508 | if (atkbd->scroll) { |
511 | if (click != -1) | 509 | if (click != -1) |
512 | input_report_key(dev, BTN_MIDDLE, click); | 510 | input_report_key(dev, BTN_MIDDLE, click); |
513 | input_report_rel(dev, REL_WHEEL, scroll); | 511 | input_report_rel(dev, REL_WHEEL, |
512 | atkbd->release ? -scroll : scroll); | ||
514 | input_report_rel(dev, REL_HWHEEL, hscroll); | 513 | input_report_rel(dev, REL_HWHEEL, hscroll); |
515 | input_sync(dev); | 514 | input_sync(dev); |
516 | } | 515 | } |
517 | 516 | ||
518 | atkbd->release = 0; | 517 | atkbd->release = false; |
519 | out: | 518 | out: |
520 | return IRQ_HANDLED; | 519 | return IRQ_HANDLED; |
521 | } | 520 | } |
@@ -634,17 +633,18 @@ static int atkbd_event(struct input_dev *dev, | |||
634 | 633 | ||
635 | switch (type) { | 634 | switch (type) { |
636 | 635 | ||
637 | case EV_LED: | 636 | case EV_LED: |
638 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); | 637 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); |
639 | return 0; | 638 | return 0; |
640 | 639 | ||
641 | case EV_REP: | 640 | case EV_REP: |
642 | if (!atkbd->softrepeat) | 641 | if (!atkbd->softrepeat) |
643 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); | 642 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); |
644 | return 0; | 643 | return 0; |
645 | } | ||
646 | 644 | ||
647 | return -1; | 645 | default: |
646 | return -1; | ||
647 | } | ||
648 | } | 648 | } |
649 | 649 | ||
650 | /* | 650 | /* |
@@ -655,7 +655,7 @@ static int atkbd_event(struct input_dev *dev, | |||
655 | static inline void atkbd_enable(struct atkbd *atkbd) | 655 | static inline void atkbd_enable(struct atkbd *atkbd) |
656 | { | 656 | { |
657 | serio_pause_rx(atkbd->ps2dev.serio); | 657 | serio_pause_rx(atkbd->ps2dev.serio); |
658 | atkbd->enabled = 1; | 658 | atkbd->enabled = true; |
659 | serio_continue_rx(atkbd->ps2dev.serio); | 659 | serio_continue_rx(atkbd->ps2dev.serio); |
660 | } | 660 | } |
661 | 661 | ||
@@ -667,7 +667,7 @@ static inline void atkbd_enable(struct atkbd *atkbd) | |||
667 | static inline void atkbd_disable(struct atkbd *atkbd) | 667 | static inline void atkbd_disable(struct atkbd *atkbd) |
668 | { | 668 | { |
669 | serio_pause_rx(atkbd->ps2dev.serio); | 669 | serio_pause_rx(atkbd->ps2dev.serio); |
670 | atkbd->enabled = 0; | 670 | atkbd->enabled = false; |
671 | serio_continue_rx(atkbd->ps2dev.serio); | 671 | serio_continue_rx(atkbd->ps2dev.serio); |
672 | } | 672 | } |
673 | 673 | ||
@@ -688,7 +688,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
688 | 688 | ||
689 | if (atkbd_reset) | 689 | if (atkbd_reset) |
690 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) | 690 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) |
691 | printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys); | 691 | dev_warn(&ps2dev->serio->dev, |
692 | "keyboard reset failed on %s\n", | ||
693 | ps2dev->serio->phys); | ||
692 | 694 | ||
693 | /* | 695 | /* |
694 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. | 696 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. |
@@ -718,8 +720,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
718 | atkbd->id = (param[0] << 8) | param[1]; | 720 | atkbd->id = (param[0] << 8) | param[1]; |
719 | 721 | ||
720 | if (atkbd->id == 0xaca1 && atkbd->translated) { | 722 | if (atkbd->id == 0xaca1 && atkbd->translated) { |
721 | printk(KERN_ERR "atkbd.c: NCD terminal keyboards are only supported on non-translating\n"); | 723 | dev_err(&ps2dev->serio->dev, |
722 | printk(KERN_ERR "atkbd.c: controllers. Use i8042.direct=1 to disable translation.\n"); | 724 | "NCD terminal keyboards are only supported on non-translating controlelrs. " |
725 | "Use i8042.direct=1 to disable translation.\n"); | ||
723 | return -1; | 726 | return -1; |
724 | } | 727 | } |
725 | 728 | ||
@@ -737,7 +740,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
737 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 740 | struct ps2dev *ps2dev = &atkbd->ps2dev; |
738 | unsigned char param[2]; | 741 | unsigned char param[2]; |
739 | 742 | ||
740 | atkbd->extra = 0; | 743 | atkbd->extra = false; |
741 | /* | 744 | /* |
742 | * For known special keyboards we can go ahead and set the correct set. | 745 | * For known special keyboards we can go ahead and set the correct set. |
743 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and | 746 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and |
@@ -756,7 +759,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
756 | if (allow_extra) { | 759 | if (allow_extra) { |
757 | param[0] = 0x71; | 760 | param[0] = 0x71; |
758 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { | 761 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { |
759 | atkbd->extra = 1; | 762 | atkbd->extra = true; |
760 | return 2; | 763 | return 2; |
761 | } | 764 | } |
762 | } | 765 | } |
@@ -821,7 +824,8 @@ static int atkbd_activate(struct atkbd *atkbd) | |||
821 | */ | 824 | */ |
822 | 825 | ||
823 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { | 826 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { |
824 | printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n", | 827 | dev_err(&ps2dev->serio->dev, |
828 | "Failed to enable keyboard on %s\n", | ||
825 | ps2dev->serio->phys); | 829 | ps2dev->serio->phys); |
826 | return -1; | 830 | return -1; |
827 | } | 831 | } |
@@ -1070,9 +1074,13 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
1070 | input_dev->keycodesize = sizeof(unsigned short); | 1074 | input_dev->keycodesize = sizeof(unsigned short); |
1071 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 1075 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); |
1072 | 1076 | ||
1073 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) | 1077 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) { |
1074 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) | 1078 | if (atkbd->keycode[i] != KEY_RESERVED && |
1079 | atkbd->keycode[i] != ATKBD_KEY_NULL && | ||
1080 | atkbd->keycode[i] < ATKBD_SPECIAL) { | ||
1075 | __set_bit(atkbd->keycode[i], input_dev->keybit); | 1081 | __set_bit(atkbd->keycode[i], input_dev->keybit); |
1082 | } | ||
1083 | } | ||
1076 | } | 1084 | } |
1077 | 1085 | ||
1078 | /* | 1086 | /* |
@@ -1100,12 +1108,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1100 | 1108 | ||
1101 | switch (serio->id.type) { | 1109 | switch (serio->id.type) { |
1102 | 1110 | ||
1103 | case SERIO_8042_XL: | 1111 | case SERIO_8042_XL: |
1104 | atkbd->translated = 1; | 1112 | atkbd->translated = true; |
1105 | case SERIO_8042: | 1113 | /* Fall through */ |
1106 | if (serio->write) | 1114 | |
1107 | atkbd->write = 1; | 1115 | case SERIO_8042: |
1108 | break; | 1116 | if (serio->write) |
1117 | atkbd->write = true; | ||
1118 | break; | ||
1109 | } | 1119 | } |
1110 | 1120 | ||
1111 | atkbd->softraw = atkbd_softraw; | 1121 | atkbd->softraw = atkbd_softraw; |
@@ -1113,7 +1123,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1113 | atkbd->scroll = atkbd_scroll; | 1123 | atkbd->scroll = atkbd_scroll; |
1114 | 1124 | ||
1115 | if (atkbd->softrepeat) | 1125 | if (atkbd->softrepeat) |
1116 | atkbd->softraw = 1; | 1126 | atkbd->softraw = true; |
1117 | 1127 | ||
1118 | serio_set_drvdata(serio, atkbd); | 1128 | serio_set_drvdata(serio, atkbd); |
1119 | 1129 | ||
@@ -1172,7 +1182,8 @@ static int atkbd_reconnect(struct serio *serio) | |||
1172 | int retval = -1; | 1182 | int retval = -1; |
1173 | 1183 | ||
1174 | if (!atkbd || !drv) { | 1184 | if (!atkbd || !drv) { |
1175 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 1185 | dev_dbg(&serio->dev, |
1186 | "reconnect request, but serio is disconnected, ignoring...\n"); | ||
1176 | return -1; | 1187 | return -1; |
1177 | } | 1188 | } |
1178 | 1189 | ||
@@ -1286,7 +1297,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1286 | struct input_dev *old_dev, *new_dev; | 1297 | struct input_dev *old_dev, *new_dev; |
1287 | unsigned long value; | 1298 | unsigned long value; |
1288 | int err; | 1299 | int err; |
1289 | unsigned char old_extra, old_set; | 1300 | bool old_extra; |
1301 | unsigned char old_set; | ||
1290 | 1302 | ||
1291 | if (!atkbd->write) | 1303 | if (!atkbd->write) |
1292 | return -EIO; | 1304 | return -EIO; |
@@ -1369,7 +1381,7 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou | |||
1369 | struct input_dev *old_dev, *new_dev; | 1381 | struct input_dev *old_dev, *new_dev; |
1370 | unsigned long value; | 1382 | unsigned long value; |
1371 | int err; | 1383 | int err; |
1372 | unsigned char old_scroll; | 1384 | bool old_scroll; |
1373 | 1385 | ||
1374 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1386 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1375 | return -EINVAL; | 1387 | return -EINVAL; |
@@ -1413,7 +1425,8 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | |||
1413 | struct input_dev *old_dev, *new_dev; | 1425 | struct input_dev *old_dev, *new_dev; |
1414 | unsigned long value; | 1426 | unsigned long value; |
1415 | int err; | 1427 | int err; |
1416 | unsigned char old_set, old_extra; | 1428 | unsigned char old_set; |
1429 | bool old_extra; | ||
1417 | 1430 | ||
1418 | if (!atkbd->write) | 1431 | if (!atkbd->write) |
1419 | return -EIO; | 1432 | return -EIO; |
@@ -1463,7 +1476,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1463 | struct input_dev *old_dev, *new_dev; | 1476 | struct input_dev *old_dev, *new_dev; |
1464 | unsigned long value; | 1477 | unsigned long value; |
1465 | int err; | 1478 | int err; |
1466 | unsigned char old_softrepeat, old_softraw; | 1479 | bool old_softrepeat, old_softraw; |
1467 | 1480 | ||
1468 | if (!atkbd->write) | 1481 | if (!atkbd->write) |
1469 | return -EIO; | 1482 | return -EIO; |
@@ -1483,7 +1496,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1483 | atkbd->dev = new_dev; | 1496 | atkbd->dev = new_dev; |
1484 | atkbd->softrepeat = value; | 1497 | atkbd->softrepeat = value; |
1485 | if (atkbd->softrepeat) | 1498 | if (atkbd->softrepeat) |
1486 | atkbd->softraw = 1; | 1499 | atkbd->softraw = true; |
1487 | atkbd_set_device_attrs(atkbd); | 1500 | atkbd_set_device_attrs(atkbd); |
1488 | 1501 | ||
1489 | err = input_register_device(atkbd->dev); | 1502 | err = input_register_device(atkbd->dev); |
@@ -1513,7 +1526,7 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co | |||
1513 | struct input_dev *old_dev, *new_dev; | 1526 | struct input_dev *old_dev, *new_dev; |
1514 | unsigned long value; | 1527 | unsigned long value; |
1515 | int err; | 1528 | int err; |
1516 | unsigned char old_softraw; | 1529 | bool old_softraw; |
1517 | 1530 | ||
1518 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1531 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1519 | return -EINVAL; | 1532 | return -EINVAL; |
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index e45740429f7e..bd25a3af1664 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
@@ -69,7 +69,7 @@ struct ep93xx_keypad { | |||
69 | 69 | ||
70 | void __iomem *mmio_base; | 70 | void __iomem *mmio_base; |
71 | 71 | ||
72 | unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE]; | 72 | unsigned short keycodes[EP93XX_MATRIX_SIZE]; |
73 | 73 | ||
74 | int key1; | 74 | int key1; |
75 | int key2; | 75 | int key2; |
@@ -79,24 +79,6 @@ struct ep93xx_keypad { | |||
79 | bool enabled; | 79 | bool enabled; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad) | ||
83 | { | ||
84 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | ||
85 | struct input_dev *input_dev = keypad->input_dev; | ||
86 | unsigned int *key; | ||
87 | int i; | ||
88 | |||
89 | key = &pdata->matrix_key_map[0]; | ||
90 | for (i = 0; i < pdata->matrix_key_map_size; i++, key++) { | ||
91 | int row = KEY_ROW(*key); | ||
92 | int col = KEY_COL(*key); | ||
93 | int code = KEY_VAL(*key); | ||
94 | |||
95 | keypad->matrix_keycodes[(row << 3) + col] = code; | ||
96 | __set_bit(code, input_dev->keybit); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) | 82 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) |
101 | { | 83 | { |
102 | struct ep93xx_keypad *keypad = dev_id; | 84 | struct ep93xx_keypad *keypad = dev_id; |
@@ -107,10 +89,10 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) | |||
107 | status = __raw_readl(keypad->mmio_base + KEY_REG); | 89 | status = __raw_readl(keypad->mmio_base + KEY_REG); |
108 | 90 | ||
109 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; | 91 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; |
110 | key1 = keypad->matrix_keycodes[keycode]; | 92 | key1 = keypad->keycodes[keycode]; |
111 | 93 | ||
112 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; | 94 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; |
113 | key2 = keypad->matrix_keycodes[keycode]; | 95 | key2 = keypad->keycodes[keycode]; |
114 | 96 | ||
115 | if (status & KEY_REG_2KEYS) { | 97 | if (status & KEY_REG_2KEYS) { |
116 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) | 98 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) |
@@ -256,6 +238,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) | |||
256 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | 238 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) |
257 | { | 239 | { |
258 | struct ep93xx_keypad *keypad; | 240 | struct ep93xx_keypad *keypad; |
241 | const struct matrix_keymap_data *keymap_data; | ||
259 | struct input_dev *input_dev; | 242 | struct input_dev *input_dev; |
260 | struct resource *res; | 243 | struct resource *res; |
261 | int err; | 244 | int err; |
@@ -270,6 +253,12 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
270 | goto failed_free; | 253 | goto failed_free; |
271 | } | 254 | } |
272 | 255 | ||
256 | keymap_data = keypad->pdata->keymap_data; | ||
257 | if (!keymap_data) { | ||
258 | err = -EINVAL; | ||
259 | goto failed_free; | ||
260 | } | ||
261 | |||
273 | keypad->irq = platform_get_irq(pdev, 0); | 262 | keypad->irq = platform_get_irq(pdev, 0); |
274 | if (!keypad->irq) { | 263 | if (!keypad->irq) { |
275 | err = -ENXIO; | 264 | err = -ENXIO; |
@@ -317,9 +306,9 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
317 | input_dev->open = ep93xx_keypad_open; | 306 | input_dev->open = ep93xx_keypad_open; |
318 | input_dev->close = ep93xx_keypad_close; | 307 | input_dev->close = ep93xx_keypad_close; |
319 | input_dev->dev.parent = &pdev->dev; | 308 | input_dev->dev.parent = &pdev->dev; |
320 | input_dev->keycode = keypad->matrix_keycodes; | 309 | input_dev->keycode = keypad->keycodes; |
321 | input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); | 310 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); |
322 | input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); | 311 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); |
323 | 312 | ||
324 | input_set_drvdata(input_dev, keypad); | 313 | input_set_drvdata(input_dev, keypad); |
325 | 314 | ||
@@ -327,7 +316,8 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
327 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) | 316 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) |
328 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | 317 | input_dev->evbit[0] |= BIT_MASK(EV_REP); |
329 | 318 | ||
330 | ep93xx_keypad_build_keycode(keypad); | 319 | matrix_keypad_build_keymap(keymap_data, 3, |
320 | input_dev->keycode, input_dev->keybit); | ||
331 | platform_set_drvdata(pdev, keypad); | 321 | platform_set_drvdata(pdev, keypad); |
332 | 322 | ||
333 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, | 323 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 1aff3b76effd..2b708aa85553 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -30,13 +30,289 @@ struct gpio_button_data { | |||
30 | struct input_dev *input; | 30 | struct input_dev *input; |
31 | struct timer_list timer; | 31 | struct timer_list timer; |
32 | struct work_struct work; | 32 | struct work_struct work; |
33 | bool disabled; | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct gpio_keys_drvdata { | 36 | struct gpio_keys_drvdata { |
36 | struct input_dev *input; | 37 | struct input_dev *input; |
38 | struct mutex disable_lock; | ||
39 | unsigned int n_buttons; | ||
37 | struct gpio_button_data data[0]; | 40 | struct gpio_button_data data[0]; |
38 | }; | 41 | }; |
39 | 42 | ||
43 | /* | ||
44 | * SYSFS interface for enabling/disabling keys and switches: | ||
45 | * | ||
46 | * There are 4 attributes under /sys/devices/platform/gpio-keys/ | ||
47 | * keys [ro] - bitmap of keys (EV_KEY) which can be | ||
48 | * disabled | ||
49 | * switches [ro] - bitmap of switches (EV_SW) which can be | ||
50 | * disabled | ||
51 | * disabled_keys [rw] - bitmap of keys currently disabled | ||
52 | * disabled_switches [rw] - bitmap of switches currently disabled | ||
53 | * | ||
54 | * Userland can change these values and hence disable event generation | ||
55 | * for each key (or switch). Disabling a key means its interrupt line | ||
56 | * is disabled. | ||
57 | * | ||
58 | * For example, if we have following switches set up as gpio-keys: | ||
59 | * SW_DOCK = 5 | ||
60 | * SW_CAMERA_LENS_COVER = 9 | ||
61 | * SW_KEYPAD_SLIDE = 10 | ||
62 | * SW_FRONT_PROXIMITY = 11 | ||
63 | * This is read from switches: | ||
64 | * 11-9,5 | ||
65 | * Next we want to disable proximity (11) and dock (5), we write: | ||
66 | * 11,5 | ||
67 | * to file disabled_switches. Now proximity and dock IRQs are disabled. | ||
68 | * This can be verified by reading the file disabled_switches: | ||
69 | * 11,5 | ||
70 | * If we now want to enable proximity (11) switch we write: | ||
71 | * 5 | ||
72 | * to disabled_switches. | ||
73 | * | ||
74 | * We can disable only those keys which don't allow sharing the irq. | ||
75 | */ | ||
76 | |||
77 | /** | ||
78 | * get_n_events_by_type() - returns maximum number of events per @type | ||
79 | * @type: type of button (%EV_KEY, %EV_SW) | ||
80 | * | ||
81 | * Return value of this function can be used to allocate bitmap | ||
82 | * large enough to hold all bits for given type. | ||
83 | */ | ||
84 | static inline int get_n_events_by_type(int type) | ||
85 | { | ||
86 | BUG_ON(type != EV_SW && type != EV_KEY); | ||
87 | |||
88 | return (type == EV_KEY) ? KEY_CNT : SW_CNT; | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * gpio_keys_disable_button() - disables given GPIO button | ||
93 | * @bdata: button data for button to be disabled | ||
94 | * | ||
95 | * Disables button pointed by @bdata. This is done by masking | ||
96 | * IRQ line. After this function is called, button won't generate | ||
97 | * input events anymore. Note that one can only disable buttons | ||
98 | * that don't share IRQs. | ||
99 | * | ||
100 | * Make sure that @bdata->disable_lock is locked when entering | ||
101 | * this function to avoid races when concurrent threads are | ||
102 | * disabling buttons at the same time. | ||
103 | */ | ||
104 | static void gpio_keys_disable_button(struct gpio_button_data *bdata) | ||
105 | { | ||
106 | if (!bdata->disabled) { | ||
107 | /* | ||
108 | * Disable IRQ and possible debouncing timer. | ||
109 | */ | ||
110 | disable_irq(gpio_to_irq(bdata->button->gpio)); | ||
111 | if (bdata->button->debounce_interval) | ||
112 | del_timer_sync(&bdata->timer); | ||
113 | |||
114 | bdata->disabled = true; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * gpio_keys_enable_button() - enables given GPIO button | ||
120 | * @bdata: button data for button to be disabled | ||
121 | * | ||
122 | * Enables given button pointed by @bdata. | ||
123 | * | ||
124 | * Make sure that @bdata->disable_lock is locked when entering | ||
125 | * this function to avoid races with concurrent threads trying | ||
126 | * to enable the same button at the same time. | ||
127 | */ | ||
128 | static void gpio_keys_enable_button(struct gpio_button_data *bdata) | ||
129 | { | ||
130 | if (bdata->disabled) { | ||
131 | enable_irq(gpio_to_irq(bdata->button->gpio)); | ||
132 | bdata->disabled = false; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons | ||
138 | * @ddata: pointer to drvdata | ||
139 | * @buf: buffer where stringified bitmap is written | ||
140 | * @type: button type (%EV_KEY, %EV_SW) | ||
141 | * @only_disabled: does caller want only those buttons that are | ||
142 | * currently disabled or all buttons that can be | ||
143 | * disabled | ||
144 | * | ||
145 | * This function writes buttons that can be disabled to @buf. If | ||
146 | * @only_disabled is true, then @buf contains only those buttons | ||
147 | * that are currently disabled. Returns 0 on success or negative | ||
148 | * errno on failure. | ||
149 | */ | ||
150 | static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, | ||
151 | char *buf, unsigned int type, | ||
152 | bool only_disabled) | ||
153 | { | ||
154 | int n_events = get_n_events_by_type(type); | ||
155 | unsigned long *bits; | ||
156 | ssize_t ret; | ||
157 | int i; | ||
158 | |||
159 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
160 | if (!bits) | ||
161 | return -ENOMEM; | ||
162 | |||
163 | for (i = 0; i < ddata->n_buttons; i++) { | ||
164 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
165 | |||
166 | if (bdata->button->type != type) | ||
167 | continue; | ||
168 | |||
169 | if (only_disabled && !bdata->disabled) | ||
170 | continue; | ||
171 | |||
172 | __set_bit(bdata->button->code, bits); | ||
173 | } | ||
174 | |||
175 | ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); | ||
176 | buf[ret++] = '\n'; | ||
177 | buf[ret] = '\0'; | ||
178 | |||
179 | kfree(bits); | ||
180 | |||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap | ||
186 | * @ddata: pointer to drvdata | ||
187 | * @buf: buffer from userspace that contains stringified bitmap | ||
188 | * @type: button type (%EV_KEY, %EV_SW) | ||
189 | * | ||
190 | * This function parses stringified bitmap from @buf and disables/enables | ||
191 | * GPIO buttons accordinly. Returns 0 on success and negative error | ||
192 | * on failure. | ||
193 | */ | ||
194 | static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | ||
195 | const char *buf, unsigned int type) | ||
196 | { | ||
197 | int n_events = get_n_events_by_type(type); | ||
198 | unsigned long *bits; | ||
199 | ssize_t error; | ||
200 | int i; | ||
201 | |||
202 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
203 | if (!bits) | ||
204 | return -ENOMEM; | ||
205 | |||
206 | error = bitmap_parselist(buf, bits, n_events); | ||
207 | if (error) | ||
208 | goto out; | ||
209 | |||
210 | /* First validate */ | ||
211 | for (i = 0; i < ddata->n_buttons; i++) { | ||
212 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
213 | |||
214 | if (bdata->button->type != type) | ||
215 | continue; | ||
216 | |||
217 | if (test_bit(bdata->button->code, bits) && | ||
218 | !bdata->button->can_disable) { | ||
219 | error = -EINVAL; | ||
220 | goto out; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | mutex_lock(&ddata->disable_lock); | ||
225 | |||
226 | for (i = 0; i < ddata->n_buttons; i++) { | ||
227 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
228 | |||
229 | if (bdata->button->type != type) | ||
230 | continue; | ||
231 | |||
232 | if (test_bit(bdata->button->code, bits)) | ||
233 | gpio_keys_disable_button(bdata); | ||
234 | else | ||
235 | gpio_keys_enable_button(bdata); | ||
236 | } | ||
237 | |||
238 | mutex_unlock(&ddata->disable_lock); | ||
239 | |||
240 | out: | ||
241 | kfree(bits); | ||
242 | return error; | ||
243 | } | ||
244 | |||
245 | #define ATTR_SHOW_FN(name, type, only_disabled) \ | ||
246 | static ssize_t gpio_keys_show_##name(struct device *dev, \ | ||
247 | struct device_attribute *attr, \ | ||
248 | char *buf) \ | ||
249 | { \ | ||
250 | struct platform_device *pdev = to_platform_device(dev); \ | ||
251 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
252 | \ | ||
253 | return gpio_keys_attr_show_helper(ddata, buf, \ | ||
254 | type, only_disabled); \ | ||
255 | } | ||
256 | |||
257 | ATTR_SHOW_FN(keys, EV_KEY, false); | ||
258 | ATTR_SHOW_FN(switches, EV_SW, false); | ||
259 | ATTR_SHOW_FN(disabled_keys, EV_KEY, true); | ||
260 | ATTR_SHOW_FN(disabled_switches, EV_SW, true); | ||
261 | |||
262 | /* | ||
263 | * ATTRIBUTES: | ||
264 | * | ||
265 | * /sys/devices/platform/gpio-keys/keys [ro] | ||
266 | * /sys/devices/platform/gpio-keys/switches [ro] | ||
267 | */ | ||
268 | static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); | ||
269 | static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); | ||
270 | |||
271 | #define ATTR_STORE_FN(name, type) \ | ||
272 | static ssize_t gpio_keys_store_##name(struct device *dev, \ | ||
273 | struct device_attribute *attr, \ | ||
274 | const char *buf, \ | ||
275 | size_t count) \ | ||
276 | { \ | ||
277 | struct platform_device *pdev = to_platform_device(dev); \ | ||
278 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
279 | ssize_t error; \ | ||
280 | \ | ||
281 | error = gpio_keys_attr_store_helper(ddata, buf, type); \ | ||
282 | if (error) \ | ||
283 | return error; \ | ||
284 | \ | ||
285 | return count; \ | ||
286 | } | ||
287 | |||
288 | ATTR_STORE_FN(disabled_keys, EV_KEY); | ||
289 | ATTR_STORE_FN(disabled_switches, EV_SW); | ||
290 | |||
291 | /* | ||
292 | * ATTRIBUTES: | ||
293 | * | ||
294 | * /sys/devices/platform/gpio-keys/disabled_keys [rw] | ||
295 | * /sys/devices/platform/gpio-keys/disables_switches [rw] | ||
296 | */ | ||
297 | static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, | ||
298 | gpio_keys_show_disabled_keys, | ||
299 | gpio_keys_store_disabled_keys); | ||
300 | static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, | ||
301 | gpio_keys_show_disabled_switches, | ||
302 | gpio_keys_store_disabled_switches); | ||
303 | |||
304 | static struct attribute *gpio_keys_attrs[] = { | ||
305 | &dev_attr_keys.attr, | ||
306 | &dev_attr_switches.attr, | ||
307 | &dev_attr_disabled_keys.attr, | ||
308 | &dev_attr_disabled_switches.attr, | ||
309 | NULL, | ||
310 | }; | ||
311 | |||
312 | static struct attribute_group gpio_keys_attr_group = { | ||
313 | .attrs = gpio_keys_attrs, | ||
314 | }; | ||
315 | |||
40 | static void gpio_keys_report_event(struct gpio_button_data *bdata) | 316 | static void gpio_keys_report_event(struct gpio_button_data *bdata) |
41 | { | 317 | { |
42 | struct gpio_keys_button *button = bdata->button; | 318 | struct gpio_keys_button *button = bdata->button; |
@@ -79,11 +355,13 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
79 | return IRQ_HANDLED; | 355 | return IRQ_HANDLED; |
80 | } | 356 | } |
81 | 357 | ||
82 | static int __devinit gpio_keys_setup_key(struct device *dev, | 358 | static int __devinit gpio_keys_setup_key(struct platform_device *pdev, |
83 | struct gpio_button_data *bdata, | 359 | struct gpio_button_data *bdata, |
84 | struct gpio_keys_button *button) | 360 | struct gpio_keys_button *button) |
85 | { | 361 | { |
86 | char *desc = button->desc ? button->desc : "gpio_keys"; | 362 | char *desc = button->desc ? button->desc : "gpio_keys"; |
363 | struct device *dev = &pdev->dev; | ||
364 | unsigned long irqflags; | ||
87 | int irq, error; | 365 | int irq, error; |
88 | 366 | ||
89 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); | 367 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); |
@@ -112,10 +390,15 @@ static int __devinit gpio_keys_setup_key(struct device *dev, | |||
112 | goto fail3; | 390 | goto fail3; |
113 | } | 391 | } |
114 | 392 | ||
115 | error = request_irq(irq, gpio_keys_isr, | 393 | irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; |
116 | IRQF_SHARED | | 394 | /* |
117 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 395 | * If platform has specified that the button can be disabled, |
118 | desc, bdata); | 396 | * we don't want it to share the interrupt line. |
397 | */ | ||
398 | if (!button->can_disable) | ||
399 | irqflags |= IRQF_SHARED; | ||
400 | |||
401 | error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); | ||
119 | if (error) { | 402 | if (error) { |
120 | dev_err(dev, "Unable to claim irq %d; error %d\n", | 403 | dev_err(dev, "Unable to claim irq %d; error %d\n", |
121 | irq, error); | 404 | irq, error); |
@@ -149,6 +432,10 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
149 | goto fail1; | 432 | goto fail1; |
150 | } | 433 | } |
151 | 434 | ||
435 | ddata->input = input; | ||
436 | ddata->n_buttons = pdata->nbuttons; | ||
437 | mutex_init(&ddata->disable_lock); | ||
438 | |||
152 | platform_set_drvdata(pdev, ddata); | 439 | platform_set_drvdata(pdev, ddata); |
153 | 440 | ||
154 | input->name = pdev->name; | 441 | input->name = pdev->name; |
@@ -164,8 +451,6 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
164 | if (pdata->rep) | 451 | if (pdata->rep) |
165 | __set_bit(EV_REP, input->evbit); | 452 | __set_bit(EV_REP, input->evbit); |
166 | 453 | ||
167 | ddata->input = input; | ||
168 | |||
169 | for (i = 0; i < pdata->nbuttons; i++) { | 454 | for (i = 0; i < pdata->nbuttons; i++) { |
170 | struct gpio_keys_button *button = &pdata->buttons[i]; | 455 | struct gpio_keys_button *button = &pdata->buttons[i]; |
171 | struct gpio_button_data *bdata = &ddata->data[i]; | 456 | struct gpio_button_data *bdata = &ddata->data[i]; |
@@ -174,7 +459,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
174 | bdata->input = input; | 459 | bdata->input = input; |
175 | bdata->button = button; | 460 | bdata->button = button; |
176 | 461 | ||
177 | error = gpio_keys_setup_key(dev, bdata, button); | 462 | error = gpio_keys_setup_key(pdev, bdata, button); |
178 | if (error) | 463 | if (error) |
179 | goto fail2; | 464 | goto fail2; |
180 | 465 | ||
@@ -184,13 +469,20 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
184 | input_set_capability(input, type, button->code); | 469 | input_set_capability(input, type, button->code); |
185 | } | 470 | } |
186 | 471 | ||
187 | error = input_register_device(input); | 472 | error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); |
188 | if (error) { | 473 | if (error) { |
189 | dev_err(dev, "Unable to register input device, " | 474 | dev_err(dev, "Unable to export keys/switches, error: %d\n", |
190 | "error: %d\n", error); | 475 | error); |
191 | goto fail2; | 476 | goto fail2; |
192 | } | 477 | } |
193 | 478 | ||
479 | error = input_register_device(input); | ||
480 | if (error) { | ||
481 | dev_err(dev, "Unable to register input device, error: %d\n", | ||
482 | error); | ||
483 | goto fail3; | ||
484 | } | ||
485 | |||
194 | /* get current state of buttons */ | 486 | /* get current state of buttons */ |
195 | for (i = 0; i < pdata->nbuttons; i++) | 487 | for (i = 0; i < pdata->nbuttons; i++) |
196 | gpio_keys_report_event(&ddata->data[i]); | 488 | gpio_keys_report_event(&ddata->data[i]); |
@@ -200,6 +492,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
200 | 492 | ||
201 | return 0; | 493 | return 0; |
202 | 494 | ||
495 | fail3: | ||
496 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
203 | fail2: | 497 | fail2: |
204 | while (--i >= 0) { | 498 | while (--i >= 0) { |
205 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 499 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
@@ -224,6 +518,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
224 | struct input_dev *input = ddata->input; | 518 | struct input_dev *input = ddata->input; |
225 | int i; | 519 | int i; |
226 | 520 | ||
521 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
522 | |||
227 | device_init_wakeup(&pdev->dev, 0); | 523 | device_init_wakeup(&pdev->dev, 0); |
228 | 524 | ||
229 | for (i = 0; i < pdata->nbuttons; i++) { | 525 | for (i = 0; i < pdata->nbuttons; i++) { |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c new file mode 100644 index 000000000000..2ee5b798024d --- /dev/null +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -0,0 +1,594 @@ | |||
1 | /* | ||
2 | * Driver for the IMX keypad port. | ||
3 | * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * <<Power management needs to be implemented>>. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input/matrix_keypad.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/timer.h> | ||
25 | |||
26 | /* | ||
27 | * Keypad Controller registers (halfword) | ||
28 | */ | ||
29 | #define KPCR 0x00 /* Keypad Control Register */ | ||
30 | |||
31 | #define KPSR 0x02 /* Keypad Status Register */ | ||
32 | #define KBD_STAT_KPKD (0x1 << 0) /* Key Press Interrupt Status bit (w1c) */ | ||
33 | #define KBD_STAT_KPKR (0x1 << 1) /* Key Release Interrupt Status bit (w1c) */ | ||
34 | #define KBD_STAT_KDSC (0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/ | ||
35 | #define KBD_STAT_KRSS (0x1 << 3) /* Key Release Synch Status bit (w1c)*/ | ||
36 | #define KBD_STAT_KDIE (0x1 << 8) /* Key Depress Interrupt Enable Status bit */ | ||
37 | #define KBD_STAT_KRIE (0x1 << 9) /* Key Release Interrupt Enable */ | ||
38 | #define KBD_STAT_KPPEN (0x1 << 10) /* Keypad Clock Enable */ | ||
39 | |||
40 | #define KDDR 0x04 /* Keypad Data Direction Register */ | ||
41 | #define KPDR 0x06 /* Keypad Data Register */ | ||
42 | |||
43 | #define MAX_MATRIX_KEY_ROWS 8 | ||
44 | #define MAX_MATRIX_KEY_COLS 8 | ||
45 | #define MATRIX_ROW_SHIFT 3 | ||
46 | |||
47 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | ||
48 | |||
49 | struct imx_keypad { | ||
50 | |||
51 | struct clk *clk; | ||
52 | struct input_dev *input_dev; | ||
53 | void __iomem *mmio_base; | ||
54 | |||
55 | int irq; | ||
56 | struct timer_list check_matrix_timer; | ||
57 | |||
58 | /* | ||
59 | * The matrix is stable only if no changes are detected after | ||
60 | * IMX_KEYPAD_SCANS_FOR_STABILITY scans | ||
61 | */ | ||
62 | #define IMX_KEYPAD_SCANS_FOR_STABILITY 3 | ||
63 | int stable_count; | ||
64 | |||
65 | bool enabled; | ||
66 | |||
67 | /* Masks for enabled rows/cols */ | ||
68 | unsigned short rows_en_mask; | ||
69 | unsigned short cols_en_mask; | ||
70 | |||
71 | unsigned short keycodes[MAX_MATRIX_KEY_NUM]; | ||
72 | |||
73 | /* | ||
74 | * Matrix states: | ||
75 | * -stable: achieved after a complete debounce process. | ||
76 | * -unstable: used in the debouncing process. | ||
77 | */ | ||
78 | unsigned short matrix_stable_state[MAX_MATRIX_KEY_COLS]; | ||
79 | unsigned short matrix_unstable_state[MAX_MATRIX_KEY_COLS]; | ||
80 | }; | ||
81 | |||
82 | /* Scan the matrix and return the new state in *matrix_volatile_state. */ | ||
83 | static void imx_keypad_scan_matrix(struct imx_keypad *keypad, | ||
84 | unsigned short *matrix_volatile_state) | ||
85 | { | ||
86 | int col; | ||
87 | unsigned short reg_val; | ||
88 | |||
89 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
90 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
91 | continue; | ||
92 | /* | ||
93 | * Discharge keypad capacitance: | ||
94 | * 2. write 1s on column data. | ||
95 | * 3. configure columns as totem-pole to discharge capacitance. | ||
96 | * 4. configure columns as open-drain. | ||
97 | */ | ||
98 | reg_val = readw(keypad->mmio_base + KPDR); | ||
99 | reg_val |= 0xff00; | ||
100 | writew(reg_val, keypad->mmio_base + KPDR); | ||
101 | |||
102 | reg_val = readw(keypad->mmio_base + KPCR); | ||
103 | reg_val &= ~((keypad->cols_en_mask & 0xff) << 8); | ||
104 | writew(reg_val, keypad->mmio_base + KPCR); | ||
105 | |||
106 | udelay(2); | ||
107 | |||
108 | reg_val = readw(keypad->mmio_base + KPCR); | ||
109 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; | ||
110 | writew(reg_val, keypad->mmio_base + KPCR); | ||
111 | |||
112 | /* | ||
113 | * 5. Write a single column to 0, others to 1. | ||
114 | * 6. Sample row inputs and save data. | ||
115 | * 7. Repeat steps 2 - 6 for remaining columns. | ||
116 | */ | ||
117 | reg_val = readw(keypad->mmio_base + KPDR); | ||
118 | reg_val &= ~(1 << (8 + col)); | ||
119 | writew(reg_val, keypad->mmio_base + KPDR); | ||
120 | |||
121 | /* | ||
122 | * Delay added to avoid propagating the 0 from column to row | ||
123 | * when scanning. | ||
124 | */ | ||
125 | udelay(5); | ||
126 | |||
127 | /* | ||
128 | * 1s in matrix_volatile_state[col] means key pressures | ||
129 | * throw data from non enabled rows. | ||
130 | */ | ||
131 | reg_val = readw(keypad->mmio_base + KPDR); | ||
132 | matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask; | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * Return in standby mode: | ||
137 | * 9. write 0s to columns | ||
138 | */ | ||
139 | reg_val = readw(keypad->mmio_base + KPDR); | ||
140 | reg_val &= 0x00ff; | ||
141 | writew(reg_val, keypad->mmio_base + KPDR); | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Compare the new matrix state (volatile) with the stable one stored in | ||
146 | * keypad->matrix_stable_state and fire events if changes are detected. | ||
147 | */ | ||
148 | static void imx_keypad_fire_events(struct imx_keypad *keypad, | ||
149 | unsigned short *matrix_volatile_state) | ||
150 | { | ||
151 | struct input_dev *input_dev = keypad->input_dev; | ||
152 | int row, col; | ||
153 | |||
154 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
155 | unsigned short bits_changed; | ||
156 | int code; | ||
157 | |||
158 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
159 | continue; /* Column is not enabled */ | ||
160 | |||
161 | bits_changed = keypad->matrix_stable_state[col] ^ | ||
162 | matrix_volatile_state[col]; | ||
163 | |||
164 | if (bits_changed == 0) | ||
165 | continue; /* Column does not contain changes */ | ||
166 | |||
167 | for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { | ||
168 | if ((keypad->rows_en_mask & (1 << row)) == 0) | ||
169 | continue; /* Row is not enabled */ | ||
170 | if ((bits_changed & (1 << row)) == 0) | ||
171 | continue; /* Row does not contain changes */ | ||
172 | |||
173 | code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); | ||
174 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
175 | input_report_key(input_dev, keypad->keycodes[code], | ||
176 | matrix_volatile_state[col] & (1 << row)); | ||
177 | dev_dbg(&input_dev->dev, "Event code: %d, val: %d", | ||
178 | keypad->keycodes[code], | ||
179 | matrix_volatile_state[col] & (1 << row)); | ||
180 | } | ||
181 | } | ||
182 | input_sync(input_dev); | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * imx_keypad_check_for_events is the timer handler. | ||
187 | */ | ||
188 | static void imx_keypad_check_for_events(unsigned long data) | ||
189 | { | ||
190 | struct imx_keypad *keypad = (struct imx_keypad *) data; | ||
191 | unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS]; | ||
192 | unsigned short reg_val; | ||
193 | bool state_changed, is_zero_matrix; | ||
194 | int i; | ||
195 | |||
196 | memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state)); | ||
197 | |||
198 | imx_keypad_scan_matrix(keypad, matrix_volatile_state); | ||
199 | |||
200 | state_changed = false; | ||
201 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
202 | if ((keypad->cols_en_mask & (1 << i)) == 0) | ||
203 | continue; | ||
204 | |||
205 | if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) { | ||
206 | state_changed = true; | ||
207 | break; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * If the matrix state is changed from the previous scan | ||
213 | * (Re)Begin the debouncing process, saving the new state in | ||
214 | * keypad->matrix_unstable_state. | ||
215 | * else | ||
216 | * Increase the count of number of scans with a stable state. | ||
217 | */ | ||
218 | if (state_changed) { | ||
219 | memcpy(keypad->matrix_unstable_state, matrix_volatile_state, | ||
220 | sizeof(matrix_volatile_state)); | ||
221 | keypad->stable_count = 0; | ||
222 | } else | ||
223 | keypad->stable_count++; | ||
224 | |||
225 | /* | ||
226 | * If the matrix is not as stable as we want reschedule scan | ||
227 | * in the near future. | ||
228 | */ | ||
229 | if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
230 | mod_timer(&keypad->check_matrix_timer, | ||
231 | jiffies + msecs_to_jiffies(10)); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * If the matrix state is stable, fire the events and save the new | ||
237 | * stable state. Note, if the matrix is kept stable for longer | ||
238 | * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all | ||
239 | * events have already been generated. | ||
240 | */ | ||
241 | if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
242 | imx_keypad_fire_events(keypad, matrix_volatile_state); | ||
243 | |||
244 | memcpy(keypad->matrix_stable_state, matrix_volatile_state, | ||
245 | sizeof(matrix_volatile_state)); | ||
246 | } | ||
247 | |||
248 | is_zero_matrix = true; | ||
249 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
250 | if (matrix_volatile_state[i] != 0) { | ||
251 | is_zero_matrix = false; | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | |||
257 | if (is_zero_matrix) { | ||
258 | /* | ||
259 | * All keys have been released. Enable only the KDI | ||
260 | * interrupt for future key presses (clear the KDI | ||
261 | * status bit and its sync chain before that). | ||
262 | */ | ||
263 | reg_val = readw(keypad->mmio_base + KPSR); | ||
264 | reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC; | ||
265 | writew(reg_val, keypad->mmio_base + KPSR); | ||
266 | |||
267 | reg_val = readw(keypad->mmio_base + KPSR); | ||
268 | reg_val |= KBD_STAT_KDIE; | ||
269 | reg_val &= ~KBD_STAT_KRIE; | ||
270 | writew(reg_val, keypad->mmio_base + KPSR); | ||
271 | } else { | ||
272 | /* | ||
273 | * Some keys are still pressed. Schedule a rescan in | ||
274 | * attempt to detect multiple key presses and enable | ||
275 | * the KRI interrupt to react quickly to key release | ||
276 | * event. | ||
277 | */ | ||
278 | mod_timer(&keypad->check_matrix_timer, | ||
279 | jiffies + msecs_to_jiffies(60)); | ||
280 | |||
281 | reg_val = readw(keypad->mmio_base + KPSR); | ||
282 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS; | ||
283 | writew(reg_val, keypad->mmio_base + KPSR); | ||
284 | |||
285 | reg_val = readw(keypad->mmio_base + KPSR); | ||
286 | reg_val |= KBD_STAT_KRIE; | ||
287 | reg_val &= ~KBD_STAT_KDIE; | ||
288 | writew(reg_val, keypad->mmio_base + KPSR); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id) | ||
293 | { | ||
294 | struct imx_keypad *keypad = dev_id; | ||
295 | unsigned short reg_val; | ||
296 | |||
297 | reg_val = readw(keypad->mmio_base + KPSR); | ||
298 | |||
299 | /* Disable both interrupt types */ | ||
300 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
301 | /* Clear interrupts status bits */ | ||
302 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
303 | writew(reg_val, keypad->mmio_base + KPSR); | ||
304 | |||
305 | if (keypad->enabled) { | ||
306 | /* The matrix is supposed to be changed */ | ||
307 | keypad->stable_count = 0; | ||
308 | |||
309 | /* Schedule the scanning procedure near in the future */ | ||
310 | mod_timer(&keypad->check_matrix_timer, | ||
311 | jiffies + msecs_to_jiffies(2)); | ||
312 | } | ||
313 | |||
314 | return IRQ_HANDLED; | ||
315 | } | ||
316 | |||
317 | static void imx_keypad_config(struct imx_keypad *keypad) | ||
318 | { | ||
319 | unsigned short reg_val; | ||
320 | |||
321 | /* | ||
322 | * Include enabled rows in interrupt generation (KPCR[7:0]) | ||
323 | * Configure keypad columns as open-drain (KPCR[15:8]) | ||
324 | */ | ||
325 | reg_val = readw(keypad->mmio_base + KPCR); | ||
326 | reg_val |= keypad->rows_en_mask & 0xff; /* rows */ | ||
327 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */ | ||
328 | writew(reg_val, keypad->mmio_base + KPCR); | ||
329 | |||
330 | /* Write 0's to KPDR[15:8] (Colums) */ | ||
331 | reg_val = readw(keypad->mmio_base + KPDR); | ||
332 | reg_val &= 0x00ff; | ||
333 | writew(reg_val, keypad->mmio_base + KPDR); | ||
334 | |||
335 | /* Configure columns as output, rows as input (KDDR[15:0]) */ | ||
336 | writew(0xff00, keypad->mmio_base + KDDR); | ||
337 | |||
338 | /* | ||
339 | * Clear Key Depress and Key Release status bit. | ||
340 | * Clear both synchronizer chain. | ||
341 | */ | ||
342 | reg_val = readw(keypad->mmio_base + KPSR); | ||
343 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD | | ||
344 | KBD_STAT_KDSC | KBD_STAT_KRSS; | ||
345 | writew(reg_val, keypad->mmio_base + KPSR); | ||
346 | |||
347 | /* Enable KDI and disable KRI (avoid false release events). */ | ||
348 | reg_val |= KBD_STAT_KDIE; | ||
349 | reg_val &= ~KBD_STAT_KRIE; | ||
350 | writew(reg_val, keypad->mmio_base + KPSR); | ||
351 | } | ||
352 | |||
353 | static void imx_keypad_inhibit(struct imx_keypad *keypad) | ||
354 | { | ||
355 | unsigned short reg_val; | ||
356 | |||
357 | /* Inhibit KDI and KRI interrupts. */ | ||
358 | reg_val = readw(keypad->mmio_base + KPSR); | ||
359 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
360 | writew(reg_val, keypad->mmio_base + KPSR); | ||
361 | |||
362 | /* Colums as open drain and disable all rows */ | ||
363 | writew(0xff00, keypad->mmio_base + KPCR); | ||
364 | } | ||
365 | |||
366 | static void imx_keypad_close(struct input_dev *dev) | ||
367 | { | ||
368 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
369 | |||
370 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
371 | |||
372 | /* Mark keypad as being inactive */ | ||
373 | keypad->enabled = false; | ||
374 | synchronize_irq(keypad->irq); | ||
375 | del_timer_sync(&keypad->check_matrix_timer); | ||
376 | |||
377 | imx_keypad_inhibit(keypad); | ||
378 | |||
379 | /* Disable clock unit */ | ||
380 | clk_disable(keypad->clk); | ||
381 | } | ||
382 | |||
383 | static int imx_keypad_open(struct input_dev *dev) | ||
384 | { | ||
385 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
386 | |||
387 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
388 | |||
389 | /* We became active from now */ | ||
390 | keypad->enabled = true; | ||
391 | |||
392 | /* Enable the kpp clock */ | ||
393 | clk_enable(keypad->clk); | ||
394 | imx_keypad_config(keypad); | ||
395 | |||
396 | /* Sanity control, not all the rows must be actived now. */ | ||
397 | if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) { | ||
398 | dev_err(&dev->dev, | ||
399 | "too many keys pressed, control pins initialisation\n"); | ||
400 | goto open_err; | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | |||
405 | open_err: | ||
406 | imx_keypad_close(dev); | ||
407 | return -EIO; | ||
408 | } | ||
409 | |||
410 | static int __devinit imx_keypad_probe(struct platform_device *pdev) | ||
411 | { | ||
412 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; | ||
413 | struct imx_keypad *keypad; | ||
414 | struct input_dev *input_dev; | ||
415 | struct resource *res; | ||
416 | int irq, error, i; | ||
417 | |||
418 | if (keymap_data == NULL) { | ||
419 | dev_err(&pdev->dev, "no keymap defined\n"); | ||
420 | return -EINVAL; | ||
421 | } | ||
422 | |||
423 | irq = platform_get_irq(pdev, 0); | ||
424 | if (irq < 0) { | ||
425 | dev_err(&pdev->dev, "no irq defined in platform data\n"); | ||
426 | return -EINVAL; | ||
427 | } | ||
428 | |||
429 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
430 | if (res == NULL) { | ||
431 | dev_err(&pdev->dev, "no I/O memory defined in platform data\n"); | ||
432 | return -EINVAL; | ||
433 | } | ||
434 | |||
435 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
436 | if (res == NULL) { | ||
437 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
438 | return -EBUSY; | ||
439 | } | ||
440 | |||
441 | input_dev = input_allocate_device(); | ||
442 | if (!input_dev) { | ||
443 | dev_err(&pdev->dev, "failed to allocate the input device\n"); | ||
444 | error = -ENOMEM; | ||
445 | goto failed_rel_mem; | ||
446 | } | ||
447 | |||
448 | keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL); | ||
449 | if (!keypad) { | ||
450 | dev_err(&pdev->dev, "not enough memory for driver data\n"); | ||
451 | error = -ENOMEM; | ||
452 | goto failed_free_input; | ||
453 | } | ||
454 | |||
455 | keypad->input_dev = input_dev; | ||
456 | keypad->irq = irq; | ||
457 | keypad->stable_count = 0; | ||
458 | |||
459 | setup_timer(&keypad->check_matrix_timer, | ||
460 | imx_keypad_check_for_events, (unsigned long) keypad); | ||
461 | |||
462 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | ||
463 | if (keypad->mmio_base == NULL) { | ||
464 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
465 | error = -ENOMEM; | ||
466 | goto failed_free_priv; | ||
467 | } | ||
468 | |||
469 | keypad->clk = clk_get(&pdev->dev, "kpp"); | ||
470 | if (IS_ERR(keypad->clk)) { | ||
471 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
472 | error = PTR_ERR(keypad->clk); | ||
473 | goto failed_unmap; | ||
474 | } | ||
475 | |||
476 | /* Search for rows and cols enabled */ | ||
477 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
478 | keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]); | ||
479 | keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]); | ||
480 | } | ||
481 | |||
482 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || | ||
483 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { | ||
484 | dev_err(&pdev->dev, | ||
485 | "invalid key data (too many rows or colums)\n"); | ||
486 | error = -EINVAL; | ||
487 | goto failed_clock_put; | ||
488 | } | ||
489 | dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); | ||
490 | dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); | ||
491 | |||
492 | /* Init the Input device */ | ||
493 | input_dev->name = pdev->name; | ||
494 | input_dev->id.bustype = BUS_HOST; | ||
495 | input_dev->dev.parent = &pdev->dev; | ||
496 | input_dev->open = imx_keypad_open; | ||
497 | input_dev->close = imx_keypad_close; | ||
498 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
499 | input_dev->keycode = keypad->keycodes; | ||
500 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
501 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
502 | |||
503 | matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, | ||
504 | keypad->keycodes, input_dev->keybit); | ||
505 | |||
506 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
507 | input_set_drvdata(input_dev, keypad); | ||
508 | |||
509 | /* Ensure that the keypad will stay dormant until opened */ | ||
510 | imx_keypad_inhibit(keypad); | ||
511 | |||
512 | error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED, | ||
513 | pdev->name, keypad); | ||
514 | if (error) { | ||
515 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
516 | goto failed_clock_put; | ||
517 | } | ||
518 | |||
519 | /* Register the input device */ | ||
520 | error = input_register_device(input_dev); | ||
521 | if (error) { | ||
522 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
523 | goto failed_free_irq; | ||
524 | } | ||
525 | |||
526 | platform_set_drvdata(pdev, keypad); | ||
527 | device_init_wakeup(&pdev->dev, 1); | ||
528 | |||
529 | return 0; | ||
530 | |||
531 | failed_free_irq: | ||
532 | free_irq(irq, pdev); | ||
533 | failed_clock_put: | ||
534 | clk_put(keypad->clk); | ||
535 | failed_unmap: | ||
536 | iounmap(keypad->mmio_base); | ||
537 | failed_free_priv: | ||
538 | kfree(keypad); | ||
539 | failed_free_input: | ||
540 | input_free_device(input_dev); | ||
541 | failed_rel_mem: | ||
542 | release_mem_region(res->start, resource_size(res)); | ||
543 | return error; | ||
544 | } | ||
545 | |||
546 | static int __devexit imx_keypad_remove(struct platform_device *pdev) | ||
547 | { | ||
548 | struct imx_keypad *keypad = platform_get_drvdata(pdev); | ||
549 | struct resource *res; | ||
550 | |||
551 | dev_dbg(&pdev->dev, ">%s\n", __func__); | ||
552 | |||
553 | platform_set_drvdata(pdev, NULL); | ||
554 | |||
555 | input_unregister_device(keypad->input_dev); | ||
556 | |||
557 | free_irq(keypad->irq, keypad); | ||
558 | clk_put(keypad->clk); | ||
559 | |||
560 | iounmap(keypad->mmio_base); | ||
561 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
562 | release_mem_region(res->start, resource_size(res)); | ||
563 | |||
564 | kfree(keypad); | ||
565 | |||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static struct platform_driver imx_keypad_driver = { | ||
570 | .driver = { | ||
571 | .name = "imx-keypad", | ||
572 | .owner = THIS_MODULE, | ||
573 | }, | ||
574 | .probe = imx_keypad_probe, | ||
575 | .remove = __devexit_p(imx_keypad_remove), | ||
576 | }; | ||
577 | |||
578 | static int __init imx_keypad_init(void) | ||
579 | { | ||
580 | return platform_driver_register(&imx_keypad_driver); | ||
581 | } | ||
582 | |||
583 | static void __exit imx_keypad_exit(void) | ||
584 | { | ||
585 | platform_driver_unregister(&imx_keypad_driver); | ||
586 | } | ||
587 | |||
588 | module_init(imx_keypad_init); | ||
589 | module_exit(imx_keypad_exit); | ||
590 | |||
591 | MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); | ||
592 | MODULE_DESCRIPTION("IMX Keypad Port Driver"); | ||
593 | MODULE_LICENSE("GPL v2"); | ||
594 | MODULE_ALIAS("platform:imx-keypad"); | ||
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 191cc51d6cf8..31f30087b591 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
@@ -362,7 +362,7 @@ static int __devexit qt2160_remove(struct i2c_client *client) | |||
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
364 | 364 | ||
365 | static struct i2c_device_id qt2160_idtable[] = { | 365 | static const struct i2c_device_id qt2160_idtable[] = { |
366 | { "qt2160", 0, }, | 366 | { "qt2160", 0, }, |
367 | { } | 367 | { } |
368 | }; | 368 | }; |
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 8e9380bfed40..854e2035cd6e 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -19,101 +19,141 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/input/sh_keysc.h> | 21 | #include <linux/input/sh_keysc.h> |
22 | #include <linux/bitmap.h> | ||
22 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
23 | #include <linux/io.h> | 24 | #include <linux/io.h> |
24 | 25 | ||
25 | #define KYCR1_OFFS 0x00 | ||
26 | #define KYCR2_OFFS 0x04 | ||
27 | #define KYINDR_OFFS 0x08 | ||
28 | #define KYOUTDR_OFFS 0x0c | ||
29 | |||
30 | #define KYCR2_IRQ_LEVEL 0x10 | ||
31 | #define KYCR2_IRQ_DISABLED 0x00 | ||
32 | |||
33 | static const struct { | 26 | static const struct { |
34 | unsigned char kymd, keyout, keyin; | 27 | unsigned char kymd, keyout, keyin; |
35 | } sh_keysc_mode[] = { | 28 | } sh_keysc_mode[] = { |
36 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, | 29 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, |
37 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, | 30 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, |
38 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, | 31 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, |
32 | [SH_KEYSC_MODE_4] = { 3, 6, 6 }, | ||
33 | [SH_KEYSC_MODE_5] = { 4, 6, 7 }, | ||
34 | [SH_KEYSC_MODE_6] = { 5, 7, 7 }, | ||
39 | }; | 35 | }; |
40 | 36 | ||
41 | struct sh_keysc_priv { | 37 | struct sh_keysc_priv { |
42 | void __iomem *iomem_base; | 38 | void __iomem *iomem_base; |
43 | struct clk *clk; | 39 | struct clk *clk; |
44 | unsigned long last_keys; | 40 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); |
45 | struct input_dev *input; | 41 | struct input_dev *input; |
46 | struct sh_keysc_info pdata; | 42 | struct sh_keysc_info pdata; |
47 | }; | 43 | }; |
48 | 44 | ||
45 | #define KYCR1 0 | ||
46 | #define KYCR2 1 | ||
47 | #define KYINDR 2 | ||
48 | #define KYOUTDR 3 | ||
49 | |||
50 | #define KYCR2_IRQ_LEVEL 0x10 | ||
51 | #define KYCR2_IRQ_DISABLED 0x00 | ||
52 | |||
53 | static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr) | ||
54 | { | ||
55 | return ioread16(p->iomem_base + (reg_nr << 2)); | ||
56 | } | ||
57 | |||
58 | static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr, | ||
59 | unsigned long value) | ||
60 | { | ||
61 | iowrite16(value, p->iomem_base + (reg_nr << 2)); | ||
62 | } | ||
63 | |||
64 | static void sh_keysc_level_mode(struct sh_keysc_priv *p, | ||
65 | unsigned long keys_set) | ||
66 | { | ||
67 | struct sh_keysc_info *pdata = &p->pdata; | ||
68 | |||
69 | sh_keysc_write(p, KYOUTDR, 0); | ||
70 | sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8)); | ||
71 | |||
72 | if (pdata->kycr2_delay) | ||
73 | udelay(pdata->kycr2_delay); | ||
74 | } | ||
75 | |||
76 | static void sh_keysc_map_dbg(struct device *dev, unsigned long *map, | ||
77 | const char *str) | ||
78 | { | ||
79 | int k; | ||
80 | |||
81 | for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++) | ||
82 | dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]); | ||
83 | } | ||
84 | |||
49 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | 85 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) |
50 | { | 86 | { |
51 | struct platform_device *pdev = dev_id; | 87 | struct platform_device *pdev = dev_id; |
52 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 88 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
53 | struct sh_keysc_info *pdata = &priv->pdata; | 89 | struct sh_keysc_info *pdata = &priv->pdata; |
54 | unsigned long keys, keys1, keys0, mask; | 90 | int keyout_nr = sh_keysc_mode[pdata->mode].keyout; |
91 | int keyin_nr = sh_keysc_mode[pdata->mode].keyin; | ||
92 | DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS); | ||
93 | DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS); | ||
94 | DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS); | ||
55 | unsigned char keyin_set, tmp; | 95 | unsigned char keyin_set, tmp; |
56 | int i, k; | 96 | int i, k, n; |
57 | 97 | ||
58 | dev_dbg(&pdev->dev, "isr!\n"); | 98 | dev_dbg(&pdev->dev, "isr!\n"); |
59 | 99 | ||
60 | keys1 = ~0; | 100 | bitmap_fill(keys1, SH_KEYSC_MAXKEYS); |
61 | keys0 = 0; | 101 | bitmap_zero(keys0, SH_KEYSC_MAXKEYS); |
62 | 102 | ||
63 | do { | 103 | do { |
64 | keys = 0; | 104 | bitmap_zero(keys, SH_KEYSC_MAXKEYS); |
65 | keyin_set = 0; | 105 | keyin_set = 0; |
66 | 106 | ||
67 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 107 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
108 | |||
109 | for (i = 0; i < keyout_nr; i++) { | ||
110 | n = keyin_nr * i; | ||
68 | 111 | ||
69 | for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { | 112 | /* drive one KEYOUT pin low, read KEYIN pins */ |
70 | iowrite16(0xfff ^ (3 << (i * 2)), | 113 | sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2))); |
71 | priv->iomem_base + KYOUTDR_OFFS); | ||
72 | udelay(pdata->delay); | 114 | udelay(pdata->delay); |
73 | tmp = ioread16(priv->iomem_base + KYINDR_OFFS); | 115 | tmp = sh_keysc_read(priv, KYINDR); |
74 | keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); | ||
75 | tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; | ||
76 | keyin_set |= tmp; | ||
77 | } | ||
78 | 116 | ||
79 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 117 | /* set bit if key press has been detected */ |
80 | iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), | 118 | for (k = 0; k < keyin_nr; k++) { |
81 | priv->iomem_base + KYCR2_OFFS); | 119 | if (tmp & (1 << k)) |
120 | __set_bit(n + k, keys); | ||
121 | } | ||
82 | 122 | ||
83 | if (pdata->kycr2_delay) | 123 | /* keep track of which KEYIN bits that have been set */ |
84 | udelay(pdata->kycr2_delay); | 124 | keyin_set |= tmp ^ ((1 << keyin_nr) - 1); |
125 | } | ||
85 | 126 | ||
86 | keys ^= ~0; | 127 | sh_keysc_level_mode(priv, keyin_set); |
87 | keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * | ||
88 | sh_keysc_mode[pdata->mode].keyout)) - 1; | ||
89 | keys1 &= keys; | ||
90 | keys0 |= keys; | ||
91 | 128 | ||
92 | dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); | 129 | bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS); |
130 | bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS); | ||
131 | bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS); | ||
93 | 132 | ||
94 | } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); | 133 | sh_keysc_map_dbg(&pdev->dev, keys, "keys"); |
95 | 134 | ||
96 | dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", | 135 | } while (sh_keysc_read(priv, KYCR2) & 0x01); |
97 | priv->last_keys, keys0, keys1); | 136 | |
137 | sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys"); | ||
138 | sh_keysc_map_dbg(&pdev->dev, keys0, "keys0"); | ||
139 | sh_keysc_map_dbg(&pdev->dev, keys1, "keys1"); | ||
98 | 140 | ||
99 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | 141 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { |
100 | k = pdata->keycodes[i]; | 142 | k = pdata->keycodes[i]; |
101 | if (!k) | 143 | if (!k) |
102 | continue; | 144 | continue; |
103 | 145 | ||
104 | mask = 1 << i; | 146 | if (test_bit(i, keys0) == test_bit(i, priv->last_keys)) |
105 | |||
106 | if (!((priv->last_keys ^ keys0) & mask)) | ||
107 | continue; | 147 | continue; |
108 | 148 | ||
109 | if ((keys1 | keys0) & mask) { | 149 | if (test_bit(i, keys1) || test_bit(i, keys0)) { |
110 | input_event(priv->input, EV_KEY, k, 1); | 150 | input_event(priv->input, EV_KEY, k, 1); |
111 | priv->last_keys |= mask; | 151 | __set_bit(i, priv->last_keys); |
112 | } | 152 | } |
113 | 153 | ||
114 | if (!(keys1 & mask)) { | 154 | if (!test_bit(i, keys1)) { |
115 | input_event(priv->input, EV_KEY, k, 0); | 155 | input_event(priv->input, EV_KEY, k, 0); |
116 | priv->last_keys &= ~mask; | 156 | __clear_bit(i, priv->last_keys); |
117 | } | 157 | } |
118 | 158 | ||
119 | } | 159 | } |
@@ -122,8 +162,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | |||
122 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
123 | } | 163 | } |
124 | 164 | ||
125 | #define res_size(res) ((res)->end - (res)->start + 1) | ||
126 | |||
127 | static int __devinit sh_keysc_probe(struct platform_device *pdev) | 165 | static int __devinit sh_keysc_probe(struct platform_device *pdev) |
128 | { | 166 | { |
129 | struct sh_keysc_priv *priv; | 167 | struct sh_keysc_priv *priv; |
@@ -164,7 +202,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
164 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); | 202 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); |
165 | pdata = &priv->pdata; | 203 | pdata = &priv->pdata; |
166 | 204 | ||
167 | priv->iomem_base = ioremap_nocache(res->start, res_size(res)); | 205 | priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); |
168 | if (priv->iomem_base == NULL) { | 206 | if (priv->iomem_base == NULL) { |
169 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 207 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); |
170 | error = -ENXIO; | 208 | error = -ENXIO; |
@@ -220,10 +258,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
220 | 258 | ||
221 | clk_enable(priv->clk); | 259 | clk_enable(priv->clk); |
222 | 260 | ||
223 | iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | | 261 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | |
224 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | 262 | pdata->scan_timing); |
225 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 263 | sh_keysc_level_mode(priv, 0); |
226 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | ||
227 | 264 | ||
228 | device_init_wakeup(&pdev->dev, 1); | 265 | device_init_wakeup(&pdev->dev, 1); |
229 | 266 | ||
@@ -248,7 +285,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
248 | { | 285 | { |
249 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 286 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
250 | 287 | ||
251 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 288 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
252 | 289 | ||
253 | input_unregister_device(priv->input); | 290 | input_unregister_device(priv->input); |
254 | free_irq(platform_get_irq(pdev, 0), pdev); | 291 | free_irq(platform_get_irq(pdev, 0), pdev); |
@@ -270,7 +307,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
270 | int irq = platform_get_irq(pdev, 0); | 307 | int irq = platform_get_irq(pdev, 0); |
271 | unsigned short value; | 308 | unsigned short value; |
272 | 309 | ||
273 | value = ioread16(priv->iomem_base + KYCR1_OFFS); | 310 | value = sh_keysc_read(priv, KYCR1); |
274 | 311 | ||
275 | if (device_may_wakeup(dev)) { | 312 | if (device_may_wakeup(dev)) { |
276 | value |= 0x80; | 313 | value |= 0x80; |
@@ -279,7 +316,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
279 | value &= ~0x80; | 316 | value &= ~0x80; |
280 | } | 317 | } |
281 | 318 | ||
282 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); | 319 | sh_keysc_write(priv, KYCR1, value); |
283 | 320 | ||
284 | return 0; | 321 | return 0; |
285 | } | 322 | } |