aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2012-03-19 20:02:01 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-03-19 20:02:01 -0400
commit10ce3cc919f50c2043b41ca968b43c26a3672600 (patch)
treeea409366a5208aced495bc0516a08b81fd43222e /drivers/input/keyboard
parent24e3e5ae1e4c2a3a32f5b1f96b4e3fd721806acd (diff)
parent5c6a7a62c130afef3d61c1dee153012231ff5cd9 (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/Kconfig2
-rw-r--r--drivers/input/keyboard/adp5588-keys.c12
-rw-r--r--drivers/input/keyboard/adp5589-keys.c12
-rw-r--r--drivers/input/keyboard/lm8323.c12
-rw-r--r--drivers/input/keyboard/max7359_keypad.c12
-rw-r--r--drivers/input/keyboard/mcs_touchkey.c13
-rw-r--r--drivers/input/keyboard/mpr121_touchkey.c12
-rw-r--r--drivers/input/keyboard/nomadik-ske-keypad.c17
-rw-r--r--drivers/input/keyboard/omap4-keypad.c2
-rw-r--r--drivers/input/keyboard/qt1070.c12
-rw-r--r--drivers/input/keyboard/qt2160.c12
-rw-r--r--drivers/input/keyboard/samsung-keypad.c179
-rw-r--r--drivers/input/keyboard/spear-keyboard.c16
-rw-r--r--drivers/input/keyboard/tegra-kbc.c72
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
394config KEYBOARD_TEGRA 394config 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
513config KEYBOARD_OMAP4 514config 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
656static int __init adp5588_init(void) 656module_i2c_driver(adp5588_driver);
657{
658 return i2c_add_driver(&adp5588_driver);
659}
660module_init(adp5588_init);
661
662static void __exit adp5588_exit(void)
663{
664 i2c_del_driver(&adp5588_driver);
665}
666module_exit(adp5588_exit);
667 657
668MODULE_LICENSE("GPL"); 658MODULE_LICENSE("GPL");
669MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 659MODULE_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
1111static int __init adp5589_init(void) 1111module_i2c_driver(adp5589_driver);
1112{
1113 return i2c_add_driver(&adp5589_driver);
1114}
1115module_init(adp5589_init);
1116
1117static void __exit adp5589_exit(void)
1118{
1119 i2c_del_driver(&adp5589_driver);
1120}
1121module_exit(adp5589_exit);
1122 1112
1123MODULE_LICENSE("GPL"); 1113MODULE_LICENSE("GPL");
1124MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 1114MODULE_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};
852MODULE_DEVICE_TABLE(i2c, lm8323_id); 852MODULE_DEVICE_TABLE(i2c, lm8323_id);
853 853
854static int __init lm8323_init(void) 854module_i2c_driver(lm8323_i2c_driver);
855{
856 return i2c_add_driver(&lm8323_i2c_driver);
857}
858module_init(lm8323_init);
859
860static void __exit lm8323_exit(void)
861{
862 i2c_del_driver(&lm8323_i2c_driver);
863}
864module_exit(lm8323_exit);
865 855
866MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>"); 856MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>");
867MODULE_AUTHOR("Daniel Stone"); 857MODULE_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
319static int __init max7359_init(void) 319module_i2c_driver(max7359_i2c_driver);
320{
321 return i2c_add_driver(&max7359_i2c_driver);
322}
323module_init(max7359_init);
324
325static void __exit max7359_exit(void)
326{
327 i2c_del_driver(&max7359_i2c_driver);
328}
329module_exit(max7359_exit);
330 320
331MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); 321MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
332MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver"); 322MODULE_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
277static int __init mcs_touchkey_init(void) 277module_i2c_driver(mcs_touchkey_driver);
278{
279 return i2c_add_driver(&mcs_touchkey_driver);
280}
281
282static void __exit mcs_touchkey_exit(void)
283{
284 i2c_del_driver(&mcs_touchkey_driver);
285}
286
287module_init(mcs_touchkey_init);
288module_exit(mcs_touchkey_exit);
289 278
290/* Module information */ 279/* Module information */
291MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 280MODULE_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
333static int __init mpr_touchkey_init(void) 333module_i2c_driver(mpr_touchkey_driver);
334{
335 return i2c_add_driver(&mpr_touchkey_driver);
336}
337module_init(mpr_touchkey_init);
338
339static void __exit mpr_touchkey_exit(void)
340{
341 i2c_del_driver(&mpr_touchkey_driver);
342}
343module_exit(mpr_touchkey_exit);
344 334
345MODULE_LICENSE("GPL"); 335MODULE_LICENSE("GPL");
346MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); 336MODULE_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 */
91static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) 91static 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
201static int __devinit ske_keypad_probe(struct platform_device *pdev) 201static 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
348static int ske_keypad_suspend(struct device *dev) 348static 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
376static 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
377static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops,
378 ske_keypad_suspend, ske_keypad_resume);
379
382static struct platform_driver ske_keypad_driver = { 380static 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
261static int __init qt1070_init(void) 261module_i2c_driver(qt1070_driver);
262{
263 return i2c_add_driver(&qt1070_driver);
264}
265module_init(qt1070_init);
266
267static void __exit qt1070_exit(void)
268{
269 i2c_del_driver(&qt1070_driver);
270}
271module_exit(qt1070_exit);
272 262
273MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); 263MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
274MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor"); 264MODULE_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
382static int __init qt2160_init(void) 382module_i2c_driver(qt2160_driver);
383{
384 return i2c_add_driver(&qt2160_driver);
385}
386module_init(qt2160_init);
387
388static void __exit qt2160_cleanup(void)
389{
390 i2c_del_driver(&qt2160_driver);
391}
392module_exit(qt2160_cleanup);
393 383
394MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>"); 384MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>");
395MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor"); 385MODULE_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
82static 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
91static void samsung_keypad_scan(struct samsung_keypad *keypad, 89static 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
208static void samsung_keypad_stop(struct samsung_keypad *keypad) 205static 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
238static int samsung_keypad_open(struct input_dev *input_dev) 235static 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
252static 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
310static 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
347static 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
360static
361struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev)
362{
363 return NULL;
364}
365
366static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
367{
368}
369#endif
370
254static int __devinit samsung_keypad_probe(struct platform_device *pdev) 371static 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
368err_free_irq: 503err_free_irq:
@@ -372,6 +507,7 @@ err_free_irq:
372 platform_set_drvdata(pdev, NULL); 507 platform_set_drvdata(pdev, NULL);
373err_put_clk: 508err_put_clk:
374 clk_put(keypad->clk); 509 clk_put(keypad->clk);
510 samsung_keypad_dt_gpio_free(keypad);
375err_unmap_base: 511err_unmap_base:
376 iounmap(keypad->base); 512 iounmap(keypad->base);
377err_free_mem: 513err_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
659static const struct of_device_id samsung_keypad_dt_match[] = {
660 { .compatible = "samsung,s3c6410-keypad" },
661 { .compatible = "samsung,s5pv210-keypad" },
662 {},
663};
664MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match);
665#else
666#define samsung_keypad_dt_match NULL
667#endif
668
521static struct platform_device_id samsung_keypad_driver_ids[] = { 669static 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
54struct spear_kbd { 55struct 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
312static 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
318static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume);
319
318static struct platform_driver spear_kbd_driver = { 320static 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};
329module_platform_driver(spear_kbd_driver); 329module_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
360static 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
359static void tegra_kbc_keypress_timer(unsigned long data) 372static 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
764err_free_irq: 806err_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);
775err_free_pdata: 817err_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);