aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/appletouch.c
diff options
context:
space:
mode:
authorClinton Sprain <clintonsprain@gmail.com>2014-03-31 02:21:21 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-03-31 02:44:14 -0400
commit739204bc957750ca47254114b8ee49b00edfc18d (patch)
tree1fdee3d62dc85f356cdd5996192f499f15832998 /drivers/input/mouse/appletouch.c
parent61cd4822dd810e1a3c28eab1af6005728906c0e4 (diff)
Input: appletouch - implement sensor data smoothing
Use smoothed version of sensor array data to calculate movement and add weight to prior values when calculating average. This gives more granular and more predictable movement. Signed-off-by: Clinton Sprain <clintonsprain@gmail.com> Reviewed-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse/appletouch.c')
-rw-r--r--drivers/input/mouse/appletouch.c103
1 files changed, 79 insertions, 24 deletions
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 2745832f74b6..2dbf7a0f0537 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -161,6 +161,12 @@ MODULE_DEVICE_TABLE(usb, atp_table);
161#define ATP_XSENSORS 26 161#define ATP_XSENSORS 26
162#define ATP_YSENSORS 16 162#define ATP_YSENSORS 16
163 163
164/*
165 * The largest possible bank of sensors with additional buffer of 4 extra values
166 * on either side, for an array of smoothed sensor values.
167 */
168#define ATP_SMOOTHSIZE 34
169
164/* maximum pressure this driver will report */ 170/* maximum pressure this driver will report */
165#define ATP_PRESSURE 300 171#define ATP_PRESSURE 300
166 172
@@ -168,7 +174,13 @@ MODULE_DEVICE_TABLE(usb, atp_table);
168 * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is 174 * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is
169 * ignored. 175 * ignored.
170 */ 176 */
171#define ATP_THRESHOLD 5 177#define ATP_THRESHOLD 5
178
179/*
180 * How far we'll bitshift our sensor values before averaging them. Mitigates
181 * rounding errors.
182 */
183#define ATP_SCALE 12
172 184
173/* Geyser initialization constants */ 185/* Geyser initialization constants */
174#define ATP_GEYSER_MODE_READ_REQUEST_ID 1 186#define ATP_GEYSER_MODE_READ_REQUEST_ID 1
@@ -211,6 +223,8 @@ struct atp {
211 signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; 223 signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS];
212 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; 224 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
213 int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; 225 int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
226 int smooth[ATP_SMOOTHSIZE];
227 int smooth_tmp[ATP_SMOOTHSIZE];
214 int idlecount; /* number of empty packets */ 228 int idlecount; /* number of empty packets */
215 struct work_struct work; 229 struct work_struct work;
216}; 230};
@@ -329,10 +343,17 @@ static void atp_reinit(struct work_struct *work)
329 retval); 343 retval);
330} 344}
331 345
332static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, 346static int atp_calculate_abs(struct atp *dev, int offset, int nb_sensors,
333 int *z, int *fingers) 347 int fact, int *z, int *fingers)
334{ 348{
335 int i; 349 int i, pass;
350
351 /*
352 * Use offset to point xy_sensors at the first value in dev->xy_acc
353 * for whichever dimension we're looking at this particular go-round.
354 */
355 int *xy_sensors = dev->xy_acc + offset;
356
336 /* values to calculate mean */ 357 /* values to calculate mean */
337 int pcum = 0, psum = 0; 358 int pcum = 0, psum = 0;
338 int is_increasing = 0; 359 int is_increasing = 0;
@@ -344,9 +365,6 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
344 if (is_increasing) 365 if (is_increasing)
345 is_increasing = 0; 366 is_increasing = 0;
346 367
347 continue;
348 }
349
350 /* 368 /*
351 * Makes the finger detection more versatile. For example, 369 * Makes the finger detection more versatile. For example,
352 * two fingers with no gap will be detected. Also, my 370 * two fingers with no gap will be detected. Also, my
@@ -361,27 +379,63 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
361 * 379 *
362 * - Jason Parekh <jasonparekh@gmail.com> 380 * - Jason Parekh <jasonparekh@gmail.com>
363 */ 381 */
364 if (i < 1 || 382
383 } else if (i < 1 ||
365 (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) { 384 (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
366 (*fingers)++; 385 (*fingers)++;
367 is_increasing = 1; 386 is_increasing = 1;
368 } else if (i > 0 && (xy_sensors[i - 1] - xy_sensors[i] > threshold)) { 387 } else if (i > 0 && (xy_sensors[i - 1] - xy_sensors[i] > threshold)) {
369 is_increasing = 0; 388 is_increasing = 0;
370 } 389 }
390 }
391
392 if (*fingers < 1) /* No need to continue if no fingers are found. */
393 return 0;
394
395 /*
396 * Use a smoothed version of sensor data for movement calculations, to
397 * combat noise without needing to rely so heavily on a threshold.
398 * This improves tracking.
399 *
400 * The smoothed array is bigger than the original so that the smoothing
401 * doesn't result in edge values being truncated.
402 */
403
404 memset(dev->smooth, 0, 4 * sizeof(dev->smooth[0]));
405 /* Pull base values, scaled up to help avoid truncation errors. */
406 for (i = 0; i < nb_sensors; i++)
407 dev->smooth[i + 4] = xy_sensors[i] << ATP_SCALE;
408 memset(&dev->smooth[nb_sensors + 4], 0, 4 * sizeof(dev->smooth[0]));
371 409
410 for (pass = 0; pass < 4; pass++) {
411 /* Handle edge. */
412 dev->smooth_tmp[0] = (dev->smooth[0] + dev->smooth[1]) / 2;
413
414 /* Average values with neighbors. */
415 for (i = 1; i < nb_sensors + 7; i++)
416 dev->smooth_tmp[i] = (dev->smooth[i - 1] +
417 dev->smooth[i] * 2 +
418 dev->smooth[i + 1]) / 4;
419
420 /* Handle other edge. */
421 dev->smooth_tmp[i] = (dev->smooth[i - 1] + dev->smooth[i]) / 2;
422
423 memcpy(dev->smooth, dev->smooth_tmp, sizeof(dev->smooth));
424 }
425
426 for (i = 0; i < nb_sensors + 8; i++) {
372 /* 427 /*
373 * Subtracts threshold so a high sensor that just passes the 428 * Skip values if they're small enough to be truncated to 0
374 * threshold won't skew the calculated absolute coordinate. 429 * by scale. Mostly noise.
375 * Fixes an issue where slowly moving the mouse would
376 * occasionally jump a number of pixels (slowly moving the
377 * finger makes this issue most apparent.)
378 */ 430 */
379 pcum += (xy_sensors[i] - threshold) * i; 431 if ((dev->smooth[i] >> ATP_SCALE) > 0) {
380 psum += (xy_sensors[i] - threshold); 432 pcum += dev->smooth[i] * i;
433 psum += dev->smooth[i];
434 }
381 } 435 }
382 436
383 if (psum > 0) { 437 if (psum > 0) {
384 *z = psum; 438 *z = psum >> ATP_SCALE; /* Scale down pressure output. */
385 return pcum * fact / psum; 439 return pcum * fact / psum;
386 } 440 }
387 441
@@ -551,16 +605,16 @@ static void atp_complete_geyser_1_2(struct urb *urb)
551 605
552 dbg_dump("accumulator", dev->xy_acc); 606 dbg_dump("accumulator", dev->xy_acc);
553 607
554 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 608 x = atp_calculate_abs(dev, 0, ATP_XSENSORS,
555 dev->info->xfact, &x_z, &x_f); 609 dev->info->xfact, &x_z, &x_f);
556 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 610 y = atp_calculate_abs(dev, ATP_XSENSORS, ATP_YSENSORS,
557 dev->info->yfact, &y_z, &y_f); 611 dev->info->yfact, &y_z, &y_f);
558 key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON; 612 key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON;
559 613
560 if (x && y) { 614 if (x && y) {
561 if (dev->x_old != -1) { 615 if (dev->x_old != -1) {
562 x = (dev->x_old * 3 + x) >> 2; 616 x = (dev->x_old * 7 + x) >> 3;
563 y = (dev->y_old * 3 + y) >> 2; 617 y = (dev->y_old * 7 + y) >> 3;
564 dev->x_old = x; 618 dev->x_old = x;
565 dev->y_old = y; 619 dev->y_old = y;
566 620
@@ -663,16 +717,17 @@ static void atp_complete_geyser_3_4(struct urb *urb)
663 717
664 dbg_dump("accumulator", dev->xy_acc); 718 dbg_dump("accumulator", dev->xy_acc);
665 719
666 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 720 x = atp_calculate_abs(dev, 0, ATP_XSENSORS,
667 dev->info->xfact, &x_z, &x_f); 721 dev->info->xfact, &x_z, &x_f);
668 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 722 y = atp_calculate_abs(dev, ATP_XSENSORS, ATP_YSENSORS,
669 dev->info->yfact, &y_z, &y_f); 723 dev->info->yfact, &y_z, &y_f);
724
670 key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON; 725 key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON;
671 726
672 if (x && y) { 727 if (x && y) {
673 if (dev->x_old != -1) { 728 if (dev->x_old != -1) {
674 x = (dev->x_old * 3 + x) >> 2; 729 x = (dev->x_old * 7 + x) >> 3;
675 y = (dev->y_old * 3 + y) >> 2; 730 y = (dev->y_old * 7 + y) >> 3;
676 dev->x_old = x; 731 dev->x_old = x;
677 dev->y_old = y; 732 dev->y_old = y;
678 733