From 00081d3729a450c37afb01c01528f4f305806d86 Mon Sep 17 00:00:00 2001 From: Jason Parekh Date: Fri, 17 Nov 2006 01:05:58 -0500 Subject: [PATCH] Input: appletouch - verious updates for MacBooks Change a bit the finger detection method used by the appletouch driver to reduce touchpad "jumpiness": - Adjust the method for detecting multiple fingers. Previously, it recognized a new finger when a low sensor reading is followed by a high sensor reading. The new method checks for 'humps' in the sensor readings, so there doesn't necessarily have to be a low sensor between two high sensors for two fingers to be triggered. This allows detecting presence of two fingers on the touchpad even when they touch each other. - Change absolute coordinate calculation to us to get rid of "jumps". Instead of using full value from a sensor once it passes the threshold subtract theshold value from the reading. - Allow adjusting threshold value via module parameter. The patch doesn't seem to affect the Powerbooks but does greatly improve the touchpad behaviour on the MacBooks. Signed-off-by: Jason Parekh Signed-off-by: Stelian Pop Signed-off-by: Dmitry Torokhov --- drivers/usb/input/appletouch.c | 47 +++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 4c213513484d..4825db4b2566 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c @@ -154,6 +154,13 @@ MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann"); MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); MODULE_LICENSE("GPL"); +/* + * Make the threshold a module parameter + */ +static int threshold = ATP_THRESHOLD; +module_param(threshold, int, 0644); +MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value"); + static int debug = 1; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Activate debugging output"); @@ -183,16 +190,48 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, int i; /* values to calculate mean */ int pcum = 0, psum = 0; + int is_increasing = 0; *fingers = 0; for (i = 0; i < nb_sensors; i++) { - if (xy_sensors[i] < ATP_THRESHOLD) + if (xy_sensors[i] < threshold) { + if (is_increasing) + is_increasing = 0; + continue; - if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD)) + } + + /* + * Makes the finger detection more versatile. For example, + * two fingers with no gap will be detected. Also, my + * tests show it less likely to have intermittent loss + * of multiple finger readings while moving around (scrolling). + * + * Changes the multiple finger detection to counting humps on + * sensors (transitions from nonincreasing to increasing) + * instead of counting transitions from low sensors (no + * finger reading) to high sensors (finger above + * sensor) + * + * - Jason Parekh + */ + if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) { (*fingers)++; - pcum += xy_sensors[i] * i; - psum += xy_sensors[i]; + is_increasing = 1; + } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) { + is_increasing = 0; + } + + /* + * Subtracts threshold so a high sensor that just passes the threshold + * won't skew the calculated absolute coordinate. Fixes an issue + * where slowly moving the mouse would occassionaly jump a number of + * pixels (let me restate--slowly moving the mouse makes this issue + * most apparent). + */ + pcum += (xy_sensors[i] - threshold) * i; + psum += (xy_sensors[i] - threshold); } if (psum > 0) { -- 2.30.2