Browse files

Input: synaptics - handle out of bounds values from the hardware

commit c039450 upstream.

The touchpad on the Acer Aspire One D250 will report out of range values
in the extreme lower portion of the touchpad. These appear as abrupt
changes in the values reported by the hardware from very low values to
very high values, which can cause unexpected vertical jumps in the
position of the mouse pointer.

What seems to be happening is that the value is wrapping to a two's
compliment negative value of higher resolution than the 13-bit value
reported by the hardware, with the high-order bits being truncated. This
patch adds handling for these values by converting them to the
appropriate negative values.

The only tricky part about this is deciding when to treat a number as
negative. It stands to reason that if out of range values can be
reported on the low end then it could also happen on the high end, so
not all out of range values should be treated as negative. The approach
taken here is to split the difference between the maximum legitimate
value for the axis and the maximum possible value that the hardware can
report, treating values greater than this number as negative and all
other values as positive. This can be tweaked later if hardware is found
that operates outside of these parameters.

Signed-off-by: Seth Forshee <>
Reviewed-by: Daniel Kurtz <>
Signed-off-by: Dmitry Torokhov <>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <>
  • Loading branch information...
1 parent efb6d7d commit 2028a493b8ff0cfb853be5839759e9522a6da64a Seth Forshee committed with bwhacks Jul 25, 2012
Showing with 23 additions and 0 deletions.
  1. +23 −0 drivers/input/mouse/synaptics.c
23 drivers/input/mouse/synaptics.c
@@ -40,11 +40,28 @@
* Note that newer firmware allows querying device for maximum useable
* coordinates.
+#define XMIN 0
+#define XMAX 6143
+#define YMIN 0
+#define YMAX 6143
#define XMIN_NOMINAL 1472
#define XMAX_NOMINAL 5472
#define YMIN_NOMINAL 1408
#define YMAX_NOMINAL 4448
+/* Size in bits of absolute position values reported by the hardware */
+#define ABS_POS_BITS 13
+ * Any position values from the hardware above the following limits are
+ * treated as "wrapped around negative" values that have been truncated to
+ * the 13-bit reporting range of the hardware. These are just reasonable
+ * guesses and can be adjusted if hardware is found that operates outside
+ * of these parameters.
+ */
+#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2)
+#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2)
* Synaptics touchpads report the y coordinate from bottom to top, which is
* opposite from what userspace expects.
@@ -544,6 +561,12 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
hw->right = (buf[0] & 0x02) ? 1 : 0;
+ /* Convert wrap-around values to negative */
+ if (hw->x > X_MAX_POSITIVE)
+ hw->x -= 1 << ABS_POS_BITS;
+ if (hw->y > Y_MAX_POSITIVE)
+ hw->y -= 1 << ABS_POS_BITS;
return 0;

0 comments on commit 2028a49

Please sign in to comment.