diff options
Diffstat (limited to 'drivers/input/keyboard/stmpe-keypad.c')
-rw-r--r-- | drivers/input/keyboard/stmpe-keypad.c | 142 |
1 files changed, 84 insertions, 58 deletions
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index 470a8778dec1..5cbec56f7720 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c | |||
@@ -166,7 +166,7 @@ static irqreturn_t stmpe_keypad_irq(int irq, void *dev) | |||
166 | return IRQ_HANDLED; | 166 | return IRQ_HANDLED; |
167 | } | 167 | } |
168 | 168 | ||
169 | static int __devinit stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | 169 | static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) |
170 | { | 170 | { |
171 | const struct stmpe_keypad_variant *variant = keypad->variant; | 171 | const struct stmpe_keypad_variant *variant = keypad->variant; |
172 | unsigned int col_gpios = variant->col_gpios; | 172 | unsigned int col_gpios = variant->col_gpios; |
@@ -207,7 +207,7 @@ static int __devinit stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
207 | return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); | 207 | return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); |
208 | } | 208 | } |
209 | 209 | ||
210 | static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | 210 | static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) |
211 | { | 211 | { |
212 | const struct stmpe_keypad_platform_data *plat = keypad->plat; | 212 | const struct stmpe_keypad_platform_data *plat = keypad->plat; |
213 | const struct stmpe_keypad_variant *variant = keypad->variant; | 213 | const struct stmpe_keypad_variant *variant = keypad->variant; |
@@ -257,105 +257,131 @@ static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | |||
257 | (plat->debounce_ms << 1)); | 257 | (plat->debounce_ms << 1)); |
258 | } | 258 | } |
259 | 259 | ||
260 | static int __devinit stmpe_keypad_probe(struct platform_device *pdev) | 260 | static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) |
261 | { | 261 | { |
262 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | 262 | int row, col; |
263 | |||
264 | for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) { | ||
265 | for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) { | ||
266 | int code = MATRIX_SCAN_CODE(row, col, | ||
267 | STMPE_KEYPAD_ROW_SHIFT); | ||
268 | if (keypad->keymap[code] != KEY_RESERVED) { | ||
269 | keypad->rows |= 1 << row; | ||
270 | keypad->cols |= 1 << col; | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | |||
276 | #ifdef CONFIG_OF | ||
277 | static const struct stmpe_keypad_platform_data * | ||
278 | stmpe_keypad_of_probe(struct device *dev) | ||
279 | { | ||
280 | struct device_node *np = dev->of_node; | ||
263 | struct stmpe_keypad_platform_data *plat; | 281 | struct stmpe_keypad_platform_data *plat; |
282 | |||
283 | if (!np) | ||
284 | return ERR_PTR(-ENODEV); | ||
285 | |||
286 | plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); | ||
287 | if (!plat) | ||
288 | return ERR_PTR(-ENOMEM); | ||
289 | |||
290 | of_property_read_u32(np, "debounce-interval", &plat->debounce_ms); | ||
291 | of_property_read_u32(np, "st,scan-count", &plat->scan_count); | ||
292 | |||
293 | plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat"); | ||
294 | |||
295 | return plat; | ||
296 | } | ||
297 | #else | ||
298 | static inline const struct stmpe_keypad_platform_data * | ||
299 | stmpe_keypad_of_probe(struct device *dev) | ||
300 | { | ||
301 | return ERR_PTR(-EINVAL); | ||
302 | } | ||
303 | #endif | ||
304 | |||
305 | static int stmpe_keypad_probe(struct platform_device *pdev) | ||
306 | { | ||
307 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | ||
308 | const struct stmpe_keypad_platform_data *plat; | ||
264 | struct stmpe_keypad *keypad; | 309 | struct stmpe_keypad *keypad; |
265 | struct input_dev *input; | 310 | struct input_dev *input; |
266 | int ret; | 311 | int error; |
267 | int irq; | 312 | int irq; |
268 | int i; | ||
269 | 313 | ||
270 | plat = stmpe->pdata->keypad; | 314 | plat = stmpe->pdata->keypad; |
271 | if (!plat) | 315 | if (!plat) { |
272 | return -ENODEV; | 316 | plat = stmpe_keypad_of_probe(&pdev->dev); |
317 | if (IS_ERR(plat)) | ||
318 | return PTR_ERR(plat); | ||
319 | } | ||
273 | 320 | ||
274 | irq = platform_get_irq(pdev, 0); | 321 | irq = platform_get_irq(pdev, 0); |
275 | if (irq < 0) | 322 | if (irq < 0) |
276 | return irq; | 323 | return irq; |
277 | 324 | ||
278 | keypad = kzalloc(sizeof(struct stmpe_keypad), GFP_KERNEL); | 325 | keypad = devm_kzalloc(&pdev->dev, sizeof(struct stmpe_keypad), |
326 | GFP_KERNEL); | ||
279 | if (!keypad) | 327 | if (!keypad) |
280 | return -ENOMEM; | 328 | return -ENOMEM; |
281 | 329 | ||
282 | input = input_allocate_device(); | 330 | input = devm_input_allocate_device(&pdev->dev); |
283 | if (!input) { | 331 | if (!input) |
284 | ret = -ENOMEM; | 332 | return -ENOMEM; |
285 | goto out_freekeypad; | ||
286 | } | ||
287 | 333 | ||
288 | input->name = "STMPE keypad"; | 334 | input->name = "STMPE keypad"; |
289 | input->id.bustype = BUS_I2C; | 335 | input->id.bustype = BUS_I2C; |
290 | input->dev.parent = &pdev->dev; | 336 | input->dev.parent = &pdev->dev; |
291 | 337 | ||
292 | ret = matrix_keypad_build_keymap(plat->keymap_data, NULL, | 338 | error = matrix_keypad_build_keymap(plat->keymap_data, NULL, |
293 | STMPE_KEYPAD_MAX_ROWS, | 339 | STMPE_KEYPAD_MAX_ROWS, |
294 | STMPE_KEYPAD_MAX_COLS, | 340 | STMPE_KEYPAD_MAX_COLS, |
295 | keypad->keymap, input); | 341 | keypad->keymap, input); |
296 | if (ret) | 342 | if (error) |
297 | goto out_freeinput; | 343 | return error; |
298 | 344 | ||
299 | input_set_capability(input, EV_MSC, MSC_SCAN); | 345 | input_set_capability(input, EV_MSC, MSC_SCAN); |
300 | if (!plat->no_autorepeat) | 346 | if (!plat->no_autorepeat) |
301 | __set_bit(EV_REP, input->evbit); | 347 | __set_bit(EV_REP, input->evbit); |
302 | 348 | ||
303 | for (i = 0; i < plat->keymap_data->keymap_size; i++) { | 349 | stmpe_keypad_fill_used_pins(keypad); |
304 | unsigned int key = plat->keymap_data->keymap[i]; | ||
305 | |||
306 | keypad->cols |= 1 << KEY_COL(key); | ||
307 | keypad->rows |= 1 << KEY_ROW(key); | ||
308 | } | ||
309 | 350 | ||
310 | keypad->stmpe = stmpe; | 351 | keypad->stmpe = stmpe; |
311 | keypad->plat = plat; | 352 | keypad->plat = plat; |
312 | keypad->input = input; | 353 | keypad->input = input; |
313 | keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; | 354 | keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; |
314 | 355 | ||
315 | ret = stmpe_keypad_chip_init(keypad); | 356 | error = stmpe_keypad_chip_init(keypad); |
316 | if (ret < 0) | 357 | if (error < 0) |
317 | goto out_freeinput; | 358 | return error; |
318 | 359 | ||
319 | ret = input_register_device(input); | 360 | error = devm_request_threaded_irq(&pdev->dev, irq, |
320 | if (ret) { | 361 | NULL, stmpe_keypad_irq, |
321 | dev_err(&pdev->dev, | 362 | IRQF_ONESHOT, "stmpe-keypad", keypad); |
322 | "unable to register input device: %d\n", ret); | 363 | if (error) { |
323 | goto out_freeinput; | 364 | dev_err(&pdev->dev, "unable to get irq: %d\n", error); |
365 | return error; | ||
324 | } | 366 | } |
325 | 367 | ||
326 | ret = request_threaded_irq(irq, NULL, stmpe_keypad_irq, IRQF_ONESHOT, | 368 | error = input_register_device(input); |
327 | "stmpe-keypad", keypad); | 369 | if (error) { |
328 | if (ret) { | 370 | dev_err(&pdev->dev, |
329 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); | 371 | "unable to register input device: %d\n", error); |
330 | goto out_unregisterinput; | 372 | return error; |
331 | } | 373 | } |
332 | 374 | ||
333 | platform_set_drvdata(pdev, keypad); | 375 | platform_set_drvdata(pdev, keypad); |
334 | 376 | ||
335 | return 0; | 377 | return 0; |
336 | |||
337 | out_unregisterinput: | ||
338 | input_unregister_device(input); | ||
339 | input = NULL; | ||
340 | out_freeinput: | ||
341 | input_free_device(input); | ||
342 | out_freekeypad: | ||
343 | kfree(keypad); | ||
344 | return ret; | ||
345 | } | 378 | } |
346 | 379 | ||
347 | static int __devexit stmpe_keypad_remove(struct platform_device *pdev) | 380 | static int stmpe_keypad_remove(struct platform_device *pdev) |
348 | { | 381 | { |
349 | struct stmpe_keypad *keypad = platform_get_drvdata(pdev); | 382 | struct stmpe_keypad *keypad = platform_get_drvdata(pdev); |
350 | struct stmpe *stmpe = keypad->stmpe; | ||
351 | int irq = platform_get_irq(pdev, 0); | ||
352 | |||
353 | stmpe_disable(stmpe, STMPE_BLOCK_KEYPAD); | ||
354 | 383 | ||
355 | free_irq(irq, keypad); | 384 | stmpe_disable(keypad->stmpe, STMPE_BLOCK_KEYPAD); |
356 | input_unregister_device(keypad->input); | ||
357 | platform_set_drvdata(pdev, NULL); | ||
358 | kfree(keypad); | ||
359 | 385 | ||
360 | return 0; | 386 | return 0; |
361 | } | 387 | } |
@@ -364,7 +390,7 @@ static struct platform_driver stmpe_keypad_driver = { | |||
364 | .driver.name = "stmpe-keypad", | 390 | .driver.name = "stmpe-keypad", |
365 | .driver.owner = THIS_MODULE, | 391 | .driver.owner = THIS_MODULE, |
366 | .probe = stmpe_keypad_probe, | 392 | .probe = stmpe_keypad_probe, |
367 | .remove = __devexit_p(stmpe_keypad_remove), | 393 | .remove = stmpe_keypad_remove, |
368 | }; | 394 | }; |
369 | module_platform_driver(stmpe_keypad_driver); | 395 | module_platform_driver(stmpe_keypad_driver); |
370 | 396 | ||