diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-19 20:02:01 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-19 20:02:01 -0400 |
| commit | 10ce3cc919f50c2043b41ca968b43c26a3672600 (patch) | |
| tree | ea409366a5208aced495bc0516a08b81fd43222e /drivers/input/keyboard | |
| parent | 24e3e5ae1e4c2a3a32f5b1f96b4e3fd721806acd (diff) | |
| parent | 5c6a7a62c130afef3d61c1dee153012231ff5cd9 (diff) | |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input/keyboard')
| -rw-r--r-- | drivers/input/keyboard/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/input/keyboard/adp5588-keys.c | 12 | ||||
| -rw-r--r-- | drivers/input/keyboard/adp5589-keys.c | 12 | ||||
| -rw-r--r-- | drivers/input/keyboard/lm8323.c | 12 | ||||
| -rw-r--r-- | drivers/input/keyboard/max7359_keypad.c | 12 | ||||
| -rw-r--r-- | drivers/input/keyboard/mcs_touchkey.c | 13 | ||||
| -rw-r--r-- | drivers/input/keyboard/mpr121_touchkey.c | 12 | ||||
| -rw-r--r-- | drivers/input/keyboard/nomadik-ske-keypad.c | 17 | ||||
| -rw-r--r-- | drivers/input/keyboard/omap4-keypad.c | 2 | ||||
| -rw-r--r-- | drivers/input/keyboard/qt1070.c | 12 | ||||
| -rw-r--r-- | drivers/input/keyboard/qt2160.c | 12 | ||||
| -rw-r--r-- | drivers/input/keyboard/samsung-keypad.c | 179 | ||||
| -rw-r--r-- | drivers/input/keyboard/spear-keyboard.c | 16 | ||||
| -rw-r--r-- | drivers/input/keyboard/tegra-kbc.c | 72 |
14 files changed, 248 insertions, 137 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index cdc385b2cf7d..f354813a13e8 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -394,6 +394,7 @@ config KEYBOARD_NOMADIK | |||
| 394 | config KEYBOARD_TEGRA | 394 | config KEYBOARD_TEGRA |
| 395 | tristate "NVIDIA Tegra internal matrix keyboard controller support" | 395 | tristate "NVIDIA Tegra internal matrix keyboard controller support" |
| 396 | depends on ARCH_TEGRA | 396 | depends on ARCH_TEGRA |
| 397 | select INPUT_OF_MATRIX_KEYMAP if USE_OF | ||
| 397 | help | 398 | help |
| 398 | Say Y here if you want to use a matrix keyboard connected directly | 399 | Say Y here if you want to use a matrix keyboard connected directly |
| 399 | to the internal keyboard controller on Tegra SoCs. | 400 | to the internal keyboard controller on Tegra SoCs. |
| @@ -512,7 +513,6 @@ config KEYBOARD_OMAP | |||
| 512 | 513 | ||
| 513 | config KEYBOARD_OMAP4 | 514 | config KEYBOARD_OMAP4 |
| 514 | tristate "TI OMAP4 keypad support" | 515 | tristate "TI OMAP4 keypad support" |
| 515 | depends on ARCH_OMAP4 | ||
| 516 | help | 516 | help |
| 517 | Say Y here if you want to use the OMAP4 keypad. | 517 | Say Y here if you want to use the OMAP4 keypad. |
| 518 | 518 | ||
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 4a7f534cf64b..39ebffac207e 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
| @@ -653,17 +653,7 @@ static struct i2c_driver adp5588_driver = { | |||
| 653 | .id_table = adp5588_id, | 653 | .id_table = adp5588_id, |
| 654 | }; | 654 | }; |
| 655 | 655 | ||
| 656 | static int __init adp5588_init(void) | 656 | module_i2c_driver(adp5588_driver); |
| 657 | { | ||
| 658 | return i2c_add_driver(&adp5588_driver); | ||
| 659 | } | ||
| 660 | module_init(adp5588_init); | ||
| 661 | |||
| 662 | static void __exit adp5588_exit(void) | ||
| 663 | { | ||
| 664 | i2c_del_driver(&adp5588_driver); | ||
| 665 | } | ||
| 666 | module_exit(adp5588_exit); | ||
| 667 | 657 | ||
| 668 | MODULE_LICENSE("GPL"); | 658 | MODULE_LICENSE("GPL"); |
| 669 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 659 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 02b5d53031bf..74e603213386 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c | |||
| @@ -1108,17 +1108,7 @@ static struct i2c_driver adp5589_driver = { | |||
| 1108 | .id_table = adp5589_id, | 1108 | .id_table = adp5589_id, |
| 1109 | }; | 1109 | }; |
| 1110 | 1110 | ||
| 1111 | static int __init adp5589_init(void) | 1111 | module_i2c_driver(adp5589_driver); |
| 1112 | { | ||
| 1113 | return i2c_add_driver(&adp5589_driver); | ||
| 1114 | } | ||
| 1115 | module_init(adp5589_init); | ||
| 1116 | |||
| 1117 | static void __exit adp5589_exit(void) | ||
| 1118 | { | ||
| 1119 | i2c_del_driver(&adp5589_driver); | ||
| 1120 | } | ||
| 1121 | module_exit(adp5589_exit); | ||
| 1122 | 1112 | ||
| 1123 | MODULE_LICENSE("GPL"); | 1113 | MODULE_LICENSE("GPL"); |
| 1124 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 1114 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 21823bfc7911..39ac2787e275 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
| @@ -851,17 +851,7 @@ static struct i2c_driver lm8323_i2c_driver = { | |||
| 851 | }; | 851 | }; |
| 852 | MODULE_DEVICE_TABLE(i2c, lm8323_id); | 852 | MODULE_DEVICE_TABLE(i2c, lm8323_id); |
| 853 | 853 | ||
| 854 | static int __init lm8323_init(void) | 854 | module_i2c_driver(lm8323_i2c_driver); |
| 855 | { | ||
| 856 | return i2c_add_driver(&lm8323_i2c_driver); | ||
| 857 | } | ||
| 858 | module_init(lm8323_init); | ||
| 859 | |||
| 860 | static void __exit lm8323_exit(void) | ||
| 861 | { | ||
| 862 | i2c_del_driver(&lm8323_i2c_driver); | ||
| 863 | } | ||
| 864 | module_exit(lm8323_exit); | ||
| 865 | 855 | ||
| 866 | MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>"); | 856 | MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>"); |
| 867 | MODULE_AUTHOR("Daniel Stone"); | 857 | MODULE_AUTHOR("Daniel Stone"); |
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 5afe35ad24d3..8edada8ae712 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c | |||
| @@ -316,17 +316,7 @@ static struct i2c_driver max7359_i2c_driver = { | |||
| 316 | .id_table = max7359_ids, | 316 | .id_table = max7359_ids, |
| 317 | }; | 317 | }; |
| 318 | 318 | ||
| 319 | static int __init max7359_init(void) | 319 | module_i2c_driver(max7359_i2c_driver); |
| 320 | { | ||
| 321 | return i2c_add_driver(&max7359_i2c_driver); | ||
| 322 | } | ||
| 323 | module_init(max7359_init); | ||
| 324 | |||
| 325 | static void __exit max7359_exit(void) | ||
| 326 | { | ||
| 327 | i2c_del_driver(&max7359_i2c_driver); | ||
| 328 | } | ||
| 329 | module_exit(max7359_exit); | ||
| 330 | 320 | ||
| 331 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); | 321 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); |
| 332 | MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver"); | 322 | MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver"); |
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index af1aab324a4c..64a0ca4c92f3 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c | |||
| @@ -274,18 +274,7 @@ static struct i2c_driver mcs_touchkey_driver = { | |||
| 274 | .id_table = mcs_touchkey_id, | 274 | .id_table = mcs_touchkey_id, |
| 275 | }; | 275 | }; |
| 276 | 276 | ||
| 277 | static int __init mcs_touchkey_init(void) | 277 | module_i2c_driver(mcs_touchkey_driver); |
| 278 | { | ||
| 279 | return i2c_add_driver(&mcs_touchkey_driver); | ||
| 280 | } | ||
| 281 | |||
| 282 | static void __exit mcs_touchkey_exit(void) | ||
| 283 | { | ||
| 284 | i2c_del_driver(&mcs_touchkey_driver); | ||
| 285 | } | ||
| 286 | |||
| 287 | module_init(mcs_touchkey_init); | ||
| 288 | module_exit(mcs_touchkey_exit); | ||
| 289 | 278 | ||
| 290 | /* Module information */ | 279 | /* Module information */ |
| 291 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 280 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 1c1615d9a7f9..caa218a51b5a 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c | |||
| @@ -330,17 +330,7 @@ static struct i2c_driver mpr_touchkey_driver = { | |||
| 330 | .remove = __devexit_p(mpr_touchkey_remove), | 330 | .remove = __devexit_p(mpr_touchkey_remove), |
| 331 | }; | 331 | }; |
| 332 | 332 | ||
| 333 | static int __init mpr_touchkey_init(void) | 333 | module_i2c_driver(mpr_touchkey_driver); |
| 334 | { | ||
| 335 | return i2c_add_driver(&mpr_touchkey_driver); | ||
| 336 | } | ||
| 337 | module_init(mpr_touchkey_init); | ||
| 338 | |||
| 339 | static void __exit mpr_touchkey_exit(void) | ||
| 340 | { | ||
| 341 | i2c_del_driver(&mpr_touchkey_driver); | ||
| 342 | } | ||
| 343 | module_exit(mpr_touchkey_exit); | ||
| 344 | 334 | ||
| 345 | MODULE_LICENSE("GPL"); | 335 | MODULE_LICENSE("GPL"); |
| 346 | MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); | 336 | MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); |
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index e35566aa102f..101e245944e7 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
| @@ -88,7 +88,7 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, | |||
| 88 | * | 88 | * |
| 89 | * Enable Multi key press detection, auto scan mode | 89 | * Enable Multi key press detection, auto scan mode |
| 90 | */ | 90 | */ |
| 91 | static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) | 91 | static int __init ske_keypad_chip_init(struct ske_keypad *keypad) |
| 92 | { | 92 | { |
| 93 | u32 value; | 93 | u32 value; |
| 94 | int timeout = 50; | 94 | int timeout = 50; |
| @@ -198,7 +198,7 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id) | |||
| 198 | return IRQ_HANDLED; | 198 | return IRQ_HANDLED; |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | static int __devinit ske_keypad_probe(struct platform_device *pdev) | 201 | static int __init ske_keypad_probe(struct platform_device *pdev) |
| 202 | { | 202 | { |
| 203 | const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; | 203 | const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; |
| 204 | struct ske_keypad *keypad; | 204 | struct ske_keypad *keypad; |
| @@ -344,7 +344,7 @@ static int __devexit ske_keypad_remove(struct platform_device *pdev) | |||
| 344 | return 0; | 344 | return 0; |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | #ifdef CONFIG_PM | 347 | #ifdef CONFIG_PM_SLEEP |
| 348 | static int ske_keypad_suspend(struct device *dev) | 348 | static int ske_keypad_suspend(struct device *dev) |
| 349 | { | 349 | { |
| 350 | struct platform_device *pdev = to_platform_device(dev); | 350 | struct platform_device *pdev = to_platform_device(dev); |
| @@ -372,22 +372,17 @@ static int ske_keypad_resume(struct device *dev) | |||
| 372 | 372 | ||
| 373 | return 0; | 373 | return 0; |
| 374 | } | 374 | } |
| 375 | |||
| 376 | static const struct dev_pm_ops ske_keypad_dev_pm_ops = { | ||
| 377 | .suspend = ske_keypad_suspend, | ||
| 378 | .resume = ske_keypad_resume, | ||
| 379 | }; | ||
| 380 | #endif | 375 | #endif |
| 381 | 376 | ||
| 377 | static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops, | ||
| 378 | ske_keypad_suspend, ske_keypad_resume); | ||
| 379 | |||
| 382 | static struct platform_driver ske_keypad_driver = { | 380 | static struct platform_driver ske_keypad_driver = { |
| 383 | .driver = { | 381 | .driver = { |
| 384 | .name = "nmk-ske-keypad", | 382 | .name = "nmk-ske-keypad", |
| 385 | .owner = THIS_MODULE, | 383 | .owner = THIS_MODULE, |
| 386 | #ifdef CONFIG_PM | ||
| 387 | .pm = &ske_keypad_dev_pm_ops, | 384 | .pm = &ske_keypad_dev_pm_ops, |
| 388 | #endif | ||
| 389 | }, | 385 | }, |
| 390 | .probe = ske_keypad_probe, | ||
| 391 | .remove = __devexit_p(ske_keypad_remove), | 386 | .remove = __devexit_p(ske_keypad_remove), |
| 392 | }; | 387 | }; |
| 393 | 388 | ||
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index d5c5d77f4b82..e809ac095a38 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
| 33 | 33 | ||
| 34 | #include <plat/omap4-keypad.h> | 34 | #include <linux/platform_data/omap4-keypad.h> |
| 35 | 35 | ||
| 36 | /* OMAP4 registers */ | 36 | /* OMAP4 registers */ |
| 37 | #define OMAP4_KBD_REVISION 0x00 | 37 | #define OMAP4_KBD_REVISION 0x00 |
diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index b21bf5b876bb..0b7b2f891752 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c | |||
| @@ -258,17 +258,7 @@ static struct i2c_driver qt1070_driver = { | |||
| 258 | .remove = __devexit_p(qt1070_remove), | 258 | .remove = __devexit_p(qt1070_remove), |
| 259 | }; | 259 | }; |
| 260 | 260 | ||
| 261 | static int __init qt1070_init(void) | 261 | module_i2c_driver(qt1070_driver); |
| 262 | { | ||
| 263 | return i2c_add_driver(&qt1070_driver); | ||
| 264 | } | ||
| 265 | module_init(qt1070_init); | ||
| 266 | |||
| 267 | static void __exit qt1070_exit(void) | ||
| 268 | { | ||
| 269 | i2c_del_driver(&qt1070_driver); | ||
| 270 | } | ||
| 271 | module_exit(qt1070_exit); | ||
| 272 | 262 | ||
| 273 | MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); | 263 | MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); |
| 274 | MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor"); | 264 | MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor"); |
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index fac695157e8a..e7a5e36e1203 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
| @@ -379,17 +379,7 @@ static struct i2c_driver qt2160_driver = { | |||
| 379 | .remove = __devexit_p(qt2160_remove), | 379 | .remove = __devexit_p(qt2160_remove), |
| 380 | }; | 380 | }; |
| 381 | 381 | ||
| 382 | static int __init qt2160_init(void) | 382 | module_i2c_driver(qt2160_driver); |
| 383 | { | ||
| 384 | return i2c_add_driver(&qt2160_driver); | ||
| 385 | } | ||
| 386 | module_init(qt2160_init); | ||
| 387 | |||
| 388 | static void __exit qt2160_cleanup(void) | ||
| 389 | { | ||
| 390 | i2c_del_driver(&qt2160_driver); | ||
| 391 | } | ||
| 392 | module_exit(qt2160_cleanup); | ||
| 393 | 383 | ||
| 394 | MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>"); | 384 | MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>"); |
| 395 | MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor"); | 385 | MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor"); |
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index b746fce2d120..2391ae884fee 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
| 24 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/of.h> | ||
| 27 | #include <linux/of_gpio.h> | ||
| 26 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
| 27 | #include <linux/input/samsung-keypad.h> | 29 | #include <linux/input/samsung-keypad.h> |
| 28 | 30 | ||
| @@ -72,31 +74,26 @@ struct samsung_keypad { | |||
| 72 | bool stopped; | 74 | bool stopped; |
| 73 | bool wake_enabled; | 75 | bool wake_enabled; |
| 74 | int irq; | 76 | int irq; |
| 77 | enum samsung_keypad_type type; | ||
| 75 | unsigned int row_shift; | 78 | unsigned int row_shift; |
| 76 | unsigned int rows; | 79 | unsigned int rows; |
| 77 | unsigned int cols; | 80 | unsigned int cols; |
| 78 | unsigned int row_state[SAMSUNG_MAX_COLS]; | 81 | unsigned int row_state[SAMSUNG_MAX_COLS]; |
| 82 | #ifdef CONFIG_OF | ||
| 83 | int row_gpios[SAMSUNG_MAX_ROWS]; | ||
| 84 | int col_gpios[SAMSUNG_MAX_COLS]; | ||
| 85 | #endif | ||
| 79 | unsigned short keycodes[]; | 86 | unsigned short keycodes[]; |
| 80 | }; | 87 | }; |
| 81 | 88 | ||
| 82 | static int samsung_keypad_is_s5pv210(struct device *dev) | ||
| 83 | { | ||
| 84 | struct platform_device *pdev = to_platform_device(dev); | ||
| 85 | enum samsung_keypad_type type = | ||
| 86 | platform_get_device_id(pdev)->driver_data; | ||
| 87 | |||
| 88 | return type == KEYPAD_TYPE_S5PV210; | ||
| 89 | } | ||
| 90 | |||
| 91 | static void samsung_keypad_scan(struct samsung_keypad *keypad, | 89 | static void samsung_keypad_scan(struct samsung_keypad *keypad, |
| 92 | unsigned int *row_state) | 90 | unsigned int *row_state) |
| 93 | { | 91 | { |
| 94 | struct device *dev = keypad->input_dev->dev.parent; | ||
| 95 | unsigned int col; | 92 | unsigned int col; |
| 96 | unsigned int val; | 93 | unsigned int val; |
| 97 | 94 | ||
| 98 | for (col = 0; col < keypad->cols; col++) { | 95 | for (col = 0; col < keypad->cols; col++) { |
| 99 | if (samsung_keypad_is_s5pv210(dev)) { | 96 | if (keypad->type == KEYPAD_TYPE_S5PV210) { |
| 100 | val = S5PV210_KEYIFCOLEN_MASK; | 97 | val = S5PV210_KEYIFCOLEN_MASK; |
| 101 | val &= ~(1 << col) << 8; | 98 | val &= ~(1 << col) << 8; |
| 102 | } else { | 99 | } else { |
| @@ -178,7 +175,7 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id) | |||
| 178 | 175 | ||
| 179 | } while (key_down && !keypad->stopped); | 176 | } while (key_down && !keypad->stopped); |
| 180 | 177 | ||
| 181 | pm_runtime_put_sync(&keypad->pdev->dev); | 178 | pm_runtime_put(&keypad->pdev->dev); |
| 182 | 179 | ||
| 183 | return IRQ_HANDLED; | 180 | return IRQ_HANDLED; |
| 184 | } | 181 | } |
| @@ -202,7 +199,7 @@ static void samsung_keypad_start(struct samsung_keypad *keypad) | |||
| 202 | /* KEYIFCOL reg clear. */ | 199 | /* KEYIFCOL reg clear. */ |
| 203 | writel(0, keypad->base + SAMSUNG_KEYIFCOL); | 200 | writel(0, keypad->base + SAMSUNG_KEYIFCOL); |
| 204 | 201 | ||
| 205 | pm_runtime_put_sync(&keypad->pdev->dev); | 202 | pm_runtime_put(&keypad->pdev->dev); |
| 206 | } | 203 | } |
| 207 | 204 | ||
| 208 | static void samsung_keypad_stop(struct samsung_keypad *keypad) | 205 | static void samsung_keypad_stop(struct samsung_keypad *keypad) |
| @@ -232,7 +229,7 @@ static void samsung_keypad_stop(struct samsung_keypad *keypad) | |||
| 232 | */ | 229 | */ |
| 233 | enable_irq(keypad->irq); | 230 | enable_irq(keypad->irq); |
| 234 | 231 | ||
| 235 | pm_runtime_put_sync(&keypad->pdev->dev); | 232 | pm_runtime_put(&keypad->pdev->dev); |
| 236 | } | 233 | } |
| 237 | 234 | ||
| 238 | static int samsung_keypad_open(struct input_dev *input_dev) | 235 | static int samsung_keypad_open(struct input_dev *input_dev) |
| @@ -251,6 +248,126 @@ static void samsung_keypad_close(struct input_dev *input_dev) | |||
| 251 | samsung_keypad_stop(keypad); | 248 | samsung_keypad_stop(keypad); |
| 252 | } | 249 | } |
| 253 | 250 | ||
| 251 | #ifdef CONFIG_OF | ||
| 252 | static struct samsung_keypad_platdata *samsung_keypad_parse_dt( | ||
| 253 | struct device *dev) | ||
| 254 | { | ||
| 255 | struct samsung_keypad_platdata *pdata; | ||
| 256 | struct matrix_keymap_data *keymap_data; | ||
| 257 | uint32_t *keymap, num_rows = 0, num_cols = 0; | ||
| 258 | struct device_node *np = dev->of_node, *key_np; | ||
| 259 | unsigned int key_count = 0; | ||
| 260 | |||
| 261 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
| 262 | if (!pdata) { | ||
| 263 | dev_err(dev, "could not allocate memory for platform data\n"); | ||
| 264 | return NULL; | ||
| 265 | } | ||
| 266 | |||
| 267 | of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows); | ||
| 268 | of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols); | ||
| 269 | if (!num_rows || !num_cols) { | ||
| 270 | dev_err(dev, "number of keypad rows/columns not specified\n"); | ||
| 271 | return NULL; | ||
| 272 | } | ||
| 273 | pdata->rows = num_rows; | ||
| 274 | pdata->cols = num_cols; | ||
| 275 | |||
| 276 | keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL); | ||
| 277 | if (!keymap_data) { | ||
| 278 | dev_err(dev, "could not allocate memory for keymap data\n"); | ||
| 279 | return NULL; | ||
| 280 | } | ||
| 281 | pdata->keymap_data = keymap_data; | ||
| 282 | |||
| 283 | for_each_child_of_node(np, key_np) | ||
| 284 | key_count++; | ||
| 285 | |||
| 286 | keymap_data->keymap_size = key_count; | ||
| 287 | keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); | ||
| 288 | if (!keymap) { | ||
| 289 | dev_err(dev, "could not allocate memory for keymap\n"); | ||
| 290 | return NULL; | ||
| 291 | } | ||
| 292 | keymap_data->keymap = keymap; | ||
| 293 | |||
| 294 | for_each_child_of_node(np, key_np) { | ||
| 295 | u32 row, col, key_code; | ||
| 296 | of_property_read_u32(key_np, "keypad,row", &row); | ||
| 297 | of_property_read_u32(key_np, "keypad,column", &col); | ||
| 298 | of_property_read_u32(key_np, "linux,code", &key_code); | ||
| 299 | *keymap++ = KEY(row, col, key_code); | ||
| 300 | } | ||
| 301 | |||
| 302 | if (of_get_property(np, "linux,input-no-autorepeat", NULL)) | ||
| 303 | pdata->no_autorepeat = true; | ||
| 304 | if (of_get_property(np, "linux,input-wakeup", NULL)) | ||
| 305 | pdata->wakeup = true; | ||
| 306 | |||
| 307 | return pdata; | ||
| 308 | } | ||
| 309 | |||
| 310 | static void samsung_keypad_parse_dt_gpio(struct device *dev, | ||
| 311 | struct samsung_keypad *keypad) | ||
| 312 | { | ||
| 313 | struct device_node *np = dev->of_node; | ||
| 314 | int gpio, ret, row, col; | ||
| 315 | |||
| 316 | for (row = 0; row < keypad->rows; row++) { | ||
| 317 | gpio = of_get_named_gpio(np, "row-gpios", row); | ||
| 318 | keypad->row_gpios[row] = gpio; | ||
| 319 | if (!gpio_is_valid(gpio)) { | ||
| 320 | dev_err(dev, "keypad row[%d]: invalid gpio %d\n", | ||
| 321 | row, gpio); | ||
| 322 | continue; | ||
| 323 | } | ||
| 324 | |||
| 325 | ret = gpio_request(gpio, "keypad-row"); | ||
| 326 | if (ret) | ||
| 327 | dev_err(dev, "keypad row[%d] gpio request failed\n", | ||
| 328 | row); | ||
| 329 | } | ||
| 330 | |||
| 331 | for (col = 0; col < keypad->cols; col++) { | ||
| 332 | gpio = of_get_named_gpio(np, "col-gpios", col); | ||
| 333 | keypad->col_gpios[col] = gpio; | ||
| 334 | if (!gpio_is_valid(gpio)) { | ||
| 335 | dev_err(dev, "keypad column[%d]: invalid gpio %d\n", | ||
| 336 | col, gpio); | ||
| 337 | continue; | ||
| 338 | } | ||
| 339 | |||
| 340 | ret = gpio_request(gpio, "keypad-col"); | ||
| 341 | if (ret) | ||
| 342 | dev_err(dev, "keypad column[%d] gpio request failed\n", | ||
| 343 | col); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad) | ||
| 348 | { | ||
| 349 | int cnt; | ||
| 350 | |||
| 351 | for (cnt = 0; cnt < keypad->rows; cnt++) | ||
| 352 | if (gpio_is_valid(keypad->row_gpios[cnt])) | ||
| 353 | gpio_free(keypad->row_gpios[cnt]); | ||
| 354 | |||
| 355 | for (cnt = 0; cnt < keypad->cols; cnt++) | ||
| 356 | if (gpio_is_valid(keypad->col_gpios[cnt])) | ||
| 357 | gpio_free(keypad->col_gpios[cnt]); | ||
| 358 | } | ||
| 359 | #else | ||
| 360 | static | ||
| 361 | struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev) | ||
| 362 | { | ||
| 363 | return NULL; | ||
| 364 | } | ||
| 365 | |||
| 366 | static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad) | ||
| 367 | { | ||
| 368 | } | ||
| 369 | #endif | ||
| 370 | |||
| 254 | static int __devinit samsung_keypad_probe(struct platform_device *pdev) | 371 | static int __devinit samsung_keypad_probe(struct platform_device *pdev) |
| 255 | { | 372 | { |
| 256 | const struct samsung_keypad_platdata *pdata; | 373 | const struct samsung_keypad_platdata *pdata; |
| @@ -262,7 +379,10 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) | |||
| 262 | unsigned int keymap_size; | 379 | unsigned int keymap_size; |
| 263 | int error; | 380 | int error; |
| 264 | 381 | ||
| 265 | pdata = pdev->dev.platform_data; | 382 | if (pdev->dev.of_node) |
| 383 | pdata = samsung_keypad_parse_dt(&pdev->dev); | ||
| 384 | else | ||
| 385 | pdata = pdev->dev.platform_data; | ||
| 266 | if (!pdata) { | 386 | if (!pdata) { |
| 267 | dev_err(&pdev->dev, "no platform data defined\n"); | 387 | dev_err(&pdev->dev, "no platform data defined\n"); |
| 268 | return -EINVAL; | 388 | return -EINVAL; |
| @@ -321,6 +441,16 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) | |||
| 321 | keypad->stopped = true; | 441 | keypad->stopped = true; |
| 322 | init_waitqueue_head(&keypad->wait); | 442 | init_waitqueue_head(&keypad->wait); |
| 323 | 443 | ||
| 444 | if (pdev->dev.of_node) { | ||
| 445 | #ifdef CONFIG_OF | ||
| 446 | samsung_keypad_parse_dt_gpio(&pdev->dev, keypad); | ||
| 447 | keypad->type = of_device_is_compatible(pdev->dev.of_node, | ||
| 448 | "samsung,s5pv210-keypad"); | ||
| 449 | #endif | ||
| 450 | } else { | ||
| 451 | keypad->type = platform_get_device_id(pdev)->driver_data; | ||
| 452 | } | ||
| 453 | |||
| 324 | input_dev->name = pdev->name; | 454 | input_dev->name = pdev->name; |
| 325 | input_dev->id.bustype = BUS_HOST; | 455 | input_dev->id.bustype = BUS_HOST; |
| 326 | input_dev->dev.parent = &pdev->dev; | 456 | input_dev->dev.parent = &pdev->dev; |
| @@ -363,6 +493,11 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) | |||
| 363 | if (error) | 493 | if (error) |
| 364 | goto err_free_irq; | 494 | goto err_free_irq; |
| 365 | 495 | ||
| 496 | if (pdev->dev.of_node) { | ||
| 497 | devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap); | ||
| 498 | devm_kfree(&pdev->dev, (void *)pdata->keymap_data); | ||
| 499 | devm_kfree(&pdev->dev, (void *)pdata); | ||
| 500 | } | ||
| 366 | return 0; | 501 | return 0; |
| 367 | 502 | ||
| 368 | err_free_irq: | 503 | err_free_irq: |
| @@ -372,6 +507,7 @@ err_free_irq: | |||
| 372 | platform_set_drvdata(pdev, NULL); | 507 | platform_set_drvdata(pdev, NULL); |
| 373 | err_put_clk: | 508 | err_put_clk: |
| 374 | clk_put(keypad->clk); | 509 | clk_put(keypad->clk); |
| 510 | samsung_keypad_dt_gpio_free(keypad); | ||
| 375 | err_unmap_base: | 511 | err_unmap_base: |
| 376 | iounmap(keypad->base); | 512 | iounmap(keypad->base); |
| 377 | err_free_mem: | 513 | err_free_mem: |
| @@ -398,6 +534,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev) | |||
| 398 | free_irq(keypad->irq, keypad); | 534 | free_irq(keypad->irq, keypad); |
| 399 | 535 | ||
| 400 | clk_put(keypad->clk); | 536 | clk_put(keypad->clk); |
| 537 | samsung_keypad_dt_gpio_free(keypad); | ||
| 401 | 538 | ||
| 402 | iounmap(keypad->base); | 539 | iounmap(keypad->base); |
| 403 | kfree(keypad); | 540 | kfree(keypad); |
| @@ -518,6 +655,17 @@ static const struct dev_pm_ops samsung_keypad_pm_ops = { | |||
| 518 | samsung_keypad_runtime_resume, NULL) | 655 | samsung_keypad_runtime_resume, NULL) |
| 519 | }; | 656 | }; |
| 520 | 657 | ||
| 658 | #ifdef CONFIG_OF | ||
| 659 | static const struct of_device_id samsung_keypad_dt_match[] = { | ||
| 660 | { .compatible = "samsung,s3c6410-keypad" }, | ||
| 661 | { .compatible = "samsung,s5pv210-keypad" }, | ||
| 662 | {}, | ||
| 663 | }; | ||
| 664 | MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match); | ||
| 665 | #else | ||
| 666 | #define samsung_keypad_dt_match NULL | ||
| 667 | #endif | ||
| 668 | |||
| 521 | static struct platform_device_id samsung_keypad_driver_ids[] = { | 669 | static struct platform_device_id samsung_keypad_driver_ids[] = { |
| 522 | { | 670 | { |
| 523 | .name = "samsung-keypad", | 671 | .name = "samsung-keypad", |
| @@ -536,6 +684,7 @@ static struct platform_driver samsung_keypad_driver = { | |||
| 536 | .driver = { | 684 | .driver = { |
| 537 | .name = "samsung-keypad", | 685 | .name = "samsung-keypad", |
| 538 | .owner = THIS_MODULE, | 686 | .owner = THIS_MODULE, |
| 687 | .of_match_table = samsung_keypad_dt_match, | ||
| 539 | .pm = &samsung_keypad_pm_ops, | 688 | .pm = &samsung_keypad_pm_ops, |
| 540 | }, | 689 | }, |
| 541 | .id_table = samsung_keypad_driver_ids, | 690 | .id_table = samsung_keypad_driver_ids, |
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index c88bd63dc9cc..3b6b528f02fd 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #define ROW_MASK 0xF0 | 50 | #define ROW_MASK 0xF0 |
| 51 | #define COLUMN_MASK 0x0F | 51 | #define COLUMN_MASK 0x0F |
| 52 | #define ROW_SHIFT 4 | 52 | #define ROW_SHIFT 4 |
| 53 | #define KEY_MATRIX_SHIFT 6 | ||
| 53 | 54 | ||
| 54 | struct spear_kbd { | 55 | struct spear_kbd { |
| 55 | struct input_dev *input; | 56 | struct input_dev *input; |
| @@ -57,6 +58,7 @@ struct spear_kbd { | |||
| 57 | void __iomem *io_base; | 58 | void __iomem *io_base; |
| 58 | struct clk *clk; | 59 | struct clk *clk; |
| 59 | unsigned int irq; | 60 | unsigned int irq; |
| 61 | unsigned int mode; | ||
| 60 | unsigned short last_key; | 62 | unsigned short last_key; |
| 61 | unsigned short keycodes[256]; | 63 | unsigned short keycodes[256]; |
| 62 | }; | 64 | }; |
| @@ -106,7 +108,8 @@ static int spear_kbd_open(struct input_dev *dev) | |||
| 106 | return error; | 108 | return error; |
| 107 | 109 | ||
| 108 | /* program keyboard */ | 110 | /* program keyboard */ |
| 109 | val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK; | 111 | val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK | |
| 112 | (kbd->mode << KEY_MATRIX_SHIFT); | ||
| 110 | writew(val, kbd->io_base + MODE_REG); | 113 | writew(val, kbd->io_base + MODE_REG); |
| 111 | writeb(1, kbd->io_base + STATUS_REG); | 114 | writeb(1, kbd->io_base + STATUS_REG); |
| 112 | 115 | ||
| @@ -176,6 +179,8 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev) | |||
| 176 | 179 | ||
| 177 | kbd->input = input_dev; | 180 | kbd->input = input_dev; |
| 178 | kbd->irq = irq; | 181 | kbd->irq = irq; |
| 182 | kbd->mode = pdata->mode; | ||
| 183 | |||
| 179 | kbd->res = request_mem_region(res->start, resource_size(res), | 184 | kbd->res = request_mem_region(res->start, resource_size(res), |
| 180 | pdev->name); | 185 | pdev->name); |
| 181 | if (!kbd->res) { | 186 | if (!kbd->res) { |
| @@ -308,22 +313,17 @@ static int spear_kbd_resume(struct device *dev) | |||
| 308 | 313 | ||
| 309 | return 0; | 314 | return 0; |
| 310 | } | 315 | } |
| 311 | |||
| 312 | static const struct dev_pm_ops spear_kbd_pm_ops = { | ||
| 313 | .suspend = spear_kbd_suspend, | ||
| 314 | .resume = spear_kbd_resume, | ||
| 315 | }; | ||
| 316 | #endif | 316 | #endif |
| 317 | 317 | ||
| 318 | static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume); | ||
| 319 | |||
| 318 | static struct platform_driver spear_kbd_driver = { | 320 | static struct platform_driver spear_kbd_driver = { |
| 319 | .probe = spear_kbd_probe, | 321 | .probe = spear_kbd_probe, |
| 320 | .remove = __devexit_p(spear_kbd_remove), | 322 | .remove = __devexit_p(spear_kbd_remove), |
| 321 | .driver = { | 323 | .driver = { |
| 322 | .name = "keyboard", | 324 | .name = "keyboard", |
| 323 | .owner = THIS_MODULE, | 325 | .owner = THIS_MODULE, |
| 324 | #ifdef CONFIG_PM | ||
| 325 | .pm = &spear_kbd_pm_ops, | 326 | .pm = &spear_kbd_pm_ops, |
| 326 | #endif | ||
| 327 | }, | 327 | }, |
| 328 | }; | 328 | }; |
| 329 | module_platform_driver(spear_kbd_driver); | 329 | module_platform_driver(spear_kbd_driver); |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index a136e2e832be..21c42f852343 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | #define KBC_FIFO_TH_CNT_SHIFT(cnt) (cnt << 14) | 48 | #define KBC_FIFO_TH_CNT_SHIFT(cnt) (cnt << 14) |
| 49 | #define KBC_DEBOUNCE_CNT_SHIFT(cnt) (cnt << 4) | 49 | #define KBC_DEBOUNCE_CNT_SHIFT(cnt) (cnt << 4) |
| 50 | #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) | 50 | #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) |
| 51 | #define KBC_CONTROL_KEYPRESS_INT_EN (1 << 1) | ||
| 51 | #define KBC_CONTROL_KBC_EN (1 << 0) | 52 | #define KBC_CONTROL_KBC_EN (1 << 0) |
| 52 | 53 | ||
| 53 | /* KBC Interrupt Register */ | 54 | /* KBC Interrupt Register */ |
| @@ -356,6 +357,18 @@ static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable) | |||
| 356 | writel(val, kbc->mmio + KBC_CONTROL_0); | 357 | writel(val, kbc->mmio + KBC_CONTROL_0); |
| 357 | } | 358 | } |
| 358 | 359 | ||
| 360 | static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable) | ||
| 361 | { | ||
| 362 | u32 val; | ||
| 363 | |||
| 364 | val = readl(kbc->mmio + KBC_CONTROL_0); | ||
| 365 | if (enable) | ||
| 366 | val |= KBC_CONTROL_KEYPRESS_INT_EN; | ||
| 367 | else | ||
| 368 | val &= ~KBC_CONTROL_KEYPRESS_INT_EN; | ||
| 369 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
| 370 | } | ||
| 371 | |||
| 359 | static void tegra_kbc_keypress_timer(unsigned long data) | 372 | static void tegra_kbc_keypress_timer(unsigned long data) |
| 360 | { | 373 | { |
| 361 | struct tegra_kbc *kbc = (struct tegra_kbc *)data; | 374 | struct tegra_kbc *kbc = (struct tegra_kbc *)data; |
| @@ -455,10 +468,18 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | |||
| 455 | row_cfg &= ~r_mask; | 468 | row_cfg &= ~r_mask; |
| 456 | col_cfg &= ~c_mask; | 469 | col_cfg &= ~c_mask; |
| 457 | 470 | ||
| 458 | if (pdata->pin_cfg[i].is_row) | 471 | switch (pdata->pin_cfg[i].type) { |
| 472 | case PIN_CFG_ROW: | ||
| 459 | row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft; | 473 | row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft; |
| 460 | else | 474 | break; |
| 475 | |||
| 476 | case PIN_CFG_COL: | ||
| 461 | col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft; | 477 | col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft; |
| 478 | break; | ||
| 479 | |||
| 480 | case PIN_CFG_IGNORE: | ||
| 481 | break; | ||
| 482 | } | ||
| 462 | 483 | ||
| 463 | writel(row_cfg, kbc->mmio + r_offs); | 484 | writel(row_cfg, kbc->mmio + r_offs); |
| 464 | writel(col_cfg, kbc->mmio + c_offs); | 485 | writel(col_cfg, kbc->mmio + c_offs); |
| @@ -563,7 +584,8 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
| 563 | for (i = 0; i < KBC_MAX_GPIO; i++) { | 584 | for (i = 0; i < KBC_MAX_GPIO; i++) { |
| 564 | const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; | 585 | const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; |
| 565 | 586 | ||
| 566 | if (pin_cfg->is_row) { | 587 | switch (pin_cfg->type) { |
| 588 | case PIN_CFG_ROW: | ||
| 567 | if (pin_cfg->num >= KBC_MAX_ROW) { | 589 | if (pin_cfg->num >= KBC_MAX_ROW) { |
| 568 | dev_err(dev, | 590 | dev_err(dev, |
| 569 | "pin_cfg[%d]: invalid row number %d\n", | 591 | "pin_cfg[%d]: invalid row number %d\n", |
| @@ -571,13 +593,25 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
| 571 | return false; | 593 | return false; |
| 572 | } | 594 | } |
| 573 | (*num_rows)++; | 595 | (*num_rows)++; |
| 574 | } else { | 596 | break; |
| 597 | |||
| 598 | case PIN_CFG_COL: | ||
| 575 | if (pin_cfg->num >= KBC_MAX_COL) { | 599 | if (pin_cfg->num >= KBC_MAX_COL) { |
| 576 | dev_err(dev, | 600 | dev_err(dev, |
| 577 | "pin_cfg[%d]: invalid column number %d\n", | 601 | "pin_cfg[%d]: invalid column number %d\n", |
| 578 | i, pin_cfg->num); | 602 | i, pin_cfg->num); |
| 579 | return false; | 603 | return false; |
| 580 | } | 604 | } |
| 605 | break; | ||
| 606 | |||
| 607 | case PIN_CFG_IGNORE: | ||
| 608 | break; | ||
| 609 | |||
| 610 | default: | ||
| 611 | dev_err(dev, | ||
| 612 | "pin_cfg[%d]: invalid entry type %d\n", | ||
| 613 | pin_cfg->type, pin_cfg->num); | ||
| 614 | return false; | ||
| 581 | } | 615 | } |
| 582 | } | 616 | } |
| 583 | 617 | ||
| @@ -590,24 +624,25 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev) | |||
| 590 | { | 624 | { |
| 591 | struct tegra_kbc_platform_data *pdata; | 625 | struct tegra_kbc_platform_data *pdata; |
| 592 | struct device_node *np = pdev->dev.of_node; | 626 | struct device_node *np = pdev->dev.of_node; |
| 627 | u32 prop; | ||
| 628 | int i; | ||
| 593 | 629 | ||
| 594 | if (!np) | 630 | if (!np) |
| 595 | return NULL; | 631 | return NULL; |
| 596 | 632 | ||
| 597 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
| 598 | if (!pdata) | 633 | if (!pdata) |
| 599 | return NULL; | 634 | return NULL; |
| 600 | 635 | ||
| 601 | if (!of_property_read_u32(np, "debounce-delay", &prop)) | 636 | if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop)) |
| 602 | pdata->debounce_cnt = prop; | 637 | pdata->debounce_cnt = prop; |
| 603 | 638 | ||
| 604 | if (!of_property_read_u32(np, "repeat-delay", &prop)) | 639 | if (!of_property_read_u32(np, "nvidia,repeat-delay-ms", &prop)) |
| 605 | pdata->repeat_cnt = prop; | 640 | pdata->repeat_cnt = prop; |
| 606 | 641 | ||
| 607 | if (of_find_property(np, "needs-ghost-filter", NULL)) | 642 | if (of_find_property(np, "nvidia,needs-ghost-filter", NULL)) |
| 608 | pdata->use_ghost_filter = true; | 643 | pdata->use_ghost_filter = true; |
| 609 | 644 | ||
| 610 | if (of_find_property(np, "wakeup-source", NULL)) | 645 | if (of_find_property(np, "nvidia,wakeup-source", NULL)) |
| 611 | pdata->wakeup = true; | 646 | pdata->wakeup = true; |
| 612 | 647 | ||
| 613 | /* | 648 | /* |
| @@ -616,14 +651,18 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev) | |||
| 616 | */ | 651 | */ |
| 617 | for (i = 0; i < KBC_MAX_ROW; i++) { | 652 | for (i = 0; i < KBC_MAX_ROW; i++) { |
| 618 | pdata->pin_cfg[i].num = i; | 653 | pdata->pin_cfg[i].num = i; |
| 619 | pdata->pin_cfg[i].is_row = true; | 654 | pdata->pin_cfg[i].type = PIN_CFG_ROW; |
| 620 | } | 655 | } |
| 621 | 656 | ||
| 622 | for (i = 0; i < KBC_MAX_COL; i++) { | 657 | for (i = 0; i < KBC_MAX_COL; i++) { |
| 623 | pdata->pin_cfg[KBC_MAX_ROW + i].num = i; | 658 | pdata->pin_cfg[KBC_MAX_ROW + i].num = i; |
| 624 | pdata->pin_cfg[KBC_MAX_ROW + i].is_row = false; | 659 | pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; |
| 625 | } | 660 | } |
| 626 | 661 | ||
| 662 | pdata->keymap_data = matrix_keyboard_of_fill_keymap(np, "linux,keymap"); | ||
| 663 | |||
| 664 | /* FIXME: Add handling of linux,fn-keymap here */ | ||
| 665 | |||
| 627 | return pdata; | 666 | return pdata; |
| 628 | } | 667 | } |
| 629 | #else | 668 | #else |
| @@ -759,6 +798,9 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) | |||
| 759 | platform_set_drvdata(pdev, kbc); | 798 | platform_set_drvdata(pdev, kbc); |
| 760 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 799 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
| 761 | 800 | ||
| 801 | if (!pdev->dev.platform_data) | ||
| 802 | matrix_keyboard_of_free_keymap(pdata->keymap_data); | ||
| 803 | |||
| 762 | return 0; | 804 | return 0; |
| 763 | 805 | ||
| 764 | err_free_irq: | 806 | err_free_irq: |
| @@ -773,8 +815,10 @@ err_free_mem: | |||
| 773 | input_free_device(input_dev); | 815 | input_free_device(input_dev); |
| 774 | kfree(kbc); | 816 | kfree(kbc); |
| 775 | err_free_pdata: | 817 | err_free_pdata: |
| 776 | if (!pdev->dev.platform_data) | 818 | if (!pdev->dev.platform_data) { |
| 819 | matrix_keyboard_of_free_keymap(pdata->keymap_data); | ||
| 777 | kfree(pdata); | 820 | kfree(pdata); |
| 821 | } | ||
| 778 | 822 | ||
| 779 | return err; | 823 | return err; |
| 780 | } | 824 | } |
| @@ -831,6 +875,8 @@ static int tegra_kbc_suspend(struct device *dev) | |||
| 831 | msleep(30); | 875 | msleep(30); |
| 832 | 876 | ||
| 833 | kbc->keypress_caused_wake = false; | 877 | kbc->keypress_caused_wake = false; |
| 878 | /* Enable keypress interrupt before going into suspend. */ | ||
| 879 | tegra_kbc_set_keypress_interrupt(kbc, true); | ||
| 834 | enable_irq(kbc->irq); | 880 | enable_irq(kbc->irq); |
| 835 | enable_irq_wake(kbc->irq); | 881 | enable_irq_wake(kbc->irq); |
| 836 | } else { | 882 | } else { |
| @@ -852,6 +898,8 @@ static int tegra_kbc_resume(struct device *dev) | |||
| 852 | if (device_may_wakeup(&pdev->dev)) { | 898 | if (device_may_wakeup(&pdev->dev)) { |
| 853 | disable_irq_wake(kbc->irq); | 899 | disable_irq_wake(kbc->irq); |
| 854 | tegra_kbc_setup_wakekeys(kbc, false); | 900 | tegra_kbc_setup_wakekeys(kbc, false); |
| 901 | /* We will use fifo interrupts for key detection. */ | ||
| 902 | tegra_kbc_set_keypress_interrupt(kbc, false); | ||
| 855 | 903 | ||
| 856 | /* Restore the resident time of continuous polling mode. */ | 904 | /* Restore the resident time of continuous polling mode. */ |
| 857 | writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0); | 905 | writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0); |
