aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-03-17 01:09:38 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-03-17 02:28:55 -0400
commit99bb892d8a3f4f384d61e5d20499247a7cdd3d74 (patch)
tree9bf03301750c8c21a43dc15a0f4682d2e0de2b41
parentf8a67139c68eb8a58907906622c9aa02cd6a1dd1 (diff)
Input: tsc2005 - rework driver initialization code
We need to make sure we have time/work initialized before requesting and enabling interrupts, otherwise we might start using them way too early. Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/touchscreen/tsc2005.c215
1 files changed, 105 insertions, 110 deletions
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c
index 09cbcb0b19fe..de170e9dc54a 100644
--- a/drivers/input/touchscreen/tsc2005.c
+++ b/drivers/input/touchscreen/tsc2005.c
@@ -495,6 +495,16 @@ out:
495 mutex_unlock(&ts->mutex); 495 mutex_unlock(&ts->mutex);
496} 496}
497 497
498static struct attribute *tsc2005_attrs[] = {
499 &dev_attr_disable.attr,
500 &dev_attr_selftest.attr,
501 NULL
502};
503
504static struct attribute_group tsc2005_attr_group = {
505 .attrs = tsc2005_attrs,
506};
507
498static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts) 508static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts)
499{ 509{
500 tsc2005_setup_read(&ts->spi_x, TSC2005_REG_X, 0); 510 tsc2005_setup_read(&ts->spi_x, TSC2005_REG_X, 0);
@@ -509,144 +519,130 @@ static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts)
509 spi_message_add_tail(&ts->spi_z2.spi_xfer, &ts->spi_read_msg); 519 spi_message_add_tail(&ts->spi_z2.spi_xfer, &ts->spi_read_msg);
510} 520}
511 521
512static struct attribute *tsc2005_attrs[] = { 522static int __devinit tsc2005_probe(struct spi_device *spi)
513 &dev_attr_disable.attr,
514 &dev_attr_selftest.attr,
515 NULL
516};
517
518static struct attribute_group tsc2005_attr_group = {
519 .attrs = tsc2005_attrs,
520};
521
522static int __devinit tsc2005_setup(struct tsc2005 *ts,
523 struct tsc2005_platform_data *pdata)
524{ 523{
525 int r; 524 const struct tsc2005_platform_data *pdata = spi->dev.platform_data;
526 int fudge_x; 525 struct tsc2005 *ts;
527 int fudge_y; 526 struct input_dev *input_dev;
528 int fudge_p; 527 unsigned int max_x, max_y, max_p;
529 int p_max; 528 unsigned int fudge_x, fudge_y, fudge_p;
530 int x_max; 529 int error;
531 int y_max;
532 530
533 mutex_init(&ts->mutex); 531 if (!pdata) {
532 dev_dbg(&spi->dev, "no platform data\n");
533 return -ENODEV;
534 }
534 535
535 tsc2005_setup_spi_xfer(ts); 536 fudge_x = pdata->ts_x_fudge ? : 4;
537 fudge_y = pdata->ts_y_fudge ? : 8;
538 fudge_p = pdata->ts_pressure_fudge ? : 2;
539 max_x = pdata->ts_x_max ? : MAX_12BIT;
540 max_y = pdata->ts_y_max ? : MAX_12BIT;
541 max_p = pdata->ts_pressure_max ? : MAX_12BIT;
536 542
537 init_timer(&ts->penup_timer); 543 if (spi->irq <= 0) {
538 setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts); 544 dev_dbg(&spi->dev, "no irq\n");
539 INIT_WORK(&ts->penup_work, tsc2005_penup_work); 545 return -ENODEV;
546 }
540 547
541 fudge_x = pdata->ts_x_fudge ? : 4; 548 spi->mode = SPI_MODE_0;
542 fudge_y = pdata->ts_y_fudge ? : 8; 549 spi->bits_per_word = 8;
543 fudge_p = pdata->ts_pressure_fudge ? : 2; 550 if (!spi->max_speed_hz)
544 x_max = pdata->ts_x_max ? : MAX_12BIT; 551 spi->max_speed_hz = TSC2005_SPI_MAX_SPEED_HZ;
545 y_max = pdata->ts_y_max ? : MAX_12BIT;
546 p_max = pdata->ts_pressure_max ? : MAX_12BIT;
547 ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280;
548 ts->esd_timeout = pdata->esd_timeout_ms;
549 ts->set_reset = pdata->set_reset;
550 552
551 ts->idev = input_allocate_device(); 553 error = spi_setup(spi);
552 if (ts->idev == NULL) 554 if (error)
553 return -ENOMEM; 555 return error;
554 ts->idev->name = "TSC2005 touchscreen";
555 snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts",
556 dev_name(&ts->spi->dev));
557 ts->idev->phys = ts->phys;
558 ts->idev->id.bustype = BUS_SPI;
559 ts->idev->dev.parent = &ts->spi->dev;
560 ts->idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
561 ts->idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
562 ts->idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
563
564 input_set_abs_params(ts->idev, ABS_X, 0, x_max, fudge_x, 0);
565 input_set_abs_params(ts->idev, ABS_Y, 0, y_max, fudge_y, 0);
566 input_set_abs_params(ts->idev, ABS_PRESSURE, 0, p_max, fudge_p, 0);
567
568 r = request_threaded_irq(ts->spi->irq, tsc2005_irq_handler,
569 tsc2005_irq_thread, IRQF_TRIGGER_RISING,
570 "tsc2005", ts);
571 if (r) {
572 dev_err(&ts->spi->dev, "request_threaded_irq(): %d\n", r);
573 goto err1;
574 }
575 set_irq_wake(ts->spi->irq, 1);
576 556
577 r = input_register_device(ts->idev); 557 ts = kzalloc(sizeof(*ts), GFP_KERNEL);
578 if (r) { 558 input_dev = input_allocate_device();
579 dev_err(&ts->spi->dev, "input_register_device(): %d\n", r); 559 if (!ts || !input_dev) {
580 goto err2; 560 error = -ENOMEM;
561 goto err_free_mem;
581 } 562 }
582 563
583 r = sysfs_create_group(&ts->spi->dev.kobj, &tsc2005_attr_group); 564 ts->spi = spi;
584 if (r) 565 ts->idev = input_dev;
585 dev_warn(&ts->spi->dev, "sysfs entry creation failed: %d\n", r); 566
567 ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280;
568 ts->esd_timeout = pdata->esd_timeout_ms;
569 ts->set_reset = pdata->set_reset;
586 570
587 tsc2005_start_scan(ts); 571 mutex_init(&ts->mutex);
588 572
589 if (!ts->esd_timeout || !ts->set_reset) 573 setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts);
590 goto done; 574 INIT_WORK(&ts->penup_work, tsc2005_penup_work);
591 575
592 /* start the optional ESD watchdog */
593 setup_timer(&ts->esd_timer, tsc2005_esd_timer, (unsigned long)ts); 576 setup_timer(&ts->esd_timer, tsc2005_esd_timer, (unsigned long)ts);
594 INIT_WORK(&ts->esd_work, tsc2005_esd_work); 577 INIT_WORK(&ts->esd_work, tsc2005_esd_work);
595 mod_timer(&ts->esd_timer,
596 round_jiffies(jiffies + msecs_to_jiffies(ts->esd_timeout)));
597
598done:
599 return 0;
600 578
601err2: 579 tsc2005_setup_spi_xfer(ts);
602 free_irq(ts->spi->irq, ts);
603
604err1:
605 input_free_device(ts->idev);
606 return r;
607}
608
609static int __devinit tsc2005_probe(struct spi_device *spi)
610{
611 struct tsc2005_platform_data *pdata = spi->dev.platform_data;
612 struct tsc2005 *ts;
613 int r;
614 580
615 if (spi->irq < 0) { 581 snprintf(ts->phys, sizeof(ts->phys),
616 dev_dbg(&spi->dev, "no irq\n"); 582 "%s/input-ts", dev_name(&spi->dev));
617 return -ENODEV; 583
584 input_dev->name = "TSC2005 touchscreen";
585 input_dev->phys = ts->phys;
586 input_dev->id.bustype = BUS_SPI;
587 input_dev->dev.parent = &spi->dev;
588 input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
589 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
590
591 input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);
592 input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
593 input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
594
595 error = request_threaded_irq(spi->irq,
596 tsc2005_irq_handler, tsc2005_irq_thread,
597 IRQF_TRIGGER_RISING, "tsc2005", ts);
598 if (error) {
599 dev_err(&spi->dev, "Failed to request irq, err: %d\n", error);
600 goto err_free_mem;
618 } 601 }
619 602
620 if (!pdata) { 603 spi_set_drvdata(spi, ts);
621 dev_dbg(&spi->dev, "no platform data\n"); 604 error = sysfs_create_group(&spi->dev.kobj, &tsc2005_attr_group);
622 return -ENODEV; 605 if (error) {
606 dev_err(&spi->dev,
607 "Failed to create sysfs attributes, err: %d\n", error);
608 goto err_clear_drvdata;
623 } 609 }
624 610
625 ts = kzalloc(sizeof(*ts), GFP_KERNEL); 611 error = input_register_device(ts->idev);
626 if (ts == NULL) 612 if (error) {
627 return -ENOMEM; 613 dev_err(&spi->dev,
614 "Failed to register input device, err: %d\n", error);
615 goto err_remove_sysfs;
616 }
628 617
629 spi_set_drvdata(spi, ts); 618 tsc2005_start_scan(ts);
630 ts->spi = spi;
631 spi->dev.power.power_state = PMSG_ON;
632 spi->mode = SPI_MODE_0;
633 spi->bits_per_word = 8;
634 if (!spi->max_speed_hz)
635 spi->max_speed_hz = TSC2005_SPI_MAX_SPEED_HZ;
636 spi_setup(spi);
637 619
638 r = tsc2005_setup(ts, pdata); 620 if (ts->esd_timeout && ts->set_reset) {
639 if (r) { 621 /* start the optional ESD watchdog */
640 kfree(ts); 622 mod_timer(&ts->esd_timer, round_jiffies(jiffies +
641 spi_set_drvdata(spi, NULL); 623 msecs_to_jiffies(ts->esd_timeout)));
642 } 624 }
643 return r; 625
626 set_irq_wake(spi->irq, 1);
627 return 0;
628
629err_remove_sysfs:
630 sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group);
631err_clear_drvdata:
632 spi_set_drvdata(spi, NULL);
633 free_irq(spi->irq, ts);
634err_free_mem:
635 input_free_device(input_dev);
636 kfree(ts);
637 return error;
644} 638}
645 639
646static int __devexit tsc2005_remove(struct spi_device *spi) 640static int __devexit tsc2005_remove(struct spi_device *spi)
647{ 641{
648 struct tsc2005 *ts = spi_get_drvdata(spi); 642 struct tsc2005 *ts = spi_get_drvdata(spi);
649 643
644 sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group);
645
650 mutex_lock(&ts->mutex); 646 mutex_lock(&ts->mutex);
651 tsc2005_disable(ts); 647 tsc2005_disable(ts);
652 mutex_unlock(&ts->mutex); 648 mutex_unlock(&ts->mutex);
@@ -658,7 +654,6 @@ static int __devexit tsc2005_remove(struct spi_device *spi)
658 flush_work(&ts->esd_work); 654 flush_work(&ts->esd_work);
659 flush_work(&ts->penup_work); 655 flush_work(&ts->penup_work);
660 656
661 sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group);
662 free_irq(ts->spi->irq, ts); 657 free_irq(ts->spi->irq, ts);
663 input_unregister_device(ts->idev); 658 input_unregister_device(ts->idev);
664 kfree(ts); 659 kfree(ts);