Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: ALPS - fix multi-touch decoding on SS4 plus touchpads

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>
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Nir Perry and committed by
Dmitry Torokhov
4d94e776 48282969

+19 -14
+13 -10
drivers/input/mouse/alps.c
··· 1250 1250 case SS4_PACKET_ID_MULTI: 1251 1251 if (priv->flags & ALPS_BUTTONPAD) { 1252 1252 if (IS_SS4PLUS_DEV(priv->dev_id)) { 1253 - f->mt[0].x = SS4_PLUS_BTL_MF_X_V2(p, 0); 1254 - f->mt[1].x = SS4_PLUS_BTL_MF_X_V2(p, 1); 1253 + f->mt[2].x = SS4_PLUS_BTL_MF_X_V2(p, 0); 1254 + f->mt[3].x = SS4_PLUS_BTL_MF_X_V2(p, 1); 1255 + no_data_x = SS4_PLUS_MFPACKET_NO_AX_BL; 1255 1256 } else { 1256 1257 f->mt[2].x = SS4_BTL_MF_X_V2(p, 0); 1257 1258 f->mt[3].x = SS4_BTL_MF_X_V2(p, 1); 1259 + no_data_x = SS4_MFPACKET_NO_AX_BL; 1258 1260 } 1261 + no_data_y = SS4_MFPACKET_NO_AY_BL; 1259 1262 1260 1263 f->mt[2].y = SS4_BTL_MF_Y_V2(p, 0); 1261 1264 f->mt[3].y = SS4_BTL_MF_Y_V2(p, 1); 1262 - no_data_x = SS4_MFPACKET_NO_AX_BL; 1263 - no_data_y = SS4_MFPACKET_NO_AY_BL; 1264 1265 } else { 1265 1266 if (IS_SS4PLUS_DEV(priv->dev_id)) { 1266 - f->mt[0].x = SS4_PLUS_STD_MF_X_V2(p, 0); 1267 - f->mt[1].x = SS4_PLUS_STD_MF_X_V2(p, 1); 1267 + f->mt[2].x = SS4_PLUS_STD_MF_X_V2(p, 0); 1268 + f->mt[3].x = SS4_PLUS_STD_MF_X_V2(p, 1); 1269 + no_data_x = SS4_PLUS_MFPACKET_NO_AX; 1268 1270 } else { 1269 - f->mt[0].x = SS4_STD_MF_X_V2(p, 0); 1270 - f->mt[1].x = SS4_STD_MF_X_V2(p, 1); 1271 + f->mt[2].x = SS4_STD_MF_X_V2(p, 0); 1272 + f->mt[3].x = SS4_STD_MF_X_V2(p, 1); 1273 + no_data_x = SS4_MFPACKET_NO_AX; 1271 1274 } 1275 + no_data_y = SS4_MFPACKET_NO_AY; 1276 + 1272 1277 f->mt[2].y = SS4_STD_MF_Y_V2(p, 0); 1273 1278 f->mt[3].y = SS4_STD_MF_Y_V2(p, 1); 1274 - no_data_x = SS4_MFPACKET_NO_AX; 1275 - no_data_y = SS4_MFPACKET_NO_AY; 1276 1279 } 1277 1280 1278 1281 f->first_mp = 0;
+6 -4
drivers/input/mouse/alps.h
··· 141 141 #define SS4_TS_Z_V2(_b) (s8)(_b[4] & 0x7F) 142 142 143 143 144 - #define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */ 145 - #define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */ 146 - #define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coordinate value */ 147 - #define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coordinate value */ 144 + #define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */ 145 + #define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */ 146 + #define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coord value */ 147 + #define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coord value */ 148 + #define SS4_PLUS_MFPACKET_NO_AX 4080 /* SS4 PLUS, X */ 149 + #define SS4_PLUS_MFPACKET_NO_AX_BL 4088 /* Buttonless SS4 PLUS, X */ 148 150 149 151 /* 150 152 * enum V7_PACKET_ID - defines the packet type for V7