linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models
@ 2015-04-24 14:48 Hans de Goede
  2015-04-24 14:48 ` [PATCH 1/7] alps: Change alps_decode_rushmore to do all decoding itself Hans de Goede
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Peter Hutterer, Benjamin Tissoires, linux-input

Hi Dmitry,

This patch-set improves the coordinates reported when 2 fingers are down
on semi-mt alps models, leading to a much smoother 2fg scrolling experience.

This is somewhat the result of a libinput discussion here:
https://bugs.freedesktop.org/show_bug.cgi?id=89683

This has been tested on a laptop with a Rushmore touchpad, I'll ask the
reporter of the above bug to test this on his laptop with a Dolphin touchpad,
note that switching the Dolphin over to the standard process_bitmap should be
fine, as I've tried the other way around and that works too. In hindsight
there should have never been 2 different process_bitmap functions to begin
with.

Regards,

Hans

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] alps: Change alps_decode_rushmore to do all decoding itself
  2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
@ 2015-04-24 14:48 ` Hans de Goede
  2015-04-24 14:48 ` [PATCH 2/7] alps: Only set fields actually present when decoding pinnacle / rushmore pkts Hans de Goede
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Peter Hutterer, Benjamin Tissoires, linux-input, Hans de Goede

Change alps_decode_rushmore to do all decoding itself, rather then relying
on alps_decode_pinnacle and then overriding some fields + or-ing in some
bits.

This is a preparation patch for modifying the decode functions to properly
differentiate between position and bitmap packets.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/mouse/alps.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index e6708f6..e2ae6ca 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -605,13 +605,25 @@ static int alps_decode_pinnacle(struct alps_fields *f, unsigned char *p,
 static int alps_decode_rushmore(struct alps_fields *f, unsigned char *p,
 				 struct psmouse *psmouse)
 {
-	alps_decode_pinnacle(f, p, psmouse);
-
-	/* Rushmore's packet decode has a bit difference with Pinnacle's */
+	f->first_mp = !!(p[4] & 0x40);
 	f->is_mp = !!(p[5] & 0x40);
+
 	f->fingers = max((p[5] & 0x3), ((p[5] >> 2) & 0x3)) + 1;
-	f->x_map |= (p[5] & 0x10) << 11;
-	f->y_map |= (p[5] & 0x20) << 6;
+	f->x_map = ((p[5] & 0x10) << 11) |
+		   ((p[4] & 0x7e) << 8) |
+		   ((p[1] & 0x7f) << 2) |
+		   ((p[0] & 0x30) >> 4);
+	f->y_map = ((p[5] & 0x20) << 6) |
+		   ((p[3] & 0x70) << 4) |
+		   ((p[2] & 0x7f) << 1) |
+		   (p[4] & 0x01);
+
+	f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
+	       ((p[0] & 0x30) >> 4);
+	f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
+	f->pressure = p[5] & 0x7f;
+
+	alps_decode_buttons_v3(f, p);
 
 	return 0;
 }
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/7] alps: Only set fields actually present when decoding pinnacle / rushmore pkts
  2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
  2015-04-24 14:48 ` [PATCH 1/7] alps: Change alps_decode_rushmore to do all decoding itself Hans de Goede
@ 2015-04-24 14:48 ` Hans de Goede
  2015-04-24 14:48 ` [PATCH 3/7] alps: Always decode the position packet before the packet with the bitmap data Hans de Goede
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Peter Hutterer, Benjamin Tissoires, linux-input, Hans de Goede

Pinnacle / Rushmore packets contain either position info, or bitmap info,
never both. So far we've in essence been storing garbage in the position /
bitmap fields of the fields struct when decoding a bitmap / pos packet.

We've been relying on the following sequence to get away with this:

1) Decode bitmap packet
2) Process bitmap packet
3) Decode position packet
4) Use position / button info

This patch allows us to change this sequence, which will allow using the
position info when processing the bitmap for more accurate results.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/mouse/alps.c | 62 ++++++++++++++++++++++++----------------------
 1 file changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index e2ae6ca..5449537 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -584,20 +584,22 @@ static int alps_decode_pinnacle(struct alps_fields *f, unsigned char *p,
 	f->first_mp = !!(p[4] & 0x40);
 	f->is_mp = !!(p[0] & 0x40);
 
-	f->fingers = (p[5] & 0x3) + 1;
-	f->x_map = ((p[4] & 0x7e) << 8) |
-		   ((p[1] & 0x7f) << 2) |
-		   ((p[0] & 0x30) >> 4);
-	f->y_map = ((p[3] & 0x70) << 4) |
-		   ((p[2] & 0x7f) << 1) |
-		   (p[4] & 0x01);
-
-	f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
-	       ((p[0] & 0x30) >> 4);
-	f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
-	f->pressure = p[5] & 0x7f;
+	if (f->is_mp) {
+		f->fingers = (p[5] & 0x3) + 1;
+		f->x_map = ((p[4] & 0x7e) << 8) |
+			   ((p[1] & 0x7f) << 2) |
+			   ((p[0] & 0x30) >> 4);
+		f->y_map = ((p[3] & 0x70) << 4) |
+			   ((p[2] & 0x7f) << 1) |
+			   (p[4] & 0x01);
+	} else {
+		f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
+		       ((p[0] & 0x30) >> 4);
+		f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
+		f->pressure = p[5] & 0x7f;
 
-	alps_decode_buttons_v3(f, p);
+		alps_decode_buttons_v3(f, p);
+	}
 
 	return 0;
 }
@@ -608,22 +610,24 @@ static int alps_decode_rushmore(struct alps_fields *f, unsigned char *p,
 	f->first_mp = !!(p[4] & 0x40);
 	f->is_mp = !!(p[5] & 0x40);
 
-	f->fingers = max((p[5] & 0x3), ((p[5] >> 2) & 0x3)) + 1;
-	f->x_map = ((p[5] & 0x10) << 11) |
-		   ((p[4] & 0x7e) << 8) |
-		   ((p[1] & 0x7f) << 2) |
-		   ((p[0] & 0x30) >> 4);
-	f->y_map = ((p[5] & 0x20) << 6) |
-		   ((p[3] & 0x70) << 4) |
-		   ((p[2] & 0x7f) << 1) |
-		   (p[4] & 0x01);
-
-	f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
-	       ((p[0] & 0x30) >> 4);
-	f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
-	f->pressure = p[5] & 0x7f;
-
-	alps_decode_buttons_v3(f, p);
+	if (f->is_mp) {
+		f->fingers = max((p[5] & 0x3), ((p[5] >> 2) & 0x3)) + 1;
+		f->x_map = ((p[5] & 0x10) << 11) |
+			   ((p[4] & 0x7e) << 8) |
+			   ((p[1] & 0x7f) << 2) |
+			   ((p[0] & 0x30) >> 4);
+		f->y_map = ((p[5] & 0x20) << 6) |
+			   ((p[3] & 0x70) << 4) |
+			   ((p[2] & 0x7f) << 1) |
+			   (p[4] & 0x01);
+	} else {
+		f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
+		       ((p[0] & 0x30) >> 4);
+		f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
+		f->pressure = p[5] & 0x7f;
+
+		alps_decode_buttons_v3(f, p);
+	}
 
 	return 0;
 }
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/7] alps: Always decode the position packet before the packet with the bitmap data
  2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
  2015-04-24 14:48 ` [PATCH 1/7] alps: Change alps_decode_rushmore to do all decoding itself Hans de Goede
  2015-04-24 14:48 ` [PATCH 2/7] alps: Only set fields actually present when decoding pinnacle / rushmore pkts Hans de Goede
@ 2015-04-24 14:48 ` Hans de Goede
  2015-04-24 14:48 ` [PATCH 4/7] alps: Use more accurate coordinates for first touch in semi-mt mode Hans de Goede
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Peter Hutterer, Benjamin Tissoires, linux-input, Hans de Goede

This way we can use the more accurate position info in process_bitmap() to
get better results.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/mouse/alps.c | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 5449537..1cfee85 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -696,25 +696,18 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
 		 */
 		if (f->is_mp) {
 			fingers = f->fingers;
+			/*
+			 * Bitmap processing uses position packet's coordinate
+			 * data, so we need to do decode it first.
+			 */
+			priv->decode_fields(f, priv->multi_data, psmouse);
+
 			if (priv->proto_version == ALPS_PROTO_V3 ||
 			    priv->proto_version == ALPS_PROTO_V3_RUSHMORE) {
 				if (alps_process_bitmap(priv, f) == 0)
 					fingers = 0; /* Use st data */
-
-				/* Now process position packet */
-				priv->decode_fields(f, priv->multi_data,
-						    psmouse);
 			} else {
 				/*
-				 * Because Dolphin uses position packet's
-				 * coordinate data as Pt1 and uses it to
-				 * calculate Pt2, so we need to do position
-				 * packet decode first.
-				 */
-				priv->decode_fields(f, priv->multi_data,
-						    psmouse);
-
-				/*
 				 * Since Dolphin's finger number is reliable,
 				 * there is no need to compare with bmap_fn.
 				 */
@@ -881,6 +874,14 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
 	priv->multi_data[offset] = packet[6];
 	priv->multi_data[offset + 1] = packet[7];
 
+	f->left = !!(packet[4] & 0x01);
+	f->right = !!(packet[4] & 0x02);
+
+	f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) |
+		  ((packet[0] & 0x30) >> 4);
+	f->st.y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f);
+	f->pressure = packet[5] & 0x7f;
+
 	if (++priv->multi_packet > 2) {
 		priv->multi_packet = 0;
 
@@ -895,14 +896,6 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
 		f->fingers = alps_process_bitmap(priv, f);
 	}
 
-	f->left = !!(packet[4] & 0x01);
-	f->right = !!(packet[4] & 0x02);
-
-	f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) |
-		  ((packet[0] & 0x30) >> 4);
-	f->st.y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f);
-	f->pressure = packet[5] & 0x7f;
-
 	alps_report_semi_mt_data(psmouse, f->fingers);
 }
 
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/7] alps: Use more accurate coordinates for first touch in semi-mt mode
  2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
                   ` (2 preceding siblings ...)
  2015-04-24 14:48 ` [PATCH 3/7] alps: Always decode the position packet before the packet with the bitmap data Hans de Goede
@ 2015-04-24 14:48 ` Hans de Goede
  2015-04-24 14:48 ` [PATCH 5/7] alps: Do not use input-mt finger tracking for semi-mt devices Hans de Goede
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Peter Hutterer, Benjamin Tissoires, linux-input, Hans de Goede

All alps semi-mt touchpads give us the following data when 2 (or more)
fingers are touching: 1 more or less accurate touch for the first finger
down, and a bitmap with columns and rows in which 1 or more fingers are
seen resulting in a crude (low res) bounding box.

So far for v3, rushmore and v4 touchpads we've been reporting the
coordinates of 2 opposite corners of the box when 2 fingers are touching.
Ignoring the much better resolution data given in the normal position
packet.

This commit actually uses this data for the first touch, figures out which
corner of the bounding box is closest to the first touch, and reports the
coordinates of the opposite corner for the second touch, resulting in
much better data for the first touch and for the single touch
pointer-emulation events.

This approach is similar to the one in alps_process_bitmap_dolphin, that
function takes the single accurate touch info, calculates the distance to
the center of the bounding box, and then puts the 2nd touch mirrored to
the center. The downside of that approach is that if both touches move
slowly in the same direction, the bounding box will stay the same for a
while (as it is low res) and the second touch will thus been seen moving
in the opposite direction until the bounding box actually changes, and
then the second touch snaps to its new position resulting in a saw tooth
pattern in the coordinates for the second touch, hence this new approach.

This commit fixes 2 finger scrolling being choppy / jumpy on these
touchpads.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/mouse/alps.c | 59 ++++++++++++++++++++++++++++++++++++++++------
 drivers/input/mouse/alps.h |  1 +
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 1cfee85..604dea3 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -396,9 +396,10 @@ static void alps_get_bitmap_points(unsigned int map,
 static int alps_process_bitmap(struct alps_data *priv,
 			       struct alps_fields *fields)
 {
-	int i, fingers_x = 0, fingers_y = 0, fingers;
+	int i, fingers_x = 0, fingers_y = 0, fingers, closest;
 	struct alps_bitmap_point x_low = {0,}, x_high = {0,};
 	struct alps_bitmap_point y_low = {0,}, y_high = {0,};
+	struct input_mt_pos corner[4];
 
 	if (!fields->x_map || !fields->y_map)
 		return 0;
@@ -429,26 +430,69 @@ static int alps_process_bitmap(struct alps_data *priv,
 		y_high.num_bits = max(i, 1);
 	}
 
-	fields->mt[0].x =
+	/* top-left corner */
+	corner[0].x =
 		(priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
 		(2 * (priv->x_bits - 1));
-	fields->mt[0].y =
+	corner[0].y =
 		(priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
 		(2 * (priv->y_bits - 1));
 
-	fields->mt[1].x =
+	/* top-right corner */
+	corner[1].x =
 		(priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) /
 		(2 * (priv->x_bits - 1));
-	fields->mt[1].y =
+	corner[1].y =
+		(priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
+		(2 * (priv->y_bits - 1));
+
+	/* bottom-right corner */
+	corner[2].x =
+		(priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) /
+		(2 * (priv->x_bits - 1));
+	corner[2].y =
+		(priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
+		(2 * (priv->y_bits - 1));
+
+	/* bottom-left corner */
+	corner[3].x =
+		(priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
+		(2 * (priv->x_bits - 1));
+	corner[3].y =
 		(priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
 		(2 * (priv->y_bits - 1));
 
 	/* y-bitmap order is reversed, except on rushmore */
 	if (priv->proto_version != ALPS_PROTO_V3_RUSHMORE) {
-		fields->mt[0].y = priv->y_max - fields->mt[0].y;
-		fields->mt[1].y = priv->y_max - fields->mt[1].y;
+		for (i = 0; i < 4; i++)
+			corner[i].y = priv->y_max - corner[i].y;
+	}
+
+	/*
+	 * We only select a corner for the second touch once per 2 finger
+	 * touch sequence to avoid the chosen corner (and thus the coordinates)
+	 * jumping around when the first touch is in the middle.
+	 */
+	if (priv->second_touch == -1) {
+		/* Find corner closest to our st coordinates */
+		closest = 0x7fffffff;
+		for (i = 0; i < 4; i++) {
+			int dx = fields->st.x - corner[i].x;
+			int dy = fields->st.y - corner[i].y;
+			int distance = dx * dx + dy * dy;
+
+			if (distance < closest) {
+				priv->second_touch = i;
+				closest = distance;
+			}
+		}
+		/* And select the opposite corner to use for the 2nd touch */
+		priv->second_touch = (priv->second_touch + 2) % 4;
 	}
 
+	fields->mt[0] = fields->st;
+	fields->mt[1] = corner[priv->second_touch];
+
 	return fingers;
 }
 
@@ -485,6 +529,7 @@ static void alps_report_semi_mt_data(struct psmouse *psmouse, int fingers)
 		f->mt[0].x = f->st.x;
 		f->mt[0].y = f->st.y;
 		fingers = f->pressure > 0 ? 1 : 0;
+		priv->second_touch = -1;
 	}
 
 	alps_report_mt_data(psmouse, (fingers <= 2) ? fingers : 2);
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 6dfdccc..d37f814 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -278,6 +278,7 @@ struct alps_data {
 
 	int prev_fin;
 	int multi_packet;
+	int second_touch;
 	unsigned char multi_data[6];
 	struct alps_fields f;
 	u8 quirks;
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/7] alps: Do not use input-mt finger tracking for semi-mt devices
  2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
                   ` (3 preceding siblings ...)
  2015-04-24 14:48 ` [PATCH 4/7] alps: Use more accurate coordinates for first touch in semi-mt mode Hans de Goede
@ 2015-04-24 14:48 ` Hans de Goede
  2015-04-24 14:48 ` [PATCH 6/7] alps: Rename alps_set_abs_params_mt to alps_set_abs_params_semi_mt Hans de Goede
  2015-04-24 14:48 ` [PATCH 7/7] alps: Use the generic process_bitmap function for dolphin (v5) touchpads too Hans de Goede
  6 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Peter Hutterer, Benjamin Tissoires, linux-input, Hans de Goede

With the recent process_bitmap() changes all semi-mt devices always report
the first finger down in slot 0, so stop using input-mt finger tracking
for these.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/mouse/alps.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 604dea3..11fda20 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -532,7 +532,11 @@ static void alps_report_semi_mt_data(struct psmouse *psmouse, int fingers)
 		priv->second_touch = -1;
 	}
 
-	alps_report_mt_data(psmouse, (fingers <= 2) ? fingers : 2);
+	if (fingers >= 1)
+		alps_set_slot(dev, 0, f->mt[0].x, f->mt[0].y);
+	if (fingers >= 2)
+		alps_set_slot(dev, 1, f->mt[1].x, f->mt[1].y);
+	input_mt_sync_frame(dev);
 
 	input_mt_report_finger_count(dev, fingers);
 
@@ -2835,7 +2839,7 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
 
 	input_mt_init_slots(dev1, MAX_TOUCHES,
 			    INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
-				INPUT_MT_TRACK | INPUT_MT_SEMI_MT);
+				INPUT_MT_SEMI_MT);
 }
 
 static void alps_set_abs_params_v7(struct alps_data *priv,
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/7] alps: Rename alps_set_abs_params_mt to alps_set_abs_params_semi_mt
  2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
                   ` (4 preceding siblings ...)
  2015-04-24 14:48 ` [PATCH 5/7] alps: Do not use input-mt finger tracking for semi-mt devices Hans de Goede
@ 2015-04-24 14:48 ` Hans de Goede
  2015-04-24 14:48 ` [PATCH 7/7] alps: Use the generic process_bitmap function for dolphin (v5) touchpads too Hans de Goede
  6 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Peter Hutterer, Benjamin Tissoires, linux-input, Hans de Goede

Rename alps_set_abs_params_mt to alps_set_abs_params_semi_mt,
to make it clear that it is only (to be) used for semi-mt devices.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/mouse/alps.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 11fda20..390a308 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -159,8 +159,8 @@ static const struct alps_protocol_info alps_v8_protocol_data = {
 
 static void alps_set_abs_params_st(struct alps_data *priv,
 				   struct input_dev *dev1);
-static void alps_set_abs_params_mt(struct alps_data *priv,
-				   struct input_dev *dev1);
+static void alps_set_abs_params_semi_mt(struct alps_data *priv,
+					struct input_dev *dev1);
 static void alps_set_abs_params_v7(struct alps_data *priv,
 				   struct input_dev *dev1);
 static void alps_set_abs_params_ss4_v2(struct alps_data *priv,
@@ -2615,7 +2615,7 @@ static int alps_set_protocol(struct psmouse *psmouse,
 	case ALPS_PROTO_V3:
 		priv->hw_init = alps_hw_init_v3;
 		priv->process_packet = alps_process_packet_v3;
-		priv->set_abs_params = alps_set_abs_params_mt;
+		priv->set_abs_params = alps_set_abs_params_semi_mt;
 		priv->decode_fields = alps_decode_pinnacle;
 		priv->nibble_commands = alps_v3_nibble_commands;
 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
@@ -2624,7 +2624,7 @@ static int alps_set_protocol(struct psmouse *psmouse,
 	case ALPS_PROTO_V3_RUSHMORE:
 		priv->hw_init = alps_hw_init_rushmore_v3;
 		priv->process_packet = alps_process_packet_v3;
-		priv->set_abs_params = alps_set_abs_params_mt;
+		priv->set_abs_params = alps_set_abs_params_semi_mt;
 		priv->decode_fields = alps_decode_rushmore;
 		priv->nibble_commands = alps_v3_nibble_commands;
 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
@@ -2640,7 +2640,7 @@ static int alps_set_protocol(struct psmouse *psmouse,
 	case ALPS_PROTO_V4:
 		priv->hw_init = alps_hw_init_v4;
 		priv->process_packet = alps_process_packet_v4;
-		priv->set_abs_params = alps_set_abs_params_mt;
+		priv->set_abs_params = alps_set_abs_params_semi_mt;
 		priv->nibble_commands = alps_v4_nibble_commands;
 		priv->addr_command = PSMOUSE_CMD_DISABLE;
 		break;
@@ -2649,7 +2649,7 @@ static int alps_set_protocol(struct psmouse *psmouse,
 		priv->hw_init = alps_hw_init_dolphin_v1;
 		priv->process_packet = alps_process_touchpad_packet_v3_v5;
 		priv->decode_fields = alps_decode_dolphin;
-		priv->set_abs_params = alps_set_abs_params_mt;
+		priv->set_abs_params = alps_set_abs_params_semi_mt;
 		priv->nibble_commands = alps_v3_nibble_commands;
 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
 		priv->x_bits = 23;
@@ -2831,8 +2831,8 @@ static void alps_set_abs_params_mt_common(struct alps_data *priv,
 	set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
 }
 
-static void alps_set_abs_params_mt(struct alps_data *priv,
-				   struct input_dev *dev1)
+static void alps_set_abs_params_semi_mt(struct alps_data *priv,
+					struct input_dev *dev1)
 {
 	alps_set_abs_params_mt_common(priv, dev1);
 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 7/7] alps: Use the generic process_bitmap function for dolphin (v5) touchpads too
  2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
                   ` (5 preceding siblings ...)
  2015-04-24 14:48 ` [PATCH 6/7] alps: Rename alps_set_abs_params_mt to alps_set_abs_params_semi_mt Hans de Goede
@ 2015-04-24 14:48 ` Hans de Goede
  6 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2015-04-24 14:48 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Peter Hutterer, Benjamin Tissoires, linux-input, Hans de Goede

Now that the generic process_bitmap function has been improved to offer
accurate coordinates for the first touch we can use it for v5 (dolphin)
touchpads too.

Besides being a nice code cleanup this also fixes the saw tooth pattern
in the coordinates for the second touch the dolphin specific version had.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/mouse/alps.c | 74 ++++++++--------------------------------------
 1 file changed, 12 insertions(+), 62 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 390a308..745921f 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -310,53 +310,6 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
 	input_sync(dev);
 }
 
-/*
- * Process bitmap data for V5 protocols. Return value is null.
- *
- * The bitmaps don't have enough data to track fingers, so this function
- * only generates points representing a bounding box of at most two contacts.
- * These two points are returned in fields->mt.
- */
-static void alps_process_bitmap_dolphin(struct alps_data *priv,
-					struct alps_fields *fields)
-{
-	int box_middle_x, box_middle_y;
-	unsigned int x_map, y_map;
-	unsigned char start_bit, end_bit;
-	unsigned char x_msb, x_lsb, y_msb, y_lsb;
-
-	x_map = fields->x_map;
-	y_map = fields->y_map;
-
-	if (!x_map || !y_map)
-		return;
-
-	/* Get Most-significant and Least-significant bit */
-	x_msb = fls(x_map);
-	x_lsb = ffs(x_map);
-	y_msb = fls(y_map);
-	y_lsb = ffs(y_map);
-
-	/* Most-significant bit should never exceed max sensor line number */
-	if (x_msb > priv->x_bits || y_msb > priv->y_bits)
-		return;
-
-	if (fields->fingers > 1) {
-		start_bit = priv->x_bits - x_msb;
-		end_bit = priv->x_bits - x_lsb;
-		box_middle_x = (priv->x_max * (start_bit + end_bit)) /
-				(2 * (priv->x_bits - 1));
-
-		start_bit = y_lsb - 1;
-		end_bit = y_msb - 1;
-		box_middle_y = (priv->y_max * (start_bit + end_bit)) /
-				(2 * (priv->y_bits - 1));
-		fields->mt[0] = fields->st;
-		fields->mt[1].x = 2 * box_middle_x - fields->mt[0].x;
-		fields->mt[1].y = 2 * box_middle_y - fields->mt[0].y;
-	}
-}
-
 static void alps_get_bitmap_points(unsigned int map,
 				   struct alps_bitmap_point *low,
 				   struct alps_bitmap_point *high,
@@ -384,7 +337,7 @@ static void alps_get_bitmap_points(unsigned int map,
 }
 
 /*
- * Process bitmap data from v3 and v4 protocols. Returns the number of
+ * Process bitmap data from semi-mt protocols. Returns the number of
  * fingers detected. A return value of 0 means at least one of the
  * bitmaps was empty.
  *
@@ -462,8 +415,15 @@ static int alps_process_bitmap(struct alps_data *priv,
 		(priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
 		(2 * (priv->y_bits - 1));
 
-	/* y-bitmap order is reversed, except on rushmore */
-	if (priv->proto_version != ALPS_PROTO_V3_RUSHMORE) {
+	/* x-bitmap order is reversed on v5 touchpads  */
+	if (priv->proto_version == ALPS_PROTO_V5) {
+		for (i = 0; i < 4; i++)
+			corner[i].x = priv->x_max - corner[i].x;
+	}
+
+	/* y-bitmap order is reversed on v3 and v4 touchpads  */
+	if (priv->proto_version == ALPS_PROTO_V3 ||
+	    priv->proto_version == ALPS_PROTO_V4) {
 		for (i = 0; i < 4; i++)
 			corner[i].y = priv->y_max - corner[i].y;
 	}
@@ -750,18 +710,8 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
 			 * data, so we need to do decode it first.
 			 */
 			priv->decode_fields(f, priv->multi_data, psmouse);
-
-			if (priv->proto_version == ALPS_PROTO_V3 ||
-			    priv->proto_version == ALPS_PROTO_V3_RUSHMORE) {
-				if (alps_process_bitmap(priv, f) == 0)
-					fingers = 0; /* Use st data */
-			} else {
-				/*
-				 * Since Dolphin's finger number is reliable,
-				 * there is no need to compare with bmap_fn.
-				 */
-				alps_process_bitmap_dolphin(priv, f);
-			}
+			if (alps_process_bitmap(priv, f) == 0)
+				fingers = 0; /* Use st data */
 		} else {
 			priv->multi_packet = 0;
 		}
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-04-24 14:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-24 14:48 [PATCH 0/7] alps: Improve coordinates reported when 2fg are down on semi-mt models Hans de Goede
2015-04-24 14:48 ` [PATCH 1/7] alps: Change alps_decode_rushmore to do all decoding itself Hans de Goede
2015-04-24 14:48 ` [PATCH 2/7] alps: Only set fields actually present when decoding pinnacle / rushmore pkts Hans de Goede
2015-04-24 14:48 ` [PATCH 3/7] alps: Always decode the position packet before the packet with the bitmap data Hans de Goede
2015-04-24 14:48 ` [PATCH 4/7] alps: Use more accurate coordinates for first touch in semi-mt mode Hans de Goede
2015-04-24 14:48 ` [PATCH 5/7] alps: Do not use input-mt finger tracking for semi-mt devices Hans de Goede
2015-04-24 14:48 ` [PATCH 6/7] alps: Rename alps_set_abs_params_mt to alps_set_abs_params_semi_mt Hans de Goede
2015-04-24 14:48 ` [PATCH 7/7] alps: Use the generic process_bitmap function for dolphin (v5) touchpads too Hans de Goede

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).