mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
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: 4f4001bc76 ("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>
This commit is contained in:
parent
aa4daea418
commit
46f781e0d1
|
|
@ -94,9 +94,8 @@ enum report_mode {
|
||||||
TOUCHPAD_REPORT_ALL = TOUCHPAD_REPORT_BUTTONS | TOUCHPAD_REPORT_CONTACTS,
|
TOUCHPAD_REPORT_ALL = TOUCHPAD_REPORT_BUTTONS | TOUCHPAD_REPORT_CONTACTS,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MT_IO_FLAGS_RUNNING 0
|
#define MT_IO_SLOTS_MASK GENMASK(7, 0) /* reserve first 8 bits for slot tracking */
|
||||||
#define MT_IO_FLAGS_ACTIVE_SLOTS 1
|
#define MT_IO_FLAGS_RUNNING 32
|
||||||
#define MT_IO_FLAGS_PENDING_SLOTS 2
|
|
||||||
|
|
||||||
static const bool mtrue = true; /* default for true */
|
static const bool mtrue = true; /* default for true */
|
||||||
static const bool mfalse; /* default for false */
|
static const bool mfalse; /* default for false */
|
||||||
|
|
@ -172,7 +171,11 @@ struct mt_device {
|
||||||
struct timer_list release_timer; /* to release sticky fingers */
|
struct timer_list release_timer; /* to release sticky fingers */
|
||||||
struct hid_haptic_device *haptic; /* haptic related configuration */
|
struct hid_haptic_device *haptic; /* haptic related configuration */
|
||||||
struct hid_device *hdev; /* hid_device we're attached to */
|
struct hid_device *hdev; /* hid_device we're attached to */
|
||||||
unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */
|
unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING)
|
||||||
|
* first 8 bits are reserved for keeping the slot
|
||||||
|
* states, this is fine because we only support up
|
||||||
|
* to 250 slots (MT_MAX_MAXCONTACT)
|
||||||
|
*/
|
||||||
__u8 inputmode_value; /* InputMode HID feature value */
|
__u8 inputmode_value; /* InputMode HID feature value */
|
||||||
__u8 maxcontacts;
|
__u8 maxcontacts;
|
||||||
bool is_buttonpad; /* is this device a button pad? */
|
bool is_buttonpad; /* is this device a button pad? */
|
||||||
|
|
@ -986,6 +989,7 @@ static void mt_release_pending_palms(struct mt_device *td,
|
||||||
|
|
||||||
for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) {
|
for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) {
|
||||||
clear_bit(slotnum, app->pending_palm_slots);
|
clear_bit(slotnum, app->pending_palm_slots);
|
||||||
|
clear_bit(slotnum, &td->mt_io_flags);
|
||||||
|
|
||||||
input_mt_slot(input, slotnum);
|
input_mt_slot(input, slotnum);
|
||||||
input_mt_report_slot_inactive(input);
|
input_mt_report_slot_inactive(input);
|
||||||
|
|
@ -1019,12 +1023,6 @@ static void mt_sync_frame(struct mt_device *td, struct mt_application *app,
|
||||||
app->left_button_state = 0;
|
app->left_button_state = 0;
|
||||||
if (td->is_haptic_touchpad)
|
if (td->is_haptic_touchpad)
|
||||||
hid_haptic_pressure_reset(td->haptic);
|
hid_haptic_pressure_reset(td->haptic);
|
||||||
|
|
||||||
if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags))
|
|
||||||
set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
|
|
||||||
else
|
|
||||||
clear_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
|
|
||||||
clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt_compute_timestamp(struct mt_application *app, __s32 value)
|
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,
|
||||||
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
|
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
|
||||||
input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
|
input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
|
||||||
|
|
||||||
set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
|
set_bit(slotnum, &td->mt_io_flags);
|
||||||
|
} else {
|
||||||
|
clear_bit(slotnum, &td->mt_io_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1337,7 +1337,7 @@ static void mt_touch_report(struct hid_device *hid,
|
||||||
* defect.
|
* defect.
|
||||||
*/
|
*/
|
||||||
if (app->quirks & MT_QUIRK_STICKY_FINGERS) {
|
if (app->quirks & MT_QUIRK_STICKY_FINGERS) {
|
||||||
if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
|
if (td->mt_io_flags & MT_IO_SLOTS_MASK)
|
||||||
mod_timer(&td->release_timer,
|
mod_timer(&td->release_timer,
|
||||||
jiffies + msecs_to_jiffies(100));
|
jiffies + msecs_to_jiffies(100));
|
||||||
else
|
else
|
||||||
|
|
@ -1814,6 +1814,7 @@ static void mt_release_contacts(struct hid_device *hid)
|
||||||
for (i = 0; i < mt->num_slots; i++) {
|
for (i = 0; i < mt->num_slots; i++) {
|
||||||
input_mt_slot(input_dev, i);
|
input_mt_slot(input_dev, i);
|
||||||
input_mt_report_slot_inactive(input_dev);
|
input_mt_report_slot_inactive(input_dev);
|
||||||
|
clear_bit(i, &td->mt_io_flags);
|
||||||
}
|
}
|
||||||
input_mt_sync_frame(input_dev);
|
input_mt_sync_frame(input_dev);
|
||||||
input_sync(input_dev);
|
input_sync(input_dev);
|
||||||
|
|
@ -1836,7 +1837,7 @@ static void mt_expired_timeout(struct timer_list *t)
|
||||||
*/
|
*/
|
||||||
if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
||||||
return;
|
return;
|
||||||
if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
|
if (td->mt_io_flags & MT_IO_SLOTS_MASK)
|
||||||
mt_release_contacts(hdev);
|
mt_release_contacts(hdev);
|
||||||
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
|
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user