Commit 20bea68b authored by Hans de Goede's avatar Hans de Goede Committed by Dmitry Torokhov

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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent f105e34a
...@@ -407,38 +407,33 @@ static int alps_process_bitmap(struct alps_data *priv, ...@@ -407,38 +407,33 @@ static int alps_process_bitmap(struct alps_data *priv,
fingers = max(fingers_x, fingers_y); fingers = max(fingers_x, fingers_y);
/* /*
* If total fingers is > 1 but either axis reports only a single * If an axis reports only a single contact, we have overlapping or
* contact, we have overlapping or adjacent fingers. For the * adjacent fingers. Divide the single contact between the two points.
* purposes of creating a bounding box, divide the single contact
* (roughly) equally between the two points.
*/ */
if (fingers > 1) {
if (fingers_x == 1) { if (fingers_x == 1) {
i = x_low.num_bits / 2; i = x_low.num_bits / 2;
x_low.num_bits = x_low.num_bits - i; x_low.num_bits = x_low.num_bits - i;
x_high.start_bit = x_low.start_bit + i; x_high.start_bit = x_low.start_bit + i;
x_high.num_bits = max(i, 1); x_high.num_bits = max(i, 1);
} else if (fingers_y == 1) { }
if (fingers_y == 1) {
i = y_low.num_bits / 2; i = y_low.num_bits / 2;
y_low.num_bits = y_low.num_bits - i; y_low.num_bits = y_low.num_bits - i;
y_high.start_bit = y_low.start_bit + i; y_high.start_bit = y_low.start_bit + i;
y_high.num_bits = max(i, 1); y_high.num_bits = max(i, 1);
} }
}
*x1 = (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) / *x1 = (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
(2 * (priv->x_bits - 1)); (2 * (priv->x_bits - 1));
*y1 = (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) / *y1 = (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
(2 * (priv->y_bits - 1)); (2 * (priv->y_bits - 1));
if (fingers > 1) {
*x2 = (priv->x_max * *x2 = (priv->x_max *
(2 * x_high.start_bit + x_high.num_bits - 1)) / (2 * x_high.start_bit + x_high.num_bits - 1)) /
(2 * (priv->x_bits - 1)); (2 * (priv->x_bits - 1));
*y2 = (priv->y_max * *y2 = (priv->y_max *
(2 * y_high.start_bit + y_high.num_bits - 1)) / (2 * y_high.start_bit + y_high.num_bits - 1)) /
(2 * (priv->y_bits - 1)); (2 * (priv->y_bits - 1));
}
return fingers; return fingers;
} }
...@@ -607,8 +602,7 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) ...@@ -607,8 +602,7 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
unsigned char *packet = psmouse->packet; unsigned char *packet = psmouse->packet;
struct input_dev *dev = psmouse->dev; struct input_dev *dev = psmouse->dev;
struct input_dev *dev2 = priv->dev2; struct input_dev *dev2 = priv->dev2;
int x1 = 0, y1 = 0, x2 = 0, y2 = 0; int x1 = 0, y1 = 0, x2 = 0, y2 = 0, fingers = 0;
int fingers = 0, bmap_fn;
struct alps_fields f = {0}; struct alps_fields f = {0};
priv->decode_fields(&f, packet, psmouse); priv->decode_fields(&f, packet, psmouse);
...@@ -629,16 +623,10 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) ...@@ -629,16 +623,10 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
if (f.is_mp) { if (f.is_mp) {
fingers = f.fingers; fingers = f.fingers;
if (priv->proto_version == ALPS_PROTO_V3) { if (priv->proto_version == ALPS_PROTO_V3) {
bmap_fn = alps_process_bitmap(priv, f.x_map, if (alps_process_bitmap(priv, f.x_map,
f.y_map, &x1, &y1, f.y_map, &x1, &y1,
&x2, &y2); &x2, &y2) == 0)
fingers = 0; /* Use st data */
/*
* We shouldn't report more than one finger if
* we don't have two coordinates.
*/
if (fingers > 1 && bmap_fn < 2)
fingers = bmap_fn;
/* Now process position packet */ /* Now process position packet */
priv->decode_fields(&f, priv->multi_data, priv->decode_fields(&f, priv->multi_data,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment