diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/input/keyboard | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/input/keyboard')
49 files changed, 1767 insertions, 3565 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 5a240c60342..b4dee9d5a05 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -33,10 +33,10 @@ config KEYBOARD_ADP5588 | |||
33 | module will be called adp5588-keys. | 33 | module will be called adp5588-keys. |
34 | 34 | ||
35 | config KEYBOARD_ADP5589 | 35 | config KEYBOARD_ADP5589 |
36 | tristate "ADP5585/ADP5589 I2C QWERTY Keypad and IO Expander" | 36 | tristate "ADP5589 I2C QWERTY Keypad and IO Expander" |
37 | depends on I2C | 37 | depends on I2C |
38 | help | 38 | help |
39 | Say Y here if you want to use a ADP5585/ADP5589 attached to your | 39 | Say Y here if you want to use a ADP5589 attached to your |
40 | system I2C bus. | 40 | system I2C bus. |
41 | 41 | ||
42 | To compile this driver as a module, choose M here: the | 42 | To compile this driver as a module, choose M here: the |
@@ -134,7 +134,7 @@ config KEYBOARD_QT1070 | |||
134 | 134 | ||
135 | config KEYBOARD_QT2160 | 135 | config KEYBOARD_QT2160 |
136 | tristate "Atmel AT42QT2160 Touch Sensor Chip" | 136 | tristate "Atmel AT42QT2160 Touch Sensor Chip" |
137 | depends on I2C | 137 | depends on I2C && EXPERIMENTAL |
138 | help | 138 | help |
139 | If you say yes here you get support for Atmel AT42QT2160 Touch | 139 | If you say yes here you get support for Atmel AT42QT2160 Touch |
140 | Sensor chip as a keyboard input. | 140 | Sensor chip as a keyboard input. |
@@ -166,7 +166,6 @@ config KEYBOARD_LKKBD | |||
166 | config KEYBOARD_EP93XX | 166 | config KEYBOARD_EP93XX |
167 | tristate "EP93xx Matrix Keypad support" | 167 | tristate "EP93xx Matrix Keypad support" |
168 | depends on ARCH_EP93XX | 168 | depends on ARCH_EP93XX |
169 | select INPUT_MATRIXKMAP | ||
170 | help | 169 | help |
171 | Say Y here to enable the matrix keypad on the Cirrus EP93XX. | 170 | Say Y here to enable the matrix keypad on the Cirrus EP93XX. |
172 | 171 | ||
@@ -222,27 +221,9 @@ config KEYBOARD_TCA6416 | |||
222 | To compile this driver as a module, choose M here: the | 221 | To compile this driver as a module, choose M here: the |
223 | module will be called tca6416_keypad. | 222 | module will be called tca6416_keypad. |
224 | 223 | ||
225 | config KEYBOARD_TCA8418 | ||
226 | tristate "TCA8418 Keypad Support" | ||
227 | depends on I2C | ||
228 | select INPUT_MATRIXKMAP | ||
229 | help | ||
230 | This driver implements basic keypad functionality | ||
231 | for keys connected through TCA8418 keypad decoder. | ||
232 | |||
233 | Say Y here if your device has keys connected to | ||
234 | TCA8418 keypad decoder. | ||
235 | |||
236 | If enabled the complete TCA8418 device will be managed through | ||
237 | this driver. | ||
238 | |||
239 | To compile this driver as a module, choose M here: the | ||
240 | module will be called tca8418_keypad. | ||
241 | |||
242 | config KEYBOARD_MATRIX | 224 | config KEYBOARD_MATRIX |
243 | tristate "GPIO driven matrix keypad support" | 225 | tristate "GPIO driven matrix keypad support" |
244 | depends on GENERIC_GPIO | 226 | depends on GENERIC_GPIO |
245 | select INPUT_MATRIXKMAP | ||
246 | help | 227 | help |
247 | Enable support for GPIO driven matrix keypad. | 228 | Enable support for GPIO driven matrix keypad. |
248 | 229 | ||
@@ -312,17 +293,6 @@ config KEYBOARD_LM8323 | |||
312 | To compile this driver as a module, choose M here: the | 293 | To compile this driver as a module, choose M here: the |
313 | module will be called lm8323. | 294 | module will be called lm8323. |
314 | 295 | ||
315 | config KEYBOARD_LM8333 | ||
316 | tristate "LM8333 keypad chip" | ||
317 | depends on I2C | ||
318 | select INPUT_MATRIXKMAP | ||
319 | help | ||
320 | If you say yes here you get support for the National Semiconductor | ||
321 | LM8333 keypad controller. | ||
322 | |||
323 | To compile this driver as a module, choose M here: the | ||
324 | module will be called lm8333. | ||
325 | |||
326 | config KEYBOARD_LOCOMO | 296 | config KEYBOARD_LOCOMO |
327 | tristate "LoCoMo Keyboard Support" | 297 | tristate "LoCoMo Keyboard Support" |
328 | depends on SHARP_LOCOMO | 298 | depends on SHARP_LOCOMO |
@@ -332,17 +302,6 @@ config KEYBOARD_LOCOMO | |||
332 | To compile this driver as a module, choose M here: the | 302 | To compile this driver as a module, choose M here: the |
333 | module will be called locomokbd. | 303 | module will be called locomokbd. |
334 | 304 | ||
335 | config KEYBOARD_LPC32XX | ||
336 | tristate "LPC32XX matrix key scanner support" | ||
337 | depends on ARCH_LPC32XX && OF | ||
338 | select INPUT_MATRIXKMAP | ||
339 | help | ||
340 | Say Y here if you want to use NXP LPC32XX SoC key scanner interface, | ||
341 | connected to a key matrix. | ||
342 | |||
343 | To compile this driver as a module, choose M here: the | ||
344 | module will be called lpc32xx-keys. | ||
345 | |||
346 | config KEYBOARD_MAPLE | 305 | config KEYBOARD_MAPLE |
347 | tristate "Maple bus keyboard" | 306 | tristate "Maple bus keyboard" |
348 | depends on SH_DREAMCAST && MAPLE | 307 | depends on SH_DREAMCAST && MAPLE |
@@ -391,7 +350,6 @@ config KEYBOARD_MPR121 | |||
391 | config KEYBOARD_IMX | 350 | config KEYBOARD_IMX |
392 | tristate "IMX keypad support" | 351 | tristate "IMX keypad support" |
393 | depends on ARCH_MXC | 352 | depends on ARCH_MXC |
394 | select INPUT_MATRIXKMAP | ||
395 | help | 353 | help |
396 | Enable support for IMX keypad port. | 354 | Enable support for IMX keypad port. |
397 | 355 | ||
@@ -409,8 +367,7 @@ config KEYBOARD_NEWTON | |||
409 | 367 | ||
410 | config KEYBOARD_NOMADIK | 368 | config KEYBOARD_NOMADIK |
411 | tristate "ST-Ericsson Nomadik SKE keyboard" | 369 | tristate "ST-Ericsson Nomadik SKE keyboard" |
412 | depends on (ARCH_NOMADIK || ARCH_U8500) | 370 | depends on PLAT_NOMADIK |
413 | select INPUT_MATRIXKMAP | ||
414 | help | 371 | help |
415 | Say Y here if you want to use a keypad provided on the SKE controller | 372 | Say Y here if you want to use a keypad provided on the SKE controller |
416 | used on the Ux500 and Nomadik platforms | 373 | used on the Ux500 and Nomadik platforms |
@@ -421,7 +378,6 @@ config KEYBOARD_NOMADIK | |||
421 | config KEYBOARD_TEGRA | 378 | config KEYBOARD_TEGRA |
422 | tristate "NVIDIA Tegra internal matrix keyboard controller support" | 379 | tristate "NVIDIA Tegra internal matrix keyboard controller support" |
423 | depends on ARCH_TEGRA | 380 | depends on ARCH_TEGRA |
424 | select INPUT_MATRIXKMAP | ||
425 | help | 381 | help |
426 | Say Y here if you want to use a matrix keyboard connected directly | 382 | Say Y here if you want to use a matrix keyboard connected directly |
427 | to the internal keyboard controller on Tegra SoCs. | 383 | to the internal keyboard controller on Tegra SoCs. |
@@ -459,7 +415,6 @@ config KEYBOARD_PXA930_ROTARY | |||
459 | config KEYBOARD_PMIC8XXX | 415 | config KEYBOARD_PMIC8XXX |
460 | tristate "Qualcomm PMIC8XXX keypad support" | 416 | tristate "Qualcomm PMIC8XXX keypad support" |
461 | depends on MFD_PM8XXX | 417 | depends on MFD_PM8XXX |
462 | select INPUT_MATRIXKMAP | ||
463 | help | 418 | help |
464 | Say Y here if you want to enable the driver for the PMIC8XXX | 419 | Say Y here if you want to enable the driver for the PMIC8XXX |
465 | keypad provided as a reference design from Qualcomm. This is intended | 420 | keypad provided as a reference design from Qualcomm. This is intended |
@@ -470,11 +425,9 @@ config KEYBOARD_PMIC8XXX | |||
470 | 425 | ||
471 | config KEYBOARD_SAMSUNG | 426 | config KEYBOARD_SAMSUNG |
472 | tristate "Samsung keypad support" | 427 | tristate "Samsung keypad support" |
473 | depends on HAVE_CLK | 428 | depends on SAMSUNG_DEV_KEYPAD |
474 | select INPUT_MATRIXKMAP | ||
475 | help | 429 | help |
476 | Say Y here if you want to use the keypad on your Samsung mobile | 430 | Say Y here if you want to use the Samsung keypad. |
477 | device. | ||
478 | 431 | ||
479 | To compile this driver as a module, choose M here: the | 432 | To compile this driver as a module, choose M here: the |
480 | module will be called samsung-keypad. | 433 | module will be called samsung-keypad. |
@@ -514,7 +467,6 @@ config KEYBOARD_SH_KEYSC | |||
514 | config KEYBOARD_STMPE | 467 | config KEYBOARD_STMPE |
515 | tristate "STMPE keypad support" | 468 | tristate "STMPE keypad support" |
516 | depends on MFD_STMPE | 469 | depends on MFD_STMPE |
517 | select INPUT_MATRIXKMAP | ||
518 | help | 470 | help |
519 | Say Y here if you want to use the keypad controller on STMPE I/O | 471 | Say Y here if you want to use the keypad controller on STMPE I/O |
520 | expanders. | 472 | expanders. |
@@ -534,8 +486,7 @@ config KEYBOARD_DAVINCI | |||
534 | 486 | ||
535 | config KEYBOARD_OMAP | 487 | config KEYBOARD_OMAP |
536 | tristate "TI OMAP keypad support" | 488 | tristate "TI OMAP keypad support" |
537 | depends on ARCH_OMAP1 | 489 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
538 | select INPUT_MATRIXKMAP | ||
539 | help | 490 | help |
540 | Say Y here if you want to use the OMAP keypad. | 491 | Say Y here if you want to use the OMAP keypad. |
541 | 492 | ||
@@ -543,11 +494,10 @@ config KEYBOARD_OMAP | |||
543 | module will be called omap-keypad. | 494 | module will be called omap-keypad. |
544 | 495 | ||
545 | config KEYBOARD_OMAP4 | 496 | config KEYBOARD_OMAP4 |
546 | tristate "TI OMAP4+ keypad support" | 497 | tristate "TI OMAP4 keypad support" |
547 | depends on ARCH_OMAP2PLUS | 498 | depends on ARCH_OMAP4 |
548 | select INPUT_MATRIXKMAP | ||
549 | help | 499 | help |
550 | Say Y here if you want to use the OMAP4+ keypad. | 500 | Say Y here if you want to use the OMAP4 keypad. |
551 | 501 | ||
552 | To compile this driver as a module, choose M here: the | 502 | To compile this driver as a module, choose M here: the |
553 | module will be called omap4-keypad. | 503 | module will be called omap4-keypad. |
@@ -555,7 +505,6 @@ config KEYBOARD_OMAP4 | |||
555 | config KEYBOARD_SPEAR | 505 | config KEYBOARD_SPEAR |
556 | tristate "ST SPEAR keyboard support" | 506 | tristate "ST SPEAR keyboard support" |
557 | depends on PLAT_SPEAR | 507 | depends on PLAT_SPEAR |
558 | select INPUT_MATRIXKMAP | ||
559 | help | 508 | help |
560 | Say Y here if you want to use the SPEAR keyboard. | 509 | Say Y here if you want to use the SPEAR keyboard. |
561 | 510 | ||
@@ -565,7 +514,6 @@ config KEYBOARD_SPEAR | |||
565 | config KEYBOARD_TC3589X | 514 | config KEYBOARD_TC3589X |
566 | tristate "TC3589X Keypad support" | 515 | tristate "TC3589X Keypad support" |
567 | depends on MFD_TC3589X | 516 | depends on MFD_TC3589X |
568 | select INPUT_MATRIXKMAP | ||
569 | help | 517 | help |
570 | Say Y here if you want to use the keypad controller on | 518 | Say Y here if you want to use the keypad controller on |
571 | TC35892/3 I/O expander. | 519 | TC35892/3 I/O expander. |
@@ -576,7 +524,6 @@ config KEYBOARD_TC3589X | |||
576 | config KEYBOARD_TNETV107X | 524 | config KEYBOARD_TNETV107X |
577 | tristate "TI TNETV107X keypad support" | 525 | tristate "TI TNETV107X keypad support" |
578 | depends on ARCH_DAVINCI_TNETV107X | 526 | depends on ARCH_DAVINCI_TNETV107X |
579 | select INPUT_MATRIXKMAP | ||
580 | help | 527 | help |
581 | Say Y here if you want to use the TNETV107X keypad. | 528 | Say Y here if you want to use the TNETV107X keypad. |
582 | 529 | ||
@@ -586,7 +533,6 @@ config KEYBOARD_TNETV107X | |||
586 | config KEYBOARD_TWL4030 | 533 | config KEYBOARD_TWL4030 |
587 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" | 534 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" |
588 | depends on TWL4030_CORE | 535 | depends on TWL4030_CORE |
589 | select INPUT_MATRIXKMAP | ||
590 | help | 536 | help |
591 | Say Y here if your board use the keypad controller on | 537 | Say Y here if your board use the keypad controller on |
592 | TWL4030 family chips. It's safe to say enable this | 538 | TWL4030 family chips. It's safe to say enable this |
@@ -610,7 +556,6 @@ config KEYBOARD_XTKBD | |||
610 | config KEYBOARD_W90P910 | 556 | config KEYBOARD_W90P910 |
611 | tristate "W90P910 Matrix Keypad support" | 557 | tristate "W90P910 Matrix Keypad support" |
612 | depends on ARCH_W90X900 | 558 | depends on ARCH_W90X900 |
613 | select INPUT_MATRIXKMAP | ||
614 | help | 559 | help |
615 | Say Y here to enable the matrix keypad on evaluation board | 560 | Say Y here to enable the matrix keypad on evaluation board |
616 | based on W90P910. | 561 | based on W90P910. |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 44e76002f54..23b440a4c27 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the input core drivers. | 2 | # Makefile for the input core drivers. |
3 | # | 3 | # |
4 | GCOV_PROFILE_tegra-kbc.o := y | ||
4 | 5 | ||
5 | # Each configuration option enables a list of files. | 6 | # Each configuration option enables a list of files. |
6 | 7 | ||
@@ -16,7 +17,6 @@ obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | |||
16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 17 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
17 | obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o | 18 | obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o |
18 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o | 19 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o |
19 | obj-$(CONFIG_KEYBOARD_TCA8418) += tca8418_keypad.o | ||
20 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 20 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
21 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 21 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
22 | obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o | 22 | obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o |
@@ -24,9 +24,7 @@ obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | |||
24 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | 24 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o |
25 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | 25 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o |
26 | obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o | 26 | obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o |
27 | obj-$(CONFIG_KEYBOARD_LM8333) += lm8333.o | ||
28 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | 27 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o |
29 | obj-$(CONFIG_KEYBOARD_LPC32XX) += lpc32xx-keys.o | ||
30 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | 28 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o |
31 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | 29 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o |
32 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o | 30 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o |
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index ef26b17fb15..3db8006dac3 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c | |||
@@ -69,7 +69,7 @@ static int adp5520_keys_notifier(struct notifier_block *nb, | |||
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
72 | static int adp5520_keys_probe(struct platform_device *pdev) | 72 | static int __devinit adp5520_keys_probe(struct platform_device *pdev) |
73 | { | 73 | { |
74 | struct adp5520_keys_platform_data *pdata = pdev->dev.platform_data; | 74 | struct adp5520_keys_platform_data *pdata = pdev->dev.platform_data; |
75 | struct input_dev *input; | 75 | struct input_dev *input; |
@@ -182,7 +182,7 @@ err: | |||
182 | return ret; | 182 | return ret; |
183 | } | 183 | } |
184 | 184 | ||
185 | static int adp5520_keys_remove(struct platform_device *pdev) | 185 | static int __devexit adp5520_keys_remove(struct platform_device *pdev) |
186 | { | 186 | { |
187 | struct adp5520_keys *dev = platform_get_drvdata(pdev); | 187 | struct adp5520_keys *dev = platform_get_drvdata(pdev); |
188 | 188 | ||
@@ -200,9 +200,20 @@ static struct platform_driver adp5520_keys_driver = { | |||
200 | .owner = THIS_MODULE, | 200 | .owner = THIS_MODULE, |
201 | }, | 201 | }, |
202 | .probe = adp5520_keys_probe, | 202 | .probe = adp5520_keys_probe, |
203 | .remove = adp5520_keys_remove, | 203 | .remove = __devexit_p(adp5520_keys_remove), |
204 | }; | 204 | }; |
205 | module_platform_driver(adp5520_keys_driver); | 205 | |
206 | static int __init adp5520_keys_init(void) | ||
207 | { | ||
208 | return platform_driver_register(&adp5520_keys_driver); | ||
209 | } | ||
210 | module_init(adp5520_keys_init); | ||
211 | |||
212 | static void __exit adp5520_keys_exit(void) | ||
213 | { | ||
214 | platform_driver_unregister(&adp5520_keys_driver); | ||
215 | } | ||
216 | module_exit(adp5520_keys_exit); | ||
206 | 217 | ||
207 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 218 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
208 | MODULE_DESCRIPTION("Keys ADP5520 Driver"); | 219 | MODULE_DESCRIPTION("Keys ADP5520 Driver"); |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index dbd2047f164..e34eeb8ae37 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -145,7 +145,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, | |||
145 | return ret; | 145 | return ret; |
146 | } | 146 | } |
147 | 147 | ||
148 | static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, | 148 | static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, |
149 | const struct adp5588_kpad_platform_data *pdata) | 149 | const struct adp5588_kpad_platform_data *pdata) |
150 | { | 150 | { |
151 | bool pin_used[ADP5588_MAXGPIO]; | 151 | bool pin_used[ADP5588_MAXGPIO]; |
@@ -170,7 +170,7 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, | |||
170 | return n_unused; | 170 | return n_unused; |
171 | } | 171 | } |
172 | 172 | ||
173 | static int adp5588_gpio_add(struct adp5588_kpad *kpad) | 173 | static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) |
174 | { | 174 | { |
175 | struct device *dev = &kpad->client->dev; | 175 | struct device *dev = &kpad->client->dev; |
176 | const struct adp5588_kpad_platform_data *pdata = dev->platform_data; | 176 | const struct adp5588_kpad_platform_data *pdata = dev->platform_data; |
@@ -197,7 +197,6 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) | |||
197 | kpad->gc.base = gpio_data->gpio_start; | 197 | kpad->gc.base = gpio_data->gpio_start; |
198 | kpad->gc.label = kpad->client->name; | 198 | kpad->gc.label = kpad->client->name; |
199 | kpad->gc.owner = THIS_MODULE; | 199 | kpad->gc.owner = THIS_MODULE; |
200 | kpad->gc.names = gpio_data->names; | ||
201 | 200 | ||
202 | mutex_init(&kpad->gpio_lock); | 201 | mutex_init(&kpad->gpio_lock); |
203 | 202 | ||
@@ -224,7 +223,7 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) | |||
224 | return 0; | 223 | return 0; |
225 | } | 224 | } |
226 | 225 | ||
227 | static void adp5588_gpio_remove(struct adp5588_kpad *kpad) | 226 | static void __devexit adp5588_gpio_remove(struct adp5588_kpad *kpad) |
228 | { | 227 | { |
229 | struct device *dev = &kpad->client->dev; | 228 | struct device *dev = &kpad->client->dev; |
230 | const struct adp5588_kpad_platform_data *pdata = dev->platform_data; | 229 | const struct adp5588_kpad_platform_data *pdata = dev->platform_data; |
@@ -319,7 +318,7 @@ static irqreturn_t adp5588_irq(int irq, void *handle) | |||
319 | return IRQ_HANDLED; | 318 | return IRQ_HANDLED; |
320 | } | 319 | } |
321 | 320 | ||
322 | static int adp5588_setup(struct i2c_client *client) | 321 | static int __devinit adp5588_setup(struct i2c_client *client) |
323 | { | 322 | { |
324 | const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; | 323 | const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; |
325 | const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; | 324 | const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; |
@@ -382,7 +381,7 @@ static int adp5588_setup(struct i2c_client *client) | |||
382 | return 0; | 381 | return 0; |
383 | } | 382 | } |
384 | 383 | ||
385 | static void adp5588_report_switch_state(struct adp5588_kpad *kpad) | 384 | static void __devinit adp5588_report_switch_state(struct adp5588_kpad *kpad) |
386 | { | 385 | { |
387 | int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1); | 386 | int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1); |
388 | int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2); | 387 | int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2); |
@@ -420,8 +419,8 @@ static void adp5588_report_switch_state(struct adp5588_kpad *kpad) | |||
420 | } | 419 | } |
421 | 420 | ||
422 | 421 | ||
423 | static int adp5588_probe(struct i2c_client *client, | 422 | static int __devinit adp5588_probe(struct i2c_client *client, |
424 | const struct i2c_device_id *id) | 423 | const struct i2c_device_id *id) |
425 | { | 424 | { |
426 | struct adp5588_kpad *kpad; | 425 | struct adp5588_kpad *kpad; |
427 | const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; | 426 | const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; |
@@ -551,7 +550,7 @@ static int adp5588_probe(struct i2c_client *client, | |||
551 | } | 550 | } |
552 | 551 | ||
553 | error = request_irq(client->irq, adp5588_irq, | 552 | error = request_irq(client->irq, adp5588_irq, |
554 | IRQF_TRIGGER_FALLING, | 553 | IRQF_TRIGGER_FALLING | IRQF_DISABLED, |
555 | client->dev.driver->name, kpad); | 554 | client->dev.driver->name, kpad); |
556 | if (error) { | 555 | if (error) { |
557 | dev_err(&client->dev, "irq %d busy?\n", client->irq); | 556 | dev_err(&client->dev, "irq %d busy?\n", client->irq); |
@@ -587,7 +586,7 @@ static int adp5588_probe(struct i2c_client *client, | |||
587 | return error; | 586 | return error; |
588 | } | 587 | } |
589 | 588 | ||
590 | static int adp5588_remove(struct i2c_client *client) | 589 | static int __devexit adp5588_remove(struct i2c_client *client) |
591 | { | 590 | { |
592 | struct adp5588_kpad *kpad = i2c_get_clientdata(client); | 591 | struct adp5588_kpad *kpad = i2c_get_clientdata(client); |
593 | 592 | ||
@@ -650,11 +649,21 @@ static struct i2c_driver adp5588_driver = { | |||
650 | #endif | 649 | #endif |
651 | }, | 650 | }, |
652 | .probe = adp5588_probe, | 651 | .probe = adp5588_probe, |
653 | .remove = adp5588_remove, | 652 | .remove = __devexit_p(adp5588_remove), |
654 | .id_table = adp5588_id, | 653 | .id_table = adp5588_id, |
655 | }; | 654 | }; |
656 | 655 | ||
657 | module_i2c_driver(adp5588_driver); | 656 | static int __init adp5588_init(void) |
657 | { | ||
658 | return i2c_add_driver(&adp5588_driver); | ||
659 | } | ||
660 | module_init(adp5588_init); | ||
661 | |||
662 | static void __exit adp5588_exit(void) | ||
663 | { | ||
664 | i2c_del_driver(&adp5588_driver); | ||
665 | } | ||
666 | module_exit(adp5588_exit); | ||
658 | 667 | ||
659 | MODULE_LICENSE("GPL"); | 668 | MODULE_LICENSE("GPL"); |
660 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 669 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 67d12b3427c..c7708263051 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Description: keypad driver for ADP5589, ADP5585 | 2 | * Description: keypad driver for ADP5589 |
3 | * I2C QWERTY Keypad and IO Expander | 3 | * I2C QWERTY Keypad and IO Expander |
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
5 | * | 5 | * |
@@ -22,165 +22,35 @@ | |||
22 | 22 | ||
23 | #include <linux/input/adp5589.h> | 23 | #include <linux/input/adp5589.h> |
24 | 24 | ||
25 | /* ADP5589/ADP5585 Common Registers */ | ||
26 | #define ADP5589_5_ID 0x00 | ||
27 | #define ADP5589_5_INT_STATUS 0x01 | ||
28 | #define ADP5589_5_STATUS 0x02 | ||
29 | #define ADP5589_5_FIFO_1 0x03 | ||
30 | #define ADP5589_5_FIFO_2 0x04 | ||
31 | #define ADP5589_5_FIFO_3 0x05 | ||
32 | #define ADP5589_5_FIFO_4 0x06 | ||
33 | #define ADP5589_5_FIFO_5 0x07 | ||
34 | #define ADP5589_5_FIFO_6 0x08 | ||
35 | #define ADP5589_5_FIFO_7 0x09 | ||
36 | #define ADP5589_5_FIFO_8 0x0A | ||
37 | #define ADP5589_5_FIFO_9 0x0B | ||
38 | #define ADP5589_5_FIFO_10 0x0C | ||
39 | #define ADP5589_5_FIFO_11 0x0D | ||
40 | #define ADP5589_5_FIFO_12 0x0E | ||
41 | #define ADP5589_5_FIFO_13 0x0F | ||
42 | #define ADP5589_5_FIFO_14 0x10 | ||
43 | #define ADP5589_5_FIFO_15 0x11 | ||
44 | #define ADP5589_5_FIFO_16 0x12 | ||
45 | #define ADP5589_5_GPI_INT_STAT_A 0x13 | ||
46 | #define ADP5589_5_GPI_INT_STAT_B 0x14 | ||
47 | |||
48 | /* ADP5589 Registers */ | ||
49 | #define ADP5589_GPI_INT_STAT_C 0x15 | ||
50 | #define ADP5589_GPI_STATUS_A 0x16 | ||
51 | #define ADP5589_GPI_STATUS_B 0x17 | ||
52 | #define ADP5589_GPI_STATUS_C 0x18 | ||
53 | #define ADP5589_RPULL_CONFIG_A 0x19 | ||
54 | #define ADP5589_RPULL_CONFIG_B 0x1A | ||
55 | #define ADP5589_RPULL_CONFIG_C 0x1B | ||
56 | #define ADP5589_RPULL_CONFIG_D 0x1C | ||
57 | #define ADP5589_RPULL_CONFIG_E 0x1D | ||
58 | #define ADP5589_GPI_INT_LEVEL_A 0x1E | ||
59 | #define ADP5589_GPI_INT_LEVEL_B 0x1F | ||
60 | #define ADP5589_GPI_INT_LEVEL_C 0x20 | ||
61 | #define ADP5589_GPI_EVENT_EN_A 0x21 | ||
62 | #define ADP5589_GPI_EVENT_EN_B 0x22 | ||
63 | #define ADP5589_GPI_EVENT_EN_C 0x23 | ||
64 | #define ADP5589_GPI_INTERRUPT_EN_A 0x24 | ||
65 | #define ADP5589_GPI_INTERRUPT_EN_B 0x25 | ||
66 | #define ADP5589_GPI_INTERRUPT_EN_C 0x26 | ||
67 | #define ADP5589_DEBOUNCE_DIS_A 0x27 | ||
68 | #define ADP5589_DEBOUNCE_DIS_B 0x28 | ||
69 | #define ADP5589_DEBOUNCE_DIS_C 0x29 | ||
70 | #define ADP5589_GPO_DATA_OUT_A 0x2A | ||
71 | #define ADP5589_GPO_DATA_OUT_B 0x2B | ||
72 | #define ADP5589_GPO_DATA_OUT_C 0x2C | ||
73 | #define ADP5589_GPO_OUT_MODE_A 0x2D | ||
74 | #define ADP5589_GPO_OUT_MODE_B 0x2E | ||
75 | #define ADP5589_GPO_OUT_MODE_C 0x2F | ||
76 | #define ADP5589_GPIO_DIRECTION_A 0x30 | ||
77 | #define ADP5589_GPIO_DIRECTION_B 0x31 | ||
78 | #define ADP5589_GPIO_DIRECTION_C 0x32 | ||
79 | #define ADP5589_UNLOCK1 0x33 | ||
80 | #define ADP5589_UNLOCK2 0x34 | ||
81 | #define ADP5589_EXT_LOCK_EVENT 0x35 | ||
82 | #define ADP5589_UNLOCK_TIMERS 0x36 | ||
83 | #define ADP5589_LOCK_CFG 0x37 | ||
84 | #define ADP5589_RESET1_EVENT_A 0x38 | ||
85 | #define ADP5589_RESET1_EVENT_B 0x39 | ||
86 | #define ADP5589_RESET1_EVENT_C 0x3A | ||
87 | #define ADP5589_RESET2_EVENT_A 0x3B | ||
88 | #define ADP5589_RESET2_EVENT_B 0x3C | ||
89 | #define ADP5589_RESET_CFG 0x3D | ||
90 | #define ADP5589_PWM_OFFT_LOW 0x3E | ||
91 | #define ADP5589_PWM_OFFT_HIGH 0x3F | ||
92 | #define ADP5589_PWM_ONT_LOW 0x40 | ||
93 | #define ADP5589_PWM_ONT_HIGH 0x41 | ||
94 | #define ADP5589_PWM_CFG 0x42 | ||
95 | #define ADP5589_CLOCK_DIV_CFG 0x43 | ||
96 | #define ADP5589_LOGIC_1_CFG 0x44 | ||
97 | #define ADP5589_LOGIC_2_CFG 0x45 | ||
98 | #define ADP5589_LOGIC_FF_CFG 0x46 | ||
99 | #define ADP5589_LOGIC_INT_EVENT_EN 0x47 | ||
100 | #define ADP5589_POLL_PTIME_CFG 0x48 | ||
101 | #define ADP5589_PIN_CONFIG_A 0x49 | ||
102 | #define ADP5589_PIN_CONFIG_B 0x4A | ||
103 | #define ADP5589_PIN_CONFIG_C 0x4B | ||
104 | #define ADP5589_PIN_CONFIG_D 0x4C | ||
105 | #define ADP5589_GENERAL_CFG 0x4D | ||
106 | #define ADP5589_INT_EN 0x4E | ||
107 | |||
108 | /* ADP5585 Registers */ | ||
109 | #define ADP5585_GPI_STATUS_A 0x15 | ||
110 | #define ADP5585_GPI_STATUS_B 0x16 | ||
111 | #define ADP5585_RPULL_CONFIG_A 0x17 | ||
112 | #define ADP5585_RPULL_CONFIG_B 0x18 | ||
113 | #define ADP5585_RPULL_CONFIG_C 0x19 | ||
114 | #define ADP5585_RPULL_CONFIG_D 0x1A | ||
115 | #define ADP5585_GPI_INT_LEVEL_A 0x1B | ||
116 | #define ADP5585_GPI_INT_LEVEL_B 0x1C | ||
117 | #define ADP5585_GPI_EVENT_EN_A 0x1D | ||
118 | #define ADP5585_GPI_EVENT_EN_B 0x1E | ||
119 | #define ADP5585_GPI_INTERRUPT_EN_A 0x1F | ||
120 | #define ADP5585_GPI_INTERRUPT_EN_B 0x20 | ||
121 | #define ADP5585_DEBOUNCE_DIS_A 0x21 | ||
122 | #define ADP5585_DEBOUNCE_DIS_B 0x22 | ||
123 | #define ADP5585_GPO_DATA_OUT_A 0x23 | ||
124 | #define ADP5585_GPO_DATA_OUT_B 0x24 | ||
125 | #define ADP5585_GPO_OUT_MODE_A 0x25 | ||
126 | #define ADP5585_GPO_OUT_MODE_B 0x26 | ||
127 | #define ADP5585_GPIO_DIRECTION_A 0x27 | ||
128 | #define ADP5585_GPIO_DIRECTION_B 0x28 | ||
129 | #define ADP5585_RESET1_EVENT_A 0x29 | ||
130 | #define ADP5585_RESET1_EVENT_B 0x2A | ||
131 | #define ADP5585_RESET1_EVENT_C 0x2B | ||
132 | #define ADP5585_RESET2_EVENT_A 0x2C | ||
133 | #define ADP5585_RESET2_EVENT_B 0x2D | ||
134 | #define ADP5585_RESET_CFG 0x2E | ||
135 | #define ADP5585_PWM_OFFT_LOW 0x2F | ||
136 | #define ADP5585_PWM_OFFT_HIGH 0x30 | ||
137 | #define ADP5585_PWM_ONT_LOW 0x31 | ||
138 | #define ADP5585_PWM_ONT_HIGH 0x32 | ||
139 | #define ADP5585_PWM_CFG 0x33 | ||
140 | #define ADP5585_LOGIC_CFG 0x34 | ||
141 | #define ADP5585_LOGIC_FF_CFG 0x35 | ||
142 | #define ADP5585_LOGIC_INT_EVENT_EN 0x36 | ||
143 | #define ADP5585_POLL_PTIME_CFG 0x37 | ||
144 | #define ADP5585_PIN_CONFIG_A 0x38 | ||
145 | #define ADP5585_PIN_CONFIG_B 0x39 | ||
146 | #define ADP5585_PIN_CONFIG_D 0x3A | ||
147 | #define ADP5585_GENERAL_CFG 0x3B | ||
148 | #define ADP5585_INT_EN 0x3C | ||
149 | |||
150 | /* ID Register */ | ||
151 | #define ADP5589_5_DEVICE_ID_MASK 0xF | ||
152 | #define ADP5589_5_MAN_ID_MASK 0xF | ||
153 | #define ADP5589_5_MAN_ID_SHIFT 4 | ||
154 | #define ADP5589_5_MAN_ID 0x02 | ||
155 | |||
156 | /* GENERAL_CFG Register */ | 25 | /* GENERAL_CFG Register */ |
157 | #define OSC_EN (1 << 7) | 26 | #define OSC_EN (1 << 7) |
158 | #define CORE_CLK(x) (((x) & 0x3) << 5) | 27 | #define CORE_CLK(x) (((x) & 0x3) << 5) |
159 | #define LCK_TRK_LOGIC (1 << 4) /* ADP5589 only */ | 28 | #define LCK_TRK_LOGIC (1 << 4) |
160 | #define LCK_TRK_GPI (1 << 3) /* ADP5589 only */ | 29 | #define LCK_TRK_GPI (1 << 3) |
161 | #define INT_CFG (1 << 1) | 30 | #define INT_CFG (1 << 1) |
162 | #define RST_CFG (1 << 0) | 31 | #define RST_CFG (1 << 0) |
163 | 32 | ||
164 | /* INT_EN Register */ | 33 | /* INT_EN Register */ |
165 | #define LOGIC2_IEN (1 << 5) /* ADP5589 only */ | 34 | #define LOGIC2_IEN (1 << 5) |
166 | #define LOGIC1_IEN (1 << 4) | 35 | #define LOGIC1_IEN (1 << 4) |
167 | #define LOCK_IEN (1 << 3) /* ADP5589 only */ | 36 | #define LOCK_IEN (1 << 3) |
168 | #define OVRFLOW_IEN (1 << 2) | 37 | #define OVRFLOW_IEN (1 << 2) |
169 | #define GPI_IEN (1 << 1) | 38 | #define GPI_IEN (1 << 1) |
170 | #define EVENT_IEN (1 << 0) | 39 | #define EVENT_IEN (1 << 0) |
171 | 40 | ||
172 | /* Interrupt Status Register */ | 41 | /* Interrupt Status Register */ |
173 | #define LOGIC2_INT (1 << 5) /* ADP5589 only */ | 42 | #define LOGIC2_INT (1 << 5) |
174 | #define LOGIC1_INT (1 << 4) | 43 | #define LOGIC1_INT (1 << 4) |
175 | #define LOCK_INT (1 << 3) /* ADP5589 only */ | 44 | #define LOCK_INT (1 << 3) |
176 | #define OVRFLOW_INT (1 << 2) | 45 | #define OVRFLOW_INT (1 << 2) |
177 | #define GPI_INT (1 << 1) | 46 | #define GPI_INT (1 << 1) |
178 | #define EVENT_INT (1 << 0) | 47 | #define EVENT_INT (1 << 0) |
179 | 48 | ||
180 | /* STATUS Register */ | 49 | /* STATUS Register */ |
181 | #define LOGIC2_STAT (1 << 7) /* ADP5589 only */ | 50 | |
51 | #define LOGIC2_STAT (1 << 7) | ||
182 | #define LOGIC1_STAT (1 << 6) | 52 | #define LOGIC1_STAT (1 << 6) |
183 | #define LOCK_STAT (1 << 5) /* ADP5589 only */ | 53 | #define LOCK_STAT (1 << 5) |
184 | #define KEC 0xF | 54 | #define KEC 0xF |
185 | 55 | ||
186 | /* PIN_CONFIG_D Register */ | 56 | /* PIN_CONFIG_D Register */ |
@@ -191,54 +61,27 @@ | |||
191 | #define LOCK_EN (1 << 0) | 61 | #define LOCK_EN (1 << 0) |
192 | 62 | ||
193 | #define PTIME_MASK 0x3 | 63 | #define PTIME_MASK 0x3 |
194 | #define LTIME_MASK 0x3 /* ADP5589 only */ | 64 | #define LTIME_MASK 0x3 |
195 | 65 | ||
196 | /* Key Event Register xy */ | 66 | /* Key Event Register xy */ |
197 | #define KEY_EV_PRESSED (1 << 7) | 67 | #define KEY_EV_PRESSED (1 << 7) |
198 | #define KEY_EV_MASK (0x7F) | 68 | #define KEY_EV_MASK (0x7F) |
199 | 69 | ||
200 | #define KEYP_MAX_EVENT 16 | 70 | #define KEYP_MAX_EVENT 16 |
201 | #define ADP5589_MAXGPIO 19 | ||
202 | #define ADP5585_MAXGPIO 11 /* 10 on the ADP5585-01, 11 on ADP5585-02 */ | ||
203 | 71 | ||
204 | enum { | 72 | #define MAXGPIO 19 |
205 | ADP5589, | 73 | #define ADP_BANK(offs) ((offs) >> 3) |
206 | ADP5585_01, | 74 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) |
207 | ADP5585_02 | ||
208 | }; | ||
209 | |||
210 | struct adp_constants { | ||
211 | u8 maxgpio; | ||
212 | u8 keymapsize; | ||
213 | u8 gpi_pin_row_base; | ||
214 | u8 gpi_pin_row_end; | ||
215 | u8 gpi_pin_col_base; | ||
216 | u8 gpi_pin_base; | ||
217 | u8 gpi_pin_end; | ||
218 | u8 gpimapsize_max; | ||
219 | u8 max_row_num; | ||
220 | u8 max_col_num; | ||
221 | u8 row_mask; | ||
222 | u8 col_mask; | ||
223 | u8 col_shift; | ||
224 | u8 c4_extend_cfg; | ||
225 | u8 (*bank) (u8 offset); | ||
226 | u8 (*bit) (u8 offset); | ||
227 | u8 (*reg) (u8 reg); | ||
228 | }; | ||
229 | 75 | ||
230 | struct adp5589_kpad { | 76 | struct adp5589_kpad { |
231 | struct i2c_client *client; | 77 | struct i2c_client *client; |
232 | struct input_dev *input; | 78 | struct input_dev *input; |
233 | const struct adp_constants *var; | ||
234 | unsigned short keycode[ADP5589_KEYMAPSIZE]; | 79 | unsigned short keycode[ADP5589_KEYMAPSIZE]; |
235 | const struct adp5589_gpi_map *gpimap; | 80 | const struct adp5589_gpi_map *gpimap; |
236 | unsigned short gpimapsize; | 81 | unsigned short gpimapsize; |
237 | unsigned extend_cfg; | 82 | unsigned extend_cfg; |
238 | bool is_adp5585; | ||
239 | bool adp5585_support_row5; | ||
240 | #ifdef CONFIG_GPIOLIB | 83 | #ifdef CONFIG_GPIOLIB |
241 | unsigned char gpiomap[ADP5589_MAXGPIO]; | 84 | unsigned char gpiomap[MAXGPIO]; |
242 | bool export_gpio; | 85 | bool export_gpio; |
243 | struct gpio_chip gc; | 86 | struct gpio_chip gc; |
244 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ | 87 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ |
@@ -247,129 +90,6 @@ struct adp5589_kpad { | |||
247 | #endif | 90 | #endif |
248 | }; | 91 | }; |
249 | 92 | ||
250 | /* | ||
251 | * ADP5589 / ADP5585 derivative / variant handling | ||
252 | */ | ||
253 | |||
254 | |||
255 | /* ADP5589 */ | ||
256 | |||
257 | static unsigned char adp5589_bank(unsigned char offset) | ||
258 | { | ||
259 | return offset >> 3; | ||
260 | } | ||
261 | |||
262 | static unsigned char adp5589_bit(unsigned char offset) | ||
263 | { | ||
264 | return 1u << (offset & 0x7); | ||
265 | } | ||
266 | |||
267 | static unsigned char adp5589_reg(unsigned char reg) | ||
268 | { | ||
269 | return reg; | ||
270 | } | ||
271 | |||
272 | static const struct adp_constants const_adp5589 = { | ||
273 | .maxgpio = ADP5589_MAXGPIO, | ||
274 | .keymapsize = ADP5589_KEYMAPSIZE, | ||
275 | .gpi_pin_row_base = ADP5589_GPI_PIN_ROW_BASE, | ||
276 | .gpi_pin_row_end = ADP5589_GPI_PIN_ROW_END, | ||
277 | .gpi_pin_col_base = ADP5589_GPI_PIN_COL_BASE, | ||
278 | .gpi_pin_base = ADP5589_GPI_PIN_BASE, | ||
279 | .gpi_pin_end = ADP5589_GPI_PIN_END, | ||
280 | .gpimapsize_max = ADP5589_GPIMAPSIZE_MAX, | ||
281 | .c4_extend_cfg = 12, | ||
282 | .max_row_num = ADP5589_MAX_ROW_NUM, | ||
283 | .max_col_num = ADP5589_MAX_COL_NUM, | ||
284 | .row_mask = ADP5589_ROW_MASK, | ||
285 | .col_mask = ADP5589_COL_MASK, | ||
286 | .col_shift = ADP5589_COL_SHIFT, | ||
287 | .bank = adp5589_bank, | ||
288 | .bit = adp5589_bit, | ||
289 | .reg = adp5589_reg, | ||
290 | }; | ||
291 | |||
292 | /* ADP5585 */ | ||
293 | |||
294 | static unsigned char adp5585_bank(unsigned char offset) | ||
295 | { | ||
296 | return offset > ADP5585_MAX_ROW_NUM; | ||
297 | } | ||
298 | |||
299 | static unsigned char adp5585_bit(unsigned char offset) | ||
300 | { | ||
301 | return (offset > ADP5585_MAX_ROW_NUM) ? | ||
302 | 1u << (offset - ADP5585_COL_SHIFT) : 1u << offset; | ||
303 | } | ||
304 | |||
305 | static const unsigned char adp5585_reg_lut[] = { | ||
306 | [ADP5589_GPI_STATUS_A] = ADP5585_GPI_STATUS_A, | ||
307 | [ADP5589_GPI_STATUS_B] = ADP5585_GPI_STATUS_B, | ||
308 | [ADP5589_RPULL_CONFIG_A] = ADP5585_RPULL_CONFIG_A, | ||
309 | [ADP5589_RPULL_CONFIG_B] = ADP5585_RPULL_CONFIG_B, | ||
310 | [ADP5589_RPULL_CONFIG_C] = ADP5585_RPULL_CONFIG_C, | ||
311 | [ADP5589_RPULL_CONFIG_D] = ADP5585_RPULL_CONFIG_D, | ||
312 | [ADP5589_GPI_INT_LEVEL_A] = ADP5585_GPI_INT_LEVEL_A, | ||
313 | [ADP5589_GPI_INT_LEVEL_B] = ADP5585_GPI_INT_LEVEL_B, | ||
314 | [ADP5589_GPI_EVENT_EN_A] = ADP5585_GPI_EVENT_EN_A, | ||
315 | [ADP5589_GPI_EVENT_EN_B] = ADP5585_GPI_EVENT_EN_B, | ||
316 | [ADP5589_GPI_INTERRUPT_EN_A] = ADP5585_GPI_INTERRUPT_EN_A, | ||
317 | [ADP5589_GPI_INTERRUPT_EN_B] = ADP5585_GPI_INTERRUPT_EN_B, | ||
318 | [ADP5589_DEBOUNCE_DIS_A] = ADP5585_DEBOUNCE_DIS_A, | ||
319 | [ADP5589_DEBOUNCE_DIS_B] = ADP5585_DEBOUNCE_DIS_B, | ||
320 | [ADP5589_GPO_DATA_OUT_A] = ADP5585_GPO_DATA_OUT_A, | ||
321 | [ADP5589_GPO_DATA_OUT_B] = ADP5585_GPO_DATA_OUT_B, | ||
322 | [ADP5589_GPO_OUT_MODE_A] = ADP5585_GPO_OUT_MODE_A, | ||
323 | [ADP5589_GPO_OUT_MODE_B] = ADP5585_GPO_OUT_MODE_B, | ||
324 | [ADP5589_GPIO_DIRECTION_A] = ADP5585_GPIO_DIRECTION_A, | ||
325 | [ADP5589_GPIO_DIRECTION_B] = ADP5585_GPIO_DIRECTION_B, | ||
326 | [ADP5589_RESET1_EVENT_A] = ADP5585_RESET1_EVENT_A, | ||
327 | [ADP5589_RESET1_EVENT_B] = ADP5585_RESET1_EVENT_B, | ||
328 | [ADP5589_RESET1_EVENT_C] = ADP5585_RESET1_EVENT_C, | ||
329 | [ADP5589_RESET2_EVENT_A] = ADP5585_RESET2_EVENT_A, | ||
330 | [ADP5589_RESET2_EVENT_B] = ADP5585_RESET2_EVENT_B, | ||
331 | [ADP5589_RESET_CFG] = ADP5585_RESET_CFG, | ||
332 | [ADP5589_PWM_OFFT_LOW] = ADP5585_PWM_OFFT_LOW, | ||
333 | [ADP5589_PWM_OFFT_HIGH] = ADP5585_PWM_OFFT_HIGH, | ||
334 | [ADP5589_PWM_ONT_LOW] = ADP5585_PWM_ONT_LOW, | ||
335 | [ADP5589_PWM_ONT_HIGH] = ADP5585_PWM_ONT_HIGH, | ||
336 | [ADP5589_PWM_CFG] = ADP5585_PWM_CFG, | ||
337 | [ADP5589_LOGIC_1_CFG] = ADP5585_LOGIC_CFG, | ||
338 | [ADP5589_LOGIC_FF_CFG] = ADP5585_LOGIC_FF_CFG, | ||
339 | [ADP5589_LOGIC_INT_EVENT_EN] = ADP5585_LOGIC_INT_EVENT_EN, | ||
340 | [ADP5589_POLL_PTIME_CFG] = ADP5585_POLL_PTIME_CFG, | ||
341 | [ADP5589_PIN_CONFIG_A] = ADP5585_PIN_CONFIG_A, | ||
342 | [ADP5589_PIN_CONFIG_B] = ADP5585_PIN_CONFIG_B, | ||
343 | [ADP5589_PIN_CONFIG_D] = ADP5585_PIN_CONFIG_D, | ||
344 | [ADP5589_GENERAL_CFG] = ADP5585_GENERAL_CFG, | ||
345 | [ADP5589_INT_EN] = ADP5585_INT_EN, | ||
346 | }; | ||
347 | |||
348 | static unsigned char adp5585_reg(unsigned char reg) | ||
349 | { | ||
350 | return adp5585_reg_lut[reg]; | ||
351 | } | ||
352 | |||
353 | static const struct adp_constants const_adp5585 = { | ||
354 | .maxgpio = ADP5585_MAXGPIO, | ||
355 | .keymapsize = ADP5585_KEYMAPSIZE, | ||
356 | .gpi_pin_row_base = ADP5585_GPI_PIN_ROW_BASE, | ||
357 | .gpi_pin_row_end = ADP5585_GPI_PIN_ROW_END, | ||
358 | .gpi_pin_col_base = ADP5585_GPI_PIN_COL_BASE, | ||
359 | .gpi_pin_base = ADP5585_GPI_PIN_BASE, | ||
360 | .gpi_pin_end = ADP5585_GPI_PIN_END, | ||
361 | .gpimapsize_max = ADP5585_GPIMAPSIZE_MAX, | ||
362 | .c4_extend_cfg = 10, | ||
363 | .max_row_num = ADP5585_MAX_ROW_NUM, | ||
364 | .max_col_num = ADP5585_MAX_COL_NUM, | ||
365 | .row_mask = ADP5585_ROW_MASK, | ||
366 | .col_mask = ADP5585_COL_MASK, | ||
367 | .col_shift = ADP5585_COL_SHIFT, | ||
368 | .bank = adp5585_bank, | ||
369 | .bit = adp5585_bit, | ||
370 | .reg = adp5585_reg, | ||
371 | }; | ||
372 | |||
373 | static int adp5589_read(struct i2c_client *client, u8 reg) | 93 | static int adp5589_read(struct i2c_client *client, u8 reg) |
374 | { | 94 | { |
375 | int ret = i2c_smbus_read_byte_data(client, reg); | 95 | int ret = i2c_smbus_read_byte_data(client, reg); |
@@ -389,20 +109,19 @@ static int adp5589_write(struct i2c_client *client, u8 reg, u8 val) | |||
389 | static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) | 109 | static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) |
390 | { | 110 | { |
391 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 111 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
392 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); | 112 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); |
393 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); | 113 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); |
394 | 114 | ||
395 | return !!(adp5589_read(kpad->client, | 115 | return !!(adp5589_read(kpad->client, ADP5589_GPI_STATUS_A + bank) & |
396 | kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) & | 116 | bit); |
397 | bit); | ||
398 | } | 117 | } |
399 | 118 | ||
400 | static void adp5589_gpio_set_value(struct gpio_chip *chip, | 119 | static void adp5589_gpio_set_value(struct gpio_chip *chip, |
401 | unsigned off, int val) | 120 | unsigned off, int val) |
402 | { | 121 | { |
403 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 122 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
404 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); | 123 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); |
405 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); | 124 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); |
406 | 125 | ||
407 | mutex_lock(&kpad->gpio_lock); | 126 | mutex_lock(&kpad->gpio_lock); |
408 | 127 | ||
@@ -411,8 +130,8 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip, | |||
411 | else | 130 | else |
412 | kpad->dat_out[bank] &= ~bit; | 131 | kpad->dat_out[bank] &= ~bit; |
413 | 132 | ||
414 | adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) + | 133 | adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, |
415 | bank, kpad->dat_out[bank]); | 134 | kpad->dat_out[bank]); |
416 | 135 | ||
417 | mutex_unlock(&kpad->gpio_lock); | 136 | mutex_unlock(&kpad->gpio_lock); |
418 | } | 137 | } |
@@ -420,15 +139,14 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip, | |||
420 | static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) | 139 | static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) |
421 | { | 140 | { |
422 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 141 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
423 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); | 142 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); |
424 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); | 143 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); |
425 | int ret; | 144 | int ret; |
426 | 145 | ||
427 | mutex_lock(&kpad->gpio_lock); | 146 | mutex_lock(&kpad->gpio_lock); |
428 | 147 | ||
429 | kpad->dir[bank] &= ~bit; | 148 | kpad->dir[bank] &= ~bit; |
430 | ret = adp5589_write(kpad->client, | 149 | ret = adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, |
431 | kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank, | ||
432 | kpad->dir[bank]); | 150 | kpad->dir[bank]); |
433 | 151 | ||
434 | mutex_unlock(&kpad->gpio_lock); | 152 | mutex_unlock(&kpad->gpio_lock); |
@@ -440,8 +158,8 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip, | |||
440 | unsigned off, int val) | 158 | unsigned off, int val) |
441 | { | 159 | { |
442 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 160 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
443 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); | 161 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); |
444 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); | 162 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); |
445 | int ret; | 163 | int ret; |
446 | 164 | ||
447 | mutex_lock(&kpad->gpio_lock); | 165 | mutex_lock(&kpad->gpio_lock); |
@@ -453,10 +171,9 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip, | |||
453 | else | 171 | else |
454 | kpad->dat_out[bank] &= ~bit; | 172 | kpad->dat_out[bank] &= ~bit; |
455 | 173 | ||
456 | ret = adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) | 174 | ret = adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, |
457 | + bank, kpad->dat_out[bank]); | 175 | kpad->dat_out[bank]); |
458 | ret |= adp5589_write(kpad->client, | 176 | ret |= adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, |
459 | kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank, | ||
460 | kpad->dir[bank]); | 177 | kpad->dir[bank]); |
461 | 178 | ||
462 | mutex_unlock(&kpad->gpio_lock); | 179 | mutex_unlock(&kpad->gpio_lock); |
@@ -464,39 +181,36 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip, | |||
464 | return ret; | 181 | return ret; |
465 | } | 182 | } |
466 | 183 | ||
467 | static int adp5589_build_gpiomap(struct adp5589_kpad *kpad, | 184 | static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad, |
468 | const struct adp5589_kpad_platform_data *pdata) | 185 | const struct adp5589_kpad_platform_data *pdata) |
469 | { | 186 | { |
470 | bool pin_used[ADP5589_MAXGPIO]; | 187 | bool pin_used[MAXGPIO]; |
471 | int n_unused = 0; | 188 | int n_unused = 0; |
472 | int i; | 189 | int i; |
473 | 190 | ||
474 | memset(pin_used, false, sizeof(pin_used)); | 191 | memset(pin_used, false, sizeof(pin_used)); |
475 | 192 | ||
476 | for (i = 0; i < kpad->var->maxgpio; i++) | 193 | for (i = 0; i < MAXGPIO; i++) |
477 | if (pdata->keypad_en_mask & (1 << i)) | 194 | if (pdata->keypad_en_mask & (1 << i)) |
478 | pin_used[i] = true; | 195 | pin_used[i] = true; |
479 | 196 | ||
480 | for (i = 0; i < kpad->gpimapsize; i++) | 197 | for (i = 0; i < kpad->gpimapsize; i++) |
481 | pin_used[kpad->gpimap[i].pin - kpad->var->gpi_pin_base] = true; | 198 | pin_used[kpad->gpimap[i].pin - ADP5589_GPI_PIN_BASE] = true; |
482 | 199 | ||
483 | if (kpad->extend_cfg & R4_EXTEND_CFG) | 200 | if (kpad->extend_cfg & R4_EXTEND_CFG) |
484 | pin_used[4] = true; | 201 | pin_used[4] = true; |
485 | 202 | ||
486 | if (kpad->extend_cfg & C4_EXTEND_CFG) | 203 | if (kpad->extend_cfg & C4_EXTEND_CFG) |
487 | pin_used[kpad->var->c4_extend_cfg] = true; | 204 | pin_used[12] = true; |
488 | |||
489 | if (!kpad->adp5585_support_row5) | ||
490 | pin_used[5] = true; | ||
491 | 205 | ||
492 | for (i = 0; i < kpad->var->maxgpio; i++) | 206 | for (i = 0; i < MAXGPIO; i++) |
493 | if (!pin_used[i]) | 207 | if (!pin_used[i]) |
494 | kpad->gpiomap[n_unused++] = i; | 208 | kpad->gpiomap[n_unused++] = i; |
495 | 209 | ||
496 | return n_unused; | 210 | return n_unused; |
497 | } | 211 | } |
498 | 212 | ||
499 | static int adp5589_gpio_add(struct adp5589_kpad *kpad) | 213 | static int __devinit adp5589_gpio_add(struct adp5589_kpad *kpad) |
500 | { | 214 | { |
501 | struct device *dev = &kpad->client->dev; | 215 | struct device *dev = &kpad->client->dev; |
502 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; | 216 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; |
@@ -532,11 +246,11 @@ static int adp5589_gpio_add(struct adp5589_kpad *kpad) | |||
532 | return error; | 246 | return error; |
533 | } | 247 | } |
534 | 248 | ||
535 | for (i = 0; i <= kpad->var->bank(kpad->var->maxgpio); i++) { | 249 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { |
536 | kpad->dat_out[i] = adp5589_read(kpad->client, kpad->var->reg( | 250 | kpad->dat_out[i] = adp5589_read(kpad->client, |
537 | ADP5589_GPO_DATA_OUT_A) + i); | 251 | ADP5589_GPO_DATA_OUT_A + i); |
538 | kpad->dir[i] = adp5589_read(kpad->client, kpad->var->reg( | 252 | kpad->dir[i] = adp5589_read(kpad->client, |
539 | ADP5589_GPIO_DIRECTION_A) + i); | 253 | ADP5589_GPIO_DIRECTION_A + i); |
540 | } | 254 | } |
541 | 255 | ||
542 | if (gpio_data->setup) { | 256 | if (gpio_data->setup) { |
@@ -550,7 +264,7 @@ static int adp5589_gpio_add(struct adp5589_kpad *kpad) | |||
550 | return 0; | 264 | return 0; |
551 | } | 265 | } |
552 | 266 | ||
553 | static void adp5589_gpio_remove(struct adp5589_kpad *kpad) | 267 | static void __devexit adp5589_gpio_remove(struct adp5589_kpad *kpad) |
554 | { | 268 | { |
555 | struct device *dev = &kpad->client->dev; | 269 | struct device *dev = &kpad->client->dev; |
556 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; | 270 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; |
@@ -603,11 +317,11 @@ static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt) | |||
603 | int i; | 317 | int i; |
604 | 318 | ||
605 | for (i = 0; i < ev_cnt; i++) { | 319 | for (i = 0; i < ev_cnt; i++) { |
606 | int key = adp5589_read(kpad->client, ADP5589_5_FIFO_1 + i); | 320 | int key = adp5589_read(kpad->client, ADP5589_FIFO_1 + i); |
607 | int key_val = key & KEY_EV_MASK; | 321 | int key_val = key & KEY_EV_MASK; |
608 | 322 | ||
609 | if (key_val >= kpad->var->gpi_pin_base && | 323 | if (key_val >= ADP5589_GPI_PIN_BASE && |
610 | key_val <= kpad->var->gpi_pin_end) { | 324 | key_val <= ADP5589_GPI_PIN_END) { |
611 | adp5589_report_switches(kpad, key, key_val); | 325 | adp5589_report_switches(kpad, key, key_val); |
612 | } else { | 326 | } else { |
613 | input_report_key(kpad->input, | 327 | input_report_key(kpad->input, |
@@ -623,29 +337,29 @@ static irqreturn_t adp5589_irq(int irq, void *handle) | |||
623 | struct i2c_client *client = kpad->client; | 337 | struct i2c_client *client = kpad->client; |
624 | int status, ev_cnt; | 338 | int status, ev_cnt; |
625 | 339 | ||
626 | status = adp5589_read(client, ADP5589_5_INT_STATUS); | 340 | status = adp5589_read(client, ADP5589_INT_STATUS); |
627 | 341 | ||
628 | if (status & OVRFLOW_INT) /* Unlikely and should never happen */ | 342 | if (status & OVRFLOW_INT) /* Unlikely and should never happen */ |
629 | dev_err(&client->dev, "Event Overflow Error\n"); | 343 | dev_err(&client->dev, "Event Overflow Error\n"); |
630 | 344 | ||
631 | if (status & EVENT_INT) { | 345 | if (status & EVENT_INT) { |
632 | ev_cnt = adp5589_read(client, ADP5589_5_STATUS) & KEC; | 346 | ev_cnt = adp5589_read(client, ADP5589_STATUS) & KEC; |
633 | if (ev_cnt) { | 347 | if (ev_cnt) { |
634 | adp5589_report_events(kpad, ev_cnt); | 348 | adp5589_report_events(kpad, ev_cnt); |
635 | input_sync(kpad->input); | 349 | input_sync(kpad->input); |
636 | } | 350 | } |
637 | } | 351 | } |
638 | 352 | ||
639 | adp5589_write(client, ADP5589_5_INT_STATUS, status); /* Status is W1C */ | 353 | adp5589_write(client, ADP5589_INT_STATUS, status); /* Status is W1C */ |
640 | 354 | ||
641 | return IRQ_HANDLED; | 355 | return IRQ_HANDLED; |
642 | } | 356 | } |
643 | 357 | ||
644 | static int adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key) | 358 | static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key) |
645 | { | 359 | { |
646 | int i; | 360 | int i; |
647 | 361 | ||
648 | for (i = 0; i < kpad->var->keymapsize; i++) | 362 | for (i = 0; i < ADP5589_KEYMAPSIZE; i++) |
649 | if (key == kpad->keycode[i]) | 363 | if (key == kpad->keycode[i]) |
650 | return (i + 1) | KEY_EV_PRESSED; | 364 | return (i + 1) | KEY_EV_PRESSED; |
651 | 365 | ||
@@ -654,27 +368,23 @@ static int adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key) | |||
654 | return -EINVAL; | 368 | return -EINVAL; |
655 | } | 369 | } |
656 | 370 | ||
657 | static int adp5589_setup(struct adp5589_kpad *kpad) | 371 | static int __devinit adp5589_setup(struct adp5589_kpad *kpad) |
658 | { | 372 | { |
659 | struct i2c_client *client = kpad->client; | 373 | struct i2c_client *client = kpad->client; |
660 | const struct adp5589_kpad_platform_data *pdata = | 374 | const struct adp5589_kpad_platform_data *pdata = |
661 | client->dev.platform_data; | 375 | client->dev.platform_data; |
662 | u8 (*reg) (u8) = kpad->var->reg; | 376 | int i, ret; |
663 | unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; | 377 | unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; |
664 | unsigned char pull_mask = 0; | 378 | unsigned char pull_mask = 0; |
665 | int i, ret; | ||
666 | 379 | ||
667 | ret = adp5589_write(client, reg(ADP5589_PIN_CONFIG_A), | 380 | ret = adp5589_write(client, ADP5589_PIN_CONFIG_A, |
668 | pdata->keypad_en_mask & kpad->var->row_mask); | 381 | pdata->keypad_en_mask & 0xFF); |
669 | ret |= adp5589_write(client, reg(ADP5589_PIN_CONFIG_B), | 382 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_B, |
670 | (pdata->keypad_en_mask >> kpad->var->col_shift) & | 383 | (pdata->keypad_en_mask >> 8) & 0xFF); |
671 | kpad->var->col_mask); | 384 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C, |
385 | (pdata->keypad_en_mask >> 16) & 0xFF); | ||
672 | 386 | ||
673 | if (!kpad->is_adp5585) | 387 | if (pdata->en_keylock) { |
674 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C, | ||
675 | (pdata->keypad_en_mask >> 16) & 0xFF); | ||
676 | |||
677 | if (!kpad->is_adp5585 && pdata->en_keylock) { | ||
678 | ret |= adp5589_write(client, ADP5589_UNLOCK1, | 388 | ret |= adp5589_write(client, ADP5589_UNLOCK1, |
679 | pdata->unlock_key1); | 389 | pdata->unlock_key1); |
680 | ret |= adp5589_write(client, ADP5589_UNLOCK2, | 390 | ret |= adp5589_write(client, ADP5589_UNLOCK2, |
@@ -685,130 +395,96 @@ static int adp5589_setup(struct adp5589_kpad *kpad) | |||
685 | } | 395 | } |
686 | 396 | ||
687 | for (i = 0; i < KEYP_MAX_EVENT; i++) | 397 | for (i = 0; i < KEYP_MAX_EVENT; i++) |
688 | ret |= adp5589_read(client, ADP5589_5_FIFO_1 + i); | 398 | ret |= adp5589_read(client, ADP5589_FIFO_1 + i); |
689 | 399 | ||
690 | for (i = 0; i < pdata->gpimapsize; i++) { | 400 | for (i = 0; i < pdata->gpimapsize; i++) { |
691 | unsigned short pin = pdata->gpimap[i].pin; | 401 | unsigned short pin = pdata->gpimap[i].pin; |
692 | 402 | ||
693 | if (pin <= kpad->var->gpi_pin_row_end) { | 403 | if (pin <= ADP5589_GPI_PIN_ROW_END) { |
694 | evt_mode1 |= (1 << (pin - kpad->var->gpi_pin_row_base)); | 404 | evt_mode1 |= (1 << (pin - ADP5589_GPI_PIN_ROW_BASE)); |
695 | } else { | 405 | } else { |
696 | evt_mode2 |= | 406 | evt_mode2 |= |
697 | ((1 << (pin - kpad->var->gpi_pin_col_base)) & 0xFF); | 407 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) & 0xFF); |
698 | if (!kpad->is_adp5585) | 408 | evt_mode3 |= |
699 | evt_mode3 |= ((1 << (pin - | 409 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) >> 8); |
700 | kpad->var->gpi_pin_col_base)) >> 8); | ||
701 | } | 410 | } |
702 | } | 411 | } |
703 | 412 | ||
704 | if (pdata->gpimapsize) { | 413 | if (pdata->gpimapsize) { |
705 | ret |= adp5589_write(client, reg(ADP5589_GPI_EVENT_EN_A), | 414 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_A, evt_mode1); |
706 | evt_mode1); | 415 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_B, evt_mode2); |
707 | ret |= adp5589_write(client, reg(ADP5589_GPI_EVENT_EN_B), | 416 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_C, evt_mode3); |
708 | evt_mode2); | ||
709 | if (!kpad->is_adp5585) | ||
710 | ret |= adp5589_write(client, | ||
711 | reg(ADP5589_GPI_EVENT_EN_C), | ||
712 | evt_mode3); | ||
713 | } | 417 | } |
714 | 418 | ||
715 | if (pdata->pull_dis_mask & pdata->pullup_en_100k & | 419 | if (pdata->pull_dis_mask & pdata->pullup_en_100k & |
716 | pdata->pullup_en_300k & pdata->pulldown_en_300k) | 420 | pdata->pullup_en_300k & pdata->pulldown_en_300k) |
717 | dev_warn(&client->dev, "Conflicting pull resistor config\n"); | 421 | dev_warn(&client->dev, "Conflicting pull resistor config\n"); |
718 | 422 | ||
719 | for (i = 0; i <= kpad->var->max_row_num; i++) { | 423 | for (i = 0; i < MAXGPIO; i++) { |
720 | unsigned val = 0, bit = (1 << i); | 424 | unsigned val = 0; |
721 | if (pdata->pullup_en_300k & bit) | ||
722 | val = 0; | ||
723 | else if (pdata->pulldown_en_300k & bit) | ||
724 | val = 1; | ||
725 | else if (pdata->pullup_en_100k & bit) | ||
726 | val = 2; | ||
727 | else if (pdata->pull_dis_mask & bit) | ||
728 | val = 3; | ||
729 | |||
730 | pull_mask |= val << (2 * (i & 0x3)); | ||
731 | 425 | ||
732 | if (i == 3 || i == kpad->var->max_row_num) { | 426 | if (pdata->pullup_en_300k & (1 << i)) |
733 | ret |= adp5589_write(client, reg(ADP5585_RPULL_CONFIG_A) | ||
734 | + (i >> 2), pull_mask); | ||
735 | pull_mask = 0; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | for (i = 0; i <= kpad->var->max_col_num; i++) { | ||
740 | unsigned val = 0, bit = 1 << (i + kpad->var->col_shift); | ||
741 | if (pdata->pullup_en_300k & bit) | ||
742 | val = 0; | 427 | val = 0; |
743 | else if (pdata->pulldown_en_300k & bit) | 428 | else if (pdata->pulldown_en_300k & (1 << i)) |
744 | val = 1; | 429 | val = 1; |
745 | else if (pdata->pullup_en_100k & bit) | 430 | else if (pdata->pullup_en_100k & (1 << i)) |
746 | val = 2; | 431 | val = 2; |
747 | else if (pdata->pull_dis_mask & bit) | 432 | else if (pdata->pull_dis_mask & (1 << i)) |
748 | val = 3; | 433 | val = 3; |
749 | 434 | ||
750 | pull_mask |= val << (2 * (i & 0x3)); | 435 | pull_mask |= val << (2 * (i & 0x3)); |
751 | 436 | ||
752 | if (i == 3 || i == kpad->var->max_col_num) { | 437 | if ((i & 0x3) == 0x3 || i == MAXGPIO - 1) { |
753 | ret |= adp5589_write(client, | 438 | ret |= adp5589_write(client, |
754 | reg(ADP5585_RPULL_CONFIG_C) + | 439 | ADP5589_RPULL_CONFIG_A + (i >> 2), |
755 | (i >> 2), pull_mask); | 440 | pull_mask); |
756 | pull_mask = 0; | 441 | pull_mask = 0; |
757 | } | 442 | } |
758 | } | 443 | } |
759 | 444 | ||
760 | if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { | 445 | if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { |
761 | ret |= adp5589_write(client, reg(ADP5589_RESET1_EVENT_A), | 446 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_A, |
762 | adp5589_get_evcode(kpad, | 447 | adp5589_get_evcode(kpad, |
763 | pdata->reset1_key_1)); | 448 | pdata->reset1_key_1)); |
764 | ret |= adp5589_write(client, reg(ADP5589_RESET1_EVENT_B), | 449 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_B, |
765 | adp5589_get_evcode(kpad, | 450 | adp5589_get_evcode(kpad, |
766 | pdata->reset1_key_2)); | 451 | pdata->reset1_key_2)); |
767 | ret |= adp5589_write(client, reg(ADP5589_RESET1_EVENT_C), | 452 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_C, |
768 | adp5589_get_evcode(kpad, | 453 | adp5589_get_evcode(kpad, |
769 | pdata->reset1_key_3)); | 454 | pdata->reset1_key_3)); |
770 | kpad->extend_cfg |= R4_EXTEND_CFG; | 455 | kpad->extend_cfg |= R4_EXTEND_CFG; |
771 | } | 456 | } |
772 | 457 | ||
773 | if (pdata->reset2_key_1 && pdata->reset2_key_2) { | 458 | if (pdata->reset2_key_1 && pdata->reset2_key_2) { |
774 | ret |= adp5589_write(client, reg(ADP5589_RESET2_EVENT_A), | 459 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_A, |
775 | adp5589_get_evcode(kpad, | 460 | adp5589_get_evcode(kpad, |
776 | pdata->reset2_key_1)); | 461 | pdata->reset2_key_1)); |
777 | ret |= adp5589_write(client, reg(ADP5589_RESET2_EVENT_B), | 462 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_B, |
778 | adp5589_get_evcode(kpad, | 463 | adp5589_get_evcode(kpad, |
779 | pdata->reset2_key_2)); | 464 | pdata->reset2_key_2)); |
780 | kpad->extend_cfg |= C4_EXTEND_CFG; | 465 | kpad->extend_cfg |= C4_EXTEND_CFG; |
781 | } | 466 | } |
782 | 467 | ||
783 | if (kpad->extend_cfg) { | 468 | if (kpad->extend_cfg) { |
784 | ret |= adp5589_write(client, reg(ADP5589_RESET_CFG), | 469 | ret |= adp5589_write(client, ADP5589_RESET_CFG, |
785 | pdata->reset_cfg); | 470 | pdata->reset_cfg); |
786 | ret |= adp5589_write(client, reg(ADP5589_PIN_CONFIG_D), | 471 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_D, |
787 | kpad->extend_cfg); | 472 | kpad->extend_cfg); |
788 | } | 473 | } |
789 | 474 | ||
790 | ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_A), | 475 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) |
791 | pdata->debounce_dis_mask & kpad->var->row_mask); | 476 | ret |= adp5589_write(client, ADP5589_DEBOUNCE_DIS_A + i, |
792 | 477 | pdata->debounce_dis_mask >> (i * 8)); | |
793 | ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_B), | ||
794 | (pdata->debounce_dis_mask >> kpad->var->col_shift) | ||
795 | & kpad->var->col_mask); | ||
796 | 478 | ||
797 | if (!kpad->is_adp5585) | 479 | ret |= adp5589_write(client, ADP5589_POLL_PTIME_CFG, |
798 | ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_C), | ||
799 | (pdata->debounce_dis_mask >> 16) & 0xFF); | ||
800 | |||
801 | ret |= adp5589_write(client, reg(ADP5589_POLL_PTIME_CFG), | ||
802 | pdata->scan_cycle_time & PTIME_MASK); | 480 | pdata->scan_cycle_time & PTIME_MASK); |
803 | ret |= adp5589_write(client, ADP5589_5_INT_STATUS, | 481 | ret |= adp5589_write(client, ADP5589_INT_STATUS, LOGIC2_INT | |
804 | (kpad->is_adp5585 ? 0 : LOGIC2_INT) | | 482 | LOGIC1_INT | OVRFLOW_INT | LOCK_INT | |
805 | LOGIC1_INT | OVRFLOW_INT | | ||
806 | (kpad->is_adp5585 ? 0 : LOCK_INT) | | ||
807 | GPI_INT | EVENT_INT); /* Status is W1C */ | 483 | GPI_INT | EVENT_INT); /* Status is W1C */ |
808 | 484 | ||
809 | ret |= adp5589_write(client, reg(ADP5589_GENERAL_CFG), | 485 | ret |= adp5589_write(client, ADP5589_GENERAL_CFG, |
810 | INT_CFG | OSC_EN | CORE_CLK(3)); | 486 | INT_CFG | OSC_EN | CORE_CLK(3)); |
811 | ret |= adp5589_write(client, reg(ADP5589_INT_EN), | 487 | ret |= adp5589_write(client, ADP5589_INT_EN, |
812 | OVRFLOW_IEN | GPI_IEN | EVENT_IEN); | 488 | OVRFLOW_IEN | GPI_IEN | EVENT_IEN); |
813 | 489 | ||
814 | if (ret < 0) { | 490 | if (ret < 0) { |
@@ -819,35 +495,32 @@ static int adp5589_setup(struct adp5589_kpad *kpad) | |||
819 | return 0; | 495 | return 0; |
820 | } | 496 | } |
821 | 497 | ||
822 | static void adp5589_report_switch_state(struct adp5589_kpad *kpad) | 498 | static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad) |
823 | { | 499 | { |
500 | int gpi_stat1 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_A); | ||
501 | int gpi_stat2 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_B); | ||
502 | int gpi_stat3 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_C); | ||
824 | int gpi_stat_tmp, pin_loc; | 503 | int gpi_stat_tmp, pin_loc; |
825 | int i; | 504 | int i; |
826 | int gpi_stat1 = adp5589_read(kpad->client, | ||
827 | kpad->var->reg(ADP5589_GPI_STATUS_A)); | ||
828 | int gpi_stat2 = adp5589_read(kpad->client, | ||
829 | kpad->var->reg(ADP5589_GPI_STATUS_B)); | ||
830 | int gpi_stat3 = !kpad->is_adp5585 ? | ||
831 | adp5589_read(kpad->client, ADP5589_GPI_STATUS_C) : 0; | ||
832 | 505 | ||
833 | for (i = 0; i < kpad->gpimapsize; i++) { | 506 | for (i = 0; i < kpad->gpimapsize; i++) { |
834 | unsigned short pin = kpad->gpimap[i].pin; | 507 | unsigned short pin = kpad->gpimap[i].pin; |
835 | 508 | ||
836 | if (pin <= kpad->var->gpi_pin_row_end) { | 509 | if (pin <= ADP5589_GPI_PIN_ROW_END) { |
837 | gpi_stat_tmp = gpi_stat1; | 510 | gpi_stat_tmp = gpi_stat1; |
838 | pin_loc = pin - kpad->var->gpi_pin_row_base; | 511 | pin_loc = pin - ADP5589_GPI_PIN_ROW_BASE; |
839 | } else if ((pin - kpad->var->gpi_pin_col_base) < 8) { | 512 | } else if ((pin - ADP5589_GPI_PIN_COL_BASE) < 8) { |
840 | gpi_stat_tmp = gpi_stat2; | 513 | gpi_stat_tmp = gpi_stat2; |
841 | pin_loc = pin - kpad->var->gpi_pin_col_base; | 514 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE; |
842 | } else { | 515 | } else { |
843 | gpi_stat_tmp = gpi_stat3; | 516 | gpi_stat_tmp = gpi_stat3; |
844 | pin_loc = pin - kpad->var->gpi_pin_col_base - 8; | 517 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE - 8; |
845 | } | 518 | } |
846 | 519 | ||
847 | if (gpi_stat_tmp < 0) { | 520 | if (gpi_stat_tmp < 0) { |
848 | dev_err(&kpad->client->dev, | 521 | dev_err(&kpad->client->dev, |
849 | "Can't read GPIO_DAT_STAT switch %d, default to OFF\n", | 522 | "Can't read GPIO_DAT_STAT switch" |
850 | pin); | 523 | " %d default to OFF\n", pin); |
851 | gpi_stat_tmp = 0; | 524 | gpi_stat_tmp = 0; |
852 | } | 525 | } |
853 | 526 | ||
@@ -859,12 +532,11 @@ static void adp5589_report_switch_state(struct adp5589_kpad *kpad) | |||
859 | input_sync(kpad->input); | 532 | input_sync(kpad->input); |
860 | } | 533 | } |
861 | 534 | ||
862 | static int adp5589_probe(struct i2c_client *client, | 535 | static int __devinit adp5589_probe(struct i2c_client *client, |
863 | const struct i2c_device_id *id) | 536 | const struct i2c_device_id *id) |
864 | { | 537 | { |
865 | struct adp5589_kpad *kpad; | 538 | struct adp5589_kpad *kpad; |
866 | const struct adp5589_kpad_platform_data *pdata = | 539 | const struct adp5589_kpad_platform_data *pdata; |
867 | client->dev.platform_data; | ||
868 | struct input_dev *input; | 540 | struct input_dev *input; |
869 | unsigned int revid; | 541 | unsigned int revid; |
870 | int ret, i; | 542 | int ret, i; |
@@ -876,79 +548,56 @@ static int adp5589_probe(struct i2c_client *client, | |||
876 | return -EIO; | 548 | return -EIO; |
877 | } | 549 | } |
878 | 550 | ||
551 | pdata = client->dev.platform_data; | ||
879 | if (!pdata) { | 552 | if (!pdata) { |
880 | dev_err(&client->dev, "no platform data?\n"); | 553 | dev_err(&client->dev, "no platform data?\n"); |
881 | return -EINVAL; | 554 | return -EINVAL; |
882 | } | 555 | } |
883 | 556 | ||
884 | kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); | 557 | if (!((pdata->keypad_en_mask & 0xFF) && |
885 | if (!kpad) | 558 | (pdata->keypad_en_mask >> 8)) || !pdata->keymap) { |
886 | return -ENOMEM; | ||
887 | |||
888 | switch (id->driver_data) { | ||
889 | case ADP5585_02: | ||
890 | kpad->adp5585_support_row5 = true; | ||
891 | case ADP5585_01: | ||
892 | kpad->is_adp5585 = true; | ||
893 | kpad->var = &const_adp5585; | ||
894 | break; | ||
895 | case ADP5589: | ||
896 | kpad->var = &const_adp5589; | ||
897 | break; | ||
898 | } | ||
899 | |||
900 | if (!((pdata->keypad_en_mask & kpad->var->row_mask) && | ||
901 | (pdata->keypad_en_mask >> kpad->var->col_shift)) || | ||
902 | !pdata->keymap) { | ||
903 | dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); | 559 | dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); |
904 | error = -EINVAL; | 560 | return -EINVAL; |
905 | goto err_free_mem; | ||
906 | } | 561 | } |
907 | 562 | ||
908 | if (pdata->keymapsize != kpad->var->keymapsize) { | 563 | if (pdata->keymapsize != ADP5589_KEYMAPSIZE) { |
909 | dev_err(&client->dev, "invalid keymapsize\n"); | 564 | dev_err(&client->dev, "invalid keymapsize\n"); |
910 | error = -EINVAL; | 565 | return -EINVAL; |
911 | goto err_free_mem; | ||
912 | } | 566 | } |
913 | 567 | ||
914 | if (!pdata->gpimap && pdata->gpimapsize) { | 568 | if (!pdata->gpimap && pdata->gpimapsize) { |
915 | dev_err(&client->dev, "invalid gpimap from pdata\n"); | 569 | dev_err(&client->dev, "invalid gpimap from pdata\n"); |
916 | error = -EINVAL; | 570 | return -EINVAL; |
917 | goto err_free_mem; | ||
918 | } | 571 | } |
919 | 572 | ||
920 | if (pdata->gpimapsize > kpad->var->gpimapsize_max) { | 573 | if (pdata->gpimapsize > ADP5589_GPIMAPSIZE_MAX) { |
921 | dev_err(&client->dev, "invalid gpimapsize\n"); | 574 | dev_err(&client->dev, "invalid gpimapsize\n"); |
922 | error = -EINVAL; | 575 | return -EINVAL; |
923 | goto err_free_mem; | ||
924 | } | 576 | } |
925 | 577 | ||
926 | for (i = 0; i < pdata->gpimapsize; i++) { | 578 | for (i = 0; i < pdata->gpimapsize; i++) { |
927 | unsigned short pin = pdata->gpimap[i].pin; | 579 | unsigned short pin = pdata->gpimap[i].pin; |
928 | 580 | ||
929 | if (pin < kpad->var->gpi_pin_base || | 581 | if (pin < ADP5589_GPI_PIN_BASE || pin > ADP5589_GPI_PIN_END) { |
930 | pin > kpad->var->gpi_pin_end) { | ||
931 | dev_err(&client->dev, "invalid gpi pin data\n"); | 582 | dev_err(&client->dev, "invalid gpi pin data\n"); |
932 | error = -EINVAL; | 583 | return -EINVAL; |
933 | goto err_free_mem; | ||
934 | } | 584 | } |
935 | 585 | ||
936 | if ((1 << (pin - kpad->var->gpi_pin_row_base)) & | 586 | if ((1 << (pin - ADP5589_GPI_PIN_ROW_BASE)) & |
937 | pdata->keypad_en_mask) { | 587 | pdata->keypad_en_mask) { |
938 | dev_err(&client->dev, "invalid gpi row/col data\n"); | 588 | dev_err(&client->dev, "invalid gpi row/col data\n"); |
939 | error = -EINVAL; | 589 | return -EINVAL; |
940 | goto err_free_mem; | ||
941 | } | 590 | } |
942 | } | 591 | } |
943 | 592 | ||
944 | if (!client->irq) { | 593 | if (!client->irq) { |
945 | dev_err(&client->dev, "no IRQ?\n"); | 594 | dev_err(&client->dev, "no IRQ?\n"); |
946 | error = -EINVAL; | 595 | return -EINVAL; |
947 | goto err_free_mem; | ||
948 | } | 596 | } |
949 | 597 | ||
598 | kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); | ||
950 | input = input_allocate_device(); | 599 | input = input_allocate_device(); |
951 | if (!input) { | 600 | if (!kpad || !input) { |
952 | error = -ENOMEM; | 601 | error = -ENOMEM; |
953 | goto err_free_mem; | 602 | goto err_free_mem; |
954 | } | 603 | } |
@@ -956,13 +605,13 @@ static int adp5589_probe(struct i2c_client *client, | |||
956 | kpad->client = client; | 605 | kpad->client = client; |
957 | kpad->input = input; | 606 | kpad->input = input; |
958 | 607 | ||
959 | ret = adp5589_read(client, ADP5589_5_ID); | 608 | ret = adp5589_read(client, ADP5589_ID); |
960 | if (ret < 0) { | 609 | if (ret < 0) { |
961 | error = ret; | 610 | error = ret; |
962 | goto err_free_input; | 611 | goto err_free_mem; |
963 | } | 612 | } |
964 | 613 | ||
965 | revid = (u8) ret & ADP5589_5_DEVICE_ID_MASK; | 614 | revid = (u8) ret & ADP5589_DEVICE_ID_MASK; |
966 | 615 | ||
967 | input->name = client->name; | 616 | input->name = client->name; |
968 | input->phys = "adp5589-keys/input0"; | 617 | input->phys = "adp5589-keys/input0"; |
@@ -1003,7 +652,7 @@ static int adp5589_probe(struct i2c_client *client, | |||
1003 | error = input_register_device(input); | 652 | error = input_register_device(input); |
1004 | if (error) { | 653 | if (error) { |
1005 | dev_err(&client->dev, "unable to register input device\n"); | 654 | dev_err(&client->dev, "unable to register input device\n"); |
1006 | goto err_free_input; | 655 | goto err_free_mem; |
1007 | } | 656 | } |
1008 | 657 | ||
1009 | error = request_threaded_irq(client->irq, NULL, adp5589_irq, | 658 | error = request_threaded_irq(client->irq, NULL, adp5589_irq, |
@@ -1036,19 +685,18 @@ err_free_irq: | |||
1036 | err_unreg_dev: | 685 | err_unreg_dev: |
1037 | input_unregister_device(input); | 686 | input_unregister_device(input); |
1038 | input = NULL; | 687 | input = NULL; |
1039 | err_free_input: | ||
1040 | input_free_device(input); | ||
1041 | err_free_mem: | 688 | err_free_mem: |
689 | input_free_device(input); | ||
1042 | kfree(kpad); | 690 | kfree(kpad); |
1043 | 691 | ||
1044 | return error; | 692 | return error; |
1045 | } | 693 | } |
1046 | 694 | ||
1047 | static int adp5589_remove(struct i2c_client *client) | 695 | static int __devexit adp5589_remove(struct i2c_client *client) |
1048 | { | 696 | { |
1049 | struct adp5589_kpad *kpad = i2c_get_clientdata(client); | 697 | struct adp5589_kpad *kpad = i2c_get_clientdata(client); |
1050 | 698 | ||
1051 | adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0); | 699 | adp5589_write(client, ADP5589_GENERAL_CFG, 0); |
1052 | free_irq(client->irq, kpad); | 700 | free_irq(client->irq, kpad); |
1053 | input_unregister_device(kpad->input); | 701 | input_unregister_device(kpad->input); |
1054 | adp5589_gpio_remove(kpad); | 702 | adp5589_gpio_remove(kpad); |
@@ -1088,9 +736,7 @@ static int adp5589_resume(struct device *dev) | |||
1088 | static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume); | 736 | static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume); |
1089 | 737 | ||
1090 | static const struct i2c_device_id adp5589_id[] = { | 738 | static const struct i2c_device_id adp5589_id[] = { |
1091 | {"adp5589-keys", ADP5589}, | 739 | {"adp5589-keys", 0}, |
1092 | {"adp5585-keys", ADP5585_01}, | ||
1093 | {"adp5585-02-keys", ADP5585_02}, /* Adds ROW5 to ADP5585 */ | ||
1094 | {} | 740 | {} |
1095 | }; | 741 | }; |
1096 | 742 | ||
@@ -1103,12 +749,22 @@ static struct i2c_driver adp5589_driver = { | |||
1103 | .pm = &adp5589_dev_pm_ops, | 749 | .pm = &adp5589_dev_pm_ops, |
1104 | }, | 750 | }, |
1105 | .probe = adp5589_probe, | 751 | .probe = adp5589_probe, |
1106 | .remove = adp5589_remove, | 752 | .remove = __devexit_p(adp5589_remove), |
1107 | .id_table = adp5589_id, | 753 | .id_table = adp5589_id, |
1108 | }; | 754 | }; |
1109 | 755 | ||
1110 | module_i2c_driver(adp5589_driver); | 756 | static int __init adp5589_init(void) |
757 | { | ||
758 | return i2c_add_driver(&adp5589_driver); | ||
759 | } | ||
760 | module_init(adp5589_init); | ||
761 | |||
762 | static void __exit adp5589_exit(void) | ||
763 | { | ||
764 | i2c_del_driver(&adp5589_driver); | ||
765 | } | ||
766 | module_exit(adp5589_exit); | ||
1111 | 767 | ||
1112 | MODULE_LICENSE("GPL"); | 768 | MODULE_LICENSE("GPL"); |
1113 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 769 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
1114 | MODULE_DESCRIPTION("ADP5589/ADP5585 Keypad driver"); | 770 | MODULE_DESCRIPTION("ADP5589 Keypad driver"); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index add5ffd9fe2..19cfc0cf558 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -433,7 +433,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
433 | if (printk_ratelimit()) | 433 | if (printk_ratelimit()) |
434 | dev_warn(&serio->dev, | 434 | dev_warn(&serio->dev, |
435 | "Spurious %s on %s. " | 435 | "Spurious %s on %s. " |
436 | "Some program might be trying to access hardware directly.\n", | 436 | "Some program might be trying access hardware directly.\n", |
437 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | 437 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); |
438 | goto out; | 438 | goto out; |
439 | case ATKBD_RET_ERR: | 439 | case ATKBD_RET_ERR: |
@@ -1305,7 +1305,7 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf) | |||
1305 | static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) | 1305 | static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) |
1306 | { | 1306 | { |
1307 | struct input_dev *old_dev, *new_dev; | 1307 | struct input_dev *old_dev, *new_dev; |
1308 | unsigned int value; | 1308 | unsigned long value; |
1309 | int err; | 1309 | int err; |
1310 | bool old_extra; | 1310 | bool old_extra; |
1311 | unsigned char old_set; | 1311 | unsigned char old_set; |
@@ -1313,11 +1313,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1313 | if (!atkbd->write) | 1313 | if (!atkbd->write) |
1314 | return -EIO; | 1314 | return -EIO; |
1315 | 1315 | ||
1316 | err = kstrtouint(buf, 10, &value); | 1316 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1317 | if (err) | ||
1318 | return err; | ||
1319 | |||
1320 | if (value > 1) | ||
1321 | return -EINVAL; | 1317 | return -EINVAL; |
1322 | 1318 | ||
1323 | if (atkbd->extra != value) { | 1319 | if (atkbd->extra != value) { |
@@ -1393,15 +1389,11 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) | |||
1393 | static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) | 1389 | static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) |
1394 | { | 1390 | { |
1395 | struct input_dev *old_dev, *new_dev; | 1391 | struct input_dev *old_dev, *new_dev; |
1396 | unsigned int value; | 1392 | unsigned long value; |
1397 | int err; | 1393 | int err; |
1398 | bool old_scroll; | 1394 | bool old_scroll; |
1399 | 1395 | ||
1400 | err = kstrtouint(buf, 10, &value); | 1396 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1401 | if (err) | ||
1402 | return err; | ||
1403 | |||
1404 | if (value > 1) | ||
1405 | return -EINVAL; | 1397 | return -EINVAL; |
1406 | 1398 | ||
1407 | if (atkbd->scroll != value) { | 1399 | if (atkbd->scroll != value) { |
@@ -1441,7 +1433,7 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf) | |||
1441 | static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | 1433 | static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) |
1442 | { | 1434 | { |
1443 | struct input_dev *old_dev, *new_dev; | 1435 | struct input_dev *old_dev, *new_dev; |
1444 | unsigned int value; | 1436 | unsigned long value; |
1445 | int err; | 1437 | int err; |
1446 | unsigned char old_set; | 1438 | unsigned char old_set; |
1447 | bool old_extra; | 1439 | bool old_extra; |
@@ -1449,11 +1441,7 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | |||
1449 | if (!atkbd->write) | 1441 | if (!atkbd->write) |
1450 | return -EIO; | 1442 | return -EIO; |
1451 | 1443 | ||
1452 | err = kstrtouint(buf, 10, &value); | 1444 | if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3)) |
1453 | if (err) | ||
1454 | return err; | ||
1455 | |||
1456 | if (value != 2 && value != 3) | ||
1457 | return -EINVAL; | 1445 | return -EINVAL; |
1458 | 1446 | ||
1459 | if (atkbd->set != value) { | 1447 | if (atkbd->set != value) { |
@@ -1496,18 +1484,14 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf) | |||
1496 | static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) | 1484 | static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) |
1497 | { | 1485 | { |
1498 | struct input_dev *old_dev, *new_dev; | 1486 | struct input_dev *old_dev, *new_dev; |
1499 | unsigned int value; | 1487 | unsigned long value; |
1500 | int err; | 1488 | int err; |
1501 | bool old_softrepeat, old_softraw; | 1489 | bool old_softrepeat, old_softraw; |
1502 | 1490 | ||
1503 | if (!atkbd->write) | 1491 | if (!atkbd->write) |
1504 | return -EIO; | 1492 | return -EIO; |
1505 | 1493 | ||
1506 | err = kstrtouint(buf, 10, &value); | 1494 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1507 | if (err) | ||
1508 | return err; | ||
1509 | |||
1510 | if (value > 1) | ||
1511 | return -EINVAL; | 1495 | return -EINVAL; |
1512 | 1496 | ||
1513 | if (atkbd->softrepeat != value) { | 1497 | if (atkbd->softrepeat != value) { |
@@ -1550,15 +1534,11 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf) | |||
1550 | static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) | 1534 | static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) |
1551 | { | 1535 | { |
1552 | struct input_dev *old_dev, *new_dev; | 1536 | struct input_dev *old_dev, *new_dev; |
1553 | unsigned int value; | 1537 | unsigned long value; |
1554 | int err; | 1538 | int err; |
1555 | bool old_softraw; | 1539 | bool old_softraw; |
1556 | 1540 | ||
1557 | err = kstrtouint(buf, 10, &value); | 1541 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1558 | if (err) | ||
1559 | return err; | ||
1560 | |||
1561 | if (value > 1) | ||
1562 | return -EINVAL; | 1542 | return -EINVAL; |
1563 | 1543 | ||
1564 | if (atkbd->softraw != value) { | 1544 | if (atkbd->softraw != value) { |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 20b9fa91fb9..7d989603f87 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -177,7 +177,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) | |||
177 | return IRQ_HANDLED; | 177 | return IRQ_HANDLED; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int bfin_kpad_probe(struct platform_device *pdev) | 180 | static int __devinit bfin_kpad_probe(struct platform_device *pdev) |
181 | { | 181 | { |
182 | struct bf54x_kpad *bf54x_kpad; | 182 | struct bf54x_kpad *bf54x_kpad; |
183 | struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; | 183 | struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; |
@@ -331,7 +331,7 @@ out: | |||
331 | return error; | 331 | return error; |
332 | } | 332 | } |
333 | 333 | ||
334 | static int bfin_kpad_remove(struct platform_device *pdev) | 334 | static int __devexit bfin_kpad_remove(struct platform_device *pdev) |
335 | { | 335 | { |
336 | struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; | 336 | struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; |
337 | struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); | 337 | struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); |
@@ -384,17 +384,29 @@ static int bfin_kpad_resume(struct platform_device *pdev) | |||
384 | # define bfin_kpad_resume NULL | 384 | # define bfin_kpad_resume NULL |
385 | #endif | 385 | #endif |
386 | 386 | ||
387 | static struct platform_driver bfin_kpad_device_driver = { | 387 | struct platform_driver bfin_kpad_device_driver = { |
388 | .driver = { | 388 | .driver = { |
389 | .name = DRV_NAME, | 389 | .name = DRV_NAME, |
390 | .owner = THIS_MODULE, | 390 | .owner = THIS_MODULE, |
391 | }, | 391 | }, |
392 | .probe = bfin_kpad_probe, | 392 | .probe = bfin_kpad_probe, |
393 | .remove = bfin_kpad_remove, | 393 | .remove = __devexit_p(bfin_kpad_remove), |
394 | .suspend = bfin_kpad_suspend, | 394 | .suspend = bfin_kpad_suspend, |
395 | .resume = bfin_kpad_resume, | 395 | .resume = bfin_kpad_resume, |
396 | }; | 396 | }; |
397 | module_platform_driver(bfin_kpad_device_driver); | 397 | |
398 | static int __init bfin_kpad_init(void) | ||
399 | { | ||
400 | return platform_driver_register(&bfin_kpad_device_driver); | ||
401 | } | ||
402 | |||
403 | static void __exit bfin_kpad_exit(void) | ||
404 | { | ||
405 | platform_driver_unregister(&bfin_kpad_device_driver); | ||
406 | } | ||
407 | |||
408 | module_init(bfin_kpad_init); | ||
409 | module_exit(bfin_kpad_exit); | ||
398 | 410 | ||
399 | MODULE_LICENSE("GPL"); | 411 | MODULE_LICENSE("GPL"); |
400 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 412 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 4e4e453ea15..cd89d17162a 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
38 | #include <mach/irqs.h> | 38 | #include <mach/irqs.h> |
39 | #include <linux/platform_data/keyscan-davinci.h> | 39 | #include <mach/keyscan.h> |
40 | 40 | ||
41 | /* Key scan registers */ | 41 | /* Key scan registers */ |
42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 | 42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 |
@@ -271,7 +271,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev) | |||
271 | } | 271 | } |
272 | 272 | ||
273 | error = request_irq(davinci_ks->irq, davinci_ks_interrupt, | 273 | error = request_irq(davinci_ks->irq, davinci_ks_interrupt, |
274 | 0, pdev->name, davinci_ks); | 274 | IRQF_DISABLED, pdev->name, davinci_ks); |
275 | if (error < 0) { | 275 | if (error < 0) { |
276 | dev_err(dev, "unable to register davinci key scan interrupt\n"); | 276 | dev_err(dev, "unable to register davinci key scan interrupt\n"); |
277 | goto fail5; | 277 | goto fail5; |
@@ -303,7 +303,7 @@ fail1: | |||
303 | return error; | 303 | return error; |
304 | } | 304 | } |
305 | 305 | ||
306 | static int davinci_ks_remove(struct platform_device *pdev) | 306 | static int __devexit davinci_ks_remove(struct platform_device *pdev) |
307 | { | 307 | { |
308 | struct davinci_ks *davinci_ks = platform_get_drvdata(pdev); | 308 | struct davinci_ks *davinci_ks = platform_get_drvdata(pdev); |
309 | 309 | ||
@@ -326,7 +326,7 @@ static struct platform_driver davinci_ks_driver = { | |||
326 | .name = "davinci_keyscan", | 326 | .name = "davinci_keyscan", |
327 | .owner = THIS_MODULE, | 327 | .owner = THIS_MODULE, |
328 | }, | 328 | }, |
329 | .remove = davinci_ks_remove, | 329 | .remove = __devexit_p(davinci_ks_remove), |
330 | }; | 330 | }; |
331 | 331 | ||
332 | static int __init davinci_ks_init(void) | 332 | static int __init davinci_ks_init(void) |
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index 9857e8fd098..aa17e024d80 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | 30 | ||
31 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
32 | #include <linux/platform_data/keypad-ep93xx.h> | 32 | #include <mach/ep93xx_keypad.h> |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Keypad Interface Register offsets | 35 | * Keypad Interface Register offsets |
@@ -182,10 +182,16 @@ static void ep93xx_keypad_close(struct input_dev *pdev) | |||
182 | } | 182 | } |
183 | 183 | ||
184 | 184 | ||
185 | #ifdef CONFIG_PM_SLEEP | 185 | #ifdef CONFIG_PM |
186 | static int ep93xx_keypad_suspend(struct device *dev) | 186 | /* |
187 | * NOTE: I don't know if this is correct, or will work on the ep93xx. | ||
188 | * | ||
189 | * None of the existing ep93xx drivers have power management support. | ||
190 | * But, this is basically what the pxa27x_keypad driver does. | ||
191 | */ | ||
192 | static int ep93xx_keypad_suspend(struct platform_device *pdev, | ||
193 | pm_message_t state) | ||
187 | { | 194 | { |
188 | struct platform_device *pdev = to_platform_device(dev); | ||
189 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | 195 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); |
190 | struct input_dev *input_dev = keypad->input_dev; | 196 | struct input_dev *input_dev = keypad->input_dev; |
191 | 197 | ||
@@ -204,9 +210,8 @@ static int ep93xx_keypad_suspend(struct device *dev) | |||
204 | return 0; | 210 | return 0; |
205 | } | 211 | } |
206 | 212 | ||
207 | static int ep93xx_keypad_resume(struct device *dev) | 213 | static int ep93xx_keypad_resume(struct platform_device *pdev) |
208 | { | 214 | { |
209 | struct platform_device *pdev = to_platform_device(dev); | ||
210 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | 215 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); |
211 | struct input_dev *input_dev = keypad->input_dev; | 216 | struct input_dev *input_dev = keypad->input_dev; |
212 | 217 | ||
@@ -227,12 +232,12 @@ static int ep93xx_keypad_resume(struct device *dev) | |||
227 | 232 | ||
228 | return 0; | 233 | return 0; |
229 | } | 234 | } |
230 | #endif | 235 | #else /* !CONFIG_PM */ |
236 | #define ep93xx_keypad_suspend NULL | ||
237 | #define ep93xx_keypad_resume NULL | ||
238 | #endif /* !CONFIG_PM */ | ||
231 | 239 | ||
232 | static SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops, | 240 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) |
233 | ep93xx_keypad_suspend, ep93xx_keypad_resume); | ||
234 | |||
235 | static int ep93xx_keypad_probe(struct platform_device *pdev) | ||
236 | { | 241 | { |
237 | struct ep93xx_keypad *keypad; | 242 | struct ep93xx_keypad *keypad; |
238 | const struct matrix_keymap_data *keymap_data; | 243 | const struct matrix_keymap_data *keymap_data; |
@@ -303,19 +308,22 @@ static int ep93xx_keypad_probe(struct platform_device *pdev) | |||
303 | input_dev->open = ep93xx_keypad_open; | 308 | input_dev->open = ep93xx_keypad_open; |
304 | input_dev->close = ep93xx_keypad_close; | 309 | input_dev->close = ep93xx_keypad_close; |
305 | input_dev->dev.parent = &pdev->dev; | 310 | input_dev->dev.parent = &pdev->dev; |
311 | input_dev->keycode = keypad->keycodes; | ||
312 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
313 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
306 | 314 | ||
307 | err = matrix_keypad_build_keymap(keymap_data, NULL, | 315 | input_set_drvdata(input_dev, keypad); |
308 | EP93XX_MATRIX_ROWS, EP93XX_MATRIX_COLS, | ||
309 | keypad->keycodes, input_dev); | ||
310 | if (err) | ||
311 | goto failed_free_dev; | ||
312 | 316 | ||
317 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
313 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) | 318 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) |
314 | __set_bit(EV_REP, input_dev->evbit); | 319 | input_dev->evbit[0] |= BIT_MASK(EV_REP); |
315 | input_set_drvdata(input_dev, keypad); | 320 | |
321 | matrix_keypad_build_keymap(keymap_data, 3, | ||
322 | input_dev->keycode, input_dev->keybit); | ||
323 | platform_set_drvdata(pdev, keypad); | ||
316 | 324 | ||
317 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, | 325 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, |
318 | 0, pdev->name, keypad); | 326 | IRQF_DISABLED, pdev->name, keypad); |
319 | if (err) | 327 | if (err) |
320 | goto failed_free_dev; | 328 | goto failed_free_dev; |
321 | 329 | ||
@@ -323,7 +331,6 @@ static int ep93xx_keypad_probe(struct platform_device *pdev) | |||
323 | if (err) | 331 | if (err) |
324 | goto failed_free_irq; | 332 | goto failed_free_irq; |
325 | 333 | ||
326 | platform_set_drvdata(pdev, keypad); | ||
327 | device_init_wakeup(&pdev->dev, 1); | 334 | device_init_wakeup(&pdev->dev, 1); |
328 | 335 | ||
329 | return 0; | 336 | return 0; |
@@ -346,7 +353,7 @@ failed_free: | |||
346 | return err; | 353 | return err; |
347 | } | 354 | } |
348 | 355 | ||
349 | static int ep93xx_keypad_remove(struct platform_device *pdev) | 356 | static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) |
350 | { | 357 | { |
351 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | 358 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); |
352 | struct resource *res; | 359 | struct resource *res; |
@@ -377,12 +384,25 @@ static struct platform_driver ep93xx_keypad_driver = { | |||
377 | .driver = { | 384 | .driver = { |
378 | .name = "ep93xx-keypad", | 385 | .name = "ep93xx-keypad", |
379 | .owner = THIS_MODULE, | 386 | .owner = THIS_MODULE, |
380 | .pm = &ep93xx_keypad_pm_ops, | ||
381 | }, | 387 | }, |
382 | .probe = ep93xx_keypad_probe, | 388 | .probe = ep93xx_keypad_probe, |
383 | .remove = ep93xx_keypad_remove, | 389 | .remove = __devexit_p(ep93xx_keypad_remove), |
390 | .suspend = ep93xx_keypad_suspend, | ||
391 | .resume = ep93xx_keypad_resume, | ||
384 | }; | 392 | }; |
385 | module_platform_driver(ep93xx_keypad_driver); | 393 | |
394 | static int __init ep93xx_keypad_init(void) | ||
395 | { | ||
396 | return platform_driver_register(&ep93xx_keypad_driver); | ||
397 | } | ||
398 | |||
399 | static void __exit ep93xx_keypad_exit(void) | ||
400 | { | ||
401 | platform_driver_unregister(&ep93xx_keypad_driver); | ||
402 | } | ||
403 | |||
404 | module_init(ep93xx_keypad_init); | ||
405 | module_exit(ep93xx_keypad_exit); | ||
386 | 406 | ||
387 | MODULE_LICENSE("GPL"); | 407 | MODULE_LICENSE("GPL"); |
388 | MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); | 408 | MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index b29ca651a39..1def6f105d6 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright 2005 Phil Blundell | 4 | * Copyright 2005 Phil Blundell |
5 | * Copyright 2010, 2011 David Jander <david@protonic.nl> | 5 | * Copyright 2010, 2011 David Jander <david@protonic.nl> |
6 | * | 6 | * |
7 | * Copyright 2010-2011 NVIDIA Corporation | ||
8 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
@@ -43,9 +45,11 @@ struct gpio_button_data { | |||
43 | }; | 45 | }; |
44 | 46 | ||
45 | struct gpio_keys_drvdata { | 47 | struct gpio_keys_drvdata { |
46 | const struct gpio_keys_platform_data *pdata; | ||
47 | struct input_dev *input; | 48 | struct input_dev *input; |
48 | struct mutex disable_lock; | 49 | struct mutex disable_lock; |
50 | unsigned int n_buttons; | ||
51 | int (*enable)(struct device *dev); | ||
52 | void (*disable)(struct device *dev); | ||
49 | struct gpio_button_data data[0]; | 53 | struct gpio_button_data data[0]; |
50 | }; | 54 | }; |
51 | 55 | ||
@@ -169,7 +173,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, | |||
169 | if (!bits) | 173 | if (!bits) |
170 | return -ENOMEM; | 174 | return -ENOMEM; |
171 | 175 | ||
172 | for (i = 0; i < ddata->pdata->nbuttons; i++) { | 176 | for (i = 0; i < ddata->n_buttons; i++) { |
173 | struct gpio_button_data *bdata = &ddata->data[i]; | 177 | struct gpio_button_data *bdata = &ddata->data[i]; |
174 | 178 | ||
175 | if (bdata->button->type != type) | 179 | if (bdata->button->type != type) |
@@ -217,7 +221,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | |||
217 | goto out; | 221 | goto out; |
218 | 222 | ||
219 | /* First validate */ | 223 | /* First validate */ |
220 | for (i = 0; i < ddata->pdata->nbuttons; i++) { | 224 | for (i = 0; i < ddata->n_buttons; i++) { |
221 | struct gpio_button_data *bdata = &ddata->data[i]; | 225 | struct gpio_button_data *bdata = &ddata->data[i]; |
222 | 226 | ||
223 | if (bdata->button->type != type) | 227 | if (bdata->button->type != type) |
@@ -232,7 +236,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | |||
232 | 236 | ||
233 | mutex_lock(&ddata->disable_lock); | 237 | mutex_lock(&ddata->disable_lock); |
234 | 238 | ||
235 | for (i = 0; i < ddata->pdata->nbuttons; i++) { | 239 | for (i = 0; i < ddata->n_buttons; i++) { |
236 | struct gpio_button_data *bdata = &ddata->data[i]; | 240 | struct gpio_button_data *bdata = &ddata->data[i]; |
237 | 241 | ||
238 | if (bdata->button->type != type) | 242 | if (bdata->button->type != type) |
@@ -344,9 +348,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) | |||
344 | container_of(work, struct gpio_button_data, work); | 348 | container_of(work, struct gpio_button_data, work); |
345 | 349 | ||
346 | gpio_keys_gpio_report_event(bdata); | 350 | gpio_keys_gpio_report_event(bdata); |
347 | |||
348 | if (bdata->button->wakeup) | ||
349 | pm_relax(bdata->input->dev.parent); | ||
350 | } | 351 | } |
351 | 352 | ||
352 | static void gpio_keys_gpio_timer(unsigned long _data) | 353 | static void gpio_keys_gpio_timer(unsigned long _data) |
@@ -362,8 +363,6 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) | |||
362 | 363 | ||
363 | BUG_ON(irq != bdata->irq); | 364 | BUG_ON(irq != bdata->irq); |
364 | 365 | ||
365 | if (bdata->button->wakeup) | ||
366 | pm_stay_awake(bdata->input->dev.parent); | ||
367 | if (bdata->timer_debounce) | 366 | if (bdata->timer_debounce) |
368 | mod_timer(&bdata->timer, | 367 | mod_timer(&bdata->timer, |
369 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); | 368 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); |
@@ -400,9 +399,6 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) | |||
400 | spin_lock_irqsave(&bdata->lock, flags); | 399 | spin_lock_irqsave(&bdata->lock, flags); |
401 | 400 | ||
402 | if (!bdata->key_pressed) { | 401 | if (!bdata->key_pressed) { |
403 | if (bdata->button->wakeup) | ||
404 | pm_wakeup_event(bdata->input->dev.parent, 0); | ||
405 | |||
406 | input_event(input, EV_KEY, button->code, 1); | 402 | input_event(input, EV_KEY, button->code, 1); |
407 | input_sync(input); | 403 | input_sync(input); |
408 | 404 | ||
@@ -423,10 +419,10 @@ out: | |||
423 | return IRQ_HANDLED; | 419 | return IRQ_HANDLED; |
424 | } | 420 | } |
425 | 421 | ||
426 | static int gpio_keys_setup_key(struct platform_device *pdev, | 422 | static int __devinit gpio_keys_setup_key(struct platform_device *pdev, |
427 | struct input_dev *input, | 423 | struct input_dev *input, |
428 | struct gpio_button_data *bdata, | 424 | struct gpio_button_data *bdata, |
429 | const struct gpio_keys_button *button) | 425 | const struct gpio_keys_button *button) |
430 | { | 426 | { |
431 | const char *desc = button->desc ? button->desc : "gpio_keys"; | 427 | const char *desc = button->desc ? button->desc : "gpio_keys"; |
432 | struct device *dev = &pdev->dev; | 428 | struct device *dev = &pdev->dev; |
@@ -440,13 +436,21 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
440 | 436 | ||
441 | if (gpio_is_valid(button->gpio)) { | 437 | if (gpio_is_valid(button->gpio)) { |
442 | 438 | ||
443 | error = gpio_request_one(button->gpio, GPIOF_IN, desc); | 439 | error = gpio_request(button->gpio, desc); |
444 | if (error < 0) { | 440 | if (error < 0) { |
445 | dev_err(dev, "Failed to request GPIO %d, error %d\n", | 441 | dev_err(dev, "Failed to request GPIO %d, error %d\n", |
446 | button->gpio, error); | 442 | button->gpio, error); |
447 | return error; | 443 | return error; |
448 | } | 444 | } |
449 | 445 | ||
446 | error = gpio_direction_input(button->gpio); | ||
447 | if (error < 0) { | ||
448 | dev_err(dev, | ||
449 | "Failed to configure direction for GPIO %d, error %d\n", | ||
450 | button->gpio, error); | ||
451 | goto fail; | ||
452 | } | ||
453 | |||
450 | if (button->debounce_interval) { | 454 | if (button->debounce_interval) { |
451 | error = gpio_set_debounce(button->gpio, | 455 | error = gpio_set_debounce(button->gpio, |
452 | button->debounce_interval * 1000); | 456 | button->debounce_interval * 1000); |
@@ -518,91 +522,60 @@ fail: | |||
518 | return error; | 522 | return error; |
519 | } | 523 | } |
520 | 524 | ||
521 | static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata) | ||
522 | { | ||
523 | struct input_dev *input = ddata->input; | ||
524 | int i; | ||
525 | |||
526 | for (i = 0; i < ddata->pdata->nbuttons; i++) { | ||
527 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
528 | if (gpio_is_valid(bdata->button->gpio)) | ||
529 | gpio_keys_gpio_report_event(bdata); | ||
530 | } | ||
531 | input_sync(input); | ||
532 | } | ||
533 | |||
534 | static int gpio_keys_open(struct input_dev *input) | 525 | static int gpio_keys_open(struct input_dev *input) |
535 | { | 526 | { |
536 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); | 527 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); |
537 | const struct gpio_keys_platform_data *pdata = ddata->pdata; | ||
538 | int error; | ||
539 | |||
540 | if (pdata->enable) { | ||
541 | error = pdata->enable(input->dev.parent); | ||
542 | if (error) | ||
543 | return error; | ||
544 | } | ||
545 | 528 | ||
546 | /* Report current state of buttons that are connected to GPIOs */ | 529 | return ddata->enable ? ddata->enable(input->dev.parent) : 0; |
547 | gpio_keys_report_state(ddata); | ||
548 | |||
549 | return 0; | ||
550 | } | 530 | } |
551 | 531 | ||
552 | static void gpio_keys_close(struct input_dev *input) | 532 | static void gpio_keys_close(struct input_dev *input) |
553 | { | 533 | { |
554 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); | 534 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); |
555 | const struct gpio_keys_platform_data *pdata = ddata->pdata; | ||
556 | 535 | ||
557 | if (pdata->disable) | 536 | if (ddata->disable) |
558 | pdata->disable(input->dev.parent); | 537 | ddata->disable(input->dev.parent); |
559 | } | 538 | } |
560 | 539 | ||
561 | /* | 540 | /* |
562 | * Handlers for alternative sources of platform_data | 541 | * Handlers for alternative sources of platform_data |
563 | */ | 542 | */ |
564 | |||
565 | #ifdef CONFIG_OF | 543 | #ifdef CONFIG_OF |
566 | /* | 544 | /* |
567 | * Translate OpenFirmware node properties into platform_data | 545 | * Translate OpenFirmware node properties into platform_data |
568 | */ | 546 | */ |
569 | static struct gpio_keys_platform_data * | 547 | static int gpio_keys_get_devtree_pdata(struct device *dev, |
570 | gpio_keys_get_devtree_pdata(struct device *dev) | 548 | struct gpio_keys_platform_data *pdata) |
571 | { | 549 | { |
572 | struct device_node *node, *pp; | 550 | struct device_node *node, *pp; |
573 | struct gpio_keys_platform_data *pdata; | ||
574 | struct gpio_keys_button *button; | ||
575 | int error; | ||
576 | int nbuttons; | ||
577 | int i; | 551 | int i; |
552 | struct gpio_keys_button *buttons; | ||
553 | u32 reg; | ||
578 | 554 | ||
579 | node = dev->of_node; | 555 | node = dev->of_node; |
580 | if (!node) { | 556 | if (node == NULL) |
581 | error = -ENODEV; | 557 | return -ENODEV; |
582 | goto err_out; | ||
583 | } | ||
584 | 558 | ||
585 | nbuttons = of_get_child_count(node); | 559 | memset(pdata, 0, sizeof *pdata); |
586 | if (nbuttons == 0) { | ||
587 | error = -ENODEV; | ||
588 | goto err_out; | ||
589 | } | ||
590 | 560 | ||
591 | pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), | 561 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); |
592 | GFP_KERNEL); | ||
593 | if (!pdata) { | ||
594 | error = -ENOMEM; | ||
595 | goto err_out; | ||
596 | } | ||
597 | 562 | ||
598 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); | 563 | /* First count the subnodes */ |
599 | pdata->nbuttons = nbuttons; | 564 | pdata->nbuttons = 0; |
565 | pp = NULL; | ||
566 | while ((pp = of_get_next_child(node, pp))) | ||
567 | pdata->nbuttons++; | ||
600 | 568 | ||
601 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); | 569 | if (pdata->nbuttons == 0) |
570 | return -ENODEV; | ||
571 | |||
572 | buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); | ||
573 | if (!buttons) | ||
574 | return -ENOMEM; | ||
602 | 575 | ||
576 | pp = NULL; | ||
603 | i = 0; | 577 | i = 0; |
604 | for_each_child_of_node(node, pp) { | 578 | while ((pp = of_get_next_child(node, pp))) { |
605 | int gpio; | ||
606 | enum of_gpio_flags flags; | 579 | enum of_gpio_flags flags; |
607 | 580 | ||
608 | if (!of_find_property(pp, "gpios", NULL)) { | 581 | if (!of_find_property(pp, "gpios", NULL)) { |
@@ -610,52 +583,39 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
610 | dev_warn(dev, "Found button without gpios\n"); | 583 | dev_warn(dev, "Found button without gpios\n"); |
611 | continue; | 584 | continue; |
612 | } | 585 | } |
586 | buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); | ||
587 | buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
613 | 588 | ||
614 | gpio = of_get_gpio_flags(pp, 0, &flags); | 589 | if (of_property_read_u32(pp, "linux,code", ®)) { |
615 | if (gpio < 0) { | 590 | dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); |
616 | error = gpio; | 591 | goto out_fail; |
617 | if (error != -EPROBE_DEFER) | ||
618 | dev_err(dev, | ||
619 | "Failed to get gpio flags, error: %d\n", | ||
620 | error); | ||
621 | goto err_free_pdata; | ||
622 | } | 592 | } |
593 | buttons[i].code = reg; | ||
623 | 594 | ||
624 | button = &pdata->buttons[i++]; | 595 | buttons[i].desc = of_get_property(pp, "label", NULL); |
625 | 596 | ||
626 | button->gpio = gpio; | 597 | if (of_property_read_u32(pp, "linux,input-type", ®) == 0) |
627 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | 598 | buttons[i].type = reg; |
628 | 599 | else | |
629 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | 600 | buttons[i].type = EV_KEY; |
630 | dev_err(dev, "Button without keycode: 0x%x\n", | ||
631 | button->gpio); | ||
632 | error = -EINVAL; | ||
633 | goto err_free_pdata; | ||
634 | } | ||
635 | |||
636 | button->desc = of_get_property(pp, "label", NULL); | ||
637 | 601 | ||
638 | if (of_property_read_u32(pp, "linux,input-type", &button->type)) | 602 | buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); |
639 | button->type = EV_KEY; | ||
640 | 603 | ||
641 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | 604 | if (of_property_read_u32(pp, "debounce-interval", ®) == 0) |
605 | buttons[i].debounce_interval = reg; | ||
606 | else | ||
607 | buttons[i].debounce_interval = 5; | ||
642 | 608 | ||
643 | if (of_property_read_u32(pp, "debounce-interval", | 609 | i++; |
644 | &button->debounce_interval)) | ||
645 | button->debounce_interval = 5; | ||
646 | } | 610 | } |
647 | 611 | ||
648 | if (pdata->nbuttons == 0) { | 612 | pdata->buttons = buttons; |
649 | error = -EINVAL; | ||
650 | goto err_free_pdata; | ||
651 | } | ||
652 | 613 | ||
653 | return pdata; | 614 | return 0; |
654 | 615 | ||
655 | err_free_pdata: | 616 | out_fail: |
656 | kfree(pdata); | 617 | kfree(buttons); |
657 | err_out: | 618 | return -ENODEV; |
658 | return ERR_PTR(error); | ||
659 | } | 619 | } |
660 | 620 | ||
661 | static struct of_device_id gpio_keys_of_match[] = { | 621 | static struct of_device_id gpio_keys_of_match[] = { |
@@ -666,12 +626,14 @@ MODULE_DEVICE_TABLE(of, gpio_keys_of_match); | |||
666 | 626 | ||
667 | #else | 627 | #else |
668 | 628 | ||
669 | static inline struct gpio_keys_platform_data * | 629 | static int gpio_keys_get_devtree_pdata(struct device *dev, |
670 | gpio_keys_get_devtree_pdata(struct device *dev) | 630 | struct gpio_keys_platform_data *altp) |
671 | { | 631 | { |
672 | return ERR_PTR(-ENODEV); | 632 | return -ENODEV; |
673 | } | 633 | } |
674 | 634 | ||
635 | #define gpio_keys_of_match NULL | ||
636 | |||
675 | #endif | 637 | #endif |
676 | 638 | ||
677 | static void gpio_remove_key(struct gpio_button_data *bdata) | 639 | static void gpio_remove_key(struct gpio_button_data *bdata) |
@@ -684,19 +646,21 @@ static void gpio_remove_key(struct gpio_button_data *bdata) | |||
684 | gpio_free(bdata->button->gpio); | 646 | gpio_free(bdata->button->gpio); |
685 | } | 647 | } |
686 | 648 | ||
687 | static int gpio_keys_probe(struct platform_device *pdev) | 649 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
688 | { | 650 | { |
689 | struct device *dev = &pdev->dev; | 651 | const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
690 | const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); | ||
691 | struct gpio_keys_drvdata *ddata; | 652 | struct gpio_keys_drvdata *ddata; |
653 | struct device *dev = &pdev->dev; | ||
654 | struct gpio_keys_platform_data alt_pdata; | ||
692 | struct input_dev *input; | 655 | struct input_dev *input; |
693 | int i, error; | 656 | int i, error; |
694 | int wakeup = 0; | 657 | int wakeup = 0; |
695 | 658 | ||
696 | if (!pdata) { | 659 | if (!pdata) { |
697 | pdata = gpio_keys_get_devtree_pdata(dev); | 660 | error = gpio_keys_get_devtree_pdata(dev, &alt_pdata); |
698 | if (IS_ERR(pdata)) | 661 | if (error) |
699 | return PTR_ERR(pdata); | 662 | return error; |
663 | pdata = &alt_pdata; | ||
700 | } | 664 | } |
701 | 665 | ||
702 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + | 666 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + |
@@ -709,8 +673,10 @@ static int gpio_keys_probe(struct platform_device *pdev) | |||
709 | goto fail1; | 673 | goto fail1; |
710 | } | 674 | } |
711 | 675 | ||
712 | ddata->pdata = pdata; | ||
713 | ddata->input = input; | 676 | ddata->input = input; |
677 | ddata->n_buttons = pdata->nbuttons; | ||
678 | ddata->enable = pdata->enable; | ||
679 | ddata->disable = pdata->disable; | ||
714 | mutex_init(&ddata->disable_lock); | 680 | mutex_init(&ddata->disable_lock); |
715 | 681 | ||
716 | platform_set_drvdata(pdev, ddata); | 682 | platform_set_drvdata(pdev, ddata); |
@@ -757,6 +723,14 @@ static int gpio_keys_probe(struct platform_device *pdev) | |||
757 | goto fail3; | 723 | goto fail3; |
758 | } | 724 | } |
759 | 725 | ||
726 | /* get current state of buttons that are connected to GPIOs */ | ||
727 | for (i = 0; i < pdata->nbuttons; i++) { | ||
728 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
729 | if (gpio_is_valid(bdata->button->gpio)) | ||
730 | gpio_keys_gpio_report_event(bdata); | ||
731 | } | ||
732 | input_sync(input); | ||
733 | |||
760 | device_init_wakeup(&pdev->dev, wakeup); | 734 | device_init_wakeup(&pdev->dev, wakeup); |
761 | 735 | ||
762 | return 0; | 736 | return 0; |
@@ -771,14 +745,14 @@ static int gpio_keys_probe(struct platform_device *pdev) | |||
771 | fail1: | 745 | fail1: |
772 | input_free_device(input); | 746 | input_free_device(input); |
773 | kfree(ddata); | 747 | kfree(ddata); |
774 | /* If we have no platform data, we allocated pdata dynamically. */ | 748 | /* If we have no platform_data, we allocated buttons dynamically. */ |
775 | if (!dev_get_platdata(&pdev->dev)) | 749 | if (!pdev->dev.platform_data) |
776 | kfree(pdata); | 750 | kfree(pdata->buttons); |
777 | 751 | ||
778 | return error; | 752 | return error; |
779 | } | 753 | } |
780 | 754 | ||
781 | static int gpio_keys_remove(struct platform_device *pdev) | 755 | static int __devexit gpio_keys_remove(struct platform_device *pdev) |
782 | { | 756 | { |
783 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | 757 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); |
784 | struct input_dev *input = ddata->input; | 758 | struct input_dev *input = ddata->input; |
@@ -788,14 +762,18 @@ static int gpio_keys_remove(struct platform_device *pdev) | |||
788 | 762 | ||
789 | device_init_wakeup(&pdev->dev, 0); | 763 | device_init_wakeup(&pdev->dev, 0); |
790 | 764 | ||
791 | for (i = 0; i < ddata->pdata->nbuttons; i++) | 765 | for (i = 0; i < ddata->n_buttons; i++) |
792 | gpio_remove_key(&ddata->data[i]); | 766 | gpio_remove_key(&ddata->data[i]); |
793 | 767 | ||
794 | input_unregister_device(input); | 768 | input_unregister_device(input); |
795 | 769 | ||
796 | /* If we have no platform data, we allocated pdata dynamically. */ | 770 | /* |
797 | if (!dev_get_platdata(&pdev->dev)) | 771 | * If we had no platform_data, we allocated buttons dynamically, and |
798 | kfree(ddata->pdata); | 772 | * must free them here. ddata->data[0].button is the pointer to the |
773 | * beginning of the allocated array. | ||
774 | */ | ||
775 | if (!pdev->dev.platform_data) | ||
776 | kfree(ddata->data[0].button); | ||
799 | 777 | ||
800 | kfree(ddata); | 778 | kfree(ddata); |
801 | 779 | ||
@@ -806,20 +784,14 @@ static int gpio_keys_remove(struct platform_device *pdev) | |||
806 | static int gpio_keys_suspend(struct device *dev) | 784 | static int gpio_keys_suspend(struct device *dev) |
807 | { | 785 | { |
808 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); | 786 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); |
809 | struct input_dev *input = ddata->input; | ||
810 | int i; | 787 | int i; |
811 | 788 | ||
812 | if (device_may_wakeup(dev)) { | 789 | if (device_may_wakeup(dev)) { |
813 | for (i = 0; i < ddata->pdata->nbuttons; i++) { | 790 | for (i = 0; i < ddata->n_buttons; i++) { |
814 | struct gpio_button_data *bdata = &ddata->data[i]; | 791 | struct gpio_button_data *bdata = &ddata->data[i]; |
815 | if (bdata->button->wakeup) | 792 | if (bdata->button->wakeup) |
816 | enable_irq_wake(bdata->irq); | 793 | enable_irq_wake(bdata->irq); |
817 | } | 794 | } |
818 | } else { | ||
819 | mutex_lock(&input->mutex); | ||
820 | if (input->users) | ||
821 | gpio_keys_close(input); | ||
822 | mutex_unlock(&input->mutex); | ||
823 | } | 795 | } |
824 | 796 | ||
825 | return 0; | 797 | return 0; |
@@ -827,28 +799,33 @@ static int gpio_keys_suspend(struct device *dev) | |||
827 | 799 | ||
828 | static int gpio_keys_resume(struct device *dev) | 800 | static int gpio_keys_resume(struct device *dev) |
829 | { | 801 | { |
802 | struct platform_device *pdev = to_platform_device(dev); | ||
830 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); | 803 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); |
831 | struct input_dev *input = ddata->input; | 804 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
832 | int error = 0; | 805 | int wakeup_key = KEY_RESERVED; |
833 | int i; | 806 | int i; |
834 | 807 | ||
835 | if (device_may_wakeup(dev)) { | 808 | if (pdata && pdata->wakeup_key) |
836 | for (i = 0; i < ddata->pdata->nbuttons; i++) { | 809 | wakeup_key = pdata->wakeup_key(); |
837 | struct gpio_button_data *bdata = &ddata->data[i]; | 810 | |
838 | if (bdata->button->wakeup) | 811 | for (i = 0; i < ddata->n_buttons; i++) { |
839 | disable_irq_wake(bdata->irq); | 812 | struct gpio_button_data *bdata = &ddata->data[i]; |
813 | if (bdata->button->wakeup && device_may_wakeup(dev)) { | ||
814 | disable_irq_wake(bdata->irq); | ||
815 | if (wakeup_key == bdata->button->code) { | ||
816 | unsigned int type = bdata->button->type ?: EV_KEY; | ||
817 | |||
818 | input_event(ddata->input, type, bdata->button->code, 1); | ||
819 | input_event(ddata->input, type, bdata->button->code, 0); | ||
820 | input_sync(ddata->input); | ||
821 | } | ||
840 | } | 822 | } |
841 | } else { | ||
842 | mutex_lock(&input->mutex); | ||
843 | if (input->users) | ||
844 | error = gpio_keys_open(input); | ||
845 | mutex_unlock(&input->mutex); | ||
846 | } | ||
847 | 823 | ||
848 | if (error) | 824 | if (gpio_is_valid(bdata->button->gpio)) |
849 | return error; | 825 | gpio_keys_gpio_report_event(bdata); |
826 | } | ||
827 | input_sync(ddata->input); | ||
850 | 828 | ||
851 | gpio_keys_report_state(ddata); | ||
852 | return 0; | 829 | return 0; |
853 | } | 830 | } |
854 | #endif | 831 | #endif |
@@ -857,12 +834,12 @@ static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume); | |||
857 | 834 | ||
858 | static struct platform_driver gpio_keys_device_driver = { | 835 | static struct platform_driver gpio_keys_device_driver = { |
859 | .probe = gpio_keys_probe, | 836 | .probe = gpio_keys_probe, |
860 | .remove = gpio_keys_remove, | 837 | .remove = __devexit_p(gpio_keys_remove), |
861 | .driver = { | 838 | .driver = { |
862 | .name = "gpio-keys", | 839 | .name = "gpio-keys", |
863 | .owner = THIS_MODULE, | 840 | .owner = THIS_MODULE, |
864 | .pm = &gpio_keys_pm_ops, | 841 | .pm = &gpio_keys_pm_ops, |
865 | .of_match_table = of_match_ptr(gpio_keys_of_match), | 842 | .of_match_table = gpio_keys_of_match, |
866 | } | 843 | } |
867 | }; | 844 | }; |
868 | 845 | ||
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 21147164874..4c17aff2065 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
27 | #include <linux/gpio_keys.h> | 27 | #include <linux/gpio_keys.h> |
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/of_gpio.h> | ||
30 | 28 | ||
31 | #define DRV_NAME "gpio-keys-polled" | 29 | #define DRV_NAME "gpio-keys-polled" |
32 | 30 | ||
@@ -40,7 +38,7 @@ struct gpio_keys_button_data { | |||
40 | struct gpio_keys_polled_dev { | 38 | struct gpio_keys_polled_dev { |
41 | struct input_polled_dev *poll_dev; | 39 | struct input_polled_dev *poll_dev; |
42 | struct device *dev; | 40 | struct device *dev; |
43 | const struct gpio_keys_platform_data *pdata; | 41 | struct gpio_keys_platform_data *pdata; |
44 | struct gpio_keys_button_data data[0]; | 42 | struct gpio_keys_button_data data[0]; |
45 | }; | 43 | }; |
46 | 44 | ||
@@ -69,11 +67,11 @@ static void gpio_keys_polled_check_state(struct input_dev *input, | |||
69 | static void gpio_keys_polled_poll(struct input_polled_dev *dev) | 67 | static void gpio_keys_polled_poll(struct input_polled_dev *dev) |
70 | { | 68 | { |
71 | struct gpio_keys_polled_dev *bdev = dev->private; | 69 | struct gpio_keys_polled_dev *bdev = dev->private; |
72 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | 70 | struct gpio_keys_platform_data *pdata = bdev->pdata; |
73 | struct input_dev *input = dev->input; | 71 | struct input_dev *input = dev->input; |
74 | int i; | 72 | int i; |
75 | 73 | ||
76 | for (i = 0; i < pdata->nbuttons; i++) { | 74 | for (i = 0; i < bdev->pdata->nbuttons; i++) { |
77 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | 75 | struct gpio_keys_button_data *bdata = &bdev->data[i]; |
78 | 76 | ||
79 | if (bdata->count < bdata->threshold) | 77 | if (bdata->count < bdata->threshold) |
@@ -87,7 +85,7 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev) | |||
87 | static void gpio_keys_polled_open(struct input_polled_dev *dev) | 85 | static void gpio_keys_polled_open(struct input_polled_dev *dev) |
88 | { | 86 | { |
89 | struct gpio_keys_polled_dev *bdev = dev->private; | 87 | struct gpio_keys_polled_dev *bdev = dev->private; |
90 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | 88 | struct gpio_keys_platform_data *pdata = bdev->pdata; |
91 | 89 | ||
92 | if (pdata->enable) | 90 | if (pdata->enable) |
93 | pdata->enable(bdev->dev); | 91 | pdata->enable(bdev->dev); |
@@ -96,149 +94,31 @@ static void gpio_keys_polled_open(struct input_polled_dev *dev) | |||
96 | static void gpio_keys_polled_close(struct input_polled_dev *dev) | 94 | static void gpio_keys_polled_close(struct input_polled_dev *dev) |
97 | { | 95 | { |
98 | struct gpio_keys_polled_dev *bdev = dev->private; | 96 | struct gpio_keys_polled_dev *bdev = dev->private; |
99 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | 97 | struct gpio_keys_platform_data *pdata = bdev->pdata; |
100 | 98 | ||
101 | if (pdata->disable) | 99 | if (pdata->disable) |
102 | pdata->disable(bdev->dev); | 100 | pdata->disable(bdev->dev); |
103 | } | 101 | } |
104 | 102 | ||
105 | #ifdef CONFIG_OF | 103 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) |
106 | static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev) | ||
107 | { | ||
108 | struct device_node *node, *pp; | ||
109 | struct gpio_keys_platform_data *pdata; | ||
110 | struct gpio_keys_button *button; | ||
111 | int error; | ||
112 | int nbuttons; | ||
113 | int i; | ||
114 | |||
115 | node = dev->of_node; | ||
116 | if (!node) | ||
117 | return NULL; | ||
118 | |||
119 | nbuttons = of_get_child_count(node); | ||
120 | if (nbuttons == 0) | ||
121 | return NULL; | ||
122 | |||
123 | pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), | ||
124 | GFP_KERNEL); | ||
125 | if (!pdata) { | ||
126 | error = -ENOMEM; | ||
127 | goto err_out; | ||
128 | } | ||
129 | |||
130 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); | ||
131 | pdata->nbuttons = nbuttons; | ||
132 | |||
133 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); | ||
134 | of_property_read_u32(node, "poll-interval", &pdata->poll_interval); | ||
135 | |||
136 | i = 0; | ||
137 | for_each_child_of_node(node, pp) { | ||
138 | int gpio; | ||
139 | enum of_gpio_flags flags; | ||
140 | |||
141 | if (!of_find_property(pp, "gpios", NULL)) { | ||
142 | pdata->nbuttons--; | ||
143 | dev_warn(dev, "Found button without gpios\n"); | ||
144 | continue; | ||
145 | } | ||
146 | |||
147 | gpio = of_get_gpio_flags(pp, 0, &flags); | ||
148 | if (gpio < 0) { | ||
149 | error = gpio; | ||
150 | if (error != -EPROBE_DEFER) | ||
151 | dev_err(dev, | ||
152 | "Failed to get gpio flags, error: %d\n", | ||
153 | error); | ||
154 | goto err_free_pdata; | ||
155 | } | ||
156 | |||
157 | button = &pdata->buttons[i++]; | ||
158 | |||
159 | button->gpio = gpio; | ||
160 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
161 | |||
162 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | ||
163 | dev_err(dev, "Button without keycode: 0x%x\n", | ||
164 | button->gpio); | ||
165 | error = -EINVAL; | ||
166 | goto err_free_pdata; | ||
167 | } | ||
168 | |||
169 | button->desc = of_get_property(pp, "label", NULL); | ||
170 | |||
171 | if (of_property_read_u32(pp, "linux,input-type", &button->type)) | ||
172 | button->type = EV_KEY; | ||
173 | |||
174 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | ||
175 | |||
176 | if (of_property_read_u32(pp, "debounce-interval", | ||
177 | &button->debounce_interval)) | ||
178 | button->debounce_interval = 5; | ||
179 | } | ||
180 | |||
181 | if (pdata->nbuttons == 0) { | ||
182 | error = -EINVAL; | ||
183 | goto err_free_pdata; | ||
184 | } | ||
185 | |||
186 | return pdata; | ||
187 | |||
188 | err_free_pdata: | ||
189 | kfree(pdata); | ||
190 | err_out: | ||
191 | return ERR_PTR(error); | ||
192 | } | ||
193 | |||
194 | static struct of_device_id gpio_keys_polled_of_match[] = { | ||
195 | { .compatible = "gpio-keys-polled", }, | ||
196 | { }, | ||
197 | }; | ||
198 | MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); | ||
199 | |||
200 | #else | ||
201 | |||
202 | static inline struct gpio_keys_platform_data * | ||
203 | gpio_keys_polled_get_devtree_pdata(struct device *dev) | ||
204 | { | ||
205 | return NULL; | ||
206 | } | ||
207 | #endif | ||
208 | |||
209 | static int gpio_keys_polled_probe(struct platform_device *pdev) | ||
210 | { | 104 | { |
105 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
211 | struct device *dev = &pdev->dev; | 106 | struct device *dev = &pdev->dev; |
212 | const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); | ||
213 | struct gpio_keys_polled_dev *bdev; | 107 | struct gpio_keys_polled_dev *bdev; |
214 | struct input_polled_dev *poll_dev; | 108 | struct input_polled_dev *poll_dev; |
215 | struct input_dev *input; | 109 | struct input_dev *input; |
216 | int error; | 110 | int error; |
217 | int i; | 111 | int i; |
218 | 112 | ||
219 | if (!pdata) { | 113 | if (!pdata || !pdata->poll_interval) |
220 | pdata = gpio_keys_polled_get_devtree_pdata(dev); | 114 | return -EINVAL; |
221 | if (IS_ERR(pdata)) | ||
222 | return PTR_ERR(pdata); | ||
223 | if (!pdata) { | ||
224 | dev_err(dev, "missing platform data\n"); | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | if (!pdata->poll_interval) { | ||
230 | dev_err(dev, "missing poll_interval value\n"); | ||
231 | error = -EINVAL; | ||
232 | goto err_free_pdata; | ||
233 | } | ||
234 | 115 | ||
235 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + | 116 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + |
236 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), | 117 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), |
237 | GFP_KERNEL); | 118 | GFP_KERNEL); |
238 | if (!bdev) { | 119 | if (!bdev) { |
239 | dev_err(dev, "no memory for private data\n"); | 120 | dev_err(dev, "no memory for private data\n"); |
240 | error = -ENOMEM; | 121 | return -ENOMEM; |
241 | goto err_free_pdata; | ||
242 | } | 122 | } |
243 | 123 | ||
244 | poll_dev = input_allocate_polled_device(); | 124 | poll_dev = input_allocate_polled_device(); |
@@ -256,6 +136,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
256 | 136 | ||
257 | input = poll_dev->input; | 137 | input = poll_dev->input; |
258 | 138 | ||
139 | input->evbit[0] = BIT(EV_KEY); | ||
259 | input->name = pdev->name; | 140 | input->name = pdev->name; |
260 | input->phys = DRV_NAME"/input0"; | 141 | input->phys = DRV_NAME"/input0"; |
261 | input->dev.parent = &pdev->dev; | 142 | input->dev.parent = &pdev->dev; |
@@ -265,10 +146,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
265 | input->id.product = 0x0001; | 146 | input->id.product = 0x0001; |
266 | input->id.version = 0x0100; | 147 | input->id.version = 0x0100; |
267 | 148 | ||
268 | __set_bit(EV_KEY, input->evbit); | ||
269 | if (pdata->rep) | ||
270 | __set_bit(EV_REP, input->evbit); | ||
271 | |||
272 | for (i = 0; i < pdata->nbuttons; i++) { | 149 | for (i = 0; i < pdata->nbuttons; i++) { |
273 | struct gpio_keys_button *button = &pdata->buttons[i]; | 150 | struct gpio_keys_button *button = &pdata->buttons[i]; |
274 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | 151 | struct gpio_keys_button_data *bdata = &bdev->data[i]; |
@@ -281,14 +158,22 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
281 | goto err_free_gpio; | 158 | goto err_free_gpio; |
282 | } | 159 | } |
283 | 160 | ||
284 | error = gpio_request_one(gpio, GPIOF_IN, | 161 | error = gpio_request(gpio, |
285 | button->desc ?: DRV_NAME); | 162 | button->desc ? button->desc : DRV_NAME); |
286 | if (error) { | 163 | if (error) { |
287 | dev_err(dev, "unable to claim gpio %u, err=%d\n", | 164 | dev_err(dev, "unable to claim gpio %u, err=%d\n", |
288 | gpio, error); | 165 | gpio, error); |
289 | goto err_free_gpio; | 166 | goto err_free_gpio; |
290 | } | 167 | } |
291 | 168 | ||
169 | error = gpio_direction_input(gpio); | ||
170 | if (error) { | ||
171 | dev_err(dev, | ||
172 | "unable to set direction on gpio %u, err=%d\n", | ||
173 | gpio, error); | ||
174 | goto err_free_gpio; | ||
175 | } | ||
176 | |||
292 | bdata->can_sleep = gpio_cansleep(gpio); | 177 | bdata->can_sleep = gpio_cansleep(gpio); |
293 | bdata->last_state = -1; | 178 | bdata->last_state = -1; |
294 | bdata->threshold = DIV_ROUND_UP(button->debounce_interval, | 179 | bdata->threshold = DIV_ROUND_UP(button->debounce_interval, |
@@ -312,7 +197,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
312 | /* report initial state of the buttons */ | 197 | /* report initial state of the buttons */ |
313 | for (i = 0; i < pdata->nbuttons; i++) | 198 | for (i = 0; i < pdata->nbuttons; i++) |
314 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | 199 | gpio_keys_polled_check_state(input, &pdata->buttons[i], |
315 | &bdev->data[i]); | 200 | &bdev->data[i]); |
316 | 201 | ||
317 | return 0; | 202 | return 0; |
318 | 203 | ||
@@ -324,20 +209,15 @@ err_free_gpio: | |||
324 | 209 | ||
325 | err_free_bdev: | 210 | err_free_bdev: |
326 | kfree(bdev); | 211 | kfree(bdev); |
327 | platform_set_drvdata(pdev, NULL); | ||
328 | |||
329 | err_free_pdata: | ||
330 | /* If we have no platform_data, we allocated pdata dynamically. */ | ||
331 | if (!dev_get_platdata(&pdev->dev)) | ||
332 | kfree(pdata); | ||
333 | 212 | ||
213 | platform_set_drvdata(pdev, NULL); | ||
334 | return error; | 214 | return error; |
335 | } | 215 | } |
336 | 216 | ||
337 | static int gpio_keys_polled_remove(struct platform_device *pdev) | 217 | static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) |
338 | { | 218 | { |
339 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); | 219 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); |
340 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | 220 | struct gpio_keys_platform_data *pdata = bdev->pdata; |
341 | int i; | 221 | int i; |
342 | 222 | ||
343 | input_unregister_polled_device(bdev->poll_dev); | 223 | input_unregister_polled_device(bdev->poll_dev); |
@@ -347,13 +227,6 @@ static int gpio_keys_polled_remove(struct platform_device *pdev) | |||
347 | 227 | ||
348 | input_free_polled_device(bdev->poll_dev); | 228 | input_free_polled_device(bdev->poll_dev); |
349 | 229 | ||
350 | /* | ||
351 | * If we had no platform_data, we allocated pdata dynamically and | ||
352 | * must free it here. | ||
353 | */ | ||
354 | if (!dev_get_platdata(&pdev->dev)) | ||
355 | kfree(pdata); | ||
356 | |||
357 | kfree(bdev); | 230 | kfree(bdev); |
358 | platform_set_drvdata(pdev, NULL); | 231 | platform_set_drvdata(pdev, NULL); |
359 | 232 | ||
@@ -362,14 +235,25 @@ static int gpio_keys_polled_remove(struct platform_device *pdev) | |||
362 | 235 | ||
363 | static struct platform_driver gpio_keys_polled_driver = { | 236 | static struct platform_driver gpio_keys_polled_driver = { |
364 | .probe = gpio_keys_polled_probe, | 237 | .probe = gpio_keys_polled_probe, |
365 | .remove = gpio_keys_polled_remove, | 238 | .remove = __devexit_p(gpio_keys_polled_remove), |
366 | .driver = { | 239 | .driver = { |
367 | .name = DRV_NAME, | 240 | .name = DRV_NAME, |
368 | .owner = THIS_MODULE, | 241 | .owner = THIS_MODULE, |
369 | .of_match_table = of_match_ptr(gpio_keys_polled_of_match), | ||
370 | }, | 242 | }, |
371 | }; | 243 | }; |
372 | module_platform_driver(gpio_keys_polled_driver); | 244 | |
245 | static int __init gpio_keys_polled_init(void) | ||
246 | { | ||
247 | return platform_driver_register(&gpio_keys_polled_driver); | ||
248 | } | ||
249 | |||
250 | static void __exit gpio_keys_polled_exit(void) | ||
251 | { | ||
252 | platform_driver_unregister(&gpio_keys_polled_driver); | ||
253 | } | ||
254 | |||
255 | module_init(gpio_keys_polled_init); | ||
256 | module_exit(gpio_keys_polled_exit); | ||
373 | 257 | ||
374 | MODULE_LICENSE("GPL v2"); | 258 | MODULE_LICENSE("GPL v2"); |
375 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | 259 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 589e3c258f3..fed31e0947a 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -583,4 +583,15 @@ static struct serio_driver hil_serio_drv = { | |||
583 | .interrupt = hil_dev_interrupt | 583 | .interrupt = hil_dev_interrupt |
584 | }; | 584 | }; |
585 | 585 | ||
586 | module_serio_driver(hil_serio_drv); | 586 | static int __init hil_dev_init(void) |
587 | { | ||
588 | return serio_register_driver(&hil_serio_drv); | ||
589 | } | ||
590 | |||
591 | static void __exit hil_dev_exit(void) | ||
592 | { | ||
593 | serio_unregister_driver(&hil_serio_drv); | ||
594 | } | ||
595 | |||
596 | module_init(hil_dev_init); | ||
597 | module_exit(hil_dev_exit); | ||
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 198dc07a1be..5f72440b50c 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c | |||
@@ -200,7 +200,7 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) | |||
200 | 200 | ||
201 | 201 | ||
202 | /* initialize HIL */ | 202 | /* initialize HIL */ |
203 | static int hil_keyb_init(void) | 203 | static int __devinit hil_keyb_init(void) |
204 | { | 204 | { |
205 | unsigned char c; | 205 | unsigned char c; |
206 | unsigned int i, kbid; | 206 | unsigned int i, kbid; |
@@ -286,7 +286,7 @@ err1: | |||
286 | return err; | 286 | return err; |
287 | } | 287 | } |
288 | 288 | ||
289 | static void hil_keyb_exit(void) | 289 | static void __devexit hil_keyb_exit(void) |
290 | { | 290 | { |
291 | if (HIL_IRQ) | 291 | if (HIL_IRQ) |
292 | free_irq(HIL_IRQ, hil_dev.dev_id); | 292 | free_irq(HIL_IRQ, hil_dev.dev_id); |
@@ -299,7 +299,7 @@ static void hil_keyb_exit(void) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | #if defined(CONFIG_PARISC) | 301 | #if defined(CONFIG_PARISC) |
302 | static int hil_probe_chip(struct parisc_device *dev) | 302 | static int __devinit hil_probe_chip(struct parisc_device *dev) |
303 | { | 303 | { |
304 | /* Only allow one HIL keyboard */ | 304 | /* Only allow one HIL keyboard */ |
305 | if (hil_dev.dev) | 305 | if (hil_dev.dev) |
@@ -320,7 +320,7 @@ static int hil_probe_chip(struct parisc_device *dev) | |||
320 | return hil_keyb_init(); | 320 | return hil_keyb_init(); |
321 | } | 321 | } |
322 | 322 | ||
323 | static int hil_remove_chip(struct parisc_device *dev) | 323 | static int __devexit hil_remove_chip(struct parisc_device *dev) |
324 | { | 324 | { |
325 | hil_keyb_exit(); | 325 | hil_keyb_exit(); |
326 | 326 | ||
@@ -341,7 +341,7 @@ static struct parisc_driver hil_driver = { | |||
341 | .name = "hil", | 341 | .name = "hil", |
342 | .id_table = hil_tbl, | 342 | .id_table = hil_tbl, |
343 | .probe = hil_probe_chip, | 343 | .probe = hil_probe_chip, |
344 | .remove = hil_remove_chip, | 344 | .remove = __devexit_p(hil_remove_chip), |
345 | }; | 345 | }; |
346 | 346 | ||
347 | static int __init hil_init(void) | 347 | static int __init hil_init(void) |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 6d150e3e1f5..d92c15c39e6 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -358,12 +358,10 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad) | |||
358 | /* Inhibit KDI and KRI interrupts. */ | 358 | /* Inhibit KDI and KRI interrupts. */ |
359 | reg_val = readw(keypad->mmio_base + KPSR); | 359 | reg_val = readw(keypad->mmio_base + KPSR); |
360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | 360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); |
361 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
362 | writew(reg_val, keypad->mmio_base + KPSR); | 361 | writew(reg_val, keypad->mmio_base + KPSR); |
363 | 362 | ||
364 | /* Colums as open drain and disable all rows */ | 363 | /* Colums as open drain and disable all rows */ |
365 | reg_val = (keypad->cols_en_mask & 0xff) << 8; | 364 | writew(0xff00, keypad->mmio_base + KPCR); |
366 | writew(reg_val, keypad->mmio_base + KPCR); | ||
367 | } | 365 | } |
368 | 366 | ||
369 | static void imx_keypad_close(struct input_dev *dev) | 367 | static void imx_keypad_close(struct input_dev *dev) |
@@ -380,24 +378,20 @@ static void imx_keypad_close(struct input_dev *dev) | |||
380 | imx_keypad_inhibit(keypad); | 378 | imx_keypad_inhibit(keypad); |
381 | 379 | ||
382 | /* Disable clock unit */ | 380 | /* Disable clock unit */ |
383 | clk_disable_unprepare(keypad->clk); | 381 | clk_disable(keypad->clk); |
384 | } | 382 | } |
385 | 383 | ||
386 | static int imx_keypad_open(struct input_dev *dev) | 384 | static int imx_keypad_open(struct input_dev *dev) |
387 | { | 385 | { |
388 | struct imx_keypad *keypad = input_get_drvdata(dev); | 386 | struct imx_keypad *keypad = input_get_drvdata(dev); |
389 | int error; | ||
390 | 387 | ||
391 | dev_dbg(&dev->dev, ">%s\n", __func__); | 388 | dev_dbg(&dev->dev, ">%s\n", __func__); |
392 | 389 | ||
393 | /* Enable the kpp clock */ | ||
394 | error = clk_prepare_enable(keypad->clk); | ||
395 | if (error) | ||
396 | return error; | ||
397 | |||
398 | /* We became active from now */ | 390 | /* We became active from now */ |
399 | keypad->enabled = true; | 391 | keypad->enabled = true; |
400 | 392 | ||
393 | /* Enable the kpp clock */ | ||
394 | clk_enable(keypad->clk); | ||
401 | imx_keypad_config(keypad); | 395 | imx_keypad_config(keypad); |
402 | 396 | ||
403 | /* Sanity control, not all the rows must be actived now. */ | 397 | /* Sanity control, not all the rows must be actived now. */ |
@@ -414,7 +408,7 @@ open_err: | |||
414 | return -EIO; | 408 | return -EIO; |
415 | } | 409 | } |
416 | 410 | ||
417 | static int imx_keypad_probe(struct platform_device *pdev) | 411 | static int __devinit imx_keypad_probe(struct platform_device *pdev) |
418 | { | 412 | { |
419 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; | 413 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; |
420 | struct imx_keypad *keypad; | 414 | struct imx_keypad *keypad; |
@@ -473,7 +467,7 @@ static int imx_keypad_probe(struct platform_device *pdev) | |||
473 | goto failed_free_priv; | 467 | goto failed_free_priv; |
474 | } | 468 | } |
475 | 469 | ||
476 | keypad->clk = clk_get(&pdev->dev, NULL); | 470 | keypad->clk = clk_get(&pdev->dev, "kpp"); |
477 | if (IS_ERR(keypad->clk)) { | 471 | if (IS_ERR(keypad->clk)) { |
478 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | 472 | dev_err(&pdev->dev, "failed to get keypad clock\n"); |
479 | error = PTR_ERR(keypad->clk); | 473 | error = PTR_ERR(keypad->clk); |
@@ -487,7 +481,7 @@ static int imx_keypad_probe(struct platform_device *pdev) | |||
487 | } | 481 | } |
488 | 482 | ||
489 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || | 483 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || |
490 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { | 484 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { |
491 | dev_err(&pdev->dev, | 485 | dev_err(&pdev->dev, |
492 | "invalid key data (too many rows or colums)\n"); | 486 | "invalid key data (too many rows or colums)\n"); |
493 | error = -EINVAL; | 487 | error = -EINVAL; |
@@ -502,26 +496,21 @@ static int imx_keypad_probe(struct platform_device *pdev) | |||
502 | input_dev->dev.parent = &pdev->dev; | 496 | input_dev->dev.parent = &pdev->dev; |
503 | input_dev->open = imx_keypad_open; | 497 | input_dev->open = imx_keypad_open; |
504 | input_dev->close = imx_keypad_close; | 498 | input_dev->close = imx_keypad_close; |
499 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
500 | input_dev->keycode = keypad->keycodes; | ||
501 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
502 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
505 | 503 | ||
506 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 504 | matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, |
507 | MAX_MATRIX_KEY_ROWS, | 505 | keypad->keycodes, input_dev->keybit); |
508 | MAX_MATRIX_KEY_COLS, | ||
509 | keypad->keycodes, input_dev); | ||
510 | if (error) { | ||
511 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
512 | goto failed_clock_put; | ||
513 | } | ||
514 | 506 | ||
515 | __set_bit(EV_REP, input_dev->evbit); | ||
516 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 507 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
517 | input_set_drvdata(input_dev, keypad); | 508 | input_set_drvdata(input_dev, keypad); |
518 | 509 | ||
519 | /* Ensure that the keypad will stay dormant until opened */ | 510 | /* Ensure that the keypad will stay dormant until opened */ |
520 | clk_prepare_enable(keypad->clk); | ||
521 | imx_keypad_inhibit(keypad); | 511 | imx_keypad_inhibit(keypad); |
522 | clk_disable_unprepare(keypad->clk); | ||
523 | 512 | ||
524 | error = request_irq(irq, imx_keypad_irq_handler, 0, | 513 | error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED, |
525 | pdev->name, keypad); | 514 | pdev->name, keypad); |
526 | if (error) { | 515 | if (error) { |
527 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 516 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
@@ -555,7 +544,7 @@ failed_rel_mem: | |||
555 | return error; | 544 | return error; |
556 | } | 545 | } |
557 | 546 | ||
558 | static int imx_keypad_remove(struct platform_device *pdev) | 547 | static int __devexit imx_keypad_remove(struct platform_device *pdev) |
559 | { | 548 | { |
560 | struct imx_keypad *keypad = platform_get_drvdata(pdev); | 549 | struct imx_keypad *keypad = platform_get_drvdata(pdev); |
561 | struct resource *res; | 550 | struct resource *res; |
@@ -578,64 +567,27 @@ static int imx_keypad_remove(struct platform_device *pdev) | |||
578 | return 0; | 567 | return 0; |
579 | } | 568 | } |
580 | 569 | ||
581 | #ifdef CONFIG_PM_SLEEP | ||
582 | static int imx_kbd_suspend(struct device *dev) | ||
583 | { | ||
584 | struct platform_device *pdev = to_platform_device(dev); | ||
585 | struct imx_keypad *kbd = platform_get_drvdata(pdev); | ||
586 | struct input_dev *input_dev = kbd->input_dev; | ||
587 | |||
588 | /* imx kbd can wake up system even clock is disabled */ | ||
589 | mutex_lock(&input_dev->mutex); | ||
590 | |||
591 | if (input_dev->users) | ||
592 | clk_disable_unprepare(kbd->clk); | ||
593 | |||
594 | mutex_unlock(&input_dev->mutex); | ||
595 | |||
596 | if (device_may_wakeup(&pdev->dev)) | ||
597 | enable_irq_wake(kbd->irq); | ||
598 | |||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | static int imx_kbd_resume(struct device *dev) | ||
603 | { | ||
604 | struct platform_device *pdev = to_platform_device(dev); | ||
605 | struct imx_keypad *kbd = platform_get_drvdata(pdev); | ||
606 | struct input_dev *input_dev = kbd->input_dev; | ||
607 | int ret = 0; | ||
608 | |||
609 | if (device_may_wakeup(&pdev->dev)) | ||
610 | disable_irq_wake(kbd->irq); | ||
611 | |||
612 | mutex_lock(&input_dev->mutex); | ||
613 | |||
614 | if (input_dev->users) { | ||
615 | ret = clk_prepare_enable(kbd->clk); | ||
616 | if (ret) | ||
617 | goto err_clk; | ||
618 | } | ||
619 | |||
620 | err_clk: | ||
621 | mutex_unlock(&input_dev->mutex); | ||
622 | |||
623 | return ret; | ||
624 | } | ||
625 | #endif | ||
626 | |||
627 | static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume); | ||
628 | |||
629 | static struct platform_driver imx_keypad_driver = { | 570 | static struct platform_driver imx_keypad_driver = { |
630 | .driver = { | 571 | .driver = { |
631 | .name = "imx-keypad", | 572 | .name = "imx-keypad", |
632 | .owner = THIS_MODULE, | 573 | .owner = THIS_MODULE, |
633 | .pm = &imx_kbd_pm_ops, | ||
634 | }, | 574 | }, |
635 | .probe = imx_keypad_probe, | 575 | .probe = imx_keypad_probe, |
636 | .remove = imx_keypad_remove, | 576 | .remove = __devexit_p(imx_keypad_remove), |
637 | }; | 577 | }; |
638 | module_platform_driver(imx_keypad_driver); | 578 | |
579 | static int __init imx_keypad_init(void) | ||
580 | { | ||
581 | return platform_driver_register(&imx_keypad_driver); | ||
582 | } | ||
583 | |||
584 | static void __exit imx_keypad_exit(void) | ||
585 | { | ||
586 | platform_driver_unregister(&imx_keypad_driver); | ||
587 | } | ||
588 | |||
589 | module_init(imx_keypad_init); | ||
590 | module_exit(imx_keypad_exit); | ||
639 | 591 | ||
640 | MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); | 592 | MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); |
641 | MODULE_DESCRIPTION("IMX Keypad Port Driver"); | 593 | MODULE_DESCRIPTION("IMX Keypad Port Driver"); |
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 74e75a6e8de..7197c569874 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -179,7 +179,7 @@ static void jornadakbd680_poll(struct input_polled_dev *dev) | |||
179 | memcpy(jornadakbd->old_scan, jornadakbd->new_scan, JORNADA_SCAN_SIZE); | 179 | memcpy(jornadakbd->old_scan, jornadakbd->new_scan, JORNADA_SCAN_SIZE); |
180 | } | 180 | } |
181 | 181 | ||
182 | static int jornada680kbd_probe(struct platform_device *pdev) | 182 | static int __devinit jornada680kbd_probe(struct platform_device *pdev) |
183 | { | 183 | { |
184 | struct jornadakbd *jornadakbd; | 184 | struct jornadakbd *jornadakbd; |
185 | struct input_polled_dev *poll_dev; | 185 | struct input_polled_dev *poll_dev; |
@@ -240,7 +240,7 @@ static int jornada680kbd_probe(struct platform_device *pdev) | |||
240 | 240 | ||
241 | } | 241 | } |
242 | 242 | ||
243 | static int jornada680kbd_remove(struct platform_device *pdev) | 243 | static int __devexit jornada680kbd_remove(struct platform_device *pdev) |
244 | { | 244 | { |
245 | struct jornadakbd *jornadakbd = platform_get_drvdata(pdev); | 245 | struct jornadakbd *jornadakbd = platform_get_drvdata(pdev); |
246 | 246 | ||
@@ -258,9 +258,21 @@ static struct platform_driver jornada680kbd_driver = { | |||
258 | .owner = THIS_MODULE, | 258 | .owner = THIS_MODULE, |
259 | }, | 259 | }, |
260 | .probe = jornada680kbd_probe, | 260 | .probe = jornada680kbd_probe, |
261 | .remove = jornada680kbd_remove, | 261 | .remove = __devexit_p(jornada680kbd_remove), |
262 | }; | 262 | }; |
263 | module_platform_driver(jornada680kbd_driver); | 263 | |
264 | static int __init jornada680kbd_init(void) | ||
265 | { | ||
266 | return platform_driver_register(&jornada680kbd_driver); | ||
267 | } | ||
268 | |||
269 | static void __exit jornada680kbd_exit(void) | ||
270 | { | ||
271 | platform_driver_unregister(&jornada680kbd_driver); | ||
272 | } | ||
273 | |||
274 | module_init(jornada680kbd_init); | ||
275 | module_exit(jornada680kbd_exit); | ||
264 | 276 | ||
265 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); | 277 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); |
266 | MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); | 278 | MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); |
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index 5ceef636df2..2cd3e1d56ea 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include <mach/jornada720.h> | 28 | #include <mach/jornada720.h> |
29 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include <mach/irqs.h> | ||
31 | 30 | ||
32 | MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>"); | 31 | MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>"); |
33 | MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver"); | 32 | MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver"); |
@@ -94,7 +93,7 @@ static irqreturn_t jornada720_kbd_interrupt(int irq, void *dev_id) | |||
94 | return IRQ_HANDLED; | 93 | return IRQ_HANDLED; |
95 | }; | 94 | }; |
96 | 95 | ||
97 | static int jornada720_kbd_probe(struct platform_device *pdev) | 96 | static int __devinit jornada720_kbd_probe(struct platform_device *pdev) |
98 | { | 97 | { |
99 | struct jornadakbd *jornadakbd; | 98 | struct jornadakbd *jornadakbd; |
100 | struct input_dev *input_dev; | 99 | struct input_dev *input_dev; |
@@ -130,7 +129,7 @@ static int jornada720_kbd_probe(struct platform_device *pdev) | |||
130 | 129 | ||
131 | err = request_irq(IRQ_GPIO0, | 130 | err = request_irq(IRQ_GPIO0, |
132 | jornada720_kbd_interrupt, | 131 | jornada720_kbd_interrupt, |
133 | IRQF_TRIGGER_FALLING, | 132 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, |
134 | "jornadakbd", pdev); | 133 | "jornadakbd", pdev); |
135 | if (err) { | 134 | if (err) { |
136 | printk(KERN_INFO "jornadakbd720_kbd: Unable to grab IRQ\n"); | 135 | printk(KERN_INFO "jornadakbd720_kbd: Unable to grab IRQ\n"); |
@@ -152,7 +151,7 @@ static int jornada720_kbd_probe(struct platform_device *pdev) | |||
152 | return err; | 151 | return err; |
153 | }; | 152 | }; |
154 | 153 | ||
155 | static int jornada720_kbd_remove(struct platform_device *pdev) | 154 | static int __devexit jornada720_kbd_remove(struct platform_device *pdev) |
156 | { | 155 | { |
157 | struct jornadakbd *jornadakbd = platform_get_drvdata(pdev); | 156 | struct jornadakbd *jornadakbd = platform_get_drvdata(pdev); |
158 | 157 | ||
@@ -173,6 +172,18 @@ static struct platform_driver jornada720_kbd_driver = { | |||
173 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
174 | }, | 173 | }, |
175 | .probe = jornada720_kbd_probe, | 174 | .probe = jornada720_kbd_probe, |
176 | .remove = jornada720_kbd_remove, | 175 | .remove = __devexit_p(jornada720_kbd_remove), |
177 | }; | 176 | }; |
178 | module_platform_driver(jornada720_kbd_driver); | 177 | |
178 | static int __init jornada720_kbd_init(void) | ||
179 | { | ||
180 | return platform_driver_register(&jornada720_kbd_driver); | ||
181 | } | ||
182 | |||
183 | static void __exit jornada720_kbd_exit(void) | ||
184 | { | ||
185 | platform_driver_unregister(&jornada720_kbd_driver); | ||
186 | } | ||
187 | |||
188 | module_init(jornada720_kbd_init); | ||
189 | module_exit(jornada720_kbd_exit); | ||
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index fc0a63c2f27..fa9bb6d235e 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -731,4 +731,19 @@ static struct serio_driver lkkbd_drv = { | |||
731 | .interrupt = lkkbd_interrupt, | 731 | .interrupt = lkkbd_interrupt, |
732 | }; | 732 | }; |
733 | 733 | ||
734 | module_serio_driver(lkkbd_drv); | 734 | /* |
735 | * The functions for insering/removing us as a module. | ||
736 | */ | ||
737 | static int __init lkkbd_init(void) | ||
738 | { | ||
739 | return serio_register_driver(&lkkbd_drv); | ||
740 | } | ||
741 | |||
742 | static void __exit lkkbd_exit(void) | ||
743 | { | ||
744 | serio_unregister_driver(&lkkbd_drv); | ||
745 | } | ||
746 | |||
747 | module_init(lkkbd_init); | ||
748 | module_exit(lkkbd_exit); | ||
749 | |||
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 93c81266213..756348a7f93 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
@@ -545,12 +545,13 @@ static ssize_t lm8323_pwm_store_time(struct device *dev, | |||
545 | { | 545 | { |
546 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 546 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
547 | struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); | 547 | struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); |
548 | int ret, time; | 548 | int ret; |
549 | unsigned long time; | ||
549 | 550 | ||
550 | ret = kstrtoint(buf, 10, &time); | 551 | ret = strict_strtoul(buf, 10, &time); |
551 | /* Numbers only, please. */ | 552 | /* Numbers only, please. */ |
552 | if (ret) | 553 | if (ret) |
553 | return ret; | 554 | return -EINVAL; |
554 | 555 | ||
555 | pwm->fade_time = time; | 556 | pwm->fade_time = time; |
556 | 557 | ||
@@ -612,9 +613,9 @@ static ssize_t lm8323_set_disable(struct device *dev, | |||
612 | { | 613 | { |
613 | struct lm8323_chip *lm = dev_get_drvdata(dev); | 614 | struct lm8323_chip *lm = dev_get_drvdata(dev); |
614 | int ret; | 615 | int ret; |
615 | unsigned int i; | 616 | unsigned long i; |
616 | 617 | ||
617 | ret = kstrtouint(buf, 10, &i); | 618 | ret = strict_strtoul(buf, 10, &i); |
618 | 619 | ||
619 | mutex_lock(&lm->lock); | 620 | mutex_lock(&lm->lock); |
620 | lm->kp_enabled = !i; | 621 | lm->kp_enabled = !i; |
@@ -624,7 +625,7 @@ static ssize_t lm8323_set_disable(struct device *dev, | |||
624 | } | 625 | } |
625 | static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable); | 626 | static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable); |
626 | 627 | ||
627 | static int lm8323_probe(struct i2c_client *client, | 628 | static int __devinit lm8323_probe(struct i2c_client *client, |
628 | const struct i2c_device_id *id) | 629 | const struct i2c_device_id *id) |
629 | { | 630 | { |
630 | struct lm8323_platform_data *pdata = client->dev.platform_data; | 631 | struct lm8323_platform_data *pdata = client->dev.platform_data; |
@@ -764,7 +765,7 @@ fail1: | |||
764 | return err; | 765 | return err; |
765 | } | 766 | } |
766 | 767 | ||
767 | static int lm8323_remove(struct i2c_client *client) | 768 | static int __devexit lm8323_remove(struct i2c_client *client) |
768 | { | 769 | { |
769 | struct lm8323_chip *lm = i2c_get_clientdata(client); | 770 | struct lm8323_chip *lm = i2c_get_clientdata(client); |
770 | int i; | 771 | int i; |
@@ -787,7 +788,7 @@ static int lm8323_remove(struct i2c_client *client) | |||
787 | return 0; | 788 | return 0; |
788 | } | 789 | } |
789 | 790 | ||
790 | #ifdef CONFIG_PM_SLEEP | 791 | #ifdef CONFIG_PM |
791 | /* | 792 | /* |
792 | * We don't need to explicitly suspend the chip, as it already switches off | 793 | * We don't need to explicitly suspend the chip, as it already switches off |
793 | * when there's no activity. | 794 | * when there's no activity. |
@@ -846,12 +847,22 @@ static struct i2c_driver lm8323_i2c_driver = { | |||
846 | .pm = &lm8323_pm_ops, | 847 | .pm = &lm8323_pm_ops, |
847 | }, | 848 | }, |
848 | .probe = lm8323_probe, | 849 | .probe = lm8323_probe, |
849 | .remove = lm8323_remove, | 850 | .remove = __devexit_p(lm8323_remove), |
850 | .id_table = lm8323_id, | 851 | .id_table = lm8323_id, |
851 | }; | 852 | }; |
852 | MODULE_DEVICE_TABLE(i2c, lm8323_id); | 853 | MODULE_DEVICE_TABLE(i2c, lm8323_id); |
853 | 854 | ||
854 | module_i2c_driver(lm8323_i2c_driver); | 855 | static int __init lm8323_init(void) |
856 | { | ||
857 | return i2c_add_driver(&lm8323_i2c_driver); | ||
858 | } | ||
859 | module_init(lm8323_init); | ||
860 | |||
861 | static void __exit lm8323_exit(void) | ||
862 | { | ||
863 | i2c_del_driver(&lm8323_i2c_driver); | ||
864 | } | ||
865 | module_exit(lm8323_exit); | ||
855 | 866 | ||
856 | MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>"); | 867 | MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>"); |
857 | MODULE_AUTHOR("Daniel Stone"); | 868 | MODULE_AUTHOR("Daniel Stone"); |
diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c deleted file mode 100644 index 5a8ca35dc9a..00000000000 --- a/drivers/input/keyboard/lm8333.c +++ /dev/null | |||
@@ -1,235 +0,0 @@ | |||
1 | /* | ||
2 | * LM8333 keypad driver | ||
3 | * Copyright (C) 2012 Wolfram Sang, Pengutronix <w.sang@pengutronix.de> | ||
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 as published by | ||
7 | * the Free Software Foundation; either version 2 of the License. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/input/matrix_keypad.h> | ||
16 | #include <linux/input/lm8333.h> | ||
17 | |||
18 | #define LM8333_FIFO_READ 0x20 | ||
19 | #define LM8333_DEBOUNCE 0x22 | ||
20 | #define LM8333_READ_INT 0xD0 | ||
21 | #define LM8333_ACTIVE 0xE4 | ||
22 | #define LM8333_READ_ERROR 0xF0 | ||
23 | |||
24 | #define LM8333_KEYPAD_IRQ (1 << 0) | ||
25 | #define LM8333_ERROR_IRQ (1 << 3) | ||
26 | |||
27 | #define LM8333_ERROR_KEYOVR 0x04 | ||
28 | #define LM8333_ERROR_FIFOOVR 0x40 | ||
29 | |||
30 | #define LM8333_FIFO_TRANSFER_SIZE 16 | ||
31 | |||
32 | #define LM8333_NUM_ROWS 8 | ||
33 | #define LM8333_NUM_COLS 16 | ||
34 | #define LM8333_ROW_SHIFT 4 | ||
35 | |||
36 | struct lm8333 { | ||
37 | struct i2c_client *client; | ||
38 | struct input_dev *input; | ||
39 | unsigned short keycodes[LM8333_NUM_ROWS << LM8333_ROW_SHIFT]; | ||
40 | }; | ||
41 | |||
42 | /* The accessors try twice because the first access may be needed for wakeup */ | ||
43 | #define LM8333_READ_RETRIES 2 | ||
44 | |||
45 | int lm8333_read8(struct lm8333 *lm8333, u8 cmd) | ||
46 | { | ||
47 | int retries = 0, ret; | ||
48 | |||
49 | do { | ||
50 | ret = i2c_smbus_read_byte_data(lm8333->client, cmd); | ||
51 | } while (ret < 0 && retries++ < LM8333_READ_RETRIES); | ||
52 | |||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | int lm8333_write8(struct lm8333 *lm8333, u8 cmd, u8 val) | ||
57 | { | ||
58 | int retries = 0, ret; | ||
59 | |||
60 | do { | ||
61 | ret = i2c_smbus_write_byte_data(lm8333->client, cmd, val); | ||
62 | } while (ret < 0 && retries++ < LM8333_READ_RETRIES); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | int lm8333_read_block(struct lm8333 *lm8333, u8 cmd, u8 len, u8 *buf) | ||
68 | { | ||
69 | int retries = 0, ret; | ||
70 | |||
71 | do { | ||
72 | ret = i2c_smbus_read_i2c_block_data(lm8333->client, | ||
73 | cmd, len, buf); | ||
74 | } while (ret < 0 && retries++ < LM8333_READ_RETRIES); | ||
75 | |||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | static void lm8333_key_handler(struct lm8333 *lm8333) | ||
80 | { | ||
81 | struct input_dev *input = lm8333->input; | ||
82 | u8 keys[LM8333_FIFO_TRANSFER_SIZE]; | ||
83 | u8 code, pressed; | ||
84 | int i, ret; | ||
85 | |||
86 | ret = lm8333_read_block(lm8333, LM8333_FIFO_READ, | ||
87 | LM8333_FIFO_TRANSFER_SIZE, keys); | ||
88 | if (ret != LM8333_FIFO_TRANSFER_SIZE) { | ||
89 | dev_err(&lm8333->client->dev, | ||
90 | "Error %d while reading FIFO\n", ret); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | for (i = 0; i < LM8333_FIFO_TRANSFER_SIZE && keys[i]; i++) { | ||
95 | pressed = keys[i] & 0x80; | ||
96 | code = keys[i] & 0x7f; | ||
97 | |||
98 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
99 | input_report_key(input, lm8333->keycodes[code], pressed); | ||
100 | } | ||
101 | |||
102 | input_sync(input); | ||
103 | } | ||
104 | |||
105 | static irqreturn_t lm8333_irq_thread(int irq, void *data) | ||
106 | { | ||
107 | struct lm8333 *lm8333 = data; | ||
108 | u8 status = lm8333_read8(lm8333, LM8333_READ_INT); | ||
109 | |||
110 | if (!status) | ||
111 | return IRQ_NONE; | ||
112 | |||
113 | if (status & LM8333_ERROR_IRQ) { | ||
114 | u8 err = lm8333_read8(lm8333, LM8333_READ_ERROR); | ||
115 | |||
116 | if (err & (LM8333_ERROR_KEYOVR | LM8333_ERROR_FIFOOVR)) { | ||
117 | u8 dummy[LM8333_FIFO_TRANSFER_SIZE]; | ||
118 | |||
119 | lm8333_read_block(lm8333, LM8333_FIFO_READ, | ||
120 | LM8333_FIFO_TRANSFER_SIZE, dummy); | ||
121 | } | ||
122 | dev_err(&lm8333->client->dev, "Got error %02x\n", err); | ||
123 | } | ||
124 | |||
125 | if (status & LM8333_KEYPAD_IRQ) | ||
126 | lm8333_key_handler(lm8333); | ||
127 | |||
128 | return IRQ_HANDLED; | ||
129 | } | ||
130 | |||
131 | static int lm8333_probe(struct i2c_client *client, | ||
132 | const struct i2c_device_id *id) | ||
133 | { | ||
134 | const struct lm8333_platform_data *pdata = client->dev.platform_data; | ||
135 | struct lm8333 *lm8333; | ||
136 | struct input_dev *input; | ||
137 | int err, active_time; | ||
138 | |||
139 | if (!pdata) | ||
140 | return -EINVAL; | ||
141 | |||
142 | active_time = pdata->active_time ?: 500; | ||
143 | if (active_time / 3 <= pdata->debounce_time / 3) { | ||
144 | dev_err(&client->dev, "Active time not big enough!\n"); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | lm8333 = kzalloc(sizeof(*lm8333), GFP_KERNEL); | ||
149 | input = input_allocate_device(); | ||
150 | if (!lm8333 || !input) { | ||
151 | err = -ENOMEM; | ||
152 | goto free_mem; | ||
153 | } | ||
154 | |||
155 | lm8333->client = client; | ||
156 | lm8333->input = input; | ||
157 | |||
158 | input->name = client->name; | ||
159 | input->dev.parent = &client->dev; | ||
160 | input->id.bustype = BUS_I2C; | ||
161 | |||
162 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
163 | |||
164 | err = matrix_keypad_build_keymap(pdata->matrix_data, NULL, | ||
165 | LM8333_NUM_ROWS, LM8333_NUM_COLS, | ||
166 | lm8333->keycodes, input); | ||
167 | if (err) | ||
168 | goto free_mem; | ||
169 | |||
170 | if (pdata->debounce_time) { | ||
171 | err = lm8333_write8(lm8333, LM8333_DEBOUNCE, | ||
172 | pdata->debounce_time / 3); | ||
173 | if (err) | ||
174 | dev_warn(&client->dev, "Unable to set debounce time\n"); | ||
175 | } | ||
176 | |||
177 | if (pdata->active_time) { | ||
178 | err = lm8333_write8(lm8333, LM8333_ACTIVE, | ||
179 | pdata->active_time / 3); | ||
180 | if (err) | ||
181 | dev_warn(&client->dev, "Unable to set active time\n"); | ||
182 | } | ||
183 | |||
184 | err = request_threaded_irq(client->irq, NULL, lm8333_irq_thread, | ||
185 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
186 | "lm8333", lm8333); | ||
187 | if (err) | ||
188 | goto free_mem; | ||
189 | |||
190 | err = input_register_device(input); | ||
191 | if (err) | ||
192 | goto free_irq; | ||
193 | |||
194 | i2c_set_clientdata(client, lm8333); | ||
195 | return 0; | ||
196 | |||
197 | free_irq: | ||
198 | free_irq(client->irq, lm8333); | ||
199 | free_mem: | ||
200 | input_free_device(input); | ||
201 | kfree(lm8333); | ||
202 | return err; | ||
203 | } | ||
204 | |||
205 | static int lm8333_remove(struct i2c_client *client) | ||
206 | { | ||
207 | struct lm8333 *lm8333 = i2c_get_clientdata(client); | ||
208 | |||
209 | free_irq(client->irq, lm8333); | ||
210 | input_unregister_device(lm8333->input); | ||
211 | kfree(lm8333); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static const struct i2c_device_id lm8333_id[] = { | ||
217 | { "lm8333", 0 }, | ||
218 | { } | ||
219 | }; | ||
220 | MODULE_DEVICE_TABLE(i2c, lm8333_id); | ||
221 | |||
222 | static struct i2c_driver lm8333_driver = { | ||
223 | .driver = { | ||
224 | .name = "lm8333", | ||
225 | .owner = THIS_MODULE, | ||
226 | }, | ||
227 | .probe = lm8333_probe, | ||
228 | .remove = lm8333_remove, | ||
229 | .id_table = lm8333_id, | ||
230 | }; | ||
231 | module_i2c_driver(lm8333_driver); | ||
232 | |||
233 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); | ||
234 | MODULE_DESCRIPTION("LM8333 keyboard driver"); | ||
235 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index c94d610b9d7..b1ab29861e1 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -46,7 +46,7 @@ MODULE_LICENSE("GPL"); | |||
46 | #define KEY_CENTER KEY_F15 | 46 | #define KEY_CENTER KEY_F15 |
47 | 47 | ||
48 | static const unsigned char | 48 | static const unsigned char |
49 | locomokbd_keycode[LOCOMOKBD_NUMKEYS] = { | 49 | locomokbd_keycode[LOCOMOKBD_NUMKEYS] __devinitconst = { |
50 | 0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0, /* 0 - 9 */ | 50 | 0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0, /* 0 - 9 */ |
51 | 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT, /* 10 - 19 */ | 51 | 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT, /* 10 - 19 */ |
52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 29 */ | 52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 29 */ |
@@ -236,7 +236,7 @@ static void locomokbd_close(struct input_dev *dev) | |||
236 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | 236 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); |
237 | } | 237 | } |
238 | 238 | ||
239 | static int locomokbd_probe(struct locomo_dev *dev) | 239 | static int __devinit locomokbd_probe(struct locomo_dev *dev) |
240 | { | 240 | { |
241 | struct locomokbd *locomokbd; | 241 | struct locomokbd *locomokbd; |
242 | struct input_dev *input_dev; | 242 | struct input_dev *input_dev; |
@@ -321,7 +321,7 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
321 | return err; | 321 | return err; |
322 | } | 322 | } |
323 | 323 | ||
324 | static int locomokbd_remove(struct locomo_dev *dev) | 324 | static int __devexit locomokbd_remove(struct locomo_dev *dev) |
325 | { | 325 | { |
326 | struct locomokbd *locomokbd = locomo_get_drvdata(dev); | 326 | struct locomokbd *locomokbd = locomo_get_drvdata(dev); |
327 | 327 | ||
@@ -345,7 +345,7 @@ static struct locomo_driver keyboard_driver = { | |||
345 | }, | 345 | }, |
346 | .devid = LOCOMO_DEVID_KEYBOARD, | 346 | .devid = LOCOMO_DEVID_KEYBOARD, |
347 | .probe = locomokbd_probe, | 347 | .probe = locomokbd_probe, |
348 | .remove = locomokbd_remove, | 348 | .remove = __devexit_p(locomokbd_remove), |
349 | }; | 349 | }; |
350 | 350 | ||
351 | static int __init locomokbd_init(void) | 351 | static int __init locomokbd_init(void) |
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c deleted file mode 100644 index 1b8add6cfb9..00000000000 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ /dev/null | |||
@@ -1,394 +0,0 @@ | |||
1 | /* | ||
2 | * NXP LPC32xx SoC Key Scan Interface | ||
3 | * | ||
4 | * Authors: | ||
5 | * Kevin Wells <kevin.wells@nxp.com> | ||
6 | * Roland Stigge <stigge@antcom.de> | ||
7 | * | ||
8 | * Copyright (C) 2010 NXP Semiconductors | ||
9 | * Copyright (C) 2012 Roland Stigge | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * | ||
22 | * This controller supports square key matrices from 1x1 up to 8x8 | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/pm.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/clk.h> | ||
33 | #include <linux/io.h> | ||
34 | #include <linux/of.h> | ||
35 | #include <linux/input/matrix_keypad.h> | ||
36 | |||
37 | #define DRV_NAME "lpc32xx_keys" | ||
38 | |||
39 | /* | ||
40 | * Key scanner register offsets | ||
41 | */ | ||
42 | #define LPC32XX_KS_DEB(x) ((x) + 0x00) | ||
43 | #define LPC32XX_KS_STATE_COND(x) ((x) + 0x04) | ||
44 | #define LPC32XX_KS_IRQ(x) ((x) + 0x08) | ||
45 | #define LPC32XX_KS_SCAN_CTL(x) ((x) + 0x0C) | ||
46 | #define LPC32XX_KS_FAST_TST(x) ((x) + 0x10) | ||
47 | #define LPC32XX_KS_MATRIX_DIM(x) ((x) + 0x14) /* 1..8 */ | ||
48 | #define LPC32XX_KS_DATA(x, y) ((x) + 0x40 + ((y) << 2)) | ||
49 | |||
50 | #define LPC32XX_KSCAN_DEB_NUM_DEB_PASS(n) ((n) & 0xFF) | ||
51 | |||
52 | #define LPC32XX_KSCAN_SCOND_IN_IDLE 0x0 | ||
53 | #define LPC32XX_KSCAN_SCOND_IN_SCANONCE 0x1 | ||
54 | #define LPC32XX_KSCAN_SCOND_IN_IRQGEN 0x2 | ||
55 | #define LPC32XX_KSCAN_SCOND_IN_SCAN_MATRIX 0x3 | ||
56 | |||
57 | #define LPC32XX_KSCAN_IRQ_PENDING_CLR 0x1 | ||
58 | |||
59 | #define LPC32XX_KSCAN_SCTRL_SCAN_DELAY(n) ((n) & 0xFF) | ||
60 | |||
61 | #define LPC32XX_KSCAN_FTST_FORCESCANONCE 0x1 | ||
62 | #define LPC32XX_KSCAN_FTST_USE32K_CLK 0x2 | ||
63 | |||
64 | #define LPC32XX_KSCAN_MSEL_SELECT(n) ((n) & 0xF) | ||
65 | |||
66 | struct lpc32xx_kscan_drv { | ||
67 | struct input_dev *input; | ||
68 | struct clk *clk; | ||
69 | struct resource *iores; | ||
70 | void __iomem *kscan_base; | ||
71 | unsigned int irq; | ||
72 | |||
73 | u32 matrix_sz; /* Size of matrix in XxY, ie. 3 = 3x3 */ | ||
74 | u32 deb_clks; /* Debounce clocks (based on 32KHz clock) */ | ||
75 | u32 scan_delay; /* Scan delay (based on 32KHz clock) */ | ||
76 | |||
77 | unsigned short *keymap; /* Pointer to key map for the scan matrix */ | ||
78 | unsigned int row_shift; | ||
79 | |||
80 | u8 lastkeystates[8]; | ||
81 | }; | ||
82 | |||
83 | static void lpc32xx_mod_states(struct lpc32xx_kscan_drv *kscandat, int col) | ||
84 | { | ||
85 | struct input_dev *input = kscandat->input; | ||
86 | unsigned row, changed, scancode, keycode; | ||
87 | u8 key; | ||
88 | |||
89 | key = readl(LPC32XX_KS_DATA(kscandat->kscan_base, col)); | ||
90 | changed = key ^ kscandat->lastkeystates[col]; | ||
91 | kscandat->lastkeystates[col] = key; | ||
92 | |||
93 | for (row = 0; changed; row++, changed >>= 1) { | ||
94 | if (changed & 1) { | ||
95 | /* Key state changed, signal an event */ | ||
96 | scancode = MATRIX_SCAN_CODE(row, col, | ||
97 | kscandat->row_shift); | ||
98 | keycode = kscandat->keymap[scancode]; | ||
99 | input_event(input, EV_MSC, MSC_SCAN, scancode); | ||
100 | input_report_key(input, keycode, key & (1 << row)); | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static irqreturn_t lpc32xx_kscan_irq(int irq, void *dev_id) | ||
106 | { | ||
107 | struct lpc32xx_kscan_drv *kscandat = dev_id; | ||
108 | int i; | ||
109 | |||
110 | for (i = 0; i < kscandat->matrix_sz; i++) | ||
111 | lpc32xx_mod_states(kscandat, i); | ||
112 | |||
113 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); | ||
114 | |||
115 | input_sync(kscandat->input); | ||
116 | |||
117 | return IRQ_HANDLED; | ||
118 | } | ||
119 | |||
120 | static int lpc32xx_kscan_open(struct input_dev *dev) | ||
121 | { | ||
122 | struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev); | ||
123 | int error; | ||
124 | |||
125 | error = clk_prepare_enable(kscandat->clk); | ||
126 | if (error) | ||
127 | return error; | ||
128 | |||
129 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static void lpc32xx_kscan_close(struct input_dev *dev) | ||
135 | { | ||
136 | struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev); | ||
137 | |||
138 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); | ||
139 | clk_disable_unprepare(kscandat->clk); | ||
140 | } | ||
141 | |||
142 | static int lpc32xx_parse_dt(struct device *dev, | ||
143 | struct lpc32xx_kscan_drv *kscandat) | ||
144 | { | ||
145 | struct device_node *np = dev->of_node; | ||
146 | u32 rows = 0, columns = 0; | ||
147 | |||
148 | of_property_read_u32(np, "keypad,num-rows", &rows); | ||
149 | of_property_read_u32(np, "keypad,num-columns", &columns); | ||
150 | if (!rows || rows != columns) { | ||
151 | dev_err(dev, | ||
152 | "rows and columns must be specified and be equal!\n"); | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | |||
156 | kscandat->matrix_sz = rows; | ||
157 | kscandat->row_shift = get_count_order(columns); | ||
158 | |||
159 | of_property_read_u32(np, "nxp,debounce-delay-ms", &kscandat->deb_clks); | ||
160 | of_property_read_u32(np, "nxp,scan-delay-ms", &kscandat->scan_delay); | ||
161 | if (!kscandat->deb_clks || !kscandat->scan_delay) { | ||
162 | dev_err(dev, "debounce or scan delay not specified\n"); | ||
163 | return -EINVAL; | ||
164 | } | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int lpc32xx_kscan_probe(struct platform_device *pdev) | ||
170 | { | ||
171 | struct lpc32xx_kscan_drv *kscandat; | ||
172 | struct input_dev *input; | ||
173 | struct resource *res; | ||
174 | size_t keymap_size; | ||
175 | int error; | ||
176 | int irq; | ||
177 | |||
178 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
179 | if (!res) { | ||
180 | dev_err(&pdev->dev, "failed to get platform I/O memory\n"); | ||
181 | return -EINVAL; | ||
182 | } | ||
183 | |||
184 | irq = platform_get_irq(pdev, 0); | ||
185 | if (irq < 0 || irq >= NR_IRQS) { | ||
186 | dev_err(&pdev->dev, "failed to get platform irq\n"); | ||
187 | return -EINVAL; | ||
188 | } | ||
189 | |||
190 | kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL); | ||
191 | if (!kscandat) { | ||
192 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
193 | return -ENOMEM; | ||
194 | } | ||
195 | |||
196 | error = lpc32xx_parse_dt(&pdev->dev, kscandat); | ||
197 | if (error) { | ||
198 | dev_err(&pdev->dev, "failed to parse device tree\n"); | ||
199 | goto err_free_mem; | ||
200 | } | ||
201 | |||
202 | keymap_size = sizeof(kscandat->keymap[0]) * | ||
203 | (kscandat->matrix_sz << kscandat->row_shift); | ||
204 | kscandat->keymap = kzalloc(keymap_size, GFP_KERNEL); | ||
205 | if (!kscandat->keymap) { | ||
206 | dev_err(&pdev->dev, "could not allocate memory for keymap\n"); | ||
207 | error = -ENOMEM; | ||
208 | goto err_free_mem; | ||
209 | } | ||
210 | |||
211 | kscandat->input = input = input_allocate_device(); | ||
212 | if (!input) { | ||
213 | dev_err(&pdev->dev, "failed to allocate input device\n"); | ||
214 | error = -ENOMEM; | ||
215 | goto err_free_keymap; | ||
216 | } | ||
217 | |||
218 | /* Setup key input */ | ||
219 | input->name = pdev->name; | ||
220 | input->phys = "lpc32xx/input0"; | ||
221 | input->id.vendor = 0x0001; | ||
222 | input->id.product = 0x0001; | ||
223 | input->id.version = 0x0100; | ||
224 | input->open = lpc32xx_kscan_open; | ||
225 | input->close = lpc32xx_kscan_close; | ||
226 | input->dev.parent = &pdev->dev; | ||
227 | |||
228 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
229 | |||
230 | error = matrix_keypad_build_keymap(NULL, NULL, | ||
231 | kscandat->matrix_sz, | ||
232 | kscandat->matrix_sz, | ||
233 | kscandat->keymap, kscandat->input); | ||
234 | if (error) { | ||
235 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
236 | goto err_free_input; | ||
237 | } | ||
238 | |||
239 | input_set_drvdata(kscandat->input, kscandat); | ||
240 | |||
241 | kscandat->iores = request_mem_region(res->start, resource_size(res), | ||
242 | pdev->name); | ||
243 | if (!kscandat->iores) { | ||
244 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
245 | error = -EBUSY; | ||
246 | goto err_free_input; | ||
247 | } | ||
248 | |||
249 | kscandat->kscan_base = ioremap(kscandat->iores->start, | ||
250 | resource_size(kscandat->iores)); | ||
251 | if (!kscandat->kscan_base) { | ||
252 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
253 | error = -EBUSY; | ||
254 | goto err_release_memregion; | ||
255 | } | ||
256 | |||
257 | /* Get the key scanner clock */ | ||
258 | kscandat->clk = clk_get(&pdev->dev, NULL); | ||
259 | if (IS_ERR(kscandat->clk)) { | ||
260 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
261 | error = PTR_ERR(kscandat->clk); | ||
262 | goto err_unmap; | ||
263 | } | ||
264 | |||
265 | /* Configure the key scanner */ | ||
266 | error = clk_prepare_enable(kscandat->clk); | ||
267 | if (error) | ||
268 | goto err_clk_put; | ||
269 | |||
270 | writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); | ||
271 | writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); | ||
272 | writel(LPC32XX_KSCAN_FTST_USE32K_CLK, | ||
273 | LPC32XX_KS_FAST_TST(kscandat->kscan_base)); | ||
274 | writel(kscandat->matrix_sz, | ||
275 | LPC32XX_KS_MATRIX_DIM(kscandat->kscan_base)); | ||
276 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); | ||
277 | clk_disable_unprepare(kscandat->clk); | ||
278 | |||
279 | error = request_irq(irq, lpc32xx_kscan_irq, 0, pdev->name, kscandat); | ||
280 | if (error) { | ||
281 | dev_err(&pdev->dev, "failed to request irq\n"); | ||
282 | goto err_clk_put; | ||
283 | } | ||
284 | |||
285 | error = input_register_device(kscandat->input); | ||
286 | if (error) { | ||
287 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
288 | goto err_free_irq; | ||
289 | } | ||
290 | |||
291 | platform_set_drvdata(pdev, kscandat); | ||
292 | return 0; | ||
293 | |||
294 | err_free_irq: | ||
295 | free_irq(irq, kscandat); | ||
296 | err_clk_put: | ||
297 | clk_put(kscandat->clk); | ||
298 | err_unmap: | ||
299 | iounmap(kscandat->kscan_base); | ||
300 | err_release_memregion: | ||
301 | release_mem_region(kscandat->iores->start, | ||
302 | resource_size(kscandat->iores)); | ||
303 | err_free_input: | ||
304 | input_free_device(kscandat->input); | ||
305 | err_free_keymap: | ||
306 | kfree(kscandat->keymap); | ||
307 | err_free_mem: | ||
308 | kfree(kscandat); | ||
309 | |||
310 | return error; | ||
311 | } | ||
312 | |||
313 | static int lpc32xx_kscan_remove(struct platform_device *pdev) | ||
314 | { | ||
315 | struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); | ||
316 | |||
317 | free_irq(platform_get_irq(pdev, 0), kscandat); | ||
318 | clk_put(kscandat->clk); | ||
319 | iounmap(kscandat->kscan_base); | ||
320 | release_mem_region(kscandat->iores->start, | ||
321 | resource_size(kscandat->iores)); | ||
322 | input_unregister_device(kscandat->input); | ||
323 | kfree(kscandat->keymap); | ||
324 | kfree(kscandat); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | #ifdef CONFIG_PM_SLEEP | ||
330 | static int lpc32xx_kscan_suspend(struct device *dev) | ||
331 | { | ||
332 | struct platform_device *pdev = to_platform_device(dev); | ||
333 | struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); | ||
334 | struct input_dev *input = kscandat->input; | ||
335 | |||
336 | mutex_lock(&input->mutex); | ||
337 | |||
338 | if (input->users) { | ||
339 | /* Clear IRQ and disable clock */ | ||
340 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); | ||
341 | clk_disable_unprepare(kscandat->clk); | ||
342 | } | ||
343 | |||
344 | mutex_unlock(&input->mutex); | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int lpc32xx_kscan_resume(struct device *dev) | ||
349 | { | ||
350 | struct platform_device *pdev = to_platform_device(dev); | ||
351 | struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); | ||
352 | struct input_dev *input = kscandat->input; | ||
353 | int retval = 0; | ||
354 | |||
355 | mutex_lock(&input->mutex); | ||
356 | |||
357 | if (input->users) { | ||
358 | /* Enable clock and clear IRQ */ | ||
359 | retval = clk_prepare_enable(kscandat->clk); | ||
360 | if (retval == 0) | ||
361 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); | ||
362 | } | ||
363 | |||
364 | mutex_unlock(&input->mutex); | ||
365 | return retval; | ||
366 | } | ||
367 | #endif | ||
368 | |||
369 | static SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend, | ||
370 | lpc32xx_kscan_resume); | ||
371 | |||
372 | static const struct of_device_id lpc32xx_kscan_match[] = { | ||
373 | { .compatible = "nxp,lpc3220-key" }, | ||
374 | {}, | ||
375 | }; | ||
376 | MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); | ||
377 | |||
378 | static struct platform_driver lpc32xx_kscan_driver = { | ||
379 | .probe = lpc32xx_kscan_probe, | ||
380 | .remove = lpc32xx_kscan_remove, | ||
381 | .driver = { | ||
382 | .name = DRV_NAME, | ||
383 | .owner = THIS_MODULE, | ||
384 | .pm = &lpc32xx_kscan_pm_ops, | ||
385 | .of_match_table = of_match_ptr(lpc32xx_kscan_match), | ||
386 | } | ||
387 | }; | ||
388 | |||
389 | module_platform_driver(lpc32xx_kscan_driver); | ||
390 | |||
391 | MODULE_LICENSE("GPL"); | ||
392 | MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); | ||
393 | MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); | ||
394 | MODULE_DESCRIPTION("Key scanner driver for LPC32XX devices"); | ||
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index f4ff0dda759..b02e4268e18 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -23,13 +23,11 @@ | |||
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/input/matrix_keypad.h> | 24 | #include <linux/input/matrix_keypad.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/of.h> | ||
27 | #include <linux/of_gpio.h> | ||
28 | #include <linux/of_platform.h> | ||
29 | 26 | ||
30 | struct matrix_keypad { | 27 | struct matrix_keypad { |
31 | const struct matrix_keypad_platform_data *pdata; | 28 | const struct matrix_keypad_platform_data *pdata; |
32 | struct input_dev *input_dev; | 29 | struct input_dev *input_dev; |
30 | unsigned short *keycodes; | ||
33 | unsigned int row_shift; | 31 | unsigned int row_shift; |
34 | 32 | ||
35 | DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); | 33 | DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); |
@@ -119,7 +117,6 @@ static void matrix_keypad_scan(struct work_struct *work) | |||
119 | struct matrix_keypad *keypad = | 117 | struct matrix_keypad *keypad = |
120 | container_of(work, struct matrix_keypad, work.work); | 118 | container_of(work, struct matrix_keypad, work.work); |
121 | struct input_dev *input_dev = keypad->input_dev; | 119 | struct input_dev *input_dev = keypad->input_dev; |
122 | const unsigned short *keycodes = input_dev->keycode; | ||
123 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 120 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
124 | uint32_t new_state[MATRIX_MAX_COLS]; | 121 | uint32_t new_state[MATRIX_MAX_COLS]; |
125 | int row, col, code; | 122 | int row, col, code; |
@@ -155,7 +152,7 @@ static void matrix_keypad_scan(struct work_struct *work) | |||
155 | code = MATRIX_SCAN_CODE(row, col, keypad->row_shift); | 152 | code = MATRIX_SCAN_CODE(row, col, keypad->row_shift); |
156 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | 153 | input_event(input_dev, EV_MSC, MSC_SCAN, code); |
157 | input_report_key(input_dev, | 154 | input_report_key(input_dev, |
158 | keycodes[code], | 155 | keypad->keycodes[code], |
159 | new_state[col] & (1 << row)); | 156 | new_state[col] & (1 << row)); |
160 | } | 157 | } |
161 | } | 158 | } |
@@ -227,7 +224,7 @@ static void matrix_keypad_stop(struct input_dev *dev) | |||
227 | disable_row_irqs(keypad); | 224 | disable_row_irqs(keypad); |
228 | } | 225 | } |
229 | 226 | ||
230 | #ifdef CONFIG_PM_SLEEP | 227 | #ifdef CONFIG_PM |
231 | static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) | 228 | static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) |
232 | { | 229 | { |
233 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 230 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
@@ -296,16 +293,16 @@ static int matrix_keypad_resume(struct device *dev) | |||
296 | 293 | ||
297 | return 0; | 294 | return 0; |
298 | } | 295 | } |
299 | #endif | ||
300 | 296 | ||
301 | static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, | 297 | static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, |
302 | matrix_keypad_suspend, matrix_keypad_resume); | 298 | matrix_keypad_suspend, matrix_keypad_resume); |
299 | #endif | ||
303 | 300 | ||
304 | static int matrix_keypad_init_gpio(struct platform_device *pdev, | 301 | static int __devinit init_matrix_gpio(struct platform_device *pdev, |
305 | struct matrix_keypad *keypad) | 302 | struct matrix_keypad *keypad) |
306 | { | 303 | { |
307 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 304 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
308 | int i, err; | 305 | int i, err = -EINVAL; |
309 | 306 | ||
310 | /* initialized strobe lines as outputs, activated */ | 307 | /* initialized strobe lines as outputs, activated */ |
311 | for (i = 0; i < pdata->num_col_gpios; i++) { | 308 | for (i = 0; i < pdata->num_col_gpios; i++) { |
@@ -346,12 +343,14 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, | |||
346 | for (i = 0; i < pdata->num_row_gpios; i++) { | 343 | for (i = 0; i < pdata->num_row_gpios; i++) { |
347 | err = request_irq(gpio_to_irq(pdata->row_gpios[i]), | 344 | err = request_irq(gpio_to_irq(pdata->row_gpios[i]), |
348 | matrix_keypad_interrupt, | 345 | matrix_keypad_interrupt, |
346 | IRQF_DISABLED | | ||
349 | IRQF_TRIGGER_RISING | | 347 | IRQF_TRIGGER_RISING | |
350 | IRQF_TRIGGER_FALLING, | 348 | IRQF_TRIGGER_FALLING, |
351 | "matrix-keypad", keypad); | 349 | "matrix-keypad", keypad); |
352 | if (err) { | 350 | if (err) { |
353 | dev_err(&pdev->dev, | 351 | dev_err(&pdev->dev, |
354 | "Unable to acquire interrupt for GPIO line %i\n", | 352 | "Unable to acquire interrupt " |
353 | "for GPIO line %i\n", | ||
355 | pdata->row_gpios[i]); | 354 | pdata->row_gpios[i]); |
356 | goto err_free_irqs; | 355 | goto err_free_irqs; |
357 | } | 356 | } |
@@ -377,123 +376,44 @@ err_free_cols: | |||
377 | return err; | 376 | return err; |
378 | } | 377 | } |
379 | 378 | ||
380 | static void matrix_keypad_free_gpio(struct matrix_keypad *keypad) | 379 | static int __devinit matrix_keypad_probe(struct platform_device *pdev) |
381 | { | ||
382 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
383 | int i; | ||
384 | |||
385 | if (pdata->clustered_irq > 0) { | ||
386 | free_irq(pdata->clustered_irq, keypad); | ||
387 | } else { | ||
388 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
389 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | ||
390 | } | ||
391 | |||
392 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
393 | gpio_free(pdata->row_gpios[i]); | ||
394 | |||
395 | for (i = 0; i < pdata->num_col_gpios; i++) | ||
396 | gpio_free(pdata->col_gpios[i]); | ||
397 | } | ||
398 | |||
399 | #ifdef CONFIG_OF | ||
400 | static struct matrix_keypad_platform_data * | ||
401 | matrix_keypad_parse_dt(struct device *dev) | ||
402 | { | ||
403 | struct matrix_keypad_platform_data *pdata; | ||
404 | struct device_node *np = dev->of_node; | ||
405 | unsigned int *gpios; | ||
406 | int i; | ||
407 | |||
408 | if (!np) { | ||
409 | dev_err(dev, "device lacks DT data\n"); | ||
410 | return ERR_PTR(-ENODEV); | ||
411 | } | ||
412 | |||
413 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
414 | if (!pdata) { | ||
415 | dev_err(dev, "could not allocate memory for platform data\n"); | ||
416 | return ERR_PTR(-ENOMEM); | ||
417 | } | ||
418 | |||
419 | pdata->num_row_gpios = of_gpio_named_count(np, "row-gpios"); | ||
420 | pdata->num_col_gpios = of_gpio_named_count(np, "col-gpios"); | ||
421 | if (!pdata->num_row_gpios || !pdata->num_col_gpios) { | ||
422 | dev_err(dev, "number of keypad rows/columns not specified\n"); | ||
423 | return ERR_PTR(-EINVAL); | ||
424 | } | ||
425 | |||
426 | if (of_get_property(np, "linux,no-autorepeat", NULL)) | ||
427 | pdata->no_autorepeat = true; | ||
428 | if (of_get_property(np, "linux,wakeup", NULL)) | ||
429 | pdata->wakeup = true; | ||
430 | if (of_get_property(np, "gpio-activelow", NULL)) | ||
431 | pdata->active_low = true; | ||
432 | |||
433 | of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms); | ||
434 | of_property_read_u32(np, "col-scan-delay-us", | ||
435 | &pdata->col_scan_delay_us); | ||
436 | |||
437 | gpios = devm_kzalloc(dev, | ||
438 | sizeof(unsigned int) * | ||
439 | (pdata->num_row_gpios + pdata->num_col_gpios), | ||
440 | GFP_KERNEL); | ||
441 | if (!gpios) { | ||
442 | dev_err(dev, "could not allocate memory for gpios\n"); | ||
443 | return ERR_PTR(-ENOMEM); | ||
444 | } | ||
445 | |||
446 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
447 | gpios[i] = of_get_named_gpio(np, "row-gpios", i); | ||
448 | |||
449 | for (i = 0; i < pdata->num_col_gpios; i++) | ||
450 | gpios[pdata->num_row_gpios + i] = | ||
451 | of_get_named_gpio(np, "col-gpios", i); | ||
452 | |||
453 | pdata->row_gpios = gpios; | ||
454 | pdata->col_gpios = &gpios[pdata->num_row_gpios]; | ||
455 | |||
456 | return pdata; | ||
457 | } | ||
458 | #else | ||
459 | static inline struct matrix_keypad_platform_data * | ||
460 | matrix_keypad_parse_dt(struct device *dev) | ||
461 | { | ||
462 | dev_err(dev, "no platform data defined\n"); | ||
463 | |||
464 | return ERR_PTR(-EINVAL); | ||
465 | } | ||
466 | #endif | ||
467 | |||
468 | static int matrix_keypad_probe(struct platform_device *pdev) | ||
469 | { | 380 | { |
470 | const struct matrix_keypad_platform_data *pdata; | 381 | const struct matrix_keypad_platform_data *pdata; |
382 | const struct matrix_keymap_data *keymap_data; | ||
471 | struct matrix_keypad *keypad; | 383 | struct matrix_keypad *keypad; |
472 | struct input_dev *input_dev; | 384 | struct input_dev *input_dev; |
385 | unsigned short *keycodes; | ||
386 | unsigned int row_shift; | ||
473 | int err; | 387 | int err; |
474 | 388 | ||
475 | pdata = dev_get_platdata(&pdev->dev); | 389 | pdata = pdev->dev.platform_data; |
476 | if (!pdata) { | 390 | if (!pdata) { |
477 | pdata = matrix_keypad_parse_dt(&pdev->dev); | 391 | dev_err(&pdev->dev, "no platform data defined\n"); |
478 | if (IS_ERR(pdata)) { | 392 | return -EINVAL; |
479 | dev_err(&pdev->dev, "no platform data defined\n"); | 393 | } |
480 | return PTR_ERR(pdata); | 394 | |
481 | } | 395 | keymap_data = pdata->keymap_data; |
482 | } else if (!pdata->keymap_data) { | 396 | if (!keymap_data) { |
483 | dev_err(&pdev->dev, "no keymap data defined\n"); | 397 | dev_err(&pdev->dev, "no keymap data defined\n"); |
484 | return -EINVAL; | 398 | return -EINVAL; |
485 | } | 399 | } |
486 | 400 | ||
401 | row_shift = get_count_order(pdata->num_col_gpios); | ||
402 | |||
487 | keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); | 403 | keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); |
404 | keycodes = kzalloc((pdata->num_row_gpios << row_shift) * | ||
405 | sizeof(*keycodes), | ||
406 | GFP_KERNEL); | ||
488 | input_dev = input_allocate_device(); | 407 | input_dev = input_allocate_device(); |
489 | if (!keypad || !input_dev) { | 408 | if (!keypad || !keycodes || !input_dev) { |
490 | err = -ENOMEM; | 409 | err = -ENOMEM; |
491 | goto err_free_mem; | 410 | goto err_free_mem; |
492 | } | 411 | } |
493 | 412 | ||
494 | keypad->input_dev = input_dev; | 413 | keypad->input_dev = input_dev; |
495 | keypad->pdata = pdata; | 414 | keypad->pdata = pdata; |
496 | keypad->row_shift = get_count_order(pdata->num_col_gpios); | 415 | keypad->keycodes = keycodes; |
416 | keypad->row_shift = row_shift; | ||
497 | keypad->stopped = true; | 417 | keypad->stopped = true; |
498 | INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); | 418 | INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); |
499 | spin_lock_init(&keypad->lock); | 419 | spin_lock_init(&keypad->lock); |
@@ -501,78 +421,95 @@ static int matrix_keypad_probe(struct platform_device *pdev) | |||
501 | input_dev->name = pdev->name; | 421 | input_dev->name = pdev->name; |
502 | input_dev->id.bustype = BUS_HOST; | 422 | input_dev->id.bustype = BUS_HOST; |
503 | input_dev->dev.parent = &pdev->dev; | 423 | input_dev->dev.parent = &pdev->dev; |
424 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
425 | if (!pdata->no_autorepeat) | ||
426 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
504 | input_dev->open = matrix_keypad_start; | 427 | input_dev->open = matrix_keypad_start; |
505 | input_dev->close = matrix_keypad_stop; | 428 | input_dev->close = matrix_keypad_stop; |
506 | 429 | ||
507 | err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, | 430 | input_dev->keycode = keycodes; |
508 | pdata->num_row_gpios, | 431 | input_dev->keycodesize = sizeof(*keycodes); |
509 | pdata->num_col_gpios, | 432 | input_dev->keycodemax = pdata->num_row_gpios << row_shift; |
510 | NULL, input_dev); | 433 | |
511 | if (err) { | 434 | matrix_keypad_build_keymap(keymap_data, row_shift, |
512 | dev_err(&pdev->dev, "failed to build keymap\n"); | 435 | input_dev->keycode, input_dev->keybit); |
513 | goto err_free_mem; | ||
514 | } | ||
515 | 436 | ||
516 | if (!pdata->no_autorepeat) | ||
517 | __set_bit(EV_REP, input_dev->evbit); | ||
518 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 437 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
519 | input_set_drvdata(input_dev, keypad); | 438 | input_set_drvdata(input_dev, keypad); |
520 | 439 | ||
521 | err = matrix_keypad_init_gpio(pdev, keypad); | 440 | err = init_matrix_gpio(pdev, keypad); |
522 | if (err) | 441 | if (err) |
523 | goto err_free_mem; | 442 | goto err_free_mem; |
524 | 443 | ||
525 | err = input_register_device(keypad->input_dev); | 444 | err = input_register_device(keypad->input_dev); |
526 | if (err) | 445 | if (err) |
527 | goto err_free_gpio; | 446 | goto err_free_mem; |
528 | 447 | ||
529 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 448 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
530 | platform_set_drvdata(pdev, keypad); | 449 | platform_set_drvdata(pdev, keypad); |
531 | 450 | ||
532 | return 0; | 451 | return 0; |
533 | 452 | ||
534 | err_free_gpio: | ||
535 | matrix_keypad_free_gpio(keypad); | ||
536 | err_free_mem: | 453 | err_free_mem: |
537 | input_free_device(input_dev); | 454 | input_free_device(input_dev); |
455 | kfree(keycodes); | ||
538 | kfree(keypad); | 456 | kfree(keypad); |
539 | return err; | 457 | return err; |
540 | } | 458 | } |
541 | 459 | ||
542 | static int matrix_keypad_remove(struct platform_device *pdev) | 460 | static int __devexit matrix_keypad_remove(struct platform_device *pdev) |
543 | { | 461 | { |
544 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 462 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
463 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
464 | int i; | ||
545 | 465 | ||
546 | device_init_wakeup(&pdev->dev, 0); | 466 | device_init_wakeup(&pdev->dev, 0); |
547 | 467 | ||
548 | matrix_keypad_free_gpio(keypad); | 468 | if (pdata->clustered_irq > 0) { |
549 | input_unregister_device(keypad->input_dev); | 469 | free_irq(pdata->clustered_irq, keypad); |
550 | kfree(keypad); | 470 | } else { |
471 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
472 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | ||
473 | } | ||
474 | |||
475 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
476 | gpio_free(pdata->row_gpios[i]); | ||
551 | 477 | ||
478 | for (i = 0; i < pdata->num_col_gpios; i++) | ||
479 | gpio_free(pdata->col_gpios[i]); | ||
480 | |||
481 | input_unregister_device(keypad->input_dev); | ||
552 | platform_set_drvdata(pdev, NULL); | 482 | platform_set_drvdata(pdev, NULL); |
483 | kfree(keypad->keycodes); | ||
484 | kfree(keypad); | ||
553 | 485 | ||
554 | return 0; | 486 | return 0; |
555 | } | 487 | } |
556 | 488 | ||
557 | #ifdef CONFIG_OF | ||
558 | static const struct of_device_id matrix_keypad_dt_match[] = { | ||
559 | { .compatible = "gpio-matrix-keypad" }, | ||
560 | { } | ||
561 | }; | ||
562 | MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match); | ||
563 | #endif | ||
564 | |||
565 | static struct platform_driver matrix_keypad_driver = { | 489 | static struct platform_driver matrix_keypad_driver = { |
566 | .probe = matrix_keypad_probe, | 490 | .probe = matrix_keypad_probe, |
567 | .remove = matrix_keypad_remove, | 491 | .remove = __devexit_p(matrix_keypad_remove), |
568 | .driver = { | 492 | .driver = { |
569 | .name = "matrix-keypad", | 493 | .name = "matrix-keypad", |
570 | .owner = THIS_MODULE, | 494 | .owner = THIS_MODULE, |
495 | #ifdef CONFIG_PM | ||
571 | .pm = &matrix_keypad_pm_ops, | 496 | .pm = &matrix_keypad_pm_ops, |
572 | .of_match_table = of_match_ptr(matrix_keypad_dt_match), | 497 | #endif |
573 | }, | 498 | }, |
574 | }; | 499 | }; |
575 | module_platform_driver(matrix_keypad_driver); | 500 | |
501 | static int __init matrix_keypad_init(void) | ||
502 | { | ||
503 | return platform_driver_register(&matrix_keypad_driver); | ||
504 | } | ||
505 | |||
506 | static void __exit matrix_keypad_exit(void) | ||
507 | { | ||
508 | platform_driver_unregister(&matrix_keypad_driver); | ||
509 | } | ||
510 | |||
511 | module_init(matrix_keypad_init); | ||
512 | module_exit(matrix_keypad_exit); | ||
576 | 513 | ||
577 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); | 514 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); |
578 | MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver"); | 515 | MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver"); |
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 7c7af2b01e6..5afe35ad24d 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c | |||
@@ -179,7 +179,7 @@ static void max7359_initialize(struct i2c_client *client) | |||
179 | max7359_fall_deepsleep(client); | 179 | max7359_fall_deepsleep(client); |
180 | } | 180 | } |
181 | 181 | ||
182 | static int max7359_probe(struct i2c_client *client, | 182 | static int __devinit max7359_probe(struct i2c_client *client, |
183 | const struct i2c_device_id *id) | 183 | const struct i2c_device_id *id) |
184 | { | 184 | { |
185 | const struct matrix_keymap_data *keymap_data = client->dev.platform_data; | 185 | const struct matrix_keymap_data *keymap_data = client->dev.platform_data; |
@@ -260,7 +260,7 @@ failed_free_mem: | |||
260 | return error; | 260 | return error; |
261 | } | 261 | } |
262 | 262 | ||
263 | static int max7359_remove(struct i2c_client *client) | 263 | static int __devexit max7359_remove(struct i2c_client *client) |
264 | { | 264 | { |
265 | struct max7359_keypad *keypad = i2c_get_clientdata(client); | 265 | struct max7359_keypad *keypad = i2c_get_clientdata(client); |
266 | 266 | ||
@@ -312,11 +312,21 @@ static struct i2c_driver max7359_i2c_driver = { | |||
312 | .pm = &max7359_pm, | 312 | .pm = &max7359_pm, |
313 | }, | 313 | }, |
314 | .probe = max7359_probe, | 314 | .probe = max7359_probe, |
315 | .remove = max7359_remove, | 315 | .remove = __devexit_p(max7359_remove), |
316 | .id_table = max7359_ids, | 316 | .id_table = max7359_ids, |
317 | }; | 317 | }; |
318 | 318 | ||
319 | module_i2c_driver(max7359_i2c_driver); | 319 | static int __init max7359_init(void) |
320 | { | ||
321 | return i2c_add_driver(&max7359_i2c_driver); | ||
322 | } | ||
323 | module_init(max7359_init); | ||
324 | |||
325 | static void __exit max7359_exit(void) | ||
326 | { | ||
327 | i2c_del_driver(&max7359_i2c_driver); | ||
328 | } | ||
329 | module_exit(max7359_exit); | ||
320 | 330 | ||
321 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); | 331 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); |
322 | MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver"); | 332 | MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver"); |
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 7c236f9c6a5..af1aab324a4 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c | |||
@@ -97,7 +97,7 @@ static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id) | |||
97 | return IRQ_HANDLED; | 97 | return IRQ_HANDLED; |
98 | } | 98 | } |
99 | 99 | ||
100 | static int mcs_touchkey_probe(struct i2c_client *client, | 100 | static int __devinit mcs_touchkey_probe(struct i2c_client *client, |
101 | const struct i2c_device_id *id) | 101 | const struct i2c_device_id *id) |
102 | { | 102 | { |
103 | const struct mcs_platform_data *pdata; | 103 | const struct mcs_platform_data *pdata; |
@@ -178,8 +178,7 @@ static int mcs_touchkey_probe(struct i2c_client *client, | |||
178 | } | 178 | } |
179 | 179 | ||
180 | error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, | 180 | error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, |
181 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 181 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); |
182 | client->dev.driver->name, data); | ||
183 | if (error) { | 182 | if (error) { |
184 | dev_err(&client->dev, "Failed to register interrupt\n"); | 183 | dev_err(&client->dev, "Failed to register interrupt\n"); |
185 | goto err_free_mem; | 184 | goto err_free_mem; |
@@ -200,7 +199,7 @@ err_free_mem: | |||
200 | return error; | 199 | return error; |
201 | } | 200 | } |
202 | 201 | ||
203 | static int mcs_touchkey_remove(struct i2c_client *client) | 202 | static int __devexit mcs_touchkey_remove(struct i2c_client *client) |
204 | { | 203 | { |
205 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); | 204 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); |
206 | 205 | ||
@@ -270,12 +269,23 @@ static struct i2c_driver mcs_touchkey_driver = { | |||
270 | .pm = &mcs_touchkey_pm_ops, | 269 | .pm = &mcs_touchkey_pm_ops, |
271 | }, | 270 | }, |
272 | .probe = mcs_touchkey_probe, | 271 | .probe = mcs_touchkey_probe, |
273 | .remove = mcs_touchkey_remove, | 272 | .remove = __devexit_p(mcs_touchkey_remove), |
274 | .shutdown = mcs_touchkey_shutdown, | 273 | .shutdown = mcs_touchkey_shutdown, |
275 | .id_table = mcs_touchkey_id, | 274 | .id_table = mcs_touchkey_id, |
276 | }; | 275 | }; |
277 | 276 | ||
278 | module_i2c_driver(mcs_touchkey_driver); | 277 | static int __init mcs_touchkey_init(void) |
278 | { | ||
279 | return i2c_add_driver(&mcs_touchkey_driver); | ||
280 | } | ||
281 | |||
282 | static void __exit mcs_touchkey_exit(void) | ||
283 | { | ||
284 | i2c_del_driver(&mcs_touchkey_driver); | ||
285 | } | ||
286 | |||
287 | module_init(mcs_touchkey_init); | ||
288 | module_exit(mcs_touchkey_exit); | ||
279 | 289 | ||
280 | /* Module information */ | 290 | /* Module information */ |
281 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 291 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index f7f3e9a9fd3..1c1615d9a7f 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c | |||
@@ -71,7 +71,7 @@ struct mpr121_init_register { | |||
71 | u8 val; | 71 | u8 val; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static const struct mpr121_init_register init_reg_table[] = { | 74 | static const struct mpr121_init_register init_reg_table[] __devinitconst = { |
75 | { MHD_RISING_ADDR, 0x1 }, | 75 | { MHD_RISING_ADDR, 0x1 }, |
76 | { NHD_RISING_ADDR, 0x1 }, | 76 | { NHD_RISING_ADDR, 0x1 }, |
77 | { MHD_FALLING_ADDR, 0x1 }, | 77 | { MHD_FALLING_ADDR, 0x1 }, |
@@ -123,7 +123,7 @@ out: | |||
123 | return IRQ_HANDLED; | 123 | return IRQ_HANDLED; |
124 | } | 124 | } |
125 | 125 | ||
126 | static int mpr121_phys_init(const struct mpr121_platform_data *pdata, | 126 | static int __devinit mpr121_phys_init(const struct mpr121_platform_data *pdata, |
127 | struct mpr121_touchkey *mpr121, | 127 | struct mpr121_touchkey *mpr121, |
128 | struct i2c_client *client) | 128 | struct i2c_client *client) |
129 | { | 129 | { |
@@ -185,8 +185,8 @@ err_i2c_write: | |||
185 | return ret; | 185 | return ret; |
186 | } | 186 | } |
187 | 187 | ||
188 | static int mpr_touchkey_probe(struct i2c_client *client, | 188 | static int __devinit mpr_touchkey_probe(struct i2c_client *client, |
189 | const struct i2c_device_id *id) | 189 | const struct i2c_device_id *id) |
190 | { | 190 | { |
191 | const struct mpr121_platform_data *pdata = client->dev.platform_data; | 191 | const struct mpr121_platform_data *pdata = client->dev.platform_data; |
192 | struct mpr121_touchkey *mpr121; | 192 | struct mpr121_touchkey *mpr121; |
@@ -248,7 +248,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, | |||
248 | 248 | ||
249 | error = request_threaded_irq(client->irq, NULL, | 249 | error = request_threaded_irq(client->irq, NULL, |
250 | mpr_touchkey_interrupt, | 250 | mpr_touchkey_interrupt, |
251 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 251 | IRQF_TRIGGER_FALLING, |
252 | client->dev.driver->name, mpr121); | 252 | client->dev.driver->name, mpr121); |
253 | if (error) { | 253 | if (error) { |
254 | dev_err(&client->dev, "Failed to register interrupt\n"); | 254 | dev_err(&client->dev, "Failed to register interrupt\n"); |
@@ -272,7 +272,7 @@ err_free_mem: | |||
272 | return error; | 272 | return error; |
273 | } | 273 | } |
274 | 274 | ||
275 | static int mpr_touchkey_remove(struct i2c_client *client) | 275 | static int __devexit mpr_touchkey_remove(struct i2c_client *client) |
276 | { | 276 | { |
277 | struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); | 277 | struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); |
278 | 278 | ||
@@ -327,10 +327,20 @@ static struct i2c_driver mpr_touchkey_driver = { | |||
327 | }, | 327 | }, |
328 | .id_table = mpr121_id, | 328 | .id_table = mpr121_id, |
329 | .probe = mpr_touchkey_probe, | 329 | .probe = mpr_touchkey_probe, |
330 | .remove = mpr_touchkey_remove, | 330 | .remove = __devexit_p(mpr_touchkey_remove), |
331 | }; | 331 | }; |
332 | 332 | ||
333 | module_i2c_driver(mpr_touchkey_driver); | 333 | static int __init mpr_touchkey_init(void) |
334 | { | ||
335 | return i2c_add_driver(&mpr_touchkey_driver); | ||
336 | } | ||
337 | module_init(mpr_touchkey_init); | ||
338 | |||
339 | static void __exit mpr_touchkey_exit(void) | ||
340 | { | ||
341 | i2c_del_driver(&mpr_touchkey_driver); | ||
342 | } | ||
343 | module_exit(mpr_touchkey_exit); | ||
334 | 344 | ||
335 | MODULE_LICENSE("GPL"); | 345 | MODULE_LICENSE("GPL"); |
336 | MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); | 346 | MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); |
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index f971898ad59..48d1cab0aa1 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c | |||
@@ -166,4 +166,15 @@ static struct serio_driver nkbd_drv = { | |||
166 | .disconnect = nkbd_disconnect, | 166 | .disconnect = nkbd_disconnect, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | module_serio_driver(nkbd_drv); | 169 | static int __init nkbd_init(void) |
170 | { | ||
171 | return serio_register_driver(&nkbd_drv); | ||
172 | } | ||
173 | |||
174 | static void __exit nkbd_exit(void) | ||
175 | { | ||
176 | serio_unregister_driver(&nkbd_drv); | ||
177 | } | ||
178 | |||
179 | module_init(nkbd_init); | ||
180 | module_exit(nkbd_exit); | ||
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 0e6a8151fee..6e0f2309136 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
@@ -18,9 +18,8 @@ | |||
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | #include <linux/module.h> | ||
22 | 21 | ||
23 | #include <linux/platform_data/keypad-nomadik-ske.h> | 22 | #include <plat/ske.h> |
24 | 23 | ||
25 | /* SKE_CR bits */ | 24 | /* SKE_CR bits */ |
26 | #define SKE_KPMLT (0x1 << 6) | 25 | #define SKE_KPMLT (0x1 << 6) |
@@ -39,8 +38,7 @@ | |||
39 | #define SKE_KPRISA (0x1 << 2) | 38 | #define SKE_KPRISA (0x1 << 2) |
40 | 39 | ||
41 | #define SKE_KEYPAD_ROW_SHIFT 3 | 40 | #define SKE_KEYPAD_ROW_SHIFT 3 |
42 | #define SKE_KPD_NUM_ROWS 8 | 41 | #define SKE_KPD_KEYMAP_SIZE (8 * 8) |
43 | #define SKE_KPD_NUM_COLS 8 | ||
44 | 42 | ||
45 | /* keypad auto scan registers */ | 43 | /* keypad auto scan registers */ |
46 | #define SKE_ASR0 0x20 | 44 | #define SKE_ASR0 0x20 |
@@ -49,7 +47,6 @@ | |||
49 | #define SKE_ASR3 0x2C | 47 | #define SKE_ASR3 0x2C |
50 | 48 | ||
51 | #define SKE_NUM_ASRX_REGISTERS (4) | 49 | #define SKE_NUM_ASRX_REGISTERS (4) |
52 | #define KEY_PRESSED_DELAY 10 | ||
53 | 50 | ||
54 | /** | 51 | /** |
55 | * struct ske_keypad - data structure used by keypad driver | 52 | * struct ske_keypad - data structure used by keypad driver |
@@ -65,9 +62,8 @@ struct ske_keypad { | |||
65 | void __iomem *reg_base; | 62 | void __iomem *reg_base; |
66 | struct input_dev *input; | 63 | struct input_dev *input; |
67 | const struct ske_keypad_platform_data *board; | 64 | const struct ske_keypad_platform_data *board; |
68 | unsigned short keymap[SKE_KPD_NUM_ROWS * SKE_KPD_NUM_COLS]; | 65 | unsigned short keymap[SKE_KPD_KEYMAP_SIZE]; |
69 | struct clk *clk; | 66 | struct clk *clk; |
70 | struct clk *pclk; | ||
71 | spinlock_t ske_keypad_lock; | 67 | spinlock_t ske_keypad_lock; |
72 | }; | 68 | }; |
73 | 69 | ||
@@ -91,10 +87,10 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, | |||
91 | * | 87 | * |
92 | * Enable Multi key press detection, auto scan mode | 88 | * Enable Multi key press detection, auto scan mode |
93 | */ | 89 | */ |
94 | static int __init ske_keypad_chip_init(struct ske_keypad *keypad) | 90 | static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) |
95 | { | 91 | { |
96 | u32 value; | 92 | u32 value; |
97 | int timeout = keypad->board->debounce_ms; | 93 | int timeout = 50; |
98 | 94 | ||
99 | /* check SKE_RIS to be 0 */ | 95 | /* check SKE_RIS to be 0 */ |
100 | while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--) | 96 | while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--) |
@@ -137,37 +133,12 @@ static int __init ske_keypad_chip_init(struct ske_keypad *keypad) | |||
137 | return 0; | 133 | return 0; |
138 | } | 134 | } |
139 | 135 | ||
140 | static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col) | ||
141 | { | ||
142 | int row = 0, code, pos; | ||
143 | struct input_dev *input = keypad->input; | ||
144 | u32 ske_ris; | ||
145 | int key_pressed; | ||
146 | int num_of_rows; | ||
147 | |||
148 | /* find out the row */ | ||
149 | num_of_rows = hweight8(status); | ||
150 | do { | ||
151 | pos = __ffs(status); | ||
152 | row = pos; | ||
153 | status &= ~(1 << pos); | ||
154 | |||
155 | code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); | ||
156 | ske_ris = readl(keypad->reg_base + SKE_RIS); | ||
157 | key_pressed = ske_ris & SKE_KPRISA; | ||
158 | |||
159 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
160 | input_report_key(input, keypad->keymap[code], key_pressed); | ||
161 | input_sync(input); | ||
162 | num_of_rows--; | ||
163 | } while (num_of_rows); | ||
164 | } | ||
165 | |||
166 | static void ske_keypad_read_data(struct ske_keypad *keypad) | 136 | static void ske_keypad_read_data(struct ske_keypad *keypad) |
167 | { | 137 | { |
168 | u8 status; | 138 | struct input_dev *input = keypad->input; |
169 | int col = 0; | 139 | u16 status; |
170 | int ske_asr, i; | 140 | int col = 0, row = 0, code; |
141 | int ske_asr, ske_ris, key_pressed, i; | ||
171 | 142 | ||
172 | /* | 143 | /* |
173 | * Read the auto scan registers | 144 | * Read the auto scan registers |
@@ -181,38 +152,44 @@ static void ske_keypad_read_data(struct ske_keypad *keypad) | |||
181 | if (!ske_asr) | 152 | if (!ske_asr) |
182 | continue; | 153 | continue; |
183 | 154 | ||
184 | /* now that ASRx is zero, find out the coloumn x and row y */ | 155 | /* now that ASRx is zero, find out the column x and row y*/ |
185 | status = ske_asr & 0xff; | 156 | if (ske_asr & 0xff) { |
186 | if (status) { | ||
187 | col = i * 2; | 157 | col = i * 2; |
188 | ske_keypad_report(keypad, status, col); | 158 | status = ske_asr & 0xff; |
189 | } | 159 | } else { |
190 | status = (ske_asr & 0xff00) >> 8; | ||
191 | if (status) { | ||
192 | col = (i * 2) + 1; | 160 | col = (i * 2) + 1; |
193 | ske_keypad_report(keypad, status, col); | 161 | status = (ske_asr & 0xff00) >> 8; |
194 | } | 162 | } |
163 | |||
164 | /* find out the row */ | ||
165 | row = __ffs(status); | ||
166 | |||
167 | code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); | ||
168 | ske_ris = readl(keypad->reg_base + SKE_RIS); | ||
169 | key_pressed = ske_ris & SKE_KPRISA; | ||
170 | |||
171 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
172 | input_report_key(input, keypad->keymap[code], key_pressed); | ||
173 | input_sync(input); | ||
195 | } | 174 | } |
196 | } | 175 | } |
197 | 176 | ||
198 | static irqreturn_t ske_keypad_irq(int irq, void *dev_id) | 177 | static irqreturn_t ske_keypad_irq(int irq, void *dev_id) |
199 | { | 178 | { |
200 | struct ske_keypad *keypad = dev_id; | 179 | struct ske_keypad *keypad = dev_id; |
201 | int timeout = keypad->board->debounce_ms; | 180 | int retries = 20; |
202 | 181 | ||
203 | /* disable auto scan interrupt; mask the interrupt generated */ | 182 | /* disable auto scan interrupt; mask the interrupt generated */ |
204 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); | 183 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); |
205 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); | 184 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); |
206 | 185 | ||
207 | while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --timeout) | 186 | while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) |
208 | cpu_relax(); | 187 | msleep(5); |
209 | |||
210 | /* SKEx registers are stable and can be read */ | ||
211 | ske_keypad_read_data(keypad); | ||
212 | 188 | ||
213 | /* wait until raw interrupt is clear */ | 189 | if (retries) { |
214 | while ((readl(keypad->reg_base + SKE_RIS)) && --timeout) | 190 | /* SKEx registers are stable and can be read */ |
215 | msleep(KEY_PRESSED_DELAY); | 191 | ske_keypad_read_data(keypad); |
192 | } | ||
216 | 193 | ||
217 | /* enable auto scan interrupts */ | 194 | /* enable auto scan interrupts */ |
218 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | 195 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); |
@@ -220,7 +197,7 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id) | |||
220 | return IRQ_HANDLED; | 197 | return IRQ_HANDLED; |
221 | } | 198 | } |
222 | 199 | ||
223 | static int __init ske_keypad_probe(struct platform_device *pdev) | 200 | static int __devinit ske_keypad_probe(struct platform_device *pdev) |
224 | { | 201 | { |
225 | const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; | 202 | const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; |
226 | struct ske_keypad *keypad; | 203 | struct ske_keypad *keypad; |
@@ -272,48 +249,31 @@ static int __init ske_keypad_probe(struct platform_device *pdev) | |||
272 | goto err_free_mem_region; | 249 | goto err_free_mem_region; |
273 | } | 250 | } |
274 | 251 | ||
275 | keypad->pclk = clk_get(&pdev->dev, "apb_pclk"); | ||
276 | if (IS_ERR(keypad->pclk)) { | ||
277 | dev_err(&pdev->dev, "failed to get pclk\n"); | ||
278 | error = PTR_ERR(keypad->pclk); | ||
279 | goto err_iounmap; | ||
280 | } | ||
281 | |||
282 | keypad->clk = clk_get(&pdev->dev, NULL); | 252 | keypad->clk = clk_get(&pdev->dev, NULL); |
283 | if (IS_ERR(keypad->clk)) { | 253 | if (IS_ERR(keypad->clk)) { |
284 | dev_err(&pdev->dev, "failed to get clk\n"); | 254 | dev_err(&pdev->dev, "failed to get clk\n"); |
285 | error = PTR_ERR(keypad->clk); | 255 | error = PTR_ERR(keypad->clk); |
286 | goto err_pclk; | 256 | goto err_iounmap; |
287 | } | 257 | } |
288 | 258 | ||
289 | input->id.bustype = BUS_HOST; | 259 | input->id.bustype = BUS_HOST; |
290 | input->name = "ux500-ske-keypad"; | 260 | input->name = "ux500-ske-keypad"; |
291 | input->dev.parent = &pdev->dev; | 261 | input->dev.parent = &pdev->dev; |
292 | 262 | ||
293 | error = matrix_keypad_build_keymap(plat->keymap_data, NULL, | 263 | input->keycode = keypad->keymap; |
294 | SKE_KPD_NUM_ROWS, SKE_KPD_NUM_COLS, | 264 | input->keycodesize = sizeof(keypad->keymap[0]); |
295 | keypad->keymap, input); | 265 | input->keycodemax = ARRAY_SIZE(keypad->keymap); |
296 | if (error) { | ||
297 | dev_err(&pdev->dev, "Failed to build keymap\n"); | ||
298 | goto err_clk; | ||
299 | } | ||
300 | 266 | ||
301 | input_set_capability(input, EV_MSC, MSC_SCAN); | 267 | input_set_capability(input, EV_MSC, MSC_SCAN); |
268 | |||
269 | __set_bit(EV_KEY, input->evbit); | ||
302 | if (!plat->no_autorepeat) | 270 | if (!plat->no_autorepeat) |
303 | __set_bit(EV_REP, input->evbit); | 271 | __set_bit(EV_REP, input->evbit); |
304 | 272 | ||
305 | error = clk_prepare_enable(keypad->pclk); | 273 | matrix_keypad_build_keymap(plat->keymap_data, SKE_KEYPAD_ROW_SHIFT, |
306 | if (error) { | 274 | input->keycode, input->keybit); |
307 | dev_err(&pdev->dev, "Failed to prepare/enable pclk\n"); | ||
308 | goto err_clk; | ||
309 | } | ||
310 | |||
311 | error = clk_prepare_enable(keypad->clk); | ||
312 | if (error) { | ||
313 | dev_err(&pdev->dev, "Failed to prepare/enable clk\n"); | ||
314 | goto err_pclk_disable; | ||
315 | } | ||
316 | 275 | ||
276 | clk_enable(keypad->clk); | ||
317 | 277 | ||
318 | /* go through board initialization helpers */ | 278 | /* go through board initialization helpers */ |
319 | if (keypad->board->init) | 279 | if (keypad->board->init) |
@@ -349,13 +309,8 @@ static int __init ske_keypad_probe(struct platform_device *pdev) | |||
349 | err_free_irq: | 309 | err_free_irq: |
350 | free_irq(keypad->irq, keypad); | 310 | free_irq(keypad->irq, keypad); |
351 | err_clk_disable: | 311 | err_clk_disable: |
352 | clk_disable_unprepare(keypad->clk); | 312 | clk_disable(keypad->clk); |
353 | err_pclk_disable: | ||
354 | clk_disable_unprepare(keypad->pclk); | ||
355 | err_clk: | ||
356 | clk_put(keypad->clk); | 313 | clk_put(keypad->clk); |
357 | err_pclk: | ||
358 | clk_put(keypad->pclk); | ||
359 | err_iounmap: | 314 | err_iounmap: |
360 | iounmap(keypad->reg_base); | 315 | iounmap(keypad->reg_base); |
361 | err_free_mem_region: | 316 | err_free_mem_region: |
@@ -366,7 +321,7 @@ err_free_mem: | |||
366 | return error; | 321 | return error; |
367 | } | 322 | } |
368 | 323 | ||
369 | static int ske_keypad_remove(struct platform_device *pdev) | 324 | static int __devexit ske_keypad_remove(struct platform_device *pdev) |
370 | { | 325 | { |
371 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | 326 | struct ske_keypad *keypad = platform_get_drvdata(pdev); |
372 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 327 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -375,7 +330,7 @@ static int ske_keypad_remove(struct platform_device *pdev) | |||
375 | 330 | ||
376 | input_unregister_device(keypad->input); | 331 | input_unregister_device(keypad->input); |
377 | 332 | ||
378 | clk_disable_unprepare(keypad->clk); | 333 | clk_disable(keypad->clk); |
379 | clk_put(keypad->clk); | 334 | clk_put(keypad->clk); |
380 | 335 | ||
381 | if (keypad->board->exit) | 336 | if (keypad->board->exit) |
@@ -388,7 +343,7 @@ static int ske_keypad_remove(struct platform_device *pdev) | |||
388 | return 0; | 343 | return 0; |
389 | } | 344 | } |
390 | 345 | ||
391 | #ifdef CONFIG_PM_SLEEP | 346 | #ifdef CONFIG_PM |
392 | static int ske_keypad_suspend(struct device *dev) | 347 | static int ske_keypad_suspend(struct device *dev) |
393 | { | 348 | { |
394 | struct platform_device *pdev = to_platform_device(dev); | 349 | struct platform_device *pdev = to_platform_device(dev); |
@@ -416,18 +371,23 @@ static int ske_keypad_resume(struct device *dev) | |||
416 | 371 | ||
417 | return 0; | 372 | return 0; |
418 | } | 373 | } |
419 | #endif | ||
420 | 374 | ||
421 | static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops, | 375 | static const struct dev_pm_ops ske_keypad_dev_pm_ops = { |
422 | ske_keypad_suspend, ske_keypad_resume); | 376 | .suspend = ske_keypad_suspend, |
377 | .resume = ske_keypad_resume, | ||
378 | }; | ||
379 | #endif | ||
423 | 380 | ||
424 | static struct platform_driver ske_keypad_driver = { | 381 | struct platform_driver ske_keypad_driver = { |
425 | .driver = { | 382 | .driver = { |
426 | .name = "nmk-ske-keypad", | 383 | .name = "nmk-ske-keypad", |
427 | .owner = THIS_MODULE, | 384 | .owner = THIS_MODULE, |
385 | #ifdef CONFIG_PM | ||
428 | .pm = &ske_keypad_dev_pm_ops, | 386 | .pm = &ske_keypad_dev_pm_ops, |
387 | #endif | ||
429 | }, | 388 | }, |
430 | .remove = ske_keypad_remove, | 389 | .probe = ske_keypad_probe, |
390 | .remove = __devexit_p(ske_keypad_remove), | ||
431 | }; | 391 | }; |
432 | 392 | ||
433 | static int __init ske_keypad_init(void) | 393 | static int __init ske_keypad_init(void) |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index d0d5226d9cd..33d0bdc837c 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -35,9 +35,13 @@ | |||
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/gpio.h> | 38 | #include <mach/gpio.h> |
39 | #include <linux/platform_data/gpio-omap.h> | 39 | #include <plat/keypad.h> |
40 | #include <linux/platform_data/keypad-omap.h> | 40 | #include <plat/menelaus.h> |
41 | #include <asm/irq.h> | ||
42 | #include <mach/hardware.h> | ||
43 | #include <asm/io.h> | ||
44 | #include <plat/mux.h> | ||
41 | 45 | ||
42 | #undef NEW_BOARD_LEARNING_MODE | 46 | #undef NEW_BOARD_LEARNING_MODE |
43 | 47 | ||
@@ -57,7 +61,6 @@ struct omap_kp { | |||
57 | unsigned int cols; | 61 | unsigned int cols; |
58 | unsigned long delay; | 62 | unsigned long delay; |
59 | unsigned int debounce; | 63 | unsigned int debounce; |
60 | unsigned short keymap[]; | ||
61 | }; | 64 | }; |
62 | 65 | ||
63 | static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); | 66 | static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); |
@@ -92,8 +95,28 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp) | |||
92 | 95 | ||
93 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) | 96 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) |
94 | { | 97 | { |
98 | struct omap_kp *omap_kp = dev_id; | ||
99 | |||
95 | /* disable keyboard interrupt and schedule for handling */ | 100 | /* disable keyboard interrupt and schedule for handling */ |
96 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 101 | if (cpu_is_omap24xx()) { |
102 | int i; | ||
103 | |||
104 | for (i = 0; i < omap_kp->rows; i++) { | ||
105 | int gpio_irq = gpio_to_irq(row_gpios[i]); | ||
106 | /* | ||
107 | * The interrupt which we're currently handling should | ||
108 | * be disabled _nosync() to avoid deadlocks waiting | ||
109 | * for this handler to complete. All others should | ||
110 | * be disabled the regular way for SMP safety. | ||
111 | */ | ||
112 | if (gpio_irq == irq) | ||
113 | disable_irq_nosync(gpio_irq); | ||
114 | else | ||
115 | disable_irq(gpio_irq); | ||
116 | } | ||
117 | } else | ||
118 | /* disable keyboard interrupt and schedule for handling */ | ||
119 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
97 | 120 | ||
98 | tasklet_schedule(&kp_tasklet); | 121 | tasklet_schedule(&kp_tasklet); |
99 | 122 | ||
@@ -109,22 +132,33 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state) | |||
109 | { | 132 | { |
110 | int col = 0; | 133 | int col = 0; |
111 | 134 | ||
112 | /* disable keyboard interrupt and schedule for handling */ | ||
113 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
114 | |||
115 | /* read the keypad status */ | 135 | /* read the keypad status */ |
116 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 136 | if (cpu_is_omap24xx()) { |
117 | for (col = 0; col < omap_kp->cols; col++) { | 137 | /* read the keypad status */ |
118 | omap_writew(~(1 << col) & 0xff, | 138 | for (col = 0; col < omap_kp->cols; col++) { |
119 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 139 | set_col_gpio_val(omap_kp, ~(1 << col)); |
140 | state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff; | ||
141 | } | ||
142 | set_col_gpio_val(omap_kp, 0); | ||
120 | 143 | ||
121 | udelay(omap_kp->delay); | 144 | } else { |
145 | /* disable keyboard interrupt and schedule for handling */ | ||
146 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
122 | 147 | ||
123 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + | 148 | /* read the keypad status */ |
124 | OMAP_MPUIO_KBR_LATCH) & 0xff; | 149 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); |
150 | for (col = 0; col < omap_kp->cols; col++) { | ||
151 | omap_writew(~(1 << col) & 0xff, | ||
152 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
153 | |||
154 | udelay(omap_kp->delay); | ||
155 | |||
156 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + | ||
157 | OMAP_MPUIO_KBR_LATCH) & 0xff; | ||
158 | } | ||
159 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
160 | udelay(2); | ||
125 | } | 161 | } |
126 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
127 | udelay(2); | ||
128 | } | 162 | } |
129 | 163 | ||
130 | static void omap_kp_tasklet(unsigned long data) | 164 | static void omap_kp_tasklet(unsigned long data) |
@@ -179,7 +213,7 @@ static void omap_kp_tasklet(unsigned long data) | |||
179 | memcpy(keypad_state, new_state, sizeof(keypad_state)); | 213 | memcpy(keypad_state, new_state, sizeof(keypad_state)); |
180 | 214 | ||
181 | if (key_down) { | 215 | if (key_down) { |
182 | int delay = HZ / 20; | 216 | int delay = HZ / 20; |
183 | /* some key is pressed - keep irq disabled and use timer | 217 | /* some key is pressed - keep irq disabled and use timer |
184 | * to poll the keypad */ | 218 | * to poll the keypad */ |
185 | if (spurious) | 219 | if (spurious) |
@@ -187,8 +221,14 @@ static void omap_kp_tasklet(unsigned long data) | |||
187 | mod_timer(&omap_kp_data->timer, jiffies + delay); | 221 | mod_timer(&omap_kp_data->timer, jiffies + delay); |
188 | } else { | 222 | } else { |
189 | /* enable interrupts */ | 223 | /* enable interrupts */ |
190 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 224 | if (cpu_is_omap24xx()) { |
191 | kp_cur_group = -1; | 225 | int i; |
226 | for (i = 0; i < omap_kp_data->rows; i++) | ||
227 | enable_irq(gpio_to_irq(row_gpios[i])); | ||
228 | } else { | ||
229 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
230 | kp_cur_group = -1; | ||
231 | } | ||
192 | } | 232 | } |
193 | } | 233 | } |
194 | 234 | ||
@@ -201,7 +241,6 @@ static ssize_t omap_kp_enable_show(struct device *dev, | |||
201 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, | 241 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, |
202 | const char *buf, size_t count) | 242 | const char *buf, size_t count) |
203 | { | 243 | { |
204 | struct omap_kp *omap_kp = dev_get_drvdata(dev); | ||
205 | int state; | 244 | int state; |
206 | 245 | ||
207 | if (sscanf(buf, "%u", &state) != 1) | 246 | if (sscanf(buf, "%u", &state) != 1) |
@@ -213,9 +252,9 @@ static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute | |||
213 | mutex_lock(&kp_enable_mutex); | 252 | mutex_lock(&kp_enable_mutex); |
214 | if (state != kp_enable) { | 253 | if (state != kp_enable) { |
215 | if (state) | 254 | if (state) |
216 | enable_irq(omap_kp->irq); | 255 | enable_irq(INT_KEYBOARD); |
217 | else | 256 | else |
218 | disable_irq(omap_kp->irq); | 257 | disable_irq(INT_KEYBOARD); |
219 | kp_enable = state; | 258 | kp_enable = state; |
220 | } | 259 | } |
221 | mutex_unlock(&kp_enable_mutex); | 260 | mutex_unlock(&kp_enable_mutex); |
@@ -244,12 +283,12 @@ static int omap_kp_resume(struct platform_device *dev) | |||
244 | #define omap_kp_resume NULL | 283 | #define omap_kp_resume NULL |
245 | #endif | 284 | #endif |
246 | 285 | ||
247 | static int omap_kp_probe(struct platform_device *pdev) | 286 | static int __devinit omap_kp_probe(struct platform_device *pdev) |
248 | { | 287 | { |
249 | struct omap_kp *omap_kp; | 288 | struct omap_kp *omap_kp; |
250 | struct input_dev *input_dev; | 289 | struct input_dev *input_dev; |
251 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; | 290 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; |
252 | int i, col_idx, row_idx, ret; | 291 | int i, col_idx, row_idx, irq_idx, ret; |
253 | unsigned int row_shift, keycodemax; | 292 | unsigned int row_shift, keycodemax; |
254 | 293 | ||
255 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { | 294 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { |
@@ -274,7 +313,15 @@ static int omap_kp_probe(struct platform_device *pdev) | |||
274 | omap_kp->input = input_dev; | 313 | omap_kp->input = input_dev; |
275 | 314 | ||
276 | /* Disable the interrupt for the MPUIO keyboard */ | 315 | /* Disable the interrupt for the MPUIO keyboard */ |
277 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 316 | if (!cpu_is_omap24xx()) |
317 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
318 | |||
319 | input_dev->keycode = &omap_kp[1]; | ||
320 | input_dev->keycodesize = sizeof(unsigned short); | ||
321 | input_dev->keycodemax = keycodemax; | ||
322 | |||
323 | if (pdata->rep) | ||
324 | __set_bit(EV_REP, input_dev->evbit); | ||
278 | 325 | ||
279 | if (pdata->delay) | 326 | if (pdata->delay) |
280 | omap_kp->delay = pdata->delay; | 327 | omap_kp->delay = pdata->delay; |
@@ -287,8 +334,31 @@ static int omap_kp_probe(struct platform_device *pdev) | |||
287 | omap_kp->rows = pdata->rows; | 334 | omap_kp->rows = pdata->rows; |
288 | omap_kp->cols = pdata->cols; | 335 | omap_kp->cols = pdata->cols; |
289 | 336 | ||
290 | col_idx = 0; | 337 | if (cpu_is_omap24xx()) { |
291 | row_idx = 0; | 338 | /* Cols: outputs */ |
339 | for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { | ||
340 | if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) { | ||
341 | printk(KERN_ERR "Failed to request" | ||
342 | "GPIO%d for keypad\n", | ||
343 | col_gpios[col_idx]); | ||
344 | goto err1; | ||
345 | } | ||
346 | gpio_direction_output(col_gpios[col_idx], 0); | ||
347 | } | ||
348 | /* Rows: inputs */ | ||
349 | for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { | ||
350 | if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) { | ||
351 | printk(KERN_ERR "Failed to request" | ||
352 | "GPIO%d for keypad\n", | ||
353 | row_gpios[row_idx]); | ||
354 | goto err2; | ||
355 | } | ||
356 | gpio_direction_input(row_gpios[row_idx]); | ||
357 | } | ||
358 | } else { | ||
359 | col_idx = 0; | ||
360 | row_idx = 0; | ||
361 | } | ||
292 | 362 | ||
293 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); | 363 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); |
294 | 364 | ||
@@ -301,6 +371,9 @@ static int omap_kp_probe(struct platform_device *pdev) | |||
301 | goto err2; | 371 | goto err2; |
302 | 372 | ||
303 | /* setup input device */ | 373 | /* setup input device */ |
374 | __set_bit(EV_KEY, input_dev->evbit); | ||
375 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | ||
376 | input_dev->keycode, input_dev->keybit); | ||
304 | input_dev->name = "omap-keypad"; | 377 | input_dev->name = "omap-keypad"; |
305 | input_dev->phys = "omap-keypad/input0"; | 378 | input_dev->phys = "omap-keypad/input0"; |
306 | input_dev->dev.parent = &pdev->dev; | 379 | input_dev->dev.parent = &pdev->dev; |
@@ -310,15 +383,6 @@ static int omap_kp_probe(struct platform_device *pdev) | |||
310 | input_dev->id.product = 0x0001; | 383 | input_dev->id.product = 0x0001; |
311 | input_dev->id.version = 0x0100; | 384 | input_dev->id.version = 0x0100; |
312 | 385 | ||
313 | if (pdata->rep) | ||
314 | __set_bit(EV_REP, input_dev->evbit); | ||
315 | |||
316 | ret = matrix_keypad_build_keymap(pdata->keymap_data, NULL, | ||
317 | pdata->rows, pdata->cols, | ||
318 | omap_kp->keymap, input_dev); | ||
319 | if (ret < 0) | ||
320 | goto err3; | ||
321 | |||
322 | ret = input_register_device(omap_kp->input); | 386 | ret = input_register_device(omap_kp->input); |
323 | if (ret < 0) { | 387 | if (ret < 0) { |
324 | printk(KERN_ERR "Unable to register omap-keypad input device\n"); | 388 | printk(KERN_ERR "Unable to register omap-keypad input device\n"); |
@@ -330,25 +394,37 @@ static int omap_kp_probe(struct platform_device *pdev) | |||
330 | 394 | ||
331 | /* scan current status and enable interrupt */ | 395 | /* scan current status and enable interrupt */ |
332 | omap_kp_scan_keypad(omap_kp, keypad_state); | 396 | omap_kp_scan_keypad(omap_kp, keypad_state); |
333 | omap_kp->irq = platform_get_irq(pdev, 0); | 397 | if (!cpu_is_omap24xx()) { |
334 | if (omap_kp->irq >= 0) { | 398 | omap_kp->irq = platform_get_irq(pdev, 0); |
335 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, | 399 | if (omap_kp->irq >= 0) { |
336 | "omap-keypad", omap_kp) < 0) | 400 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, |
337 | goto err4; | 401 | "omap-keypad", omap_kp) < 0) |
402 | goto err4; | ||
403 | } | ||
404 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
405 | } else { | ||
406 | for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) { | ||
407 | if (request_irq(gpio_to_irq(row_gpios[irq_idx]), | ||
408 | omap_kp_interrupt, | ||
409 | IRQF_TRIGGER_FALLING, | ||
410 | "omap-keypad", omap_kp) < 0) | ||
411 | goto err5; | ||
412 | } | ||
338 | } | 413 | } |
339 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
340 | |||
341 | return 0; | 414 | return 0; |
342 | 415 | err5: | |
416 | for (i = irq_idx - 1; i >=0; i--) | ||
417 | free_irq(row_gpios[i], omap_kp); | ||
343 | err4: | 418 | err4: |
344 | input_unregister_device(omap_kp->input); | 419 | input_unregister_device(omap_kp->input); |
345 | input_dev = NULL; | 420 | input_dev = NULL; |
346 | err3: | 421 | err3: |
347 | device_remove_file(&pdev->dev, &dev_attr_enable); | 422 | device_remove_file(&pdev->dev, &dev_attr_enable); |
348 | err2: | 423 | err2: |
349 | for (i = row_idx - 1; i >= 0; i--) | 424 | for (i = row_idx - 1; i >=0; i--) |
350 | gpio_free(row_gpios[i]); | 425 | gpio_free(row_gpios[i]); |
351 | for (i = col_idx - 1; i >= 0; i--) | 426 | err1: |
427 | for (i = col_idx - 1; i >=0; i--) | ||
352 | gpio_free(col_gpios[i]); | 428 | gpio_free(col_gpios[i]); |
353 | 429 | ||
354 | kfree(omap_kp); | 430 | kfree(omap_kp); |
@@ -357,14 +433,24 @@ err2: | |||
357 | return -EINVAL; | 433 | return -EINVAL; |
358 | } | 434 | } |
359 | 435 | ||
360 | static int omap_kp_remove(struct platform_device *pdev) | 436 | static int __devexit omap_kp_remove(struct platform_device *pdev) |
361 | { | 437 | { |
362 | struct omap_kp *omap_kp = platform_get_drvdata(pdev); | 438 | struct omap_kp *omap_kp = platform_get_drvdata(pdev); |
363 | 439 | ||
364 | /* disable keypad interrupt handling */ | 440 | /* disable keypad interrupt handling */ |
365 | tasklet_disable(&kp_tasklet); | 441 | tasklet_disable(&kp_tasklet); |
366 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 442 | if (cpu_is_omap24xx()) { |
367 | free_irq(omap_kp->irq, omap_kp); | 443 | int i; |
444 | for (i = 0; i < omap_kp->cols; i++) | ||
445 | gpio_free(col_gpios[i]); | ||
446 | for (i = 0; i < omap_kp->rows; i++) { | ||
447 | gpio_free(row_gpios[i]); | ||
448 | free_irq(gpio_to_irq(row_gpios[i]), omap_kp); | ||
449 | } | ||
450 | } else { | ||
451 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
452 | free_irq(omap_kp->irq, omap_kp); | ||
453 | } | ||
368 | 454 | ||
369 | del_timer_sync(&omap_kp->timer); | 455 | del_timer_sync(&omap_kp->timer); |
370 | tasklet_kill(&kp_tasklet); | 456 | tasklet_kill(&kp_tasklet); |
@@ -379,7 +465,7 @@ static int omap_kp_remove(struct platform_device *pdev) | |||
379 | 465 | ||
380 | static struct platform_driver omap_kp_driver = { | 466 | static struct platform_driver omap_kp_driver = { |
381 | .probe = omap_kp_probe, | 467 | .probe = omap_kp_probe, |
382 | .remove = omap_kp_remove, | 468 | .remove = __devexit_p(omap_kp_remove), |
383 | .suspend = omap_kp_suspend, | 469 | .suspend = omap_kp_suspend, |
384 | .resume = omap_kp_resume, | 470 | .resume = omap_kp_resume, |
385 | .driver = { | 471 | .driver = { |
@@ -387,7 +473,20 @@ static struct platform_driver omap_kp_driver = { | |||
387 | .owner = THIS_MODULE, | 473 | .owner = THIS_MODULE, |
388 | }, | 474 | }, |
389 | }; | 475 | }; |
390 | module_platform_driver(omap_kp_driver); | 476 | |
477 | static int __init omap_kp_init(void) | ||
478 | { | ||
479 | printk(KERN_INFO "OMAP Keypad Driver\n"); | ||
480 | return platform_driver_register(&omap_kp_driver); | ||
481 | } | ||
482 | |||
483 | static void __exit omap_kp_exit(void) | ||
484 | { | ||
485 | platform_driver_unregister(&omap_kp_driver); | ||
486 | } | ||
487 | |||
488 | module_init(omap_kp_init); | ||
489 | module_exit(omap_kp_exit); | ||
391 | 490 | ||
392 | MODULE_AUTHOR("Timo Teräs"); | 491 | MODULE_AUTHOR("Timo Teräs"); |
393 | MODULE_DESCRIPTION("OMAP Keypad Driver"); | 492 | MODULE_DESCRIPTION("OMAP Keypad Driver"); |
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index e25b022692c..c51a3c4a7fe 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c | |||
@@ -27,12 +27,11 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/input.h> | 30 | #include <linux/input.h> |
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
33 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
34 | 33 | ||
35 | #include <linux/platform_data/omap4-keypad.h> | 34 | #include <plat/omap4-keypad.h> |
36 | 35 | ||
37 | /* OMAP4 registers */ | 36 | /* OMAP4 registers */ |
38 | #define OMAP4_KBD_REVISION 0x00 | 37 | #define OMAP4_KBD_REVISION 0x00 |
@@ -69,53 +68,19 @@ | |||
69 | 68 | ||
70 | #define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF | 69 | #define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF |
71 | 70 | ||
72 | enum { | ||
73 | KBD_REVISION_OMAP4 = 0, | ||
74 | KBD_REVISION_OMAP5, | ||
75 | }; | ||
76 | |||
77 | struct omap4_keypad { | 71 | struct omap4_keypad { |
78 | struct input_dev *input; | 72 | struct input_dev *input; |
79 | 73 | ||
80 | void __iomem *base; | 74 | void __iomem *base; |
81 | unsigned int irq; | 75 | int irq; |
82 | 76 | ||
83 | unsigned int rows; | 77 | unsigned int rows; |
84 | unsigned int cols; | 78 | unsigned int cols; |
85 | u32 reg_offset; | ||
86 | u32 irqreg_offset; | ||
87 | unsigned int row_shift; | 79 | unsigned int row_shift; |
88 | bool no_autorepeat; | ||
89 | unsigned char key_state[8]; | 80 | unsigned char key_state[8]; |
90 | unsigned short *keymap; | 81 | unsigned short keymap[]; |
91 | }; | 82 | }; |
92 | 83 | ||
93 | static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset) | ||
94 | { | ||
95 | return __raw_readl(keypad_data->base + | ||
96 | keypad_data->reg_offset + offset); | ||
97 | } | ||
98 | |||
99 | static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value) | ||
100 | { | ||
101 | __raw_writel(value, | ||
102 | keypad_data->base + keypad_data->reg_offset + offset); | ||
103 | } | ||
104 | |||
105 | static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset) | ||
106 | { | ||
107 | return __raw_readl(keypad_data->base + | ||
108 | keypad_data->irqreg_offset + offset); | ||
109 | } | ||
110 | |||
111 | static void kbd_write_irqreg(struct omap4_keypad *keypad_data, | ||
112 | u32 offset, u32 value) | ||
113 | { | ||
114 | __raw_writel(value, | ||
115 | keypad_data->base + keypad_data->irqreg_offset + offset); | ||
116 | } | ||
117 | |||
118 | |||
119 | /* Interrupt handler */ | 84 | /* Interrupt handler */ |
120 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | 85 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) |
121 | { | 86 | { |
@@ -126,11 +91,12 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | |||
126 | u32 *new_state = (u32 *) key_state; | 91 | u32 *new_state = (u32 *) key_state; |
127 | 92 | ||
128 | /* Disable interrupts */ | 93 | /* Disable interrupts */ |
129 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | 94 | __raw_writel(OMAP4_VAL_IRQDISABLE, |
130 | OMAP4_VAL_IRQDISABLE); | 95 | keypad_data->base + OMAP4_KBD_IRQENABLE); |
131 | 96 | ||
132 | *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0); | 97 | *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0); |
133 | *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32); | 98 | *(new_state + 1) = __raw_readl(keypad_data->base |
99 | + OMAP4_KBD_FULLCODE63_32); | ||
134 | 100 | ||
135 | for (row = 0; row < keypad_data->rows; row++) { | 101 | for (row = 0; row < keypad_data->rows; row++) { |
136 | changed = key_state[row] ^ keypad_data->key_state[row]; | 102 | changed = key_state[row] ^ keypad_data->key_state[row]; |
@@ -155,13 +121,12 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | |||
155 | sizeof(keypad_data->key_state)); | 121 | sizeof(keypad_data->key_state)); |
156 | 122 | ||
157 | /* clear pending interrupts */ | 123 | /* clear pending interrupts */ |
158 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, | 124 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), |
159 | kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); | 125 | keypad_data->base + OMAP4_KBD_IRQSTATUS); |
160 | 126 | ||
161 | /* enable interrupts */ | 127 | /* enable interrupts */ |
162 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | 128 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, |
163 | OMAP4_DEF_IRQENABLE_EVENTEN | | 129 | keypad_data->base + OMAP4_KBD_IRQENABLE); |
164 | OMAP4_DEF_IRQENABLE_LONGKEY); | ||
165 | 130 | ||
166 | return IRQ_HANDLED; | 131 | return IRQ_HANDLED; |
167 | } | 132 | } |
@@ -174,17 +139,16 @@ static int omap4_keypad_open(struct input_dev *input) | |||
174 | 139 | ||
175 | disable_irq(keypad_data->irq); | 140 | disable_irq(keypad_data->irq); |
176 | 141 | ||
177 | kbd_writel(keypad_data, OMAP4_KBD_CTRL, | 142 | __raw_writel(OMAP4_VAL_FUNCTIONALCFG, |
178 | OMAP4_VAL_FUNCTIONALCFG); | 143 | keypad_data->base + OMAP4_KBD_CTRL); |
179 | kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME, | 144 | __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, |
180 | OMAP4_VAL_DEBOUNCINGTIME); | 145 | keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); |
181 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, | 146 | __raw_writel(OMAP4_VAL_IRQDISABLE, |
182 | OMAP4_VAL_IRQDISABLE); | 147 | keypad_data->base + OMAP4_KBD_IRQSTATUS); |
183 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | 148 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, |
184 | OMAP4_DEF_IRQENABLE_EVENTEN | | 149 | keypad_data->base + OMAP4_KBD_IRQENABLE); |
185 | OMAP4_DEF_IRQENABLE_LONGKEY); | 150 | __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA, |
186 | kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE, | 151 | keypad_data->base + OMAP4_KBD_WAKEUPENABLE); |
187 | OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA); | ||
188 | 152 | ||
189 | enable_irq(keypad_data->irq); | 153 | enable_irq(keypad_data->irq); |
190 | 154 | ||
@@ -198,63 +162,36 @@ static void omap4_keypad_close(struct input_dev *input) | |||
198 | disable_irq(keypad_data->irq); | 162 | disable_irq(keypad_data->irq); |
199 | 163 | ||
200 | /* Disable interrupts */ | 164 | /* Disable interrupts */ |
201 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | 165 | __raw_writel(OMAP4_VAL_IRQDISABLE, |
202 | OMAP4_VAL_IRQDISABLE); | 166 | keypad_data->base + OMAP4_KBD_IRQENABLE); |
203 | 167 | ||
204 | /* clear pending interrupts */ | 168 | /* clear pending interrupts */ |
205 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, | 169 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), |
206 | kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); | 170 | keypad_data->base + OMAP4_KBD_IRQSTATUS); |
207 | 171 | ||
208 | enable_irq(keypad_data->irq); | 172 | enable_irq(keypad_data->irq); |
209 | 173 | ||
210 | pm_runtime_put_sync(input->dev.parent); | 174 | pm_runtime_put_sync(input->dev.parent); |
211 | } | 175 | } |
212 | 176 | ||
213 | #ifdef CONFIG_OF | 177 | static int __devinit omap4_keypad_probe(struct platform_device *pdev) |
214 | static int omap4_keypad_parse_dt(struct device *dev, | ||
215 | struct omap4_keypad *keypad_data) | ||
216 | { | ||
217 | struct device_node *np = dev->of_node; | ||
218 | |||
219 | if (!np) { | ||
220 | dev_err(dev, "missing DT data"); | ||
221 | return -EINVAL; | ||
222 | } | ||
223 | |||
224 | of_property_read_u32(np, "keypad,num-rows", &keypad_data->rows); | ||
225 | of_property_read_u32(np, "keypad,num-columns", &keypad_data->cols); | ||
226 | if (!keypad_data->rows || !keypad_data->cols) { | ||
227 | dev_err(dev, "number of keypad rows/columns not specified\n"); | ||
228 | return -EINVAL; | ||
229 | } | ||
230 | |||
231 | if (of_get_property(np, "linux,input-no-autorepeat", NULL)) | ||
232 | keypad_data->no_autorepeat = true; | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | #else | ||
237 | static inline int omap4_keypad_parse_dt(struct device *dev, | ||
238 | struct omap4_keypad *keypad_data) | ||
239 | { | ||
240 | return -ENOSYS; | ||
241 | } | ||
242 | #endif | ||
243 | |||
244 | static int omap4_keypad_probe(struct platform_device *pdev) | ||
245 | { | 178 | { |
246 | const struct omap4_keypad_platform_data *pdata = | 179 | const struct omap4_keypad_platform_data *pdata; |
247 | dev_get_platdata(&pdev->dev); | ||
248 | const struct matrix_keymap_data *keymap_data = | ||
249 | pdata ? pdata->keymap_data : NULL; | ||
250 | struct omap4_keypad *keypad_data; | 180 | struct omap4_keypad *keypad_data; |
251 | struct input_dev *input_dev; | 181 | struct input_dev *input_dev; |
252 | struct resource *res; | 182 | struct resource *res; |
253 | unsigned int max_keys; | 183 | resource_size_t size; |
254 | int rev; | 184 | unsigned int row_shift, max_keys; |
255 | int irq; | 185 | int irq; |
256 | int error; | 186 | int error; |
257 | 187 | ||
188 | /* platform data */ | ||
189 | pdata = pdev->dev.platform_data; | ||
190 | if (!pdata) { | ||
191 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | |||
258 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 195 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
259 | if (!res) { | 196 | if (!res) { |
260 | dev_err(&pdev->dev, "no base address specified\n"); | 197 | dev_err(&pdev->dev, "no base address specified\n"); |
@@ -267,24 +204,25 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
267 | return -EINVAL; | 204 | return -EINVAL; |
268 | } | 205 | } |
269 | 206 | ||
270 | keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); | 207 | if (!pdata->keymap_data) { |
208 | dev_err(&pdev->dev, "no keymap data defined\n"); | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | |||
212 | row_shift = get_count_order(pdata->cols); | ||
213 | max_keys = pdata->rows << row_shift; | ||
214 | |||
215 | keypad_data = kzalloc(sizeof(struct omap4_keypad) + | ||
216 | max_keys * sizeof(keypad_data->keymap[0]), | ||
217 | GFP_KERNEL); | ||
271 | if (!keypad_data) { | 218 | if (!keypad_data) { |
272 | dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); | 219 | dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); |
273 | return -ENOMEM; | 220 | return -ENOMEM; |
274 | } | 221 | } |
275 | 222 | ||
276 | keypad_data->irq = irq; | 223 | size = resource_size(res); |
277 | 224 | ||
278 | if (pdata) { | 225 | res = request_mem_region(res->start, size, pdev->name); |
279 | keypad_data->rows = pdata->rows; | ||
280 | keypad_data->cols = pdata->cols; | ||
281 | } else { | ||
282 | error = omap4_keypad_parse_dt(&pdev->dev, keypad_data); | ||
283 | if (error) | ||
284 | return error; | ||
285 | } | ||
286 | |||
287 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
288 | if (!res) { | 226 | if (!res) { |
289 | dev_err(&pdev->dev, "can't request mem region\n"); | 227 | dev_err(&pdev->dev, "can't request mem region\n"); |
290 | error = -EBUSY; | 228 | error = -EBUSY; |
@@ -298,41 +236,16 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
298 | goto err_release_mem; | 236 | goto err_release_mem; |
299 | } | 237 | } |
300 | 238 | ||
301 | 239 | keypad_data->irq = irq; | |
302 | /* | 240 | keypad_data->row_shift = row_shift; |
303 | * Enable clocks for the keypad module so that we can read | 241 | keypad_data->rows = pdata->rows; |
304 | * revision register. | 242 | keypad_data->cols = pdata->cols; |
305 | */ | ||
306 | pm_runtime_enable(&pdev->dev); | ||
307 | error = pm_runtime_get_sync(&pdev->dev); | ||
308 | if (error) { | ||
309 | dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); | ||
310 | goto err_unmap; | ||
311 | } | ||
312 | rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION); | ||
313 | rev &= 0x03 << 30; | ||
314 | rev >>= 30; | ||
315 | switch (rev) { | ||
316 | case KBD_REVISION_OMAP4: | ||
317 | keypad_data->reg_offset = 0x00; | ||
318 | keypad_data->irqreg_offset = 0x00; | ||
319 | break; | ||
320 | case KBD_REVISION_OMAP5: | ||
321 | keypad_data->reg_offset = 0x10; | ||
322 | keypad_data->irqreg_offset = 0x0c; | ||
323 | break; | ||
324 | default: | ||
325 | dev_err(&pdev->dev, | ||
326 | "Keypad reports unsupported revision %d", rev); | ||
327 | error = -EINVAL; | ||
328 | goto err_pm_put_sync; | ||
329 | } | ||
330 | 243 | ||
331 | /* input device allocation */ | 244 | /* input device allocation */ |
332 | keypad_data->input = input_dev = input_allocate_device(); | 245 | keypad_data->input = input_dev = input_allocate_device(); |
333 | if (!input_dev) { | 246 | if (!input_dev) { |
334 | error = -ENOMEM; | 247 | error = -ENOMEM; |
335 | goto err_pm_put_sync; | 248 | goto err_unmap; |
336 | } | 249 | } |
337 | 250 | ||
338 | input_dev->name = pdev->name; | 251 | input_dev->name = pdev->name; |
@@ -345,29 +258,19 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
345 | input_dev->open = omap4_keypad_open; | 258 | input_dev->open = omap4_keypad_open; |
346 | input_dev->close = omap4_keypad_close; | 259 | input_dev->close = omap4_keypad_close; |
347 | 260 | ||
261 | input_dev->keycode = keypad_data->keymap; | ||
262 | input_dev->keycodesize = sizeof(keypad_data->keymap[0]); | ||
263 | input_dev->keycodemax = max_keys; | ||
264 | |||
265 | __set_bit(EV_KEY, input_dev->evbit); | ||
266 | __set_bit(EV_REP, input_dev->evbit); | ||
267 | |||
348 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 268 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
349 | if (!keypad_data->no_autorepeat) | ||
350 | __set_bit(EV_REP, input_dev->evbit); | ||
351 | 269 | ||
352 | input_set_drvdata(input_dev, keypad_data); | 270 | input_set_drvdata(input_dev, keypad_data); |
353 | 271 | ||
354 | keypad_data->row_shift = get_count_order(keypad_data->cols); | 272 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, |
355 | max_keys = keypad_data->rows << keypad_data->row_shift; | 273 | input_dev->keycode, input_dev->keybit); |
356 | keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]), | ||
357 | GFP_KERNEL); | ||
358 | if (!keypad_data->keymap) { | ||
359 | dev_err(&pdev->dev, "Not enough memory for keymap\n"); | ||
360 | error = -ENOMEM; | ||
361 | goto err_free_input; | ||
362 | } | ||
363 | |||
364 | error = matrix_keypad_build_keymap(keymap_data, NULL, | ||
365 | keypad_data->rows, keypad_data->cols, | ||
366 | keypad_data->keymap, input_dev); | ||
367 | if (error) { | ||
368 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
369 | goto err_free_keymap; | ||
370 | } | ||
371 | 274 | ||
372 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, | 275 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, |
373 | IRQF_TRIGGER_RISING, | 276 | IRQF_TRIGGER_RISING, |
@@ -377,7 +280,7 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
377 | goto err_free_input; | 280 | goto err_free_input; |
378 | } | 281 | } |
379 | 282 | ||
380 | pm_runtime_put_sync(&pdev->dev); | 283 | pm_runtime_enable(&pdev->dev); |
381 | 284 | ||
382 | error = input_register_device(keypad_data->input); | 285 | error = input_register_device(keypad_data->input); |
383 | if (error < 0) { | 286 | if (error < 0) { |
@@ -391,22 +294,18 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
391 | err_pm_disable: | 294 | err_pm_disable: |
392 | pm_runtime_disable(&pdev->dev); | 295 | pm_runtime_disable(&pdev->dev); |
393 | free_irq(keypad_data->irq, keypad_data); | 296 | free_irq(keypad_data->irq, keypad_data); |
394 | err_free_keymap: | ||
395 | kfree(keypad_data->keymap); | ||
396 | err_free_input: | 297 | err_free_input: |
397 | input_free_device(input_dev); | 298 | input_free_device(input_dev); |
398 | err_pm_put_sync: | ||
399 | pm_runtime_put_sync(&pdev->dev); | ||
400 | err_unmap: | 299 | err_unmap: |
401 | iounmap(keypad_data->base); | 300 | iounmap(keypad_data->base); |
402 | err_release_mem: | 301 | err_release_mem: |
403 | release_mem_region(res->start, resource_size(res)); | 302 | release_mem_region(res->start, size); |
404 | err_free_keypad: | 303 | err_free_keypad: |
405 | kfree(keypad_data); | 304 | kfree(keypad_data); |
406 | return error; | 305 | return error; |
407 | } | 306 | } |
408 | 307 | ||
409 | static int omap4_keypad_remove(struct platform_device *pdev) | 308 | static int __devexit omap4_keypad_remove(struct platform_device *pdev) |
410 | { | 309 | { |
411 | struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); | 310 | struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); |
412 | struct resource *res; | 311 | struct resource *res; |
@@ -422,32 +321,32 @@ static int omap4_keypad_remove(struct platform_device *pdev) | |||
422 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 321 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
423 | release_mem_region(res->start, resource_size(res)); | 322 | release_mem_region(res->start, resource_size(res)); |
424 | 323 | ||
425 | kfree(keypad_data->keymap); | ||
426 | kfree(keypad_data); | 324 | kfree(keypad_data); |
427 | |||
428 | platform_set_drvdata(pdev, NULL); | 325 | platform_set_drvdata(pdev, NULL); |
429 | 326 | ||
430 | return 0; | 327 | return 0; |
431 | } | 328 | } |
432 | 329 | ||
433 | #ifdef CONFIG_OF | ||
434 | static const struct of_device_id omap_keypad_dt_match[] = { | ||
435 | { .compatible = "ti,omap4-keypad" }, | ||
436 | {}, | ||
437 | }; | ||
438 | MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); | ||
439 | #endif | ||
440 | |||
441 | static struct platform_driver omap4_keypad_driver = { | 330 | static struct platform_driver omap4_keypad_driver = { |
442 | .probe = omap4_keypad_probe, | 331 | .probe = omap4_keypad_probe, |
443 | .remove = omap4_keypad_remove, | 332 | .remove = __devexit_p(omap4_keypad_remove), |
444 | .driver = { | 333 | .driver = { |
445 | .name = "omap4-keypad", | 334 | .name = "omap4-keypad", |
446 | .owner = THIS_MODULE, | 335 | .owner = THIS_MODULE, |
447 | .of_match_table = of_match_ptr(omap_keypad_dt_match), | ||
448 | }, | 336 | }, |
449 | }; | 337 | }; |
450 | module_platform_driver(omap4_keypad_driver); | 338 | |
339 | static int __init omap4_keypad_init(void) | ||
340 | { | ||
341 | return platform_driver_register(&omap4_keypad_driver); | ||
342 | } | ||
343 | module_init(omap4_keypad_init); | ||
344 | |||
345 | static void __exit omap4_keypad_exit(void) | ||
346 | { | ||
347 | platform_driver_unregister(&omap4_keypad_driver); | ||
348 | } | ||
349 | module_exit(omap4_keypad_exit); | ||
451 | 350 | ||
452 | MODULE_AUTHOR("Texas Instruments"); | 351 | MODULE_AUTHOR("Texas Instruments"); |
453 | MODULE_DESCRIPTION("OMAP4 Keypad Driver"); | 352 | MODULE_DESCRIPTION("OMAP4 Keypad Driver"); |
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 7ac5f174c6f..1f1a5563f60 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c | |||
@@ -37,7 +37,7 @@ static irqreturn_t opencores_kbd_isr(int irq, void *dev_id) | |||
37 | return IRQ_HANDLED; | 37 | return IRQ_HANDLED; |
38 | } | 38 | } |
39 | 39 | ||
40 | static int opencores_kbd_probe(struct platform_device *pdev) | 40 | static int __devinit opencores_kbd_probe(struct platform_device *pdev) |
41 | { | 41 | { |
42 | struct input_dev *input; | 42 | struct input_dev *input; |
43 | struct opencores_kbd *opencores_kbd; | 43 | struct opencores_kbd *opencores_kbd; |
@@ -139,7 +139,7 @@ static int opencores_kbd_probe(struct platform_device *pdev) | |||
139 | return error; | 139 | return error; |
140 | } | 140 | } |
141 | 141 | ||
142 | static int opencores_kbd_remove(struct platform_device *pdev) | 142 | static int __devexit opencores_kbd_remove(struct platform_device *pdev) |
143 | { | 143 | { |
144 | struct opencores_kbd *opencores_kbd = platform_get_drvdata(pdev); | 144 | struct opencores_kbd *opencores_kbd = platform_get_drvdata(pdev); |
145 | 145 | ||
@@ -158,12 +158,23 @@ static int opencores_kbd_remove(struct platform_device *pdev) | |||
158 | 158 | ||
159 | static struct platform_driver opencores_kbd_device_driver = { | 159 | static struct platform_driver opencores_kbd_device_driver = { |
160 | .probe = opencores_kbd_probe, | 160 | .probe = opencores_kbd_probe, |
161 | .remove = opencores_kbd_remove, | 161 | .remove = __devexit_p(opencores_kbd_remove), |
162 | .driver = { | 162 | .driver = { |
163 | .name = "opencores-kbd", | 163 | .name = "opencores-kbd", |
164 | }, | 164 | }, |
165 | }; | 165 | }; |
166 | module_platform_driver(opencores_kbd_device_driver); | 166 | |
167 | static int __init opencores_kbd_init(void) | ||
168 | { | ||
169 | return platform_driver_register(&opencores_kbd_device_driver); | ||
170 | } | ||
171 | module_init(opencores_kbd_init); | ||
172 | |||
173 | static void __exit opencores_kbd_exit(void) | ||
174 | { | ||
175 | platform_driver_unregister(&opencores_kbd_device_driver); | ||
176 | } | ||
177 | module_exit(opencores_kbd_exit); | ||
167 | 178 | ||
168 | MODULE_LICENSE("GPL"); | 179 | MODULE_LICENSE("GPL"); |
169 | MODULE_AUTHOR("Javier Herrero <jherrero@hvsistemas.es>"); | 180 | MODULE_AUTHOR("Javier Herrero <jherrero@hvsistemas.es>"); |
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 74339e139d4..e7cc51d0fb3 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c | |||
@@ -397,7 +397,7 @@ static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) | |||
397 | return IRQ_HANDLED; | 397 | return IRQ_HANDLED; |
398 | } | 398 | } |
399 | 399 | ||
400 | static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) | 400 | static int __devinit pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) |
401 | { | 401 | { |
402 | int bits, rc, cycles; | 402 | int bits, rc, cycles; |
403 | u8 scan_val = 0, ctrl_val = 0; | 403 | u8 scan_val = 0, ctrl_val = 0; |
@@ -447,7 +447,7 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) | |||
447 | 447 | ||
448 | } | 448 | } |
449 | 449 | ||
450 | static int pmic8xxx_kp_config_gpio(int gpio_start, int num_gpios, | 450 | static int __devinit pmic8xxx_kp_config_gpio(int gpio_start, int num_gpios, |
451 | struct pmic8xxx_kp *kp, struct pm_gpio *gpio_config) | 451 | struct pmic8xxx_kp *kp, struct pm_gpio *gpio_config) |
452 | { | 452 | { |
453 | int rc, i; | 453 | int rc, i; |
@@ -518,7 +518,7 @@ static void pmic8xxx_kp_close(struct input_dev *dev) | |||
518 | * - set irq edge type. | 518 | * - set irq edge type. |
519 | * - enable the keypad controller. | 519 | * - enable the keypad controller. |
520 | */ | 520 | */ |
521 | static int pmic8xxx_kp_probe(struct platform_device *pdev) | 521 | static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) |
522 | { | 522 | { |
523 | const struct pm8xxx_keypad_platform_data *pdata = | 523 | const struct pm8xxx_keypad_platform_data *pdata = |
524 | dev_get_platdata(&pdev->dev); | 524 | dev_get_platdata(&pdev->dev); |
@@ -626,21 +626,21 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) | |||
626 | kp->input->id.product = 0x0001; | 626 | kp->input->id.product = 0x0001; |
627 | kp->input->id.vendor = 0x0001; | 627 | kp->input->id.vendor = 0x0001; |
628 | 628 | ||
629 | kp->input->evbit[0] = BIT_MASK(EV_KEY); | ||
630 | |||
631 | if (pdata->rep) | ||
632 | __set_bit(EV_REP, kp->input->evbit); | ||
633 | |||
634 | kp->input->keycode = kp->keycodes; | ||
635 | kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; | ||
636 | kp->input->keycodesize = sizeof(kp->keycodes); | ||
629 | kp->input->open = pmic8xxx_kp_open; | 637 | kp->input->open = pmic8xxx_kp_open; |
630 | kp->input->close = pmic8xxx_kp_close; | 638 | kp->input->close = pmic8xxx_kp_close; |
631 | 639 | ||
632 | rc = matrix_keypad_build_keymap(keymap_data, NULL, | 640 | matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, |
633 | PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, | 641 | kp->input->keycode, kp->input->keybit); |
634 | kp->keycodes, kp->input); | ||
635 | if (rc) { | ||
636 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
637 | goto err_get_irq; | ||
638 | } | ||
639 | 642 | ||
640 | if (pdata->rep) | ||
641 | __set_bit(EV_REP, kp->input->evbit); | ||
642 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); | 643 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); |
643 | |||
644 | input_set_drvdata(kp->input, kp); | 644 | input_set_drvdata(kp->input, kp); |
645 | 645 | ||
646 | /* initialize keypad state */ | 646 | /* initialize keypad state */ |
@@ -712,7 +712,7 @@ err_alloc_device: | |||
712 | return rc; | 712 | return rc; |
713 | } | 713 | } |
714 | 714 | ||
715 | static int pmic8xxx_kp_remove(struct platform_device *pdev) | 715 | static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) |
716 | { | 716 | { |
717 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | 717 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); |
718 | 718 | ||
@@ -773,14 +773,25 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, | |||
773 | 773 | ||
774 | static struct platform_driver pmic8xxx_kp_driver = { | 774 | static struct platform_driver pmic8xxx_kp_driver = { |
775 | .probe = pmic8xxx_kp_probe, | 775 | .probe = pmic8xxx_kp_probe, |
776 | .remove = pmic8xxx_kp_remove, | 776 | .remove = __devexit_p(pmic8xxx_kp_remove), |
777 | .driver = { | 777 | .driver = { |
778 | .name = PM8XXX_KEYPAD_DEV_NAME, | 778 | .name = PM8XXX_KEYPAD_DEV_NAME, |
779 | .owner = THIS_MODULE, | 779 | .owner = THIS_MODULE, |
780 | .pm = &pm8xxx_kp_pm_ops, | 780 | .pm = &pm8xxx_kp_pm_ops, |
781 | }, | 781 | }, |
782 | }; | 782 | }; |
783 | module_platform_driver(pmic8xxx_kp_driver); | 783 | |
784 | static int __init pmic8xxx_kp_init(void) | ||
785 | { | ||
786 | return platform_driver_register(&pmic8xxx_kp_driver); | ||
787 | } | ||
788 | module_init(pmic8xxx_kp_init); | ||
789 | |||
790 | static void __exit pmic8xxx_kp_exit(void) | ||
791 | { | ||
792 | platform_driver_unregister(&pmic8xxx_kp_driver); | ||
793 | } | ||
794 | module_exit(pmic8xxx_kp_exit); | ||
784 | 795 | ||
785 | MODULE_LICENSE("GPL v2"); | 796 | MODULE_LICENSE("GPL v2"); |
786 | MODULE_DESCRIPTION("PMIC8XXX keypad driver"); | 797 | MODULE_DESCRIPTION("PMIC8XXX keypad driver"); |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 5330d8fbf6c..4b0ec35259a 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
33 | 33 | ||
34 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
35 | #include <linux/platform_data/keypad-pxa27x.h> | 35 | #include <plat/pxa27x_keypad.h> |
36 | /* | 36 | /* |
37 | * Keypad Controller registers | 37 | * Keypad Controller registers |
38 | */ | 38 | */ |
@@ -311,15 +311,7 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | |||
311 | if (pdata->enable_rotary0 || pdata->enable_rotary1) | 311 | if (pdata->enable_rotary0 || pdata->enable_rotary1) |
312 | pxa27x_keypad_scan_rotary(keypad); | 312 | pxa27x_keypad_scan_rotary(keypad); |
313 | 313 | ||
314 | /* | 314 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; |
315 | * The KPDR_DK only output the key pin level, so it relates to board, | ||
316 | * and low level may be active. | ||
317 | */ | ||
318 | if (pdata->direct_key_low_active) | ||
319 | new_state = ~KPDK_DK(kpdk) & keypad->direct_key_mask; | ||
320 | else | ||
321 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; | ||
322 | |||
323 | bits_changed = keypad->direct_key_state ^ new_state; | 315 | bits_changed = keypad->direct_key_state ^ new_state; |
324 | 316 | ||
325 | if (bits_changed == 0) | 317 | if (bits_changed == 0) |
@@ -368,9 +360,6 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) | |||
368 | unsigned int mask = 0, direct_key_num = 0; | 360 | unsigned int mask = 0, direct_key_num = 0; |
369 | unsigned long kpc = 0; | 361 | unsigned long kpc = 0; |
370 | 362 | ||
371 | /* clear pending interrupt bit */ | ||
372 | keypad_readl(KPC); | ||
373 | |||
374 | /* enable matrix keys with automatic scan */ | 363 | /* enable matrix keys with automatic scan */ |
375 | if (pdata->matrix_key_rows && pdata->matrix_key_cols) { | 364 | if (pdata->matrix_key_rows && pdata->matrix_key_cols) { |
376 | kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; | 365 | kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; |
@@ -394,14 +383,7 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) | |||
394 | if (pdata->direct_key_num > direct_key_num) | 383 | if (pdata->direct_key_num > direct_key_num) |
395 | direct_key_num = pdata->direct_key_num; | 384 | direct_key_num = pdata->direct_key_num; |
396 | 385 | ||
397 | /* | 386 | keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask; |
398 | * Direct keys usage may not start from KP_DKIN0, check the platfrom | ||
399 | * mask data to config the specific. | ||
400 | */ | ||
401 | if (pdata->direct_key_mask) | ||
402 | keypad->direct_key_mask = pdata->direct_key_mask; | ||
403 | else | ||
404 | keypad->direct_key_mask = ((1 << direct_key_num) - 1) & ~mask; | ||
405 | 387 | ||
406 | /* enable direct key */ | 388 | /* enable direct key */ |
407 | if (direct_key_num) | 389 | if (direct_key_num) |
@@ -417,7 +399,7 @@ static int pxa27x_keypad_open(struct input_dev *dev) | |||
417 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); | 399 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); |
418 | 400 | ||
419 | /* Enable unit clock */ | 401 | /* Enable unit clock */ |
420 | clk_prepare_enable(keypad->clk); | 402 | clk_enable(keypad->clk); |
421 | pxa27x_keypad_config(keypad); | 403 | pxa27x_keypad_config(keypad); |
422 | 404 | ||
423 | return 0; | 405 | return 0; |
@@ -428,7 +410,7 @@ static void pxa27x_keypad_close(struct input_dev *dev) | |||
428 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); | 410 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); |
429 | 411 | ||
430 | /* Disable clock unit */ | 412 | /* Disable clock unit */ |
431 | clk_disable_unprepare(keypad->clk); | 413 | clk_disable(keypad->clk); |
432 | } | 414 | } |
433 | 415 | ||
434 | #ifdef CONFIG_PM | 416 | #ifdef CONFIG_PM |
@@ -437,14 +419,10 @@ static int pxa27x_keypad_suspend(struct device *dev) | |||
437 | struct platform_device *pdev = to_platform_device(dev); | 419 | struct platform_device *pdev = to_platform_device(dev); |
438 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 420 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
439 | 421 | ||
440 | /* | 422 | clk_disable(keypad->clk); |
441 | * If the keypad is used a wake up source, clock can not be disabled. | 423 | |
442 | * Or it can not detect the key pressing. | ||
443 | */ | ||
444 | if (device_may_wakeup(&pdev->dev)) | 424 | if (device_may_wakeup(&pdev->dev)) |
445 | enable_irq_wake(keypad->irq); | 425 | enable_irq_wake(keypad->irq); |
446 | else | ||
447 | clk_disable_unprepare(keypad->clk); | ||
448 | 426 | ||
449 | return 0; | 427 | return 0; |
450 | } | 428 | } |
@@ -455,24 +433,19 @@ static int pxa27x_keypad_resume(struct device *dev) | |||
455 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 433 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
456 | struct input_dev *input_dev = keypad->input_dev; | 434 | struct input_dev *input_dev = keypad->input_dev; |
457 | 435 | ||
458 | /* | 436 | if (device_may_wakeup(&pdev->dev)) |
459 | * If the keypad is used as wake up source, the clock is not turned | ||
460 | * off. So do not need configure it again. | ||
461 | */ | ||
462 | if (device_may_wakeup(&pdev->dev)) { | ||
463 | disable_irq_wake(keypad->irq); | 437 | disable_irq_wake(keypad->irq); |
464 | } else { | ||
465 | mutex_lock(&input_dev->mutex); | ||
466 | 438 | ||
467 | if (input_dev->users) { | 439 | mutex_lock(&input_dev->mutex); |
468 | /* Enable unit clock */ | ||
469 | clk_prepare_enable(keypad->clk); | ||
470 | pxa27x_keypad_config(keypad); | ||
471 | } | ||
472 | 440 | ||
473 | mutex_unlock(&input_dev->mutex); | 441 | if (input_dev->users) { |
442 | /* Enable unit clock */ | ||
443 | clk_enable(keypad->clk); | ||
444 | pxa27x_keypad_config(keypad); | ||
474 | } | 445 | } |
475 | 446 | ||
447 | mutex_unlock(&input_dev->mutex); | ||
448 | |||
476 | return 0; | 449 | return 0; |
477 | } | 450 | } |
478 | 451 | ||
@@ -482,7 +455,7 @@ static const struct dev_pm_ops pxa27x_keypad_pm_ops = { | |||
482 | }; | 455 | }; |
483 | #endif | 456 | #endif |
484 | 457 | ||
485 | static int pxa27x_keypad_probe(struct platform_device *pdev) | 458 | static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) |
486 | { | 459 | { |
487 | struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data; | 460 | struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data; |
488 | struct pxa27x_keypad *keypad; | 461 | struct pxa27x_keypad *keypad; |
@@ -562,7 +535,7 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) | |||
562 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | 535 | input_dev->evbit[0] |= BIT_MASK(EV_REL); |
563 | } | 536 | } |
564 | 537 | ||
565 | error = request_irq(irq, pxa27x_keypad_irq_handler, 0, | 538 | error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED, |
566 | pdev->name, keypad); | 539 | pdev->name, keypad); |
567 | if (error) { | 540 | if (error) { |
568 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 541 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
@@ -595,7 +568,7 @@ failed_free: | |||
595 | return error; | 568 | return error; |
596 | } | 569 | } |
597 | 570 | ||
598 | static int pxa27x_keypad_remove(struct platform_device *pdev) | 571 | static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) |
599 | { | 572 | { |
600 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 573 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
601 | struct resource *res; | 574 | struct resource *res; |
@@ -620,7 +593,7 @@ MODULE_ALIAS("platform:pxa27x-keypad"); | |||
620 | 593 | ||
621 | static struct platform_driver pxa27x_keypad_driver = { | 594 | static struct platform_driver pxa27x_keypad_driver = { |
622 | .probe = pxa27x_keypad_probe, | 595 | .probe = pxa27x_keypad_probe, |
623 | .remove = pxa27x_keypad_remove, | 596 | .remove = __devexit_p(pxa27x_keypad_remove), |
624 | .driver = { | 597 | .driver = { |
625 | .name = "pxa27x-keypad", | 598 | .name = "pxa27x-keypad", |
626 | .owner = THIS_MODULE, | 599 | .owner = THIS_MODULE, |
@@ -629,7 +602,19 @@ static struct platform_driver pxa27x_keypad_driver = { | |||
629 | #endif | 602 | #endif |
630 | }, | 603 | }, |
631 | }; | 604 | }; |
632 | module_platform_driver(pxa27x_keypad_driver); | 605 | |
606 | static int __init pxa27x_keypad_init(void) | ||
607 | { | ||
608 | return platform_driver_register(&pxa27x_keypad_driver); | ||
609 | } | ||
610 | |||
611 | static void __exit pxa27x_keypad_exit(void) | ||
612 | { | ||
613 | platform_driver_unregister(&pxa27x_keypad_driver); | ||
614 | } | ||
615 | |||
616 | module_init(pxa27x_keypad_init); | ||
617 | module_exit(pxa27x_keypad_exit); | ||
633 | 618 | ||
634 | MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); | 619 | MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); |
635 | MODULE_LICENSE("GPL"); | 620 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index bcad95be73a..b7123a44b6e 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | 17 | ||
18 | #include <linux/platform_data/keyboard-pxa930_rotary.h> | 18 | #include <mach/pxa930_rotary.h> |
19 | 19 | ||
20 | #define SBCR (0x04) | 20 | #define SBCR (0x04) |
21 | #define ERCR (0x0c) | 21 | #define ERCR (0x0c) |
@@ -82,7 +82,7 @@ static void pxa930_rotary_close(struct input_dev *dev) | |||
82 | clear_sbcr(r); | 82 | clear_sbcr(r); |
83 | } | 83 | } |
84 | 84 | ||
85 | static int pxa930_rotary_probe(struct platform_device *pdev) | 85 | static int __devinit pxa930_rotary_probe(struct platform_device *pdev) |
86 | { | 86 | { |
87 | struct pxa930_rotary_platform_data *pdata = pdev->dev.platform_data; | 87 | struct pxa930_rotary_platform_data *pdata = pdev->dev.platform_data; |
88 | struct pxa930_rotary *r; | 88 | struct pxa930_rotary *r; |
@@ -148,7 +148,7 @@ static int pxa930_rotary_probe(struct platform_device *pdev) | |||
148 | r->input_dev = input_dev; | 148 | r->input_dev = input_dev; |
149 | input_set_drvdata(input_dev, r); | 149 | input_set_drvdata(input_dev, r); |
150 | 150 | ||
151 | err = request_irq(irq, rotary_irq, 0, | 151 | err = request_irq(irq, rotary_irq, IRQF_DISABLED, |
152 | "enhanced rotary", r); | 152 | "enhanced rotary", r); |
153 | if (err) { | 153 | if (err) { |
154 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 154 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
@@ -174,7 +174,7 @@ failed_free: | |||
174 | return err; | 174 | return err; |
175 | } | 175 | } |
176 | 176 | ||
177 | static int pxa930_rotary_remove(struct platform_device *pdev) | 177 | static int __devexit pxa930_rotary_remove(struct platform_device *pdev) |
178 | { | 178 | { |
179 | struct pxa930_rotary *r = platform_get_drvdata(pdev); | 179 | struct pxa930_rotary *r = platform_get_drvdata(pdev); |
180 | 180 | ||
@@ -193,9 +193,20 @@ static struct platform_driver pxa930_rotary_driver = { | |||
193 | .owner = THIS_MODULE, | 193 | .owner = THIS_MODULE, |
194 | }, | 194 | }, |
195 | .probe = pxa930_rotary_probe, | 195 | .probe = pxa930_rotary_probe, |
196 | .remove = pxa930_rotary_remove, | 196 | .remove = __devexit_p(pxa930_rotary_remove), |
197 | }; | 197 | }; |
198 | module_platform_driver(pxa930_rotary_driver); | 198 | |
199 | static int __init pxa930_rotary_init(void) | ||
200 | { | ||
201 | return platform_driver_register(&pxa930_rotary_driver); | ||
202 | } | ||
203 | module_init(pxa930_rotary_init); | ||
204 | |||
205 | static void __exit pxa930_rotary_exit(void) | ||
206 | { | ||
207 | platform_driver_unregister(&pxa930_rotary_driver); | ||
208 | } | ||
209 | module_exit(pxa930_rotary_exit); | ||
199 | 210 | ||
200 | MODULE_LICENSE("GPL"); | 211 | MODULE_LICENSE("GPL"); |
201 | MODULE_DESCRIPTION("Driver for PXA93x Enhanced Rotary Controller"); | 212 | MODULE_DESCRIPTION("Driver for PXA93x Enhanced Rotary Controller"); |
diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index 42b773b3125..b21bf5b876b 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c | |||
@@ -91,7 +91,7 @@ static int qt1070_write(struct i2c_client *client, u8 reg, u8 data) | |||
91 | return ret; | 91 | return ret; |
92 | } | 92 | } |
93 | 93 | ||
94 | static bool qt1070_identify(struct i2c_client *client) | 94 | static bool __devinit qt1070_identify(struct i2c_client *client) |
95 | { | 95 | { |
96 | int id, ver; | 96 | int id, ver; |
97 | 97 | ||
@@ -140,7 +140,7 @@ static irqreturn_t qt1070_interrupt(int irq, void *dev_id) | |||
140 | return IRQ_HANDLED; | 140 | return IRQ_HANDLED; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int qt1070_probe(struct i2c_client *client, | 143 | static int __devinit qt1070_probe(struct i2c_client *client, |
144 | const struct i2c_device_id *id) | 144 | const struct i2c_device_id *id) |
145 | { | 145 | { |
146 | struct qt1070_data *data; | 146 | struct qt1070_data *data; |
@@ -201,8 +201,7 @@ static int qt1070_probe(struct i2c_client *client, | |||
201 | msleep(QT1070_RESET_TIME); | 201 | msleep(QT1070_RESET_TIME); |
202 | 202 | ||
203 | err = request_threaded_irq(client->irq, NULL, qt1070_interrupt, | 203 | err = request_threaded_irq(client->irq, NULL, qt1070_interrupt, |
204 | IRQF_TRIGGER_NONE | IRQF_ONESHOT, | 204 | IRQF_TRIGGER_NONE, client->dev.driver->name, data); |
205 | client->dev.driver->name, data); | ||
206 | if (err) { | 205 | if (err) { |
207 | dev_err(&client->dev, "fail to request irq\n"); | 206 | dev_err(&client->dev, "fail to request irq\n"); |
208 | goto err_free_mem; | 207 | goto err_free_mem; |
@@ -230,7 +229,7 @@ err_free_mem: | |||
230 | return err; | 229 | return err; |
231 | } | 230 | } |
232 | 231 | ||
233 | static int qt1070_remove(struct i2c_client *client) | 232 | static int __devexit qt1070_remove(struct i2c_client *client) |
234 | { | 233 | { |
235 | struct qt1070_data *data = i2c_get_clientdata(client); | 234 | struct qt1070_data *data = i2c_get_clientdata(client); |
236 | 235 | ||
@@ -256,10 +255,20 @@ static struct i2c_driver qt1070_driver = { | |||
256 | }, | 255 | }, |
257 | .id_table = qt1070_id, | 256 | .id_table = qt1070_id, |
258 | .probe = qt1070_probe, | 257 | .probe = qt1070_probe, |
259 | .remove = qt1070_remove, | 258 | .remove = __devexit_p(qt1070_remove), |
260 | }; | 259 | }; |
261 | 260 | ||
262 | module_i2c_driver(qt1070_driver); | 261 | static int __init qt1070_init(void) |
262 | { | ||
263 | return i2c_add_driver(&qt1070_driver); | ||
264 | } | ||
265 | module_init(qt1070_init); | ||
266 | |||
267 | static void __exit qt1070_exit(void) | ||
268 | { | ||
269 | i2c_del_driver(&qt1070_driver); | ||
270 | } | ||
271 | module_exit(qt1070_exit); | ||
263 | 272 | ||
264 | MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); | 273 | MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); |
265 | MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor"); | 274 | MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor"); |
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 3dc2b0f27b0..fac695157e8 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
@@ -156,7 +156,8 @@ static irqreturn_t qt2160_irq(int irq, void *_qt2160) | |||
156 | 156 | ||
157 | spin_lock_irqsave(&qt2160->lock, flags); | 157 | spin_lock_irqsave(&qt2160->lock, flags); |
158 | 158 | ||
159 | mod_delayed_work(system_wq, &qt2160->dwork, 0); | 159 | __cancel_delayed_work(&qt2160->dwork); |
160 | schedule_delayed_work(&qt2160->dwork, 0); | ||
160 | 161 | ||
161 | spin_unlock_irqrestore(&qt2160->lock, flags); | 162 | spin_unlock_irqrestore(&qt2160->lock, flags); |
162 | 163 | ||
@@ -183,7 +184,7 @@ static void qt2160_worker(struct work_struct *work) | |||
183 | qt2160_schedule_read(qt2160); | 184 | qt2160_schedule_read(qt2160); |
184 | } | 185 | } |
185 | 186 | ||
186 | static int qt2160_read(struct i2c_client *client, u8 reg) | 187 | static int __devinit qt2160_read(struct i2c_client *client, u8 reg) |
187 | { | 188 | { |
188 | int ret; | 189 | int ret; |
189 | 190 | ||
@@ -204,20 +205,29 @@ static int qt2160_read(struct i2c_client *client, u8 reg) | |||
204 | return ret; | 205 | return ret; |
205 | } | 206 | } |
206 | 207 | ||
207 | static int qt2160_write(struct i2c_client *client, u8 reg, u8 data) | 208 | static int __devinit qt2160_write(struct i2c_client *client, u8 reg, u8 data) |
208 | { | 209 | { |
209 | int ret; | 210 | int error; |
210 | 211 | ||
211 | ret = i2c_smbus_write_byte_data(client, reg, data); | 212 | error = i2c_smbus_write_byte(client, reg); |
212 | if (ret < 0) | 213 | if (error) { |
213 | dev_err(&client->dev, | 214 | dev_err(&client->dev, |
214 | "couldn't write data. Returned %d\n", ret); | 215 | "couldn't send request. Returned %d\n", error); |
216 | return error; | ||
217 | } | ||
215 | 218 | ||
216 | return ret; | 219 | error = i2c_smbus_write_byte(client, data); |
220 | if (error) { | ||
221 | dev_err(&client->dev, | ||
222 | "couldn't write data. Returned %d\n", error); | ||
223 | return error; | ||
224 | } | ||
225 | |||
226 | return error; | ||
217 | } | 227 | } |
218 | 228 | ||
219 | 229 | ||
220 | static bool qt2160_identify(struct i2c_client *client) | 230 | static bool __devinit qt2160_identify(struct i2c_client *client) |
221 | { | 231 | { |
222 | int id, ver, rev; | 232 | int id, ver, rev; |
223 | 233 | ||
@@ -248,7 +258,7 @@ static bool qt2160_identify(struct i2c_client *client) | |||
248 | return true; | 258 | return true; |
249 | } | 259 | } |
250 | 260 | ||
251 | static int qt2160_probe(struct i2c_client *client, | 261 | static int __devinit qt2160_probe(struct i2c_client *client, |
252 | const struct i2c_device_id *id) | 262 | const struct i2c_device_id *id) |
253 | { | 263 | { |
254 | struct qt2160_data *qt2160; | 264 | struct qt2160_data *qt2160; |
@@ -335,7 +345,7 @@ err_free_mem: | |||
335 | return error; | 345 | return error; |
336 | } | 346 | } |
337 | 347 | ||
338 | static int qt2160_remove(struct i2c_client *client) | 348 | static int __devexit qt2160_remove(struct i2c_client *client) |
339 | { | 349 | { |
340 | struct qt2160_data *qt2160 = i2c_get_clientdata(client); | 350 | struct qt2160_data *qt2160 = i2c_get_clientdata(client); |
341 | 351 | ||
@@ -366,10 +376,20 @@ static struct i2c_driver qt2160_driver = { | |||
366 | 376 | ||
367 | .id_table = qt2160_idtable, | 377 | .id_table = qt2160_idtable, |
368 | .probe = qt2160_probe, | 378 | .probe = qt2160_probe, |
369 | .remove = qt2160_remove, | 379 | .remove = __devexit_p(qt2160_remove), |
370 | }; | 380 | }; |
371 | 381 | ||
372 | module_i2c_driver(qt2160_driver); | 382 | static int __init qt2160_init(void) |
383 | { | ||
384 | return i2c_add_driver(&qt2160_driver); | ||
385 | } | ||
386 | module_init(qt2160_init); | ||
387 | |||
388 | static void __exit qt2160_cleanup(void) | ||
389 | { | ||
390 | i2c_del_driver(&qt2160_driver); | ||
391 | } | ||
392 | module_exit(qt2160_cleanup); | ||
373 | 393 | ||
374 | MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>"); | 394 | MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>"); |
375 | MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor"); | 395 | MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor"); |
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 22e357b5102..f689f49e310 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c | |||
@@ -20,13 +20,9 @@ | |||
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/pm.h> | ||
24 | #include <linux/pm_runtime.h> | ||
25 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
26 | #include <linux/of.h> | ||
27 | #include <linux/of_gpio.h> | ||
28 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
29 | #include <linux/input/samsung-keypad.h> | 25 | #include <plat/keypad.h> |
30 | 26 | ||
31 | #define SAMSUNG_KEYIFCON 0x00 | 27 | #define SAMSUNG_KEYIFCON 0x00 |
32 | #define SAMSUNG_KEYIFSTSCLR 0x04 | 28 | #define SAMSUNG_KEYIFSTSCLR 0x04 |
@@ -67,33 +63,36 @@ enum samsung_keypad_type { | |||
67 | 63 | ||
68 | struct samsung_keypad { | 64 | struct samsung_keypad { |
69 | struct input_dev *input_dev; | 65 | struct input_dev *input_dev; |
70 | struct platform_device *pdev; | ||
71 | struct clk *clk; | 66 | struct clk *clk; |
72 | void __iomem *base; | 67 | void __iomem *base; |
73 | wait_queue_head_t wait; | 68 | wait_queue_head_t wait; |
74 | bool stopped; | 69 | bool stopped; |
75 | bool wake_enabled; | ||
76 | int irq; | 70 | int irq; |
77 | enum samsung_keypad_type type; | ||
78 | unsigned int row_shift; | 71 | unsigned int row_shift; |
79 | unsigned int rows; | 72 | unsigned int rows; |
80 | unsigned int cols; | 73 | unsigned int cols; |
81 | unsigned int row_state[SAMSUNG_MAX_COLS]; | 74 | unsigned int row_state[SAMSUNG_MAX_COLS]; |
82 | #ifdef CONFIG_OF | ||
83 | int row_gpios[SAMSUNG_MAX_ROWS]; | ||
84 | int col_gpios[SAMSUNG_MAX_COLS]; | ||
85 | #endif | ||
86 | unsigned short keycodes[]; | 75 | unsigned short keycodes[]; |
87 | }; | 76 | }; |
88 | 77 | ||
78 | static int samsung_keypad_is_s5pv210(struct device *dev) | ||
79 | { | ||
80 | struct platform_device *pdev = to_platform_device(dev); | ||
81 | enum samsung_keypad_type type = | ||
82 | platform_get_device_id(pdev)->driver_data; | ||
83 | |||
84 | return type == KEYPAD_TYPE_S5PV210; | ||
85 | } | ||
86 | |||
89 | static void samsung_keypad_scan(struct samsung_keypad *keypad, | 87 | static void samsung_keypad_scan(struct samsung_keypad *keypad, |
90 | unsigned int *row_state) | 88 | unsigned int *row_state) |
91 | { | 89 | { |
90 | struct device *dev = keypad->input_dev->dev.parent; | ||
92 | unsigned int col; | 91 | unsigned int col; |
93 | unsigned int val; | 92 | unsigned int val; |
94 | 93 | ||
95 | for (col = 0; col < keypad->cols; col++) { | 94 | for (col = 0; col < keypad->cols; col++) { |
96 | if (keypad->type == KEYPAD_TYPE_S5PV210) { | 95 | if (samsung_keypad_is_s5pv210(dev)) { |
97 | val = S5PV210_KEYIFCOLEN_MASK; | 96 | val = S5PV210_KEYIFCOLEN_MASK; |
98 | val &= ~(1 << col) << 8; | 97 | val &= ~(1 << col) << 8; |
99 | } else { | 98 | } else { |
@@ -159,8 +158,6 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id) | |||
159 | unsigned int val; | 158 | unsigned int val; |
160 | bool key_down; | 159 | bool key_down; |
161 | 160 | ||
162 | pm_runtime_get_sync(&keypad->pdev->dev); | ||
163 | |||
164 | do { | 161 | do { |
165 | val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR); | 162 | val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR); |
166 | /* Clear interrupt. */ | 163 | /* Clear interrupt. */ |
@@ -175,8 +172,6 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id) | |||
175 | 172 | ||
176 | } while (key_down && !keypad->stopped); | 173 | } while (key_down && !keypad->stopped); |
177 | 174 | ||
178 | pm_runtime_put(&keypad->pdev->dev); | ||
179 | |||
180 | return IRQ_HANDLED; | 175 | return IRQ_HANDLED; |
181 | } | 176 | } |
182 | 177 | ||
@@ -184,8 +179,6 @@ static void samsung_keypad_start(struct samsung_keypad *keypad) | |||
184 | { | 179 | { |
185 | unsigned int val; | 180 | unsigned int val; |
186 | 181 | ||
187 | pm_runtime_get_sync(&keypad->pdev->dev); | ||
188 | |||
189 | /* Tell IRQ thread that it may poll the device. */ | 182 | /* Tell IRQ thread that it may poll the device. */ |
190 | keypad->stopped = false; | 183 | keypad->stopped = false; |
191 | 184 | ||
@@ -198,16 +191,12 @@ static void samsung_keypad_start(struct samsung_keypad *keypad) | |||
198 | 191 | ||
199 | /* KEYIFCOL reg clear. */ | 192 | /* KEYIFCOL reg clear. */ |
200 | writel(0, keypad->base + SAMSUNG_KEYIFCOL); | 193 | writel(0, keypad->base + SAMSUNG_KEYIFCOL); |
201 | |||
202 | pm_runtime_put(&keypad->pdev->dev); | ||
203 | } | 194 | } |
204 | 195 | ||
205 | static void samsung_keypad_stop(struct samsung_keypad *keypad) | 196 | static void samsung_keypad_stop(struct samsung_keypad *keypad) |
206 | { | 197 | { |
207 | unsigned int val; | 198 | unsigned int val; |
208 | 199 | ||
209 | pm_runtime_get_sync(&keypad->pdev->dev); | ||
210 | |||
211 | /* Signal IRQ thread to stop polling and disable the handler. */ | 200 | /* Signal IRQ thread to stop polling and disable the handler. */ |
212 | keypad->stopped = true; | 201 | keypad->stopped = true; |
213 | wake_up(&keypad->wait); | 202 | wake_up(&keypad->wait); |
@@ -228,8 +217,6 @@ static void samsung_keypad_stop(struct samsung_keypad *keypad) | |||
228 | * re-enable the handler. | 217 | * re-enable the handler. |
229 | */ | 218 | */ |
230 | enable_irq(keypad->irq); | 219 | enable_irq(keypad->irq); |
231 | |||
232 | pm_runtime_put(&keypad->pdev->dev); | ||
233 | } | 220 | } |
234 | 221 | ||
235 | static int samsung_keypad_open(struct input_dev *input_dev) | 222 | static int samsung_keypad_open(struct input_dev *input_dev) |
@@ -248,110 +235,7 @@ static void samsung_keypad_close(struct input_dev *input_dev) | |||
248 | samsung_keypad_stop(keypad); | 235 | samsung_keypad_stop(keypad); |
249 | } | 236 | } |
250 | 237 | ||
251 | #ifdef CONFIG_OF | 238 | static int __devinit samsung_keypad_probe(struct platform_device *pdev) |
252 | static struct samsung_keypad_platdata *samsung_keypad_parse_dt( | ||
253 | struct device *dev) | ||
254 | { | ||
255 | struct samsung_keypad_platdata *pdata; | ||
256 | struct matrix_keymap_data *keymap_data; | ||
257 | uint32_t *keymap, num_rows = 0, num_cols = 0; | ||
258 | struct device_node *np = dev->of_node, *key_np; | ||
259 | unsigned int key_count; | ||
260 | |||
261 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
262 | if (!pdata) { | ||
263 | dev_err(dev, "could not allocate memory for platform data\n"); | ||
264 | return NULL; | ||
265 | } | ||
266 | |||
267 | of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows); | ||
268 | of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols); | ||
269 | if (!num_rows || !num_cols) { | ||
270 | dev_err(dev, "number of keypad rows/columns not specified\n"); | ||
271 | return NULL; | ||
272 | } | ||
273 | pdata->rows = num_rows; | ||
274 | pdata->cols = num_cols; | ||
275 | |||
276 | keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL); | ||
277 | if (!keymap_data) { | ||
278 | dev_err(dev, "could not allocate memory for keymap data\n"); | ||
279 | return NULL; | ||
280 | } | ||
281 | pdata->keymap_data = keymap_data; | ||
282 | |||
283 | key_count = of_get_child_count(np); | ||
284 | keymap_data->keymap_size = key_count; | ||
285 | keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); | ||
286 | if (!keymap) { | ||
287 | dev_err(dev, "could not allocate memory for keymap\n"); | ||
288 | return NULL; | ||
289 | } | ||
290 | keymap_data->keymap = keymap; | ||
291 | |||
292 | for_each_child_of_node(np, key_np) { | ||
293 | u32 row, col, key_code; | ||
294 | of_property_read_u32(key_np, "keypad,row", &row); | ||
295 | of_property_read_u32(key_np, "keypad,column", &col); | ||
296 | of_property_read_u32(key_np, "linux,code", &key_code); | ||
297 | *keymap++ = KEY(row, col, key_code); | ||
298 | } | ||
299 | |||
300 | if (of_get_property(np, "linux,input-no-autorepeat", NULL)) | ||
301 | pdata->no_autorepeat = true; | ||
302 | if (of_get_property(np, "linux,input-wakeup", NULL)) | ||
303 | pdata->wakeup = true; | ||
304 | |||
305 | return pdata; | ||
306 | } | ||
307 | |||
308 | static void samsung_keypad_parse_dt_gpio(struct device *dev, | ||
309 | struct samsung_keypad *keypad) | ||
310 | { | ||
311 | struct device_node *np = dev->of_node; | ||
312 | int gpio, error, row, col; | ||
313 | |||
314 | for (row = 0; row < keypad->rows; row++) { | ||
315 | gpio = of_get_named_gpio(np, "row-gpios", row); | ||
316 | keypad->row_gpios[row] = gpio; | ||
317 | if (!gpio_is_valid(gpio)) { | ||
318 | dev_err(dev, "keypad row[%d]: invalid gpio %d\n", | ||
319 | row, gpio); | ||
320 | continue; | ||
321 | } | ||
322 | |||
323 | error = devm_gpio_request(dev, gpio, "keypad-row"); | ||
324 | if (error) | ||
325 | dev_err(dev, | ||
326 | "keypad row[%d] gpio request failed: %d\n", | ||
327 | row, error); | ||
328 | } | ||
329 | |||
330 | for (col = 0; col < keypad->cols; col++) { | ||
331 | gpio = of_get_named_gpio(np, "col-gpios", col); | ||
332 | keypad->col_gpios[col] = gpio; | ||
333 | if (!gpio_is_valid(gpio)) { | ||
334 | dev_err(dev, "keypad column[%d]: invalid gpio %d\n", | ||
335 | col, gpio); | ||
336 | continue; | ||
337 | } | ||
338 | |||
339 | error = devm_gpio_request(dev, gpio, "keypad-col"); | ||
340 | if (error) | ||
341 | dev_err(dev, | ||
342 | "keypad column[%d] gpio request failed: %d\n", | ||
343 | col, error); | ||
344 | } | ||
345 | } | ||
346 | #else | ||
347 | static | ||
348 | struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev) | ||
349 | { | ||
350 | return NULL; | ||
351 | } | ||
352 | #endif | ||
353 | |||
354 | static int samsung_keypad_probe(struct platform_device *pdev) | ||
355 | { | 239 | { |
356 | const struct samsung_keypad_platdata *pdata; | 240 | const struct samsung_keypad_platdata *pdata; |
357 | const struct matrix_keymap_data *keymap_data; | 241 | const struct matrix_keymap_data *keymap_data; |
@@ -362,10 +246,7 @@ static int samsung_keypad_probe(struct platform_device *pdev) | |||
362 | unsigned int keymap_size; | 246 | unsigned int keymap_size; |
363 | int error; | 247 | int error; |
364 | 248 | ||
365 | if (pdev->dev.of_node) | 249 | pdata = pdev->dev.platform_data; |
366 | pdata = samsung_keypad_parse_dt(&pdev->dev); | ||
367 | else | ||
368 | pdata = pdev->dev.platform_data; | ||
369 | if (!pdata) { | 250 | if (!pdata) { |
370 | dev_err(&pdev->dev, "no platform data defined\n"); | 251 | dev_err(&pdev->dev, "no platform data defined\n"); |
371 | return -EINVAL; | 252 | return -EINVAL; |
@@ -390,175 +271,121 @@ static int samsung_keypad_probe(struct platform_device *pdev) | |||
390 | row_shift = get_count_order(pdata->cols); | 271 | row_shift = get_count_order(pdata->cols); |
391 | keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]); | 272 | keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]); |
392 | 273 | ||
393 | keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad) + keymap_size, | 274 | keypad = kzalloc(sizeof(*keypad) + keymap_size, GFP_KERNEL); |
394 | GFP_KERNEL); | 275 | input_dev = input_allocate_device(); |
395 | input_dev = devm_input_allocate_device(&pdev->dev); | 276 | if (!keypad || !input_dev) { |
396 | if (!keypad || !input_dev) | 277 | error = -ENOMEM; |
397 | return -ENOMEM; | 278 | goto err_free_mem; |
279 | } | ||
398 | 280 | ||
399 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 281 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
400 | if (!res) | 282 | if (!res) { |
401 | return -ENODEV; | 283 | error = -ENODEV; |
284 | goto err_free_mem; | ||
285 | } | ||
402 | 286 | ||
403 | keypad->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | 287 | keypad->base = ioremap(res->start, resource_size(res)); |
404 | if (!keypad->base) | 288 | if (!keypad->base) { |
405 | return -EBUSY; | 289 | error = -EBUSY; |
290 | goto err_free_mem; | ||
291 | } | ||
406 | 292 | ||
407 | keypad->clk = devm_clk_get(&pdev->dev, "keypad"); | 293 | keypad->clk = clk_get(&pdev->dev, "keypad"); |
408 | if (IS_ERR(keypad->clk)) { | 294 | if (IS_ERR(keypad->clk)) { |
409 | dev_err(&pdev->dev, "failed to get keypad clk\n"); | 295 | dev_err(&pdev->dev, "failed to get keypad clk\n"); |
410 | return PTR_ERR(keypad->clk); | 296 | error = PTR_ERR(keypad->clk); |
411 | } | 297 | goto err_unmap_base; |
412 | |||
413 | error = clk_prepare(keypad->clk); | ||
414 | if (error) { | ||
415 | dev_err(&pdev->dev, "keypad clock prepare failed\n"); | ||
416 | return error; | ||
417 | } | 298 | } |
418 | 299 | ||
419 | keypad->input_dev = input_dev; | 300 | keypad->input_dev = input_dev; |
420 | keypad->pdev = pdev; | ||
421 | keypad->row_shift = row_shift; | 301 | keypad->row_shift = row_shift; |
422 | keypad->rows = pdata->rows; | 302 | keypad->rows = pdata->rows; |
423 | keypad->cols = pdata->cols; | 303 | keypad->cols = pdata->cols; |
424 | keypad->stopped = true; | ||
425 | init_waitqueue_head(&keypad->wait); | 304 | init_waitqueue_head(&keypad->wait); |
426 | 305 | ||
427 | if (pdev->dev.of_node) { | ||
428 | #ifdef CONFIG_OF | ||
429 | samsung_keypad_parse_dt_gpio(&pdev->dev, keypad); | ||
430 | keypad->type = of_device_is_compatible(pdev->dev.of_node, | ||
431 | "samsung,s5pv210-keypad"); | ||
432 | #endif | ||
433 | } else { | ||
434 | keypad->type = platform_get_device_id(pdev)->driver_data; | ||
435 | } | ||
436 | |||
437 | input_dev->name = pdev->name; | 306 | input_dev->name = pdev->name; |
438 | input_dev->id.bustype = BUS_HOST; | 307 | input_dev->id.bustype = BUS_HOST; |
439 | input_dev->dev.parent = &pdev->dev; | 308 | input_dev->dev.parent = &pdev->dev; |
309 | input_set_drvdata(input_dev, keypad); | ||
440 | 310 | ||
441 | input_dev->open = samsung_keypad_open; | 311 | input_dev->open = samsung_keypad_open; |
442 | input_dev->close = samsung_keypad_close; | 312 | input_dev->close = samsung_keypad_close; |
443 | 313 | ||
444 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 314 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
445 | pdata->rows, pdata->cols, | 315 | if (!pdata->no_autorepeat) |
446 | keypad->keycodes, input_dev); | 316 | input_dev->evbit[0] |= BIT_MASK(EV_REP); |
447 | if (error) { | ||
448 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
449 | goto err_unprepare_clk; | ||
450 | } | ||
451 | 317 | ||
452 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 318 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
453 | if (!pdata->no_autorepeat) | ||
454 | __set_bit(EV_REP, input_dev->evbit); | ||
455 | 319 | ||
456 | input_set_drvdata(input_dev, keypad); | 320 | input_dev->keycode = keypad->keycodes; |
321 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
322 | input_dev->keycodemax = pdata->rows << row_shift; | ||
323 | |||
324 | matrix_keypad_build_keymap(keymap_data, row_shift, | ||
325 | input_dev->keycode, input_dev->keybit); | ||
457 | 326 | ||
458 | keypad->irq = platform_get_irq(pdev, 0); | 327 | keypad->irq = platform_get_irq(pdev, 0); |
459 | if (keypad->irq < 0) { | 328 | if (keypad->irq < 0) { |
460 | error = keypad->irq; | 329 | error = keypad->irq; |
461 | goto err_unprepare_clk; | 330 | goto err_put_clk; |
462 | } | 331 | } |
463 | 332 | ||
464 | error = devm_request_threaded_irq(&pdev->dev, keypad->irq, NULL, | 333 | error = request_threaded_irq(keypad->irq, NULL, samsung_keypad_irq, |
465 | samsung_keypad_irq, IRQF_ONESHOT, | 334 | IRQF_ONESHOT, dev_name(&pdev->dev), keypad); |
466 | dev_name(&pdev->dev), keypad); | ||
467 | if (error) { | 335 | if (error) { |
468 | dev_err(&pdev->dev, "failed to register keypad interrupt\n"); | 336 | dev_err(&pdev->dev, "failed to register keypad interrupt\n"); |
469 | goto err_unprepare_clk; | 337 | goto err_put_clk; |
470 | } | 338 | } |
471 | 339 | ||
472 | device_init_wakeup(&pdev->dev, pdata->wakeup); | ||
473 | platform_set_drvdata(pdev, keypad); | ||
474 | pm_runtime_enable(&pdev->dev); | ||
475 | |||
476 | error = input_register_device(keypad->input_dev); | 340 | error = input_register_device(keypad->input_dev); |
477 | if (error) | 341 | if (error) |
478 | goto err_disable_runtime_pm; | 342 | goto err_free_irq; |
479 | 343 | ||
480 | if (pdev->dev.of_node) { | 344 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
481 | devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap); | 345 | platform_set_drvdata(pdev, keypad); |
482 | devm_kfree(&pdev->dev, (void *)pdata->keymap_data); | ||
483 | devm_kfree(&pdev->dev, (void *)pdata); | ||
484 | } | ||
485 | return 0; | 346 | return 0; |
486 | 347 | ||
487 | err_disable_runtime_pm: | 348 | err_free_irq: |
488 | pm_runtime_disable(&pdev->dev); | 349 | free_irq(keypad->irq, keypad); |
489 | device_init_wakeup(&pdev->dev, 0); | 350 | err_put_clk: |
490 | platform_set_drvdata(pdev, NULL); | 351 | clk_put(keypad->clk); |
491 | err_unprepare_clk: | 352 | err_unmap_base: |
492 | clk_unprepare(keypad->clk); | 353 | iounmap(keypad->base); |
354 | err_free_mem: | ||
355 | input_free_device(input_dev); | ||
356 | kfree(keypad); | ||
357 | |||
493 | return error; | 358 | return error; |
494 | } | 359 | } |
495 | 360 | ||
496 | static int samsung_keypad_remove(struct platform_device *pdev) | 361 | static int __devexit samsung_keypad_remove(struct platform_device *pdev) |
497 | { | 362 | { |
498 | struct samsung_keypad *keypad = platform_get_drvdata(pdev); | 363 | struct samsung_keypad *keypad = platform_get_drvdata(pdev); |
499 | 364 | ||
500 | pm_runtime_disable(&pdev->dev); | ||
501 | device_init_wakeup(&pdev->dev, 0); | 365 | device_init_wakeup(&pdev->dev, 0); |
502 | platform_set_drvdata(pdev, NULL); | 366 | platform_set_drvdata(pdev, NULL); |
503 | 367 | ||
504 | input_unregister_device(keypad->input_dev); | 368 | input_unregister_device(keypad->input_dev); |
505 | 369 | ||
506 | clk_unprepare(keypad->clk); | 370 | /* |
507 | 371 | * It is safe to free IRQ after unregistering device because | |
508 | return 0; | 372 | * samsung_keypad_close will shut off interrupts. |
509 | } | 373 | */ |
510 | 374 | free_irq(keypad->irq, keypad); | |
511 | #ifdef CONFIG_PM_RUNTIME | ||
512 | static int samsung_keypad_runtime_suspend(struct device *dev) | ||
513 | { | ||
514 | struct platform_device *pdev = to_platform_device(dev); | ||
515 | struct samsung_keypad *keypad = platform_get_drvdata(pdev); | ||
516 | unsigned int val; | ||
517 | int error; | ||
518 | |||
519 | if (keypad->stopped) | ||
520 | return 0; | ||
521 | |||
522 | /* This may fail on some SoCs due to lack of controller support */ | ||
523 | error = enable_irq_wake(keypad->irq); | ||
524 | if (!error) | ||
525 | keypad->wake_enabled = true; | ||
526 | |||
527 | val = readl(keypad->base + SAMSUNG_KEYIFCON); | ||
528 | val |= SAMSUNG_KEYIFCON_WAKEUPEN; | ||
529 | writel(val, keypad->base + SAMSUNG_KEYIFCON); | ||
530 | |||
531 | clk_disable(keypad->clk); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int samsung_keypad_runtime_resume(struct device *dev) | ||
537 | { | ||
538 | struct platform_device *pdev = to_platform_device(dev); | ||
539 | struct samsung_keypad *keypad = platform_get_drvdata(pdev); | ||
540 | unsigned int val; | ||
541 | |||
542 | if (keypad->stopped) | ||
543 | return 0; | ||
544 | |||
545 | clk_enable(keypad->clk); | ||
546 | 375 | ||
547 | val = readl(keypad->base + SAMSUNG_KEYIFCON); | 376 | clk_put(keypad->clk); |
548 | val &= ~SAMSUNG_KEYIFCON_WAKEUPEN; | ||
549 | writel(val, keypad->base + SAMSUNG_KEYIFCON); | ||
550 | 377 | ||
551 | if (keypad->wake_enabled) | 378 | iounmap(keypad->base); |
552 | disable_irq_wake(keypad->irq); | 379 | kfree(keypad); |
553 | 380 | ||
554 | return 0; | 381 | return 0; |
555 | } | 382 | } |
556 | #endif | ||
557 | 383 | ||
558 | #ifdef CONFIG_PM_SLEEP | 384 | #ifdef CONFIG_PM |
559 | static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad, | 385 | static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad, |
560 | bool enable) | 386 | bool enable) |
561 | { | 387 | { |
388 | struct device *dev = keypad->input_dev->dev.parent; | ||
562 | unsigned int val; | 389 | unsigned int val; |
563 | 390 | ||
564 | clk_enable(keypad->clk); | 391 | clk_enable(keypad->clk); |
@@ -566,11 +393,11 @@ static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad, | |||
566 | val = readl(keypad->base + SAMSUNG_KEYIFCON); | 393 | val = readl(keypad->base + SAMSUNG_KEYIFCON); |
567 | if (enable) { | 394 | if (enable) { |
568 | val |= SAMSUNG_KEYIFCON_WAKEUPEN; | 395 | val |= SAMSUNG_KEYIFCON_WAKEUPEN; |
569 | if (device_may_wakeup(&keypad->pdev->dev)) | 396 | if (device_may_wakeup(dev)) |
570 | enable_irq_wake(keypad->irq); | 397 | enable_irq_wake(keypad->irq); |
571 | } else { | 398 | } else { |
572 | val &= ~SAMSUNG_KEYIFCON_WAKEUPEN; | 399 | val &= ~SAMSUNG_KEYIFCON_WAKEUPEN; |
573 | if (device_may_wakeup(&keypad->pdev->dev)) | 400 | if (device_may_wakeup(dev)) |
574 | disable_irq_wake(keypad->irq); | 401 | disable_irq_wake(keypad->irq); |
575 | } | 402 | } |
576 | writel(val, keypad->base + SAMSUNG_KEYIFCON); | 403 | writel(val, keypad->base + SAMSUNG_KEYIFCON); |
@@ -613,21 +440,11 @@ static int samsung_keypad_resume(struct device *dev) | |||
613 | 440 | ||
614 | return 0; | 441 | return 0; |
615 | } | 442 | } |
616 | #endif | ||
617 | 443 | ||
618 | static const struct dev_pm_ops samsung_keypad_pm_ops = { | 444 | static const struct dev_pm_ops samsung_keypad_pm_ops = { |
619 | SET_SYSTEM_SLEEP_PM_OPS(samsung_keypad_suspend, samsung_keypad_resume) | 445 | .suspend = samsung_keypad_suspend, |
620 | SET_RUNTIME_PM_OPS(samsung_keypad_runtime_suspend, | 446 | .resume = samsung_keypad_resume, |
621 | samsung_keypad_runtime_resume, NULL) | ||
622 | }; | ||
623 | |||
624 | #ifdef CONFIG_OF | ||
625 | static const struct of_device_id samsung_keypad_dt_match[] = { | ||
626 | { .compatible = "samsung,s3c6410-keypad" }, | ||
627 | { .compatible = "samsung,s5pv210-keypad" }, | ||
628 | {}, | ||
629 | }; | 447 | }; |
630 | MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match); | ||
631 | #endif | 448 | #endif |
632 | 449 | ||
633 | static struct platform_device_id samsung_keypad_driver_ids[] = { | 450 | static struct platform_device_id samsung_keypad_driver_ids[] = { |
@@ -644,18 +461,31 @@ MODULE_DEVICE_TABLE(platform, samsung_keypad_driver_ids); | |||
644 | 461 | ||
645 | static struct platform_driver samsung_keypad_driver = { | 462 | static struct platform_driver samsung_keypad_driver = { |
646 | .probe = samsung_keypad_probe, | 463 | .probe = samsung_keypad_probe, |
647 | .remove = samsung_keypad_remove, | 464 | .remove = __devexit_p(samsung_keypad_remove), |
648 | .driver = { | 465 | .driver = { |
649 | .name = "samsung-keypad", | 466 | .name = "samsung-keypad", |
650 | .owner = THIS_MODULE, | 467 | .owner = THIS_MODULE, |
651 | .of_match_table = of_match_ptr(samsung_keypad_dt_match), | 468 | #ifdef CONFIG_PM |
652 | .pm = &samsung_keypad_pm_ops, | 469 | .pm = &samsung_keypad_pm_ops, |
470 | #endif | ||
653 | }, | 471 | }, |
654 | .id_table = samsung_keypad_driver_ids, | 472 | .id_table = samsung_keypad_driver_ids, |
655 | }; | 473 | }; |
656 | module_platform_driver(samsung_keypad_driver); | 474 | |
475 | static int __init samsung_keypad_init(void) | ||
476 | { | ||
477 | return platform_driver_register(&samsung_keypad_driver); | ||
478 | } | ||
479 | module_init(samsung_keypad_init); | ||
480 | |||
481 | static void __exit samsung_keypad_exit(void) | ||
482 | { | ||
483 | platform_driver_unregister(&samsung_keypad_driver); | ||
484 | } | ||
485 | module_exit(samsung_keypad_exit); | ||
657 | 486 | ||
658 | MODULE_DESCRIPTION("Samsung keypad driver"); | 487 | MODULE_DESCRIPTION("Samsung keypad driver"); |
659 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 488 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
660 | MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>"); | 489 | MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>"); |
661 | MODULE_LICENSE("GPL"); | 490 | MODULE_LICENSE("GPL"); |
491 | MODULE_ALIAS("platform:samsung-keypad"); | ||
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index fdb9eb2df38..934aeb583b3 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -162,7 +162,7 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | |||
162 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
163 | } | 163 | } |
164 | 164 | ||
165 | static int sh_keysc_probe(struct platform_device *pdev) | 165 | static int __devinit sh_keysc_probe(struct platform_device *pdev) |
166 | { | 166 | { |
167 | struct sh_keysc_priv *priv; | 167 | struct sh_keysc_priv *priv; |
168 | struct sh_keysc_info *pdata; | 168 | struct sh_keysc_info *pdata; |
@@ -272,7 +272,7 @@ static int sh_keysc_probe(struct platform_device *pdev) | |||
272 | return error; | 272 | return error; |
273 | } | 273 | } |
274 | 274 | ||
275 | static int sh_keysc_remove(struct platform_device *pdev) | 275 | static int __devexit sh_keysc_remove(struct platform_device *pdev) |
276 | { | 276 | { |
277 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 277 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
278 | 278 | ||
@@ -331,13 +331,25 @@ static SIMPLE_DEV_PM_OPS(sh_keysc_dev_pm_ops, | |||
331 | 331 | ||
332 | static struct platform_driver sh_keysc_device_driver = { | 332 | static struct platform_driver sh_keysc_device_driver = { |
333 | .probe = sh_keysc_probe, | 333 | .probe = sh_keysc_probe, |
334 | .remove = sh_keysc_remove, | 334 | .remove = __devexit_p(sh_keysc_remove), |
335 | .driver = { | 335 | .driver = { |
336 | .name = "sh_keysc", | 336 | .name = "sh_keysc", |
337 | .pm = &sh_keysc_dev_pm_ops, | 337 | .pm = &sh_keysc_dev_pm_ops, |
338 | } | 338 | } |
339 | }; | 339 | }; |
340 | module_platform_driver(sh_keysc_device_driver); | 340 | |
341 | static int __init sh_keysc_init(void) | ||
342 | { | ||
343 | return platform_driver_register(&sh_keysc_device_driver); | ||
344 | } | ||
345 | |||
346 | static void __exit sh_keysc_exit(void) | ||
347 | { | ||
348 | platform_driver_unregister(&sh_keysc_device_driver); | ||
349 | } | ||
350 | |||
351 | module_init(sh_keysc_init); | ||
352 | module_exit(sh_keysc_exit); | ||
341 | 353 | ||
342 | MODULE_AUTHOR("Magnus Damm"); | 354 | MODULE_AUTHOR("Magnus Damm"); |
343 | MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver"); | 355 | MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver"); |
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 695d237417d..d712dffd215 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c | |||
@@ -19,52 +19,46 @@ | |||
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/of.h> | ||
23 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
24 | #include <linux/pm_wakeup.h> | 23 | #include <linux/pm_wakeup.h> |
25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
26 | #include <linux/types.h> | 25 | #include <linux/types.h> |
27 | #include <linux/platform_data/keyboard-spear.h> | 26 | #include <plat/keyboard.h> |
28 | 27 | ||
29 | /* Keyboard Registers */ | 28 | /* Keyboard Registers */ |
30 | #define MODE_CTL_REG 0x00 | 29 | #define MODE_REG 0x00 /* 16 bit reg */ |
31 | #define STATUS_REG 0x0C | 30 | #define STATUS_REG 0x0C /* 2 bit reg */ |
32 | #define DATA_REG 0x10 | 31 | #define DATA_REG 0x10 /* 8 bit reg */ |
33 | #define INTR_MASK 0x54 | 32 | #define INTR_MASK 0x54 |
34 | 33 | ||
35 | /* Register Values */ | 34 | /* Register Values */ |
36 | #define NUM_ROWS 16 | 35 | /* |
37 | #define NUM_COLS 16 | 36 | * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode |
38 | #define MODE_CTL_PCLK_FREQ_SHIFT 9 | 37 | * control register as 1010010(82MHZ) |
39 | #define MODE_CTL_PCLK_FREQ_MSK 0x7F | 38 | */ |
40 | 39 | #define PCLK_FREQ_MSK 0xA400 /* 82 MHz */ | |
41 | #define MODE_CTL_KEYBOARD (0x2 << 0) | 40 | #define START_SCAN 0x0100 |
42 | #define MODE_CTL_SCAN_RATE_10 (0x0 << 2) | 41 | #define SCAN_RATE_10 0x0000 |
43 | #define MODE_CTL_SCAN_RATE_20 (0x1 << 2) | 42 | #define SCAN_RATE_20 0x0004 |
44 | #define MODE_CTL_SCAN_RATE_40 (0x2 << 2) | 43 | #define SCAN_RATE_40 0x0008 |
45 | #define MODE_CTL_SCAN_RATE_80 (0x3 << 2) | 44 | #define SCAN_RATE_80 0x000C |
46 | #define MODE_CTL_KEYNUM_SHIFT 6 | 45 | #define MODE_KEYBOARD 0x0002 |
47 | #define MODE_CTL_START_SCAN (0x1 << 8) | 46 | #define DATA_AVAIL 0x2 |
48 | 47 | ||
49 | #define STATUS_DATA_AVAIL (0x1 << 1) | 48 | #define KEY_MASK 0xFF000000 |
50 | 49 | #define KEY_VALUE 0x00FFFFFF | |
51 | #define DATA_ROW_MASK 0xF0 | 50 | #define ROW_MASK 0xF0 |
52 | #define DATA_COLUMN_MASK 0x0F | 51 | #define COLUMN_MASK 0x0F |
53 | 52 | #define ROW_SHIFT 4 | |
54 | #define ROW_SHIFT 4 | ||
55 | 53 | ||
56 | struct spear_kbd { | 54 | struct spear_kbd { |
57 | struct input_dev *input; | 55 | struct input_dev *input; |
56 | struct resource *res; | ||
58 | void __iomem *io_base; | 57 | void __iomem *io_base; |
59 | struct clk *clk; | 58 | struct clk *clk; |
60 | unsigned int irq; | 59 | unsigned int irq; |
61 | unsigned int mode; | ||
62 | unsigned int suspended_rate; | ||
63 | unsigned short last_key; | 60 | unsigned short last_key; |
64 | unsigned short keycodes[NUM_ROWS * NUM_COLS]; | 61 | unsigned short keycodes[256]; |
65 | bool rep; | ||
66 | bool irq_wake_enabled; | ||
67 | u32 mode_ctl_reg; | ||
68 | }; | 62 | }; |
69 | 63 | ||
70 | static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) | 64 | static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) |
@@ -72,10 +66,10 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) | |||
72 | struct spear_kbd *kbd = dev_id; | 66 | struct spear_kbd *kbd = dev_id; |
73 | struct input_dev *input = kbd->input; | 67 | struct input_dev *input = kbd->input; |
74 | unsigned int key; | 68 | unsigned int key; |
75 | u32 sts, val; | 69 | u8 sts, val; |
76 | 70 | ||
77 | sts = readl_relaxed(kbd->io_base + STATUS_REG); | 71 | sts = readb(kbd->io_base + STATUS_REG); |
78 | if (!(sts & STATUS_DATA_AVAIL)) | 72 | if (!(sts & DATA_AVAIL)) |
79 | return IRQ_NONE; | 73 | return IRQ_NONE; |
80 | 74 | ||
81 | if (kbd->last_key != KEY_RESERVED) { | 75 | if (kbd->last_key != KEY_RESERVED) { |
@@ -84,8 +78,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) | |||
84 | } | 78 | } |
85 | 79 | ||
86 | /* following reads active (row, col) pair */ | 80 | /* following reads active (row, col) pair */ |
87 | val = readl_relaxed(kbd->io_base + DATA_REG) & | 81 | val = readb(kbd->io_base + DATA_REG); |
88 | (DATA_ROW_MASK | DATA_COLUMN_MASK); | ||
89 | key = kbd->keycodes[val]; | 82 | key = kbd->keycodes[val]; |
90 | 83 | ||
91 | input_event(input, EV_MSC, MSC_SCAN, val); | 84 | input_event(input, EV_MSC, MSC_SCAN, val); |
@@ -95,7 +88,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) | |||
95 | kbd->last_key = key; | 88 | kbd->last_key = key; |
96 | 89 | ||
97 | /* clear interrupt */ | 90 | /* clear interrupt */ |
98 | writel_relaxed(0, kbd->io_base + STATUS_REG); | 91 | writeb(0, kbd->io_base + STATUS_REG); |
99 | 92 | ||
100 | return IRQ_HANDLED; | 93 | return IRQ_HANDLED; |
101 | } | 94 | } |
@@ -104,7 +97,7 @@ static int spear_kbd_open(struct input_dev *dev) | |||
104 | { | 97 | { |
105 | struct spear_kbd *kbd = input_get_drvdata(dev); | 98 | struct spear_kbd *kbd = input_get_drvdata(dev); |
106 | int error; | 99 | int error; |
107 | u32 val; | 100 | u16 val; |
108 | 101 | ||
109 | kbd->last_key = KEY_RESERVED; | 102 | kbd->last_key = KEY_RESERVED; |
110 | 103 | ||
@@ -112,20 +105,15 @@ static int spear_kbd_open(struct input_dev *dev) | |||
112 | if (error) | 105 | if (error) |
113 | return error; | 106 | return error; |
114 | 107 | ||
115 | /* keyboard rate to be programmed is input clock (in MHz) - 1 */ | ||
116 | val = clk_get_rate(kbd->clk) / 1000000 - 1; | ||
117 | val = (val & MODE_CTL_PCLK_FREQ_MSK) << MODE_CTL_PCLK_FREQ_SHIFT; | ||
118 | |||
119 | /* program keyboard */ | 108 | /* program keyboard */ |
120 | val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | val | | 109 | val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK; |
121 | (kbd->mode << MODE_CTL_KEYNUM_SHIFT); | 110 | writew(val, kbd->io_base + MODE_REG); |
122 | writel_relaxed(val, kbd->io_base + MODE_CTL_REG); | 111 | writeb(1, kbd->io_base + STATUS_REG); |
123 | writel_relaxed(1, kbd->io_base + STATUS_REG); | ||
124 | 112 | ||
125 | /* start key scan */ | 113 | /* start key scan */ |
126 | val = readl_relaxed(kbd->io_base + MODE_CTL_REG); | 114 | val = readw(kbd->io_base + MODE_REG); |
127 | val |= MODE_CTL_START_SCAN; | 115 | val |= START_SCAN; |
128 | writel_relaxed(val, kbd->io_base + MODE_CTL_REG); | 116 | writew(val, kbd->io_base + MODE_REG); |
129 | 117 | ||
130 | return 0; | 118 | return 0; |
131 | } | 119 | } |
@@ -133,64 +121,39 @@ static int spear_kbd_open(struct input_dev *dev) | |||
133 | static void spear_kbd_close(struct input_dev *dev) | 121 | static void spear_kbd_close(struct input_dev *dev) |
134 | { | 122 | { |
135 | struct spear_kbd *kbd = input_get_drvdata(dev); | 123 | struct spear_kbd *kbd = input_get_drvdata(dev); |
136 | u32 val; | 124 | u16 val; |
137 | 125 | ||
138 | /* stop key scan */ | 126 | /* stop key scan */ |
139 | val = readl_relaxed(kbd->io_base + MODE_CTL_REG); | 127 | val = readw(kbd->io_base + MODE_REG); |
140 | val &= ~MODE_CTL_START_SCAN; | 128 | val &= ~START_SCAN; |
141 | writel_relaxed(val, kbd->io_base + MODE_CTL_REG); | 129 | writew(val, kbd->io_base + MODE_REG); |
142 | 130 | ||
143 | clk_disable(kbd->clk); | 131 | clk_disable(kbd->clk); |
144 | 132 | ||
145 | kbd->last_key = KEY_RESERVED; | 133 | kbd->last_key = KEY_RESERVED; |
146 | } | 134 | } |
147 | 135 | ||
148 | #ifdef CONFIG_OF | 136 | static int __devinit spear_kbd_probe(struct platform_device *pdev) |
149 | static int spear_kbd_parse_dt(struct platform_device *pdev, | ||
150 | struct spear_kbd *kbd) | ||
151 | { | 137 | { |
152 | struct device_node *np = pdev->dev.of_node; | 138 | const struct kbd_platform_data *pdata = pdev->dev.platform_data; |
139 | const struct matrix_keymap_data *keymap; | ||
140 | struct spear_kbd *kbd; | ||
141 | struct input_dev *input_dev; | ||
142 | struct resource *res; | ||
143 | int irq; | ||
153 | int error; | 144 | int error; |
154 | u32 val, suspended_rate; | ||
155 | 145 | ||
156 | if (!np) { | 146 | if (!pdata) { |
157 | dev_err(&pdev->dev, "Missing DT data\n"); | 147 | dev_err(&pdev->dev, "Invalid platform data\n"); |
158 | return -EINVAL; | 148 | return -EINVAL; |
159 | } | 149 | } |
160 | 150 | ||
161 | if (of_property_read_bool(np, "autorepeat")) | 151 | keymap = pdata->keymap; |
162 | kbd->rep = true; | 152 | if (!keymap) { |
163 | 153 | dev_err(&pdev->dev, "no keymap defined\n"); | |
164 | if (of_property_read_u32(np, "suspended_rate", &suspended_rate)) | 154 | return -EINVAL; |
165 | kbd->suspended_rate = suspended_rate; | ||
166 | |||
167 | error = of_property_read_u32(np, "st,mode", &val); | ||
168 | if (error) { | ||
169 | dev_err(&pdev->dev, "DT: Invalid or missing mode\n"); | ||
170 | return error; | ||
171 | } | 155 | } |
172 | 156 | ||
173 | kbd->mode = val; | ||
174 | return 0; | ||
175 | } | ||
176 | #else | ||
177 | static inline int spear_kbd_parse_dt(struct platform_device *pdev, | ||
178 | struct spear_kbd *kbd) | ||
179 | { | ||
180 | return -ENOSYS; | ||
181 | } | ||
182 | #endif | ||
183 | |||
184 | static int spear_kbd_probe(struct platform_device *pdev) | ||
185 | { | ||
186 | struct kbd_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
187 | const struct matrix_keymap_data *keymap = pdata ? pdata->keymap : NULL; | ||
188 | struct spear_kbd *kbd; | ||
189 | struct input_dev *input_dev; | ||
190 | struct resource *res; | ||
191 | int irq; | ||
192 | int error; | ||
193 | |||
194 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 157 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
195 | if (!res) { | 158 | if (!res) { |
196 | dev_err(&pdev->dev, "no keyboard resource defined\n"); | 159 | dev_err(&pdev->dev, "no keyboard resource defined\n"); |
@@ -203,43 +166,40 @@ static int spear_kbd_probe(struct platform_device *pdev) | |||
203 | return irq; | 166 | return irq; |
204 | } | 167 | } |
205 | 168 | ||
206 | kbd = devm_kzalloc(&pdev->dev, sizeof(*kbd), GFP_KERNEL); | 169 | kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); |
207 | if (!kbd) { | 170 | input_dev = input_allocate_device(); |
208 | dev_err(&pdev->dev, "not enough memory for driver data\n"); | 171 | if (!kbd || !input_dev) { |
209 | return -ENOMEM; | 172 | dev_err(&pdev->dev, "out of memory\n"); |
210 | } | 173 | error = -ENOMEM; |
211 | 174 | goto err_free_mem; | |
212 | input_dev = devm_input_allocate_device(&pdev->dev); | ||
213 | if (!input_dev) { | ||
214 | dev_err(&pdev->dev, "unable to allocate input device\n"); | ||
215 | return -ENOMEM; | ||
216 | } | 175 | } |
217 | 176 | ||
218 | kbd->input = input_dev; | 177 | kbd->input = input_dev; |
219 | kbd->irq = irq; | 178 | kbd->irq = irq; |
220 | 179 | kbd->res = request_mem_region(res->start, resource_size(res), | |
221 | if (!pdata) { | 180 | pdev->name); |
222 | error = spear_kbd_parse_dt(pdev, kbd); | 181 | if (!kbd->res) { |
223 | if (error) | 182 | dev_err(&pdev->dev, "keyboard region already claimed\n"); |
224 | return error; | 183 | error = -EBUSY; |
225 | } else { | 184 | goto err_free_mem; |
226 | kbd->mode = pdata->mode; | ||
227 | kbd->rep = pdata->rep; | ||
228 | kbd->suspended_rate = pdata->suspended_rate; | ||
229 | } | 185 | } |
230 | 186 | ||
231 | kbd->io_base = devm_request_and_ioremap(&pdev->dev, res); | 187 | kbd->io_base = ioremap(res->start, resource_size(res)); |
232 | if (!kbd->io_base) { | 188 | if (!kbd->io_base) { |
233 | dev_err(&pdev->dev, "request-ioremap failed for kbd_region\n"); | 189 | dev_err(&pdev->dev, "ioremap failed for kbd_region\n"); |
234 | return -ENOMEM; | 190 | error = -ENOMEM; |
191 | goto err_release_mem_region; | ||
235 | } | 192 | } |
236 | 193 | ||
237 | kbd->clk = devm_clk_get(&pdev->dev, NULL); | 194 | kbd->clk = clk_get(&pdev->dev, NULL); |
238 | if (IS_ERR(kbd->clk)) | 195 | if (IS_ERR(kbd->clk)) { |
239 | return PTR_ERR(kbd->clk); | 196 | error = PTR_ERR(kbd->clk); |
197 | goto err_iounmap; | ||
198 | } | ||
240 | 199 | ||
241 | input_dev->name = "Spear Keyboard"; | 200 | input_dev->name = "Spear Keyboard"; |
242 | input_dev->phys = "keyboard/input0"; | 201 | input_dev->phys = "keyboard/input0"; |
202 | input_dev->dev.parent = &pdev->dev; | ||
243 | input_dev->id.bustype = BUS_HOST; | 203 | input_dev->id.bustype = BUS_HOST; |
244 | input_dev->id.vendor = 0x0001; | 204 | input_dev->id.vendor = 0x0001; |
245 | input_dev->id.product = 0x0001; | 205 | input_dev->id.product = 0x0001; |
@@ -247,51 +207,64 @@ static int spear_kbd_probe(struct platform_device *pdev) | |||
247 | input_dev->open = spear_kbd_open; | 207 | input_dev->open = spear_kbd_open; |
248 | input_dev->close = spear_kbd_close; | 208 | input_dev->close = spear_kbd_close; |
249 | 209 | ||
250 | error = matrix_keypad_build_keymap(keymap, NULL, NUM_ROWS, NUM_COLS, | 210 | __set_bit(EV_KEY, input_dev->evbit); |
251 | kbd->keycodes, input_dev); | 211 | if (pdata->rep) |
252 | if (error) { | ||
253 | dev_err(&pdev->dev, "Failed to build keymap\n"); | ||
254 | return error; | ||
255 | } | ||
256 | |||
257 | if (kbd->rep) | ||
258 | __set_bit(EV_REP, input_dev->evbit); | 212 | __set_bit(EV_REP, input_dev->evbit); |
259 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 213 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
260 | 214 | ||
215 | input_dev->keycode = kbd->keycodes; | ||
216 | input_dev->keycodesize = sizeof(kbd->keycodes[0]); | ||
217 | input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes); | ||
218 | |||
219 | matrix_keypad_build_keymap(keymap, ROW_SHIFT, | ||
220 | input_dev->keycode, input_dev->keybit); | ||
221 | |||
261 | input_set_drvdata(input_dev, kbd); | 222 | input_set_drvdata(input_dev, kbd); |
262 | 223 | ||
263 | error = devm_request_irq(&pdev->dev, irq, spear_kbd_interrupt, 0, | 224 | error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); |
264 | "keyboard", kbd); | ||
265 | if (error) { | 225 | if (error) { |
266 | dev_err(&pdev->dev, "request_irq failed\n"); | 226 | dev_err(&pdev->dev, "request_irq fail\n"); |
267 | return error; | 227 | goto err_put_clk; |
268 | } | 228 | } |
269 | 229 | ||
270 | error = clk_prepare(kbd->clk); | ||
271 | if (error) | ||
272 | return error; | ||
273 | |||
274 | error = input_register_device(input_dev); | 230 | error = input_register_device(input_dev); |
275 | if (error) { | 231 | if (error) { |
276 | dev_err(&pdev->dev, "Unable to register keyboard device\n"); | 232 | dev_err(&pdev->dev, "Unable to register keyboard device\n"); |
277 | clk_unprepare(kbd->clk); | 233 | goto err_free_irq; |
278 | return error; | ||
279 | } | 234 | } |
280 | 235 | ||
281 | device_init_wakeup(&pdev->dev, 1); | 236 | device_init_wakeup(&pdev->dev, 1); |
282 | platform_set_drvdata(pdev, kbd); | 237 | platform_set_drvdata(pdev, kbd); |
283 | 238 | ||
284 | return 0; | 239 | return 0; |
240 | |||
241 | err_free_irq: | ||
242 | free_irq(kbd->irq, kbd); | ||
243 | err_put_clk: | ||
244 | clk_put(kbd->clk); | ||
245 | err_iounmap: | ||
246 | iounmap(kbd->io_base); | ||
247 | err_release_mem_region: | ||
248 | release_mem_region(res->start, resource_size(res)); | ||
249 | err_free_mem: | ||
250 | input_free_device(input_dev); | ||
251 | kfree(kbd); | ||
252 | |||
253 | return error; | ||
285 | } | 254 | } |
286 | 255 | ||
287 | static int spear_kbd_remove(struct platform_device *pdev) | 256 | static int __devexit spear_kbd_remove(struct platform_device *pdev) |
288 | { | 257 | { |
289 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | 258 | struct spear_kbd *kbd = platform_get_drvdata(pdev); |
290 | 259 | ||
260 | free_irq(kbd->irq, kbd); | ||
291 | input_unregister_device(kbd->input); | 261 | input_unregister_device(kbd->input); |
292 | clk_unprepare(kbd->clk); | 262 | clk_put(kbd->clk); |
263 | iounmap(kbd->io_base); | ||
264 | release_mem_region(kbd->res->start, resource_size(kbd->res)); | ||
265 | kfree(kbd); | ||
293 | 266 | ||
294 | device_init_wakeup(&pdev->dev, 0); | 267 | device_init_wakeup(&pdev->dev, 1); |
295 | platform_set_drvdata(pdev, NULL); | 268 | platform_set_drvdata(pdev, NULL); |
296 | 269 | ||
297 | return 0; | 270 | return 0; |
@@ -303,48 +276,14 @@ static int spear_kbd_suspend(struct device *dev) | |||
303 | struct platform_device *pdev = to_platform_device(dev); | 276 | struct platform_device *pdev = to_platform_device(dev); |
304 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | 277 | struct spear_kbd *kbd = platform_get_drvdata(pdev); |
305 | struct input_dev *input_dev = kbd->input; | 278 | struct input_dev *input_dev = kbd->input; |
306 | unsigned int rate = 0, mode_ctl_reg, val; | ||
307 | 279 | ||
308 | mutex_lock(&input_dev->mutex); | 280 | mutex_lock(&input_dev->mutex); |
309 | 281 | ||
310 | /* explicitly enable clock as we may program device */ | ||
311 | clk_enable(kbd->clk); | ||
312 | |||
313 | mode_ctl_reg = readl_relaxed(kbd->io_base + MODE_CTL_REG); | ||
314 | |||
315 | if (device_may_wakeup(&pdev->dev)) { | ||
316 | if (!enable_irq_wake(kbd->irq)) | ||
317 | kbd->irq_wake_enabled = true; | ||
318 | |||
319 | /* | ||
320 | * reprogram the keyboard operating frequency as on some | ||
321 | * platform it may change during system suspended | ||
322 | */ | ||
323 | if (kbd->suspended_rate) | ||
324 | rate = kbd->suspended_rate / 1000000 - 1; | ||
325 | else | ||
326 | rate = clk_get_rate(kbd->clk) / 1000000 - 1; | ||
327 | |||
328 | val = mode_ctl_reg & | ||
329 | ~(MODE_CTL_PCLK_FREQ_MSK << MODE_CTL_PCLK_FREQ_SHIFT); | ||
330 | val |= (rate & MODE_CTL_PCLK_FREQ_MSK) | ||
331 | << MODE_CTL_PCLK_FREQ_SHIFT; | ||
332 | writel_relaxed(val, kbd->io_base + MODE_CTL_REG); | ||
333 | |||
334 | } else { | ||
335 | if (input_dev->users) { | ||
336 | writel_relaxed(mode_ctl_reg & ~MODE_CTL_START_SCAN, | ||
337 | kbd->io_base + MODE_CTL_REG); | ||
338 | clk_disable(kbd->clk); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | /* store current configuration */ | ||
343 | if (input_dev->users) | 282 | if (input_dev->users) |
344 | kbd->mode_ctl_reg = mode_ctl_reg; | 283 | clk_enable(kbd->clk); |
345 | 284 | ||
346 | /* restore previous clk state */ | 285 | if (device_may_wakeup(&pdev->dev)) |
347 | clk_disable(kbd->clk); | 286 | enable_irq_wake(kbd->irq); |
348 | 287 | ||
349 | mutex_unlock(&input_dev->mutex); | 288 | mutex_unlock(&input_dev->mutex); |
350 | 289 | ||
@@ -359,47 +298,46 @@ static int spear_kbd_resume(struct device *dev) | |||
359 | 298 | ||
360 | mutex_lock(&input_dev->mutex); | 299 | mutex_lock(&input_dev->mutex); |
361 | 300 | ||
362 | if (device_may_wakeup(&pdev->dev)) { | 301 | if (device_may_wakeup(&pdev->dev)) |
363 | if (kbd->irq_wake_enabled) { | 302 | disable_irq_wake(kbd->irq); |
364 | kbd->irq_wake_enabled = false; | ||
365 | disable_irq_wake(kbd->irq); | ||
366 | } | ||
367 | } else { | ||
368 | if (input_dev->users) | ||
369 | clk_enable(kbd->clk); | ||
370 | } | ||
371 | 303 | ||
372 | /* restore current configuration */ | ||
373 | if (input_dev->users) | 304 | if (input_dev->users) |
374 | writel_relaxed(kbd->mode_ctl_reg, kbd->io_base + MODE_CTL_REG); | 305 | clk_enable(kbd->clk); |
375 | 306 | ||
376 | mutex_unlock(&input_dev->mutex); | 307 | mutex_unlock(&input_dev->mutex); |
377 | 308 | ||
378 | return 0; | 309 | return 0; |
379 | } | 310 | } |
380 | #endif | ||
381 | 311 | ||
382 | static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume); | 312 | static const struct dev_pm_ops spear_kbd_pm_ops = { |
383 | 313 | .suspend = spear_kbd_suspend, | |
384 | #ifdef CONFIG_OF | 314 | .resume = spear_kbd_resume, |
385 | static const struct of_device_id spear_kbd_id_table[] = { | ||
386 | { .compatible = "st,spear300-kbd" }, | ||
387 | {} | ||
388 | }; | 315 | }; |
389 | MODULE_DEVICE_TABLE(of, spear_kbd_id_table); | ||
390 | #endif | 316 | #endif |
391 | 317 | ||
392 | static struct platform_driver spear_kbd_driver = { | 318 | static struct platform_driver spear_kbd_driver = { |
393 | .probe = spear_kbd_probe, | 319 | .probe = spear_kbd_probe, |
394 | .remove = spear_kbd_remove, | 320 | .remove = __devexit_p(spear_kbd_remove), |
395 | .driver = { | 321 | .driver = { |
396 | .name = "keyboard", | 322 | .name = "keyboard", |
397 | .owner = THIS_MODULE, | 323 | .owner = THIS_MODULE, |
324 | #ifdef CONFIG_PM | ||
398 | .pm = &spear_kbd_pm_ops, | 325 | .pm = &spear_kbd_pm_ops, |
399 | .of_match_table = of_match_ptr(spear_kbd_id_table), | 326 | #endif |
400 | }, | 327 | }, |
401 | }; | 328 | }; |
402 | module_platform_driver(spear_kbd_driver); | 329 | |
330 | static int __init spear_kbd_init(void) | ||
331 | { | ||
332 | return platform_driver_register(&spear_kbd_driver); | ||
333 | } | ||
334 | module_init(spear_kbd_init); | ||
335 | |||
336 | static void __exit spear_kbd_exit(void) | ||
337 | { | ||
338 | platform_driver_unregister(&spear_kbd_driver); | ||
339 | } | ||
340 | module_exit(spear_kbd_exit); | ||
403 | 341 | ||
404 | MODULE_AUTHOR("Rajeev Kumar"); | 342 | MODULE_AUTHOR("Rajeev Kumar"); |
405 | MODULE_DESCRIPTION("SPEAr Keyboard Driver"); | 343 | MODULE_DESCRIPTION("SPEAr Keyboard Driver"); |
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index 5cbec56f772..ab7610ca10e 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c | |||
@@ -166,7 +166,7 @@ static irqreturn_t stmpe_keypad_irq(int irq, void *dev) | |||
166 | return IRQ_HANDLED; | 166 | return IRQ_HANDLED; |
167 | } | 167 | } |
168 | 168 | ||
169 | static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | 169 | static int __devinit stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) |
170 | { | 170 | { |
171 | const struct stmpe_keypad_variant *variant = keypad->variant; | 171 | const struct stmpe_keypad_variant *variant = keypad->variant; |
172 | unsigned int col_gpios = variant->col_gpios; | 172 | unsigned int col_gpios = variant->col_gpios; |
@@ -207,7 +207,7 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
207 | return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); | 207 | return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); |
208 | } | 208 | } |
209 | 209 | ||
210 | static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | 210 | static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad) |
211 | { | 211 | { |
212 | const struct stmpe_keypad_platform_data *plat = keypad->plat; | 212 | const struct stmpe_keypad_platform_data *plat = keypad->plat; |
213 | const struct stmpe_keypad_variant *variant = keypad->variant; | 213 | const struct stmpe_keypad_variant *variant = keypad->variant; |
@@ -257,131 +257,107 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | |||
257 | (plat->debounce_ms << 1)); | 257 | (plat->debounce_ms << 1)); |
258 | } | 258 | } |
259 | 259 | ||
260 | static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) | 260 | static int __devinit stmpe_keypad_probe(struct platform_device *pdev) |
261 | { | ||
262 | int row, col; | ||
263 | |||
264 | for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) { | ||
265 | for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) { | ||
266 | int code = MATRIX_SCAN_CODE(row, col, | ||
267 | STMPE_KEYPAD_ROW_SHIFT); | ||
268 | if (keypad->keymap[code] != KEY_RESERVED) { | ||
269 | keypad->rows |= 1 << row; | ||
270 | keypad->cols |= 1 << col; | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | |||
276 | #ifdef CONFIG_OF | ||
277 | static const struct stmpe_keypad_platform_data * | ||
278 | stmpe_keypad_of_probe(struct device *dev) | ||
279 | { | ||
280 | struct device_node *np = dev->of_node; | ||
281 | struct stmpe_keypad_platform_data *plat; | ||
282 | |||
283 | if (!np) | ||
284 | return ERR_PTR(-ENODEV); | ||
285 | |||
286 | plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); | ||
287 | if (!plat) | ||
288 | return ERR_PTR(-ENOMEM); | ||
289 | |||
290 | of_property_read_u32(np, "debounce-interval", &plat->debounce_ms); | ||
291 | of_property_read_u32(np, "st,scan-count", &plat->scan_count); | ||
292 | |||
293 | plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat"); | ||
294 | |||
295 | return plat; | ||
296 | } | ||
297 | #else | ||
298 | static inline const struct stmpe_keypad_platform_data * | ||
299 | stmpe_keypad_of_probe(struct device *dev) | ||
300 | { | ||
301 | return ERR_PTR(-EINVAL); | ||
302 | } | ||
303 | #endif | ||
304 | |||
305 | static int stmpe_keypad_probe(struct platform_device *pdev) | ||
306 | { | 261 | { |
307 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | 262 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); |
308 | const struct stmpe_keypad_platform_data *plat; | 263 | struct stmpe_keypad_platform_data *plat; |
309 | struct stmpe_keypad *keypad; | 264 | struct stmpe_keypad *keypad; |
310 | struct input_dev *input; | 265 | struct input_dev *input; |
311 | int error; | 266 | int ret; |
312 | int irq; | 267 | int irq; |
268 | int i; | ||
313 | 269 | ||
314 | plat = stmpe->pdata->keypad; | 270 | plat = stmpe->pdata->keypad; |
315 | if (!plat) { | 271 | if (!plat) |
316 | plat = stmpe_keypad_of_probe(&pdev->dev); | 272 | return -ENODEV; |
317 | if (IS_ERR(plat)) | ||
318 | return PTR_ERR(plat); | ||
319 | } | ||
320 | 273 | ||
321 | irq = platform_get_irq(pdev, 0); | 274 | irq = platform_get_irq(pdev, 0); |
322 | if (irq < 0) | 275 | if (irq < 0) |
323 | return irq; | 276 | return irq; |
324 | 277 | ||
325 | keypad = devm_kzalloc(&pdev->dev, sizeof(struct stmpe_keypad), | 278 | keypad = kzalloc(sizeof(struct stmpe_keypad), GFP_KERNEL); |
326 | GFP_KERNEL); | ||
327 | if (!keypad) | 279 | if (!keypad) |
328 | return -ENOMEM; | 280 | return -ENOMEM; |
329 | 281 | ||
330 | input = devm_input_allocate_device(&pdev->dev); | 282 | input = input_allocate_device(); |
331 | if (!input) | 283 | if (!input) { |
332 | return -ENOMEM; | 284 | ret = -ENOMEM; |
285 | goto out_freekeypad; | ||
286 | } | ||
333 | 287 | ||
334 | input->name = "STMPE keypad"; | 288 | input->name = "STMPE keypad"; |
335 | input->id.bustype = BUS_I2C; | 289 | input->id.bustype = BUS_I2C; |
336 | input->dev.parent = &pdev->dev; | 290 | input->dev.parent = &pdev->dev; |
337 | 291 | ||
338 | error = matrix_keypad_build_keymap(plat->keymap_data, NULL, | ||
339 | STMPE_KEYPAD_MAX_ROWS, | ||
340 | STMPE_KEYPAD_MAX_COLS, | ||
341 | keypad->keymap, input); | ||
342 | if (error) | ||
343 | return error; | ||
344 | |||
345 | input_set_capability(input, EV_MSC, MSC_SCAN); | 292 | input_set_capability(input, EV_MSC, MSC_SCAN); |
293 | |||
294 | __set_bit(EV_KEY, input->evbit); | ||
346 | if (!plat->no_autorepeat) | 295 | if (!plat->no_autorepeat) |
347 | __set_bit(EV_REP, input->evbit); | 296 | __set_bit(EV_REP, input->evbit); |
348 | 297 | ||
349 | stmpe_keypad_fill_used_pins(keypad); | 298 | input->keycode = keypad->keymap; |
299 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
300 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
301 | |||
302 | matrix_keypad_build_keymap(plat->keymap_data, STMPE_KEYPAD_ROW_SHIFT, | ||
303 | input->keycode, input->keybit); | ||
304 | |||
305 | for (i = 0; i < plat->keymap_data->keymap_size; i++) { | ||
306 | unsigned int key = plat->keymap_data->keymap[i]; | ||
307 | |||
308 | keypad->cols |= 1 << KEY_COL(key); | ||
309 | keypad->rows |= 1 << KEY_ROW(key); | ||
310 | } | ||
350 | 311 | ||
351 | keypad->stmpe = stmpe; | 312 | keypad->stmpe = stmpe; |
352 | keypad->plat = plat; | 313 | keypad->plat = plat; |
353 | keypad->input = input; | 314 | keypad->input = input; |
354 | keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; | 315 | keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; |
355 | 316 | ||
356 | error = stmpe_keypad_chip_init(keypad); | 317 | ret = stmpe_keypad_chip_init(keypad); |
357 | if (error < 0) | 318 | if (ret < 0) |
358 | return error; | 319 | goto out_freeinput; |
359 | 320 | ||
360 | error = devm_request_threaded_irq(&pdev->dev, irq, | 321 | ret = input_register_device(input); |
361 | NULL, stmpe_keypad_irq, | 322 | if (ret) { |
362 | IRQF_ONESHOT, "stmpe-keypad", keypad); | 323 | dev_err(&pdev->dev, |
363 | if (error) { | 324 | "unable to register input device: %d\n", ret); |
364 | dev_err(&pdev->dev, "unable to get irq: %d\n", error); | 325 | goto out_freeinput; |
365 | return error; | ||
366 | } | 326 | } |
367 | 327 | ||
368 | error = input_register_device(input); | 328 | ret = request_threaded_irq(irq, NULL, stmpe_keypad_irq, IRQF_ONESHOT, |
369 | if (error) { | 329 | "stmpe-keypad", keypad); |
370 | dev_err(&pdev->dev, | 330 | if (ret) { |
371 | "unable to register input device: %d\n", error); | 331 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); |
372 | return error; | 332 | goto out_unregisterinput; |
373 | } | 333 | } |
374 | 334 | ||
375 | platform_set_drvdata(pdev, keypad); | 335 | platform_set_drvdata(pdev, keypad); |
376 | 336 | ||
377 | return 0; | 337 | return 0; |
338 | |||
339 | out_unregisterinput: | ||
340 | input_unregister_device(input); | ||
341 | input = NULL; | ||
342 | out_freeinput: | ||
343 | input_free_device(input); | ||
344 | out_freekeypad: | ||
345 | kfree(keypad); | ||
346 | return ret; | ||
378 | } | 347 | } |
379 | 348 | ||
380 | static int stmpe_keypad_remove(struct platform_device *pdev) | 349 | static int __devexit stmpe_keypad_remove(struct platform_device *pdev) |
381 | { | 350 | { |
382 | struct stmpe_keypad *keypad = platform_get_drvdata(pdev); | 351 | struct stmpe_keypad *keypad = platform_get_drvdata(pdev); |
352 | struct stmpe *stmpe = keypad->stmpe; | ||
353 | int irq = platform_get_irq(pdev, 0); | ||
383 | 354 | ||
384 | stmpe_disable(keypad->stmpe, STMPE_BLOCK_KEYPAD); | 355 | stmpe_disable(stmpe, STMPE_BLOCK_KEYPAD); |
356 | |||
357 | free_irq(irq, keypad); | ||
358 | input_unregister_device(keypad->input); | ||
359 | platform_set_drvdata(pdev, NULL); | ||
360 | kfree(keypad); | ||
385 | 361 | ||
386 | return 0; | 362 | return 0; |
387 | } | 363 | } |
@@ -390,9 +366,20 @@ static struct platform_driver stmpe_keypad_driver = { | |||
390 | .driver.name = "stmpe-keypad", | 366 | .driver.name = "stmpe-keypad", |
391 | .driver.owner = THIS_MODULE, | 367 | .driver.owner = THIS_MODULE, |
392 | .probe = stmpe_keypad_probe, | 368 | .probe = stmpe_keypad_probe, |
393 | .remove = stmpe_keypad_remove, | 369 | .remove = __devexit_p(stmpe_keypad_remove), |
394 | }; | 370 | }; |
395 | module_platform_driver(stmpe_keypad_driver); | 371 | |
372 | static int __init stmpe_keypad_init(void) | ||
373 | { | ||
374 | return platform_driver_register(&stmpe_keypad_driver); | ||
375 | } | ||
376 | module_init(stmpe_keypad_init); | ||
377 | |||
378 | static void __exit stmpe_keypad_exit(void) | ||
379 | { | ||
380 | platform_driver_unregister(&stmpe_keypad_driver); | ||
381 | } | ||
382 | module_exit(stmpe_keypad_exit); | ||
396 | 383 | ||
397 | MODULE_LICENSE("GPL v2"); | 384 | MODULE_LICENSE("GPL v2"); |
398 | MODULE_DESCRIPTION("STMPExxxx keypad driver"); | 385 | MODULE_DESCRIPTION("STMPExxxx keypad driver"); |
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index cc612c5d542..7437219370b 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c | |||
@@ -170,4 +170,15 @@ static struct serio_driver skbd_drv = { | |||
170 | .disconnect = skbd_disconnect, | 170 | .disconnect = skbd_disconnect, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | module_serio_driver(skbd_drv); | 173 | static int __init skbd_init(void) |
174 | { | ||
175 | return serio_register_driver(&skbd_drv); | ||
176 | } | ||
177 | |||
178 | static void __exit skbd_exit(void) | ||
179 | { | ||
180 | serio_unregister_driver(&skbd_drv); | ||
181 | } | ||
182 | |||
183 | module_init(skbd_init); | ||
184 | module_exit(skbd_exit); | ||
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 5f836b1638c..a99a04b03ee 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c | |||
@@ -369,4 +369,19 @@ static struct serio_driver sunkbd_drv = { | |||
369 | .disconnect = sunkbd_disconnect, | 369 | .disconnect = sunkbd_disconnect, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | module_serio_driver(sunkbd_drv); | 372 | /* |
373 | * The functions for insering/removing us as a module. | ||
374 | */ | ||
375 | |||
376 | static int __init sunkbd_init(void) | ||
377 | { | ||
378 | return serio_register_driver(&sunkbd_drv); | ||
379 | } | ||
380 | |||
381 | static void __exit sunkbd_exit(void) | ||
382 | { | ||
383 | serio_unregister_driver(&sunkbd_drv); | ||
384 | } | ||
385 | |||
386 | module_init(sunkbd_init); | ||
387 | module_exit(sunkbd_exit); | ||
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 2fb0d76a04c..99122f59e98 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c | |||
@@ -74,13 +74,11 @@ | |||
74 | 74 | ||
75 | /** | 75 | /** |
76 | * struct tc_keypad - data structure used by keypad driver | 76 | * struct tc_keypad - data structure used by keypad driver |
77 | * @tc3589x: pointer to tc35893 | ||
78 | * @input: pointer to input device object | 77 | * @input: pointer to input device object |
79 | * @board: keypad platform device | 78 | * @board: keypad platform device |
80 | * @krow: number of rows | 79 | * @krow: number of rows |
81 | * @kcol: number of columns | 80 | * @kcol: number of coloumns |
82 | * @keymap: matrix scan code table for keycodes | 81 | * @keymap: matrix scan code table for keycodes |
83 | * @keypad_stopped: holds keypad status | ||
84 | */ | 82 | */ |
85 | struct tc_keypad { | 83 | struct tc_keypad { |
86 | struct tc3589x *tc3589x; | 84 | struct tc3589x *tc3589x; |
@@ -92,19 +90,25 @@ struct tc_keypad { | |||
92 | bool keypad_stopped; | 90 | bool keypad_stopped; |
93 | }; | 91 | }; |
94 | 92 | ||
95 | static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) | 93 | static int __devinit tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) |
96 | { | 94 | { |
97 | int ret; | 95 | int ret; |
98 | struct tc3589x *tc3589x = keypad->tc3589x; | 96 | struct tc3589x *tc3589x = keypad->tc3589x; |
99 | const struct tc3589x_keypad_platform_data *board = keypad->board; | 97 | u8 settle_time = keypad->board->settle_time; |
100 | 98 | u8 dbounce_period = keypad->board->debounce_period; | |
101 | /* validate platform configuration */ | 99 | u8 rows = keypad->board->krow & 0xf; /* mask out the nibble */ |
102 | if (board->kcol > TC3589x_MAX_KPCOL || board->krow > TC3589x_MAX_KPROW) | 100 | u8 column = keypad->board->kcol & 0xf; /* mask out the nibble */ |
101 | |||
102 | /* validate platform configurations */ | ||
103 | if (keypad->board->kcol > TC3589x_MAX_KPCOL || | ||
104 | keypad->board->krow > TC3589x_MAX_KPROW || | ||
105 | keypad->board->debounce_period > TC3589x_MAX_DEBOUNCE_SETTLE || | ||
106 | keypad->board->settle_time > TC3589x_MAX_DEBOUNCE_SETTLE) | ||
103 | return -EINVAL; | 107 | return -EINVAL; |
104 | 108 | ||
105 | /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ | 109 | /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ |
106 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, | 110 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, |
107 | (board->krow << KP_ROW_SHIFT) | board->kcol); | 111 | (rows << KP_ROW_SHIFT) | column); |
108 | if (ret < 0) | 112 | if (ret < 0) |
109 | return ret; | 113 | return ret; |
110 | 114 | ||
@@ -118,14 +122,12 @@ static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) | |||
118 | return ret; | 122 | return ret; |
119 | 123 | ||
120 | /* Configure settle time */ | 124 | /* Configure settle time */ |
121 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, | 125 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, settle_time); |
122 | board->settle_time); | ||
123 | if (ret < 0) | 126 | if (ret < 0) |
124 | return ret; | 127 | return ret; |
125 | 128 | ||
126 | /* Configure debounce time */ | 129 | /* Configure debounce time */ |
127 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, | 130 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, dbounce_period); |
128 | board->debounce_period); | ||
129 | if (ret < 0) | 131 | if (ret < 0) |
130 | return ret; | 132 | return ret; |
131 | 133 | ||
@@ -299,7 +301,7 @@ static void tc3589x_keypad_close(struct input_dev *input) | |||
299 | tc3589x_keypad_disable(keypad); | 301 | tc3589x_keypad_disable(keypad); |
300 | } | 302 | } |
301 | 303 | ||
302 | static int tc3589x_keypad_probe(struct platform_device *pdev) | 304 | static int __devinit tc3589x_keypad_probe(struct platform_device *pdev) |
303 | { | 305 | { |
304 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); | 306 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); |
305 | struct tc_keypad *keypad; | 307 | struct tc_keypad *keypad; |
@@ -333,22 +335,23 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) | |||
333 | input->name = pdev->name; | 335 | input->name = pdev->name; |
334 | input->dev.parent = &pdev->dev; | 336 | input->dev.parent = &pdev->dev; |
335 | 337 | ||
338 | input->keycode = keypad->keymap; | ||
339 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
340 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
341 | |||
336 | input->open = tc3589x_keypad_open; | 342 | input->open = tc3589x_keypad_open; |
337 | input->close = tc3589x_keypad_close; | 343 | input->close = tc3589x_keypad_close; |
338 | 344 | ||
339 | error = matrix_keypad_build_keymap(plat->keymap_data, NULL, | 345 | input_set_drvdata(input, keypad); |
340 | TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL, | ||
341 | keypad->keymap, input); | ||
342 | if (error) { | ||
343 | dev_err(&pdev->dev, "Failed to build keymap\n"); | ||
344 | goto err_free_mem; | ||
345 | } | ||
346 | 346 | ||
347 | input_set_capability(input, EV_MSC, MSC_SCAN); | 347 | input_set_capability(input, EV_MSC, MSC_SCAN); |
348 | |||
349 | __set_bit(EV_KEY, input->evbit); | ||
348 | if (!plat->no_autorepeat) | 350 | if (!plat->no_autorepeat) |
349 | __set_bit(EV_REP, input->evbit); | 351 | __set_bit(EV_REP, input->evbit); |
350 | 352 | ||
351 | input_set_drvdata(input, keypad); | 353 | matrix_keypad_build_keymap(plat->keymap_data, 0x3, |
354 | input->keycode, input->keybit); | ||
352 | 355 | ||
353 | error = request_threaded_irq(irq, NULL, | 356 | error = request_threaded_irq(irq, NULL, |
354 | tc3589x_keypad_irq, plat->irqtype, | 357 | tc3589x_keypad_irq, plat->irqtype, |
@@ -382,7 +385,7 @@ err_free_mem: | |||
382 | return error; | 385 | return error; |
383 | } | 386 | } |
384 | 387 | ||
385 | static int tc3589x_keypad_remove(struct platform_device *pdev) | 388 | static int __devexit tc3589x_keypad_remove(struct platform_device *pdev) |
386 | { | 389 | { |
387 | struct tc_keypad *keypad = platform_get_drvdata(pdev); | 390 | struct tc_keypad *keypad = platform_get_drvdata(pdev); |
388 | int irq = platform_get_irq(pdev, 0); | 391 | int irq = platform_get_irq(pdev, 0); |
@@ -448,9 +451,20 @@ static struct platform_driver tc3589x_keypad_driver = { | |||
448 | .pm = &tc3589x_keypad_dev_pm_ops, | 451 | .pm = &tc3589x_keypad_dev_pm_ops, |
449 | }, | 452 | }, |
450 | .probe = tc3589x_keypad_probe, | 453 | .probe = tc3589x_keypad_probe, |
451 | .remove = tc3589x_keypad_remove, | 454 | .remove = __devexit_p(tc3589x_keypad_remove), |
452 | }; | 455 | }; |
453 | module_platform_driver(tc3589x_keypad_driver); | 456 | |
457 | static int __init tc3589x_keypad_init(void) | ||
458 | { | ||
459 | return platform_driver_register(&tc3589x_keypad_driver); | ||
460 | } | ||
461 | module_init(tc3589x_keypad_init); | ||
462 | |||
463 | static void __exit tc3589x_keypad_exit(void) | ||
464 | { | ||
465 | return platform_driver_unregister(&tc3589x_keypad_driver); | ||
466 | } | ||
467 | module_exit(tc3589x_keypad_exit); | ||
454 | 468 | ||
455 | MODULE_LICENSE("GPL v2"); | 469 | MODULE_LICENSE("GPL v2"); |
456 | MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer"); | 470 | MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer"); |
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index bfc832c35a7..3afea3f8971 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c | |||
@@ -166,7 +166,7 @@ static void tca6416_keys_close(struct input_dev *dev) | |||
166 | disable_irq(chip->irqnum); | 166 | disable_irq(chip->irqnum); |
167 | } | 167 | } |
168 | 168 | ||
169 | static int tca6416_setup_registers(struct tca6416_keypad_chip *chip) | 169 | static int __devinit tca6416_setup_registers(struct tca6416_keypad_chip *chip) |
170 | { | 170 | { |
171 | int error; | 171 | int error; |
172 | 172 | ||
@@ -197,7 +197,7 @@ static int tca6416_setup_registers(struct tca6416_keypad_chip *chip) | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | static int tca6416_keypad_probe(struct i2c_client *client, | 200 | static int __devinit tca6416_keypad_probe(struct i2c_client *client, |
201 | const struct i2c_device_id *id) | 201 | const struct i2c_device_id *id) |
202 | { | 202 | { |
203 | struct tca6416_keys_platform_data *pdata; | 203 | struct tca6416_keys_platform_data *pdata; |
@@ -278,8 +278,7 @@ static int tca6416_keypad_probe(struct i2c_client *client, | |||
278 | 278 | ||
279 | error = request_threaded_irq(chip->irqnum, NULL, | 279 | error = request_threaded_irq(chip->irqnum, NULL, |
280 | tca6416_keys_isr, | 280 | tca6416_keys_isr, |
281 | IRQF_TRIGGER_FALLING | | 281 | IRQF_TRIGGER_FALLING, |
282 | IRQF_ONESHOT, | ||
283 | "tca6416-keypad", chip); | 282 | "tca6416-keypad", chip); |
284 | if (error) { | 283 | if (error) { |
285 | dev_dbg(&client->dev, | 284 | dev_dbg(&client->dev, |
@@ -313,7 +312,7 @@ fail1: | |||
313 | return error; | 312 | return error; |
314 | } | 313 | } |
315 | 314 | ||
316 | static int tca6416_keypad_remove(struct i2c_client *client) | 315 | static int __devexit tca6416_keypad_remove(struct i2c_client *client) |
317 | { | 316 | { |
318 | struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); | 317 | struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); |
319 | 318 | ||
@@ -361,7 +360,7 @@ static struct i2c_driver tca6416_keypad_driver = { | |||
361 | .pm = &tca6416_keypad_dev_pm_ops, | 360 | .pm = &tca6416_keypad_dev_pm_ops, |
362 | }, | 361 | }, |
363 | .probe = tca6416_keypad_probe, | 362 | .probe = tca6416_keypad_probe, |
364 | .remove = tca6416_keypad_remove, | 363 | .remove = __devexit_p(tca6416_keypad_remove), |
365 | .id_table = tca6416_id, | 364 | .id_table = tca6416_id, |
366 | }; | 365 | }; |
367 | 366 | ||
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c deleted file mode 100644 index a34cc6714e5..00000000000 --- a/drivers/input/keyboard/tca8418_keypad.c +++ /dev/null | |||
@@ -1,418 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for TCA8418 I2C keyboard | ||
3 | * | ||
4 | * Copyright (C) 2011 Fuel7, Inc. All rights reserved. | ||
5 | * | ||
6 | * Author: Kyle Manna <kyle.manna@fuel7.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public | ||
10 | * License v2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public | ||
18 | * License along with this program; if not, write to the | ||
19 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
20 | * Boston, MA 021110-1307, USA. | ||
21 | * | ||
22 | * If you can't comply with GPLv2, alternative licensing terms may be | ||
23 | * arranged. Please contact Fuel7, Inc. (http://fuel7.com/) for proprietary | ||
24 | * alternative licensing inquiries. | ||
25 | */ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/workqueue.h> | ||
34 | #include <linux/gpio.h> | ||
35 | #include <linux/i2c.h> | ||
36 | #include <linux/input.h> | ||
37 | #include <linux/input/tca8418_keypad.h> | ||
38 | #include <linux/of.h> | ||
39 | |||
40 | /* TCA8418 hardware limits */ | ||
41 | #define TCA8418_MAX_ROWS 8 | ||
42 | #define TCA8418_MAX_COLS 10 | ||
43 | |||
44 | /* TCA8418 register offsets */ | ||
45 | #define REG_CFG 0x01 | ||
46 | #define REG_INT_STAT 0x02 | ||
47 | #define REG_KEY_LCK_EC 0x03 | ||
48 | #define REG_KEY_EVENT_A 0x04 | ||
49 | #define REG_KEY_EVENT_B 0x05 | ||
50 | #define REG_KEY_EVENT_C 0x06 | ||
51 | #define REG_KEY_EVENT_D 0x07 | ||
52 | #define REG_KEY_EVENT_E 0x08 | ||
53 | #define REG_KEY_EVENT_F 0x09 | ||
54 | #define REG_KEY_EVENT_G 0x0A | ||
55 | #define REG_KEY_EVENT_H 0x0B | ||
56 | #define REG_KEY_EVENT_I 0x0C | ||
57 | #define REG_KEY_EVENT_J 0x0D | ||
58 | #define REG_KP_LCK_TIMER 0x0E | ||
59 | #define REG_UNLOCK1 0x0F | ||
60 | #define REG_UNLOCK2 0x10 | ||
61 | #define REG_GPIO_INT_STAT1 0x11 | ||
62 | #define REG_GPIO_INT_STAT2 0x12 | ||
63 | #define REG_GPIO_INT_STAT3 0x13 | ||
64 | #define REG_GPIO_DAT_STAT1 0x14 | ||
65 | #define REG_GPIO_DAT_STAT2 0x15 | ||
66 | #define REG_GPIO_DAT_STAT3 0x16 | ||
67 | #define REG_GPIO_DAT_OUT1 0x17 | ||
68 | #define REG_GPIO_DAT_OUT2 0x18 | ||
69 | #define REG_GPIO_DAT_OUT3 0x19 | ||
70 | #define REG_GPIO_INT_EN1 0x1A | ||
71 | #define REG_GPIO_INT_EN2 0x1B | ||
72 | #define REG_GPIO_INT_EN3 0x1C | ||
73 | #define REG_KP_GPIO1 0x1D | ||
74 | #define REG_KP_GPIO2 0x1E | ||
75 | #define REG_KP_GPIO3 0x1F | ||
76 | #define REG_GPI_EM1 0x20 | ||
77 | #define REG_GPI_EM2 0x21 | ||
78 | #define REG_GPI_EM3 0x22 | ||
79 | #define REG_GPIO_DIR1 0x23 | ||
80 | #define REG_GPIO_DIR2 0x24 | ||
81 | #define REG_GPIO_DIR3 0x25 | ||
82 | #define REG_GPIO_INT_LVL1 0x26 | ||
83 | #define REG_GPIO_INT_LVL2 0x27 | ||
84 | #define REG_GPIO_INT_LVL3 0x28 | ||
85 | #define REG_DEBOUNCE_DIS1 0x29 | ||
86 | #define REG_DEBOUNCE_DIS2 0x2A | ||
87 | #define REG_DEBOUNCE_DIS3 0x2B | ||
88 | #define REG_GPIO_PULL1 0x2C | ||
89 | #define REG_GPIO_PULL2 0x2D | ||
90 | #define REG_GPIO_PULL3 0x2E | ||
91 | |||
92 | /* TCA8418 bit definitions */ | ||
93 | #define CFG_AI BIT(7) | ||
94 | #define CFG_GPI_E_CFG BIT(6) | ||
95 | #define CFG_OVR_FLOW_M BIT(5) | ||
96 | #define CFG_INT_CFG BIT(4) | ||
97 | #define CFG_OVR_FLOW_IEN BIT(3) | ||
98 | #define CFG_K_LCK_IEN BIT(2) | ||
99 | #define CFG_GPI_IEN BIT(1) | ||
100 | #define CFG_KE_IEN BIT(0) | ||
101 | |||
102 | #define INT_STAT_CAD_INT BIT(4) | ||
103 | #define INT_STAT_OVR_FLOW_INT BIT(3) | ||
104 | #define INT_STAT_K_LCK_INT BIT(2) | ||
105 | #define INT_STAT_GPI_INT BIT(1) | ||
106 | #define INT_STAT_K_INT BIT(0) | ||
107 | |||
108 | /* TCA8418 register masks */ | ||
109 | #define KEY_LCK_EC_KEC 0x7 | ||
110 | #define KEY_EVENT_CODE 0x7f | ||
111 | #define KEY_EVENT_VALUE 0x80 | ||
112 | |||
113 | struct tca8418_keypad { | ||
114 | struct i2c_client *client; | ||
115 | struct input_dev *input; | ||
116 | |||
117 | unsigned int row_shift; | ||
118 | }; | ||
119 | |||
120 | /* | ||
121 | * Write a byte to the TCA8418 | ||
122 | */ | ||
123 | static int tca8418_write_byte(struct tca8418_keypad *keypad_data, | ||
124 | int reg, u8 val) | ||
125 | { | ||
126 | int error; | ||
127 | |||
128 | error = i2c_smbus_write_byte_data(keypad_data->client, reg, val); | ||
129 | if (error < 0) { | ||
130 | dev_err(&keypad_data->client->dev, | ||
131 | "%s failed, reg: %d, val: %d, error: %d\n", | ||
132 | __func__, reg, val, error); | ||
133 | return error; | ||
134 | } | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Read a byte from the TCA8418 | ||
141 | */ | ||
142 | static int tca8418_read_byte(struct tca8418_keypad *keypad_data, | ||
143 | int reg, u8 *val) | ||
144 | { | ||
145 | int error; | ||
146 | |||
147 | error = i2c_smbus_read_byte_data(keypad_data->client, reg); | ||
148 | if (error < 0) { | ||
149 | dev_err(&keypad_data->client->dev, | ||
150 | "%s failed, reg: %d, error: %d\n", | ||
151 | __func__, reg, error); | ||
152 | return error; | ||
153 | } | ||
154 | |||
155 | *val = (u8)error; | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) | ||
161 | { | ||
162 | struct input_dev *input = keypad_data->input; | ||
163 | unsigned short *keymap = input->keycode; | ||
164 | int error, col, row; | ||
165 | u8 reg, state, code; | ||
166 | |||
167 | /* Initial read of the key event FIFO */ | ||
168 | error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); | ||
169 | |||
170 | /* Assume that key code 0 signifies empty FIFO */ | ||
171 | while (error >= 0 && reg > 0) { | ||
172 | state = reg & KEY_EVENT_VALUE; | ||
173 | code = reg & KEY_EVENT_CODE; | ||
174 | |||
175 | row = code / TCA8418_MAX_COLS; | ||
176 | col = code % TCA8418_MAX_COLS; | ||
177 | |||
178 | row = (col) ? row : row - 1; | ||
179 | col = (col) ? col - 1 : TCA8418_MAX_COLS - 1; | ||
180 | |||
181 | code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); | ||
182 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
183 | input_report_key(input, keymap[code], state); | ||
184 | |||
185 | /* Read for next loop */ | ||
186 | error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); | ||
187 | } | ||
188 | |||
189 | if (error < 0) | ||
190 | dev_err(&keypad_data->client->dev, | ||
191 | "unable to read REG_KEY_EVENT_A\n"); | ||
192 | |||
193 | input_sync(input); | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * Threaded IRQ handler and this can (and will) sleep. | ||
198 | */ | ||
199 | static irqreturn_t tca8418_irq_handler(int irq, void *dev_id) | ||
200 | { | ||
201 | struct tca8418_keypad *keypad_data = dev_id; | ||
202 | u8 reg; | ||
203 | int error; | ||
204 | |||
205 | error = tca8418_read_byte(keypad_data, REG_INT_STAT, ®); | ||
206 | if (error) { | ||
207 | dev_err(&keypad_data->client->dev, | ||
208 | "unable to read REG_INT_STAT\n"); | ||
209 | return IRQ_NONE; | ||
210 | } | ||
211 | |||
212 | if (!reg) | ||
213 | return IRQ_NONE; | ||
214 | |||
215 | if (reg & INT_STAT_OVR_FLOW_INT) | ||
216 | dev_warn(&keypad_data->client->dev, "overflow occurred\n"); | ||
217 | |||
218 | if (reg & INT_STAT_K_INT) | ||
219 | tca8418_read_keypad(keypad_data); | ||
220 | |||
221 | /* Clear all interrupts, even IRQs we didn't check (GPI, CAD, LCK) */ | ||
222 | reg = 0xff; | ||
223 | error = tca8418_write_byte(keypad_data, REG_INT_STAT, reg); | ||
224 | if (error) | ||
225 | dev_err(&keypad_data->client->dev, | ||
226 | "unable to clear REG_INT_STAT\n"); | ||
227 | |||
228 | return IRQ_HANDLED; | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | * Configure the TCA8418 for keypad operation | ||
233 | */ | ||
234 | static int tca8418_configure(struct tca8418_keypad *keypad_data, | ||
235 | u32 rows, u32 cols) | ||
236 | { | ||
237 | int reg, error; | ||
238 | |||
239 | /* Write config register, if this fails assume device not present */ | ||
240 | error = tca8418_write_byte(keypad_data, REG_CFG, | ||
241 | CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN); | ||
242 | if (error < 0) | ||
243 | return -ENODEV; | ||
244 | |||
245 | |||
246 | /* Assemble a mask for row and column registers */ | ||
247 | reg = ~(~0 << rows); | ||
248 | reg += (~(~0 << cols)) << 8; | ||
249 | |||
250 | /* Set registers to keypad mode */ | ||
251 | error |= tca8418_write_byte(keypad_data, REG_KP_GPIO1, reg); | ||
252 | error |= tca8418_write_byte(keypad_data, REG_KP_GPIO2, reg >> 8); | ||
253 | error |= tca8418_write_byte(keypad_data, REG_KP_GPIO3, reg >> 16); | ||
254 | |||
255 | /* Enable column debouncing */ | ||
256 | error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS1, reg); | ||
257 | error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8); | ||
258 | error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16); | ||
259 | |||
260 | return error; | ||
261 | } | ||
262 | |||
263 | static int tca8418_keypad_probe(struct i2c_client *client, | ||
264 | const struct i2c_device_id *id) | ||
265 | { | ||
266 | struct device *dev = &client->dev; | ||
267 | const struct tca8418_keypad_platform_data *pdata = | ||
268 | dev_get_platdata(dev); | ||
269 | struct tca8418_keypad *keypad_data; | ||
270 | struct input_dev *input; | ||
271 | const struct matrix_keymap_data *keymap_data = NULL; | ||
272 | u32 rows = 0, cols = 0; | ||
273 | bool rep = false; | ||
274 | bool irq_is_gpio = false; | ||
275 | int irq; | ||
276 | int error, row_shift, max_keys; | ||
277 | |||
278 | /* Copy the platform data */ | ||
279 | if (pdata) { | ||
280 | if (!pdata->keymap_data) { | ||
281 | dev_err(dev, "no keymap data defined\n"); | ||
282 | return -EINVAL; | ||
283 | } | ||
284 | keymap_data = pdata->keymap_data; | ||
285 | rows = pdata->rows; | ||
286 | cols = pdata->cols; | ||
287 | rep = pdata->rep; | ||
288 | irq_is_gpio = pdata->irq_is_gpio; | ||
289 | } else { | ||
290 | struct device_node *np = dev->of_node; | ||
291 | of_property_read_u32(np, "keypad,num-rows", &rows); | ||
292 | of_property_read_u32(np, "keypad,num-columns", &cols); | ||
293 | rep = of_property_read_bool(np, "keypad,autorepeat"); | ||
294 | } | ||
295 | |||
296 | if (!rows || rows > TCA8418_MAX_ROWS) { | ||
297 | dev_err(dev, "invalid rows\n"); | ||
298 | return -EINVAL; | ||
299 | } | ||
300 | |||
301 | if (!cols || cols > TCA8418_MAX_COLS) { | ||
302 | dev_err(dev, "invalid columns\n"); | ||
303 | return -EINVAL; | ||
304 | } | ||
305 | |||
306 | /* Check i2c driver capabilities */ | ||
307 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { | ||
308 | dev_err(dev, "%s adapter not supported\n", | ||
309 | dev_driver_string(&client->adapter->dev)); | ||
310 | return -ENODEV; | ||
311 | } | ||
312 | |||
313 | row_shift = get_count_order(cols); | ||
314 | max_keys = rows << row_shift; | ||
315 | |||
316 | /* Allocate memory for keypad_data and input device */ | ||
317 | keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL); | ||
318 | if (!keypad_data) | ||
319 | return -ENOMEM; | ||
320 | |||
321 | keypad_data->client = client; | ||
322 | keypad_data->row_shift = row_shift; | ||
323 | |||
324 | /* Initialize the chip or fail if chip isn't present */ | ||
325 | error = tca8418_configure(keypad_data, rows, cols); | ||
326 | if (error < 0) | ||
327 | return error; | ||
328 | |||
329 | /* Configure input device */ | ||
330 | input = devm_input_allocate_device(dev); | ||
331 | if (!input) | ||
332 | return -ENOMEM; | ||
333 | |||
334 | keypad_data->input = input; | ||
335 | |||
336 | input->name = client->name; | ||
337 | input->id.bustype = BUS_I2C; | ||
338 | input->id.vendor = 0x0001; | ||
339 | input->id.product = 0x001; | ||
340 | input->id.version = 0x0001; | ||
341 | |||
342 | error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, | ||
343 | NULL, input); | ||
344 | if (error) { | ||
345 | dev_err(dev, "Failed to build keymap\n"); | ||
346 | return error; | ||
347 | } | ||
348 | |||
349 | if (rep) | ||
350 | __set_bit(EV_REP, input->evbit); | ||
351 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
352 | |||
353 | input_set_drvdata(input, keypad_data); | ||
354 | |||
355 | irq = client->irq; | ||
356 | if (irq_is_gpio) | ||
357 | irq = gpio_to_irq(irq); | ||
358 | |||
359 | error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, | ||
360 | IRQF_TRIGGER_FALLING | | ||
361 | IRQF_SHARED | | ||
362 | IRQF_ONESHOT, | ||
363 | client->name, keypad_data); | ||
364 | if (error) { | ||
365 | dev_err(dev, "Unable to claim irq %d; error %d\n", | ||
366 | client->irq, error); | ||
367 | return error; | ||
368 | } | ||
369 | |||
370 | error = input_register_device(input); | ||
371 | if (error) { | ||
372 | dev_err(dev, "Unable to register input device, error: %d\n", | ||
373 | error); | ||
374 | return error; | ||
375 | } | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static const struct i2c_device_id tca8418_id[] = { | ||
381 | { TCA8418_NAME, 8418, }, | ||
382 | { } | ||
383 | }; | ||
384 | MODULE_DEVICE_TABLE(i2c, tca8418_id); | ||
385 | |||
386 | #ifdef CONFIG_OF | ||
387 | static const struct of_device_id tca8418_dt_ids[] = { | ||
388 | { .compatible = "ti,tca8418", }, | ||
389 | { } | ||
390 | }; | ||
391 | MODULE_DEVICE_TABLE(of, tca8418_dt_ids); | ||
392 | #endif | ||
393 | |||
394 | static struct i2c_driver tca8418_keypad_driver = { | ||
395 | .driver = { | ||
396 | .name = TCA8418_NAME, | ||
397 | .owner = THIS_MODULE, | ||
398 | .of_match_table = of_match_ptr(tca8418_dt_ids), | ||
399 | }, | ||
400 | .probe = tca8418_keypad_probe, | ||
401 | .id_table = tca8418_id, | ||
402 | }; | ||
403 | |||
404 | static int __init tca8418_keypad_init(void) | ||
405 | { | ||
406 | return i2c_add_driver(&tca8418_keypad_driver); | ||
407 | } | ||
408 | subsys_initcall(tca8418_keypad_init); | ||
409 | |||
410 | static void __exit tca8418_keypad_exit(void) | ||
411 | { | ||
412 | i2c_del_driver(&tca8418_keypad_driver); | ||
413 | } | ||
414 | module_exit(tca8418_keypad_exit); | ||
415 | |||
416 | MODULE_AUTHOR("Kyle Manna <kyle.manna@fuel7.com>"); | ||
417 | MODULE_DESCRIPTION("Keypad driver for TCA8418"); | ||
418 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index c76f96872d3..01ee7485236 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -26,11 +26,10 @@ | |||
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/of.h> | ||
30 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
32 | #include <linux/input/tegra_kbc.h> | ||
33 | #include <mach/clk.h> | 31 | #include <mach/clk.h> |
32 | #include <mach/kbc.h> | ||
34 | 33 | ||
35 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu | 34 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu |
36 | 35 | ||
@@ -48,13 +47,12 @@ | |||
48 | #define KBC_FIFO_TH_CNT_SHIFT(cnt) (cnt << 14) | 47 | #define KBC_FIFO_TH_CNT_SHIFT(cnt) (cnt << 14) |
49 | #define KBC_DEBOUNCE_CNT_SHIFT(cnt) (cnt << 4) | 48 | #define KBC_DEBOUNCE_CNT_SHIFT(cnt) (cnt << 4) |
50 | #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) | 49 | #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) |
51 | #define KBC_CONTROL_KEYPRESS_INT_EN (1 << 1) | ||
52 | #define KBC_CONTROL_KBC_EN (1 << 0) | 50 | #define KBC_CONTROL_KBC_EN (1 << 0) |
51 | #define KBC_CONTROL_KP_INT_EN (1<<1) | ||
53 | 52 | ||
54 | /* KBC Interrupt Register */ | 53 | /* KBC Interrupt Register */ |
55 | #define KBC_INT_0 0x4 | 54 | #define KBC_INT_0 0x4 |
56 | #define KBC_INT_FIFO_CNT_INT_STATUS (1 << 2) | 55 | #define KBC_INT_FIFO_CNT_INT_STATUS (1 << 2) |
57 | #define KBC_INT_KEYPRESS_INT_STATUS (1 << 0) | ||
58 | 56 | ||
59 | #define KBC_ROW_CFG0_0 0x8 | 57 | #define KBC_ROW_CFG0_0 0x8 |
60 | #define KBC_COL_CFG0_0 0x18 | 58 | #define KBC_COL_CFG0_0 0x18 |
@@ -66,25 +64,29 @@ | |||
66 | #define KBC_ROW0_MASK_0 0x38 | 64 | #define KBC_ROW0_MASK_0 0x38 |
67 | 65 | ||
68 | #define KBC_ROW_SHIFT 3 | 66 | #define KBC_ROW_SHIFT 3 |
67 | #define DEFAULT_SCAN_COUNT 2 | ||
68 | #define DEFAULT_INIT_DLY 5 | ||
69 | 69 | ||
70 | struct tegra_kbc { | 70 | struct tegra_kbc { |
71 | void __iomem *mmio; | 71 | void __iomem *mmio; |
72 | struct input_dev *idev; | 72 | struct input_dev *idev; |
73 | unsigned int irq; | 73 | unsigned int irq; |
74 | unsigned int wake_enable_rows; | ||
75 | unsigned int wake_enable_cols; | ||
74 | spinlock_t lock; | 76 | spinlock_t lock; |
75 | unsigned int repoll_dly; | 77 | unsigned int repoll_dly; |
76 | unsigned long cp_dly_jiffies; | 78 | unsigned long cp_dly_jiffies; |
77 | unsigned int cp_to_wkup_dly; | ||
78 | bool use_fn_map; | 79 | bool use_fn_map; |
79 | bool use_ghost_filter; | 80 | bool use_ghost_filter; |
80 | bool keypress_caused_wake; | ||
81 | const struct tegra_kbc_platform_data *pdata; | 81 | const struct tegra_kbc_platform_data *pdata; |
82 | unsigned short keycode[KBC_MAX_KEY * 2]; | 82 | unsigned short keycode[KBC_MAX_KEY * 2]; |
83 | unsigned short current_keys[KBC_MAX_KPENT]; | 83 | unsigned short current_keys[KBC_MAX_KPENT]; |
84 | unsigned int num_pressed_keys; | 84 | unsigned int num_pressed_keys; |
85 | u32 wakeup_key; | ||
86 | struct timer_list timer; | 85 | struct timer_list timer; |
87 | struct clk *clk; | 86 | struct clk *clk; |
87 | int is_open; | ||
88 | unsigned long scan_timeout_count; | ||
89 | unsigned long one_scan_time; | ||
88 | }; | 90 | }; |
89 | 91 | ||
90 | static const u32 tegra_kbc_default_keymap[] = { | 92 | static const u32 tegra_kbc_default_keymap[] = { |
@@ -222,8 +224,7 @@ static const u32 tegra_kbc_default_keymap[] = { | |||
222 | KEY(31, 4, KEY_HELP), | 224 | KEY(31, 4, KEY_HELP), |
223 | }; | 225 | }; |
224 | 226 | ||
225 | static const | 227 | static const struct matrix_keymap_data tegra_kbc_default_keymap_data = { |
226 | struct matrix_keymap_data tegra_kbc_default_keymap_data = { | ||
227 | .keymap = tegra_kbc_default_keymap, | 228 | .keymap = tegra_kbc_default_keymap, |
228 | .keymap_size = ARRAY_SIZE(tegra_kbc_default_keymap), | 229 | .keymap_size = ARRAY_SIZE(tegra_kbc_default_keymap), |
229 | }; | 230 | }; |
@@ -266,10 +267,12 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | |||
266 | u32 val = 0; | 267 | u32 val = 0; |
267 | unsigned int i; | 268 | unsigned int i; |
268 | unsigned int num_down = 0; | 269 | unsigned int num_down = 0; |
270 | unsigned long flags; | ||
269 | bool fn_keypress = false; | 271 | bool fn_keypress = false; |
270 | bool key_in_same_row = false; | 272 | bool key_in_same_row = false; |
271 | bool key_in_same_col = false; | 273 | bool key_in_same_col = false; |
272 | 274 | ||
275 | spin_lock_irqsave(&kbc->lock, flags); | ||
273 | for (i = 0; i < KBC_MAX_KPENT; i++) { | 276 | for (i = 0; i < KBC_MAX_KPENT; i++) { |
274 | if ((i % 4) == 0) | 277 | if ((i % 4) == 0) |
275 | val = readl(kbc->mmio + KBC_KP_ENT0_0 + i); | 278 | val = readl(kbc->mmio + KBC_KP_ENT0_0 + i); |
@@ -298,7 +301,7 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | |||
298 | * any 2 of the 3 keys share a row, and any 2 of them share a column. | 301 | * any 2 of the 3 keys share a row, and any 2 of them share a column. |
299 | * If so ignore the key presses for this iteration. | 302 | * If so ignore the key presses for this iteration. |
300 | */ | 303 | */ |
301 | if (kbc->use_ghost_filter && num_down >= 3) { | 304 | if ((kbc->use_ghost_filter) && (num_down >= 3)) { |
302 | for (i = 0; i < num_down; i++) { | 305 | for (i = 0; i < num_down; i++) { |
303 | unsigned int j; | 306 | unsigned int j; |
304 | u8 curr_col = scancodes[i] & 0x07; | 307 | u8 curr_col = scancodes[i] & 0x07; |
@@ -331,6 +334,8 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | |||
331 | } | 334 | } |
332 | } | 335 | } |
333 | 336 | ||
337 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
338 | |||
334 | /* Ignore the key presses for this iteration? */ | 339 | /* Ignore the key presses for this iteration? */ |
335 | if (key_in_same_col && key_in_same_row) | 340 | if (key_in_same_col && key_in_same_row) |
336 | return; | 341 | return; |
@@ -345,30 +350,6 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | |||
345 | kbc->num_pressed_keys = num_down; | 350 | kbc->num_pressed_keys = num_down; |
346 | } | 351 | } |
347 | 352 | ||
348 | static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable) | ||
349 | { | ||
350 | u32 val; | ||
351 | |||
352 | val = readl(kbc->mmio + KBC_CONTROL_0); | ||
353 | if (enable) | ||
354 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; | ||
355 | else | ||
356 | val &= ~KBC_CONTROL_FIFO_CNT_INT_EN; | ||
357 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
358 | } | ||
359 | |||
360 | static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable) | ||
361 | { | ||
362 | u32 val; | ||
363 | |||
364 | val = readl(kbc->mmio + KBC_CONTROL_0); | ||
365 | if (enable) | ||
366 | val |= KBC_CONTROL_KEYPRESS_INT_EN; | ||
367 | else | ||
368 | val &= ~KBC_CONTROL_KEYPRESS_INT_EN; | ||
369 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
370 | } | ||
371 | |||
372 | static void tegra_kbc_keypress_timer(unsigned long data) | 353 | static void tegra_kbc_keypress_timer(unsigned long data) |
373 | { | 354 | { |
374 | struct tegra_kbc *kbc = (struct tegra_kbc *)data; | 355 | struct tegra_kbc *kbc = (struct tegra_kbc *)data; |
@@ -376,8 +357,6 @@ static void tegra_kbc_keypress_timer(unsigned long data) | |||
376 | u32 val; | 357 | u32 val; |
377 | unsigned int i; | 358 | unsigned int i; |
378 | 359 | ||
379 | spin_lock_irqsave(&kbc->lock, flags); | ||
380 | |||
381 | val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf; | 360 | val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf; |
382 | if (val) { | 361 | if (val) { |
383 | unsigned long dly; | 362 | unsigned long dly; |
@@ -399,19 +378,26 @@ static void tegra_kbc_keypress_timer(unsigned long data) | |||
399 | kbc->num_pressed_keys = 0; | 378 | kbc->num_pressed_keys = 0; |
400 | 379 | ||
401 | /* All keys are released so enable the keypress interrupt */ | 380 | /* All keys are released so enable the keypress interrupt */ |
402 | tegra_kbc_set_fifo_interrupt(kbc, true); | 381 | spin_lock_irqsave(&kbc->lock, flags); |
382 | val = readl(kbc->mmio + KBC_CONTROL_0); | ||
383 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; | ||
384 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
385 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
403 | } | 386 | } |
404 | |||
405 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
406 | } | 387 | } |
407 | 388 | ||
408 | static irqreturn_t tegra_kbc_isr(int irq, void *args) | 389 | static irqreturn_t tegra_kbc_isr(int irq, void *args) |
409 | { | 390 | { |
410 | struct tegra_kbc *kbc = args; | 391 | struct tegra_kbc *kbc = args; |
411 | unsigned long flags; | 392 | u32 val, ctl; |
412 | u32 val; | ||
413 | 393 | ||
414 | spin_lock_irqsave(&kbc->lock, flags); | 394 | /* |
395 | * Until all keys are released, defer further processing to | ||
396 | * the polling loop in tegra_kbc_keypress_timer | ||
397 | */ | ||
398 | ctl = readl(kbc->mmio + KBC_CONTROL_0); | ||
399 | ctl &= ~KBC_CONTROL_FIFO_CNT_INT_EN; | ||
400 | writel(ctl, kbc->mmio + KBC_CONTROL_0); | ||
415 | 401 | ||
416 | /* | 402 | /* |
417 | * Quickly bail out & reenable interrupts if the fifo threshold | 403 | * Quickly bail out & reenable interrupts if the fifo threshold |
@@ -422,18 +408,15 @@ static irqreturn_t tegra_kbc_isr(int irq, void *args) | |||
422 | 408 | ||
423 | if (val & KBC_INT_FIFO_CNT_INT_STATUS) { | 409 | if (val & KBC_INT_FIFO_CNT_INT_STATUS) { |
424 | /* | 410 | /* |
425 | * Until all keys are released, defer further processing to | 411 | * Schedule timer to run when hardware is in continuous |
426 | * the polling loop in tegra_kbc_keypress_timer. | 412 | * polling mode. |
427 | */ | 413 | */ |
428 | tegra_kbc_set_fifo_interrupt(kbc, false); | ||
429 | mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies); | 414 | mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies); |
430 | } else if (val & KBC_INT_KEYPRESS_INT_STATUS) { | 415 | } else { |
431 | /* We can be here only through system resume path */ | 416 | ctl |= KBC_CONTROL_FIFO_CNT_INT_EN; |
432 | kbc->keypress_caused_wake = true; | 417 | writel(ctl, kbc->mmio + KBC_CONTROL_0); |
433 | } | 418 | } |
434 | 419 | ||
435 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
436 | |||
437 | return IRQ_HANDLED; | 420 | return IRQ_HANDLED; |
438 | } | 421 | } |
439 | 422 | ||
@@ -443,11 +426,21 @@ static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter) | |||
443 | int i; | 426 | int i; |
444 | unsigned int rst_val; | 427 | unsigned int rst_val; |
445 | 428 | ||
446 | /* Either mask all keys or none. */ | 429 | BUG_ON(pdata->wake_cnt > KBC_MAX_KEY); |
447 | rst_val = (filter && !pdata->wakeup) ? ~0 : 0; | 430 | rst_val = (filter && pdata->wake_cnt) ? ~0 : 0; |
448 | 431 | ||
449 | for (i = 0; i < KBC_MAX_ROW; i++) | 432 | for (i = 0; i < KBC_MAX_ROW; i++) |
450 | writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); | 433 | writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); |
434 | |||
435 | if (filter) { | ||
436 | for (i = 0; i < pdata->wake_cnt; i++) { | ||
437 | u32 val, addr; | ||
438 | addr = pdata->wake_cfg[i].row * 4 + KBC_ROW0_MASK_0; | ||
439 | val = readl(kbc->mmio + addr); | ||
440 | val &= ~(1 << pdata->wake_cfg[i].col); | ||
441 | writel(val, kbc->mmio + addr); | ||
442 | } | ||
443 | } | ||
451 | } | 444 | } |
452 | 445 | ||
453 | static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | 446 | static void tegra_kbc_config_pins(struct tegra_kbc *kbc) |
@@ -468,19 +461,14 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | |||
468 | row_cfg &= ~r_mask; | 461 | row_cfg &= ~r_mask; |
469 | col_cfg &= ~c_mask; | 462 | col_cfg &= ~c_mask; |
470 | 463 | ||
471 | switch (pdata->pin_cfg[i].type) { | 464 | if (pdata->pin_cfg[i].en) { |
472 | case PIN_CFG_ROW: | 465 | if (pdata->pin_cfg[i].is_row) |
473 | row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft; | 466 | row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) |
474 | break; | 467 | << r_shft; |
475 | 468 | else | |
476 | case PIN_CFG_COL: | 469 | col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) |
477 | col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft; | 470 | << c_shft; |
478 | break; | ||
479 | |||
480 | case PIN_CFG_IGNORE: | ||
481 | break; | ||
482 | } | 471 | } |
483 | |||
484 | writel(row_cfg, kbc->mmio + r_offs); | 472 | writel(row_cfg, kbc->mmio + r_offs); |
485 | writel(col_cfg, kbc->mmio + c_offs); | 473 | writel(col_cfg, kbc->mmio + c_offs); |
486 | } | 474 | } |
@@ -489,10 +477,12 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | |||
489 | static int tegra_kbc_start(struct tegra_kbc *kbc) | 477 | static int tegra_kbc_start(struct tegra_kbc *kbc) |
490 | { | 478 | { |
491 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | 479 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; |
480 | unsigned long flags; | ||
492 | unsigned int debounce_cnt; | 481 | unsigned int debounce_cnt; |
493 | u32 val = 0; | 482 | u32 val = 0; |
494 | 483 | ||
495 | clk_prepare_enable(kbc->clk); | 484 | clk_enable(kbc->clk); |
485 | kbc->is_open = 1; | ||
496 | 486 | ||
497 | /* Reset the KBC controller to clear all previous status.*/ | 487 | /* Reset the KBC controller to clear all previous status.*/ |
498 | tegra_periph_reset_assert(kbc->clk); | 488 | tegra_periph_reset_assert(kbc->clk); |
@@ -511,8 +501,12 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) | |||
511 | val |= KBC_FIFO_TH_CNT_SHIFT(1); /* set fifo interrupt threshold to 1 */ | 501 | val |= KBC_FIFO_TH_CNT_SHIFT(1); /* set fifo interrupt threshold to 1 */ |
512 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; /* interrupt on FIFO threshold */ | 502 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; /* interrupt on FIFO threshold */ |
513 | val |= KBC_CONTROL_KBC_EN; /* enable */ | 503 | val |= KBC_CONTROL_KBC_EN; /* enable */ |
504 | val |= KBC_CONTROL_KP_INT_EN; | ||
514 | writel(val, kbc->mmio + KBC_CONTROL_0); | 505 | writel(val, kbc->mmio + KBC_CONTROL_0); |
515 | 506 | ||
507 | writel(DEFAULT_INIT_DLY, kbc->mmio + KBC_INIT_DLY_0); | ||
508 | writel(kbc->scan_timeout_count, kbc->mmio + KBC_TO_CNT_0); | ||
509 | |||
516 | /* | 510 | /* |
517 | * Compute the delay(ns) from interrupt mode to continuous polling | 511 | * Compute the delay(ns) from interrupt mode to continuous polling |
518 | * mode so the timer routine is scheduled appropriately. | 512 | * mode so the timer routine is scheduled appropriately. |
@@ -526,6 +520,7 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) | |||
526 | * Atomically clear out any remaining entries in the key FIFO | 520 | * Atomically clear out any remaining entries in the key FIFO |
527 | * and enable keyboard interrupts. | 521 | * and enable keyboard interrupts. |
528 | */ | 522 | */ |
523 | spin_lock_irqsave(&kbc->lock, flags); | ||
529 | while (1) { | 524 | while (1) { |
530 | val = readl(kbc->mmio + KBC_INT_0); | 525 | val = readl(kbc->mmio + KBC_INT_0); |
531 | val >>= 4; | 526 | val >>= 4; |
@@ -536,6 +531,7 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) | |||
536 | val = readl(kbc->mmio + KBC_KP_ENT1_0); | 531 | val = readl(kbc->mmio + KBC_KP_ENT1_0); |
537 | } | 532 | } |
538 | writel(0x7, kbc->mmio + KBC_INT_0); | 533 | writel(0x7, kbc->mmio + KBC_INT_0); |
534 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
539 | 535 | ||
540 | enable_irq(kbc->irq); | 536 | enable_irq(kbc->irq); |
541 | 537 | ||
@@ -556,7 +552,8 @@ static void tegra_kbc_stop(struct tegra_kbc *kbc) | |||
556 | disable_irq(kbc->irq); | 552 | disable_irq(kbc->irq); |
557 | del_timer_sync(&kbc->timer); | 553 | del_timer_sync(&kbc->timer); |
558 | 554 | ||
559 | clk_disable_unprepare(kbc->clk); | 555 | clk_disable(kbc->clk); |
556 | kbc->is_open = 0; | ||
560 | } | 557 | } |
561 | 558 | ||
562 | static int tegra_kbc_open(struct input_dev *dev) | 559 | static int tegra_kbc_open(struct input_dev *dev) |
@@ -573,7 +570,7 @@ static void tegra_kbc_close(struct input_dev *dev) | |||
573 | return tegra_kbc_stop(kbc); | 570 | return tegra_kbc_stop(kbc); |
574 | } | 571 | } |
575 | 572 | ||
576 | static bool | 573 | static bool __devinit |
577 | tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | 574 | tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, |
578 | struct device *dev, unsigned int *num_rows) | 575 | struct device *dev, unsigned int *num_rows) |
579 | { | 576 | { |
@@ -584,8 +581,7 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
584 | for (i = 0; i < KBC_MAX_GPIO; i++) { | 581 | for (i = 0; i < KBC_MAX_GPIO; i++) { |
585 | const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; | 582 | const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; |
586 | 583 | ||
587 | switch (pin_cfg->type) { | 584 | if (pin_cfg->is_row) { |
588 | case PIN_CFG_ROW: | ||
589 | if (pin_cfg->num >= KBC_MAX_ROW) { | 585 | if (pin_cfg->num >= KBC_MAX_ROW) { |
590 | dev_err(dev, | 586 | dev_err(dev, |
591 | "pin_cfg[%d]: invalid row number %d\n", | 587 | "pin_cfg[%d]: invalid row number %d\n", |
@@ -593,145 +589,52 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
593 | return false; | 589 | return false; |
594 | } | 590 | } |
595 | (*num_rows)++; | 591 | (*num_rows)++; |
596 | break; | 592 | } else { |
597 | |||
598 | case PIN_CFG_COL: | ||
599 | if (pin_cfg->num >= KBC_MAX_COL) { | 593 | if (pin_cfg->num >= KBC_MAX_COL) { |
600 | dev_err(dev, | 594 | dev_err(dev, |
601 | "pin_cfg[%d]: invalid column number %d\n", | 595 | "pin_cfg[%d]: invalid column number %d\n", |
602 | i, pin_cfg->num); | 596 | i, pin_cfg->num); |
603 | return false; | 597 | return false; |
604 | } | 598 | } |
605 | break; | ||
606 | |||
607 | case PIN_CFG_IGNORE: | ||
608 | break; | ||
609 | |||
610 | default: | ||
611 | dev_err(dev, | ||
612 | "pin_cfg[%d]: invalid entry type %d\n", | ||
613 | pin_cfg->type, pin_cfg->num); | ||
614 | return false; | ||
615 | } | 599 | } |
616 | } | 600 | } |
617 | 601 | ||
618 | return true; | 602 | return true; |
619 | } | 603 | } |
620 | 604 | ||
621 | #ifdef CONFIG_OF | 605 | static int __devinit tegra_kbc_probe(struct platform_device *pdev) |
622 | static struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata( | ||
623 | struct platform_device *pdev) | ||
624 | { | ||
625 | struct tegra_kbc_platform_data *pdata; | ||
626 | struct device_node *np = pdev->dev.of_node; | ||
627 | u32 prop; | ||
628 | int i; | ||
629 | |||
630 | if (!np) | ||
631 | return NULL; | ||
632 | |||
633 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
634 | if (!pdata) | ||
635 | return NULL; | ||
636 | |||
637 | if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop)) | ||
638 | pdata->debounce_cnt = prop; | ||
639 | |||
640 | if (!of_property_read_u32(np, "nvidia,repeat-delay-ms", &prop)) | ||
641 | pdata->repeat_cnt = prop; | ||
642 | |||
643 | if (of_find_property(np, "nvidia,needs-ghost-filter", NULL)) | ||
644 | pdata->use_ghost_filter = true; | ||
645 | |||
646 | if (of_find_property(np, "nvidia,wakeup-source", NULL)) | ||
647 | pdata->wakeup = true; | ||
648 | |||
649 | /* | ||
650 | * All currently known keymaps with device tree support use the same | ||
651 | * pin_cfg, so set it up here. | ||
652 | */ | ||
653 | for (i = 0; i < KBC_MAX_ROW; i++) { | ||
654 | pdata->pin_cfg[i].num = i; | ||
655 | pdata->pin_cfg[i].type = PIN_CFG_ROW; | ||
656 | } | ||
657 | |||
658 | for (i = 0; i < KBC_MAX_COL; i++) { | ||
659 | pdata->pin_cfg[KBC_MAX_ROW + i].num = i; | ||
660 | pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; | ||
661 | } | ||
662 | |||
663 | return pdata; | ||
664 | } | ||
665 | #else | ||
666 | static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata( | ||
667 | struct platform_device *pdev) | ||
668 | { | ||
669 | return NULL; | ||
670 | } | ||
671 | #endif | ||
672 | |||
673 | static int tegra_kbd_setup_keymap(struct tegra_kbc *kbc) | ||
674 | { | ||
675 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
676 | const struct matrix_keymap_data *keymap_data = pdata->keymap_data; | ||
677 | unsigned int keymap_rows = KBC_MAX_KEY; | ||
678 | int retval; | ||
679 | |||
680 | if (keymap_data && pdata->use_fn_map) | ||
681 | keymap_rows *= 2; | ||
682 | |||
683 | retval = matrix_keypad_build_keymap(keymap_data, NULL, | ||
684 | keymap_rows, KBC_MAX_COL, | ||
685 | kbc->keycode, kbc->idev); | ||
686 | if (retval == -ENOSYS || retval == -ENOENT) { | ||
687 | /* | ||
688 | * If there is no OF support in kernel or keymap | ||
689 | * property is missing, use default keymap. | ||
690 | */ | ||
691 | retval = matrix_keypad_build_keymap( | ||
692 | &tegra_kbc_default_keymap_data, NULL, | ||
693 | keymap_rows, KBC_MAX_COL, | ||
694 | kbc->keycode, kbc->idev); | ||
695 | } | ||
696 | |||
697 | return retval; | ||
698 | } | ||
699 | |||
700 | static int tegra_kbc_probe(struct platform_device *pdev) | ||
701 | { | 606 | { |
702 | const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; | 607 | const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; |
608 | const struct matrix_keymap_data *keymap_data; | ||
703 | struct tegra_kbc *kbc; | 609 | struct tegra_kbc *kbc; |
704 | struct input_dev *input_dev; | 610 | struct input_dev *input_dev; |
705 | struct resource *res; | 611 | struct resource *res; |
706 | int irq; | 612 | int irq; |
707 | int err; | 613 | int err; |
614 | int i; | ||
708 | int num_rows = 0; | 615 | int num_rows = 0; |
709 | unsigned int debounce_cnt; | 616 | unsigned int debounce_cnt; |
710 | unsigned int scan_time_rows; | 617 | unsigned int scan_time_rows; |
618 | unsigned long scan_tc; | ||
711 | 619 | ||
712 | if (!pdata) | 620 | dev_dbg(&pdev->dev, "KBC: tegra_kbc_probe\n"); |
713 | pdata = tegra_kbc_dt_parse_pdata(pdev); | ||
714 | 621 | ||
715 | if (!pdata) | 622 | if (!pdata) |
716 | return -EINVAL; | 623 | return -EINVAL; |
717 | 624 | ||
718 | if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows)) { | 625 | if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows)) |
719 | err = -EINVAL; | 626 | return -EINVAL; |
720 | goto err_free_pdata; | ||
721 | } | ||
722 | 627 | ||
723 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 628 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
724 | if (!res) { | 629 | if (!res) { |
725 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | 630 | dev_err(&pdev->dev, "failed to get I/O memory\n"); |
726 | err = -ENXIO; | 631 | return -ENXIO; |
727 | goto err_free_pdata; | ||
728 | } | 632 | } |
729 | 633 | ||
730 | irq = platform_get_irq(pdev, 0); | 634 | irq = platform_get_irq(pdev, 0); |
731 | if (irq < 0) { | 635 | if (irq < 0) { |
732 | dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); | 636 | dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); |
733 | err = -ENXIO; | 637 | return -ENXIO; |
734 | goto err_free_pdata; | ||
735 | } | 638 | } |
736 | 639 | ||
737 | kbc = kzalloc(sizeof(*kbc), GFP_KERNEL); | 640 | kbc = kzalloc(sizeof(*kbc), GFP_KERNEL); |
@@ -768,6 +671,14 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
768 | goto err_iounmap; | 671 | goto err_iounmap; |
769 | } | 672 | } |
770 | 673 | ||
674 | kbc->is_open = 0; | ||
675 | kbc->wake_enable_rows = 0; | ||
676 | kbc->wake_enable_cols = 0; | ||
677 | for (i = 0; i < pdata->wake_cnt; i++) { | ||
678 | kbc->wake_enable_rows |= (1 << pdata->wake_cfg[i].row); | ||
679 | kbc->wake_enable_cols |= (1 << pdata->wake_cfg[i].col); | ||
680 | } | ||
681 | |||
771 | /* | 682 | /* |
772 | * The time delay between two consecutive reads of the FIFO is | 683 | * The time delay between two consecutive reads of the FIFO is |
773 | * the sum of the repeat time and the time taken for scanning | 684 | * the sum of the repeat time and the time taken for scanning |
@@ -779,9 +690,16 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
779 | kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt; | 690 | kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt; |
780 | kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); | 691 | kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); |
781 | 692 | ||
782 | kbc->wakeup_key = pdata->wakeup_key; | 693 | if (pdata->scan_count) |
783 | kbc->use_fn_map = pdata->use_fn_map; | 694 | scan_tc = DEFAULT_INIT_DLY + (scan_time_rows + |
784 | kbc->use_ghost_filter = pdata->use_ghost_filter; | 695 | pdata->repeat_cnt) * pdata->scan_count; |
696 | else | ||
697 | scan_tc = DEFAULT_INIT_DLY + (scan_time_rows + | ||
698 | pdata->repeat_cnt) * DEFAULT_SCAN_COUNT; | ||
699 | |||
700 | kbc->one_scan_time = scan_time_rows + pdata->repeat_cnt; | ||
701 | /* Bit 19:0 is for scan timeout count */ | ||
702 | kbc->scan_timeout_count = scan_tc & 0xFFFFF; | ||
785 | 703 | ||
786 | input_dev->name = pdev->name; | 704 | input_dev->name = pdev->name; |
787 | input_dev->id.bustype = BUS_HOST; | 705 | input_dev->id.bustype = BUS_HOST; |
@@ -789,19 +707,28 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
789 | input_dev->open = tegra_kbc_open; | 707 | input_dev->open = tegra_kbc_open; |
790 | input_dev->close = tegra_kbc_close; | 708 | input_dev->close = tegra_kbc_close; |
791 | 709 | ||
792 | err = tegra_kbd_setup_keymap(kbc); | 710 | input_set_drvdata(input_dev, kbc); |
793 | if (err) { | 711 | |
794 | dev_err(&pdev->dev, "failed to setup keymap\n"); | 712 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
795 | goto err_put_clk; | 713 | if (!pdata->disable_ev_rep) |
796 | } | 714 | input_dev->evbit[0] |= BIT_MASK(EV_REP); |
797 | 715 | ||
798 | __set_bit(EV_REP, input_dev->evbit); | ||
799 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 716 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
800 | 717 | ||
801 | input_set_drvdata(input_dev, kbc); | 718 | input_dev->keycode = kbc->keycode; |
719 | input_dev->keycodesize = sizeof(kbc->keycode[0]); | ||
720 | input_dev->keycodemax = KBC_MAX_KEY; | ||
721 | if (pdata->use_fn_map) | ||
722 | input_dev->keycodemax *= 2; | ||
723 | |||
724 | kbc->use_fn_map = pdata->use_fn_map; | ||
725 | kbc->use_ghost_filter = pdata->use_ghost_filter; | ||
726 | keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; | ||
727 | matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, | ||
728 | input_dev->keycode, input_dev->keybit); | ||
802 | 729 | ||
803 | err = request_irq(kbc->irq, tegra_kbc_isr, | 730 | err = request_irq(kbc->irq, tegra_kbc_isr, IRQF_TRIGGER_HIGH, |
804 | IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc); | 731 | pdev->name, kbc); |
805 | if (err) { | 732 | if (err) { |
806 | dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); | 733 | dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); |
807 | goto err_put_clk; | 734 | goto err_put_clk; |
@@ -831,20 +758,15 @@ err_free_mem_region: | |||
831 | err_free_mem: | 758 | err_free_mem: |
832 | input_free_device(input_dev); | 759 | input_free_device(input_dev); |
833 | kfree(kbc); | 760 | kfree(kbc); |
834 | err_free_pdata: | ||
835 | if (!pdev->dev.platform_data) | ||
836 | kfree(pdata); | ||
837 | 761 | ||
838 | return err; | 762 | return err; |
839 | } | 763 | } |
840 | 764 | ||
841 | static int tegra_kbc_remove(struct platform_device *pdev) | 765 | static int __devexit tegra_kbc_remove(struct platform_device *pdev) |
842 | { | 766 | { |
843 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); | 767 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); |
844 | struct resource *res; | 768 | struct resource *res; |
845 | 769 | ||
846 | platform_set_drvdata(pdev, NULL); | ||
847 | |||
848 | free_irq(kbc->irq, pdev); | 770 | free_irq(kbc->irq, pdev); |
849 | clk_put(kbc->clk); | 771 | clk_put(kbc->clk); |
850 | 772 | ||
@@ -853,15 +775,10 @@ static int tegra_kbc_remove(struct platform_device *pdev) | |||
853 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 775 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
854 | release_mem_region(res->start, resource_size(res)); | 776 | release_mem_region(res->start, resource_size(res)); |
855 | 777 | ||
856 | /* | ||
857 | * If we do not have platform data attached to the device we | ||
858 | * allocated it ourselves and thus need to free it. | ||
859 | */ | ||
860 | if (!pdev->dev.platform_data) | ||
861 | kfree(kbc->pdata); | ||
862 | |||
863 | kfree(kbc); | 778 | kfree(kbc); |
864 | 779 | ||
780 | platform_set_drvdata(pdev, NULL); | ||
781 | |||
865 | return 0; | 782 | return 0; |
866 | } | 783 | } |
867 | 784 | ||
@@ -870,35 +787,42 @@ static int tegra_kbc_suspend(struct device *dev) | |||
870 | { | 787 | { |
871 | struct platform_device *pdev = to_platform_device(dev); | 788 | struct platform_device *pdev = to_platform_device(dev); |
872 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); | 789 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); |
790 | int timeout; | ||
791 | unsigned long int_st; | ||
792 | |||
793 | dev_dbg(&pdev->dev, "KBC: tegra_kbc_suspend\n"); | ||
794 | |||
795 | if (!kbc->is_open) | ||
796 | return 0; | ||
873 | 797 | ||
874 | mutex_lock(&kbc->idev->mutex); | ||
875 | if (device_may_wakeup(&pdev->dev)) { | 798 | if (device_may_wakeup(&pdev->dev)) { |
876 | disable_irq(kbc->irq); | 799 | timeout = DIV_ROUND_UP((kbc->scan_timeout_count + |
877 | del_timer_sync(&kbc->timer); | 800 | kbc->one_scan_time), 32); |
878 | tegra_kbc_set_fifo_interrupt(kbc, false); | 801 | timeout = DIV_ROUND_UP(timeout, 10); |
802 | while (timeout--) { | ||
803 | int_st = readl(kbc->mmio + KBC_INT_0); | ||
804 | if (int_st & 0x8) { | ||
805 | msleep(10); | ||
806 | continue; | ||
807 | } | ||
808 | break; | ||
809 | } | ||
810 | int_st = readl(kbc->mmio + KBC_INT_0); | ||
811 | if (int_st & 0x8) | ||
812 | dev_err(&pdev->dev, "KBC: Controller is not in " | ||
813 | "wakeupmode\n"); | ||
879 | 814 | ||
815 | tegra_kbc_setup_wakekeys(kbc, true); | ||
816 | enable_irq_wake(kbc->irq); | ||
880 | /* Forcefully clear the interrupt status */ | 817 | /* Forcefully clear the interrupt status */ |
881 | writel(0x7, kbc->mmio + KBC_INT_0); | 818 | writel(0x7, kbc->mmio + KBC_INT_0); |
882 | /* | ||
883 | * Store the previous resident time of continuous polling mode. | ||
884 | * Force the keyboard into interrupt mode. | ||
885 | */ | ||
886 | kbc->cp_to_wkup_dly = readl(kbc->mmio + KBC_TO_CNT_0); | ||
887 | writel(0, kbc->mmio + KBC_TO_CNT_0); | ||
888 | |||
889 | tegra_kbc_setup_wakekeys(kbc, true); | ||
890 | msleep(30); | 819 | msleep(30); |
891 | |||
892 | kbc->keypress_caused_wake = false; | ||
893 | /* Enable keypress interrupt before going into suspend. */ | ||
894 | tegra_kbc_set_keypress_interrupt(kbc, true); | ||
895 | enable_irq(kbc->irq); | ||
896 | enable_irq_wake(kbc->irq); | ||
897 | } else { | 820 | } else { |
821 | mutex_lock(&kbc->idev->mutex); | ||
898 | if (kbc->idev->users) | 822 | if (kbc->idev->users) |
899 | tegra_kbc_stop(kbc); | 823 | tegra_kbc_stop(kbc); |
824 | mutex_unlock(&kbc->idev->mutex); | ||
900 | } | 825 | } |
901 | mutex_unlock(&kbc->idev->mutex); | ||
902 | 826 | ||
903 | return 0; | 827 | return 0; |
904 | } | 828 | } |
@@ -909,36 +833,18 @@ static int tegra_kbc_resume(struct device *dev) | |||
909 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); | 833 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); |
910 | int err = 0; | 834 | int err = 0; |
911 | 835 | ||
912 | mutex_lock(&kbc->idev->mutex); | 836 | if (!kbc->is_open) |
837 | return tegra_kbc_start(kbc); | ||
838 | |||
913 | if (device_may_wakeup(&pdev->dev)) { | 839 | if (device_may_wakeup(&pdev->dev)) { |
914 | disable_irq_wake(kbc->irq); | 840 | disable_irq_wake(kbc->irq); |
915 | tegra_kbc_setup_wakekeys(kbc, false); | 841 | tegra_kbc_setup_wakekeys(kbc, false); |
916 | /* We will use fifo interrupts for key detection. */ | ||
917 | tegra_kbc_set_keypress_interrupt(kbc, false); | ||
918 | |||
919 | /* Restore the resident time of continuous polling mode. */ | ||
920 | writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0); | ||
921 | |||
922 | tegra_kbc_set_fifo_interrupt(kbc, true); | ||
923 | |||
924 | if (kbc->keypress_caused_wake && kbc->wakeup_key) { | ||
925 | /* | ||
926 | * We can't report events directly from the ISR | ||
927 | * because timekeeping is stopped when processing | ||
928 | * wakeup request and we get a nasty warning when | ||
929 | * we try to call do_gettimeofday() in evdev | ||
930 | * handler. | ||
931 | */ | ||
932 | input_report_key(kbc->idev, kbc->wakeup_key, 1); | ||
933 | input_sync(kbc->idev); | ||
934 | input_report_key(kbc->idev, kbc->wakeup_key, 0); | ||
935 | input_sync(kbc->idev); | ||
936 | } | ||
937 | } else { | 842 | } else { |
843 | mutex_lock(&kbc->idev->mutex); | ||
938 | if (kbc->idev->users) | 844 | if (kbc->idev->users) |
939 | err = tegra_kbc_start(kbc); | 845 | err = tegra_kbc_start(kbc); |
846 | mutex_unlock(&kbc->idev->mutex); | ||
940 | } | 847 | } |
941 | mutex_unlock(&kbc->idev->mutex); | ||
942 | 848 | ||
943 | return err; | 849 | return err; |
944 | } | 850 | } |
@@ -946,23 +852,27 @@ static int tegra_kbc_resume(struct device *dev) | |||
946 | 852 | ||
947 | static SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops, tegra_kbc_suspend, tegra_kbc_resume); | 853 | static SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops, tegra_kbc_suspend, tegra_kbc_resume); |
948 | 854 | ||
949 | static const struct of_device_id tegra_kbc_of_match[] = { | ||
950 | { .compatible = "nvidia,tegra20-kbc", }, | ||
951 | { }, | ||
952 | }; | ||
953 | MODULE_DEVICE_TABLE(of, tegra_kbc_of_match); | ||
954 | |||
955 | static struct platform_driver tegra_kbc_driver = { | 855 | static struct platform_driver tegra_kbc_driver = { |
956 | .probe = tegra_kbc_probe, | 856 | .probe = tegra_kbc_probe, |
957 | .remove = tegra_kbc_remove, | 857 | .remove = __devexit_p(tegra_kbc_remove), |
958 | .driver = { | 858 | .driver = { |
959 | .name = "tegra-kbc", | 859 | .name = "tegra-kbc", |
960 | .owner = THIS_MODULE, | 860 | .owner = THIS_MODULE, |
961 | .pm = &tegra_kbc_pm_ops, | 861 | .pm = &tegra_kbc_pm_ops, |
962 | .of_match_table = tegra_kbc_of_match, | ||
963 | }, | 862 | }, |
964 | }; | 863 | }; |
965 | module_platform_driver(tegra_kbc_driver); | 864 | |
865 | static void __exit tegra_kbc_exit(void) | ||
866 | { | ||
867 | platform_driver_unregister(&tegra_kbc_driver); | ||
868 | } | ||
869 | module_exit(tegra_kbc_exit); | ||
870 | |||
871 | static int __init tegra_kbc_init(void) | ||
872 | { | ||
873 | return platform_driver_register(&tegra_kbc_driver); | ||
874 | } | ||
875 | module_init(tegra_kbc_init); | ||
966 | 876 | ||
967 | MODULE_LICENSE("GPL"); | 877 | MODULE_LICENSE("GPL"); |
968 | MODULE_AUTHOR("Rakesh Iyer <riyer@nvidia.com>"); | 878 | MODULE_AUTHOR("Rakesh Iyer <riyer@nvidia.com>"); |
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c index ee163501129..1c58681de81 100644 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ b/drivers/input/keyboard/tnetv107x-keypad.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/input/matrix_keypad.h> | 26 | #include <linux/input/matrix_keypad.h> |
27 | #include <linux/module.h> | ||
28 | 27 | ||
29 | #define BITS(x) (BIT(x) - 1) | 28 | #define BITS(x) (BIT(x) - 1) |
30 | 29 | ||
@@ -153,7 +152,7 @@ static void keypad_stop(struct input_dev *dev) | |||
153 | clk_disable(kp->clk); | 152 | clk_disable(kp->clk); |
154 | } | 153 | } |
155 | 154 | ||
156 | static int keypad_probe(struct platform_device *pdev) | 155 | static int __devinit keypad_probe(struct platform_device *pdev) |
157 | { | 156 | { |
158 | const struct matrix_keypad_platform_data *pdata; | 157 | const struct matrix_keypad_platform_data *pdata; |
159 | const struct matrix_keymap_data *keymap_data; | 158 | const struct matrix_keymap_data *keymap_data; |
@@ -227,15 +226,15 @@ static int keypad_probe(struct platform_device *pdev) | |||
227 | goto error_clk; | 226 | goto error_clk; |
228 | } | 227 | } |
229 | 228 | ||
230 | error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, | 229 | error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0, |
231 | IRQF_ONESHOT, dev_name(dev), kp); | 230 | dev_name(dev), kp); |
232 | if (error < 0) { | 231 | if (error < 0) { |
233 | dev_err(kp->dev, "Could not allocate keypad press key irq\n"); | 232 | dev_err(kp->dev, "Could not allocate keypad press key irq\n"); |
234 | goto error_irq_press; | 233 | goto error_irq_press; |
235 | } | 234 | } |
236 | 235 | ||
237 | error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, | 236 | error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0, |
238 | IRQF_ONESHOT, dev_name(dev), kp); | 237 | dev_name(dev), kp); |
239 | if (error < 0) { | 238 | if (error < 0) { |
240 | dev_err(kp->dev, "Could not allocate keypad release key irq\n"); | 239 | dev_err(kp->dev, "Could not allocate keypad release key irq\n"); |
241 | goto error_irq_release; | 240 | goto error_irq_release; |
@@ -247,11 +246,15 @@ static int keypad_probe(struct platform_device *pdev) | |||
247 | error = -ENOMEM; | 246 | error = -ENOMEM; |
248 | goto error_input; | 247 | goto error_input; |
249 | } | 248 | } |
249 | input_set_drvdata(kp->input_dev, kp); | ||
250 | 250 | ||
251 | kp->input_dev->name = pdev->name; | 251 | kp->input_dev->name = pdev->name; |
252 | kp->input_dev->dev.parent = &pdev->dev; | 252 | kp->input_dev->dev.parent = &pdev->dev; |
253 | kp->input_dev->open = keypad_start; | 253 | kp->input_dev->open = keypad_start; |
254 | kp->input_dev->close = keypad_stop; | 254 | kp->input_dev->close = keypad_stop; |
255 | kp->input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
256 | if (!pdata->no_autorepeat) | ||
257 | kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
255 | 258 | ||
256 | clk_enable(kp->clk); | 259 | clk_enable(kp->clk); |
257 | rev = keypad_read(kp, rev); | 260 | rev = keypad_read(kp, rev); |
@@ -260,19 +263,14 @@ static int keypad_probe(struct platform_device *pdev) | |||
260 | kp->input_dev->id.version = ((rev >> 16) & 0xfff); | 263 | kp->input_dev->id.version = ((rev >> 16) & 0xfff); |
261 | clk_disable(kp->clk); | 264 | clk_disable(kp->clk); |
262 | 265 | ||
263 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 266 | kp->input_dev->keycode = kp->keycodes; |
264 | kp->rows, kp->cols, | 267 | kp->input_dev->keycodesize = sizeof(kp->keycodes[0]); |
265 | kp->keycodes, kp->input_dev); | 268 | kp->input_dev->keycodemax = kp->rows << kp->row_shift; |
266 | if (error) { | ||
267 | dev_err(dev, "Failed to build keymap\n"); | ||
268 | goto error_reg; | ||
269 | } | ||
270 | 269 | ||
271 | if (!pdata->no_autorepeat) | 270 | matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes, |
272 | kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); | 271 | kp->input_dev->keybit); |
273 | input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); | ||
274 | 272 | ||
275 | input_set_drvdata(kp->input_dev, kp); | 273 | input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); |
276 | 274 | ||
277 | error = input_register_device(kp->input_dev); | 275 | error = input_register_device(kp->input_dev); |
278 | if (error < 0) { | 276 | if (error < 0) { |
@@ -301,7 +299,7 @@ error_res: | |||
301 | return error; | 299 | return error; |
302 | } | 300 | } |
303 | 301 | ||
304 | static int keypad_remove(struct platform_device *pdev) | 302 | static int __devexit keypad_remove(struct platform_device *pdev) |
305 | { | 303 | { |
306 | struct keypad_data *kp = platform_get_drvdata(pdev); | 304 | struct keypad_data *kp = platform_get_drvdata(pdev); |
307 | 305 | ||
@@ -319,11 +317,23 @@ static int keypad_remove(struct platform_device *pdev) | |||
319 | 317 | ||
320 | static struct platform_driver keypad_driver = { | 318 | static struct platform_driver keypad_driver = { |
321 | .probe = keypad_probe, | 319 | .probe = keypad_probe, |
322 | .remove = keypad_remove, | 320 | .remove = __devexit_p(keypad_remove), |
323 | .driver.name = "tnetv107x-keypad", | 321 | .driver.name = "tnetv107x-keypad", |
324 | .driver.owner = THIS_MODULE, | 322 | .driver.owner = THIS_MODULE, |
325 | }; | 323 | }; |
326 | module_platform_driver(keypad_driver); | 324 | |
325 | static int __init keypad_init(void) | ||
326 | { | ||
327 | return platform_driver_register(&keypad_driver); | ||
328 | } | ||
329 | |||
330 | static void __exit keypad_exit(void) | ||
331 | { | ||
332 | platform_driver_unregister(&keypad_driver); | ||
333 | } | ||
334 | |||
335 | module_init(keypad_init); | ||
336 | module_exit(keypad_exit); | ||
327 | 337 | ||
328 | MODULE_AUTHOR("Cyril Chemparathy"); | 338 | MODULE_AUTHOR("Cyril Chemparathy"); |
329 | MODULE_DESCRIPTION("TNETV107X Keypad Driver"); | 339 | MODULE_DESCRIPTION("TNETV107X Keypad Driver"); |
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 04f84fd5717..a26922cf0e8 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/i2c/twl.h> | 34 | #include <linux/i2c/twl.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | 36 | ||
37 | |||
37 | /* | 38 | /* |
38 | * The TWL4030 family chips include a keypad controller that supports | 39 | * The TWL4030 family chips include a keypad controller that supports |
39 | * up to an 8x8 switch matrix. The controller can issue system wakeup | 40 | * up to an 8x8 switch matrix. The controller can issue system wakeup |
@@ -271,7 +272,7 @@ static irqreturn_t do_kp_irq(int irq, void *_kp) | |||
271 | return IRQ_HANDLED; | 272 | return IRQ_HANDLED; |
272 | } | 273 | } |
273 | 274 | ||
274 | static int twl4030_kp_program(struct twl4030_keypad *kp) | 275 | static int __devinit twl4030_kp_program(struct twl4030_keypad *kp) |
275 | { | 276 | { |
276 | u8 reg; | 277 | u8 reg; |
277 | int i; | 278 | int i; |
@@ -301,7 +302,7 @@ static int twl4030_kp_program(struct twl4030_keypad *kp) | |||
301 | if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0) | 302 | if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0) |
302 | return -EIO; | 303 | return -EIO; |
303 | 304 | ||
304 | /* Set timeout period to 200 ms */ | 305 | /* Set timeout period to 100 ms */ |
305 | i = KEYP_PERIOD_US(200000, PTV_PRESCALER); | 306 | i = KEYP_PERIOD_US(200000, PTV_PRESCALER); |
306 | if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0) | 307 | if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0) |
307 | return -EIO; | 308 | return -EIO; |
@@ -328,7 +329,7 @@ static int twl4030_kp_program(struct twl4030_keypad *kp) | |||
328 | * Registers keypad device with input subsystem | 329 | * Registers keypad device with input subsystem |
329 | * and configures TWL4030 keypad registers | 330 | * and configures TWL4030 keypad registers |
330 | */ | 331 | */ |
331 | static int twl4030_kp_probe(struct platform_device *pdev) | 332 | static int __devinit twl4030_kp_probe(struct platform_device *pdev) |
332 | { | 333 | { |
333 | struct twl4030_keypad_data *pdata = pdev->dev.platform_data; | 334 | struct twl4030_keypad_data *pdata = pdev->dev.platform_data; |
334 | const struct matrix_keymap_data *keymap_data; | 335 | const struct matrix_keymap_data *keymap_data; |
@@ -361,6 +362,14 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
361 | kp->irq = platform_get_irq(pdev, 0); | 362 | kp->irq = platform_get_irq(pdev, 0); |
362 | 363 | ||
363 | /* setup input device */ | 364 | /* setup input device */ |
365 | __set_bit(EV_KEY, input->evbit); | ||
366 | |||
367 | /* Enable auto repeat feature of Linux input subsystem */ | ||
368 | if (pdata->rep) | ||
369 | __set_bit(EV_REP, input->evbit); | ||
370 | |||
371 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
372 | |||
364 | input->name = "TWL4030 Keypad"; | 373 | input->name = "TWL4030 Keypad"; |
365 | input->phys = "twl4030_keypad/input0"; | 374 | input->phys = "twl4030_keypad/input0"; |
366 | input->dev.parent = &pdev->dev; | 375 | input->dev.parent = &pdev->dev; |
@@ -370,19 +379,12 @@ static int twl4030_kp_probe(struct platform_device *pdev) | |||
370 | input->id.product = 0x0001; | 379 | input->id.product = 0x0001; |
371 | input->id.version = 0x0003; | 380 | input->id.version = 0x0003; |
372 | 381 | ||
373 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 382 | input->keycode = kp->keymap; |
374 | TWL4030_MAX_ROWS, | 383 | input->keycodesize = sizeof(kp->keymap[0]); |
375 | 1 << TWL4030_ROW_SHIFT, | 384 | input->keycodemax = ARRAY_SIZE(kp->keymap); |
376 | kp->keymap, input); | ||
377 | if (error) { | ||
378 | dev_err(kp->dbg_dev, "Failed to build keymap\n"); | ||
379 | goto err1; | ||
380 | } | ||
381 | 385 | ||
382 | input_set_capability(input, EV_MSC, MSC_SCAN); | 386 | matrix_keypad_build_keymap(keymap_data, TWL4030_ROW_SHIFT, |
383 | /* Enable auto repeat feature of Linux input subsystem */ | 387 | input->keycode, input->keybit); |
384 | if (pdata->rep) | ||
385 | __set_bit(EV_REP, input->evbit); | ||
386 | 388 | ||
387 | error = input_register_device(input); | 389 | error = input_register_device(input); |
388 | if (error) { | 390 | if (error) { |
@@ -432,7 +434,7 @@ err1: | |||
432 | return error; | 434 | return error; |
433 | } | 435 | } |
434 | 436 | ||
435 | static int twl4030_kp_remove(struct platform_device *pdev) | 437 | static int __devexit twl4030_kp_remove(struct platform_device *pdev) |
436 | { | 438 | { |
437 | struct twl4030_keypad *kp = platform_get_drvdata(pdev); | 439 | struct twl4030_keypad *kp = platform_get_drvdata(pdev); |
438 | 440 | ||
@@ -452,15 +454,27 @@ static int twl4030_kp_remove(struct platform_device *pdev) | |||
452 | 454 | ||
453 | static struct platform_driver twl4030_kp_driver = { | 455 | static struct platform_driver twl4030_kp_driver = { |
454 | .probe = twl4030_kp_probe, | 456 | .probe = twl4030_kp_probe, |
455 | .remove = twl4030_kp_remove, | 457 | .remove = __devexit_p(twl4030_kp_remove), |
456 | .driver = { | 458 | .driver = { |
457 | .name = "twl4030_keypad", | 459 | .name = "twl4030_keypad", |
458 | .owner = THIS_MODULE, | 460 | .owner = THIS_MODULE, |
459 | }, | 461 | }, |
460 | }; | 462 | }; |
461 | module_platform_driver(twl4030_kp_driver); | 463 | |
464 | static int __init twl4030_kp_init(void) | ||
465 | { | ||
466 | return platform_driver_register(&twl4030_kp_driver); | ||
467 | } | ||
468 | module_init(twl4030_kp_init); | ||
469 | |||
470 | static void __exit twl4030_kp_exit(void) | ||
471 | { | ||
472 | platform_driver_unregister(&twl4030_kp_driver); | ||
473 | } | ||
474 | module_exit(twl4030_kp_exit); | ||
462 | 475 | ||
463 | MODULE_AUTHOR("Texas Instruments"); | 476 | MODULE_AUTHOR("Texas Instruments"); |
464 | MODULE_DESCRIPTION("TWL4030 Keypad Driver"); | 477 | MODULE_DESCRIPTION("TWL4030 Keypad Driver"); |
465 | MODULE_LICENSE("GPL"); | 478 | MODULE_LICENSE("GPL"); |
466 | MODULE_ALIAS("platform:twl4030_keypad"); | 479 | MODULE_ALIAS("platform:twl4030_keypad"); |
480 | |||
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index ee163bee8cc..ee2bf6bcf29 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | 23 | ||
24 | #include <linux/platform_data/keypad-w90p910.h> | 24 | #include <mach/w90p910_keypad.h> |
25 | 25 | ||
26 | /* Keypad Interface Control Registers */ | 26 | /* Keypad Interface Control Registers */ |
27 | #define KPI_CONF 0x00 | 27 | #define KPI_CONF 0x00 |
@@ -42,8 +42,7 @@ | |||
42 | #define KGET_RAW(n) (((n) & KEY0R) >> 3) | 42 | #define KGET_RAW(n) (((n) & KEY0R) >> 3) |
43 | #define KGET_COLUMN(n) ((n) & KEY0C) | 43 | #define KGET_COLUMN(n) ((n) & KEY0C) |
44 | 44 | ||
45 | #define W90P910_NUM_ROWS 8 | 45 | #define W90P910_MAX_KEY_NUM (8 * 8) |
46 | #define W90P910_NUM_COLS 8 | ||
47 | #define W90P910_ROW_SHIFT 3 | 46 | #define W90P910_ROW_SHIFT 3 |
48 | 47 | ||
49 | struct w90p910_keypad { | 48 | struct w90p910_keypad { |
@@ -52,7 +51,7 @@ struct w90p910_keypad { | |||
52 | struct input_dev *input_dev; | 51 | struct input_dev *input_dev; |
53 | void __iomem *mmio_base; | 52 | void __iomem *mmio_base; |
54 | int irq; | 53 | int irq; |
55 | unsigned short keymap[W90P910_NUM_ROWS * W90P910_NUM_COLS]; | 54 | unsigned short keymap[W90P910_MAX_KEY_NUM]; |
56 | }; | 55 | }; |
57 | 56 | ||
58 | static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, | 57 | static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, |
@@ -118,7 +117,7 @@ static void w90p910_keypad_close(struct input_dev *dev) | |||
118 | clk_disable(keypad->clk); | 117 | clk_disable(keypad->clk); |
119 | } | 118 | } |
120 | 119 | ||
121 | static int w90p910_keypad_probe(struct platform_device *pdev) | 120 | static int __devinit w90p910_keypad_probe(struct platform_device *pdev) |
122 | { | 121 | { |
123 | const struct w90p910_keypad_platform_data *pdata = | 122 | const struct w90p910_keypad_platform_data *pdata = |
124 | pdev->dev.platform_data; | 123 | pdev->dev.platform_data; |
@@ -191,25 +190,25 @@ static int w90p910_keypad_probe(struct platform_device *pdev) | |||
191 | input_dev->close = w90p910_keypad_close; | 190 | input_dev->close = w90p910_keypad_close; |
192 | input_dev->dev.parent = &pdev->dev; | 191 | input_dev->dev.parent = &pdev->dev; |
193 | 192 | ||
194 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 193 | input_dev->keycode = keypad->keymap; |
195 | W90P910_NUM_ROWS, W90P910_NUM_COLS, | 194 | input_dev->keycodesize = sizeof(keypad->keymap[0]); |
196 | keypad->keymap, input_dev); | 195 | input_dev->keycodemax = ARRAY_SIZE(keypad->keymap); |
197 | if (error) { | 196 | |
198 | dev_err(&pdev->dev, "failed to build keymap\n"); | 197 | input_set_drvdata(input_dev, keypad); |
199 | goto failed_put_clk; | 198 | |
200 | } | 199 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
200 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
201 | |||
202 | matrix_keypad_build_keymap(keymap_data, W90P910_ROW_SHIFT, | ||
203 | input_dev->keycode, input_dev->keybit); | ||
201 | 204 | ||
202 | error = request_irq(keypad->irq, w90p910_keypad_irq_handler, | 205 | error = request_irq(keypad->irq, w90p910_keypad_irq_handler, |
203 | 0, pdev->name, keypad); | 206 | IRQF_DISABLED, pdev->name, keypad); |
204 | if (error) { | 207 | if (error) { |
205 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 208 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
206 | goto failed_put_clk; | 209 | goto failed_put_clk; |
207 | } | 210 | } |
208 | 211 | ||
209 | __set_bit(EV_REP, input_dev->evbit); | ||
210 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
211 | input_set_drvdata(input_dev, keypad); | ||
212 | |||
213 | /* Register the input device */ | 212 | /* Register the input device */ |
214 | error = input_register_device(input_dev); | 213 | error = input_register_device(input_dev); |
215 | if (error) { | 214 | if (error) { |
@@ -234,7 +233,7 @@ failed_free: | |||
234 | return error; | 233 | return error; |
235 | } | 234 | } |
236 | 235 | ||
237 | static int w90p910_keypad_remove(struct platform_device *pdev) | 236 | static int __devexit w90p910_keypad_remove(struct platform_device *pdev) |
238 | { | 237 | { |
239 | struct w90p910_keypad *keypad = platform_get_drvdata(pdev); | 238 | struct w90p910_keypad *keypad = platform_get_drvdata(pdev); |
240 | struct resource *res; | 239 | struct resource *res; |
@@ -257,13 +256,25 @@ static int w90p910_keypad_remove(struct platform_device *pdev) | |||
257 | 256 | ||
258 | static struct platform_driver w90p910_keypad_driver = { | 257 | static struct platform_driver w90p910_keypad_driver = { |
259 | .probe = w90p910_keypad_probe, | 258 | .probe = w90p910_keypad_probe, |
260 | .remove = w90p910_keypad_remove, | 259 | .remove = __devexit_p(w90p910_keypad_remove), |
261 | .driver = { | 260 | .driver = { |
262 | .name = "nuc900-kpi", | 261 | .name = "nuc900-kpi", |
263 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
264 | }, | 263 | }, |
265 | }; | 264 | }; |
266 | module_platform_driver(w90p910_keypad_driver); | 265 | |
266 | static int __init w90p910_keypad_init(void) | ||
267 | { | ||
268 | return platform_driver_register(&w90p910_keypad_driver); | ||
269 | } | ||
270 | |||
271 | static void __exit w90p910_keypad_exit(void) | ||
272 | { | ||
273 | platform_driver_unregister(&w90p910_keypad_driver); | ||
274 | } | ||
275 | |||
276 | module_init(w90p910_keypad_init); | ||
277 | module_exit(w90p910_keypad_exit); | ||
267 | 278 | ||
268 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | 279 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); |
269 | MODULE_DESCRIPTION("w90p910 keypad driver"); | 280 | MODULE_DESCRIPTION("w90p910 keypad driver"); |
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index d050d9d0011..37b01d777a4 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c | |||
@@ -169,4 +169,15 @@ static struct serio_driver xtkbd_drv = { | |||
169 | .disconnect = xtkbd_disconnect, | 169 | .disconnect = xtkbd_disconnect, |
170 | }; | 170 | }; |
171 | 171 | ||
172 | module_serio_driver(xtkbd_drv); | 172 | static int __init xtkbd_init(void) |
173 | { | ||
174 | return serio_register_driver(&xtkbd_drv); | ||
175 | } | ||
176 | |||
177 | static void __exit xtkbd_exit(void) | ||
178 | { | ||
179 | serio_unregister_driver(&xtkbd_drv); | ||
180 | } | ||
181 | |||
182 | module_init(xtkbd_init); | ||
183 | module_exit(xtkbd_exit); | ||