diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2013-03-22 13:38:29 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-03-27 09:02:45 -0400 |
commit | a69c5f8b16c05e68d41e4858c1c2c55fddf085e1 (patch) | |
tree | 5f92fe6eba3a44984bb9a86cad63a9844b330132 | |
parent | 4f22decf9b6329acfe59091c5cba6b378b9b31db (diff) |
HID: multitouch: breaks out touch handling in specific functions
This will allow easier integration of hybrid pen and touch devices.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-multitouch.c | 123 |
1 files changed, 83 insertions, 40 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 1f544a48507d..35b6025a064f 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -114,6 +114,9 @@ struct mt_device { | |||
114 | unsigned mt_flags; /* flags to pass to input-mt */ | 114 | unsigned mt_flags; /* flags to pass to input-mt */ |
115 | }; | 115 | }; |
116 | 116 | ||
117 | static void mt_post_parse_default_settings(struct mt_device *td); | ||
118 | static void mt_post_parse(struct mt_device *td); | ||
119 | |||
117 | /* classes of device behavior */ | 120 | /* classes of device behavior */ |
118 | #define MT_CLS_DEFAULT 0x0001 | 121 | #define MT_CLS_DEFAULT 0x0001 |
119 | 122 | ||
@@ -364,7 +367,7 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td, | |||
364 | f->usages[f->length++] = usage->hid; | 367 | f->usages[f->length++] = usage->hid; |
365 | } | 368 | } |
366 | 369 | ||
367 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 370 | static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
368 | struct hid_field *field, struct hid_usage *usage, | 371 | struct hid_field *field, struct hid_usage *usage, |
369 | unsigned long **bit, int *max) | 372 | unsigned long **bit, int *max) |
370 | { | 373 | { |
@@ -373,13 +376,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
373 | int code; | 376 | int code; |
374 | struct hid_usage *prev_usage = NULL; | 377 | struct hid_usage *prev_usage = NULL; |
375 | 378 | ||
376 | /* Only map fields from TouchScreen or TouchPad collections. | ||
377 | * We need to ignore fields that belong to other collections | ||
378 | * such as Mouse that might have the same GenericDesktop usages. */ | ||
379 | if (field->application == HID_DG_TOUCHSCREEN) | 379 | if (field->application == HID_DG_TOUCHSCREEN) |
380 | td->mt_flags |= INPUT_MT_DIRECT; | 380 | td->mt_flags |= INPUT_MT_DIRECT; |
381 | else if (field->application != HID_DG_TOUCHPAD) | ||
382 | return 0; | ||
383 | 381 | ||
384 | /* | 382 | /* |
385 | * Model touchscreens providing buttons as touchpads. | 383 | * Model touchscreens providing buttons as touchpads. |
@@ -388,12 +386,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
388 | (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) | 386 | (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) |
389 | td->mt_flags |= INPUT_MT_POINTER; | 387 | td->mt_flags |= INPUT_MT_POINTER; |
390 | 388 | ||
391 | /* eGalax devices provide a Digitizer.Stylus input which overrides | ||
392 | * the correct Digitizers.Finger X/Y ranges. | ||
393 | * Let's just ignore this input. */ | ||
394 | if (field->physical == HID_DG_STYLUS) | ||
395 | return -1; | ||
396 | |||
397 | if (usage->usage_index) | 389 | if (usage->usage_index) |
398 | prev_usage = &field->usage[usage->usage_index - 1]; | 390 | prev_usage = &field->usage[usage->usage_index - 1]; |
399 | 391 | ||
@@ -514,7 +506,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
514 | return 0; | 506 | return 0; |
515 | } | 507 | } |
516 | 508 | ||
517 | static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 509 | static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
518 | struct hid_field *field, struct hid_usage *usage, | 510 | struct hid_field *field, struct hid_usage *usage, |
519 | unsigned long **bit, int *max) | 511 | unsigned long **bit, int *max) |
520 | { | 512 | { |
@@ -605,7 +597,7 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) | |||
605 | td->num_received = 0; | 597 | td->num_received = 0; |
606 | } | 598 | } |
607 | 599 | ||
608 | static int mt_event(struct hid_device *hid, struct hid_field *field, | 600 | static int mt_touch_event(struct hid_device *hid, struct hid_field *field, |
609 | struct hid_usage *usage, __s32 value) | 601 | struct hid_usage *usage, __s32 value) |
610 | { | 602 | { |
611 | /* we will handle the hidinput part later, now remains hiddev */ | 603 | /* we will handle the hidinput part later, now remains hiddev */ |
@@ -681,19 +673,13 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, | |||
681 | } | 673 | } |
682 | } | 674 | } |
683 | 675 | ||
684 | static void mt_report(struct hid_device *hid, struct hid_report *report) | 676 | static void mt_touch_report(struct hid_device *hid, struct hid_report *report) |
685 | { | 677 | { |
686 | struct mt_device *td = hid_get_drvdata(hid); | 678 | struct mt_device *td = hid_get_drvdata(hid); |
687 | struct hid_field *field; | 679 | struct hid_field *field; |
688 | unsigned count; | 680 | unsigned count; |
689 | int r, n; | 681 | int r, n; |
690 | 682 | ||
691 | if (report->id != td->mt_report_id) | ||
692 | return; | ||
693 | |||
694 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | ||
695 | return; | ||
696 | |||
697 | /* | 683 | /* |
698 | * Includes multi-packet support where subsequent | 684 | * Includes multi-packet support where subsequent |
699 | * packets are sent with zero contactcount. | 685 | * packets are sent with zero contactcount. |
@@ -721,6 +707,81 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) | |||
721 | mt_sync_frame(td, report->field[0]->hidinput->input); | 707 | mt_sync_frame(td, report->field[0]->hidinput->input); |
722 | } | 708 | } |
723 | 709 | ||
710 | static void mt_touch_input_configured(struct hid_device *hdev, | ||
711 | struct hid_input *hi) | ||
712 | { | ||
713 | struct mt_device *td = hid_get_drvdata(hdev); | ||
714 | struct mt_class *cls = &td->mtclass; | ||
715 | struct input_dev *input = hi->input; | ||
716 | |||
717 | if (!td->maxcontacts) | ||
718 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | ||
719 | |||
720 | mt_post_parse(td); | ||
721 | if (td->serial_maybe) | ||
722 | mt_post_parse_default_settings(td); | ||
723 | |||
724 | if (cls->is_indirect) | ||
725 | td->mt_flags |= INPUT_MT_POINTER; | ||
726 | |||
727 | if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) | ||
728 | td->mt_flags |= INPUT_MT_DROP_UNUSED; | ||
729 | |||
730 | input_mt_init_slots(input, td->maxcontacts, td->mt_flags); | ||
731 | |||
732 | td->mt_flags = 0; | ||
733 | } | ||
734 | |||
735 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
736 | struct hid_field *field, struct hid_usage *usage, | ||
737 | unsigned long **bit, int *max) | ||
738 | { | ||
739 | /* Only map fields from TouchScreen or TouchPad collections. | ||
740 | * We need to ignore fields that belong to other collections | ||
741 | * such as Mouse that might have the same GenericDesktop usages. */ | ||
742 | if (field->application != HID_DG_TOUCHSCREEN && | ||
743 | field->application != HID_DG_TOUCHPAD) | ||
744 | return 0; | ||
745 | |||
746 | /* eGalax devices provide a Digitizer.Stylus input which overrides | ||
747 | * the correct Digitizers.Finger X/Y ranges. | ||
748 | * Let's just ignore this input. */ | ||
749 | if (field->physical == HID_DG_STYLUS) | ||
750 | return -1; | ||
751 | |||
752 | return mt_touch_input_mapping(hdev, hi, field, usage, bit, max); | ||
753 | } | ||
754 | |||
755 | static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
756 | struct hid_field *field, struct hid_usage *usage, | ||
757 | unsigned long **bit, int *max) | ||
758 | { | ||
759 | return mt_touch_input_mapped(hdev, hi, field, usage, bit, max); | ||
760 | } | ||
761 | |||
762 | static int mt_event(struct hid_device *hid, struct hid_field *field, | ||
763 | struct hid_usage *usage, __s32 value) | ||
764 | { | ||
765 | struct mt_device *td = hid_get_drvdata(hid); | ||
766 | |||
767 | if (field->report->id == td->mt_report_id) | ||
768 | return mt_touch_event(hid, field, usage, value); | ||
769 | |||
770 | /* ignore other reports */ | ||
771 | return 1; | ||
772 | } | ||
773 | |||
774 | static void mt_report(struct hid_device *hid, struct hid_report *report) | ||
775 | { | ||
776 | struct mt_device *td = hid_get_drvdata(hid); | ||
777 | |||
778 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | ||
779 | return; | ||
780 | |||
781 | if (report->id == td->mt_report_id) | ||
782 | mt_touch_report(hid, report); | ||
783 | } | ||
784 | |||
724 | static void mt_set_input_mode(struct hid_device *hdev) | 785 | static void mt_set_input_mode(struct hid_device *hdev) |
725 | { | 786 | { |
726 | struct mt_device *td = hid_get_drvdata(hdev); | 787 | struct mt_device *td = hid_get_drvdata(hdev); |
@@ -795,32 +856,14 @@ static void mt_post_parse(struct mt_device *td) | |||
795 | } | 856 | } |
796 | 857 | ||
797 | static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) | 858 | static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) |
798 | |||
799 | { | 859 | { |
800 | struct mt_device *td = hid_get_drvdata(hdev); | ||
801 | struct mt_class *cls = &td->mtclass; | ||
802 | struct input_dev *input = hi->input; | 860 | struct input_dev *input = hi->input; |
803 | 861 | ||
804 | /* Only initialize slots for MT input devices */ | 862 | /* Only initialize slots for MT input devices */ |
805 | if (!test_bit(ABS_MT_POSITION_X, input->absbit)) | 863 | if (!test_bit(ABS_MT_POSITION_X, input->absbit)) |
806 | return; | 864 | return; |
807 | 865 | ||
808 | if (!td->maxcontacts) | 866 | mt_touch_input_configured(hdev, hi); |
809 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | ||
810 | |||
811 | mt_post_parse(td); | ||
812 | if (td->serial_maybe) | ||
813 | mt_post_parse_default_settings(td); | ||
814 | |||
815 | if (cls->is_indirect) | ||
816 | td->mt_flags |= INPUT_MT_POINTER; | ||
817 | |||
818 | if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) | ||
819 | td->mt_flags |= INPUT_MT_DROP_UNUSED; | ||
820 | |||
821 | input_mt_init_slots(input, td->maxcontacts, td->mt_flags); | ||
822 | |||
823 | td->mt_flags = 0; | ||
824 | } | 867 | } |
825 | 868 | ||
826 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | 869 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |