diff options
Diffstat (limited to 'drivers/hid')
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 545 |
1 files changed, 264 insertions, 281 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index a2c10fc62ef2..346e9caef6f3 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -87,30 +87,34 @@ enum latency_mode { | |||
| 87 | #define MT_IO_FLAGS_ACTIVE_SLOTS 1 | 87 | #define MT_IO_FLAGS_ACTIVE_SLOTS 1 |
| 88 | #define MT_IO_FLAGS_PENDING_SLOTS 2 | 88 | #define MT_IO_FLAGS_PENDING_SLOTS 2 |
| 89 | 89 | ||
| 90 | struct mt_slot { | 90 | static const bool mtrue = true; /* default for true */ |
| 91 | __s32 x, y, cx, cy, p, w, h, a; | 91 | static const bool mfalse; /* default for false */ |
| 92 | __s32 contactid; /* the device ContactID assigned to this slot */ | 92 | static const __s32 mzero; /* default for 0 */ |
| 93 | bool touch_state; /* is the touch valid? */ | 93 | |
| 94 | bool inrange_state; /* is the finger in proximity of the sensor? */ | 94 | #define DEFAULT_TRUE ((void *)&mtrue) |
| 95 | bool confidence_state; /* is the touch made by a finger? */ | 95 | #define DEFAULT_FALSE ((void *)&mfalse) |
| 96 | bool has_azimuth; /* the contact reports azimuth */ | 96 | #define DEFAULT_ZERO ((void *)&mzero) |
| 97 | |||
| 98 | struct mt_usages { | ||
| 99 | struct list_head list; | ||
| 100 | __s32 *x, *y, *cx, *cy, *p, *w, *h, *a; | ||
| 101 | __s32 *contactid; /* the device ContactID assigned to this slot */ | ||
| 102 | bool *tip_state; /* is the touch valid? */ | ||
| 103 | bool *inrange_state; /* is the finger in proximity of the sensor? */ | ||
| 104 | bool *confidence_state; /* is the touch made by a finger? */ | ||
| 97 | }; | 105 | }; |
| 98 | 106 | ||
| 99 | struct mt_application { | 107 | struct mt_application { |
| 100 | struct list_head list; | 108 | struct list_head list; |
| 101 | unsigned int application; | 109 | unsigned int application; |
| 110 | struct list_head mt_usages; /* mt usages list */ | ||
| 102 | 111 | ||
| 103 | __s32 quirks; | 112 | __s32 quirks; |
| 104 | 113 | ||
| 105 | struct mt_slot curdata; /* placeholder of incoming data */ | 114 | __s32 *scantime; /* scantime reported */ |
| 106 | 115 | __s32 scantime_logical_max; /* max value for raw scantime */ | |
| 107 | int cc_index; /* contact count field index in the report */ | ||
| 108 | int cc_value_index; /* contact count value index in the field */ | ||
| 109 | int scantime_index; /* scantime field index in the report */ | ||
| 110 | int scantime_val_index; /* scantime value index in the field */ | ||
| 111 | unsigned int last_slot_field; /* the last field of a slot */ | ||
| 112 | bool curvalid; /* is the current contact valid? */ | ||
| 113 | 116 | ||
| 117 | __s32 *raw_cc; /* contact count in the report */ | ||
| 114 | int left_button_state; /* left button state */ | 118 | int left_button_state; /* left button state */ |
| 115 | unsigned int mt_flags; /* flags to pass to input-mt */ | 119 | unsigned int mt_flags; /* flags to pass to input-mt */ |
| 116 | 120 | ||
| @@ -142,11 +146,6 @@ struct mt_class { | |||
| 142 | bool export_all_inputs; /* do not ignore mouse, keyboards, etc... */ | 146 | bool export_all_inputs; /* do not ignore mouse, keyboards, etc... */ |
| 143 | }; | 147 | }; |
| 144 | 148 | ||
| 145 | struct mt_fields { | ||
| 146 | unsigned usages[HID_MAX_FIELDS]; | ||
| 147 | unsigned int length; | ||
| 148 | }; | ||
| 149 | |||
| 150 | struct mt_report_data { | 149 | struct mt_report_data { |
| 151 | struct list_head list; | 150 | struct list_head list; |
| 152 | struct hid_report *report; | 151 | struct hid_report *report; |
| @@ -158,8 +157,6 @@ struct mt_device { | |||
| 158 | struct mt_class mtclass; /* our mt device class */ | 157 | struct mt_class mtclass; /* our mt device class */ |
| 159 | struct timer_list release_timer; /* to release sticky fingers */ | 158 | struct timer_list release_timer; /* to release sticky fingers */ |
| 160 | struct hid_device *hdev; /* hid_device we're attached to */ | 159 | struct hid_device *hdev; /* hid_device we're attached to */ |
| 161 | struct mt_fields *fields; /* temporary placeholder for storing the | ||
| 162 | multitouch fields */ | ||
| 163 | unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */ | 160 | unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */ |
| 164 | __u8 inputmode_value; /* InputMode HID feature value */ | 161 | __u8 inputmode_value; /* InputMode HID feature value */ |
| 165 | __u8 maxcontacts; | 162 | __u8 maxcontacts; |
| @@ -225,10 +222,11 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); | |||
| 225 | * to a valid contact that was just read. | 222 | * to a valid contact that was just read. |
| 226 | */ | 223 | */ |
| 227 | 224 | ||
| 228 | static int cypress_compute_slot(struct mt_application *app) | 225 | static int cypress_compute_slot(struct mt_application *application, |
| 226 | struct mt_usages *slot) | ||
| 229 | { | 227 | { |
| 230 | if (app->curdata.contactid != 0 || app->num_received == 0) | 228 | if (*slot->contactid != 0 || application->num_received == 0) |
| 231 | return app->curdata.contactid; | 229 | return *slot->contactid; |
| 232 | else | 230 | else |
| 233 | return -1; | 231 | return -1; |
| 234 | } | 232 | } |
| @@ -483,6 +481,34 @@ static void set_abs(struct input_dev *input, unsigned int code, | |||
| 483 | input_abs_set_res(input, code, hidinput_calc_abs_res(field, code)); | 481 | input_abs_set_res(input, code, hidinput_calc_abs_res(field, code)); |
| 484 | } | 482 | } |
| 485 | 483 | ||
| 484 | static struct mt_usages *mt_allocate_usage(struct hid_device *hdev, | ||
| 485 | struct mt_application *application) | ||
| 486 | { | ||
| 487 | struct mt_usages *usage; | ||
| 488 | |||
| 489 | usage = devm_kzalloc(&hdev->dev, sizeof(*usage), GFP_KERNEL); | ||
| 490 | if (!usage) | ||
| 491 | return NULL; | ||
| 492 | |||
| 493 | /* set some defaults so we do not need to check for null pointers */ | ||
| 494 | usage->x = DEFAULT_ZERO; | ||
| 495 | usage->y = DEFAULT_ZERO; | ||
| 496 | usage->cx = DEFAULT_ZERO; | ||
| 497 | usage->cy = DEFAULT_ZERO; | ||
| 498 | usage->p = DEFAULT_ZERO; | ||
| 499 | usage->w = DEFAULT_ZERO; | ||
| 500 | usage->h = DEFAULT_ZERO; | ||
| 501 | usage->a = DEFAULT_ZERO; | ||
| 502 | usage->contactid = DEFAULT_ZERO; | ||
| 503 | usage->tip_state = DEFAULT_FALSE; | ||
| 504 | usage->inrange_state = DEFAULT_FALSE; | ||
| 505 | usage->confidence_state = DEFAULT_TRUE; | ||
| 506 | |||
| 507 | list_add_tail(&usage->list, &application->mt_usages); | ||
| 508 | |||
| 509 | return usage; | ||
| 510 | } | ||
| 511 | |||
| 486 | static struct mt_application *mt_allocate_application(struct mt_device *td, | 512 | static struct mt_application *mt_allocate_application(struct mt_device *td, |
| 487 | unsigned int application) | 513 | unsigned int application) |
| 488 | { | 514 | { |
| @@ -494,6 +520,7 @@ static struct mt_application *mt_allocate_application(struct mt_device *td, | |||
| 494 | return NULL; | 520 | return NULL; |
| 495 | 521 | ||
| 496 | mt_application->application = application; | 522 | mt_application->application = application; |
| 523 | INIT_LIST_HEAD(&mt_application->mt_usages); | ||
| 497 | 524 | ||
| 498 | if (application == HID_DG_TOUCHSCREEN) | 525 | if (application == HID_DG_TOUCHSCREEN) |
| 499 | mt_application->mt_flags |= INPUT_MT_DIRECT; | 526 | mt_application->mt_flags |= INPUT_MT_DIRECT; |
| @@ -506,8 +533,8 @@ static struct mt_application *mt_allocate_application(struct mt_device *td, | |||
| 506 | td->inputmode_value = MT_INPUTMODE_TOUCHPAD; | 533 | td->inputmode_value = MT_INPUTMODE_TOUCHPAD; |
| 507 | } | 534 | } |
| 508 | 535 | ||
| 509 | mt_application->cc_index = -1; | 536 | mt_application->scantime = DEFAULT_ZERO; |
| 510 | mt_application->scantime_index = -1; | 537 | mt_application->raw_cc = DEFAULT_ZERO; |
| 511 | mt_application->quirks = td->mtclass.quirks; | 538 | mt_application->quirks = td->mtclass.quirks; |
| 512 | 539 | ||
| 513 | list_add_tail(&mt_application->list, &td->applications); | 540 | list_add_tail(&mt_application->list, &td->applications); |
| @@ -587,17 +614,45 @@ static struct mt_report_data *mt_find_report_data(struct mt_device *td, | |||
| 587 | return rdata; | 614 | return rdata; |
| 588 | } | 615 | } |
| 589 | 616 | ||
| 590 | static void mt_store_field(struct hid_usage *usage, struct mt_device *td, | 617 | static void mt_store_field(struct hid_device *hdev, |
| 591 | struct hid_input *hi) | 618 | struct mt_application *application, |
| 619 | __s32 *value, | ||
| 620 | size_t offset) | ||
| 592 | { | 621 | { |
| 593 | struct mt_fields *f = td->fields; | 622 | struct mt_usages *usage; |
| 623 | __s32 **target; | ||
| 624 | |||
| 625 | if (list_empty(&application->mt_usages)) | ||
| 626 | usage = mt_allocate_usage(hdev, application); | ||
| 627 | else | ||
| 628 | usage = list_last_entry(&application->mt_usages, | ||
| 629 | struct mt_usages, | ||
| 630 | list); | ||
| 594 | 631 | ||
| 595 | if (f->length >= HID_MAX_FIELDS) | 632 | if (!usage) |
| 596 | return; | 633 | return; |
| 597 | 634 | ||
| 598 | f->usages[f->length++] = usage->hid; | 635 | target = (__s32 **)((char *)usage + offset); |
| 636 | |||
| 637 | /* the value has already been filled, create a new slot */ | ||
| 638 | if (*target != DEFAULT_TRUE && | ||
| 639 | *target != DEFAULT_FALSE && | ||
| 640 | *target != DEFAULT_ZERO) { | ||
| 641 | usage = mt_allocate_usage(hdev, application); | ||
| 642 | if (!usage) | ||
| 643 | return; | ||
| 644 | |||
| 645 | target = (__s32 **)((char *)usage + offset); | ||
| 646 | } | ||
| 647 | |||
| 648 | *target = value; | ||
| 599 | } | 649 | } |
| 600 | 650 | ||
| 651 | #define MT_STORE_FIELD(__name) \ | ||
| 652 | mt_store_field(hdev, app, \ | ||
| 653 | &field->value[usage->usage_index], \ | ||
| 654 | offsetof(struct mt_usages, __name)) | ||
| 655 | |||
| 601 | static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 656 | static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
| 602 | struct hid_field *field, struct hid_usage *usage, | 657 | struct hid_field *field, struct hid_usage *usage, |
| 603 | unsigned long **bit, int *max, struct mt_application *app) | 658 | unsigned long **bit, int *max, struct mt_application *app) |
| @@ -627,24 +682,28 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 627 | case HID_UP_GENDESK: | 682 | case HID_UP_GENDESK: |
| 628 | switch (usage->hid) { | 683 | switch (usage->hid) { |
| 629 | case HID_GD_X: | 684 | case HID_GD_X: |
| 630 | if (prev_usage && (prev_usage->hid == usage->hid)) | 685 | if (prev_usage && (prev_usage->hid == usage->hid)) { |
| 631 | code = ABS_MT_TOOL_X; | 686 | code = ABS_MT_TOOL_X; |
| 632 | else | 687 | MT_STORE_FIELD(cx); |
| 688 | } else { | ||
| 633 | code = ABS_MT_POSITION_X; | 689 | code = ABS_MT_POSITION_X; |
| 690 | MT_STORE_FIELD(x); | ||
| 691 | } | ||
| 634 | 692 | ||
| 635 | hid_map_usage(hi, usage, bit, max, EV_ABS, code); | ||
| 636 | set_abs(hi->input, code, field, cls->sn_move); | 693 | set_abs(hi->input, code, field, cls->sn_move); |
| 637 | mt_store_field(usage, td, hi); | 694 | |
| 638 | return 1; | 695 | return 1; |
| 639 | case HID_GD_Y: | 696 | case HID_GD_Y: |
| 640 | if (prev_usage && (prev_usage->hid == usage->hid)) | 697 | if (prev_usage && (prev_usage->hid == usage->hid)) { |
| 641 | code = ABS_MT_TOOL_Y; | 698 | code = ABS_MT_TOOL_Y; |
| 642 | else | 699 | MT_STORE_FIELD(cy); |
| 700 | } else { | ||
| 643 | code = ABS_MT_POSITION_Y; | 701 | code = ABS_MT_POSITION_Y; |
| 702 | MT_STORE_FIELD(y); | ||
| 703 | } | ||
| 644 | 704 | ||
| 645 | hid_map_usage(hi, usage, bit, max, EV_ABS, code); | ||
| 646 | set_abs(hi->input, code, field, cls->sn_move); | 705 | set_abs(hi->input, code, field, cls->sn_move); |
| 647 | mt_store_field(usage, td, hi); | 706 | |
| 648 | return 1; | 707 | return 1; |
| 649 | } | 708 | } |
| 650 | return 0; | 709 | return 0; |
| @@ -653,40 +712,33 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 653 | switch (usage->hid) { | 712 | switch (usage->hid) { |
| 654 | case HID_DG_INRANGE: | 713 | case HID_DG_INRANGE: |
| 655 | if (app->quirks & MT_QUIRK_HOVERING) { | 714 | if (app->quirks & MT_QUIRK_HOVERING) { |
| 656 | hid_map_usage(hi, usage, bit, max, | ||
| 657 | EV_ABS, ABS_MT_DISTANCE); | ||
| 658 | input_set_abs_params(hi->input, | 715 | input_set_abs_params(hi->input, |
| 659 | ABS_MT_DISTANCE, 0, 1, 0, 0); | 716 | ABS_MT_DISTANCE, 0, 1, 0, 0); |
| 660 | } | 717 | } |
| 661 | mt_store_field(usage, td, hi); | 718 | MT_STORE_FIELD(inrange_state); |
| 662 | return 1; | 719 | return 1; |
| 663 | case HID_DG_CONFIDENCE: | 720 | case HID_DG_CONFIDENCE: |
| 664 | if ((cls->name == MT_CLS_WIN_8 || | 721 | if ((cls->name == MT_CLS_WIN_8 || |
| 665 | cls->name == MT_CLS_WIN_8_DUAL) && | 722 | cls->name == MT_CLS_WIN_8_DUAL) && |
| 666 | field->application == HID_DG_TOUCHPAD) | 723 | field->application == HID_DG_TOUCHPAD) |
| 667 | app->quirks |= MT_QUIRK_CONFIDENCE; | 724 | app->quirks |= MT_QUIRK_CONFIDENCE; |
| 668 | mt_store_field(usage, td, hi); | 725 | MT_STORE_FIELD(confidence_state); |
| 669 | return 1; | 726 | return 1; |
| 670 | case HID_DG_TIPSWITCH: | 727 | case HID_DG_TIPSWITCH: |
| 671 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
| 672 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 728 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
| 673 | mt_store_field(usage, td, hi); | 729 | MT_STORE_FIELD(tip_state); |
| 674 | return 1; | 730 | return 1; |
| 675 | case HID_DG_CONTACTID: | 731 | case HID_DG_CONTACTID: |
| 676 | mt_store_field(usage, td, hi); | 732 | MT_STORE_FIELD(contactid); |
| 677 | app->touches_by_report++; | 733 | app->touches_by_report++; |
| 678 | return 1; | 734 | return 1; |
| 679 | case HID_DG_WIDTH: | 735 | case HID_DG_WIDTH: |
| 680 | hid_map_usage(hi, usage, bit, max, | ||
| 681 | EV_ABS, ABS_MT_TOUCH_MAJOR); | ||
| 682 | if (!(app->quirks & MT_QUIRK_NO_AREA)) | 736 | if (!(app->quirks & MT_QUIRK_NO_AREA)) |
| 683 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | 737 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, |
| 684 | cls->sn_width); | 738 | cls->sn_width); |
| 685 | mt_store_field(usage, td, hi); | 739 | MT_STORE_FIELD(w); |
| 686 | return 1; | 740 | return 1; |
| 687 | case HID_DG_HEIGHT: | 741 | case HID_DG_HEIGHT: |
| 688 | hid_map_usage(hi, usage, bit, max, | ||
| 689 | EV_ABS, ABS_MT_TOUCH_MINOR); | ||
| 690 | if (!(app->quirks & MT_QUIRK_NO_AREA)) { | 742 | if (!(app->quirks & MT_QUIRK_NO_AREA)) { |
| 691 | set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, | 743 | set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, |
| 692 | cls->sn_height); | 744 | cls->sn_height); |
| @@ -700,37 +752,23 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 700 | input_set_abs_params(hi->input, | 752 | input_set_abs_params(hi->input, |
| 701 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | 753 | ABS_MT_ORIENTATION, 0, 1, 0, 0); |
| 702 | } | 754 | } |
| 703 | mt_store_field(usage, td, hi); | 755 | MT_STORE_FIELD(h); |
| 704 | return 1; | 756 | return 1; |
| 705 | case HID_DG_TIPPRESSURE: | 757 | case HID_DG_TIPPRESSURE: |
| 706 | hid_map_usage(hi, usage, bit, max, | ||
| 707 | EV_ABS, ABS_MT_PRESSURE); | ||
| 708 | set_abs(hi->input, ABS_MT_PRESSURE, field, | 758 | set_abs(hi->input, ABS_MT_PRESSURE, field, |
| 709 | cls->sn_pressure); | 759 | cls->sn_pressure); |
| 710 | mt_store_field(usage, td, hi); | 760 | MT_STORE_FIELD(p); |
| 711 | return 1; | 761 | return 1; |
| 712 | case HID_DG_SCANTIME: | 762 | case HID_DG_SCANTIME: |
| 713 | hid_map_usage(hi, usage, bit, max, | ||
| 714 | EV_MSC, MSC_TIMESTAMP); | ||
| 715 | input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP); | 763 | input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP); |
| 716 | /* Ignore if indexes are out of bounds. */ | 764 | app->scantime = &field->value[usage->usage_index]; |
| 717 | if (field->index >= field->report->maxfield || | 765 | app->scantime_logical_max = field->logical_maximum; |
| 718 | usage->usage_index >= field->report_count) | ||
| 719 | return 1; | ||
| 720 | app->scantime_index = field->index; | ||
| 721 | app->scantime_val_index = usage->usage_index; | ||
| 722 | return 1; | 766 | return 1; |
| 723 | case HID_DG_CONTACTCOUNT: | 767 | case HID_DG_CONTACTCOUNT: |
| 724 | /* Ignore if indexes are out of bounds. */ | 768 | app->have_contact_count = true; |
| 725 | if (field->index >= field->report->maxfield || | 769 | app->raw_cc = &field->value[usage->usage_index]; |
| 726 | usage->usage_index >= field->report_count) | ||
| 727 | return 1; | ||
| 728 | app->cc_index = field->index; | ||
| 729 | app->cc_value_index = usage->usage_index; | ||
| 730 | return 1; | 770 | return 1; |
| 731 | case HID_DG_AZIMUTH: | 771 | case HID_DG_AZIMUTH: |
| 732 | hid_map_usage(hi, usage, bit, max, | ||
| 733 | EV_ABS, ABS_MT_ORIENTATION); | ||
| 734 | /* | 772 | /* |
| 735 | * Azimuth has the range of [0, MAX) representing a full | 773 | * Azimuth has the range of [0, MAX) representing a full |
| 736 | * revolution. Set ABS_MT_ORIENTATION to a quarter of | 774 | * revolution. Set ABS_MT_ORIENTATION to a quarter of |
| @@ -741,11 +779,10 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 741 | field->logical_maximum / 4, | 779 | field->logical_maximum / 4, |
| 742 | cls->sn_move ? | 780 | cls->sn_move ? |
| 743 | field->logical_maximum / cls->sn_move : 0, 0); | 781 | field->logical_maximum / cls->sn_move : 0, 0); |
| 744 | mt_store_field(usage, td, hi); | 782 | MT_STORE_FIELD(a); |
| 745 | return 1; | 783 | return 1; |
| 746 | case HID_DG_CONTACTMAX: | 784 | case HID_DG_CONTACTMAX: |
| 747 | /* we don't set td->last_slot_field as contactcount and | 785 | /* contact max are global to the report */ |
| 748 | * contact max are global to the report */ | ||
| 749 | return -1; | 786 | return -1; |
| 750 | case HID_DG_TOUCH: | 787 | case HID_DG_TOUCH: |
| 751 | /* Legacy devices use TIPSWITCH and not TOUCH. | 788 | /* Legacy devices use TIPSWITCH and not TOUCH. |
| @@ -778,95 +815,24 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 778 | } | 815 | } |
| 779 | 816 | ||
| 780 | static int mt_compute_slot(struct mt_device *td, struct mt_application *app, | 817 | static int mt_compute_slot(struct mt_device *td, struct mt_application *app, |
| 818 | struct mt_usages *slot, | ||
| 781 | struct input_dev *input) | 819 | struct input_dev *input) |
| 782 | { | 820 | { |
| 783 | __s32 quirks = app->quirks; | 821 | __s32 quirks = app->quirks; |
| 784 | 822 | ||
| 785 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTID) | 823 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTID) |
| 786 | return app->curdata.contactid; | 824 | return *slot->contactid; |
| 787 | 825 | ||
| 788 | if (quirks & MT_QUIRK_CYPRESS) | 826 | if (quirks & MT_QUIRK_CYPRESS) |
| 789 | return cypress_compute_slot(app); | 827 | return cypress_compute_slot(app, slot); |
| 790 | 828 | ||
| 791 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) | 829 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) |
| 792 | return app->num_received; | 830 | return app->num_received; |
| 793 | 831 | ||
| 794 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) | 832 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) |
| 795 | return app->curdata.contactid - 1; | 833 | return *slot->contactid - 1; |
| 796 | 834 | ||
| 797 | return input_mt_get_slot_by_key(input, app->curdata.contactid); | 835 | return input_mt_get_slot_by_key(input, *slot->contactid); |
| 798 | } | ||
| 799 | |||
| 800 | /* | ||
| 801 | * this function is called when a whole contact has been processed, | ||
| 802 | * so that it can assign it to a slot and store the data there | ||
| 803 | */ | ||
| 804 | static void mt_complete_slot(struct mt_device *td, struct mt_application *app, | ||
| 805 | struct input_dev *input) | ||
| 806 | { | ||
| 807 | if ((app->quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) && | ||
| 808 | app->num_received >= app->num_expected) | ||
| 809 | return; | ||
| 810 | |||
| 811 | if (app->curvalid || (app->quirks & MT_QUIRK_ALWAYS_VALID)) { | ||
| 812 | int active; | ||
| 813 | int slotnum = mt_compute_slot(td, app, input); | ||
| 814 | struct mt_slot *s = &app->curdata; | ||
| 815 | struct input_mt *mt = input->mt; | ||
| 816 | |||
| 817 | if (slotnum < 0 || slotnum >= td->maxcontacts) | ||
| 818 | return; | ||
| 819 | |||
| 820 | if ((app->quirks & MT_QUIRK_IGNORE_DUPLICATES) && mt) { | ||
| 821 | struct input_mt_slot *slot = &mt->slots[slotnum]; | ||
| 822 | if (input_mt_is_active(slot) && | ||
| 823 | input_mt_is_used(mt, slot)) | ||
| 824 | return; | ||
| 825 | } | ||
| 826 | |||
| 827 | if (!(app->quirks & MT_QUIRK_CONFIDENCE)) | ||
| 828 | s->confidence_state = true; | ||
| 829 | active = (s->touch_state || s->inrange_state) && | ||
| 830 | s->confidence_state; | ||
| 831 | |||
| 832 | input_mt_slot(input, slotnum); | ||
| 833 | input_mt_report_slot_state(input, MT_TOOL_FINGER, active); | ||
| 834 | if (active) { | ||
| 835 | /* this finger is in proximity of the sensor */ | ||
| 836 | int wide = (s->w > s->h); | ||
| 837 | int major = max(s->w, s->h); | ||
| 838 | int minor = min(s->w, s->h); | ||
| 839 | int orientation = wide; | ||
| 840 | |||
| 841 | if (s->has_azimuth) | ||
| 842 | orientation = s->a; | ||
| 843 | |||
| 844 | /* | ||
| 845 | * divided by two to match visual scale of touch | ||
| 846 | * for devices with this quirk | ||
| 847 | */ | ||
| 848 | if (app->quirks & MT_QUIRK_TOUCH_SIZE_SCALING) { | ||
| 849 | major = major >> 1; | ||
| 850 | minor = minor >> 1; | ||
| 851 | } | ||
| 852 | |||
| 853 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); | ||
| 854 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); | ||
| 855 | input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx); | ||
| 856 | input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy); | ||
| 857 | input_event(input, EV_ABS, ABS_MT_DISTANCE, | ||
| 858 | !s->touch_state); | ||
| 859 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, | ||
| 860 | orientation); | ||
| 861 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); | ||
| 862 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); | ||
| 863 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); | ||
| 864 | |||
| 865 | set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); | ||
| 866 | } | ||
| 867 | } | ||
| 868 | |||
| 869 | app->num_received++; | ||
| 870 | } | 836 | } |
| 871 | 837 | ||
| 872 | /* | 838 | /* |
| @@ -892,8 +858,7 @@ static void mt_sync_frame(struct mt_device *td, struct mt_application *app, | |||
| 892 | clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); | 858 | clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); |
| 893 | } | 859 | } |
| 894 | 860 | ||
| 895 | static int mt_compute_timestamp(struct mt_application *app, | 861 | static int mt_compute_timestamp(struct mt_application *app, __s32 value) |
| 896 | struct hid_field *field, __s32 value) | ||
| 897 | { | 862 | { |
| 898 | long delta = value - app->prev_scantime; | 863 | long delta = value - app->prev_scantime; |
| 899 | unsigned long jdelta = jiffies_to_usecs(jiffies - app->jiffies); | 864 | unsigned long jdelta = jiffies_to_usecs(jiffies - app->jiffies); |
| @@ -901,7 +866,7 @@ static int mt_compute_timestamp(struct mt_application *app, | |||
| 901 | app->jiffies = jiffies; | 866 | app->jiffies = jiffies; |
| 902 | 867 | ||
| 903 | if (delta < 0) | 868 | if (delta < 0) |
| 904 | delta += field->logical_maximum; | 869 | delta += app->scantime_logical_max; |
| 905 | 870 | ||
| 906 | /* HID_DG_SCANTIME is expressed in 100us, we want it in us. */ | 871 | /* HID_DG_SCANTIME is expressed in 100us, we want it in us. */ |
| 907 | delta *= 100; | 872 | delta *= 100; |
| @@ -923,64 +888,69 @@ static int mt_touch_event(struct hid_device *hid, struct hid_field *field, | |||
| 923 | return 1; | 888 | return 1; |
| 924 | } | 889 | } |
| 925 | 890 | ||
| 926 | static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, | 891 | static int mt_process_slot(struct mt_device *td, struct input_dev *input, |
| 927 | struct hid_usage *usage, __s32 value, | 892 | struct mt_application *app, |
| 928 | struct mt_application *app, bool first_packet) | 893 | struct mt_usages *slot) |
| 929 | { | 894 | { |
| 930 | struct mt_device *td = hid_get_drvdata(hid); | 895 | struct input_mt *mt = input->mt; |
| 931 | __s32 quirks = app->quirks; | 896 | __s32 quirks = app->quirks; |
| 932 | struct input_dev *input = field->hidinput->input; | 897 | bool valid = true; |
| 898 | bool confidence_state = true; | ||
| 899 | bool inrange_state = false; | ||
| 900 | int active; | ||
| 901 | int slotnum; | ||
| 933 | 902 | ||
| 934 | if (hid->claimed & HID_CLAIMED_INPUT) { | 903 | if (!slot) |
| 935 | switch (usage->hid) { | 904 | return -EINVAL; |
| 936 | case HID_DG_INRANGE: | 905 | |
| 937 | if (quirks & MT_QUIRK_VALID_IS_INRANGE) | 906 | if ((quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) && |
| 938 | app->curvalid = value; | 907 | app->num_received >= app->num_expected) |
| 939 | if (quirks & MT_QUIRK_HOVERING) | 908 | return -EAGAIN; |
| 940 | app->curdata.inrange_state = value; | 909 | |
| 941 | break; | 910 | if (!(quirks & MT_QUIRK_ALWAYS_VALID)) { |
| 942 | case HID_DG_TIPSWITCH: | 911 | if (quirks & MT_QUIRK_VALID_IS_INRANGE) |
| 943 | if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) | 912 | valid = *slot->inrange_state; |
| 944 | app->curvalid = value; | 913 | if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) |
| 945 | app->curdata.touch_state = value; | 914 | valid = *slot->tip_state; |
| 946 | break; | 915 | if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) |
| 947 | case HID_DG_CONFIDENCE: | 916 | valid = *slot->confidence_state; |
| 948 | if (quirks & MT_QUIRK_CONFIDENCE) | 917 | |
| 949 | app->curdata.confidence_state = value; | 918 | if (!valid) |
| 950 | if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) | 919 | return 0; |
| 951 | app->curvalid = value; | 920 | } |
| 952 | break; | 921 | |
| 953 | case HID_DG_CONTACTID: | 922 | slotnum = mt_compute_slot(td, app, slot, input); |
| 954 | app->curdata.contactid = value; | 923 | if (slotnum < 0 || slotnum >= td->maxcontacts) |
| 955 | break; | 924 | return 0; |
| 956 | case HID_DG_TIPPRESSURE: | 925 | |
| 957 | app->curdata.p = value; | 926 | if ((quirks & MT_QUIRK_IGNORE_DUPLICATES) && mt) { |
| 958 | break; | 927 | struct input_mt_slot *i_slot = &mt->slots[slotnum]; |
| 959 | case HID_GD_X: | 928 | |
| 960 | if (usage->code == ABS_MT_TOOL_X) | 929 | if (input_mt_is_active(i_slot) && |
| 961 | app->curdata.cx = value; | 930 | input_mt_is_used(mt, i_slot)) |
| 962 | else | 931 | return -EAGAIN; |
| 963 | app->curdata.x = value; | 932 | } |
| 964 | break; | 933 | |
| 965 | case HID_GD_Y: | 934 | if (quirks & MT_QUIRK_CONFIDENCE) |
| 966 | if (usage->code == ABS_MT_TOOL_Y) | 935 | confidence_state = *slot->confidence_state; |
| 967 | app->curdata.cy = value; | 936 | |
| 968 | else | 937 | if (quirks & MT_QUIRK_HOVERING) |
| 969 | app->curdata.y = value; | 938 | inrange_state = *slot->inrange_state; |
| 970 | break; | 939 | |
| 971 | case HID_DG_WIDTH: | 940 | active = (*slot->tip_state || inrange_state) && confidence_state; |
| 972 | app->curdata.w = value; | 941 | |
| 973 | break; | 942 | input_mt_slot(input, slotnum); |
| 974 | case HID_DG_HEIGHT: | 943 | input_mt_report_slot_state(input, MT_TOOL_FINGER, active); |
| 975 | app->curdata.h = value; | 944 | if (active) { |
| 976 | break; | 945 | /* this finger is in proximity of the sensor */ |
| 977 | case HID_DG_SCANTIME: | 946 | int wide = (*slot->w > *slot->h); |
| 978 | app->timestamp = mt_compute_timestamp(app, field, | 947 | int major = max(*slot->w, *slot->h); |
| 979 | value); | 948 | int minor = min(*slot->w, *slot->h); |
| 980 | break; | 949 | int orientation = wide; |
| 981 | case HID_DG_CONTACTCOUNT: | 950 | int max_azimuth; |
| 982 | break; | 951 | int azimuth; |
| 983 | case HID_DG_AZIMUTH: | 952 | |
| 953 | if (slot->a != DEFAULT_ZERO) { | ||
| 984 | /* | 954 | /* |
| 985 | * Azimuth is counter-clockwise and ranges from [0, MAX) | 955 | * Azimuth is counter-clockwise and ranges from [0, MAX) |
| 986 | * (a full revolution). Convert it to clockwise ranging | 956 | * (a full revolution). Convert it to clockwise ranging |
| @@ -991,52 +961,76 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, | |||
| 991 | * out of range to [-MAX/2, MAX/2] to report an upside | 961 | * out of range to [-MAX/2, MAX/2] to report an upside |
| 992 | * down ellipsis. | 962 | * down ellipsis. |
| 993 | */ | 963 | */ |
| 994 | if (value > field->logical_maximum / 2) | 964 | azimuth = *slot->a; |
| 995 | value -= field->logical_maximum; | 965 | max_azimuth = input_abs_get_max(input, |
| 996 | app->curdata.a = -value; | 966 | ABS_MT_ORIENTATION); |
| 997 | app->curdata.has_azimuth = true; | 967 | if (azimuth > max_azimuth * 2) |
| 998 | break; | 968 | azimuth -= max_azimuth * 4; |
| 999 | case HID_DG_TOUCH: | 969 | orientation = -azimuth; |
| 1000 | /* do nothing */ | 970 | } |
| 1001 | break; | ||
| 1002 | 971 | ||
| 1003 | default: | 972 | /* |
| 1004 | /* | 973 | * divided by two to match visual scale of touch |
| 1005 | * For Win8 PTP touchpads we should only look at | 974 | * for devices with this quirk |
| 1006 | * non finger/touch events in the first_packet of | 975 | */ |
| 1007 | * a (possible) multi-packet frame. | 976 | if (quirks & MT_QUIRK_TOUCH_SIZE_SCALING) { |
| 1008 | */ | 977 | major = major >> 1; |
| 1009 | if ((quirks & MT_QUIRK_WIN8_PTP_BUTTONS) && | 978 | minor = minor >> 1; |
| 1010 | !first_packet) | 979 | } |
| 1011 | return; | ||
| 1012 | 980 | ||
| 1013 | /* | 981 | input_event(input, EV_ABS, ABS_MT_POSITION_X, *slot->x); |
| 1014 | * For Win8 PTP touchpads we map both the clickpad click | 982 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, *slot->y); |
| 1015 | * and any "external" left buttons to BTN_LEFT if a | 983 | input_event(input, EV_ABS, ABS_MT_TOOL_X, *slot->cx); |
| 1016 | * device claims to have both we need to report 1 for | 984 | input_event(input, EV_ABS, ABS_MT_TOOL_Y, *slot->cy); |
| 1017 | * BTN_LEFT if either is pressed, so we or all values | 985 | input_event(input, EV_ABS, ABS_MT_DISTANCE, !*slot->tip_state); |
| 1018 | * together and report the result in mt_sync_frame(). | 986 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, orientation); |
| 1019 | */ | 987 | input_event(input, EV_ABS, ABS_MT_PRESSURE, *slot->p); |
| 1020 | if ((quirks & MT_QUIRK_WIN8_PTP_BUTTONS) && | 988 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); |
| 1021 | usage->type == EV_KEY && usage->code == BTN_LEFT) { | 989 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); |
| 1022 | app->left_button_state |= value; | 990 | |
| 1023 | return; | 991 | set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); |
| 1024 | } | 992 | } |
| 1025 | 993 | ||
| 1026 | if (usage->type) | 994 | return 0; |
| 1027 | input_event(input, usage->type, usage->code, | 995 | } |
| 1028 | value); | 996 | |
| 997 | static void mt_process_mt_event(struct hid_device *hid, | ||
| 998 | struct mt_application *app, | ||
| 999 | struct hid_field *field, | ||
| 1000 | struct hid_usage *usage, | ||
| 1001 | __s32 value, | ||
| 1002 | bool first_packet) | ||
| 1003 | { | ||
| 1004 | __s32 quirks = app->quirks; | ||
| 1005 | struct input_dev *input = field->hidinput->input; | ||
| 1006 | |||
| 1007 | if (!usage->type || !(hid->claimed & HID_CLAIMED_INPUT)) | ||
| 1008 | return; | ||
| 1009 | |||
| 1010 | if (quirks & MT_QUIRK_WIN8_PTP_BUTTONS) { | ||
| 1011 | |||
| 1012 | /* | ||
| 1013 | * For Win8 PTP touchpads we should only look at | ||
| 1014 | * non finger/touch events in the first_packet of a | ||
| 1015 | * (possible) multi-packet frame. | ||
| 1016 | */ | ||
| 1017 | if (!first_packet) | ||
| 1029 | return; | 1018 | return; |
| 1030 | } | ||
| 1031 | 1019 | ||
| 1032 | if (usage->usage_index + 1 == field->report_count) { | 1020 | /* |
| 1033 | /* we only take into account the last report. */ | 1021 | * For Win8 PTP touchpads we map both the clickpad click |
| 1034 | if (usage->hid == app->last_slot_field) | 1022 | * and any "external" left buttons to BTN_LEFT if a |
| 1035 | mt_complete_slot(td, app, | 1023 | * device claims to have both we need to report 1 for |
| 1036 | field->hidinput->input); | 1024 | * BTN_LEFT if either is pressed, so we or all values |
| 1025 | * together and report the result in mt_sync_frame(). | ||
| 1026 | */ | ||
| 1027 | if (usage->type == EV_KEY && usage->code == BTN_LEFT) { | ||
| 1028 | app->left_button_state |= value; | ||
| 1029 | return; | ||
| 1037 | } | 1030 | } |
| 1038 | |||
| 1039 | } | 1031 | } |
| 1032 | |||
| 1033 | input_event(input, usage->type, usage->code, value); | ||
| 1040 | } | 1034 | } |
| 1041 | 1035 | ||
| 1042 | static void mt_touch_report(struct hid_device *hid, | 1036 | static void mt_touch_report(struct hid_device *hid, |
| @@ -1046,6 +1040,8 @@ static void mt_touch_report(struct hid_device *hid, | |||
| 1046 | struct hid_report *report = rdata->report; | 1040 | struct hid_report *report = rdata->report; |
| 1047 | struct mt_application *app = rdata->application; | 1041 | struct mt_application *app = rdata->application; |
| 1048 | struct hid_field *field; | 1042 | struct hid_field *field; |
| 1043 | struct input_dev *input; | ||
| 1044 | struct mt_usages *slot; | ||
| 1049 | bool first_packet; | 1045 | bool first_packet; |
| 1050 | unsigned count; | 1046 | unsigned count; |
| 1051 | int r, n; | 1047 | int r, n; |
| @@ -1056,18 +1052,16 @@ static void mt_touch_report(struct hid_device *hid, | |||
| 1056 | if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) | 1052 | if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) |
| 1057 | return; | 1053 | return; |
| 1058 | 1054 | ||
| 1055 | scantime = *app->scantime; | ||
| 1056 | app->timestamp = mt_compute_timestamp(app, scantime); | ||
| 1057 | if (app->raw_cc != DEFAULT_ZERO) | ||
| 1058 | contact_count = *app->raw_cc; | ||
| 1059 | |||
| 1059 | /* | 1060 | /* |
| 1060 | * Includes multi-packet support where subsequent | 1061 | * Includes multi-packet support where subsequent |
| 1061 | * packets are sent with zero contactcount. | 1062 | * packets are sent with zero contactcount. |
| 1062 | */ | 1063 | */ |
| 1063 | if (app->scantime_index >= 0) { | 1064 | if (contact_count >= 0) { |
| 1064 | field = report->field[app->scantime_index]; | ||
| 1065 | scantime = field->value[app->scantime_val_index]; | ||
| 1066 | } | ||
| 1067 | if (app->cc_index >= 0) { | ||
| 1068 | field = report->field[app->cc_index]; | ||
| 1069 | contact_count = field->value[app->cc_value_index]; | ||
| 1070 | |||
| 1071 | /* | 1065 | /* |
| 1072 | * For Win8 PTPs the first packet (td->num_received == 0) may | 1066 | * For Win8 PTPs the first packet (td->num_received == 0) may |
| 1073 | * have a contactcount of 0 if there only is a button event. | 1067 | * have a contactcount of 0 if there only is a button event. |
| @@ -1086,6 +1080,14 @@ static void mt_touch_report(struct hid_device *hid, | |||
| 1086 | app->prev_scantime = scantime; | 1080 | app->prev_scantime = scantime; |
| 1087 | 1081 | ||
| 1088 | first_packet = app->num_received == 0; | 1082 | first_packet = app->num_received == 0; |
| 1083 | |||
| 1084 | input = report->field[0]->hidinput->input; | ||
| 1085 | |||
| 1086 | list_for_each_entry(slot, &app->mt_usages, list) { | ||
| 1087 | if (!mt_process_slot(td, input, app, slot)) | ||
| 1088 | app->num_received++; | ||
| 1089 | } | ||
| 1090 | |||
| 1089 | for (r = 0; r < report->maxfield; r++) { | 1091 | for (r = 0; r < report->maxfield; r++) { |
| 1090 | field = report->field[r]; | 1092 | field = report->field[r]; |
| 1091 | count = field->report_count; | 1093 | count = field->report_count; |
| @@ -1094,12 +1096,13 @@ static void mt_touch_report(struct hid_device *hid, | |||
| 1094 | continue; | 1096 | continue; |
| 1095 | 1097 | ||
| 1096 | for (n = 0; n < count; n++) | 1098 | for (n = 0; n < count; n++) |
| 1097 | mt_process_mt_event(hid, field, &field->usage[n], | 1099 | mt_process_mt_event(hid, app, field, |
| 1098 | field->value[n], app, first_packet); | 1100 | &field->usage[n], field->value[n], |
| 1101 | first_packet); | ||
| 1099 | } | 1102 | } |
| 1100 | 1103 | ||
| 1101 | if (app->num_received >= app->num_expected) | 1104 | if (app->num_received >= app->num_expected) |
| 1102 | mt_sync_frame(td, app, report->field[0]->hidinput->input); | 1105 | mt_sync_frame(td, app, input); |
| 1103 | 1106 | ||
| 1104 | /* | 1107 | /* |
| 1105 | * Windows 8 specs says 2 things: | 1108 | * Windows 8 specs says 2 things: |
| @@ -1391,7 +1394,7 @@ static void mt_post_parse_default_settings(struct mt_device *td, | |||
| 1391 | __s32 quirks = app->quirks; | 1394 | __s32 quirks = app->quirks; |
| 1392 | 1395 | ||
| 1393 | /* unknown serial device needs special quirks */ | 1396 | /* unknown serial device needs special quirks */ |
| 1394 | if (app->touches_by_report == 1) { | 1397 | if (list_is_singular(&app->mt_usages)) { |
| 1395 | quirks |= MT_QUIRK_ALWAYS_VALID; | 1398 | quirks |= MT_QUIRK_ALWAYS_VALID; |
| 1396 | quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; | 1399 | quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; |
| 1397 | quirks &= ~MT_QUIRK_VALID_IS_INRANGE; | 1400 | quirks &= ~MT_QUIRK_VALID_IS_INRANGE; |
| @@ -1404,16 +1407,7 @@ static void mt_post_parse_default_settings(struct mt_device *td, | |||
| 1404 | 1407 | ||
| 1405 | static void mt_post_parse(struct mt_device *td, struct mt_application *app) | 1408 | static void mt_post_parse(struct mt_device *td, struct mt_application *app) |
| 1406 | { | 1409 | { |
| 1407 | struct mt_fields *f = td->fields; | 1410 | if (!app->have_contact_count) |
| 1408 | |||
| 1409 | if (app->touches_by_report > 0) { | ||
| 1410 | int field_count_per_touch; | ||
| 1411 | |||
| 1412 | field_count_per_touch = f->length / app->touches_by_report; | ||
| 1413 | app->last_slot_field = f->usages[field_count_per_touch - 1]; | ||
| 1414 | } | ||
| 1415 | |||
| 1416 | if (app->cc_index < 0) | ||
| 1417 | app->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; | 1411 | app->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; |
| 1418 | } | 1412 | } |
| 1419 | 1413 | ||
| @@ -1596,13 +1590,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1596 | INIT_LIST_HEAD(&td->applications); | 1590 | INIT_LIST_HEAD(&td->applications); |
| 1597 | INIT_LIST_HEAD(&td->reports); | 1591 | INIT_LIST_HEAD(&td->reports); |
| 1598 | 1592 | ||
| 1599 | td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields), | ||
| 1600 | GFP_KERNEL); | ||
| 1601 | if (!td->fields) { | ||
| 1602 | dev_err(&hdev->dev, "cannot allocate multitouch fields data\n"); | ||
| 1603 | return -ENOMEM; | ||
| 1604 | } | ||
| 1605 | |||
| 1606 | if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) | 1593 | if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) |
| 1607 | td->serial_maybe = true; | 1594 | td->serial_maybe = true; |
| 1608 | 1595 | ||
| @@ -1638,10 +1625,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1638 | 1625 | ||
| 1639 | mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); | 1626 | mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); |
| 1640 | 1627 | ||
| 1641 | /* release .fields memory as it is not used anymore */ | ||
| 1642 | devm_kfree(&hdev->dev, td->fields); | ||
| 1643 | td->fields = NULL; | ||
| 1644 | |||
| 1645 | return 0; | 1628 | return 0; |
| 1646 | } | 1629 | } |
| 1647 | 1630 | ||
