aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2012-01-09 02:38:23 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-01-09 02:38:23 -0500
commitda733563be5a9da26fe81d9f007262d00b846e22 (patch)
treedb28291df94a2043af2123911984c5c173da4e6f /drivers/input/keyboard
parent6ccbcf2cb41131f8d56ef0723bf3f7c1f8486076 (diff)
parentdab78d7924598ea4031663dd10db814e2e324928 (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/Kconfig21
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/adp5520-keys.c13
-rw-r--r--drivers/input/keyboard/amikbd.c15
-rw-r--r--drivers/input/keyboard/atkbd.c40
-rw-r--r--drivers/input/keyboard/bf54x-keys.c16
-rw-r--r--drivers/input/keyboard/davinci_keyscan.c13
-rw-r--r--drivers/input/keyboard/ep93xx_keypad.c14
-rw-r--r--drivers/input/keyboard/gpio_keys_polled.c14
-rw-r--r--drivers/input/keyboard/imx_keypad.c14
-rw-r--r--drivers/input/keyboard/jornada680_kbd.c14
-rw-r--r--drivers/input/keyboard/jornada720_kbd.c14
-rw-r--r--drivers/input/keyboard/lm8323.c11
-rw-r--r--drivers/input/keyboard/matrix_keypad.c14
-rw-r--r--drivers/input/keyboard/nomadik-ske-keypad.c16
-rw-r--r--drivers/input/keyboard/omap-keypad.c17
-rw-r--r--drivers/input/keyboard/omap4-keypad.c13
-rw-r--r--drivers/input/keyboard/opencores-kbd.c13
-rw-r--r--drivers/input/keyboard/pmic8xxx-keypad.c13
-rw-r--r--drivers/input/keyboard/pxa27x_keypad.c14
-rw-r--r--drivers/input/keyboard/pxa930_rotary.c13
-rw-r--r--drivers/input/keyboard/samsung-keypad.c107
-rw-r--r--drivers/input/keyboard/sh_keysc.c14
-rw-r--r--drivers/input/keyboard/spear-keyboard.c13
-rw-r--r--drivers/input/keyboard/stmpe-keypad.c13
-rw-r--r--drivers/input/keyboard/tc3589x-keypad.c15
-rw-r--r--drivers/input/keyboard/tca8418_keypad.c430
-rw-r--r--drivers/input/keyboard/tegra-kbc.c132
-rw-r--r--drivers/input/keyboard/tnetv107x-keypad.c15
-rw-r--r--drivers/input/keyboard/twl4030_keypad.c13
-rw-r--r--drivers/input/keyboard/w90p910_keypad.c14
31 files changed, 707 insertions, 372 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 615c21f2a553..cdc385b2cf7d 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -221,6 +221,22 @@ config KEYBOARD_TCA6416
221 To compile this driver as a module, choose M here: the 221 To compile this driver as a module, choose M here: the
222 module will be called tca6416_keypad. 222 module will be called tca6416_keypad.
223 223
224config KEYBOARD_TCA8418
225 tristate "TCA8418 Keypad Support"
226 depends on I2C
227 help
228 This driver implements basic keypad functionality
229 for keys connected through TCA8418 keypad decoder.
230
231 Say Y here if your device has keys connected to
232 TCA8418 keypad decoder.
233
234 If enabled the complete TCA8418 device will be managed through
235 this driver.
236
237 To compile this driver as a module, choose M here: the
238 module will be called tca8418_keypad.
239
224config KEYBOARD_MATRIX 240config KEYBOARD_MATRIX
225 tristate "GPIO driven matrix keypad support" 241 tristate "GPIO driven matrix keypad support"
226 depends on GENERIC_GPIO 242 depends on GENERIC_GPIO
@@ -425,9 +441,10 @@ config KEYBOARD_PMIC8XXX
425 441
426config KEYBOARD_SAMSUNG 442config KEYBOARD_SAMSUNG
427 tristate "Samsung keypad support" 443 tristate "Samsung keypad support"
428 depends on SAMSUNG_DEV_KEYPAD 444 depends on HAVE_CLK
429 help 445 help
430 Say Y here if you want to use the Samsung keypad. 446 Say Y here if you want to use the keypad on your Samsung mobile
447 device.
431 448
432 To compile this driver as a module, choose M here: the 449 To compile this driver as a module, choose M here: the
433 module will be called samsung-keypad. 450 module will be called samsung-keypad.
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index ddde0fd476f7..df7061f12918 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
16obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o 16obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
17obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o 17obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o
18obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o 18obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o
19obj-$(CONFIG_KEYBOARD_TCA8418) += tca8418_keypad.o
19obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o 20obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
20obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o 21obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
21obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o 22obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c
index 3db8006dac3a..e9e8674dfda1 100644
--- a/drivers/input/keyboard/adp5520-keys.c
+++ b/drivers/input/keyboard/adp5520-keys.c
@@ -202,18 +202,7 @@ static struct platform_driver adp5520_keys_driver = {
202 .probe = adp5520_keys_probe, 202 .probe = adp5520_keys_probe,
203 .remove = __devexit_p(adp5520_keys_remove), 203 .remove = __devexit_p(adp5520_keys_remove),
204}; 204};
205 205module_platform_driver(adp5520_keys_driver);
206static int __init adp5520_keys_init(void)
207{
208 return platform_driver_register(&adp5520_keys_driver);
209}
210module_init(adp5520_keys_init);
211
212static void __exit adp5520_keys_exit(void)
213{
214 platform_driver_unregister(&adp5520_keys_driver);
215}
216module_exit(adp5520_keys_exit);
217 206
218MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 207MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
219MODULE_DESCRIPTION("Keys ADP5520 Driver"); 208MODULE_DESCRIPTION("Keys ADP5520 Driver");
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 79172af164f2..6df5f6aa7908 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -259,19 +259,6 @@ static struct platform_driver amikbd_driver = {
259 .owner = THIS_MODULE, 259 .owner = THIS_MODULE,
260 }, 260 },
261}; 261};
262 262module_platform_driver(amikbd_driver);
263static int __init amikbd_init(void)
264{
265 return platform_driver_probe(&amikbd_driver, amikbd_probe);
266}
267
268module_init(amikbd_init);
269
270static void __exit amikbd_exit(void)
271{
272 platform_driver_unregister(&amikbd_driver);
273}
274
275module_exit(amikbd_exit);
276 263
277MODULE_ALIAS("platform:amiga-keyboard"); 264MODULE_ALIAS("platform:amiga-keyboard");
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 19cfc0cf558c..e05a2e7073c6 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1305,7 +1305,7 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf)
1305static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) 1305static 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 long value; 1308 unsigned int 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,7 +1313,11 @@ 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 if (strict_strtoul(buf, 10, &value) || value > 1) 1316 err = kstrtouint(buf, 10, &value);
1317 if (err)
1318 return err;
1319
1320 if (value > 1)
1317 return -EINVAL; 1321 return -EINVAL;
1318 1322
1319 if (atkbd->extra != value) { 1323 if (atkbd->extra != value) {
@@ -1389,11 +1393,15 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
1389static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) 1393static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
1390{ 1394{
1391 struct input_dev *old_dev, *new_dev; 1395 struct input_dev *old_dev, *new_dev;
1392 unsigned long value; 1396 unsigned int value;
1393 int err; 1397 int err;
1394 bool old_scroll; 1398 bool old_scroll;
1395 1399
1396 if (strict_strtoul(buf, 10, &value) || value > 1) 1400 err = kstrtouint(buf, 10, &value);
1401 if (err)
1402 return err;
1403
1404 if (value > 1)
1397 return -EINVAL; 1405 return -EINVAL;
1398 1406
1399 if (atkbd->scroll != value) { 1407 if (atkbd->scroll != value) {
@@ -1433,7 +1441,7 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf)
1433static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) 1441static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
1434{ 1442{
1435 struct input_dev *old_dev, *new_dev; 1443 struct input_dev *old_dev, *new_dev;
1436 unsigned long value; 1444 unsigned int value;
1437 int err; 1445 int err;
1438 unsigned char old_set; 1446 unsigned char old_set;
1439 bool old_extra; 1447 bool old_extra;
@@ -1441,7 +1449,11 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
1441 if (!atkbd->write) 1449 if (!atkbd->write)
1442 return -EIO; 1450 return -EIO;
1443 1451
1444 if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3)) 1452 err = kstrtouint(buf, 10, &value);
1453 if (err)
1454 return err;
1455
1456 if (value != 2 && value != 3)
1445 return -EINVAL; 1457 return -EINVAL;
1446 1458
1447 if (atkbd->set != value) { 1459 if (atkbd->set != value) {
@@ -1484,14 +1496,18 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf)
1484static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) 1496static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
1485{ 1497{
1486 struct input_dev *old_dev, *new_dev; 1498 struct input_dev *old_dev, *new_dev;
1487 unsigned long value; 1499 unsigned int value;
1488 int err; 1500 int err;
1489 bool old_softrepeat, old_softraw; 1501 bool old_softrepeat, old_softraw;
1490 1502
1491 if (!atkbd->write) 1503 if (!atkbd->write)
1492 return -EIO; 1504 return -EIO;
1493 1505
1494 if (strict_strtoul(buf, 10, &value) || value > 1) 1506 err = kstrtouint(buf, 10, &value);
1507 if (err)
1508 return err;
1509
1510 if (value > 1)
1495 return -EINVAL; 1511 return -EINVAL;
1496 1512
1497 if (atkbd->softrepeat != value) { 1513 if (atkbd->softrepeat != value) {
@@ -1534,11 +1550,15 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf)
1534static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) 1550static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
1535{ 1551{
1536 struct input_dev *old_dev, *new_dev; 1552 struct input_dev *old_dev, *new_dev;
1537 unsigned long value; 1553 unsigned int value;
1538 int err; 1554 int err;
1539 bool old_softraw; 1555 bool old_softraw;
1540 1556
1541 if (strict_strtoul(buf, 10, &value) || value > 1) 1557 err = kstrtouint(buf, 10, &value);
1558 if (err)
1559 return err;
1560
1561 if (value > 1)
1542 return -EINVAL; 1562 return -EINVAL;
1543 1563
1544 if (atkbd->softraw != value) { 1564 if (atkbd->softraw != value) {
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index 7d989603f875..8eb9116e0a5f 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -384,7 +384,7 @@ 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
387struct platform_driver bfin_kpad_device_driver = { 387static 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,
@@ -394,19 +394,7 @@ struct platform_driver bfin_kpad_device_driver = {
394 .suspend = bfin_kpad_suspend, 394 .suspend = bfin_kpad_suspend,
395 .resume = bfin_kpad_resume, 395 .resume = bfin_kpad_resume,
396}; 396};
397 397module_platform_driver(bfin_kpad_device_driver);
398static int __init bfin_kpad_init(void)
399{
400 return platform_driver_register(&bfin_kpad_device_driver);
401}
402
403static void __exit bfin_kpad_exit(void)
404{
405 platform_driver_unregister(&bfin_kpad_device_driver);
406}
407
408module_init(bfin_kpad_init);
409module_exit(bfin_kpad_exit);
410 398
411MODULE_LICENSE("GPL"); 399MODULE_LICENSE("GPL");
412MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 400MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c
index 9d82b3aeff5e..469825247552 100644
--- a/drivers/input/keyboard/davinci_keyscan.c
+++ b/drivers/input/keyboard/davinci_keyscan.c
@@ -328,18 +328,7 @@ static struct platform_driver davinci_ks_driver = {
328 }, 328 },
329 .remove = __devexit_p(davinci_ks_remove), 329 .remove = __devexit_p(davinci_ks_remove),
330}; 330};
331 331module_platform_driver(davinci_ks_driver);
332static int __init davinci_ks_init(void)
333{
334 return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe);
335}
336module_init(davinci_ks_init);
337
338static void __exit davinci_ks_exit(void)
339{
340 platform_driver_unregister(&davinci_ks_driver);
341}
342module_exit(davinci_ks_exit);
343 332
344MODULE_AUTHOR("Miguel Aguilar"); 333MODULE_AUTHOR("Miguel Aguilar");
345MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver"); 334MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver");
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index 4662c5da8018..0ba69f3fcb52 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -390,19 +390,7 @@ static struct platform_driver ep93xx_keypad_driver = {
390 .suspend = ep93xx_keypad_suspend, 390 .suspend = ep93xx_keypad_suspend,
391 .resume = ep93xx_keypad_resume, 391 .resume = ep93xx_keypad_resume,
392}; 392};
393 393module_platform_driver(ep93xx_keypad_driver);
394static int __init ep93xx_keypad_init(void)
395{
396 return platform_driver_register(&ep93xx_keypad_driver);
397}
398
399static void __exit ep93xx_keypad_exit(void)
400{
401 platform_driver_unregister(&ep93xx_keypad_driver);
402}
403
404module_init(ep93xx_keypad_init);
405module_exit(ep93xx_keypad_exit);
406 394
407MODULE_LICENSE("GPL"); 395MODULE_LICENSE("GPL");
408MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); 396MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index 4c17aff20657..20c8ab172214 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -241,19 +241,7 @@ static struct platform_driver gpio_keys_polled_driver = {
241 .owner = THIS_MODULE, 241 .owner = THIS_MODULE,
242 }, 242 },
243}; 243};
244 244module_platform_driver(gpio_keys_polled_driver);
245static int __init gpio_keys_polled_init(void)
246{
247 return platform_driver_register(&gpio_keys_polled_driver);
248}
249
250static void __exit gpio_keys_polled_exit(void)
251{
252 platform_driver_unregister(&gpio_keys_polled_driver);
253}
254
255module_init(gpio_keys_polled_init);
256module_exit(gpio_keys_polled_exit);
257 245
258MODULE_LICENSE("GPL v2"); 246MODULE_LICENSE("GPL v2");
259MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); 247MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index ccebd2d09151..fb87b3bcadb9 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -619,19 +619,7 @@ static struct platform_driver imx_keypad_driver = {
619 .probe = imx_keypad_probe, 619 .probe = imx_keypad_probe,
620 .remove = __devexit_p(imx_keypad_remove), 620 .remove = __devexit_p(imx_keypad_remove),
621}; 621};
622 622module_platform_driver(imx_keypad_driver);
623static int __init imx_keypad_init(void)
624{
625 return platform_driver_register(&imx_keypad_driver);
626}
627
628static void __exit imx_keypad_exit(void)
629{
630 platform_driver_unregister(&imx_keypad_driver);
631}
632
633module_init(imx_keypad_init);
634module_exit(imx_keypad_exit);
635 623
636MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); 624MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
637MODULE_DESCRIPTION("IMX Keypad Port Driver"); 625MODULE_DESCRIPTION("IMX Keypad Port Driver");
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c
index 7197c5698747..24f3ea01c4d5 100644
--- a/drivers/input/keyboard/jornada680_kbd.c
+++ b/drivers/input/keyboard/jornada680_kbd.c
@@ -260,19 +260,7 @@ static struct platform_driver jornada680kbd_driver = {
260 .probe = jornada680kbd_probe, 260 .probe = jornada680kbd_probe,
261 .remove = __devexit_p(jornada680kbd_remove), 261 .remove = __devexit_p(jornada680kbd_remove),
262}; 262};
263 263module_platform_driver(jornada680kbd_driver);
264static int __init jornada680kbd_init(void)
265{
266 return platform_driver_register(&jornada680kbd_driver);
267}
268
269static void __exit jornada680kbd_exit(void)
270{
271 platform_driver_unregister(&jornada680kbd_driver);
272}
273
274module_init(jornada680kbd_init);
275module_exit(jornada680kbd_exit);
276 264
277MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); 265MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
278MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); 266MODULE_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 0aa6740e60d0..eeafc30b207b 100644
--- a/drivers/input/keyboard/jornada720_kbd.c
+++ b/drivers/input/keyboard/jornada720_kbd.c
@@ -174,16 +174,4 @@ static struct platform_driver jornada720_kbd_driver = {
174 .probe = jornada720_kbd_probe, 174 .probe = jornada720_kbd_probe,
175 .remove = __devexit_p(jornada720_kbd_remove), 175 .remove = __devexit_p(jornada720_kbd_remove),
176}; 176};
177 177module_platform_driver(jornada720_kbd_driver);
178static int __init jornada720_kbd_init(void)
179{
180 return platform_driver_register(&jornada720_kbd_driver);
181}
182
183static void __exit jornada720_kbd_exit(void)
184{
185 platform_driver_unregister(&jornada720_kbd_driver);
186}
187
188module_init(jornada720_kbd_init);
189module_exit(jornada720_kbd_exit);
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index 82d1dc8badd5..21823bfc7911 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -545,13 +545,12 @@ 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; 548 int ret, time;
549 unsigned long time;
550 549
551 ret = strict_strtoul(buf, 10, &time); 550 ret = kstrtoint(buf, 10, &time);
552 /* Numbers only, please. */ 551 /* Numbers only, please. */
553 if (ret) 552 if (ret)
554 return -EINVAL; 553 return ret;
555 554
556 pwm->fade_time = time; 555 pwm->fade_time = time;
557 556
@@ -613,9 +612,9 @@ static ssize_t lm8323_set_disable(struct device *dev,
613{ 612{
614 struct lm8323_chip *lm = dev_get_drvdata(dev); 613 struct lm8323_chip *lm = dev_get_drvdata(dev);
615 int ret; 614 int ret;
616 unsigned long i; 615 unsigned int i;
617 616
618 ret = strict_strtoul(buf, 10, &i); 617 ret = kstrtouint(buf, 10, &i);
619 618
620 mutex_lock(&lm->lock); 619 mutex_lock(&lm->lock);
621 lm->kp_enabled = !i; 620 lm->kp_enabled = !i;
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index e2ae657717ea..9b223d73de32 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -496,19 +496,7 @@ static struct platform_driver matrix_keypad_driver = {
496#endif 496#endif
497 }, 497 },
498}; 498};
499 499module_platform_driver(matrix_keypad_driver);
500static int __init matrix_keypad_init(void)
501{
502 return platform_driver_register(&matrix_keypad_driver);
503}
504
505static void __exit matrix_keypad_exit(void)
506{
507 platform_driver_unregister(&matrix_keypad_driver);
508}
509
510module_init(matrix_keypad_init);
511module_exit(matrix_keypad_exit);
512 500
513MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); 501MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
514MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver"); 502MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver");
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c
index 6e0f23091360..5a71e55c9c54 100644
--- a/drivers/input/keyboard/nomadik-ske-keypad.c
+++ b/drivers/input/keyboard/nomadik-ske-keypad.c
@@ -18,6 +18,7 @@
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>
21 22
22#include <plat/ske.h> 23#include <plat/ske.h>
23 24
@@ -378,7 +379,7 @@ static const struct dev_pm_ops ske_keypad_dev_pm_ops = {
378}; 379};
379#endif 380#endif
380 381
381struct platform_driver ske_keypad_driver = { 382static struct platform_driver ske_keypad_driver = {
382 .driver = { 383 .driver = {
383 .name = "nmk-ske-keypad", 384 .name = "nmk-ske-keypad",
384 .owner = THIS_MODULE, 385 .owner = THIS_MODULE,
@@ -389,18 +390,7 @@ struct platform_driver ske_keypad_driver = {
389 .probe = ske_keypad_probe, 390 .probe = ske_keypad_probe,
390 .remove = __devexit_p(ske_keypad_remove), 391 .remove = __devexit_p(ske_keypad_remove),
391}; 392};
392 393module_platform_driver(ske_keypad_driver);
393static int __init ske_keypad_init(void)
394{
395 return platform_driver_probe(&ske_keypad_driver, ske_keypad_probe);
396}
397module_init(ske_keypad_init);
398
399static void __exit ske_keypad_exit(void)
400{
401 platform_driver_unregister(&ske_keypad_driver);
402}
403module_exit(ske_keypad_exit);
404 394
405MODULE_LICENSE("GPL v2"); 395MODULE_LICENSE("GPL v2");
406MODULE_AUTHOR("Naveen Kumar <naveen.gaddipati@stericsson.com> / Sundar Iyer <sundar.iyer@stericsson.com>"); 396MODULE_AUTHOR("Naveen Kumar <naveen.gaddipati@stericsson.com> / Sundar Iyer <sundar.iyer@stericsson.com>");
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 33d0bdc837c0..6b630d9d3dff 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -35,7 +35,7 @@
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 <mach/gpio.h> 38#include <asm/gpio.h>
39#include <plat/keypad.h> 39#include <plat/keypad.h>
40#include <plat/menelaus.h> 40#include <plat/menelaus.h>
41#include <asm/irq.h> 41#include <asm/irq.h>
@@ -473,20 +473,7 @@ static struct platform_driver omap_kp_driver = {
473 .owner = THIS_MODULE, 473 .owner = THIS_MODULE,
474 }, 474 },
475}; 475};
476 476module_platform_driver(omap_kp_driver);
477static 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
483static void __exit omap_kp_exit(void)
484{
485 platform_driver_unregister(&omap_kp_driver);
486}
487
488module_init(omap_kp_init);
489module_exit(omap_kp_exit);
490 477
491MODULE_AUTHOR("Timo Teräs"); 478MODULE_AUTHOR("Timo Teräs");
492MODULE_DESCRIPTION("OMAP Keypad Driver"); 479MODULE_DESCRIPTION("OMAP Keypad Driver");
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c
index c51a3c4a7feb..d5c5d77f4b82 100644
--- a/drivers/input/keyboard/omap4-keypad.c
+++ b/drivers/input/keyboard/omap4-keypad.c
@@ -335,18 +335,7 @@ static struct platform_driver omap4_keypad_driver = {
335 .owner = THIS_MODULE, 335 .owner = THIS_MODULE,
336 }, 336 },
337}; 337};
338 338module_platform_driver(omap4_keypad_driver);
339static int __init omap4_keypad_init(void)
340{
341 return platform_driver_register(&omap4_keypad_driver);
342}
343module_init(omap4_keypad_init);
344
345static void __exit omap4_keypad_exit(void)
346{
347 platform_driver_unregister(&omap4_keypad_driver);
348}
349module_exit(omap4_keypad_exit);
350 339
351MODULE_AUTHOR("Texas Instruments"); 340MODULE_AUTHOR("Texas Instruments");
352MODULE_DESCRIPTION("OMAP4 Keypad Driver"); 341MODULE_DESCRIPTION("OMAP4 Keypad Driver");
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c
index 1f1a5563f60a..abe728c7b88e 100644
--- a/drivers/input/keyboard/opencores-kbd.c
+++ b/drivers/input/keyboard/opencores-kbd.c
@@ -163,18 +163,7 @@ static struct platform_driver opencores_kbd_device_driver = {
163 .name = "opencores-kbd", 163 .name = "opencores-kbd",
164 }, 164 },
165}; 165};
166 166module_platform_driver(opencores_kbd_device_driver);
167static int __init opencores_kbd_init(void)
168{
169 return platform_driver_register(&opencores_kbd_device_driver);
170}
171module_init(opencores_kbd_init);
172
173static void __exit opencores_kbd_exit(void)
174{
175 platform_driver_unregister(&opencores_kbd_device_driver);
176}
177module_exit(opencores_kbd_exit);
178 167
179MODULE_LICENSE("GPL"); 168MODULE_LICENSE("GPL");
180MODULE_AUTHOR("Javier Herrero <jherrero@hvsistemas.es>"); 169MODULE_AUTHOR("Javier Herrero <jherrero@hvsistemas.es>");
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index e7cc51d0fb34..01a1c9f8a383 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -780,18 +780,7 @@ static struct platform_driver pmic8xxx_kp_driver = {
780 .pm = &pm8xxx_kp_pm_ops, 780 .pm = &pm8xxx_kp_pm_ops,
781 }, 781 },
782}; 782};
783 783module_platform_driver(pmic8xxx_kp_driver);
784static int __init pmic8xxx_kp_init(void)
785{
786 return platform_driver_register(&pmic8xxx_kp_driver);
787}
788module_init(pmic8xxx_kp_init);
789
790static void __exit pmic8xxx_kp_exit(void)
791{
792 platform_driver_unregister(&pmic8xxx_kp_driver);
793}
794module_exit(pmic8xxx_kp_exit);
795 784
796MODULE_LICENSE("GPL v2"); 785MODULE_LICENSE("GPL v2");
797MODULE_DESCRIPTION("PMIC8XXX keypad driver"); 786MODULE_DESCRIPTION("PMIC8XXX keypad driver");
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index eca6ae63de14..29fe1b2be1c1 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -602,19 +602,7 @@ static struct platform_driver pxa27x_keypad_driver = {
602#endif 602#endif
603 }, 603 },
604}; 604};
605 605module_platform_driver(pxa27x_keypad_driver);
606static int __init pxa27x_keypad_init(void)
607{
608 return platform_driver_register(&pxa27x_keypad_driver);
609}
610
611static void __exit pxa27x_keypad_exit(void)
612{
613 platform_driver_unregister(&pxa27x_keypad_driver);
614}
615
616module_init(pxa27x_keypad_init);
617module_exit(pxa27x_keypad_exit);
618 606
619MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); 607MODULE_DESCRIPTION("PXA27x Keypad Controller Driver");
620MODULE_LICENSE("GPL"); 608MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c
index 35451bf780c7..d7f1134b789e 100644
--- a/drivers/input/keyboard/pxa930_rotary.c
+++ b/drivers/input/keyboard/pxa930_rotary.c
@@ -195,18 +195,7 @@ static struct platform_driver pxa930_rotary_driver = {
195 .probe = pxa930_rotary_probe, 195 .probe = pxa930_rotary_probe,
196 .remove = __devexit_p(pxa930_rotary_remove), 196 .remove = __devexit_p(pxa930_rotary_remove),
197}; 197};
198 198module_platform_driver(pxa930_rotary_driver);
199static int __init pxa930_rotary_init(void)
200{
201 return platform_driver_register(&pxa930_rotary_driver);
202}
203module_init(pxa930_rotary_init);
204
205static void __exit pxa930_rotary_exit(void)
206{
207 platform_driver_unregister(&pxa930_rotary_driver);
208}
209module_exit(pxa930_rotary_exit);
210 199
211MODULE_LICENSE("GPL"); 200MODULE_LICENSE("GPL");
212MODULE_DESCRIPTION("Driver for PXA93x Enhanced Rotary Controller"); 201MODULE_DESCRIPTION("Driver for PXA93x Enhanced Rotary Controller");
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index f689f49e3109..b746fce2d120 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -20,9 +20,11 @@
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>
23#include <linux/slab.h> 25#include <linux/slab.h>
24#include <linux/sched.h> 26#include <linux/sched.h>
25#include <plat/keypad.h> 27#include <linux/input/samsung-keypad.h>
26 28
27#define SAMSUNG_KEYIFCON 0x00 29#define SAMSUNG_KEYIFCON 0x00
28#define SAMSUNG_KEYIFSTSCLR 0x04 30#define SAMSUNG_KEYIFSTSCLR 0x04
@@ -63,10 +65,12 @@ enum samsung_keypad_type {
63 65
64struct samsung_keypad { 66struct samsung_keypad {
65 struct input_dev *input_dev; 67 struct input_dev *input_dev;
68 struct platform_device *pdev;
66 struct clk *clk; 69 struct clk *clk;
67 void __iomem *base; 70 void __iomem *base;
68 wait_queue_head_t wait; 71 wait_queue_head_t wait;
69 bool stopped; 72 bool stopped;
73 bool wake_enabled;
70 int irq; 74 int irq;
71 unsigned int row_shift; 75 unsigned int row_shift;
72 unsigned int rows; 76 unsigned int rows;
@@ -158,6 +162,8 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id)
158 unsigned int val; 162 unsigned int val;
159 bool key_down; 163 bool key_down;
160 164
165 pm_runtime_get_sync(&keypad->pdev->dev);
166
161 do { 167 do {
162 val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR); 168 val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR);
163 /* Clear interrupt. */ 169 /* Clear interrupt. */
@@ -172,6 +178,8 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id)
172 178
173 } while (key_down && !keypad->stopped); 179 } while (key_down && !keypad->stopped);
174 180
181 pm_runtime_put_sync(&keypad->pdev->dev);
182
175 return IRQ_HANDLED; 183 return IRQ_HANDLED;
176} 184}
177 185
@@ -179,6 +187,8 @@ static void samsung_keypad_start(struct samsung_keypad *keypad)
179{ 187{
180 unsigned int val; 188 unsigned int val;
181 189
190 pm_runtime_get_sync(&keypad->pdev->dev);
191
182 /* Tell IRQ thread that it may poll the device. */ 192 /* Tell IRQ thread that it may poll the device. */
183 keypad->stopped = false; 193 keypad->stopped = false;
184 194
@@ -191,12 +201,16 @@ static void samsung_keypad_start(struct samsung_keypad *keypad)
191 201
192 /* KEYIFCOL reg clear. */ 202 /* KEYIFCOL reg clear. */
193 writel(0, keypad->base + SAMSUNG_KEYIFCOL); 203 writel(0, keypad->base + SAMSUNG_KEYIFCOL);
204
205 pm_runtime_put_sync(&keypad->pdev->dev);
194} 206}
195 207
196static void samsung_keypad_stop(struct samsung_keypad *keypad) 208static void samsung_keypad_stop(struct samsung_keypad *keypad)
197{ 209{
198 unsigned int val; 210 unsigned int val;
199 211
212 pm_runtime_get_sync(&keypad->pdev->dev);
213
200 /* Signal IRQ thread to stop polling and disable the handler. */ 214 /* Signal IRQ thread to stop polling and disable the handler. */
201 keypad->stopped = true; 215 keypad->stopped = true;
202 wake_up(&keypad->wait); 216 wake_up(&keypad->wait);
@@ -217,6 +231,8 @@ static void samsung_keypad_stop(struct samsung_keypad *keypad)
217 * re-enable the handler. 231 * re-enable the handler.
218 */ 232 */
219 enable_irq(keypad->irq); 233 enable_irq(keypad->irq);
234
235 pm_runtime_put_sync(&keypad->pdev->dev);
220} 236}
221 237
222static int samsung_keypad_open(struct input_dev *input_dev) 238static int samsung_keypad_open(struct input_dev *input_dev)
@@ -298,9 +314,11 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
298 } 314 }
299 315
300 keypad->input_dev = input_dev; 316 keypad->input_dev = input_dev;
317 keypad->pdev = pdev;
301 keypad->row_shift = row_shift; 318 keypad->row_shift = row_shift;
302 keypad->rows = pdata->rows; 319 keypad->rows = pdata->rows;
303 keypad->cols = pdata->cols; 320 keypad->cols = pdata->cols;
321 keypad->stopped = true;
304 init_waitqueue_head(&keypad->wait); 322 init_waitqueue_head(&keypad->wait);
305 323
306 input_dev->name = pdev->name; 324 input_dev->name = pdev->name;
@@ -337,16 +355,21 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
337 goto err_put_clk; 355 goto err_put_clk;
338 } 356 }
339 357
358 device_init_wakeup(&pdev->dev, pdata->wakeup);
359 platform_set_drvdata(pdev, keypad);
360 pm_runtime_enable(&pdev->dev);
361
340 error = input_register_device(keypad->input_dev); 362 error = input_register_device(keypad->input_dev);
341 if (error) 363 if (error)
342 goto err_free_irq; 364 goto err_free_irq;
343 365
344 device_init_wakeup(&pdev->dev, pdata->wakeup);
345 platform_set_drvdata(pdev, keypad);
346 return 0; 366 return 0;
347 367
348err_free_irq: 368err_free_irq:
349 free_irq(keypad->irq, keypad); 369 free_irq(keypad->irq, keypad);
370 pm_runtime_disable(&pdev->dev);
371 device_init_wakeup(&pdev->dev, 0);
372 platform_set_drvdata(pdev, NULL);
350err_put_clk: 373err_put_clk:
351 clk_put(keypad->clk); 374 clk_put(keypad->clk);
352err_unmap_base: 375err_unmap_base:
@@ -362,6 +385,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
362{ 385{
363 struct samsung_keypad *keypad = platform_get_drvdata(pdev); 386 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
364 387
388 pm_runtime_disable(&pdev->dev);
365 device_init_wakeup(&pdev->dev, 0); 389 device_init_wakeup(&pdev->dev, 0);
366 platform_set_drvdata(pdev, NULL); 390 platform_set_drvdata(pdev, NULL);
367 391
@@ -381,11 +405,57 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
381 return 0; 405 return 0;
382} 406}
383 407
384#ifdef CONFIG_PM 408#ifdef CONFIG_PM_RUNTIME
409static int samsung_keypad_runtime_suspend(struct device *dev)
410{
411 struct platform_device *pdev = to_platform_device(dev);
412 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
413 unsigned int val;
414 int error;
415
416 if (keypad->stopped)
417 return 0;
418
419 /* This may fail on some SoCs due to lack of controller support */
420 error = enable_irq_wake(keypad->irq);
421 if (!error)
422 keypad->wake_enabled = true;
423
424 val = readl(keypad->base + SAMSUNG_KEYIFCON);
425 val |= SAMSUNG_KEYIFCON_WAKEUPEN;
426 writel(val, keypad->base + SAMSUNG_KEYIFCON);
427
428 clk_disable(keypad->clk);
429
430 return 0;
431}
432
433static int samsung_keypad_runtime_resume(struct device *dev)
434{
435 struct platform_device *pdev = to_platform_device(dev);
436 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
437 unsigned int val;
438
439 if (keypad->stopped)
440 return 0;
441
442 clk_enable(keypad->clk);
443
444 val = readl(keypad->base + SAMSUNG_KEYIFCON);
445 val &= ~SAMSUNG_KEYIFCON_WAKEUPEN;
446 writel(val, keypad->base + SAMSUNG_KEYIFCON);
447
448 if (keypad->wake_enabled)
449 disable_irq_wake(keypad->irq);
450
451 return 0;
452}
453#endif
454
455#ifdef CONFIG_PM_SLEEP
385static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad, 456static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
386 bool enable) 457 bool enable)
387{ 458{
388 struct device *dev = keypad->input_dev->dev.parent;
389 unsigned int val; 459 unsigned int val;
390 460
391 clk_enable(keypad->clk); 461 clk_enable(keypad->clk);
@@ -393,11 +463,11 @@ static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
393 val = readl(keypad->base + SAMSUNG_KEYIFCON); 463 val = readl(keypad->base + SAMSUNG_KEYIFCON);
394 if (enable) { 464 if (enable) {
395 val |= SAMSUNG_KEYIFCON_WAKEUPEN; 465 val |= SAMSUNG_KEYIFCON_WAKEUPEN;
396 if (device_may_wakeup(dev)) 466 if (device_may_wakeup(&keypad->pdev->dev))
397 enable_irq_wake(keypad->irq); 467 enable_irq_wake(keypad->irq);
398 } else { 468 } else {
399 val &= ~SAMSUNG_KEYIFCON_WAKEUPEN; 469 val &= ~SAMSUNG_KEYIFCON_WAKEUPEN;
400 if (device_may_wakeup(dev)) 470 if (device_may_wakeup(&keypad->pdev->dev))
401 disable_irq_wake(keypad->irq); 471 disable_irq_wake(keypad->irq);
402 } 472 }
403 writel(val, keypad->base + SAMSUNG_KEYIFCON); 473 writel(val, keypad->base + SAMSUNG_KEYIFCON);
@@ -440,12 +510,13 @@ static int samsung_keypad_resume(struct device *dev)
440 510
441 return 0; 511 return 0;
442} 512}
513#endif
443 514
444static const struct dev_pm_ops samsung_keypad_pm_ops = { 515static const struct dev_pm_ops samsung_keypad_pm_ops = {
445 .suspend = samsung_keypad_suspend, 516 SET_SYSTEM_SLEEP_PM_OPS(samsung_keypad_suspend, samsung_keypad_resume)
446 .resume = samsung_keypad_resume, 517 SET_RUNTIME_PM_OPS(samsung_keypad_runtime_suspend,
518 samsung_keypad_runtime_resume, NULL)
447}; 519};
448#endif
449 520
450static struct platform_device_id samsung_keypad_driver_ids[] = { 521static struct platform_device_id samsung_keypad_driver_ids[] = {
451 { 522 {
@@ -465,27 +536,13 @@ static struct platform_driver samsung_keypad_driver = {
465 .driver = { 536 .driver = {
466 .name = "samsung-keypad", 537 .name = "samsung-keypad",
467 .owner = THIS_MODULE, 538 .owner = THIS_MODULE,
468#ifdef CONFIG_PM
469 .pm = &samsung_keypad_pm_ops, 539 .pm = &samsung_keypad_pm_ops,
470#endif
471 }, 540 },
472 .id_table = samsung_keypad_driver_ids, 541 .id_table = samsung_keypad_driver_ids,
473}; 542};
474 543module_platform_driver(samsung_keypad_driver);
475static int __init samsung_keypad_init(void)
476{
477 return platform_driver_register(&samsung_keypad_driver);
478}
479module_init(samsung_keypad_init);
480
481static void __exit samsung_keypad_exit(void)
482{
483 platform_driver_unregister(&samsung_keypad_driver);
484}
485module_exit(samsung_keypad_exit);
486 544
487MODULE_DESCRIPTION("Samsung keypad driver"); 545MODULE_DESCRIPTION("Samsung keypad driver");
488MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 546MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
489MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>"); 547MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
490MODULE_LICENSE("GPL"); 548MODULE_LICENSE("GPL");
491MODULE_ALIAS("platform:samsung-keypad");
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 934aeb583b30..da54ad5db154 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -337,19 +337,7 @@ static struct platform_driver sh_keysc_device_driver = {
337 .pm = &sh_keysc_dev_pm_ops, 337 .pm = &sh_keysc_dev_pm_ops,
338 } 338 }
339}; 339};
340 340module_platform_driver(sh_keysc_device_driver);
341static int __init sh_keysc_init(void)
342{
343 return platform_driver_register(&sh_keysc_device_driver);
344}
345
346static void __exit sh_keysc_exit(void)
347{
348 platform_driver_unregister(&sh_keysc_device_driver);
349}
350
351module_init(sh_keysc_init);
352module_exit(sh_keysc_exit);
353 341
354MODULE_AUTHOR("Magnus Damm"); 342MODULE_AUTHOR("Magnus Damm");
355MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver"); 343MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver");
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index d712dffd2157..c88bd63dc9cc 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -326,18 +326,7 @@ static struct platform_driver spear_kbd_driver = {
326#endif 326#endif
327 }, 327 },
328}; 328};
329 329module_platform_driver(spear_kbd_driver);
330static int __init spear_kbd_init(void)
331{
332 return platform_driver_register(&spear_kbd_driver);
333}
334module_init(spear_kbd_init);
335
336static void __exit spear_kbd_exit(void)
337{
338 platform_driver_unregister(&spear_kbd_driver);
339}
340module_exit(spear_kbd_exit);
341 330
342MODULE_AUTHOR("Rajeev Kumar"); 331MODULE_AUTHOR("Rajeev Kumar");
343MODULE_DESCRIPTION("SPEAr Keyboard Driver"); 332MODULE_DESCRIPTION("SPEAr Keyboard Driver");
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
index ab7610ca10eb..9397cf9c625c 100644
--- a/drivers/input/keyboard/stmpe-keypad.c
+++ b/drivers/input/keyboard/stmpe-keypad.c
@@ -368,18 +368,7 @@ static struct platform_driver stmpe_keypad_driver = {
368 .probe = stmpe_keypad_probe, 368 .probe = stmpe_keypad_probe,
369 .remove = __devexit_p(stmpe_keypad_remove), 369 .remove = __devexit_p(stmpe_keypad_remove),
370}; 370};
371 371module_platform_driver(stmpe_keypad_driver);
372static int __init stmpe_keypad_init(void)
373{
374 return platform_driver_register(&stmpe_keypad_driver);
375}
376module_init(stmpe_keypad_init);
377
378static void __exit stmpe_keypad_exit(void)
379{
380 platform_driver_unregister(&stmpe_keypad_driver);
381}
382module_exit(stmpe_keypad_exit);
383 372
384MODULE_LICENSE("GPL v2"); 373MODULE_LICENSE("GPL v2");
385MODULE_DESCRIPTION("STMPExxxx keypad driver"); 374MODULE_DESCRIPTION("STMPExxxx keypad driver");
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c
index f60c9e82f204..2dee3e4e7c6f 100644
--- a/drivers/input/keyboard/tc3589x-keypad.c
+++ b/drivers/input/keyboard/tc3589x-keypad.c
@@ -74,11 +74,13 @@
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
77 * @input: pointer to input device object 78 * @input: pointer to input device object
78 * @board: keypad platform device 79 * @board: keypad platform device
79 * @krow: number of rows 80 * @krow: number of rows
80 * @kcol: number of coloumns 81 * @kcol: number of coloumns
81 * @keymap: matrix scan code table for keycodes 82 * @keymap: matrix scan code table for keycodes
83 * @keypad_stopped: holds keypad status
82 */ 84 */
83struct tc_keypad { 85struct tc_keypad {
84 struct tc3589x *tc3589x; 86 struct tc3589x *tc3589x;
@@ -453,18 +455,7 @@ static struct platform_driver tc3589x_keypad_driver = {
453 .probe = tc3589x_keypad_probe, 455 .probe = tc3589x_keypad_probe,
454 .remove = __devexit_p(tc3589x_keypad_remove), 456 .remove = __devexit_p(tc3589x_keypad_remove),
455}; 457};
456 458module_platform_driver(tc3589x_keypad_driver);
457static int __init tc3589x_keypad_init(void)
458{
459 return platform_driver_register(&tc3589x_keypad_driver);
460}
461module_init(tc3589x_keypad_init);
462
463static void __exit tc3589x_keypad_exit(void)
464{
465 return platform_driver_unregister(&tc3589x_keypad_driver);
466}
467module_exit(tc3589x_keypad_exit);
468 459
469MODULE_LICENSE("GPL v2"); 460MODULE_LICENSE("GPL v2");
470MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer"); 461MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer");
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
new file mode 100644
index 000000000000..958ec107bfbc
--- /dev/null
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -0,0 +1,430 @@
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
39/* TCA8418 hardware limits */
40#define TCA8418_MAX_ROWS 8
41#define TCA8418_MAX_COLS 10
42
43/* TCA8418 register offsets */
44#define REG_CFG 0x01
45#define REG_INT_STAT 0x02
46#define REG_KEY_LCK_EC 0x03
47#define REG_KEY_EVENT_A 0x04
48#define REG_KEY_EVENT_B 0x05
49#define REG_KEY_EVENT_C 0x06
50#define REG_KEY_EVENT_D 0x07
51#define REG_KEY_EVENT_E 0x08
52#define REG_KEY_EVENT_F 0x09
53#define REG_KEY_EVENT_G 0x0A
54#define REG_KEY_EVENT_H 0x0B
55#define REG_KEY_EVENT_I 0x0C
56#define REG_KEY_EVENT_J 0x0D
57#define REG_KP_LCK_TIMER 0x0E
58#define REG_UNLOCK1 0x0F
59#define REG_UNLOCK2 0x10
60#define REG_GPIO_INT_STAT1 0x11
61#define REG_GPIO_INT_STAT2 0x12
62#define REG_GPIO_INT_STAT3 0x13
63#define REG_GPIO_DAT_STAT1 0x14
64#define REG_GPIO_DAT_STAT2 0x15
65#define REG_GPIO_DAT_STAT3 0x16
66#define REG_GPIO_DAT_OUT1 0x17
67#define REG_GPIO_DAT_OUT2 0x18
68#define REG_GPIO_DAT_OUT3 0x19
69#define REG_GPIO_INT_EN1 0x1A
70#define REG_GPIO_INT_EN2 0x1B
71#define REG_GPIO_INT_EN3 0x1C
72#define REG_KP_GPIO1 0x1D
73#define REG_KP_GPIO2 0x1E
74#define REG_KP_GPIO3 0x1F
75#define REG_GPI_EM1 0x20
76#define REG_GPI_EM2 0x21
77#define REG_GPI_EM3 0x22
78#define REG_GPIO_DIR1 0x23
79#define REG_GPIO_DIR2 0x24
80#define REG_GPIO_DIR3 0x25
81#define REG_GPIO_INT_LVL1 0x26
82#define REG_GPIO_INT_LVL2 0x27
83#define REG_GPIO_INT_LVL3 0x28
84#define REG_DEBOUNCE_DIS1 0x29
85#define REG_DEBOUNCE_DIS2 0x2A
86#define REG_DEBOUNCE_DIS3 0x2B
87#define REG_GPIO_PULL1 0x2C
88#define REG_GPIO_PULL2 0x2D
89#define REG_GPIO_PULL3 0x2E
90
91/* TCA8418 bit definitions */
92#define CFG_AI BIT(7)
93#define CFG_GPI_E_CFG BIT(6)
94#define CFG_OVR_FLOW_M BIT(5)
95#define CFG_INT_CFG BIT(4)
96#define CFG_OVR_FLOW_IEN BIT(3)
97#define CFG_K_LCK_IEN BIT(2)
98#define CFG_GPI_IEN BIT(1)
99#define CFG_KE_IEN BIT(0)
100
101#define INT_STAT_CAD_INT BIT(4)
102#define INT_STAT_OVR_FLOW_INT BIT(3)
103#define INT_STAT_K_LCK_INT BIT(2)
104#define INT_STAT_GPI_INT BIT(1)
105#define INT_STAT_K_INT BIT(0)
106
107/* TCA8418 register masks */
108#define KEY_LCK_EC_KEC 0x7
109#define KEY_EVENT_CODE 0x7f
110#define KEY_EVENT_VALUE 0x80
111
112
113static const struct i2c_device_id tca8418_id[] = {
114 { TCA8418_NAME, 8418, },
115 { }
116};
117MODULE_DEVICE_TABLE(i2c, tca8418_id);
118
119struct tca8418_keypad {
120 unsigned int rows;
121 unsigned int cols;
122 unsigned int keypad_mask; /* Mask for keypad col/rol regs */
123 unsigned int irq;
124 unsigned int row_shift;
125
126 struct i2c_client *client;
127 struct input_dev *input;
128
129 /* Flexible array member, must be at end of struct */
130 unsigned short keymap[];
131};
132
133/*
134 * Write a byte to the TCA8418
135 */
136static int tca8418_write_byte(struct tca8418_keypad *keypad_data,
137 int reg, u8 val)
138{
139 int error;
140
141 error = i2c_smbus_write_byte_data(keypad_data->client, reg, val);
142 if (error < 0) {
143 dev_err(&keypad_data->client->dev,
144 "%s failed, reg: %d, val: %d, error: %d\n",
145 __func__, reg, val, error);
146 return error;
147 }
148
149 return 0;
150}
151
152/*
153 * Read a byte from the TCA8418
154 */
155static int tca8418_read_byte(struct tca8418_keypad *keypad_data,
156 int reg, u8 *val)
157{
158 int error;
159
160 error = i2c_smbus_read_byte_data(keypad_data->client, reg);
161 if (error < 0) {
162 dev_err(&keypad_data->client->dev,
163 "%s failed, reg: %d, error: %d\n",
164 __func__, reg, error);
165 return error;
166 }
167
168 *val = (u8)error;
169
170 return 0;
171}
172
173static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
174{
175 int error, col, row;
176 u8 reg, state, code;
177
178 /* Initial read of the key event FIFO */
179 error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
180
181 /* Assume that key code 0 signifies empty FIFO */
182 while (error >= 0 && reg > 0) {
183 state = reg & KEY_EVENT_VALUE;
184 code = reg & KEY_EVENT_CODE;
185
186 row = code / TCA8418_MAX_COLS;
187 col = code % TCA8418_MAX_COLS;
188
189 row = (col) ? row : row - 1;
190 col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
191
192 code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
193 input_event(keypad_data->input, EV_MSC, MSC_SCAN, code);
194 input_report_key(keypad_data->input,
195 keypad_data->keymap[code], state);
196
197 /* Read for next loop */
198 error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
199 }
200
201 if (error < 0)
202 dev_err(&keypad_data->client->dev,
203 "unable to read REG_KEY_EVENT_A\n");
204
205 input_sync(keypad_data->input);
206}
207
208/*
209 * Threaded IRQ handler and this can (and will) sleep.
210 */
211static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
212{
213 struct tca8418_keypad *keypad_data = dev_id;
214 u8 reg;
215 int error;
216
217 error = tca8418_read_byte(keypad_data, REG_INT_STAT, &reg);
218 if (error) {
219 dev_err(&keypad_data->client->dev,
220 "unable to read REG_INT_STAT\n");
221 goto exit;
222 }
223
224 if (reg & INT_STAT_OVR_FLOW_INT)
225 dev_warn(&keypad_data->client->dev, "overflow occurred\n");
226
227 if (reg & INT_STAT_K_INT)
228 tca8418_read_keypad(keypad_data);
229
230exit:
231 /* Clear all interrupts, even IRQs we didn't check (GPI, CAD, LCK) */
232 reg = 0xff;
233 error = tca8418_write_byte(keypad_data, REG_INT_STAT, reg);
234 if (error)
235 dev_err(&keypad_data->client->dev,
236 "unable to clear REG_INT_STAT\n");
237
238 return IRQ_HANDLED;
239}
240
241/*
242 * Configure the TCA8418 for keypad operation
243 */
244static int __devinit tca8418_configure(struct tca8418_keypad *keypad_data)
245{
246 int reg, error;
247
248 /* Write config register, if this fails assume device not present */
249 error = tca8418_write_byte(keypad_data, REG_CFG,
250 CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
251 if (error < 0)
252 return -ENODEV;
253
254
255 /* Assemble a mask for row and column registers */
256 reg = ~(~0 << keypad_data->rows);
257 reg += (~(~0 << keypad_data->cols)) << 8;
258 keypad_data->keypad_mask = reg;
259
260 /* Set registers to keypad mode */
261 error |= tca8418_write_byte(keypad_data, REG_KP_GPIO1, reg);
262 error |= tca8418_write_byte(keypad_data, REG_KP_GPIO2, reg >> 8);
263 error |= tca8418_write_byte(keypad_data, REG_KP_GPIO3, reg >> 16);
264
265 /* Enable column debouncing */
266 error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS1, reg);
267 error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8);
268 error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16);
269
270 return error;
271}
272
273static int __devinit tca8418_keypad_probe(struct i2c_client *client,
274 const struct i2c_device_id *id)
275{
276 const struct tca8418_keypad_platform_data *pdata =
277 client->dev.platform_data;
278 struct tca8418_keypad *keypad_data;
279 struct input_dev *input;
280 int error, row_shift, max_keys;
281
282 /* Copy the platform data */
283 if (!pdata) {
284 dev_dbg(&client->dev, "no platform data\n");
285 return -EINVAL;
286 }
287
288 if (!pdata->keymap_data) {
289 dev_err(&client->dev, "no keymap data defined\n");
290 return -EINVAL;
291 }
292
293 if (!pdata->rows || pdata->rows > TCA8418_MAX_ROWS) {
294 dev_err(&client->dev, "invalid rows\n");
295 return -EINVAL;
296 }
297
298 if (!pdata->cols || pdata->cols > TCA8418_MAX_COLS) {
299 dev_err(&client->dev, "invalid columns\n");
300 return -EINVAL;
301 }
302
303 /* Check i2c driver capabilities */
304 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
305 dev_err(&client->dev, "%s adapter not supported\n",
306 dev_driver_string(&client->adapter->dev));
307 return -ENODEV;
308 }
309
310 row_shift = get_count_order(pdata->cols);
311 max_keys = pdata->rows << row_shift;
312
313 /* Allocate memory for keypad_data, keymap and input device */
314 keypad_data = kzalloc(sizeof(*keypad_data) +
315 max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL);
316 if (!keypad_data)
317 return -ENOMEM;
318
319 keypad_data->rows = pdata->rows;
320 keypad_data->cols = pdata->cols;
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);
326 if (error < 0)
327 goto fail1;
328
329 /* Configure input device */
330 input = input_allocate_device();
331 if (!input) {
332 error = -ENOMEM;
333 goto fail1;
334 }
335 keypad_data->input = input;
336
337 input->name = client->name;
338 input->dev.parent = &client->dev;
339
340 input->id.bustype = BUS_I2C;
341 input->id.vendor = 0x0001;
342 input->id.product = 0x001;
343 input->id.version = 0x0001;
344
345 input->keycode = keypad_data->keymap;
346 input->keycodesize = sizeof(keypad_data->keymap[0]);
347 input->keycodemax = max_keys;
348
349 __set_bit(EV_KEY, input->evbit);
350 if (pdata->rep)
351 __set_bit(EV_REP, input->evbit);
352
353 input_set_capability(input, EV_MSC, MSC_SCAN);
354
355 input_set_drvdata(input, keypad_data);
356
357 matrix_keypad_build_keymap(pdata->keymap_data, row_shift,
358 input->keycode, input->keybit);
359
360 if (pdata->irq_is_gpio)
361 client->irq = gpio_to_irq(client->irq);
362
363 error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler,
364 IRQF_TRIGGER_FALLING,
365 client->name, keypad_data);
366 if (error) {
367 dev_dbg(&client->dev,
368 "Unable to claim irq %d; error %d\n",
369 client->irq, error);
370 goto fail2;
371 }
372
373 error = input_register_device(input);
374 if (error) {
375 dev_dbg(&client->dev,
376 "Unable to register input device, error: %d\n", error);
377 goto fail3;
378 }
379
380 i2c_set_clientdata(client, keypad_data);
381 return 0;
382
383fail3:
384 free_irq(client->irq, keypad_data);
385fail2:
386 input_free_device(input);
387fail1:
388 kfree(keypad_data);
389 return error;
390}
391
392static int __devexit tca8418_keypad_remove(struct i2c_client *client)
393{
394 struct tca8418_keypad *keypad_data = i2c_get_clientdata(client);
395
396 free_irq(keypad_data->client->irq, keypad_data);
397
398 input_unregister_device(keypad_data->input);
399
400 kfree(keypad_data);
401
402 return 0;
403}
404
405
406static struct i2c_driver tca8418_keypad_driver = {
407 .driver = {
408 .name = TCA8418_NAME,
409 .owner = THIS_MODULE,
410 },
411 .probe = tca8418_keypad_probe,
412 .remove = __devexit_p(tca8418_keypad_remove),
413 .id_table = tca8418_id,
414};
415
416static int __init tca8418_keypad_init(void)
417{
418 return i2c_add_driver(&tca8418_keypad_driver);
419}
420subsys_initcall(tca8418_keypad_init);
421
422static void __exit tca8418_keypad_exit(void)
423{
424 i2c_del_driver(&tca8418_keypad_driver);
425}
426module_exit(tca8418_keypad_exit);
427
428MODULE_AUTHOR("Kyle Manna <kyle.manna@fuel7.com>");
429MODULE_DESCRIPTION("Keypad driver for TCA8418");
430MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index cf3228b0ab90..a136e2e832be 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -26,6 +26,7 @@
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>
29#include <linux/clk.h> 30#include <linux/clk.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <mach/clk.h> 32#include <mach/clk.h>
@@ -52,6 +53,7 @@
52/* KBC Interrupt Register */ 53/* KBC Interrupt Register */
53#define KBC_INT_0 0x4 54#define KBC_INT_0 0x4
54#define KBC_INT_FIFO_CNT_INT_STATUS (1 << 2) 55#define KBC_INT_FIFO_CNT_INT_STATUS (1 << 2)
56#define KBC_INT_KEYPRESS_INT_STATUS (1 << 0)
55 57
56#define KBC_ROW_CFG0_0 0x8 58#define KBC_ROW_CFG0_0 0x8
57#define KBC_COL_CFG0_0 0x18 59#define KBC_COL_CFG0_0 0x18
@@ -74,15 +76,17 @@ struct tegra_kbc {
74 unsigned int cp_to_wkup_dly; 76 unsigned int cp_to_wkup_dly;
75 bool use_fn_map; 77 bool use_fn_map;
76 bool use_ghost_filter; 78 bool use_ghost_filter;
79 bool keypress_caused_wake;
77 const struct tegra_kbc_platform_data *pdata; 80 const struct tegra_kbc_platform_data *pdata;
78 unsigned short keycode[KBC_MAX_KEY * 2]; 81 unsigned short keycode[KBC_MAX_KEY * 2];
79 unsigned short current_keys[KBC_MAX_KPENT]; 82 unsigned short current_keys[KBC_MAX_KPENT];
80 unsigned int num_pressed_keys; 83 unsigned int num_pressed_keys;
84 u32 wakeup_key;
81 struct timer_list timer; 85 struct timer_list timer;
82 struct clk *clk; 86 struct clk *clk;
83}; 87};
84 88
85static const u32 tegra_kbc_default_keymap[] = { 89static const u32 tegra_kbc_default_keymap[] __devinitdata = {
86 KEY(0, 2, KEY_W), 90 KEY(0, 2, KEY_W),
87 KEY(0, 3, KEY_S), 91 KEY(0, 3, KEY_S),
88 KEY(0, 4, KEY_A), 92 KEY(0, 4, KEY_A),
@@ -217,7 +221,8 @@ static const u32 tegra_kbc_default_keymap[] = {
217 KEY(31, 4, KEY_HELP), 221 KEY(31, 4, KEY_HELP),
218}; 222};
219 223
220static const struct matrix_keymap_data tegra_kbc_default_keymap_data = { 224static const
225struct matrix_keymap_data tegra_kbc_default_keymap_data __devinitdata = {
221 .keymap = tegra_kbc_default_keymap, 226 .keymap = tegra_kbc_default_keymap,
222 .keymap_size = ARRAY_SIZE(tegra_kbc_default_keymap), 227 .keymap_size = ARRAY_SIZE(tegra_kbc_default_keymap),
223}; 228};
@@ -409,6 +414,9 @@ static irqreturn_t tegra_kbc_isr(int irq, void *args)
409 */ 414 */
410 tegra_kbc_set_fifo_interrupt(kbc, false); 415 tegra_kbc_set_fifo_interrupt(kbc, false);
411 mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies); 416 mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies);
417 } else if (val & KBC_INT_KEYPRESS_INT_STATUS) {
418 /* We can be here only through system resume path */
419 kbc->keypress_caused_wake = true;
412 } 420 }
413 421
414 spin_unlock_irqrestore(&kbc->lock, flags); 422 spin_unlock_irqrestore(&kbc->lock, flags);
@@ -576,6 +584,56 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata,
576 return true; 584 return true;
577} 585}
578 586
587#ifdef CONFIG_OF
588static struct tegra_kbc_platform_data * __devinit
589tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
590{
591 struct tegra_kbc_platform_data *pdata;
592 struct device_node *np = pdev->dev.of_node;
593
594 if (!np)
595 return NULL;
596
597 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
598 if (!pdata)
599 return NULL;
600
601 if (!of_property_read_u32(np, "debounce-delay", &prop))
602 pdata->debounce_cnt = prop;
603
604 if (!of_property_read_u32(np, "repeat-delay", &prop))
605 pdata->repeat_cnt = prop;
606
607 if (of_find_property(np, "needs-ghost-filter", NULL))
608 pdata->use_ghost_filter = true;
609
610 if (of_find_property(np, "wakeup-source", NULL))
611 pdata->wakeup = true;
612
613 /*
614 * All currently known keymaps with device tree support use the same
615 * pin_cfg, so set it up here.
616 */
617 for (i = 0; i < KBC_MAX_ROW; i++) {
618 pdata->pin_cfg[i].num = i;
619 pdata->pin_cfg[i].is_row = true;
620 }
621
622 for (i = 0; i < KBC_MAX_COL; i++) {
623 pdata->pin_cfg[KBC_MAX_ROW + i].num = i;
624 pdata->pin_cfg[KBC_MAX_ROW + i].is_row = false;
625 }
626
627 return pdata;
628}
629#else
630static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
631 struct platform_device *pdev)
632{
633 return NULL;
634}
635#endif
636
579static int __devinit tegra_kbc_probe(struct platform_device *pdev) 637static int __devinit tegra_kbc_probe(struct platform_device *pdev)
580{ 638{
581 const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; 639 const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data;
@@ -590,21 +648,28 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
590 unsigned int scan_time_rows; 648 unsigned int scan_time_rows;
591 649
592 if (!pdata) 650 if (!pdata)
593 return -EINVAL; 651 pdata = tegra_kbc_dt_parse_pdata(pdev);
594 652
595 if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows)) 653 if (!pdata)
596 return -EINVAL; 654 return -EINVAL;
597 655
656 if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows)) {
657 err = -EINVAL;
658 goto err_free_pdata;
659 }
660
598 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 661 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
599 if (!res) { 662 if (!res) {
600 dev_err(&pdev->dev, "failed to get I/O memory\n"); 663 dev_err(&pdev->dev, "failed to get I/O memory\n");
601 return -ENXIO; 664 err = -ENXIO;
665 goto err_free_pdata;
602 } 666 }
603 667
604 irq = platform_get_irq(pdev, 0); 668 irq = platform_get_irq(pdev, 0);
605 if (irq < 0) { 669 if (irq < 0) {
606 dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); 670 dev_err(&pdev->dev, "failed to get keyboard IRQ\n");
607 return -ENXIO; 671 err = -ENXIO;
672 goto err_free_pdata;
608 } 673 }
609 674
610 kbc = kzalloc(sizeof(*kbc), GFP_KERNEL); 675 kbc = kzalloc(sizeof(*kbc), GFP_KERNEL);
@@ -674,9 +739,10 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
674 keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; 739 keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data;
675 matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, 740 matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT,
676 input_dev->keycode, input_dev->keybit); 741 input_dev->keycode, input_dev->keybit);
742 kbc->wakeup_key = pdata->wakeup_key;
677 743
678 err = request_irq(kbc->irq, tegra_kbc_isr, IRQF_TRIGGER_HIGH, 744 err = request_irq(kbc->irq, tegra_kbc_isr,
679 pdev->name, kbc); 745 IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc);
680 if (err) { 746 if (err) {
681 dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); 747 dev_err(&pdev->dev, "failed to request keyboard IRQ\n");
682 goto err_put_clk; 748 goto err_put_clk;
@@ -706,6 +772,9 @@ err_free_mem_region:
706err_free_mem: 772err_free_mem:
707 input_free_device(input_dev); 773 input_free_device(input_dev);
708 kfree(kbc); 774 kfree(kbc);
775err_free_pdata:
776 if (!pdev->dev.platform_data)
777 kfree(pdata);
709 778
710 return err; 779 return err;
711} 780}
@@ -715,6 +784,8 @@ static int __devexit tegra_kbc_remove(struct platform_device *pdev)
715 struct tegra_kbc *kbc = platform_get_drvdata(pdev); 784 struct tegra_kbc *kbc = platform_get_drvdata(pdev);
716 struct resource *res; 785 struct resource *res;
717 786
787 platform_set_drvdata(pdev, NULL);
788
718 free_irq(kbc->irq, pdev); 789 free_irq(kbc->irq, pdev);
719 clk_put(kbc->clk); 790 clk_put(kbc->clk);
720 791
@@ -723,9 +794,14 @@ static int __devexit tegra_kbc_remove(struct platform_device *pdev)
723 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 794 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
724 release_mem_region(res->start, resource_size(res)); 795 release_mem_region(res->start, resource_size(res));
725 796
726 kfree(kbc); 797 /*
798 * If we do not have platform data attached to the device we
799 * allocated it ourselves and thus need to free it.
800 */
801 if (!pdev->dev.platform_data)
802 kfree(kbc->pdata);
727 803
728 platform_set_drvdata(pdev, NULL); 804 kfree(kbc);
729 805
730 return 0; 806 return 0;
731} 807}
@@ -754,6 +830,8 @@ static int tegra_kbc_suspend(struct device *dev)
754 tegra_kbc_setup_wakekeys(kbc, true); 830 tegra_kbc_setup_wakekeys(kbc, true);
755 msleep(30); 831 msleep(30);
756 832
833 kbc->keypress_caused_wake = false;
834 enable_irq(kbc->irq);
757 enable_irq_wake(kbc->irq); 835 enable_irq_wake(kbc->irq);
758 } else { 836 } else {
759 if (kbc->idev->users) 837 if (kbc->idev->users)
@@ -780,7 +858,19 @@ static int tegra_kbc_resume(struct device *dev)
780 858
781 tegra_kbc_set_fifo_interrupt(kbc, true); 859 tegra_kbc_set_fifo_interrupt(kbc, true);
782 860
783 enable_irq(kbc->irq); 861 if (kbc->keypress_caused_wake && kbc->wakeup_key) {
862 /*
863 * We can't report events directly from the ISR
864 * because timekeeping is stopped when processing
865 * wakeup request and we get a nasty warning when
866 * we try to call do_gettimeofday() in evdev
867 * handler.
868 */
869 input_report_key(kbc->idev, kbc->wakeup_key, 1);
870 input_sync(kbc->idev);
871 input_report_key(kbc->idev, kbc->wakeup_key, 0);
872 input_sync(kbc->idev);
873 }
784 } else { 874 } else {
785 if (kbc->idev->users) 875 if (kbc->idev->users)
786 err = tegra_kbc_start(kbc); 876 err = tegra_kbc_start(kbc);
@@ -793,6 +883,12 @@ static int tegra_kbc_resume(struct device *dev)
793 883
794static SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops, tegra_kbc_suspend, tegra_kbc_resume); 884static SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops, tegra_kbc_suspend, tegra_kbc_resume);
795 885
886static const struct of_device_id tegra_kbc_of_match[] = {
887 { .compatible = "nvidia,tegra20-kbc", },
888 { },
889};
890MODULE_DEVICE_TABLE(of, tegra_kbc_of_match);
891
796static struct platform_driver tegra_kbc_driver = { 892static struct platform_driver tegra_kbc_driver = {
797 .probe = tegra_kbc_probe, 893 .probe = tegra_kbc_probe,
798 .remove = __devexit_p(tegra_kbc_remove), 894 .remove = __devexit_p(tegra_kbc_remove),
@@ -800,20 +896,10 @@ static struct platform_driver tegra_kbc_driver = {
800 .name = "tegra-kbc", 896 .name = "tegra-kbc",
801 .owner = THIS_MODULE, 897 .owner = THIS_MODULE,
802 .pm = &tegra_kbc_pm_ops, 898 .pm = &tegra_kbc_pm_ops,
899 .of_match_table = tegra_kbc_of_match,
803 }, 900 },
804}; 901};
805 902module_platform_driver(tegra_kbc_driver);
806static void __exit tegra_kbc_exit(void)
807{
808 platform_driver_unregister(&tegra_kbc_driver);
809}
810module_exit(tegra_kbc_exit);
811
812static int __init tegra_kbc_init(void)
813{
814 return platform_driver_register(&tegra_kbc_driver);
815}
816module_init(tegra_kbc_init);
817 903
818MODULE_LICENSE("GPL"); 904MODULE_LICENSE("GPL");
819MODULE_AUTHOR("Rakesh Iyer <riyer@nvidia.com>"); 905MODULE_AUTHOR("Rakesh Iyer <riyer@nvidia.com>");
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c
index 1c58681de81f..fb39c94b6fdd 100644
--- a/drivers/input/keyboard/tnetv107x-keypad.c
+++ b/drivers/input/keyboard/tnetv107x-keypad.c
@@ -24,6 +24,7 @@
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>
27 28
28#define BITS(x) (BIT(x) - 1) 29#define BITS(x) (BIT(x) - 1)
29 30
@@ -321,19 +322,7 @@ static struct platform_driver keypad_driver = {
321 .driver.name = "tnetv107x-keypad", 322 .driver.name = "tnetv107x-keypad",
322 .driver.owner = THIS_MODULE, 323 .driver.owner = THIS_MODULE,
323}; 324};
324 325module_platform_driver(keypad_driver);
325static int __init keypad_init(void)
326{
327 return platform_driver_register(&keypad_driver);
328}
329
330static void __exit keypad_exit(void)
331{
332 platform_driver_unregister(&keypad_driver);
333}
334
335module_init(keypad_init);
336module_exit(keypad_exit);
337 326
338MODULE_AUTHOR("Cyril Chemparathy"); 327MODULE_AUTHOR("Cyril Chemparathy");
339MODULE_DESCRIPTION("TNETV107X Keypad Driver"); 328MODULE_DESCRIPTION("TNETV107X Keypad Driver");
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c
index a26922cf0e84..a588578037eb 100644
--- a/drivers/input/keyboard/twl4030_keypad.c
+++ b/drivers/input/keyboard/twl4030_keypad.c
@@ -460,18 +460,7 @@ static struct platform_driver twl4030_kp_driver = {
460 .owner = THIS_MODULE, 460 .owner = THIS_MODULE,
461 }, 461 },
462}; 462};
463 463module_platform_driver(twl4030_kp_driver);
464static int __init twl4030_kp_init(void)
465{
466 return platform_driver_register(&twl4030_kp_driver);
467}
468module_init(twl4030_kp_init);
469
470static void __exit twl4030_kp_exit(void)
471{
472 platform_driver_unregister(&twl4030_kp_driver);
473}
474module_exit(twl4030_kp_exit);
475 464
476MODULE_AUTHOR("Texas Instruments"); 465MODULE_AUTHOR("Texas Instruments");
477MODULE_DESCRIPTION("TWL4030 Keypad Driver"); 466MODULE_DESCRIPTION("TWL4030 Keypad Driver");
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c
index 318586dadacf..99bbb7e775ae 100644
--- a/drivers/input/keyboard/w90p910_keypad.c
+++ b/drivers/input/keyboard/w90p910_keypad.c
@@ -262,19 +262,7 @@ static struct platform_driver w90p910_keypad_driver = {
262 .owner = THIS_MODULE, 262 .owner = THIS_MODULE,
263 }, 263 },
264}; 264};
265 265module_platform_driver(w90p910_keypad_driver);
266static int __init w90p910_keypad_init(void)
267{
268 return platform_driver_register(&w90p910_keypad_driver);
269}
270
271static void __exit w90p910_keypad_exit(void)
272{
273 platform_driver_unregister(&w90p910_keypad_driver);
274}
275
276module_init(w90p910_keypad_init);
277module_exit(w90p910_keypad_exit);
278 266
279MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); 267MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
280MODULE_DESCRIPTION("w90p910 keypad driver"); 268MODULE_DESCRIPTION("w90p910 keypad driver");