aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2010-10-28 17:59:05 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-10-29 01:32:50 -0400
commitb584efc9ea7575d3235cfd745e8a28201d2c37f6 (patch)
treeb00aaf5107666a706067406fa9be5debf807614d
parent49327ad2bbbaf1945d5ba431522201574219d150 (diff)
Input: ad7879 - prevent invalid finger data reports
Considering following scenario - the touch is present on the screen at the beginning of the last conversion sequence, but by the time the last sequence is finished, the finger is lift off. The AD7879 data available interrupt signals (DAV) completion, however some X,Y values are not valid because the screen inputs were floating during the acquisition. The AD7877 acts differently here, since it only asserts DAV if the touch is still present when the conversion sequence finished. Based on the fact that this can only happen in the last sample of the repeated conversion sequence, we simply skip the last (short glitches are filtered by the AD7879 internal median and average filters). This doesn't cause noticeable side effects, since the minimum conversion interval is 9.44ms. We receive ~100 waypoint samples per second, so we simply delay the result by 9.44ms. We also reject samples where pressure is greater than pressure_max. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/touchscreen/ad7879.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index ba6f0bd1e762..bc3b5187f3a3 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -129,6 +129,9 @@ struct ad7879 {
129 u16 cmd_crtl1; 129 u16 cmd_crtl1;
130 u16 cmd_crtl2; 130 u16 cmd_crtl2;
131 u16 cmd_crtl3; 131 u16 cmd_crtl3;
132 int x;
133 int y;
134 int Rt;
132}; 135};
133 136
134static int ad7879_read(struct ad7879 *ts, u8 reg) 137static int ad7879_read(struct ad7879 *ts, u8 reg)
@@ -175,13 +178,32 @@ static int ad7879_report(struct ad7879 *ts)
175 Rt /= z1; 178 Rt /= z1;
176 Rt = (Rt + 2047) >> 12; 179 Rt = (Rt + 2047) >> 12;
177 180
178 if (!timer_pending(&ts->timer)) 181 /*
182 * Sample found inconsistent, pressure is beyond
183 * the maximum. Don't report it to user space.
184 */
185 if (Rt > ts->pressure_max)
186 return -EINVAL;
187
188 /*
189 * Note that we delay reporting events by one sample.
190 * This is done to avoid reporting last sample of the
191 * touch sequence, which may be incomplete if finger
192 * leaves the surface before last reading is taken.
193 */
194 if (timer_pending(&ts->timer)) {
195 /* Touch continues */
179 input_report_key(input_dev, BTN_TOUCH, 1); 196 input_report_key(input_dev, BTN_TOUCH, 1);
197 input_report_abs(input_dev, ABS_X, ts->x);
198 input_report_abs(input_dev, ABS_Y, ts->y);
199 input_report_abs(input_dev, ABS_PRESSURE, ts->Rt);
200 input_sync(input_dev);
201 }
202
203 ts->x = x;
204 ts->y = y;
205 ts->Rt = Rt;
180 206
181 input_report_abs(input_dev, ABS_X, x);
182 input_report_abs(input_dev, ABS_Y, y);
183 input_report_abs(input_dev, ABS_PRESSURE, Rt);
184 input_sync(input_dev);
185 return 0; 207 return 0;
186 } 208 }
187 209