aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/keyboard/tegra-kbc.c56
-rw-r--r--drivers/input/matrix-keymap.c175
-rw-r--r--include/linux/input/matrix_keypad.h18
3 files changed, 130 insertions, 119 deletions
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index 6722d376e898..4ffe64d53107 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -619,8 +619,8 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata,
619} 619}
620 620
621#ifdef CONFIG_OF 621#ifdef CONFIG_OF
622static struct tegra_kbc_platform_data * __devinit 622static struct tegra_kbc_platform_data * __devinit tegra_kbc_dt_parse_pdata(
623tegra_kbc_dt_parse_pdata(struct platform_device *pdev) 623 struct platform_device *pdev)
624{ 624{
625 struct tegra_kbc_platform_data *pdata; 625 struct tegra_kbc_platform_data *pdata;
626 struct device_node *np = pdev->dev.of_node; 626 struct device_node *np = pdev->dev.of_node;
@@ -660,10 +660,6 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
660 pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; 660 pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL;
661 } 661 }
662 662
663 pdata->keymap_data = matrix_keyboard_of_fill_keymap(np, "linux,keymap");
664
665 /* FIXME: Add handling of linux,fn-keymap here */
666
667 return pdata; 663 return pdata;
668} 664}
669#else 665#else
@@ -674,10 +670,36 @@ static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
674} 670}
675#endif 671#endif
676 672
673static int __devinit tegra_kbd_setup_keymap(struct tegra_kbc *kbc)
674{
675 const struct tegra_kbc_platform_data *pdata = kbc->pdata;
676 const struct matrix_keymap_data *keymap_data = pdata->keymap_data;
677 unsigned int keymap_rows = KBC_MAX_KEY;
678 int retval;
679
680 if (keymap_data && pdata->use_fn_map)
681 keymap_rows *= 2;
682
683 retval = matrix_keypad_build_keymap(keymap_data, NULL,
684 keymap_rows, KBC_MAX_COL,
685 kbc->keycode, kbc->idev);
686 if (retval == -ENOSYS || retval == -ENOENT) {
687 /*
688 * If there is no OF support in kernel or keymap
689 * property is missing, use default keymap.
690 */
691 retval = matrix_keypad_build_keymap(
692 &tegra_kbc_default_keymap_data, NULL,
693 keymap_rows, KBC_MAX_COL,
694 kbc->keycode, kbc->idev);
695 }
696
697 return retval;
698}
699
677static int __devinit tegra_kbc_probe(struct platform_device *pdev) 700static int __devinit tegra_kbc_probe(struct platform_device *pdev)
678{ 701{
679 const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; 702 const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data;
680 const struct matrix_keymap_data *keymap_data;
681 struct tegra_kbc *kbc; 703 struct tegra_kbc *kbc;
682 struct input_dev *input_dev; 704 struct input_dev *input_dev;
683 struct resource *res; 705 struct resource *res;
@@ -686,7 +708,6 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
686 int num_rows = 0; 708 int num_rows = 0;
687 unsigned int debounce_cnt; 709 unsigned int debounce_cnt;
688 unsigned int scan_time_rows; 710 unsigned int scan_time_rows;
689 unsigned int keymap_rows;
690 711
691 if (!pdata) 712 if (!pdata)
692 pdata = tegra_kbc_dt_parse_pdata(pdev); 713 pdata = tegra_kbc_dt_parse_pdata(pdev);
@@ -768,17 +789,9 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
768 input_dev->open = tegra_kbc_open; 789 input_dev->open = tegra_kbc_open;
769 input_dev->close = tegra_kbc_close; 790 input_dev->close = tegra_kbc_close;
770 791
771 keymap_rows = KBC_MAX_KEY; 792 err = tegra_kbd_setup_keymap(kbc);
772 if (pdata->use_fn_map)
773 keymap_rows *= 2;
774
775 keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data;
776
777 err = matrix_keypad_build_keymap(keymap_data, NULL,
778 keymap_rows, KBC_MAX_COL,
779 kbc->keycode, input_dev);
780 if (err) { 793 if (err) {
781 dev_err(&pdev->dev, "failed to build keymap\n"); 794 dev_err(&pdev->dev, "failed to setup keymap\n");
782 goto err_put_clk; 795 goto err_put_clk;
783 } 796 }
784 797
@@ -805,9 +818,6 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
805 platform_set_drvdata(pdev, kbc); 818 platform_set_drvdata(pdev, kbc);
806 device_init_wakeup(&pdev->dev, pdata->wakeup); 819 device_init_wakeup(&pdev->dev, pdata->wakeup);
807 820
808 if (!pdev->dev.platform_data)
809 matrix_keyboard_of_free_keymap(pdata->keymap_data);
810
811 return 0; 821 return 0;
812 822
813err_free_irq: 823err_free_irq:
@@ -822,10 +832,8 @@ err_free_mem:
822 input_free_device(input_dev); 832 input_free_device(input_dev);
823 kfree(kbc); 833 kfree(kbc);
824err_free_pdata: 834err_free_pdata:
825 if (!pdev->dev.platform_data) { 835 if (!pdev->dev.platform_data)
826 matrix_keyboard_of_free_keymap(pdata->keymap_data);
827 kfree(pdata); 836 kfree(pdata);
828 }
829 837
830 return err; 838 return err;
831} 839}
diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c
index de7992d55da2..db92c1ebfc59 100644
--- a/drivers/input/matrix-keymap.c
+++ b/drivers/input/matrix-keymap.c
@@ -17,15 +17,91 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/device.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/types.h> 22#include <linux/types.h>
22#include <linux/input.h> 23#include <linux/input.h>
23#include <linux/of.h> 24#include <linux/of.h>
24#include <linux/export.h> 25#include <linux/export.h>
25#include <linux/gfp.h>
26#include <linux/slab.h>
27#include <linux/input/matrix_keypad.h> 26#include <linux/input/matrix_keypad.h>
28 27
28static bool matrix_keypad_map_key(struct input_dev *input_dev,
29 unsigned int rows, unsigned int cols,
30 unsigned int row_shift, unsigned int key)
31{
32 unsigned char *keymap = input_dev->keycode;
33 unsigned int row = KEY_ROW(key);
34 unsigned int col = KEY_COL(key);
35 unsigned short code = KEY_VAL(key);
36
37 if (row >= rows || col >= cols) {
38 dev_err(input_dev->dev.parent,
39 "%s: invalid keymap entry 0x%x (row: %d, col: %d, rows: %d, cols: %d)\n",
40 __func__, key, row, col, rows, cols);
41 return false;
42 }
43
44 keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code;
45 __set_bit(code, input_dev->keybit);
46
47 return true;
48}
49
50#ifdef CONFIG_OF
51static int matrix_keypad_parse_of_keymap(const char *propname,
52 unsigned int rows, unsigned int cols,
53 struct input_dev *input_dev)
54{
55 struct device *dev = input_dev->dev.parent;
56 struct device_node *np = dev->of_node;
57 unsigned int row_shift = get_count_order(cols);
58 unsigned int max_keys = rows << row_shift;
59 unsigned int proplen, i, size;
60 const __be32 *prop;
61
62 if (!np)
63 return -ENOENT;
64
65 if (!propname)
66 propname = "linux,keymap";
67
68 prop = of_get_property(np, propname, &proplen);
69 if (!prop) {
70 dev_err(dev, "OF: %s property not defined in %s\n",
71 propname, np->full_name);
72 return -ENOENT;
73 }
74
75 if (proplen % sizeof(u32)) {
76 dev_err(dev, "OF: Malformed keycode property %s in %s\n",
77 propname, np->full_name);
78 return -EINVAL;
79 }
80
81 size = proplen / sizeof(u32);
82 if (size > max_keys) {
83 dev_err(dev, "OF: %s size overflow\n", propname);
84 return -EINVAL;
85 }
86
87 for (i = 0; i < size; i++) {
88 unsigned int key = be32_to_cpup(prop + i);
89
90 if (!matrix_keypad_map_key(input_dev, rows, cols,
91 row_shift, key))
92 return -EINVAL;
93 }
94
95 return 0;
96}
97#else
98static int matrix_keypad_parse_of_keymap(const char *propname,
99 unsigned int rows, unsigned int cols,
100 struct input_dev *input_dev)
101{
102 return -ENOSYS;
103}
104#endif
29 105
30/** 106/**
31 * matrix_keypad_build_keymap - convert platform keymap into matrix keymap 107 * matrix_keypad_build_keymap - convert platform keymap into matrix keymap
@@ -41,6 +117,13 @@
41 * This function converts platform keymap (encoded with KEY() macro) into 117 * This function converts platform keymap (encoded with KEY() macro) into
42 * an array of keycodes that is suitable for using in a standard matrix 118 * an array of keycodes that is suitable for using in a standard matrix
43 * keyboard driver that uses row and col as indices. 119 * keyboard driver that uses row and col as indices.
120 *
121 * If @keymap_data is not supplied and device tree support is enabled
122 * it will attempt load the keymap from property specified by @keymap_name
123 * argument (or "linux,keymap" if @keymap_name is %NULL).
124 *
125 * Callers are expected to set up input_dev->dev.parent before calling this
126 * function.
44 */ 127 */
45int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, 128int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
46 const char *keymap_name, 129 const char *keymap_name,
@@ -50,6 +133,7 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
50{ 133{
51 unsigned int row_shift = get_count_order(cols); 134 unsigned int row_shift = get_count_order(cols);
52 int i; 135 int i;
136 int error;
53 137
54 input_dev->keycode = keymap; 138 input_dev->keycode = keymap;
55 input_dev->keycodesize = sizeof(*keymap); 139 input_dev->keycodesize = sizeof(*keymap);
@@ -57,86 +141,23 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
57 141
58 __set_bit(EV_KEY, input_dev->evbit); 142 __set_bit(EV_KEY, input_dev->evbit);
59 143
60 for (i = 0; i < keymap_data->keymap_size; i++) { 144 if (keymap_data) {
61 unsigned int key = keymap_data->keymap[i]; 145 for (i = 0; i < keymap_data->keymap_size; i++) {
62 unsigned int row = KEY_ROW(key); 146 unsigned int key = keymap_data->keymap[i];
63 unsigned int col = KEY_COL(key);
64 unsigned short code = KEY_VAL(key);
65 147
66 if (row >= rows || col >= cols) { 148 if (!matrix_keypad_map_key(input_dev, rows, cols,
67 dev_err(input_dev->dev.parent, 149 row_shift, key))
68 "%s: invalid keymap entry %d (row: %d, col: %d, rows: %d, cols: %d)\n", 150 return -EINVAL;
69 __func__, i, row, col, rows, cols);
70 return -EINVAL;
71 } 151 }
72 152 } else {
73 keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code; 153 error = matrix_keypad_parse_of_keymap(keymap_name, rows, cols,
74 __set_bit(code, input_dev->keybit); 154 input_dev);
155 if (error)
156 return error;
75 } 157 }
158
76 __clear_bit(KEY_RESERVED, input_dev->keybit); 159 __clear_bit(KEY_RESERVED, input_dev->keybit);
77 160
78 return 0; 161 return 0;
79} 162}
80EXPORT_SYMBOL(matrix_keypad_build_keymap); 163EXPORT_SYMBOL(matrix_keypad_build_keymap);
81
82#ifdef CONFIG_OF
83struct matrix_keymap_data *
84matrix_keyboard_of_fill_keymap(struct device_node *np,
85 const char *propname)
86{
87 struct matrix_keymap_data *kd;
88 u32 *keymap;
89 int proplen, i;
90 const __be32 *prop;
91
92 if (!np)
93 return NULL;
94
95 if (!propname)
96 propname = "linux,keymap";
97
98 prop = of_get_property(np, propname, &proplen);
99 if (!prop)
100 return NULL;
101
102 if (proplen % sizeof(u32)) {
103 pr_warn("Malformed keymap property %s in %s\n",
104 propname, np->full_name);
105 return NULL;
106 }
107
108 kd = kzalloc(sizeof(*kd), GFP_KERNEL);
109 if (!kd)
110 return NULL;
111
112 kd->keymap = keymap = kzalloc(proplen, GFP_KERNEL);
113 if (!kd->keymap) {
114 kfree(kd);
115 return NULL;
116 }
117
118 kd->keymap_size = proplen / sizeof(u32);
119
120 for (i = 0; i < kd->keymap_size; i++) {
121 u32 tmp = be32_to_cpup(prop + i);
122 int key_code, row, col;
123
124 row = (tmp >> 24) & 0xff;
125 col = (tmp >> 16) & 0xff;
126 key_code = tmp & 0xffff;
127 keymap[i] = KEY(row, col, key_code);
128 }
129
130 return kd;
131}
132EXPORT_SYMBOL_GPL(matrix_keyboard_of_fill_keymap);
133
134void matrix_keyboard_of_free_keymap(const struct matrix_keymap_data *kd)
135{
136 if (kd) {
137 kfree(kd->keymap);
138 kfree(kd);
139 }
140}
141EXPORT_SYMBOL_GPL(matrix_keyboard_of_free_keymap);
142#endif
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index e8fe08ebc245..5f3aa6b11bfa 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -81,22 +81,4 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
81 unsigned short *keymap, 81 unsigned short *keymap,
82 struct input_dev *input_dev); 82 struct input_dev *input_dev);
83 83
84#ifdef CONFIG_OF
85struct matrix_keymap_data *
86matrix_keyboard_of_fill_keymap(struct device_node *np, const char *propname);
87
88void matrix_keyboard_of_free_keymap(const struct matrix_keymap_data *kd);
89#else
90static inline struct matrix_keymap_data *
91matrix_keyboard_of_fill_keymap(struct device_node *np, const char *propname)
92{
93 return NULL;
94}
95
96static inline void
97matrix_keyboard_of_free_keymap(const struct matrix_keymap_data *kd)
98{
99}
100#endif
101
102#endif /* _MATRIX_KEYPAD_H */ 84#endif /* _MATRIX_KEYPAD_H */