Skip to content

Commit 46f781e

Browse files
Benjamin TissoiresJiri Kosina
authored andcommitted
HID: multitouch: fix sticky fingers
The sticky fingers quirk (MT_QUIRK_STICKY_FINGERS) was only considering the case when slots were not released during the last report. This can be problematic if the firmware forgets to release a finger while others are still present. This was observed on the Synaptics DLL0945 touchpad found on the Dell XPS 9310 and the Dell Inspiron 5406. Fixes: 4f4001b ("HID: multitouch: fix rare Win 8 cases when the touch up event gets missing") Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent aa4daea commit 46f781e

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

drivers/hid/hid-multitouch.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,8 @@ enum report_mode {
9494
TOUCHPAD_REPORT_ALL = TOUCHPAD_REPORT_BUTTONS | TOUCHPAD_REPORT_CONTACTS,
9595
};
9696

97-
#define MT_IO_FLAGS_RUNNING 0
98-
#define MT_IO_FLAGS_ACTIVE_SLOTS 1
99-
#define MT_IO_FLAGS_PENDING_SLOTS 2
97+
#define MT_IO_SLOTS_MASK GENMASK(7, 0) /* reserve first 8 bits for slot tracking */
98+
#define MT_IO_FLAGS_RUNNING 32
10099

101100
static const bool mtrue = true; /* default for true */
102101
static const bool mfalse; /* default for false */
@@ -172,7 +171,11 @@ struct mt_device {
172171
struct timer_list release_timer; /* to release sticky fingers */
173172
struct hid_haptic_device *haptic; /* haptic related configuration */
174173
struct hid_device *hdev; /* hid_device we're attached to */
175-
unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */
174+
unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING)
175+
* first 8 bits are reserved for keeping the slot
176+
* states, this is fine because we only support up
177+
* to 250 slots (MT_MAX_MAXCONTACT)
178+
*/
176179
__u8 inputmode_value; /* InputMode HID feature value */
177180
__u8 maxcontacts;
178181
bool is_buttonpad; /* is this device a button pad? */
@@ -986,6 +989,7 @@ static void mt_release_pending_palms(struct mt_device *td,
986989

987990
for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) {
988991
clear_bit(slotnum, app->pending_palm_slots);
992+
clear_bit(slotnum, &td->mt_io_flags);
989993

990994
input_mt_slot(input, slotnum);
991995
input_mt_report_slot_inactive(input);
@@ -1019,12 +1023,6 @@ static void mt_sync_frame(struct mt_device *td, struct mt_application *app,
10191023
app->left_button_state = 0;
10201024
if (td->is_haptic_touchpad)
10211025
hid_haptic_pressure_reset(td->haptic);
1022-
1023-
if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags))
1024-
set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
1025-
else
1026-
clear_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
1027-
clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
10281026
}
10291027

10301028
static int mt_compute_timestamp(struct mt_application *app, __s32 value)
@@ -1202,7 +1200,9 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
12021200
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
12031201
input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
12041202

1205-
set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
1203+
set_bit(slotnum, &td->mt_io_flags);
1204+
} else {
1205+
clear_bit(slotnum, &td->mt_io_flags);
12061206
}
12071207

12081208
return 0;
@@ -1337,7 +1337,7 @@ static void mt_touch_report(struct hid_device *hid,
13371337
* defect.
13381338
*/
13391339
if (app->quirks & MT_QUIRK_STICKY_FINGERS) {
1340-
if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
1340+
if (td->mt_io_flags & MT_IO_SLOTS_MASK)
13411341
mod_timer(&td->release_timer,
13421342
jiffies + msecs_to_jiffies(100));
13431343
else
@@ -1814,6 +1814,7 @@ static void mt_release_contacts(struct hid_device *hid)
18141814
for (i = 0; i < mt->num_slots; i++) {
18151815
input_mt_slot(input_dev, i);
18161816
input_mt_report_slot_inactive(input_dev);
1817+
clear_bit(i, &td->mt_io_flags);
18171818
}
18181819
input_mt_sync_frame(input_dev);
18191820
input_sync(input_dev);
@@ -1836,7 +1837,7 @@ static void mt_expired_timeout(struct timer_list *t)
18361837
*/
18371838
if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
18381839
return;
1839-
if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
1840+
if (td->mt_io_flags & MT_IO_SLOTS_MASK)
18401841
mt_release_contacts(hdev);
18411842
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
18421843
}

0 commit comments

Comments
 (0)