aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorSeth Forshee <seth.forshee@canonical.com>2012-09-28 13:29:21 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-09-28 13:33:57 -0400
commit824efd37415961d38821ecbd9694e213fb2e8b32 (patch)
tree2c4d3c3468fdb7ac96da3dd1f83e331e690422d9 /drivers/input/mouse
parent35b1da4e1e1026b5195649170dfb9ebb52f808e0 (diff)
Input: synaptics - adjust threshold for treating position values as negative
Commit c039450 (Input: synaptics - handle out of bounds values from the hardware) caused any hardware reported values over 7167 to be treated as a wrapped-around negative value. It turns out that some firmware uses the value 8176 to indicate a finger near the edge of the touchpad whose actual position cannot be determined. This value now gets treated as negative, which can cause pointer jumps and broken edge scrolling on these machines. I only know of one touchpad which reports negative values, and this hardware never reports any value lower than -8 (i.e. 8184). Moving the threshold for treating a value as negative up to 8176 should work fine then for any hardware we currently know about, and since we're dealing with unspecified behavior it's probably the best we can do. The special 8176 value is also likely to result in sudden jumps in position, so let's also clamp this to the maximum specified value for the axis. BugLink: http://bugs.launchpad.net/bugs/1046512 https://bugzilla.kernel.org/show_bug.cgi?id=46371 Cc: stable@vger.kernel.org Signed-off-by: Seth Forshee <seth.forshee@canonical.com> Reviewed-by: Daniel Kurtz <djkurtz@chromium.org> Tested-by: Alan Swanson <swanson@ukfsn.org> Tested-by: Arteom <arutemus@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/synaptics.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 14eaecea2b70..0786919c15cd 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -53,14 +53,19 @@
53#define ABS_POS_BITS 13 53#define ABS_POS_BITS 13
54 54
55/* 55/*
56 * Any position values from the hardware above the following limits are 56 * These values should represent the absolute maximum value that will
57 * treated as "wrapped around negative" values that have been truncated to 57 * be reported for a positive position value. Some Synaptics firmware
58 * the 13-bit reporting range of the hardware. These are just reasonable 58 * uses this value to indicate a finger near the edge of the touchpad
59 * guesses and can be adjusted if hardware is found that operates outside 59 * whose precise position cannot be determined.
60 * of these parameters. 60 *
61 * At least one touchpad is known to report positions in excess of this
62 * value which are actually negative values truncated to the 13-bit
63 * reporting range. These values have never been observed to be lower
64 * than 8184 (i.e. -8), so we treat all values greater than 8176 as
65 * negative and any other value as positive.
61 */ 66 */
62#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2) 67#define X_MAX_POSITIVE 8176
63#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2) 68#define Y_MAX_POSITIVE 8176
64 69
65/***************************************************************************** 70/*****************************************************************************
66 * Stuff we need even when we do not want native Synaptics support 71 * Stuff we need even when we do not want native Synaptics support
@@ -604,11 +609,21 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
604 hw->right = (buf[0] & 0x02) ? 1 : 0; 609 hw->right = (buf[0] & 0x02) ? 1 : 0;
605 } 610 }
606 611
607 /* Convert wrap-around values to negative */ 612 /*
613 * Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE
614 * is used by some firmware to indicate a finger at the edge of
615 * the touchpad whose precise position cannot be determined, so
616 * convert these values to the maximum axis value.
617 */
608 if (hw->x > X_MAX_POSITIVE) 618 if (hw->x > X_MAX_POSITIVE)
609 hw->x -= 1 << ABS_POS_BITS; 619 hw->x -= 1 << ABS_POS_BITS;
620 else if (hw->x == X_MAX_POSITIVE)
621 hw->x = XMAX;
622
610 if (hw->y > Y_MAX_POSITIVE) 623 if (hw->y > Y_MAX_POSITIVE)
611 hw->y -= 1 << ABS_POS_BITS; 624 hw->y -= 1 << ABS_POS_BITS;
625 else if (hw->y == Y_MAX_POSITIVE)
626 hw->y = YMAX;
612 627
613 return 0; 628 return 0;
614} 629}