aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2013-01-06 21:32:22 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-01-17 03:28:00 -0500
commit88390243a9937f9831aeba5113a8b59bb1d4411a (patch)
tree3fd73c6fc87b0c43290a4d49ee2895c8fdbeeaca
parent00eb81e56a38ffb7839e0e6262e26c20c617d2ab (diff)
Input: tegra-kbc - add support for rows/columns configuration from dt
The NVIDIA's Tegra KBC has maximum 24 pins to make matrix keypad. Any pin can be configured as row or column. The maximum column pin can be 8 and maximum row pin can be 16. Remove the assumption that all first 16 pins will be used as row and remaining as columns and Add the property for configuring pins to either row or column from DT. Update the devicetree binding document accordingly. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt22
-rw-r--r--drivers/input/keyboard/tegra-kbc.c82
2 files changed, 85 insertions, 19 deletions
diff --git a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
index 72683be6de35..2995fae7ee47 100644
--- a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
+++ b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
@@ -1,7 +1,18 @@
1* Tegra keyboard controller 1* Tegra keyboard controller
2The key controller has maximum 24 pins to make matrix keypad. Any pin
3can be configured as row or column. The maximum column pin can be 8
4and maximum row pins can be 16 for Tegra20/Tegra30.
2 5
3Required properties: 6Required properties:
4- compatible: "nvidia,tegra20-kbc" 7- compatible: "nvidia,tegra20-kbc"
8- reg: Register base address of KBC.
9- interrupts: Interrupt number for the KBC.
10- nvidia,kbc-row-pins: The KBC pins which are configured as row. This is an
11 array of pin numbers which is used as rows.
12- nvidia,kbc-col-pins: The KBC pins which are configured as column. This is an
13 array of pin numbers which is used as column.
14- linux,keymap: The keymap for keys as described in the binding document
15 devicetree/bindings/input/matrix-keymap.txt.
5 16
6Optional properties, in addition to those specified by the shared 17Optional properties, in addition to those specified by the shared
7matrix-keyboard bindings: 18matrix-keyboard bindings:
@@ -19,5 +30,16 @@ Example:
19keyboard: keyboard { 30keyboard: keyboard {
20 compatible = "nvidia,tegra20-kbc"; 31 compatible = "nvidia,tegra20-kbc";
21 reg = <0x7000e200 0x100>; 32 reg = <0x7000e200 0x100>;
33 interrupts = <0 85 0x04>;
22 nvidia,ghost-filter; 34 nvidia,ghost-filter;
35 nvidia,debounce-delay-ms = <640>;
36 nvidia,kbc-row-pins = <0 1 2>; /* pin 0, 1, 2 as rows */
37 nvidia,kbc-col-pins = <11 12 13>; /* pin 11, 12, 13 as columns */
38 linux,keymap = <0x00000074
39 0x00010067
40 0x00020066
41 0x01010068
42 0x02000069
43 0x02010070
44 0x02020071>;
23}; 45};
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index f79993679070..39ef663bb38f 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -614,13 +614,21 @@ static struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
614 struct device_node *np = pdev->dev.of_node; 614 struct device_node *np = pdev->dev.of_node;
615 u32 prop; 615 u32 prop;
616 int i; 616 int i;
617 617 u32 num_rows = 0;
618 if (!np) 618 u32 num_cols = 0;
619 return NULL; 619 u32 cols_cfg[KBC_MAX_GPIO];
620 u32 rows_cfg[KBC_MAX_GPIO];
621 int proplen;
622 int ret;
623
624 if (!np) {
625 dev_err(&pdev->dev, "device tree data is missing\n");
626 return ERR_PTR(-ENOENT);
627 }
620 628
621 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 629 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
622 if (!pdata) 630 if (!pdata)
623 return NULL; 631 return ERR_PTR(-ENOMEM);
624 632
625 if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop)) 633 if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop))
626 pdata->debounce_cnt = prop; 634 pdata->debounce_cnt = prop;
@@ -634,18 +642,55 @@ static struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
634 if (of_find_property(np, "nvidia,wakeup-source", NULL)) 642 if (of_find_property(np, "nvidia,wakeup-source", NULL))
635 pdata->wakeup = true; 643 pdata->wakeup = true;
636 644
637 /* 645 if (!of_get_property(np, "nvidia,kbc-row-pins", &proplen)) {
638 * All currently known keymaps with device tree support use the same 646 dev_err(&pdev->dev, "property nvidia,kbc-row-pins not found\n");
639 * pin_cfg, so set it up here. 647 return ERR_PTR(-ENOENT);
640 */ 648 }
641 for (i = 0; i < KBC_MAX_ROW; i++) { 649 num_rows = proplen / sizeof(u32);
642 pdata->pin_cfg[i].num = i; 650
643 pdata->pin_cfg[i].type = PIN_CFG_ROW; 651 if (!of_get_property(np, "nvidia,kbc-col-pins", &proplen)) {
652 dev_err(&pdev->dev, "property nvidia,kbc-col-pins not found\n");
653 return ERR_PTR(-ENOENT);
654 }
655 num_cols = proplen / sizeof(u32);
656
657 if (!of_get_property(np, "linux,keymap", &proplen)) {
658 dev_err(&pdev->dev, "property linux,keymap not found\n");
659 return ERR_PTR(-ENOENT);
644 } 660 }
645 661
646 for (i = 0; i < KBC_MAX_COL; i++) { 662 if (!num_rows || !num_cols || ((num_rows + num_cols) > KBC_MAX_GPIO)) {
647 pdata->pin_cfg[KBC_MAX_ROW + i].num = i; 663 dev_err(&pdev->dev,
648 pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; 664 "keypad rows/columns not porperly specified\n");
665 return ERR_PTR(-EINVAL);
666 }
667
668 /* Set all pins as non-configured */
669 for (i = 0; i < KBC_MAX_GPIO; i++)
670 pdata->pin_cfg[i].type = PIN_CFG_IGNORE;
671
672 ret = of_property_read_u32_array(np, "nvidia,kbc-row-pins",
673 rows_cfg, num_rows);
674 if (ret < 0) {
675 dev_err(&pdev->dev, "Rows configurations are not proper\n");
676 return ERR_PTR(-EINVAL);
677 }
678
679 ret = of_property_read_u32_array(np, "nvidia,kbc-col-pins",
680 cols_cfg, num_cols);
681 if (ret < 0) {
682 dev_err(&pdev->dev, "Cols configurations are not proper\n");
683 return ERR_PTR(-EINVAL);
684 }
685
686 for (i = 0; i < num_rows; i++) {
687 pdata->pin_cfg[rows_cfg[i]].type = PIN_CFG_ROW;
688 pdata->pin_cfg[rows_cfg[i]].num = i;
689 }
690
691 for (i = 0; i < num_cols; i++) {
692 pdata->pin_cfg[cols_cfg[i]].type = PIN_CFG_COL;
693 pdata->pin_cfg[cols_cfg[i]].num = i;
649 } 694 }
650 695
651 return pdata; 696 return pdata;
@@ -654,7 +699,8 @@ static struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
654static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata( 699static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
655 struct platform_device *pdev) 700 struct platform_device *pdev)
656{ 701{
657 return NULL; 702 dev_err(&pdev->dev, "platform data is missing\n");
703 return ERR_PTR(-EINVAL);
658} 704}
659#endif 705#endif
660 706
@@ -700,10 +746,8 @@ static int tegra_kbc_probe(struct platform_device *pdev)
700 if (!pdata) 746 if (!pdata)
701 pdata = tegra_kbc_dt_parse_pdata(pdev); 747 pdata = tegra_kbc_dt_parse_pdata(pdev);
702 748
703 if (!pdata) { 749 if (IS_ERR(pdata))
704 dev_err(&pdev->dev, "Platform data missing\n"); 750 return PTR_ERR(pdata);
705 return -EINVAL;
706 }
707 751
708 if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows)) 752 if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows))
709 return -EINVAL; 753 return -EINVAL;