diff options
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r-- | drivers/hid/hid-multitouch.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ecd4d2db9e80..62cac4dc3b62 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -64,6 +64,7 @@ struct mt_device { | |||
64 | struct mt_class *mtclass; /* our mt device class */ | 64 | struct mt_class *mtclass; /* our mt device class */ |
65 | unsigned last_field_index; /* last field index of the report */ | 65 | unsigned last_field_index; /* last field index of the report */ |
66 | unsigned last_slot_field; /* the last field of a slot */ | 66 | unsigned last_slot_field; /* the last field of a slot */ |
67 | int last_mt_collection; /* last known mt-related collection */ | ||
67 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 68 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
68 | __u8 num_received; /* how many contacts we received */ | 69 | __u8 num_received; /* how many contacts we received */ |
69 | __u8 num_expected; /* expected last contact index */ | 70 | __u8 num_expected; /* expected last contact index */ |
@@ -225,8 +226,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
225 | cls->sn_move); | 226 | cls->sn_move); |
226 | /* touchscreen emulation */ | 227 | /* touchscreen emulation */ |
227 | set_abs(hi->input, ABS_X, field, cls->sn_move); | 228 | set_abs(hi->input, ABS_X, field, cls->sn_move); |
228 | td->last_slot_field = usage->hid; | 229 | if (td->last_mt_collection == usage->collection_index) { |
229 | td->last_field_index = field->index; | 230 | td->last_slot_field = usage->hid; |
231 | td->last_field_index = field->index; | ||
232 | } | ||
230 | return 1; | 233 | return 1; |
231 | case HID_GD_Y: | 234 | case HID_GD_Y: |
232 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) | 235 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) |
@@ -237,8 +240,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
237 | cls->sn_move); | 240 | cls->sn_move); |
238 | /* touchscreen emulation */ | 241 | /* touchscreen emulation */ |
239 | set_abs(hi->input, ABS_Y, field, cls->sn_move); | 242 | set_abs(hi->input, ABS_Y, field, cls->sn_move); |
240 | td->last_slot_field = usage->hid; | 243 | if (td->last_mt_collection == usage->collection_index) { |
241 | td->last_field_index = field->index; | 244 | td->last_slot_field = usage->hid; |
245 | td->last_field_index = field->index; | ||
246 | } | ||
242 | return 1; | 247 | return 1; |
243 | } | 248 | } |
244 | return 0; | 249 | return 0; |
@@ -246,31 +251,42 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
246 | case HID_UP_DIGITIZER: | 251 | case HID_UP_DIGITIZER: |
247 | switch (usage->hid) { | 252 | switch (usage->hid) { |
248 | case HID_DG_INRANGE: | 253 | case HID_DG_INRANGE: |
249 | td->last_slot_field = usage->hid; | 254 | if (td->last_mt_collection == usage->collection_index) { |
250 | td->last_field_index = field->index; | 255 | td->last_slot_field = usage->hid; |
256 | td->last_field_index = field->index; | ||
257 | } | ||
251 | return 1; | 258 | return 1; |
252 | case HID_DG_CONFIDENCE: | 259 | case HID_DG_CONFIDENCE: |
253 | td->last_slot_field = usage->hid; | 260 | if (td->last_mt_collection == usage->collection_index) { |
254 | td->last_field_index = field->index; | 261 | td->last_slot_field = usage->hid; |
262 | td->last_field_index = field->index; | ||
263 | } | ||
255 | return 1; | 264 | return 1; |
256 | case HID_DG_TIPSWITCH: | 265 | case HID_DG_TIPSWITCH: |
257 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 266 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
258 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 267 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
259 | td->last_slot_field = usage->hid; | 268 | if (td->last_mt_collection == usage->collection_index) { |
260 | td->last_field_index = field->index; | 269 | td->last_slot_field = usage->hid; |
270 | td->last_field_index = field->index; | ||
271 | } | ||
261 | return 1; | 272 | return 1; |
262 | case HID_DG_CONTACTID: | 273 | case HID_DG_CONTACTID: |
274 | if (!td->maxcontacts) | ||
275 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | ||
263 | input_mt_init_slots(hi->input, td->maxcontacts); | 276 | input_mt_init_slots(hi->input, td->maxcontacts); |
264 | td->last_slot_field = usage->hid; | 277 | td->last_slot_field = usage->hid; |
265 | td->last_field_index = field->index; | 278 | td->last_field_index = field->index; |
279 | td->last_mt_collection = usage->collection_index; | ||
266 | return 1; | 280 | return 1; |
267 | case HID_DG_WIDTH: | 281 | case HID_DG_WIDTH: |
268 | hid_map_usage(hi, usage, bit, max, | 282 | hid_map_usage(hi, usage, bit, max, |
269 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 283 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
270 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | 284 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, |
271 | cls->sn_width); | 285 | cls->sn_width); |
272 | td->last_slot_field = usage->hid; | 286 | if (td->last_mt_collection == usage->collection_index) { |
273 | td->last_field_index = field->index; | 287 | td->last_slot_field = usage->hid; |
288 | td->last_field_index = field->index; | ||
289 | } | ||
274 | return 1; | 290 | return 1; |
275 | case HID_DG_HEIGHT: | 291 | case HID_DG_HEIGHT: |
276 | hid_map_usage(hi, usage, bit, max, | 292 | hid_map_usage(hi, usage, bit, max, |
@@ -279,8 +295,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
279 | cls->sn_height); | 295 | cls->sn_height); |
280 | input_set_abs_params(hi->input, | 296 | input_set_abs_params(hi->input, |
281 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | 297 | ABS_MT_ORIENTATION, 0, 1, 0, 0); |
282 | td->last_slot_field = usage->hid; | 298 | if (td->last_mt_collection == usage->collection_index) { |
283 | td->last_field_index = field->index; | 299 | td->last_slot_field = usage->hid; |
300 | td->last_field_index = field->index; | ||
301 | } | ||
284 | return 1; | 302 | return 1; |
285 | case HID_DG_TIPPRESSURE: | 303 | case HID_DG_TIPPRESSURE: |
286 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) | 304 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) |
@@ -292,16 +310,20 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
292 | /* touchscreen emulation */ | 310 | /* touchscreen emulation */ |
293 | set_abs(hi->input, ABS_PRESSURE, field, | 311 | set_abs(hi->input, ABS_PRESSURE, field, |
294 | cls->sn_pressure); | 312 | cls->sn_pressure); |
295 | td->last_slot_field = usage->hid; | 313 | if (td->last_mt_collection == usage->collection_index) { |
296 | td->last_field_index = field->index; | 314 | td->last_slot_field = usage->hid; |
315 | td->last_field_index = field->index; | ||
316 | } | ||
297 | return 1; | 317 | return 1; |
298 | case HID_DG_CONTACTCOUNT: | 318 | case HID_DG_CONTACTCOUNT: |
299 | td->last_field_index = field->index; | 319 | if (td->last_mt_collection == usage->collection_index) |
320 | td->last_field_index = field->index; | ||
300 | return 1; | 321 | return 1; |
301 | case HID_DG_CONTACTMAX: | 322 | case HID_DG_CONTACTMAX: |
302 | /* we don't set td->last_slot_field as contactcount and | 323 | /* we don't set td->last_slot_field as contactcount and |
303 | * contact max are global to the report */ | 324 | * contact max are global to the report */ |
304 | td->last_field_index = field->index; | 325 | if (td->last_mt_collection == usage->collection_index) |
326 | td->last_field_index = field->index; | ||
305 | return -1; | 327 | return -1; |
306 | } | 328 | } |
307 | /* let hid-input decide for the others */ | 329 | /* let hid-input decide for the others */ |
@@ -516,6 +538,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
516 | } | 538 | } |
517 | td->mtclass = mtclass; | 539 | td->mtclass = mtclass; |
518 | td->inputmode = -1; | 540 | td->inputmode = -1; |
541 | td->last_mt_collection = -1; | ||
519 | hid_set_drvdata(hdev, td); | 542 | hid_set_drvdata(hdev, td); |
520 | 543 | ||
521 | ret = hid_parse(hdev); | 544 | ret = hid_parse(hdev); |
@@ -526,9 +549,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
526 | if (ret) | 549 | if (ret) |
527 | goto fail; | 550 | goto fail; |
528 | 551 | ||
529 | if (!td->maxcontacts) | ||
530 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | ||
531 | |||
532 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), | 552 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), |
533 | GFP_KERNEL); | 553 | GFP_KERNEL); |
534 | if (!td->slots) { | 554 | if (!td->slots) { |
@@ -593,6 +613,11 @@ static const struct hid_device_id mt_devices[] = { | |||
593 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 613 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
594 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | 614 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, |
595 | 615 | ||
616 | /* Chunghwa Telecom touch panels */ | ||
617 | { .driver_data = MT_CLS_DEFAULT, | ||
618 | HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, | ||
619 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | ||
620 | |||
596 | /* CVTouch panels */ | 621 | /* CVTouch panels */ |
597 | { .driver_data = MT_CLS_DEFAULT, | 622 | { .driver_data = MT_CLS_DEFAULT, |
598 | HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, | 623 | HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, |
@@ -651,6 +676,9 @@ static const struct hid_device_id mt_devices[] = { | |||
651 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 676 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
652 | HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, | 677 | HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, |
653 | USB_DEVICE_ID_CRYSTALTOUCH) }, | 678 | USB_DEVICE_ID_CRYSTALTOUCH) }, |
679 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
680 | HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, | ||
681 | USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, | ||
654 | 682 | ||
655 | /* MosArt panels */ | 683 | /* MosArt panels */ |
656 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 684 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
@@ -681,10 +709,10 @@ static const struct hid_device_id mt_devices[] = { | |||
681 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, | 709 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
682 | USB_DEVICE_ID_MTP)}, | 710 | USB_DEVICE_ID_MTP)}, |
683 | { .driver_data = MT_CLS_CONFIDENCE, | 711 | { .driver_data = MT_CLS_CONFIDENCE, |
684 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, | 712 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, |
685 | USB_DEVICE_ID_MTP_STM)}, | 713 | USB_DEVICE_ID_MTP_STM)}, |
686 | { .driver_data = MT_CLS_CONFIDENCE, | 714 | { .driver_data = MT_CLS_CONFIDENCE, |
687 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, | 715 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, |
688 | USB_DEVICE_ID_MTP_SITRONIX)}, | 716 | USB_DEVICE_ID_MTP_SITRONIX)}, |
689 | 717 | ||
690 | /* Touch International panels */ | 718 | /* Touch International panels */ |