aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-w90x900/include/mach/w90p910_keypad.h5
-rw-r--r--drivers/input/keyboard/w90p910_keypad.c144
2 files changed, 66 insertions, 83 deletions
diff --git a/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
index 79462faaa189..556778e8ddaa 100644
--- a/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
+++ b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
@@ -6,13 +6,10 @@
6extern void mfp_set_groupi(struct device *dev); 6extern void mfp_set_groupi(struct device *dev);
7 7
8struct w90p910_keypad_platform_data { 8struct w90p910_keypad_platform_data {
9 const struct matrix_keymap_data *keymap_data;
9 10
10 unsigned int prescale; 11 unsigned int prescale;
11 unsigned int debounce; 12 unsigned int debounce;
12 unsigned int matrix_key_rows;
13 unsigned int matrix_key_cols;
14 unsigned int *matrix_key_map;
15 int matrix_key_map_size;
16}; 13};
17 14
18#endif /* __ASM_ARCH_W90P910_KEYPAD_H */ 15#endif /* __ASM_ARCH_W90P910_KEYPAD_H */
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c
index 472c70514af0..24096cdfcb6f 100644
--- a/drivers/input/keyboard/w90p910_keypad.c
+++ b/drivers/input/keyboard/w90p910_keypad.c
@@ -41,58 +41,34 @@
41#define KGET_RAW(n) (((n) & KEY0R) >> 3) 41#define KGET_RAW(n) (((n) & KEY0R) >> 3)
42#define KGET_COLUMN(n) ((n) & KEY0C) 42#define KGET_COLUMN(n) ((n) & KEY0C)
43 43
44#define MAX_MATRIX_KEY_NUM (8 * 8) 44#define W90P910_MAX_KEY_NUM (8 * 8)
45#define W90P910_ROW_SHIFT 3
45 46
46struct w90p910_keypad { 47struct w90p910_keypad {
47 struct w90p910_keypad_platform_data *pdata; 48 const struct w90p910_keypad_platform_data *pdata;
48 struct clk *clk; 49 struct clk *clk;
49 struct input_dev *input_dev; 50 struct input_dev *input_dev;
50 void __iomem *mmio_base; 51 void __iomem *mmio_base;
51 int irq; 52 int irq;
52 unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; 53 unsigned short keymap[W90P910_MAX_KEY_NUM];
53}; 54};
54 55
55static void w90p910_keypad_build_keycode(struct w90p910_keypad *keypad)
56{
57 struct w90p910_keypad_platform_data *pdata = keypad->pdata;
58 struct input_dev *input_dev = keypad->input_dev;
59 unsigned int *key;
60 int i;
61
62 key = &pdata->matrix_key_map[0];
63 for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
64 int row = KEY_ROW(*key);
65 int col = KEY_COL(*key);
66 int code = KEY_VAL(*key);
67
68 keypad->matrix_keycodes[(row << 3) + col] = code;
69 __set_bit(code, input_dev->keybit);
70 }
71}
72
73static inline unsigned int lookup_matrix_keycode(
74 struct w90p910_keypad *keypad, int row, int col)
75{
76 return keypad->matrix_keycodes[(row << 3) + col];
77}
78
79static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, 56static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad,
80 unsigned int status) 57 unsigned int status)
81{ 58{
82 unsigned int row, col, val; 59 struct input_dev *input_dev = keypad->input_dev;
83 60 unsigned int row = KGET_RAW(status);
84 row = KGET_RAW(status); 61 unsigned int col = KGET_COLUMN(status);
85 col = KGET_COLUMN(status); 62 unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT);
86 63 unsigned int key = keypad->keymap[code];
87 val = lookup_matrix_keycode(keypad, row, col); 64
88 65 input_event(input_dev, EV_MSC, MSC_SCAN, code);
89 input_report_key(keypad->input_dev, val, 1); 66 input_report_key(input_dev, key, 1);
90 67 input_sync(input_dev);
91 input_sync(keypad->input_dev); 68
92 69 input_event(input_dev, EV_MSC, MSC_SCAN, code);
93 input_report_key(keypad->input_dev, val, 0); 70 input_report_key(input_dev, key, 0);
94 71 input_sync(input_dev);
95 input_sync(keypad->input_dev);
96} 72}
97 73
98static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id) 74static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id)
@@ -113,7 +89,7 @@ static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id)
113static int w90p910_keypad_open(struct input_dev *dev) 89static int w90p910_keypad_open(struct input_dev *dev)
114{ 90{
115 struct w90p910_keypad *keypad = input_get_drvdata(dev); 91 struct w90p910_keypad *keypad = input_get_drvdata(dev);
116 struct w90p910_keypad_platform_data *pdata = keypad->pdata; 92 const struct w90p910_keypad_platform_data *pdata = keypad->pdata;
117 unsigned int val, config; 93 unsigned int val, config;
118 94
119 /* Enable unit clock */ 95 /* Enable unit clock */
@@ -142,31 +118,39 @@ static void w90p910_keypad_close(struct input_dev *dev)
142 118
143static int __devinit w90p910_keypad_probe(struct platform_device *pdev) 119static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
144{ 120{
121 const struct w90p910_keypad_platform_data *pdata =
122 pdev->dev.platform_data;
123 const struct matrix_keymap_data *keymap_data = pdata->keymap_data;
145 struct w90p910_keypad *keypad; 124 struct w90p910_keypad *keypad;
146 struct input_dev *input_dev; 125 struct input_dev *input_dev;
147 struct resource *res; 126 struct resource *res;
148 int irq, error; 127 int irq;
149 128 int error;
150 keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL); 129 int i;
151 if (keypad == NULL) {
152 dev_err(&pdev->dev, "failed to allocate driver data\n");
153 return -ENOMEM;
154 }
155 130
156 keypad->pdata = pdev->dev.platform_data; 131 if (!pdata) {
157 if (keypad->pdata == NULL) {
158 dev_err(&pdev->dev, "no platform data defined\n"); 132 dev_err(&pdev->dev, "no platform data defined\n");
159 error = -EINVAL; 133 return -EINVAL;
160 goto failed_free;
161 } 134 }
162 135
163 irq = platform_get_irq(pdev, 0); 136 irq = platform_get_irq(pdev, 0);
164 if (irq < 0) { 137 if (irq < 0) {
165 dev_err(&pdev->dev, "failed to get keypad irq\n"); 138 dev_err(&pdev->dev, "failed to get keypad irq\n");
166 error = -ENXIO; 139 return -ENXIO;
140 }
141
142 keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL);
143 input_dev = input_allocate_device();
144 if (!keypad || !input_dev) {
145 dev_err(&pdev->dev, "failed to allocate driver data\n");
146 error = -ENOMEM;
167 goto failed_free; 147 goto failed_free;
168 } 148 }
169 149
150 keypad->pdata = pdata;
151 keypad->input_dev = input_dev;
152 keypad->irq = irq;
153
170 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 154 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
171 if (res == NULL) { 155 if (res == NULL) {
172 dev_err(&pdev->dev, "failed to get I/O memory\n"); 156 dev_err(&pdev->dev, "failed to get I/O memory\n");
@@ -185,7 +169,7 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
185 if (keypad->mmio_base == NULL) { 169 if (keypad->mmio_base == NULL) {
186 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 170 dev_err(&pdev->dev, "failed to remap I/O memory\n");
187 error = -ENXIO; 171 error = -ENXIO;
188 goto failed_free_mem; 172 goto failed_free_res;
189 } 173 }
190 174
191 keypad->clk = clk_get(&pdev->dev, NULL); 175 keypad->clk = clk_get(&pdev->dev, NULL);
@@ -195,14 +179,6 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
195 goto failed_free_io; 179 goto failed_free_io;
196 } 180 }
197 181
198 /* Create and register the input driver. */
199 input_dev = input_allocate_device();
200 if (!input_dev) {
201 dev_err(&pdev->dev, "failed to allocate input device\n");
202 error = -ENOMEM;
203 goto failed_put_clk;
204 }
205
206 /* set multi-function pin for w90p910 kpi. */ 182 /* set multi-function pin for w90p910 kpi. */
207 mfp_set_groupi(&pdev->dev); 183 mfp_set_groupi(&pdev->dev);
208 184
@@ -211,26 +187,37 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
211 input_dev->open = w90p910_keypad_open; 187 input_dev->open = w90p910_keypad_open;
212 input_dev->close = w90p910_keypad_close; 188 input_dev->close = w90p910_keypad_close;
213 input_dev->dev.parent = &pdev->dev; 189 input_dev->dev.parent = &pdev->dev;
214 input_dev->keycode = keypad->matrix_keycodes;
215 input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]);
216 input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes);
217 190
218 keypad->input_dev = input_dev; 191 input_dev->keycode = keypad->keymap;
192 input_dev->keycodesize = sizeof(keypad->keymap[0]);
193 input_dev->keycodemax = ARRAY_SIZE(keypad->keymap);
194
219 input_set_drvdata(input_dev, keypad); 195 input_set_drvdata(input_dev, keypad);
220 196
221 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); 197 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
222 w90p910_keypad_build_keycode(keypad); 198 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
223 platform_set_drvdata(pdev, keypad); 199
200 for (i = 0; i < keymap_data->keymap_size; i++) {
201 unsigned int key = keymap_data->keymap[i];
202 unsigned int row = KEY_ROW(key);
203 unsigned int col = KEY_COL(key);
204 unsigned short keycode = KEY_VAL(key);
205 unsigned int scancode = MATRIX_SCAN_CODE(row, col,
206 W90P910_ROW_SHIFT);
207
208 keypad->keymap[scancode] = keycode;
209 __set_bit(keycode, input_dev->keybit);
210 }
211 __clear_bit(KEY_RESERVED, input_dev->keybit);
212
224 213
225 error = request_irq(irq, w90p910_keypad_irq_handler, IRQF_DISABLED, 214 error = request_irq(keypad->irq, w90p910_keypad_irq_handler,
226 pdev->name, keypad); 215 IRQF_DISABLED, pdev->name, keypad);
227 if (error) { 216 if (error) {
228 dev_err(&pdev->dev, "failed to request IRQ\n"); 217 dev_err(&pdev->dev, "failed to request IRQ\n");
229 goto failed_free_dev; 218 goto failed_put_clk;
230 } 219 }
231 220
232 keypad->irq = irq;
233
234 /* Register the input device */ 221 /* Register the input device */
235 error = input_register_device(input_dev); 222 error = input_register_device(input_dev);
236 if (error) { 223 if (error) {
@@ -238,20 +225,19 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
238 goto failed_free_irq; 225 goto failed_free_irq;
239 } 226 }
240 227
228 platform_set_drvdata(pdev, keypad);
241 return 0; 229 return 0;
242 230
243failed_free_irq: 231failed_free_irq:
244 free_irq(irq, pdev); 232 free_irq(irq, pdev);
245 platform_set_drvdata(pdev, NULL);
246failed_free_dev:
247 input_free_device(input_dev);
248failed_put_clk: 233failed_put_clk:
249 clk_put(keypad->clk); 234 clk_put(keypad->clk);
250failed_free_io: 235failed_free_io:
251 iounmap(keypad->mmio_base); 236 iounmap(keypad->mmio_base);
252failed_free_mem: 237failed_free_res:
253 release_mem_region(res->start, resource_size(res)); 238 release_mem_region(res->start, resource_size(res));
254failed_free: 239failed_free:
240 input_free_device(input_dev);
255 kfree(keypad); 241 kfree(keypad);
256 return error; 242 return error;
257} 243}
@@ -268,12 +254,12 @@ static int __devexit w90p910_keypad_remove(struct platform_device *pdev)
268 input_unregister_device(keypad->input_dev); 254 input_unregister_device(keypad->input_dev);
269 255
270 iounmap(keypad->mmio_base); 256 iounmap(keypad->mmio_base);
271
272 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 257 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
273 release_mem_region(res->start, resource_size(res)); 258 release_mem_region(res->start, resource_size(res));
274 259
275 platform_set_drvdata(pdev, NULL); 260 platform_set_drvdata(pdev, NULL);
276 kfree(keypad); 261 kfree(keypad);
262
277 return 0; 263 return 0;
278} 264}
279 265