diff options
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/ads7846.c | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index b45a45ca7cc9..72cf0a26d676 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -60,7 +60,7 @@ struct ts_event { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct ads7846 { | 62 | struct ads7846 { |
63 | struct input_dev input; | 63 | struct input_dev *input; |
64 | char phys[32]; | 64 | char phys[32]; |
65 | 65 | ||
66 | struct spi_device *spi; | 66 | struct spi_device *spi; |
@@ -152,7 +152,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
152 | struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); | 152 | struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); |
153 | int status; | 153 | int status; |
154 | int sample; | 154 | int sample; |
155 | int i; | 155 | int i; |
156 | 156 | ||
157 | if (!req) | 157 | if (!req) |
158 | return -ENOMEM; | 158 | return -ENOMEM; |
@@ -236,11 +236,12 @@ SHOW(vbatt) | |||
236 | 236 | ||
237 | static void ads7846_rx(void *ads) | 237 | static void ads7846_rx(void *ads) |
238 | { | 238 | { |
239 | struct ads7846 *ts = ads; | 239 | struct ads7846 *ts = ads; |
240 | unsigned Rt; | 240 | struct input_dev *input_dev = ts->input; |
241 | unsigned sync = 0; | 241 | unsigned Rt; |
242 | u16 x, y, z1, z2; | 242 | unsigned sync = 0; |
243 | unsigned long flags; | 243 | u16 x, y, z1, z2; |
244 | unsigned long flags; | ||
244 | 245 | ||
245 | /* adjust: 12 bit samples (left aligned), built from | 246 | /* adjust: 12 bit samples (left aligned), built from |
246 | * two 8 bit values writen msb-first. | 247 | * two 8 bit values writen msb-first. |
@@ -276,21 +277,21 @@ static void ads7846_rx(void *ads) | |||
276 | * won't notice that, even if nPENIRQ never fires ... | 277 | * won't notice that, even if nPENIRQ never fires ... |
277 | */ | 278 | */ |
278 | if (!ts->pendown && Rt != 0) { | 279 | if (!ts->pendown && Rt != 0) { |
279 | input_report_key(&ts->input, BTN_TOUCH, 1); | 280 | input_report_key(input_dev, BTN_TOUCH, 1); |
280 | sync = 1; | 281 | sync = 1; |
281 | } else if (ts->pendown && Rt == 0) { | 282 | } else if (ts->pendown && Rt == 0) { |
282 | input_report_key(&ts->input, BTN_TOUCH, 0); | 283 | input_report_key(input_dev, BTN_TOUCH, 0); |
283 | sync = 1; | 284 | sync = 1; |
284 | } | 285 | } |
285 | 286 | ||
286 | if (Rt) { | 287 | if (Rt) { |
287 | input_report_abs(&ts->input, ABS_X, x); | 288 | input_report_abs(input_dev, ABS_X, x); |
288 | input_report_abs(&ts->input, ABS_Y, y); | 289 | input_report_abs(input_dev, ABS_Y, y); |
289 | input_report_abs(&ts->input, ABS_PRESSURE, Rt); | 290 | input_report_abs(input_dev, ABS_PRESSURE, Rt); |
290 | sync = 1; | 291 | sync = 1; |
291 | } | 292 | } |
292 | if (sync) | 293 | if (sync) |
293 | input_sync(&ts->input); | 294 | input_sync(input_dev); |
294 | 295 | ||
295 | #ifdef VERBOSE | 296 | #ifdef VERBOSE |
296 | if (Rt || ts->pendown) | 297 | if (Rt || ts->pendown) |
@@ -396,9 +397,11 @@ static int ads7846_resume(struct spi_device *spi) | |||
396 | static int __devinit ads7846_probe(struct spi_device *spi) | 397 | static int __devinit ads7846_probe(struct spi_device *spi) |
397 | { | 398 | { |
398 | struct ads7846 *ts; | 399 | struct ads7846 *ts; |
400 | struct input_dev *input_dev; | ||
399 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 401 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
400 | struct spi_transfer *x; | 402 | struct spi_transfer *x; |
401 | int i; | 403 | int i; |
404 | int err; | ||
402 | 405 | ||
403 | if (!spi->irq) { | 406 | if (!spi->irq) { |
404 | dev_dbg(&spi->dev, "no IRQ?\n"); | 407 | dev_dbg(&spi->dev, "no IRQ?\n"); |
@@ -423,13 +426,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
423 | * to discard the four garbage LSBs. | 426 | * to discard the four garbage LSBs. |
424 | */ | 427 | */ |
425 | 428 | ||
426 | if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL))) | 429 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); |
427 | return -ENOMEM; | 430 | input_dev = input_allocate_device(); |
431 | if (!ts || !input_dev) { | ||
432 | err = -ENOMEM; | ||
433 | goto err_free_mem; | ||
434 | } | ||
428 | 435 | ||
429 | dev_set_drvdata(&spi->dev, ts); | 436 | dev_set_drvdata(&spi->dev, ts); |
437 | spi->dev.power.power_state = PMSG_ON; | ||
430 | 438 | ||
431 | ts->spi = spi; | 439 | ts->spi = spi; |
432 | spi->dev.power.power_state = PMSG_ON; | 440 | ts->input = input_dev; |
433 | 441 | ||
434 | init_timer(&ts->timer); | 442 | init_timer(&ts->timer); |
435 | ts->timer.data = (unsigned long) ts; | 443 | ts->timer.data = (unsigned long) ts; |
@@ -439,28 +447,25 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
439 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | 447 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; |
440 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | 448 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
441 | 449 | ||
442 | init_input_dev(&ts->input); | 450 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); |
443 | 451 | ||
444 | ts->input.dev = &spi->dev; | 452 | input_dev->name = "ADS784x Touchscreen"; |
445 | ts->input.name = "ADS784x Touchscreen"; | 453 | input_dev->phys = ts->phys; |
446 | snprintf(ts->phys, sizeof ts->phys, "%s/input0", spi->dev.bus_id); | 454 | input_dev->cdev.dev = &spi->dev; |
447 | ts->input.phys = ts->phys; | ||
448 | 455 | ||
449 | ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 456 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
450 | ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 457 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
451 | input_set_abs_params(&ts->input, ABS_X, | 458 | input_set_abs_params(input_dev, ABS_X, |
452 | pdata->x_min ? : 0, | 459 | pdata->x_min ? : 0, |
453 | pdata->x_max ? : MAX_12BIT, | 460 | pdata->x_max ? : MAX_12BIT, |
454 | 0, 0); | 461 | 0, 0); |
455 | input_set_abs_params(&ts->input, ABS_Y, | 462 | input_set_abs_params(input_dev, ABS_Y, |
456 | pdata->y_min ? : 0, | 463 | pdata->y_min ? : 0, |
457 | pdata->y_max ? : MAX_12BIT, | 464 | pdata->y_max ? : MAX_12BIT, |
458 | 0, 0); | 465 | 0, 0); |
459 | input_set_abs_params(&ts->input, ABS_PRESSURE, | 466 | input_set_abs_params(input_dev, ABS_PRESSURE, |
460 | pdata->pressure_min, pdata->pressure_max, 0, 0); | 467 | pdata->pressure_min, pdata->pressure_max, 0, 0); |
461 | 468 | ||
462 | input_register_device(&ts->input); | ||
463 | |||
464 | /* set up the transfers to read touchscreen state; this assumes we | 469 | /* set up the transfers to read touchscreen state; this assumes we |
465 | * use formula #2 for pressure, not #3. | 470 | * use formula #2 for pressure, not #3. |
466 | */ | 471 | */ |
@@ -510,9 +515,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
510 | SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, | 515 | SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, |
511 | spi->dev.bus_id, ts)) { | 516 | spi->dev.bus_id, ts)) { |
512 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 517 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
513 | input_unregister_device(&ts->input); | 518 | err = -EBUSY; |
514 | kfree(ts); | 519 | goto err_free_mem; |
515 | return -EBUSY; | ||
516 | } | 520 | } |
517 | 521 | ||
518 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); | 522 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); |
@@ -534,7 +538,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
534 | device_create_file(&spi->dev, &dev_attr_vbatt); | 538 | device_create_file(&spi->dev, &dev_attr_vbatt); |
535 | device_create_file(&spi->dev, &dev_attr_vaux); | 539 | device_create_file(&spi->dev, &dev_attr_vaux); |
536 | 540 | ||
541 | err = input_register_device(input_dev); | ||
542 | if (err) | ||
543 | goto err_free_irq; | ||
544 | |||
537 | return 0; | 545 | return 0; |
546 | |||
547 | err_free_irq: | ||
548 | free_irq(spi->irq, ts); | ||
549 | err_free_mem: | ||
550 | input_free_device(input_dev); | ||
551 | kfree(ts); | ||
552 | return err; | ||
538 | } | 553 | } |
539 | 554 | ||
540 | static int __devexit ads7846_remove(struct spi_device *spi) | 555 | static int __devexit ads7846_remove(struct spi_device *spi) |
@@ -554,7 +569,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
554 | device_remove_file(&spi->dev, &dev_attr_vbatt); | 569 | device_remove_file(&spi->dev, &dev_attr_vbatt); |
555 | device_remove_file(&spi->dev, &dev_attr_vaux); | 570 | device_remove_file(&spi->dev, &dev_attr_vaux); |
556 | 571 | ||
557 | input_unregister_device(&ts->input); | 572 | input_unregister_device(ts->input); |
558 | kfree(ts); | 573 | kfree(ts); |
559 | 574 | ||
560 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 575 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |