Commit ddae9e6e authored by Masaki Ota's avatar Masaki Ota Committed by Greg Kroah-Hartman

Input: ALPS - fix two-finger scroll breakage in right side on ALPS touchpad

commit 4a646580 upstream.

Fixed the issue that two finger scroll does not work correctly
on V8 protocol. The cause is that V8 protocol X-coordinate decode
is wrong at SS4 PLUS device. I added SS4 PLUS X decode definition.

Mote notes:
the problem manifests itself by the commit e7348396 ("Input: ALPS
- fix V8+ protocol handling (73 03 28)"), where a fix for the V8+
protocol was applied.  Although the culprit must have been present
beforehand, the two-finger scroll worked casually even with the
wrongly reported values by some reason.  It got broken by the commit
above just because it changed x_max value, and this made libinput
correctly figuring the MT events.  Since the X coord is reported as
falsely doubled, the events on the right-half side go outside the
boundary, thus they are no longer handled.  This resulted as a broken
two-finger scroll.

One finger event is decoded differently, and it didn't suffer from
this problem.  The problem was only about MT events. --tiwai

Fixes: e7348396 ("Input: ALPS - fix V8+ protocol handling (73 03 28)")
Signed-off-by: default avatarMasaki Ota <masaki.ota@jp.alps.com>
Tested-by: default avatarTakashi Iwai <tiwai@suse.de>
Tested-by: default avatarPaul Donohue <linux-kernel@PaulSD.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8dcee8e8
......@@ -1215,14 +1215,24 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
case SS4_PACKET_ID_TWO:
if (priv->flags & ALPS_BUTTONPAD) {
f->mt[0].x = SS4_BTL_MF_X_V2(p, 0);
if (IS_SS4PLUS_DEV(priv->dev_id)) {
f->mt[0].x = SS4_PLUS_BTL_MF_X_V2(p, 0);
f->mt[1].x = SS4_PLUS_BTL_MF_X_V2(p, 1);
} else {
f->mt[0].x = SS4_BTL_MF_X_V2(p, 0);
f->mt[1].x = SS4_BTL_MF_X_V2(p, 1);
}
f->mt[0].y = SS4_BTL_MF_Y_V2(p, 0);
f->mt[1].x = SS4_BTL_MF_X_V2(p, 1);
f->mt[1].y = SS4_BTL_MF_Y_V2(p, 1);
} else {
f->mt[0].x = SS4_STD_MF_X_V2(p, 0);
if (IS_SS4PLUS_DEV(priv->dev_id)) {
f->mt[0].x = SS4_PLUS_STD_MF_X_V2(p, 0);
f->mt[1].x = SS4_PLUS_STD_MF_X_V2(p, 1);
} else {
f->mt[0].x = SS4_STD_MF_X_V2(p, 0);
f->mt[1].x = SS4_STD_MF_X_V2(p, 1);
}
f->mt[0].y = SS4_STD_MF_Y_V2(p, 0);
f->mt[1].x = SS4_STD_MF_X_V2(p, 1);
f->mt[1].y = SS4_STD_MF_Y_V2(p, 1);
}
f->pressure = SS4_MF_Z_V2(p, 0) ? 0x30 : 0;
......@@ -1239,16 +1249,27 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
case SS4_PACKET_ID_MULTI:
if (priv->flags & ALPS_BUTTONPAD) {
f->mt[2].x = SS4_BTL_MF_X_V2(p, 0);
if (IS_SS4PLUS_DEV(priv->dev_id)) {
f->mt[0].x = SS4_PLUS_BTL_MF_X_V2(p, 0);
f->mt[1].x = SS4_PLUS_BTL_MF_X_V2(p, 1);
} else {
f->mt[2].x = SS4_BTL_MF_X_V2(p, 0);
f->mt[3].x = SS4_BTL_MF_X_V2(p, 1);
}
f->mt[2].y = SS4_BTL_MF_Y_V2(p, 0);
f->mt[3].x = SS4_BTL_MF_X_V2(p, 1);
f->mt[3].y = SS4_BTL_MF_Y_V2(p, 1);
no_data_x = SS4_MFPACKET_NO_AX_BL;
no_data_y = SS4_MFPACKET_NO_AY_BL;
} else {
f->mt[2].x = SS4_STD_MF_X_V2(p, 0);
if (IS_SS4PLUS_DEV(priv->dev_id)) {
f->mt[0].x = SS4_PLUS_STD_MF_X_V2(p, 0);
f->mt[1].x = SS4_PLUS_STD_MF_X_V2(p, 1);
} else {
f->mt[0].x = SS4_STD_MF_X_V2(p, 0);
f->mt[1].x = SS4_STD_MF_X_V2(p, 1);
}
f->mt[2].y = SS4_STD_MF_Y_V2(p, 0);
f->mt[3].x = SS4_STD_MF_X_V2(p, 1);
f->mt[3].y = SS4_STD_MF_Y_V2(p, 1);
no_data_x = SS4_MFPACKET_NO_AX;
no_data_y = SS4_MFPACKET_NO_AY;
......@@ -2541,8 +2562,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
memset(otp, 0, sizeof(otp));
if (alps_get_otp_values_ss4_v2(psmouse, 0, &otp[0][0]) ||
alps_get_otp_values_ss4_v2(psmouse, 1, &otp[1][0]))
if (alps_get_otp_values_ss4_v2(psmouse, 1, &otp[1][0]) ||
alps_get_otp_values_ss4_v2(psmouse, 0, &otp[0][0]))
return -1;
alps_update_device_area_ss4_v2(otp, priv);
......
......@@ -100,6 +100,10 @@ enum SS4_PACKET_ID {
((_b[1 + _i * 3] << 5) & 0x1F00) \
)
#define SS4_PLUS_STD_MF_X_V2(_b, _i) (((_b[0 + (_i) * 3] << 4) & 0x0070) | \
((_b[1 + (_i) * 3] << 4) & 0x0F80) \
)
#define SS4_STD_MF_Y_V2(_b, _i) (((_b[1 + (_i) * 3] << 3) & 0x0010) | \
((_b[2 + (_i) * 3] << 5) & 0x01E0) | \
((_b[2 + (_i) * 3] << 4) & 0x0E00) \
......@@ -109,6 +113,10 @@ enum SS4_PACKET_ID {
((_b[0 + (_i) * 3] >> 3) & 0x0010) \
)
#define SS4_PLUS_BTL_MF_X_V2(_b, _i) (SS4_PLUS_STD_MF_X_V2(_b, _i) | \
((_b[0 + (_i) * 3] >> 4) & 0x0008) \
)
#define SS4_BTL_MF_Y_V2(_b, _i) (SS4_STD_MF_Y_V2(_b, _i) | \
((_b[0 + (_i) * 3] >> 3) & 0x0008) \
)
......
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