]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Input: atmel_tsadcc - improve accuracy
authorDan Liang <Dan.Liang@atmel.com>
Fri, 15 Aug 2008 02:36:41 +0000 (22:36 -0400)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 10 Sep 2008 16:12:24 +0000 (12:12 -0400)
Discard the last sample just before pen is up because it is quite often
errorneous.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Dan Liang <dan.liang@atmel.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/input/touchscreen/atmel_tsadcc.c

index eee126b19e8b53cc3a8949a3798df9cd13c6d402..a89a6a8f05e6c9631f7368fb2488e080490b6fe0 100644 (file)
@@ -91,6 +91,9 @@ struct atmel_tsadcc {
        char                    phys[32];
        struct clk              *clk;
        int                     irq;
+       unsigned int            prev_absx;
+       unsigned int            prev_absy;
+       unsigned char           bufferedmeasure;
 };
 
 static void __iomem            *tsc_base;
@@ -100,10 +103,9 @@ static void __iomem                *tsc_base;
 
 static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
 {
-       struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input;
+       struct atmel_tsadcc     *ts_dev = (struct atmel_tsadcc *)dev;
+       struct input_dev        *input_dev = ts_dev->input;
 
-       unsigned int absx;
-       unsigned int absy;
        unsigned int status;
        unsigned int reg;
 
@@ -121,6 +123,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
                atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
 
                input_report_key(input_dev, BTN_TOUCH, 0);
+               ts_dev->bufferedmeasure = 0;
                input_sync(input_dev);
 
        } else if (status & ATMEL_TSADCC_PENCNT) {
@@ -138,16 +141,23 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
        } else if (status & ATMEL_TSADCC_EOC(3)) {
                /* Conversion finished */
 
-               absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
-               absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
-
-               absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
-               absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
-
-               input_report_abs(input_dev, ABS_X, absx);
-               input_report_abs(input_dev, ABS_Y, absy);
-               input_report_key(input_dev, BTN_TOUCH, 1);
-               input_sync(input_dev);
+               if (ts_dev->bufferedmeasure) {
+                       /* Last measurement is always discarded, since it can
+                        * be erroneous.
+                        * Always report previous measurement */
+                       input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
+                       input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
+                       input_report_key(input_dev, BTN_TOUCH, 1);
+                       input_sync(input_dev);
+               } else
+                       ts_dev->bufferedmeasure = 1;
+
+               /* Now make new measurement */
+               ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
+               ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
+
+               ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
+               ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
        }
 
        return IRQ_HANDLED;
@@ -223,6 +233,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
        }
 
        ts_dev->input = input_dev;
+       ts_dev->bufferedmeasure = 0;
 
        snprintf(ts_dev->phys, sizeof(ts_dev->phys),
                 "%s/input0", pdev->dev.bus_id);