Skip to content

Commit b84bd27

Browse files
Benjamin TissoiresJiri Kosina
authored andcommitted
HID: hid-multitouch: fix broken eGalax
Since the inclusion of eGalax devices in 2.6.39, I've got some bug reports for 480d and other devices. The problem lies in the reports descriptors: eGalax supports both pen and fingers, and so the reports descriptors contained both. But hid-multitouch relies on them to detect the last item in each field to send the multitouch events. In 480d, the last item is not Y as it should but Pressure. That means that the fields are not aligned and X,Y are at 0,0 (the other touch coordinates of the report). With this patch, the detection is made only when the field ContactID has been detected inside the collection. There is still a problem with the detections of the range as stylus and fingers may not have the same min/max, but it's a start. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> Reviewed-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
1 parent c2f0197 commit b84bd27

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

drivers/hid/hid-multitouch.c

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct mt_device {
6464
struct mt_class *mtclass; /* our mt device class */
6565
unsigned last_field_index; /* last field index of the report */
6666
unsigned last_slot_field; /* the last field of a slot */
67+
int last_mt_collection; /* last known mt-related collection */
6768
__s8 inputmode; /* InputMode HID feature, -1 if non-existent */
6869
__u8 num_received; /* how many contacts we received */
6970
__u8 num_expected; /* expected last contact index */
@@ -225,8 +226,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
225226
cls->sn_move);
226227
/* touchscreen emulation */
227228
set_abs(hi->input, ABS_X, field, cls->sn_move);
228-
td->last_slot_field = usage->hid;
229-
td->last_field_index = field->index;
229+
if (td->last_mt_collection == usage->collection_index) {
230+
td->last_slot_field = usage->hid;
231+
td->last_field_index = field->index;
232+
}
230233
return 1;
231234
case HID_GD_Y:
232235
if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -237,40 +240,51 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
237240
cls->sn_move);
238241
/* touchscreen emulation */
239242
set_abs(hi->input, ABS_Y, field, cls->sn_move);
240-
td->last_slot_field = usage->hid;
241-
td->last_field_index = field->index;
243+
if (td->last_mt_collection == usage->collection_index) {
244+
td->last_slot_field = usage->hid;
245+
td->last_field_index = field->index;
246+
}
242247
return 1;
243248
}
244249
return 0;
245250

246251
case HID_UP_DIGITIZER:
247252
switch (usage->hid) {
248253
case HID_DG_INRANGE:
249-
td->last_slot_field = usage->hid;
250-
td->last_field_index = field->index;
254+
if (td->last_mt_collection == usage->collection_index) {
255+
td->last_slot_field = usage->hid;
256+
td->last_field_index = field->index;
257+
}
251258
return 1;
252259
case HID_DG_CONFIDENCE:
253-
td->last_slot_field = usage->hid;
254-
td->last_field_index = field->index;
260+
if (td->last_mt_collection == usage->collection_index) {
261+
td->last_slot_field = usage->hid;
262+
td->last_field_index = field->index;
263+
}
255264
return 1;
256265
case HID_DG_TIPSWITCH:
257266
hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
258267
input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
259-
td->last_slot_field = usage->hid;
260-
td->last_field_index = field->index;
268+
if (td->last_mt_collection == usage->collection_index) {
269+
td->last_slot_field = usage->hid;
270+
td->last_field_index = field->index;
271+
}
261272
return 1;
262273
case HID_DG_CONTACTID:
263274
input_mt_init_slots(hi->input, td->maxcontacts);
264275
td->last_slot_field = usage->hid;
265276
td->last_field_index = field->index;
277+
td->last_mt_collection = usage->collection_index;
266278
return 1;
267279
case HID_DG_WIDTH:
268280
hid_map_usage(hi, usage, bit, max,
269281
EV_ABS, ABS_MT_TOUCH_MAJOR);
270282
set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
271283
cls->sn_width);
272-
td->last_slot_field = usage->hid;
273-
td->last_field_index = field->index;
284+
if (td->last_mt_collection == usage->collection_index) {
285+
td->last_slot_field = usage->hid;
286+
td->last_field_index = field->index;
287+
}
274288
return 1;
275289
case HID_DG_HEIGHT:
276290
hid_map_usage(hi, usage, bit, max,
@@ -279,8 +293,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
279293
cls->sn_height);
280294
input_set_abs_params(hi->input,
281295
ABS_MT_ORIENTATION, 0, 1, 0, 0);
282-
td->last_slot_field = usage->hid;
283-
td->last_field_index = field->index;
296+
if (td->last_mt_collection == usage->collection_index) {
297+
td->last_slot_field = usage->hid;
298+
td->last_field_index = field->index;
299+
}
284300
return 1;
285301
case HID_DG_TIPPRESSURE:
286302
if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -292,16 +308,20 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
292308
/* touchscreen emulation */
293309
set_abs(hi->input, ABS_PRESSURE, field,
294310
cls->sn_pressure);
295-
td->last_slot_field = usage->hid;
296-
td->last_field_index = field->index;
311+
if (td->last_mt_collection == usage->collection_index) {
312+
td->last_slot_field = usage->hid;
313+
td->last_field_index = field->index;
314+
}
297315
return 1;
298316
case HID_DG_CONTACTCOUNT:
299-
td->last_field_index = field->index;
317+
if (td->last_mt_collection == usage->collection_index)
318+
td->last_field_index = field->index;
300319
return 1;
301320
case HID_DG_CONTACTMAX:
302321
/* we don't set td->last_slot_field as contactcount and
303322
* contact max are global to the report */
304-
td->last_field_index = field->index;
323+
if (td->last_mt_collection == usage->collection_index)
324+
td->last_field_index = field->index;
305325
return -1;
306326
}
307327
/* let hid-input decide for the others */
@@ -516,6 +536,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
516536
}
517537
td->mtclass = mtclass;
518538
td->inputmode = -1;
539+
td->last_mt_collection = -1;
519540
hid_set_drvdata(hdev, td);
520541

521542
ret = hid_parse(hdev);

0 commit comments

Comments
 (0)