aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2013-03-22 13:38:29 -0400
committerJiri Kosina <jkosina@suse.cz>2013-03-27 09:02:45 -0400
commita69c5f8b16c05e68d41e4858c1c2c55fddf085e1 (patch)
tree5f92fe6eba3a44984bb9a86cad63a9844b330132
parent4f22decf9b6329acfe59091c5cba6b378b9b31db (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.c123
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
117static void mt_post_parse_default_settings(struct mt_device *td);
118static 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
367static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, 370static 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
517static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, 509static 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
608static int mt_event(struct hid_device *hid, struct hid_field *field, 600static 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
684static void mt_report(struct hid_device *hid, struct hid_report *report) 676static 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
710static 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
735static 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
755static 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
762static 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
774static 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
724static void mt_set_input_mode(struct hid_device *hdev) 785static 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
797static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) 858static 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
826static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 869static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)