aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/ads7846.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@nokia.com>2006-04-11 23:43:55 -0400
committerDmitry Torokhov <dtor_core@ameritech.net>2006-04-11 23:43:55 -0400
commit7de90a8cb9c51145d7f60d8db17ce0fa07d1b281 (patch)
tree81e2c0a54974c0a552474f5c5cc66d6082a8bfdd /drivers/input/touchscreen/ads7846.c
parentc4febb94dae915da4423b81c487eabed9cef5cba (diff)
Input: ads7846 - miscellaneous fixes
- Add disable attribute to support device locking mode where unintentional touch event shouldn't wake up the system; - Update comments; - Add missing spin_lock_init; - Do device resume with the lock held; - Do cleanup calls / free memory in the reverse order of initialization. Signed-off-by: Imre Deak <imre.deak@nokia.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/touchscreen/ads7846.c')
-rw-r--r--drivers/input/touchscreen/ads7846.c144
1 files changed, 114 insertions, 30 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index bdec112e89c4..fec3b9b22309 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -2,6 +2,8 @@
2 * ADS7846 based touchscreen and sensor driver 2 * ADS7846 based touchscreen and sensor driver
3 * 3 *
4 * Copyright (c) 2005 David Brownell 4 * Copyright (c) 2005 David Brownell
5 * Copyright (c) 2006 Nokia Corporation
6 * Various changes: Imre Deak <imre.deak@nokia.com>
5 * 7 *
6 * Using code from: 8 * Using code from:
7 * - corgi_ts.c 9 * - corgi_ts.c
@@ -34,17 +36,25 @@
34 36
35 37
36/* 38/*
37 * This code has been lightly tested on an ads7846. 39 * This code has been tested on an ads7846 / N770 device.
38 * Support for ads7843 and ads7845 has only been stubbed in. 40 * Support for ads7843 and ads7845 has only been stubbed in.
39 * 41 *
40 * Not yet done: investigate the values reported. Are x/y/pressure 42 * Not yet done: How accurate are the temperature and voltage
41 * event values sane enough for X11? How accurate are the temperature 43 * readings? (System-specific calibration should support
42 * and voltage readings? (System-specific calibration should support
43 * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.) 44 * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
44 * 45 *
46 * IRQ handling needs a workaround because of a shortcoming in handling
47 * edge triggered IRQs on some platforms like the OMAP1/2. These
48 * platforms don't handle the ARM lazy IRQ disabling properly, thus we
49 * have to maintain our own SW IRQ disabled status. This should be
50 * removed as soon as the affected platform's IRQ handling is fixed.
51 *
45 * app note sbaa036 talks in more detail about accurate sampling... 52 * app note sbaa036 talks in more detail about accurate sampling...
46 * that ought to help in situations like LCDs inducing noise (which 53 * that ought to help in situations like LCDs inducing noise (which
47 * can also be helped by using synch signals) and more generally. 54 * can also be helped by using synch signals) and more generally.
55 * This driver tries to utilize the measures described in the app
56 * note. The strength of filtering can be set in the board-* specific
57 * files.
48 */ 58 */
49 59
50#define TS_POLL_PERIOD msecs_to_jiffies(10) 60#define TS_POLL_PERIOD msecs_to_jiffies(10)
@@ -91,6 +101,7 @@ struct ads7846 {
91 unsigned pending:1; /* P: lock */ 101 unsigned pending:1; /* P: lock */
92// FIXME remove "irq_disabled" 102// FIXME remove "irq_disabled"
93 unsigned irq_disabled:1; /* P: lock */ 103 unsigned irq_disabled:1; /* P: lock */
104 unsigned disabled:1;
94}; 105};
95 106
96/* leave chip selected when we're done, for quicker re-select? */ 107/* leave chip selected when we're done, for quicker re-select? */
@@ -161,6 +172,9 @@ struct ser_req {
161 struct spi_transfer xfer[6]; 172 struct spi_transfer xfer[6];
162}; 173};
163 174
175static void ads7846_enable(struct ads7846 *ts);
176static void ads7846_disable(struct ads7846 *ts);
177
164static int ads7846_read12_ser(struct device *dev, unsigned command) 178static int ads7846_read12_ser(struct device *dev, unsigned command)
165{ 179{
166 struct spi_device *spi = to_spi_device(dev); 180 struct spi_device *spi = to_spi_device(dev);
@@ -257,6 +271,37 @@ static ssize_t ads7846_pen_down_show(struct device *dev,
257 271
258static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); 272static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL);
259 273
274static ssize_t ads7846_disable_show(struct device *dev,
275 struct device_attribute *attr, char *buf)
276{
277 struct ads7846 *ts = dev_get_drvdata(dev);
278
279 return sprintf(buf, "%u\n", ts->disabled);
280}
281
282static ssize_t ads7846_disable_store(struct device *dev,
283 struct device_attribute *attr,
284 const char *buf, size_t count)
285{
286 struct ads7846 *ts = dev_get_drvdata(dev);
287 char *endp;
288 int i;
289
290 i = simple_strtoul(buf, &endp, 10);
291 spin_lock_irq(&ts->lock);
292
293 if (i)
294 ads7846_disable(ts);
295 else
296 ads7846_enable(ts);
297
298 spin_unlock_irq(&ts->lock);
299
300 return count;
301}
302
303static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
304
260/*--------------------------------------------------------------------------*/ 305/*--------------------------------------------------------------------------*/
261 306
262/* 307/*
@@ -396,12 +441,9 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
396{ 441{
397 struct ads7846 *ts = handle; 442 struct ads7846 *ts = handle;
398 unsigned long flags; 443 unsigned long flags;
399 int r = IRQ_HANDLED;
400 444
401 spin_lock_irqsave(&ts->lock, flags); 445 spin_lock_irqsave(&ts->lock, flags);
402 if (ts->irq_disabled) 446 if (likely(!ts->irq_disabled && !ts->disabled)) {
403 r = IRQ_HANDLED;
404 else {
405 if (!ts->irq_disabled) { 447 if (!ts->irq_disabled) {
406 /* REVISIT irq logic for many ARM chips has cloned a 448 /* REVISIT irq logic for many ARM chips has cloned a
407 * bug wherein disabling an irq in its handler won't 449 * bug wherein disabling an irq in its handler won't
@@ -419,20 +461,17 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
419 } 461 }
420 } 462 }
421 spin_unlock_irqrestore(&ts->lock, flags); 463 spin_unlock_irqrestore(&ts->lock, flags);
422 return r; 464
465 return IRQ_HANDLED;
423} 466}
424 467
425/*--------------------------------------------------------------------------*/ 468/*--------------------------------------------------------------------------*/
426 469
427static int 470/* Must be called with ts->lock held */
428ads7846_suspend(struct spi_device *spi, pm_message_t message) 471static void ads7846_disable(struct ads7846 *ts)
429{ 472{
430 struct ads7846 *ts = dev_get_drvdata(&spi->dev); 473 if (ts->disabled)
431 unsigned long flags; 474 return;
432
433 spin_lock_irqsave(&ts->lock, flags);
434
435 spi->dev.power.power_state = message;
436 475
437 /* are we waiting for IRQ, or polling? */ 476 /* are we waiting for IRQ, or polling? */
438 if (!ts->pendown) { 477 if (!ts->pendown) {
@@ -448,9 +487,9 @@ ads7846_suspend(struct spi_device *spi, pm_message_t message)
448 mod_timer(&ts->timer, jiffies); 487 mod_timer(&ts->timer, jiffies);
449 488
450 while (ts->pendown || ts->pending) { 489 while (ts->pendown || ts->pending) {
451 spin_unlock_irqrestore(&ts->lock, flags); 490 spin_unlock_irq(&ts->lock);
452 msleep(1); 491 msleep(1);
453 spin_lock_irqsave(&ts->lock, flags); 492 spin_lock_irq(&ts->lock);
454 } 493 }
455 } 494 }
456 495
@@ -458,17 +497,46 @@ ads7846_suspend(struct spi_device *spi, pm_message_t message)
458 * leave it that way after every request 497 * leave it that way after every request
459 */ 498 */
460 499
461 spin_unlock_irqrestore(&ts->lock, flags); 500 ts->disabled = 1;
501}
502
503/* Must be called with ts->lock held */
504static void ads7846_enable(struct ads7846 *ts)
505{
506 if (!ts->disabled)
507 return;
508
509 ts->disabled = 0;
510 ts->irq_disabled = 0;
511 enable_irq(ts->spi->irq);
512}
513
514static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
515{
516 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
517
518 spin_lock_irq(&ts->lock);
519
520 spi->dev.power.power_state = message;
521 ads7846_disable(ts);
522
523 spin_unlock_irq(&ts->lock);
524
462 return 0; 525 return 0;
526
463} 527}
464 528
465static int ads7846_resume(struct spi_device *spi) 529static int ads7846_resume(struct spi_device *spi)
466{ 530{
467 struct ads7846 *ts = dev_get_drvdata(&spi->dev); 531 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
468 532
469 ts->irq_disabled = 0; 533 spin_lock_irq(&ts->lock);
470 enable_irq(ts->spi->irq); 534
471 spi->dev.power.power_state = PMSG_ON; 535 spi->dev.power.power_state = PMSG_ON;
536 ads7846_enable(ts);
537
538 spin_unlock_irq(&ts->lock);
539
472 return 0; 540 return 0;
473} 541}
474 542
@@ -521,6 +589,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
521 ts->timer.data = (unsigned long) ts; 589 ts->timer.data = (unsigned long) ts;
522 ts->timer.function = ads7846_timer; 590 ts->timer.function = ads7846_timer;
523 591
592 spin_lock_init(&ts->lock);
593
524 ts->model = pdata->model ? : 7846; 594 ts->model = pdata->model ? : 7846;
525 ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; 595 ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
526 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; 596 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
@@ -671,13 +741,25 @@ static int __devinit ads7846_probe(struct spi_device *spi)
671 741
672 device_create_file(&spi->dev, &dev_attr_pen_down); 742 device_create_file(&spi->dev, &dev_attr_pen_down);
673 743
744 device_create_file(&spi->dev, &dev_attr_disable);
745
674 err = input_register_device(input_dev); 746 err = input_register_device(input_dev);
675 if (err) 747 if (err)
676 goto err_free_irq; 748 goto err_remove_attr;
677 749
678 return 0; 750 return 0;
679 751
680 err_free_irq: 752 err_remove_attr:
753 device_remove_file(&spi->dev, &dev_attr_disable);
754 device_remove_file(&spi->dev, &dev_attr_pen_down);
755 if (ts->model == 7846) {
756 device_remove_file(&spi->dev, &dev_attr_temp1);
757 device_remove_file(&spi->dev, &dev_attr_temp0);
758 }
759 if (ts->model != 7845)
760 device_remove_file(&spi->dev, &dev_attr_vbatt);
761 device_remove_file(&spi->dev, &dev_attr_vaux);
762
681 free_irq(spi->irq, ts); 763 free_irq(spi->irq, ts);
682 err_free_mem: 764 err_free_mem:
683 input_free_device(input_dev); 765 input_free_device(input_dev);
@@ -689,22 +771,24 @@ static int __devexit ads7846_remove(struct spi_device *spi)
689{ 771{
690 struct ads7846 *ts = dev_get_drvdata(&spi->dev); 772 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
691 773
774 input_unregister_device(ts->input);
775
692 ads7846_suspend(spi, PMSG_SUSPEND); 776 ads7846_suspend(spi, PMSG_SUSPEND);
693 free_irq(ts->spi->irq, ts);
694 if (ts->irq_disabled)
695 enable_irq(ts->spi->irq);
696 777
778 device_remove_file(&spi->dev, &dev_attr_disable);
697 device_remove_file(&spi->dev, &dev_attr_pen_down); 779 device_remove_file(&spi->dev, &dev_attr_pen_down);
698
699 if (ts->model == 7846) { 780 if (ts->model == 7846) {
700 device_remove_file(&spi->dev, &dev_attr_temp0);
701 device_remove_file(&spi->dev, &dev_attr_temp1); 781 device_remove_file(&spi->dev, &dev_attr_temp1);
782 device_remove_file(&spi->dev, &dev_attr_temp0);
702 } 783 }
703 if (ts->model != 7845) 784 if (ts->model != 7845)
704 device_remove_file(&spi->dev, &dev_attr_vbatt); 785 device_remove_file(&spi->dev, &dev_attr_vbatt);
705 device_remove_file(&spi->dev, &dev_attr_vaux); 786 device_remove_file(&spi->dev, &dev_attr_vaux);
706 787
707 input_unregister_device(ts->input); 788 free_irq(ts->spi->irq, ts);
789 if (ts->irq_disabled)
790 enable_irq(ts->spi->irq);
791
708 kfree(ts); 792 kfree(ts);
709 793
710 dev_dbg(&spi->dev, "unregistered touchscreen\n"); 794 dev_dbg(&spi->dev, "unregistered touchscreen\n");