aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 13:55:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 13:55:52 -0500
commitdbe950f201a8edd353b0bd9079e8d536ee4ce37c (patch)
treedffbada6b3d33cc67383758570de22b4f45693b6 /drivers/input/keyboard
parentf62f61917d72c1fb0101ad405664f6fc868d676b (diff)
parentda733563be5a9da26fe81d9f007262d00b846e22 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (64 commits) Input: tc3589x-keypad - add missing kerneldoc Input: ucb1400-ts - switch to using dev_xxx() for diagnostic messages Input: ucb1400_ts - convert to threaded IRQ Input: ucb1400_ts - drop inline annotations Input: usb1400_ts - add __devinit/__devexit section annotations Input: ucb1400_ts - set driver owner Input: ucb1400_ts - convert to use dev_pm_ops Input: psmouse - make sure we do not use stale methods Input: evdev - do not block waiting for an event if fd is nonblock Input: evdev - if no events and non-block, return EAGAIN not 0 Input: evdev - only allow reading events if a full packet is present Input: add driver for pixcir i2c touchscreens Input: samsung-keypad - implement runtime power management support Input: tegra-kbc - report wakeup key for some platforms Input: tegra-kbc - add device tree bindings Input: add driver for AUO In-Cell touchscreens using pixcir ICs Input: mpu3050 - configure the sampling method Input: mpu3050 - ensure we enable interrupts Input: mpu3050 - add of_match table for device-tree probing Input: sentelic - document the latest hardware ... Fix up fairly trivial conflicts (device tree matching conflicting with some independent cleanups) in drivers/input/keyboard/samsung-keypad.c
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.c15
-rw-r--r--drivers/input/keyboard/omap-keypad.c15
-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.c108
-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.c14
-rw-r--r--drivers/input/keyboard/twl4030_keypad.c13
-rw-r--r--drivers/input/keyboard/w90p910_keypad.c14
31 files changed, 704 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 fcdec5e2b297..5a71e55c9c54 100644
--- a/drivers/input/keyboard/nomadik-ske-keypad.c
+++ b/drivers/input/keyboard/nomadik-ske-keypad.c
@@ -379,7 +379,7 @@ static const struct dev_pm_ops ske_keypad_dev_pm_ops = {
379}; 379};
380#endif 380#endif
381 381
382struct platform_driver ske_keypad_driver = { 382static struct platform_driver ske_keypad_driver = {
383 .driver = { 383 .driver = {
384 .name = "nmk-ske-keypad", 384 .name = "nmk-ske-keypad",
385 .owner = THIS_MODULE, 385 .owner = THIS_MODULE,
@@ -390,18 +390,7 @@ struct platform_driver ske_keypad_driver = {
390 .probe = ske_keypad_probe, 390 .probe = ske_keypad_probe,
391 .remove = __devexit_p(ske_keypad_remove), 391 .remove = __devexit_p(ske_keypad_remove),
392}; 392};
393 393module_platform_driver(ske_keypad_driver);
394static int __init ske_keypad_init(void)
395{
396 return platform_driver_probe(&ske_keypad_driver, ske_keypad_probe);
397}
398module_init(ske_keypad_init);
399
400static void __exit ske_keypad_exit(void)
401{
402 platform_driver_unregister(&ske_keypad_driver);
403}
404module_exit(ske_keypad_exit);
405 394
406MODULE_LICENSE("GPL v2"); 395MODULE_LICENSE("GPL v2");
407MODULE_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 323bcdfff248..6b630d9d3dff 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -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 8a0060cd3982..17ba7f9f80f3 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -20,11 +20,13 @@
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/of.h> 26#include <linux/of.h>
25#include <linux/of_gpio.h> 27#include <linux/of_gpio.h>
26#include <linux/sched.h> 28#include <linux/sched.h>
27#include <plat/keypad.h> 29#include <linux/input/samsung-keypad.h>
28 30
29#define SAMSUNG_KEYIFCON 0x00 31#define SAMSUNG_KEYIFCON 0x00
30#define SAMSUNG_KEYIFSTSCLR 0x04 32#define SAMSUNG_KEYIFSTSCLR 0x04
@@ -65,10 +67,12 @@ enum samsung_keypad_type {
65 67
66struct samsung_keypad { 68struct samsung_keypad {
67 struct input_dev *input_dev; 69 struct input_dev *input_dev;
70 struct platform_device *pdev;
68 struct clk *clk; 71 struct clk *clk;
69 void __iomem *base; 72 void __iomem *base;
70 wait_queue_head_t wait; 73 wait_queue_head_t wait;
71 bool stopped; 74 bool stopped;
75 bool wake_enabled;
72 int irq; 76 int irq;
73 enum samsung_keypad_type type; 77 enum samsung_keypad_type type;
74 unsigned int row_shift; 78 unsigned int row_shift;
@@ -155,6 +159,8 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id)
155 unsigned int val; 159 unsigned int val;
156 bool key_down; 160 bool key_down;
157 161
162 pm_runtime_get_sync(&keypad->pdev->dev);
163
158 do { 164 do {
159 val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR); 165 val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR);
160 /* Clear interrupt. */ 166 /* Clear interrupt. */
@@ -169,6 +175,8 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id)
169 175
170 } while (key_down && !keypad->stopped); 176 } while (key_down && !keypad->stopped);
171 177
178 pm_runtime_put_sync(&keypad->pdev->dev);
179
172 return IRQ_HANDLED; 180 return IRQ_HANDLED;
173} 181}
174 182
@@ -176,6 +184,8 @@ static void samsung_keypad_start(struct samsung_keypad *keypad)
176{ 184{
177 unsigned int val; 185 unsigned int val;
178 186
187 pm_runtime_get_sync(&keypad->pdev->dev);
188
179 /* Tell IRQ thread that it may poll the device. */ 189 /* Tell IRQ thread that it may poll the device. */
180 keypad->stopped = false; 190 keypad->stopped = false;
181 191
@@ -188,12 +198,16 @@ static void samsung_keypad_start(struct samsung_keypad *keypad)
188 198
189 /* KEYIFCOL reg clear. */ 199 /* KEYIFCOL reg clear. */
190 writel(0, keypad->base + SAMSUNG_KEYIFCOL); 200 writel(0, keypad->base + SAMSUNG_KEYIFCOL);
201
202 pm_runtime_put_sync(&keypad->pdev->dev);
191} 203}
192 204
193static void samsung_keypad_stop(struct samsung_keypad *keypad) 205static void samsung_keypad_stop(struct samsung_keypad *keypad)
194{ 206{
195 unsigned int val; 207 unsigned int val;
196 208
209 pm_runtime_get_sync(&keypad->pdev->dev);
210
197 /* Signal IRQ thread to stop polling and disable the handler. */ 211 /* Signal IRQ thread to stop polling and disable the handler. */
198 keypad->stopped = true; 212 keypad->stopped = true;
199 wake_up(&keypad->wait); 213 wake_up(&keypad->wait);
@@ -214,6 +228,8 @@ static void samsung_keypad_stop(struct samsung_keypad *keypad)
214 * re-enable the handler. 228 * re-enable the handler.
215 */ 229 */
216 enable_irq(keypad->irq); 230 enable_irq(keypad->irq);
231
232 pm_runtime_put_sync(&keypad->pdev->dev);
217} 233}
218 234
219static int samsung_keypad_open(struct input_dev *input_dev) 235static int samsung_keypad_open(struct input_dev *input_dev)
@@ -418,9 +434,11 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
418 } 434 }
419 435
420 keypad->input_dev = input_dev; 436 keypad->input_dev = input_dev;
437 keypad->pdev = pdev;
421 keypad->row_shift = row_shift; 438 keypad->row_shift = row_shift;
422 keypad->rows = pdata->rows; 439 keypad->rows = pdata->rows;
423 keypad->cols = pdata->cols; 440 keypad->cols = pdata->cols;
441 keypad->stopped = true;
424 init_waitqueue_head(&keypad->wait); 442 init_waitqueue_head(&keypad->wait);
425 443
426 if (pdev->dev.of_node) { 444 if (pdev->dev.of_node) {
@@ -467,13 +485,14 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
467 goto err_put_clk; 485 goto err_put_clk;
468 } 486 }
469 487
488 device_init_wakeup(&pdev->dev, pdata->wakeup);
489 platform_set_drvdata(pdev, keypad);
490 pm_runtime_enable(&pdev->dev);
491
470 error = input_register_device(keypad->input_dev); 492 error = input_register_device(keypad->input_dev);
471 if (error) 493 if (error)
472 goto err_free_irq; 494 goto err_free_irq;
473 495
474 device_init_wakeup(&pdev->dev, pdata->wakeup);
475 platform_set_drvdata(pdev, keypad);
476
477 if (pdev->dev.of_node) { 496 if (pdev->dev.of_node) {
478 devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap); 497 devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap);
479 devm_kfree(&pdev->dev, (void *)pdata->keymap_data); 498 devm_kfree(&pdev->dev, (void *)pdata->keymap_data);
@@ -483,6 +502,9 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
483 502
484err_free_irq: 503err_free_irq:
485 free_irq(keypad->irq, keypad); 504 free_irq(keypad->irq, keypad);
505 pm_runtime_disable(&pdev->dev);
506 device_init_wakeup(&pdev->dev, 0);
507 platform_set_drvdata(pdev, NULL);
486err_put_clk: 508err_put_clk:
487 clk_put(keypad->clk); 509 clk_put(keypad->clk);
488 samsung_keypad_dt_gpio_free(keypad); 510 samsung_keypad_dt_gpio_free(keypad);
@@ -499,6 +521,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
499{ 521{
500 struct samsung_keypad *keypad = platform_get_drvdata(pdev); 522 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
501 523
524 pm_runtime_disable(&pdev->dev);
502 device_init_wakeup(&pdev->dev, 0); 525 device_init_wakeup(&pdev->dev, 0);
503 platform_set_drvdata(pdev, NULL); 526 platform_set_drvdata(pdev, NULL);
504 527
@@ -519,11 +542,57 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
519 return 0; 542 return 0;
520} 543}
521 544
522#ifdef CONFIG_PM 545#ifdef CONFIG_PM_RUNTIME
546static int samsung_keypad_runtime_suspend(struct device *dev)
547{
548 struct platform_device *pdev = to_platform_device(dev);
549 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
550 unsigned int val;
551 int error;
552
553 if (keypad->stopped)
554 return 0;
555
556 /* This may fail on some SoCs due to lack of controller support */
557 error = enable_irq_wake(keypad->irq);
558 if (!error)
559 keypad->wake_enabled = true;
560
561 val = readl(keypad->base + SAMSUNG_KEYIFCON);
562 val |= SAMSUNG_KEYIFCON_WAKEUPEN;
563 writel(val, keypad->base + SAMSUNG_KEYIFCON);
564
565 clk_disable(keypad->clk);
566
567 return 0;
568}
569
570static int samsung_keypad_runtime_resume(struct device *dev)
571{
572 struct platform_device *pdev = to_platform_device(dev);
573 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
574 unsigned int val;
575
576 if (keypad->stopped)
577 return 0;
578
579 clk_enable(keypad->clk);
580
581 val = readl(keypad->base + SAMSUNG_KEYIFCON);
582 val &= ~SAMSUNG_KEYIFCON_WAKEUPEN;
583 writel(val, keypad->base + SAMSUNG_KEYIFCON);
584
585 if (keypad->wake_enabled)
586 disable_irq_wake(keypad->irq);
587
588 return 0;
589}
590#endif
591
592#ifdef CONFIG_PM_SLEEP
523static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad, 593static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
524 bool enable) 594 bool enable)
525{ 595{
526 struct device *dev = keypad->input_dev->dev.parent;
527 unsigned int val; 596 unsigned int val;
528 597
529 clk_enable(keypad->clk); 598 clk_enable(keypad->clk);
@@ -531,11 +600,11 @@ static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
531 val = readl(keypad->base + SAMSUNG_KEYIFCON); 600 val = readl(keypad->base + SAMSUNG_KEYIFCON);
532 if (enable) { 601 if (enable) {
533 val |= SAMSUNG_KEYIFCON_WAKEUPEN; 602 val |= SAMSUNG_KEYIFCON_WAKEUPEN;
534 if (device_may_wakeup(dev)) 603 if (device_may_wakeup(&keypad->pdev->dev))
535 enable_irq_wake(keypad->irq); 604 enable_irq_wake(keypad->irq);
536 } else { 605 } else {
537 val &= ~SAMSUNG_KEYIFCON_WAKEUPEN; 606 val &= ~SAMSUNG_KEYIFCON_WAKEUPEN;
538 if (device_may_wakeup(dev)) 607 if (device_may_wakeup(&keypad->pdev->dev))
539 disable_irq_wake(keypad->irq); 608 disable_irq_wake(keypad->irq);
540 } 609 }
541 writel(val, keypad->base + SAMSUNG_KEYIFCON); 610 writel(val, keypad->base + SAMSUNG_KEYIFCON);
@@ -578,12 +647,13 @@ static int samsung_keypad_resume(struct device *dev)
578 647
579 return 0; 648 return 0;
580} 649}
650#endif
581 651
582static const struct dev_pm_ops samsung_keypad_pm_ops = { 652static const struct dev_pm_ops samsung_keypad_pm_ops = {
583 .suspend = samsung_keypad_suspend, 653 SET_SYSTEM_SLEEP_PM_OPS(samsung_keypad_suspend, samsung_keypad_resume)
584 .resume = samsung_keypad_resume, 654 SET_RUNTIME_PM_OPS(samsung_keypad_runtime_suspend,
655 samsung_keypad_runtime_resume, NULL)
585}; 656};
586#endif
587 657
588#ifdef CONFIG_OF 658#ifdef CONFIG_OF
589static const struct of_device_id samsung_keypad_dt_match[] = { 659static const struct of_device_id samsung_keypad_dt_match[] = {
@@ -615,27 +685,13 @@ static struct platform_driver samsung_keypad_driver = {
615 .name = "samsung-keypad", 685 .name = "samsung-keypad",
616 .owner = THIS_MODULE, 686 .owner = THIS_MODULE,
617 .of_match_table = samsung_keypad_dt_match, 687 .of_match_table = samsung_keypad_dt_match,
618#ifdef CONFIG_PM
619 .pm = &samsung_keypad_pm_ops, 688 .pm = &samsung_keypad_pm_ops,
620#endif
621 }, 689 },
622 .id_table = samsung_keypad_driver_ids, 690 .id_table = samsung_keypad_driver_ids,
623}; 691};
624 692module_platform_driver(samsung_keypad_driver);
625static int __init samsung_keypad_init(void)
626{
627 return platform_driver_register(&samsung_keypad_driver);
628}
629module_init(samsung_keypad_init);
630
631static void __exit samsung_keypad_exit(void)
632{
633 platform_driver_unregister(&samsung_keypad_driver);
634}
635module_exit(samsung_keypad_exit);
636 693
637MODULE_DESCRIPTION("Samsung keypad driver"); 694MODULE_DESCRIPTION("Samsung keypad driver");
638MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 695MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
639MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>"); 696MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
640MODULE_LICENSE("GPL"); 697MODULE_LICENSE("GPL");
641MODULE_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 66e55e5cfdd6..fb39c94b6fdd 100644
--- a/drivers/input/keyboard/tnetv107x-keypad.c
+++ b/drivers/input/keyboard/tnetv107x-keypad.c
@@ -322,19 +322,7 @@ static struct platform_driver keypad_driver = {
322 .driver.name = "tnetv107x-keypad", 322 .driver.name = "tnetv107x-keypad",
323 .driver.owner = THIS_MODULE, 323 .driver.owner = THIS_MODULE,
324}; 324};
325 325module_platform_driver(keypad_driver);
326static int __init keypad_init(void)
327{
328 return platform_driver_register(&keypad_driver);
329}
330
331static void __exit keypad_exit(void)
332{
333 platform_driver_unregister(&keypad_driver);
334}
335
336module_init(keypad_init);
337module_exit(keypad_exit);
338 326
339MODULE_AUTHOR("Cyril Chemparathy"); 327MODULE_AUTHOR("Cyril Chemparathy");
340MODULE_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");