aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-input.c11
-rw-r--r--drivers/hid/hid-magicmouse.c2
-rw-r--r--drivers/hid/hid-multitouch.c185
4 files changed, 98 insertions, 103 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 1dcb76ff51e3..c843db9e283f 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -283,6 +283,9 @@
283#define USB_VENDOR_ID_EMS 0x2006 283#define USB_VENDOR_ID_EMS 0x2006
284#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118 284#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118
285 285
286#define USB_VENDOR_ID_FLATFROG 0x25b5
287#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002
288
286#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f 289#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
287#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 290#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
288 291
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 811bfad64609..d917c0d53685 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1154,6 +1154,7 @@ static void report_features(struct hid_device *hid)
1154 1154
1155int hidinput_connect(struct hid_device *hid, unsigned int force) 1155int hidinput_connect(struct hid_device *hid, unsigned int force)
1156{ 1156{
1157 struct hid_driver *drv = hid->driver;
1157 struct hid_report *report; 1158 struct hid_report *report;
1158 struct hid_input *hidinput = NULL; 1159 struct hid_input *hidinput = NULL;
1159 struct input_dev *input_dev; 1160 struct input_dev *input_dev;
@@ -1228,6 +1229,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1228 * UGCI) cram a lot of unrelated inputs into the 1229 * UGCI) cram a lot of unrelated inputs into the
1229 * same interface. */ 1230 * same interface. */
1230 hidinput->report = report; 1231 hidinput->report = report;
1232 if (drv->input_configured)
1233 drv->input_configured(hid, hidinput);
1231 if (input_register_device(hidinput->input)) 1234 if (input_register_device(hidinput->input))
1232 goto out_cleanup; 1235 goto out_cleanup;
1233 hidinput = NULL; 1236 hidinput = NULL;
@@ -1235,8 +1238,12 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1235 } 1238 }
1236 } 1239 }
1237 1240
1238 if (hidinput && input_register_device(hidinput->input)) 1241 if (hidinput) {
1239 goto out_cleanup; 1242 if (drv->input_configured)
1243 drv->input_configured(hid, hidinput);
1244 if (input_register_device(hidinput->input))
1245 goto out_cleanup;
1246 }
1240 1247
1241 return 0; 1248 return 0;
1242 1249
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 73647266daad..25ddf3e3aec6 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -392,7 +392,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
392 392
393 __set_bit(EV_ABS, input->evbit); 393 __set_bit(EV_ABS, input->evbit);
394 394
395 error = input_mt_init_slots(input, 16); 395 error = input_mt_init_slots(input, 16, 0);
396 if (error) 396 if (error)
397 return error; 397 return error;
398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, 398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 59c8b5c1d2de..ee0b76b398cb 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -51,12 +51,12 @@ MODULE_LICENSE("GPL");
51#define MT_QUIRK_VALID_IS_INRANGE (1 << 5) 51#define MT_QUIRK_VALID_IS_INRANGE (1 << 5)
52#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) 52#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6)
53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) 53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
54#define MT_QUIRK_NO_AREA (1 << 9)
54 55
55struct mt_slot { 56struct mt_slot {
56 __s32 x, y, p, w, h; 57 __s32 x, y, p, w, h;
57 __s32 contactid; /* the device ContactID assigned to this slot */ 58 __s32 contactid; /* the device ContactID assigned to this slot */
58 bool touch_state; /* is the touch valid? */ 59 bool touch_state; /* is the touch valid? */
59 bool seen_in_this_frame;/* has this slot been updated */
60}; 60};
61 61
62struct mt_class { 62struct mt_class {
@@ -92,8 +92,9 @@ struct mt_device {
92 __u8 touches_by_report; /* how many touches are present in one report: 92 __u8 touches_by_report; /* how many touches are present in one report:
93 * 1 means we should use a serial protocol 93 * 1 means we should use a serial protocol
94 * > 1 means hybrid (multitouch) protocol */ 94 * > 1 means hybrid (multitouch) protocol */
95 bool serial_maybe; /* need to check for serial protocol */
95 bool curvalid; /* is the current contact valid? */ 96 bool curvalid; /* is the current contact valid? */
96 struct mt_slot *slots; 97 unsigned mt_flags; /* flags to pass to input-mt */
97}; 98};
98 99
99/* classes of device behavior */ 100/* classes of device behavior */
@@ -115,6 +116,7 @@ struct mt_device {
115#define MT_CLS_EGALAX_SERIAL 0x0104 116#define MT_CLS_EGALAX_SERIAL 0x0104
116#define MT_CLS_TOPSEED 0x0105 117#define MT_CLS_TOPSEED 0x0105
117#define MT_CLS_PANASONIC 0x0106 118#define MT_CLS_PANASONIC 0x0106
119#define MT_CLS_FLATFROG 0x0107
118 120
119#define MT_DEFAULT_MAXCONTACT 10 121#define MT_DEFAULT_MAXCONTACT 10
120 122
@@ -134,25 +136,6 @@ static int cypress_compute_slot(struct mt_device *td)
134 return -1; 136 return -1;
135} 137}
136 138
137static int find_slot_from_contactid(struct mt_device *td)
138{
139 int i;
140 for (i = 0; i < td->maxcontacts; ++i) {
141 if (td->slots[i].contactid == td->curdata.contactid &&
142 td->slots[i].touch_state)
143 return i;
144 }
145 for (i = 0; i < td->maxcontacts; ++i) {
146 if (!td->slots[i].seen_in_this_frame &&
147 !td->slots[i].touch_state)
148 return i;
149 }
150 /* should not occurs. If this happens that means
151 * that the device sent more touches that it says
152 * in the report descriptor. It is ignored then. */
153 return -1;
154}
155
156static struct mt_class mt_classes[] = { 139static struct mt_class mt_classes[] = {
157 { .name = MT_CLS_DEFAULT, 140 { .name = MT_CLS_DEFAULT,
158 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, 141 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
@@ -190,7 +173,9 @@ static struct mt_class mt_classes[] = {
190 MT_QUIRK_SLOT_IS_CONTACTID, 173 MT_QUIRK_SLOT_IS_CONTACTID,
191 .sn_move = 2048, 174 .sn_move = 2048,
192 .sn_width = 128, 175 .sn_width = 128,
193 .sn_height = 128 }, 176 .sn_height = 128,
177 .maxcontacts = 60,
178 },
194 { .name = MT_CLS_CYPRESS, 179 { .name = MT_CLS_CYPRESS,
195 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 180 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
196 MT_QUIRK_CYPRESS, 181 MT_QUIRK_CYPRESS,
@@ -216,6 +201,12 @@ static struct mt_class mt_classes[] = {
216 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, 201 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
217 .maxcontacts = 4 }, 202 .maxcontacts = 4 },
218 203
204 { .name = MT_CLS_FLATFROG,
205 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
206 MT_QUIRK_NO_AREA,
207 .sn_move = 2048,
208 .maxcontacts = 40,
209 },
219 { } 210 { }
220}; 211};
221 212
@@ -319,24 +310,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
319 * We need to ignore fields that belong to other collections 310 * We need to ignore fields that belong to other collections
320 * such as Mouse that might have the same GenericDesktop usages. */ 311 * such as Mouse that might have the same GenericDesktop usages. */
321 if (field->application == HID_DG_TOUCHSCREEN) 312 if (field->application == HID_DG_TOUCHSCREEN)
322 set_bit(INPUT_PROP_DIRECT, hi->input->propbit); 313 td->mt_flags |= INPUT_MT_DIRECT;
323 else if (field->application != HID_DG_TOUCHPAD) 314 else if (field->application != HID_DG_TOUCHPAD)
324 return 0; 315 return 0;
325 316
326 /* In case of an indirect device (touchpad), we need to add 317 /*
327 * specific BTN_TOOL_* to be handled by the synaptics xorg 318 * Model touchscreens providing buttons as touchpads.
328 * driver.
329 * We also consider that touchscreens providing buttons are touchpads.
330 */ 319 */
331 if (field->application == HID_DG_TOUCHPAD || 320 if (field->application == HID_DG_TOUCHPAD ||
332 (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || 321 (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
333 cls->is_indirect) { 322 td->mt_flags |= INPUT_MT_POINTER;
334 set_bit(INPUT_PROP_POINTER, hi->input->propbit);
335 set_bit(BTN_TOOL_FINGER, hi->input->keybit);
336 set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit);
337 set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit);
338 set_bit(BTN_TOOL_QUADTAP, hi->input->keybit);
339 }
340 323
341 /* eGalax devices provide a Digitizer.Stylus input which overrides 324 /* eGalax devices provide a Digitizer.Stylus input which overrides
342 * the correct Digitizers.Finger X/Y ranges. 325 * the correct Digitizers.Finger X/Y ranges.
@@ -353,8 +336,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
353 EV_ABS, ABS_MT_POSITION_X); 336 EV_ABS, ABS_MT_POSITION_X);
354 set_abs(hi->input, ABS_MT_POSITION_X, field, 337 set_abs(hi->input, ABS_MT_POSITION_X, field,
355 cls->sn_move); 338 cls->sn_move);
356 /* touchscreen emulation */
357 set_abs(hi->input, ABS_X, field, cls->sn_move);
358 mt_store_field(usage, td, hi); 339 mt_store_field(usage, td, hi);
359 td->last_field_index = field->index; 340 td->last_field_index = field->index;
360 return 1; 341 return 1;
@@ -363,8 +344,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
363 EV_ABS, ABS_MT_POSITION_Y); 344 EV_ABS, ABS_MT_POSITION_Y);
364 set_abs(hi->input, ABS_MT_POSITION_Y, field, 345 set_abs(hi->input, ABS_MT_POSITION_Y, field,
365 cls->sn_move); 346 cls->sn_move);
366 /* touchscreen emulation */
367 set_abs(hi->input, ABS_Y, field, cls->sn_move);
368 mt_store_field(usage, td, hi); 347 mt_store_field(usage, td, hi);
369 td->last_field_index = field->index; 348 td->last_field_index = field->index;
370 return 1; 349 return 1;
@@ -388,9 +367,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
388 td->last_field_index = field->index; 367 td->last_field_index = field->index;
389 return 1; 368 return 1;
390 case HID_DG_CONTACTID: 369 case HID_DG_CONTACTID:
391 if (!td->maxcontacts)
392 td->maxcontacts = MT_DEFAULT_MAXCONTACT;
393 input_mt_init_slots(hi->input, td->maxcontacts);
394 mt_store_field(usage, td, hi); 370 mt_store_field(usage, td, hi);
395 td->last_field_index = field->index; 371 td->last_field_index = field->index;
396 td->touches_by_report++; 372 td->touches_by_report++;
@@ -398,18 +374,21 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
398 case HID_DG_WIDTH: 374 case HID_DG_WIDTH:
399 hid_map_usage(hi, usage, bit, max, 375 hid_map_usage(hi, usage, bit, max,
400 EV_ABS, ABS_MT_TOUCH_MAJOR); 376 EV_ABS, ABS_MT_TOUCH_MAJOR);
401 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, 377 if (!(cls->quirks & MT_QUIRK_NO_AREA))
402 cls->sn_width); 378 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
379 cls->sn_width);
403 mt_store_field(usage, td, hi); 380 mt_store_field(usage, td, hi);
404 td->last_field_index = field->index; 381 td->last_field_index = field->index;
405 return 1; 382 return 1;
406 case HID_DG_HEIGHT: 383 case HID_DG_HEIGHT:
407 hid_map_usage(hi, usage, bit, max, 384 hid_map_usage(hi, usage, bit, max,
408 EV_ABS, ABS_MT_TOUCH_MINOR); 385 EV_ABS, ABS_MT_TOUCH_MINOR);
409 set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, 386 if (!(cls->quirks & MT_QUIRK_NO_AREA)) {
410 cls->sn_height); 387 set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
411 input_set_abs_params(hi->input, 388 cls->sn_height);
389 input_set_abs_params(hi->input,
412 ABS_MT_ORIENTATION, 0, 1, 0, 0); 390 ABS_MT_ORIENTATION, 0, 1, 0, 0);
391 }
413 mt_store_field(usage, td, hi); 392 mt_store_field(usage, td, hi);
414 td->last_field_index = field->index; 393 td->last_field_index = field->index;
415 return 1; 394 return 1;
@@ -418,9 +397,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
418 EV_ABS, ABS_MT_PRESSURE); 397 EV_ABS, ABS_MT_PRESSURE);
419 set_abs(hi->input, ABS_MT_PRESSURE, field, 398 set_abs(hi->input, ABS_MT_PRESSURE, field,
420 cls->sn_pressure); 399 cls->sn_pressure);
421 /* touchscreen emulation */
422 set_abs(hi->input, ABS_PRESSURE, field,
423 cls->sn_pressure);
424 mt_store_field(usage, td, hi); 400 mt_store_field(usage, td, hi);
425 td->last_field_index = field->index; 401 td->last_field_index = field->index;
426 return 1; 402 return 1;
@@ -464,7 +440,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
464 return -1; 440 return -1;
465} 441}
466 442
467static int mt_compute_slot(struct mt_device *td) 443static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
468{ 444{
469 __s32 quirks = td->mtclass.quirks; 445 __s32 quirks = td->mtclass.quirks;
470 446
@@ -480,42 +456,23 @@ static int mt_compute_slot(struct mt_device *td)
480 if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) 456 if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
481 return td->curdata.contactid - 1; 457 return td->curdata.contactid - 1;
482 458
483 return find_slot_from_contactid(td); 459 return input_mt_get_slot_by_key(input, td->curdata.contactid);
484} 460}
485 461
486/* 462/*
487 * this function is called when a whole contact has been processed, 463 * this function is called when a whole contact has been processed,
488 * so that it can assign it to a slot and store the data there 464 * so that it can assign it to a slot and store the data there
489 */ 465 */
490static void mt_complete_slot(struct mt_device *td) 466static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
491{ 467{
492 td->curdata.seen_in_this_frame = true;
493 if (td->curvalid) { 468 if (td->curvalid) {
494 int slotnum = mt_compute_slot(td); 469 int slotnum = mt_compute_slot(td, input);
495 470 struct mt_slot *s = &td->curdata;
496 if (slotnum >= 0 && slotnum < td->maxcontacts)
497 td->slots[slotnum] = td->curdata;
498 }
499 td->num_received++;
500}
501
502 471
503/* 472 if (slotnum < 0 || slotnum >= td->maxcontacts)
504 * this function is called when a whole packet has been received and processed, 473 return;
505 * so that it can decide what to send to the input layer.
506 */
507static void mt_emit_event(struct mt_device *td, struct input_dev *input)
508{
509 int i;
510 474
511 for (i = 0; i < td->maxcontacts; ++i) { 475 input_mt_slot(input, slotnum);
512 struct mt_slot *s = &(td->slots[i]);
513 if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
514 !s->seen_in_this_frame) {
515 s->touch_state = false;
516 }
517
518 input_mt_slot(input, i);
519 input_mt_report_slot_state(input, MT_TOOL_FINGER, 476 input_mt_report_slot_state(input, MT_TOOL_FINGER,
520 s->touch_state); 477 s->touch_state);
521 if (s->touch_state) { 478 if (s->touch_state) {
@@ -532,24 +489,29 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input)
532 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 489 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
533 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 490 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
534 } 491 }
535 s->seen_in_this_frame = false;
536
537 } 492 }
538 493
539 input_mt_report_pointer_emulation(input, true); 494 td->num_received++;
495}
496
497/*
498 * this function is called when a whole packet has been received and processed,
499 * so that it can decide what to send to the input layer.
500 */
501static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
502{
503 input_mt_sync_frame(input);
540 input_sync(input); 504 input_sync(input);
541 td->num_received = 0; 505 td->num_received = 0;
542} 506}
543 507
544
545
546static int mt_event(struct hid_device *hid, struct hid_field *field, 508static int mt_event(struct hid_device *hid, struct hid_field *field,
547 struct hid_usage *usage, __s32 value) 509 struct hid_usage *usage, __s32 value)
548{ 510{
549 struct mt_device *td = hid_get_drvdata(hid); 511 struct mt_device *td = hid_get_drvdata(hid);
550 __s32 quirks = td->mtclass.quirks; 512 __s32 quirks = td->mtclass.quirks;
551 513
552 if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { 514 if (hid->claimed & HID_CLAIMED_INPUT) {
553 switch (usage->hid) { 515 switch (usage->hid) {
554 case HID_DG_INRANGE: 516 case HID_DG_INRANGE:
555 if (quirks & MT_QUIRK_ALWAYS_VALID) 517 if (quirks & MT_QUIRK_ALWAYS_VALID)
@@ -602,11 +564,11 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
602 } 564 }
603 565
604 if (usage->hid == td->last_slot_field) 566 if (usage->hid == td->last_slot_field)
605 mt_complete_slot(td); 567 mt_complete_slot(td, field->hidinput->input);
606 568
607 if (field->index == td->last_field_index 569 if (field->index == td->last_field_index
608 && td->num_received >= td->num_expected) 570 && td->num_received >= td->num_expected)
609 mt_emit_event(td, field->hidinput->input); 571 mt_sync_frame(td, field->hidinput->input);
610 572
611 } 573 }
612 574
@@ -685,6 +647,35 @@ static void mt_post_parse(struct mt_device *td)
685 } 647 }
686} 648}
687 649
650static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
651
652{
653 struct mt_device *td = hid_get_drvdata(hdev);
654 struct mt_class *cls = &td->mtclass;
655 struct input_dev *input = hi->input;
656
657 /* Only initialize slots for MT input devices */
658 if (!test_bit(ABS_MT_POSITION_X, input->absbit))
659 return;
660
661 if (!td->maxcontacts)
662 td->maxcontacts = MT_DEFAULT_MAXCONTACT;
663
664 mt_post_parse(td);
665 if (td->serial_maybe)
666 mt_post_parse_default_settings(td);
667
668 if (cls->is_indirect)
669 td->mt_flags |= INPUT_MT_POINTER;
670
671 if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
672 td->mt_flags |= INPUT_MT_DROP_UNUSED;
673
674 input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
675
676 td->mt_flags = 0;
677}
678
688static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 679static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
689{ 680{
690 int ret, i; 681 int ret, i;
@@ -722,6 +713,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
722 goto fail; 713 goto fail;
723 } 714 }
724 715
716 if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
717 td->serial_maybe = true;
718
725 ret = hid_parse(hdev); 719 ret = hid_parse(hdev);
726 if (ret != 0) 720 if (ret != 0)
727 goto fail; 721 goto fail;
@@ -730,20 +724,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
730 if (ret) 724 if (ret)
731 goto fail; 725 goto fail;
732 726
733 mt_post_parse(td);
734
735 if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
736 mt_post_parse_default_settings(td);
737
738 td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
739 GFP_KERNEL);
740 if (!td->slots) {
741 dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
742 hid_hw_stop(hdev);
743 ret = -ENOMEM;
744 goto fail;
745 }
746
747 ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); 727 ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
748 728
749 mt_set_maxcontacts(hdev); 729 mt_set_maxcontacts(hdev);
@@ -774,7 +754,6 @@ static void mt_remove(struct hid_device *hdev)
774 struct mt_device *td = hid_get_drvdata(hdev); 754 struct mt_device *td = hid_get_drvdata(hdev);
775 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); 755 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
776 hid_hw_stop(hdev); 756 hid_hw_stop(hdev);
777 kfree(td->slots);
778 kfree(td); 757 kfree(td);
779 hid_set_drvdata(hdev, NULL); 758 hid_set_drvdata(hdev, NULL);
780} 759}
@@ -892,6 +871,11 @@ static const struct hid_device_id mt_devices[] = {
892 MT_USB_DEVICE(USB_VENDOR_ID_ELO, 871 MT_USB_DEVICE(USB_VENDOR_ID_ELO,
893 USB_DEVICE_ID_ELO_TS2515) }, 872 USB_DEVICE_ID_ELO_TS2515) },
894 873
874 /* Flatfrog Panels */
875 { .driver_data = MT_CLS_FLATFROG,
876 MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG,
877 USB_DEVICE_ID_MULTITOUCH_3200) },
878
895 /* GeneralTouch panel */ 879 /* GeneralTouch panel */
896 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 880 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
897 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 881 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
@@ -1087,6 +1071,7 @@ static struct hid_driver mt_driver = {
1087 .remove = mt_remove, 1071 .remove = mt_remove,
1088 .input_mapping = mt_input_mapping, 1072 .input_mapping = mt_input_mapping,
1089 .input_mapped = mt_input_mapped, 1073 .input_mapped = mt_input_mapped,
1074 .input_configured = mt_input_configured,
1090 .feature_mapping = mt_feature_mapping, 1075 .feature_mapping = mt_feature_mapping,
1091 .usage_table = mt_grabbed_usages, 1076 .usage_table = mt_grabbed_usages,
1092 .event = mt_event, 1077 .event = mt_event,