Commit e938fbfd authored by Florian Ragwitz's avatar Florian Ragwitz Committed by Dmitry Torokhov

Input: elantech - ignore high bits in the position coordinates

In older versions of the elantech hardware/firmware those bits always
were unset, so it didn't actually matter, but newer versions seem to
use those high bits for something else, screwing up the coordinates
we report to the input layer for those devices.
Signed-off-by: default avatarFlorian Ragwitz <rafl@debian.org>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent f81bc788
...@@ -333,14 +333,14 @@ byte 0: ...@@ -333,14 +333,14 @@ byte 0:
byte 1: byte 1:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
x15 x14 x13 x12 x11 x10 x9 x8 . . . . . x10 x9 x8
byte 2: byte 2:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x4 x2 x1 x0 x7 x6 x5 x4 x4 x2 x1 x0
x15..x0 = absolute x value (horizontal) x10..x0 = absolute x value (horizontal)
byte 3: byte 3:
...@@ -350,14 +350,14 @@ byte 3: ...@@ -350,14 +350,14 @@ byte 3:
byte 4: byte 4:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
y15 y14 y13 y12 y11 y10 y8 y8 . . . . . . y9 y8
byte 5: byte 5:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0 y7 y6 y5 y4 y3 y2 y1 y0
y15..y0 = absolute y value (vertical) y9..y0 = absolute y value (vertical)
4.2.2 Two finger touch 4.2.2 Two finger touch
......
...@@ -185,13 +185,17 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) ...@@ -185,13 +185,17 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
static int old_fingers; static int old_fingers;
if (etd->fw_version_maj == 0x01) { if (etd->fw_version_maj == 0x01) {
/* byte 0: D U p1 p2 1 p3 R L /*
byte 1: f 0 th tw x9 x8 y9 y8 */ * byte 0: D U p1 p2 1 p3 R L
* byte 1: f 0 th tw x9 x8 y9 y8
*/
fingers = ((packet[1] & 0x80) >> 7) + fingers = ((packet[1] & 0x80) >> 7) +
((packet[1] & 0x30) >> 4); ((packet[1] & 0x30) >> 4);
} else { } else {
/* byte 0: n1 n0 p2 p1 1 p3 R L /*
byte 1: 0 0 0 0 x9 x8 y9 y8 */ * byte 0: n1 n0 p2 p1 1 p3 R L
* byte 1: 0 0 0 0 x9 x8 y9 y8
*/
fingers = (packet[0] & 0xc0) >> 6; fingers = (packet[0] & 0xc0) >> 6;
} }
...@@ -205,13 +209,15 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) ...@@ -205,13 +209,15 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
input_report_key(dev, BTN_TOUCH, fingers != 0); input_report_key(dev, BTN_TOUCH, fingers != 0);
/* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 /*
byte 3: y7 y6 y5 y4 y3 y2 y1 y0 */ * byte 2: x7 x6 x5 x4 x3 x2 x1 x0
* byte 3: y7 y6 y5 y4 y3 y2 y1 y0
*/
if (fingers) { if (fingers) {
input_report_abs(dev, ABS_X, input_report_abs(dev, ABS_X,
((packet[1] & 0x0c) << 6) | packet[2]); ((packet[1] & 0x0c) << 6) | packet[2]);
input_report_abs(dev, ABS_Y, ETP_YMAX_V1 - input_report_abs(dev, ABS_Y,
(((packet[1] & 0x03) << 8) | packet[3])); ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
} }
input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
...@@ -250,34 +256,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) ...@@ -250,34 +256,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
switch (fingers) { switch (fingers) {
case 1: case 1:
/* byte 1: x15 x14 x13 x12 x11 x10 x9 x8 /*
byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ * byte 1: . . . . . x10 x9 x8
input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]); * byte 2: x7 x6 x5 x4 x4 x2 x1 x0
/* byte 4: y15 y14 y13 y12 y11 y10 y8 y8 */
byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ input_report_abs(dev, ABS_X,
input_report_abs(dev, ABS_Y, ETP_YMAX_V2 - ((packet[1] & 0x07) << 8) | packet[2]);
((packet[4] << 8) | packet[5])); /*
* byte 4: . . . . . . y9 y8
* byte 5: y7 y6 y5 y4 y3 y2 y1 y0
*/
input_report_abs(dev, ABS_Y,
ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]));
break; break;
case 2: case 2:
/* The coordinate of each finger is reported separately with /*
a lower resolution for two finger touches */ * The coordinate of each finger is reported separately
/* byte 0: . . ay8 ax8 . . . . * with a lower resolution for two finger touches:
byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */ * byte 0: . . ay8 ax8 . . . .
* byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
*/
x1 = ((packet[0] & 0x10) << 4) | packet[1]; x1 = ((packet[0] & 0x10) << 4) | packet[1];
/* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
/* byte 3: . . by8 bx8 . . . . /*
byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */ * byte 3: . . by8 bx8 . . . .
* byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
*/
x2 = ((packet[3] & 0x10) << 4) | packet[4]; x2 = ((packet[3] & 0x10) << 4) | packet[4];
/* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
/* For compatibility with the X Synaptics driver scale up one /*
coordinate and report as ordinary mouse movent */ * For compatibility with the X Synaptics driver scale up
* one coordinate and report as ordinary mouse movent
*/
input_report_abs(dev, ABS_X, x1 << 2); input_report_abs(dev, ABS_X, x1 << 2);
input_report_abs(dev, ABS_Y, y1 << 2); input_report_abs(dev, ABS_Y, y1 << 2);
/* For compatibility with the proprietary X Elantech driver /*
report both coordinates as hat coordinates */ * For compatibility with the proprietary X Elantech driver
* report both coordinates as hat coordinates
*/
input_report_abs(dev, ABS_HAT0X, x1); input_report_abs(dev, ABS_HAT0X, x1);
input_report_abs(dev, ABS_HAT0Y, y1); input_report_abs(dev, ABS_HAT0Y, y1);
input_report_abs(dev, ABS_HAT1X, x2); input_report_abs(dev, ABS_HAT1X, x2);
......
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