| From 4d94e776bd29670f01befa27e12df784fa05fa2e Mon Sep 17 00:00:00 2001 |
| From: Nir Perry <nirperry@gmail.com> |
| Date: Thu, 11 Jan 2018 23:43:26 -0800 |
| Subject: Input: ALPS - fix multi-touch decoding on SS4 plus touchpads |
| |
| From: Nir Perry <nirperry@gmail.com> |
| |
| commit 4d94e776bd29670f01befa27e12df784fa05fa2e upstream. |
| |
| The fix for handling two-finger scroll (i4a646580f793 - "Input: ALPS - |
| fix two-finger scroll breakage in right side on ALPS touchpad") |
| introduced a minor "typo" that broke decoding of multi-touch events are |
| decoded on some ALPS touchpads. For example, tapping with three-fingers |
| can no longer be used to emulate middle-mouse-button (the kernel doesn't |
| recognize this as the proper event, and doesn't report it correctly to |
| userspace). This affects touchpads that use SS4 "plus" protocol |
| variant, like those found on Dell E7270 & E7470 laptops (tested on |
| E7270). |
| |
| First, probably the code in alps_decode_ss4_v2() for case |
| SS4_PACKET_ID_MULTI used inconsistent indices to "f->mt[]". You can see |
| 0 & 1 are used for the "if" part but 2 & 3 are used for the "else" part. |
| |
| Second, in the previous patch, new macros were introduced to decode X |
| coordinates specific to the SS4 "plus" variant, but the macro to |
| define the maximum X value wasn't changed accordingly. The macros to |
| decode X values for "plus" variant are effectively shifted right by 1 |
| bit, but the max wasn't shifted too. This causes the driver to |
| incorrectly handle "no data" cases, which also interfered with how |
| multi-touch was handled. |
| |
| Fixes: 4a646580f793 ("Input: ALPS - fix two-finger scroll breakage...") |
| Signed-off-by: Nir Perry <nirperry@gmail.com> |
| Reviewed-by: Masaki Ota <masaki.ota@jp.alps.com> |
| Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/input/mouse/alps.c | 23 +++++++++++++---------- |
| drivers/input/mouse/alps.h | 10 ++++++---- |
| 2 files changed, 19 insertions(+), 14 deletions(-) |
| |
| --- a/drivers/input/mouse/alps.c |
| +++ b/drivers/input/mouse/alps.c |
| @@ -1250,29 +1250,32 @@ static int alps_decode_ss4_v2(struct alp |
| case SS4_PACKET_ID_MULTI: |
| if (priv->flags & ALPS_BUTTONPAD) { |
| 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); |
| + f->mt[2].x = SS4_PLUS_BTL_MF_X_V2(p, 0); |
| + f->mt[3].x = SS4_PLUS_BTL_MF_X_V2(p, 1); |
| + no_data_x = SS4_PLUS_MFPACKET_NO_AX_BL; |
| } else { |
| f->mt[2].x = SS4_BTL_MF_X_V2(p, 0); |
| f->mt[3].x = SS4_BTL_MF_X_V2(p, 1); |
| + no_data_x = SS4_MFPACKET_NO_AX_BL; |
| } |
| + no_data_y = SS4_MFPACKET_NO_AY_BL; |
| |
| f->mt[2].y = SS4_BTL_MF_Y_V2(p, 0); |
| 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 { |
| 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); |
| + f->mt[2].x = SS4_PLUS_STD_MF_X_V2(p, 0); |
| + f->mt[3].x = SS4_PLUS_STD_MF_X_V2(p, 1); |
| + no_data_x = SS4_PLUS_MFPACKET_NO_AX; |
| } 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].x = SS4_STD_MF_X_V2(p, 0); |
| + f->mt[3].x = SS4_STD_MF_X_V2(p, 1); |
| + no_data_x = SS4_MFPACKET_NO_AX; |
| } |
| + no_data_y = SS4_MFPACKET_NO_AY; |
| + |
| f->mt[2].y = SS4_STD_MF_Y_V2(p, 0); |
| 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; |
| } |
| |
| f->first_mp = 0; |
| --- a/drivers/input/mouse/alps.h |
| +++ b/drivers/input/mouse/alps.h |
| @@ -141,10 +141,12 @@ enum SS4_PACKET_ID { |
| #define SS4_TS_Z_V2(_b) (s8)(_b[4] & 0x7F) |
| |
| |
| -#define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */ |
| -#define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */ |
| -#define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coordinate value */ |
| -#define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coordinate value */ |
| +#define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */ |
| +#define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */ |
| +#define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coord value */ |
| +#define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coord value */ |
| +#define SS4_PLUS_MFPACKET_NO_AX 4080 /* SS4 PLUS, X */ |
| +#define SS4_PLUS_MFPACKET_NO_AX_BL 4088 /* Buttonless SS4 PLUS, X */ |
| |
| /* |
| * enum V7_PACKET_ID - defines the packet type for V7 |