summaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-07-25 22:33:33 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-26 14:03:13 -0700
commit20bea68bd1a5c783a23ad9e9de15ffb1b036f3a4 (patch)
treece85528901dab9edae379fac50dc5a5c6daf18a6 /drivers/input
parentf105e34a4e3ff073b0d96d5f91eb3c6e8dffaa4c (diff)
downloadlinux-20bea68bd1a5c783a23ad9e9de15ffb1b036f3a4.tar.bz2
Input: alps - improve 2-finger reporting on v3 models
V3 models only report mt bitmap data when there are 2 or more fingers on the touchpad. So always generate 2 positions in alps_process_bitmap, and for v3 models only fall back to st data when there was no mt data in a mt packet (which should never happen). This fixes 2 finger scrolling not working when using 2 fingers close to each other. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/mouse/alps.c60
1 files changed, 24 insertions, 36 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index e15daea56864..cc197d7473c9 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -407,23 +407,20 @@ static int alps_process_bitmap(struct alps_data *priv,
fingers = max(fingers_x, fingers_y);
/*
- * If total fingers is > 1 but either axis reports only a single
- * contact, we have overlapping or adjacent fingers. For the
- * purposes of creating a bounding box, divide the single contact
- * (roughly) equally between the two points.
+ * If an axis reports only a single contact, we have overlapping or
+ * adjacent fingers. Divide the single contact between the two points.
*/
- if (fingers > 1) {
- if (fingers_x == 1) {
- i = x_low.num_bits / 2;
- x_low.num_bits = x_low.num_bits - i;
- x_high.start_bit = x_low.start_bit + i;
- x_high.num_bits = max(i, 1);
- } else if (fingers_y == 1) {
- i = y_low.num_bits / 2;
- y_low.num_bits = y_low.num_bits - i;
- y_high.start_bit = y_low.start_bit + i;
- y_high.num_bits = max(i, 1);
- }
+ if (fingers_x == 1) {
+ i = x_low.num_bits / 2;
+ x_low.num_bits = x_low.num_bits - i;
+ x_high.start_bit = x_low.start_bit + i;
+ x_high.num_bits = max(i, 1);
+ }
+ if (fingers_y == 1) {
+ i = y_low.num_bits / 2;
+ y_low.num_bits = y_low.num_bits - i;
+ y_high.start_bit = y_low.start_bit + i;
+ y_high.num_bits = max(i, 1);
}
*x1 = (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
@@ -431,14 +428,12 @@ static int alps_process_bitmap(struct alps_data *priv,
*y1 = (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
(2 * (priv->y_bits - 1));
- if (fingers > 1) {
- *x2 = (priv->x_max *
- (2 * x_high.start_bit + x_high.num_bits - 1)) /
- (2 * (priv->x_bits - 1));
- *y2 = (priv->y_max *
- (2 * y_high.start_bit + y_high.num_bits - 1)) /
- (2 * (priv->y_bits - 1));
- }
+ *x2 = (priv->x_max *
+ (2 * x_high.start_bit + x_high.num_bits - 1)) /
+ (2 * (priv->x_bits - 1));
+ *y2 = (priv->y_max *
+ (2 * y_high.start_bit + y_high.num_bits - 1)) /
+ (2 * (priv->y_bits - 1));
return fingers;
}
@@ -607,8 +602,7 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
unsigned char *packet = psmouse->packet;
struct input_dev *dev = psmouse->dev;
struct input_dev *dev2 = priv->dev2;
- int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
- int fingers = 0, bmap_fn;
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0, fingers = 0;
struct alps_fields f = {0};
priv->decode_fields(&f, packet, psmouse);
@@ -629,16 +623,10 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
if (f.is_mp) {
fingers = f.fingers;
if (priv->proto_version == ALPS_PROTO_V3) {
- bmap_fn = alps_process_bitmap(priv, f.x_map,
- f.y_map, &x1, &y1,
- &x2, &y2);
-
- /*
- * We shouldn't report more than one finger if
- * we don't have two coordinates.
- */
- if (fingers > 1 && bmap_fn < 2)
- fingers = bmap_fn;
+ if (alps_process_bitmap(priv, f.x_map,
+ f.y_map, &x1, &y1,
+ &x2, &y2) == 0)
+ fingers = 0; /* Use st data */
/* Now process position packet */
priv->decode_fields(&f, priv->multi_data,