Skip to content

Commit

Permalink
HID: multitouch: Only look at non touch fields in first packet of a f…
Browse files Browse the repository at this point in the history
…rame

Devices in "single finger hybrid mode" will send one report per finger,
on some devices only the first report of such a multi-packet frame will
contain a value for BTN_LEFT, in subsequent reports (if multiple fingers
are down) the value is always 0, causing hid-mt to report BTN_LEFT going
1 - 0 - 1 - 0 when pressing a clickpad and putting down a second finger.
This happens for example on USB 0603:0002 mt touchpads.

This commit fixes this by only reporting non touch fields for the first
packet of a (possibly) multi-packet frame.

Signed-off-by: Hans de Goede <[email protected]>
Reviewed-by: Benjamin Tissoires <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
  • Loading branch information
jwrdegoede authored and Jiri Kosina committed Nov 22, 2017
1 parent af8dc4d commit 55746d2
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions drivers/hid/hid-multitouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,9 +787,11 @@ static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
}

static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value)
struct hid_usage *usage, __s32 value,
bool first_packet)
{
struct mt_device *td = hid_get_drvdata(hid);
__s32 cls = td->mtclass.name;
__s32 quirks = td->mtclass.quirks;
struct input_dev *input = field->hidinput->input;

Expand Down Expand Up @@ -846,6 +848,15 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
break;

default:
/*
* For Win8 PTP touchpads we should only look at
* non finger/touch events in the first_packet of
* a (possible) multi-packet frame.
*/
if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
!first_packet)
return;

if (usage->type)
input_event(input, usage->type, usage->code,
value);
Expand All @@ -866,6 +877,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
struct mt_device *td = hid_get_drvdata(hid);
__s32 cls = td->mtclass.name;
struct hid_field *field;
bool first_packet;
unsigned count;
int r, n, scantime = 0;

Expand Down Expand Up @@ -901,6 +913,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
}
td->prev_scantime = scantime;

first_packet = td->num_received == 0;
for (r = 0; r < report->maxfield; r++) {
field = report->field[r];
count = field->report_count;
Expand All @@ -910,7 +923,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)

for (n = 0; n < count; n++)
mt_process_mt_event(hid, field, &field->usage[n],
field->value[n]);
field->value[n], first_packet);
}

if (td->num_received >= td->num_expected)
Expand Down

0 comments on commit 55746d2

Please sign in to comment.