diff options
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r-- | drivers/hid/hid-multitouch.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ecd4d2db9e80..0b2dcd0ee591 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,40 @@ 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: |
263 | input_mt_init_slots(hi->input, td->maxcontacts); | 274 | input_mt_init_slots(hi->input, td->maxcontacts); |
264 | td->last_slot_field = usage->hid; | 275 | td->last_slot_field = usage->hid; |
265 | td->last_field_index = field->index; | 276 | td->last_field_index = field->index; |
277 | td->last_mt_collection = usage->collection_index; | ||
266 | return 1; | 278 | return 1; |
267 | case HID_DG_WIDTH: | 279 | case HID_DG_WIDTH: |
268 | hid_map_usage(hi, usage, bit, max, | 280 | hid_map_usage(hi, usage, bit, max, |
269 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 281 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
270 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | 282 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, |
271 | cls->sn_width); | 283 | cls->sn_width); |
272 | td->last_slot_field = usage->hid; | 284 | if (td->last_mt_collection == usage->collection_index) { |
273 | td->last_field_index = field->index; | 285 | td->last_slot_field = usage->hid; |
286 | td->last_field_index = field->index; | ||
287 | } | ||
274 | return 1; | 288 | return 1; |
275 | case HID_DG_HEIGHT: | 289 | case HID_DG_HEIGHT: |
276 | hid_map_usage(hi, usage, bit, max, | 290 | hid_map_usage(hi, usage, bit, max, |
@@ -279,8 +293,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
279 | cls->sn_height); | 293 | cls->sn_height); |
280 | input_set_abs_params(hi->input, | 294 | input_set_abs_params(hi->input, |
281 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | 295 | ABS_MT_ORIENTATION, 0, 1, 0, 0); |
282 | td->last_slot_field = usage->hid; | 296 | if (td->last_mt_collection == usage->collection_index) { |
283 | td->last_field_index = field->index; | 297 | td->last_slot_field = usage->hid; |
298 | td->last_field_index = field->index; | ||
299 | } | ||
284 | return 1; | 300 | return 1; |
285 | case HID_DG_TIPPRESSURE: | 301 | case HID_DG_TIPPRESSURE: |
286 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) | 302 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) |
@@ -292,16 +308,20 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
292 | /* touchscreen emulation */ | 308 | /* touchscreen emulation */ |
293 | set_abs(hi->input, ABS_PRESSURE, field, | 309 | set_abs(hi->input, ABS_PRESSURE, field, |
294 | cls->sn_pressure); | 310 | cls->sn_pressure); |
295 | td->last_slot_field = usage->hid; | 311 | if (td->last_mt_collection == usage->collection_index) { |
296 | td->last_field_index = field->index; | 312 | td->last_slot_field = usage->hid; |
313 | td->last_field_index = field->index; | ||
314 | } | ||
297 | return 1; | 315 | return 1; |
298 | case HID_DG_CONTACTCOUNT: | 316 | 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; | ||
300 | return 1; | 319 | return 1; |
301 | case HID_DG_CONTACTMAX: | 320 | case HID_DG_CONTACTMAX: |
302 | /* we don't set td->last_slot_field as contactcount and | 321 | /* we don't set td->last_slot_field as contactcount and |
303 | * contact max are global to the report */ | 322 | * 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; | ||
305 | return -1; | 325 | return -1; |
306 | } | 326 | } |
307 | /* let hid-input decide for the others */ | 327 | /* 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) | |||
516 | } | 536 | } |
517 | td->mtclass = mtclass; | 537 | td->mtclass = mtclass; |
518 | td->inputmode = -1; | 538 | td->inputmode = -1; |
539 | td->last_mt_collection = -1; | ||
519 | hid_set_drvdata(hdev, td); | 540 | hid_set_drvdata(hdev, td); |
520 | 541 | ||
521 | ret = hid_parse(hdev); | 542 | ret = hid_parse(hdev); |
@@ -593,6 +614,11 @@ static const struct hid_device_id mt_devices[] = { | |||
593 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 614 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
594 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | 615 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, |
595 | 616 | ||
617 | /* Chunghwa Telecom touch panels */ | ||
618 | { .driver_data = MT_CLS_DEFAULT, | ||
619 | HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, | ||
620 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | ||
621 | |||
596 | /* CVTouch panels */ | 622 | /* CVTouch panels */ |
597 | { .driver_data = MT_CLS_DEFAULT, | 623 | { .driver_data = MT_CLS_DEFAULT, |
598 | HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, | 624 | HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, |