aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorAnilKumar Ch <anilkumar@ti.com>2012-11-21 01:49:31 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-11-21 01:55:10 -0500
commit4a83eecff65bd327bf5cb3b400b96fa975c73308 (patch)
tree78e4fabcc1cc60875a6a557a215bc93c110e4536 /drivers/input
parent5383116b86d8e877684770d05acd1dda62be102d (diff)
Input: matrix-keypad - add device tree support
Also the driver was modifued to take advantage of recent improvements in matrix_keypad_build_keymap() implementation, which automatically allocates memory for keymap. The driver was tested on AM335x EVM. Signed-off-by: AnilKumar Ch <anilkumar@ti.com> Acked-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/matrix_keypad.c119
1 files changed, 97 insertions, 22 deletions
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 18b72372028a..05d3a969ff4e 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -23,6 +23,9 @@
23#include <linux/gpio.h> 23#include <linux/gpio.h>
24#include <linux/input/matrix_keypad.h> 24#include <linux/input/matrix_keypad.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/of.h>
27#include <linux/of_gpio.h>
28#include <linux/of_platform.h>
26 29
27struct matrix_keypad { 30struct matrix_keypad {
28 const struct matrix_keypad_platform_data *pdata; 31 const struct matrix_keypad_platform_data *pdata;
@@ -37,8 +40,6 @@ struct matrix_keypad {
37 bool scan_pending; 40 bool scan_pending;
38 bool stopped; 41 bool stopped;
39 bool gpio_all_disabled; 42 bool gpio_all_disabled;
40
41 unsigned short keycodes[];
42}; 43};
43 44
44/* 45/*
@@ -118,6 +119,7 @@ static void matrix_keypad_scan(struct work_struct *work)
118 struct matrix_keypad *keypad = 119 struct matrix_keypad *keypad =
119 container_of(work, struct matrix_keypad, work.work); 120 container_of(work, struct matrix_keypad, work.work);
120 struct input_dev *input_dev = keypad->input_dev; 121 struct input_dev *input_dev = keypad->input_dev;
122 const unsigned short *keycodes = input_dev->keycode;
121 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 123 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
122 uint32_t new_state[MATRIX_MAX_COLS]; 124 uint32_t new_state[MATRIX_MAX_COLS];
123 int row, col, code; 125 int row, col, code;
@@ -153,7 +155,7 @@ static void matrix_keypad_scan(struct work_struct *work)
153 code = MATRIX_SCAN_CODE(row, col, keypad->row_shift); 155 code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
154 input_event(input_dev, EV_MSC, MSC_SCAN, code); 156 input_event(input_dev, EV_MSC, MSC_SCAN, code);
155 input_report_key(input_dev, 157 input_report_key(input_dev,
156 keypad->keycodes[code], 158 keycodes[code],
157 new_state[col] & (1 << row)); 159 new_state[col] & (1 << row));
158 } 160 }
159 } 161 }
@@ -394,33 +396,95 @@ static void matrix_keypad_free_gpio(struct matrix_keypad *keypad)
394 gpio_free(pdata->col_gpios[i]); 396 gpio_free(pdata->col_gpios[i]);
395} 397}
396 398
399#ifdef CONFIG_OF
400static struct matrix_keypad_platform_data * __devinit
401matrix_keypad_parse_dt(struct device *dev)
402{
403 struct matrix_keypad_platform_data *pdata;
404 struct device_node *np = dev->of_node;
405 unsigned int *gpios;
406 int i;
407
408 if (!np) {
409 dev_err(dev, "device lacks DT data\n");
410 return ERR_PTR(-ENODEV);
411 }
412
413 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
414 if (!pdata) {
415 dev_err(dev, "could not allocate memory for platform data\n");
416 return ERR_PTR(-ENOMEM);
417 }
418
419 pdata->num_row_gpios = of_gpio_named_count(np, "row-gpios");
420 pdata->num_col_gpios = of_gpio_named_count(np, "col-gpios");
421 if (!pdata->num_row_gpios || !pdata->num_col_gpios) {
422 dev_err(dev, "number of keypad rows/columns not specified\n");
423 return ERR_PTR(-EINVAL);
424 }
425
426 if (of_get_property(np, "linux,no-autorepeat", NULL))
427 pdata->no_autorepeat = true;
428 if (of_get_property(np, "linux,wakeup", NULL))
429 pdata->wakeup = true;
430 if (of_get_property(np, "gpio-activelow", NULL))
431 pdata->active_low = true;
432
433 of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms);
434 of_property_read_u32(np, "col-scan-delay-us",
435 &pdata->col_scan_delay_us);
436
437 gpios = devm_kzalloc(dev,
438 sizeof(unsigned int) *
439 (pdata->num_row_gpios + pdata->num_col_gpios),
440 GFP_KERNEL);
441 if (!gpios) {
442 dev_err(dev, "could not allocate memory for gpios\n");
443 return ERR_PTR(-ENOMEM);
444 }
445
446 for (i = 0; i < pdata->num_row_gpios; i++)
447 gpios[i] = of_get_named_gpio(np, "row-gpios", i);
448
449 for (i = 0; i < pdata->num_col_gpios; i++)
450 gpios[pdata->num_row_gpios + i] =
451 of_get_named_gpio(np, "col-gpios", i);
452
453 pdata->row_gpios = gpios;
454 pdata->col_gpios = &gpios[pdata->num_row_gpios];
455
456 return pdata;
457}
458#else
459static inline struct matrix_keypad_platform_data *
460matrix_keypad_parse_dt(struct device *dev)
461{
462 dev_err(dev, "no platform data defined\n");
463
464 return ERR_PTR(-EINVAL);
465}
466#endif
467
397static int __devinit matrix_keypad_probe(struct platform_device *pdev) 468static int __devinit matrix_keypad_probe(struct platform_device *pdev)
398{ 469{
399 const struct matrix_keypad_platform_data *pdata; 470 const struct matrix_keypad_platform_data *pdata;
400 const struct matrix_keymap_data *keymap_data;
401 struct matrix_keypad *keypad; 471 struct matrix_keypad *keypad;
402 struct input_dev *input_dev; 472 struct input_dev *input_dev;
403 unsigned int row_shift;
404 size_t keymap_size;
405 int err; 473 int err;
406 474
407 pdata = pdev->dev.platform_data; 475 pdata = dev_get_platdata(&pdev->dev);
408 if (!pdata) { 476 if (!pdata) {
409 dev_err(&pdev->dev, "no platform data defined\n"); 477 pdata = matrix_keypad_parse_dt(&pdev->dev);
410 return -EINVAL; 478 if (IS_ERR(pdata)) {
411 } 479 dev_err(&pdev->dev, "no platform data defined\n");
412 480 return PTR_ERR(pdata);
413 keymap_data = pdata->keymap_data; 481 }
414 if (!keymap_data) { 482 } else if (!pdata->keymap_data) {
415 dev_err(&pdev->dev, "no keymap data defined\n"); 483 dev_err(&pdev->dev, "no keymap data defined\n");
416 return -EINVAL; 484 return -EINVAL;
417 } 485 }
418 486
419 row_shift = get_count_order(pdata->num_col_gpios); 487 keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
420 keymap_size = (pdata->num_row_gpios << row_shift) *
421 sizeof(keypad->keycodes[0]);
422 keypad = kzalloc(sizeof(struct matrix_keypad) + keymap_size,
423 GFP_KERNEL);
424 input_dev = input_allocate_device(); 488 input_dev = input_allocate_device();
425 if (!keypad || !input_dev) { 489 if (!keypad || !input_dev) {
426 err = -ENOMEM; 490 err = -ENOMEM;
@@ -429,7 +493,7 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
429 493
430 keypad->input_dev = input_dev; 494 keypad->input_dev = input_dev;
431 keypad->pdata = pdata; 495 keypad->pdata = pdata;
432 keypad->row_shift = row_shift; 496 keypad->row_shift = get_count_order(pdata->num_col_gpios);
433 keypad->stopped = true; 497 keypad->stopped = true;
434 INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); 498 INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
435 spin_lock_init(&keypad->lock); 499 spin_lock_init(&keypad->lock);
@@ -440,12 +504,14 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
440 input_dev->open = matrix_keypad_start; 504 input_dev->open = matrix_keypad_start;
441 input_dev->close = matrix_keypad_stop; 505 input_dev->close = matrix_keypad_stop;
442 506
443 err = matrix_keypad_build_keymap(keymap_data, NULL, 507 err = matrix_keypad_build_keymap(pdata->keymap_data, NULL,
444 pdata->num_row_gpios, 508 pdata->num_row_gpios,
445 pdata->num_col_gpios, 509 pdata->num_col_gpios,
446 keypad->keycodes, input_dev); 510 NULL, input_dev);
447 if (err) 511 if (err) {
512 dev_err(&pdev->dev, "failed to build keymap\n");
448 goto err_free_mem; 513 goto err_free_mem;
514 }
449 515
450 if (!pdata->no_autorepeat) 516 if (!pdata->no_autorepeat)
451 __set_bit(EV_REP, input_dev->evbit); 517 __set_bit(EV_REP, input_dev->evbit);
@@ -488,6 +554,14 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev)
488 return 0; 554 return 0;
489} 555}
490 556
557#ifdef CONFIG_OF
558static const struct of_device_id matrix_keypad_dt_match[] = {
559 { .compatible = "gpio-matrix-keypad" },
560 { }
561};
562MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match);
563#endif
564
491static struct platform_driver matrix_keypad_driver = { 565static struct platform_driver matrix_keypad_driver = {
492 .probe = matrix_keypad_probe, 566 .probe = matrix_keypad_probe,
493 .remove = __devexit_p(matrix_keypad_remove), 567 .remove = __devexit_p(matrix_keypad_remove),
@@ -495,6 +569,7 @@ static struct platform_driver matrix_keypad_driver = {
495 .name = "matrix-keypad", 569 .name = "matrix-keypad",
496 .owner = THIS_MODULE, 570 .owner = THIS_MODULE,
497 .pm = &matrix_keypad_pm_ops, 571 .pm = &matrix_keypad_pm_ops,
572 .of_match_table = of_match_ptr(matrix_keypad_dt_match),
498 }, 573 },
499}; 574};
500module_platform_driver(matrix_keypad_driver); 575module_platform_driver(matrix_keypad_driver);