aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorImre Deak <imre.deak@solidboot.com>2007-01-18 00:44:41 -0500
committerDmitry Torokhov <dtor@insightbb.com>2007-01-18 00:44:41 -0500
commitda970e69efb9fd0be0c23ace5bde42d4caf17b40 (patch)
tree8d415d9ccbf6bbdfa360146c539d8213c794a21f /drivers/input
parent78a56aab11234e53b7e94e5a255cc3d27ab0a62b (diff)
Input: ads7846 - pluggable filtering logic
Some LCDs like the LS041Y3 require a customized filtering logic for reliable readings, so make the filtering function replacable through platform specific hooks. Signed-off-by: Imre Deak <imre.deak@solidboot.com> Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/ads7846.c135
1 files changed, 95 insertions, 40 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index c6164b6f476a..03e527c16c23 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -63,11 +63,11 @@ struct ts_event {
63 /* For portability, we can't read 12 bit values using SPI (which 63 /* For portability, we can't read 12 bit values using SPI (which
64 * would make the controller deliver them as native byteorder u16 64 * would make the controller deliver them as native byteorder u16
65 * with msbs zeroed). Instead, we read them as two 8-bit values, 65 * with msbs zeroed). Instead, we read them as two 8-bit values,
66 * which need byteswapping then range adjustment. 66 * *** WHICH NEED BYTESWAPPING *** and range adjustment.
67 */ 67 */
68 __be16 x; 68 u16 x;
69 __be16 y; 69 u16 y;
70 __be16 z1, z2; 70 u16 z1, z2;
71 int ignore; 71 int ignore;
72}; 72};
73 73
@@ -106,6 +106,9 @@ struct ads7846 {
106 unsigned irq_disabled:1; /* P: lock */ 106 unsigned irq_disabled:1; /* P: lock */
107 unsigned disabled:1; 107 unsigned disabled:1;
108 108
109 int (*filter)(void *data, int data_idx, int *val);
110 void *filter_data;
111 void (*filter_cleanup)(void *data);
109 int (*get_pendown_state)(void); 112 int (*get_pendown_state)(void);
110}; 113};
111 114
@@ -379,13 +382,13 @@ static void ads7846_rx(void *ads)
379 u16 x, y, z1, z2; 382 u16 x, y, z1, z2;
380 unsigned long flags; 383 unsigned long flags;
381 384
382 /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; 385 /* ads7846_rx_val() did in-place conversion (including byteswap) from
383 * built from two 8 bit values written msb-first. 386 * on-the-wire format as part of debouncing to get stable readings.
384 */ 387 */
385 x = (be16_to_cpu(ts->tc.x) >> 3) & 0x0fff; 388 x = ts->tc.x;
386 y = (be16_to_cpu(ts->tc.y) >> 3) & 0x0fff; 389 y = ts->tc.y;
387 z1 = (be16_to_cpu(ts->tc.z1) >> 3) & 0x0fff; 390 z1 = ts->tc.z1;
388 z2 = (be16_to_cpu(ts->tc.z2) >> 3) & 0x0fff; 391 z2 = ts->tc.z2;
389 392
390 /* range filtering */ 393 /* range filtering */
391 if (x == MAX_12BIT) 394 if (x == MAX_12BIT)
@@ -453,50 +456,85 @@ static void ads7846_rx(void *ads)
453 spin_unlock_irqrestore(&ts->lock, flags); 456 spin_unlock_irqrestore(&ts->lock, flags);
454} 457}
455 458
456static void ads7846_debounce(void *ads) 459static int ads7846_debounce(void *ads, int data_idx, int *val)
457{ 460{
458 struct ads7846 *ts = ads; 461 struct ads7846 *ts = ads;
459 struct spi_message *m;
460 struct spi_transfer *t;
461 int val;
462 int status;
463 462
464 m = &ts->msg[ts->msg_idx]; 463 if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) {
465 t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); 464 /* Start over collecting consistent readings. */
466 val = (be16_to_cpu(*(__be16 *)t->rx_buf) >> 3) & 0x0fff; 465 ts->read_rep = 0;
467 if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) {
468 /* Repeat it, if this was the first read or the read 466 /* Repeat it, if this was the first read or the read
469 * wasn't consistent enough. */ 467 * wasn't consistent enough. */
470 if (ts->read_cnt < ts->debounce_max) { 468 if (ts->read_cnt < ts->debounce_max) {
471 ts->last_read = val; 469 ts->last_read = *val;
472 ts->read_cnt++; 470 ts->read_cnt++;
471 return ADS7846_FILTER_REPEAT;
473 } else { 472 } else {
474 /* Maximum number of debouncing reached and still 473 /* Maximum number of debouncing reached and still
475 * not enough number of consistent readings. Abort 474 * not enough number of consistent readings. Abort
476 * the whole sample, repeat it in the next sampling 475 * the whole sample, repeat it in the next sampling
477 * period. 476 * period.
478 */ 477 */
479 ts->tc.ignore = 1;
480 ts->read_cnt = 0; 478 ts->read_cnt = 0;
481 /* Last message will contain ads7846_rx() as the 479 return ADS7846_FILTER_IGNORE;
482 * completion function.
483 */
484 m = ts->last_msg;
485 } 480 }
486 /* Start over collecting consistent readings. */
487 ts->read_rep = 0;
488 } else { 481 } else {
489 if (++ts->read_rep > ts->debounce_rep) { 482 if (++ts->read_rep > ts->debounce_rep) {
490 /* Got a good reading for this coordinate, 483 /* Got a good reading for this coordinate,
491 * go for the next one. */ 484 * go for the next one. */
492 ts->tc.ignore = 0;
493 ts->msg_idx++;
494 ts->read_cnt = 0; 485 ts->read_cnt = 0;
495 ts->read_rep = 0; 486 ts->read_rep = 0;
496 m++; 487 return ADS7846_FILTER_OK;
497 } else 488 } else {
498 /* Read more values that are consistent. */ 489 /* Read more values that are consistent. */
499 ts->read_cnt++; 490 ts->read_cnt++;
491 return ADS7846_FILTER_REPEAT;
492 }
493 }
494}
495
496static int ads7846_no_filter(void *ads, int data_idx, int *val)
497{
498 return ADS7846_FILTER_OK;
499}
500
501static void ads7846_rx_val(void *ads)
502{
503 struct ads7846 *ts = ads;
504 struct spi_message *m;
505 struct spi_transfer *t;
506 u16 *rx_val;
507 int val;
508 int action;
509 int status;
510
511 m = &ts->msg[ts->msg_idx];
512 t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
513 rx_val = t->rx_buf;
514
515 /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding;
516 * built from two 8 bit values written msb-first.
517 */
518 val = be16_to_cpu(*rx_val) >> 3;
519
520 action = ts->filter(ts->filter_data, ts->msg_idx, &val);
521 switch (action) {
522 case ADS7846_FILTER_REPEAT:
523 break;
524 case ADS7846_FILTER_IGNORE:
525 ts->tc.ignore = 1;
526 /* Last message will contain ads7846_rx() as the
527 * completion function.
528 */
529 m = ts->last_msg;
530 break;
531 case ADS7846_FILTER_OK:
532 *rx_val = val;
533 ts->tc.ignore = 0;
534 m = &ts->msg[++ts->msg_idx];
535 break;
536 default:
537 BUG();
500 } 538 }
501 status = spi_async(ts->spi, m); 539 status = spi_async(ts->spi, m);
502 if (status) 540 if (status)
@@ -689,14 +727,25 @@ static int __devinit ads7846_probe(struct spi_device *spi)
689 ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; 727 ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
690 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; 728 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
691 ts->pressure_max = pdata->pressure_max ? : ~0; 729 ts->pressure_max = pdata->pressure_max ? : ~0;
692 if (pdata->debounce_max) { 730
731 if (pdata->filter != NULL) {
732 if (pdata->filter_init != NULL) {
733 err = pdata->filter_init(pdata, &ts->filter_data);
734 if (err < 0)
735 goto err_free_mem;
736 }
737 ts->filter = pdata->filter;
738 ts->filter_cleanup = pdata->filter_cleanup;
739 } else if (pdata->debounce_max) {
693 ts->debounce_max = pdata->debounce_max; 740 ts->debounce_max = pdata->debounce_max;
741 if (ts->debounce_max < 2)
742 ts->debounce_max = 2;
694 ts->debounce_tol = pdata->debounce_tol; 743 ts->debounce_tol = pdata->debounce_tol;
695 ts->debounce_rep = pdata->debounce_rep; 744 ts->debounce_rep = pdata->debounce_rep;
696 if (ts->debounce_rep > ts->debounce_max + 1) 745 ts->filter = ads7846_debounce;
697 ts->debounce_rep = ts->debounce_max - 1; 746 ts->filter_data = ts;
698 } else 747 } else
699 ts->debounce_tol = ~0; 748 ts->filter = ads7846_no_filter;
700 ts->get_pendown_state = pdata->get_pendown_state; 749 ts->get_pendown_state = pdata->get_pendown_state;
701 750
702 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); 751 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
@@ -737,7 +786,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
737 x->len = 2; 786 x->len = 2;
738 spi_message_add_tail(x, m); 787 spi_message_add_tail(x, m);
739 788
740 m->complete = ads7846_debounce; 789 m->complete = ads7846_rx_val;
741 m->context = ts; 790 m->context = ts;
742 791
743 m++; 792 m++;
@@ -755,7 +804,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
755 x->len = 2; 804 x->len = 2;
756 spi_message_add_tail(x, m); 805 spi_message_add_tail(x, m);
757 806
758 m->complete = ads7846_debounce; 807 m->complete = ads7846_rx_val;
759 m->context = ts; 808 m->context = ts;
760 809
761 /* turn y+ off, x- on; we'll use formula #2 */ 810 /* turn y+ off, x- on; we'll use formula #2 */
@@ -774,7 +823,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
774 x->len = 2; 823 x->len = 2;
775 spi_message_add_tail(x, m); 824 spi_message_add_tail(x, m);
776 825
777 m->complete = ads7846_debounce; 826 m->complete = ads7846_rx_val;
778 m->context = ts; 827 m->context = ts;
779 828
780 m++; 829 m++;
@@ -791,7 +840,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
791 x->len = 2; 840 x->len = 2;
792 spi_message_add_tail(x, m); 841 spi_message_add_tail(x, m);
793 842
794 m->complete = ads7846_debounce; 843 m->complete = ads7846_rx_val;
795 m->context = ts; 844 m->context = ts;
796 } 845 }
797 846
@@ -820,7 +869,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
820 spi->dev.driver->name, ts)) { 869 spi->dev.driver->name, ts)) {
821 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); 870 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
822 err = -EBUSY; 871 err = -EBUSY;
823 goto err_free_mem; 872 goto err_cleanup_filter;
824 } 873 }
825 874
826 dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); 875 dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
@@ -856,6 +905,9 @@ static int __devinit ads7846_probe(struct spi_device *spi)
856 sysfs_remove_group(&spi->dev.kobj, ts->attr_group); 905 sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
857 err_free_irq: 906 err_free_irq:
858 free_irq(spi->irq, ts); 907 free_irq(spi->irq, ts);
908 err_cleanup_filter:
909 if (ts->filter_cleanup)
910 ts->filter_cleanup(ts->filter_data);
859 err_free_mem: 911 err_free_mem:
860 input_free_device(input_dev); 912 input_free_device(input_dev);
861 kfree(ts); 913 kfree(ts);
@@ -876,6 +928,9 @@ static int __devexit ads7846_remove(struct spi_device *spi)
876 /* suspend left the IRQ disabled */ 928 /* suspend left the IRQ disabled */
877 enable_irq(ts->spi->irq); 929 enable_irq(ts->spi->irq);
878 930
931 if (ts->filter_cleanup)
932 ts->filter_cleanup(ts->filter_data);
933
879 kfree(ts); 934 kfree(ts);
880 935
881 dev_dbg(&spi->dev, "unregistered touchscreen\n"); 936 dev_dbg(&spi->dev, "unregistered touchscreen\n");