aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-02-28 11:41:25 -0500
committerJiri Kosina <jkosina@suse.cz>2014-03-05 08:29:31 -0500
commit6aef704e38293524067505eeafec9c811b18d66a (patch)
tree6c38bc7a38fa4c0cbcf4b1fc71bf80bfaf8954e8
parente55f62008671f9200e124bcb3c736cfc3e661c2a (diff)
HID: multitouch: add support of other generic collections in hid-mt
The ANTON Touch Pad is a device which can switch from a multitouch touchpad to a mouse. It thus presents several generic collections which are currently ignored by hid-multitouch. Enable them by not ignoring them in mt_input_mapping. Adding also a suffix for them depending on their application. Reported-by: Edel Maks <edelmaks@gmail.com> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-multitouch.c82
-rw-r--r--include/linux/hid.h3
3 files changed, 82 insertions, 6 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 92b40c09d917..ca9b206a01c1 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -67,6 +67,9 @@
67#define USB_VENDOR_ID_ALPS 0x0433 67#define USB_VENDOR_ID_ALPS 0x0433
68#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 68#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
69 69
70#define USB_VENDOR_ID_ANTON 0x1130
71#define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101
72
70#define USB_VENDOR_ID_APPLE 0x05ac 73#define USB_VENDOR_ID_APPLE 0x05ac
71#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 74#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
72#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d 75#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 8250cc0fd5f4..0d3113969c43 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -84,6 +84,7 @@ struct mt_class {
84 __s32 sn_pressure; /* Signal/noise ratio for pressure events */ 84 __s32 sn_pressure; /* Signal/noise ratio for pressure events */
85 __u8 maxcontacts; 85 __u8 maxcontacts;
86 bool is_indirect; /* true for touchpads */ 86 bool is_indirect; /* true for touchpads */
87 bool export_all_inputs; /* do not ignore mouse, keyboards, etc... */
87}; 88};
88 89
89struct mt_fields { 90struct mt_fields {
@@ -133,6 +134,7 @@ static void mt_post_parse(struct mt_device *td);
133/* reserved 0x0010 */ 134/* reserved 0x0010 */
134/* reserved 0x0011 */ 135/* reserved 0x0011 */
135#define MT_CLS_WIN_8 0x0012 136#define MT_CLS_WIN_8 0x0012
137#define MT_CLS_EXPORT_ALL_INPUTS 0x0013
136 138
137/* vendor specific classes */ 139/* vendor specific classes */
138#define MT_CLS_3M 0x0101 140#define MT_CLS_3M 0x0101
@@ -196,6 +198,10 @@ static struct mt_class mt_classes[] = {
196 MT_QUIRK_IGNORE_DUPLICATES | 198 MT_QUIRK_IGNORE_DUPLICATES |
197 MT_QUIRK_HOVERING | 199 MT_QUIRK_HOVERING |
198 MT_QUIRK_CONTACT_CNT_ACCURATE }, 200 MT_QUIRK_CONTACT_CNT_ACCURATE },
201 { .name = MT_CLS_EXPORT_ALL_INPUTS,
202 .quirks = MT_QUIRK_ALWAYS_VALID |
203 MT_QUIRK_CONTACT_CNT_ACCURATE,
204 .export_all_inputs = true },
199 205
200 /* 206 /*
201 * vendor specific classes 207 * vendor specific classes
@@ -718,28 +724,52 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
718 struct hid_field *field, struct hid_usage *usage, 724 struct hid_field *field, struct hid_usage *usage,
719 unsigned long **bit, int *max) 725 unsigned long **bit, int *max)
720{ 726{
721 /* Only map fields from TouchScreen or TouchPad collections. 727 struct mt_device *td = hid_get_drvdata(hdev);
722 * We need to ignore fields that belong to other collections 728
723 * such as Mouse that might have the same GenericDesktop usages. */ 729 /*
724 if (field->application != HID_DG_TOUCHSCREEN && 730 * If mtclass.export_all_inputs is not set, only map fields from
731 * TouchScreen or TouchPad collections. We need to ignore fields
732 * that belong to other collections such as Mouse that might have
733 * the same GenericDesktop usages.
734 */
735 if (!td->mtclass.export_all_inputs &&
736 field->application != HID_DG_TOUCHSCREEN &&
725 field->application != HID_DG_PEN && 737 field->application != HID_DG_PEN &&
726 field->application != HID_DG_TOUCHPAD) 738 field->application != HID_DG_TOUCHPAD)
727 return -1; 739 return -1;
728 740
741 /*
742 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
743 * for the stylus.
744 */
729 if (field->physical == HID_DG_STYLUS) 745 if (field->physical == HID_DG_STYLUS)
730 return 0; 746 return 0;
731 747
732 return mt_touch_input_mapping(hdev, hi, field, usage, bit, max); 748 if (field->application == HID_DG_TOUCHSCREEN ||
749 field->application == HID_DG_TOUCHPAD)
750 return mt_touch_input_mapping(hdev, hi, field, usage, bit, max);
751
752 /* let hid-core decide for the others */
753 return 0;
733} 754}
734 755
735static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, 756static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
736 struct hid_field *field, struct hid_usage *usage, 757 struct hid_field *field, struct hid_usage *usage,
737 unsigned long **bit, int *max) 758 unsigned long **bit, int *max)
738{ 759{
760 /*
761 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
762 * for the stylus.
763 */
739 if (field->physical == HID_DG_STYLUS) 764 if (field->physical == HID_DG_STYLUS)
740 return 0; 765 return 0;
741 766
742 return mt_touch_input_mapped(hdev, hi, field, usage, bit, max); 767 if (field->application == HID_DG_TOUCHSCREEN ||
768 field->application == HID_DG_TOUCHPAD)
769 return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
770
771 /* let hid-core decide for the others */
772 return 0;
743} 773}
744 774
745static int mt_event(struct hid_device *hid, struct hid_field *field, 775static int mt_event(struct hid_device *hid, struct hid_field *field,
@@ -846,14 +876,49 @@ static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
846 struct mt_device *td = hid_get_drvdata(hdev); 876 struct mt_device *td = hid_get_drvdata(hdev);
847 char *name; 877 char *name;
848 const char *suffix = NULL; 878 const char *suffix = NULL;
879 struct hid_field *field = hi->report->field[0];
849 880
850 if (hi->report->id == td->mt_report_id) 881 if (hi->report->id == td->mt_report_id)
851 mt_touch_input_configured(hdev, hi); 882 mt_touch_input_configured(hdev, hi);
852 883
884 /*
885 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
886 * for the stylus. Check this first, and then rely on the application
887 * field.
888 */
853 if (hi->report->field[0]->physical == HID_DG_STYLUS) { 889 if (hi->report->field[0]->physical == HID_DG_STYLUS) {
854 suffix = "Pen"; 890 suffix = "Pen";
855 /* force BTN_STYLUS to allow tablet matching in udev */ 891 /* force BTN_STYLUS to allow tablet matching in udev */
856 __set_bit(BTN_STYLUS, hi->input->keybit); 892 __set_bit(BTN_STYLUS, hi->input->keybit);
893 } else {
894 switch (field->application) {
895 case HID_GD_KEYBOARD:
896 suffix = "Keyboard";
897 break;
898 case HID_GD_KEYPAD:
899 suffix = "Keypad";
900 break;
901 case HID_GD_MOUSE:
902 suffix = "Mouse";
903 break;
904 case HID_DG_STYLUS:
905 suffix = "Pen";
906 /* force BTN_STYLUS to allow tablet matching in udev */
907 __set_bit(BTN_STYLUS, hi->input->keybit);
908 break;
909 case HID_DG_TOUCHSCREEN:
910 /* we do not set suffix = "Touchscreen" */
911 break;
912 case HID_GD_SYSTEM_CONTROL:
913 suffix = "System Control";
914 break;
915 case HID_CP_CONSUMER_CONTROL:
916 suffix = "Consumer Control";
917 break;
918 default:
919 suffix = "UNKNOWN";
920 break;
921 }
857 } 922 }
858 923
859 if (suffix) { 924 if (suffix) {
@@ -992,6 +1057,11 @@ static const struct hid_device_id mt_devices[] = {
992 MT_USB_DEVICE(USB_VENDOR_ID_3M, 1057 MT_USB_DEVICE(USB_VENDOR_ID_3M,
993 USB_DEVICE_ID_3M3266) }, 1058 USB_DEVICE_ID_3M3266) },
994 1059
1060 /* Anton devices */
1061 { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
1062 MT_USB_DEVICE(USB_VENDOR_ID_ANTON,
1063 USB_DEVICE_ID_ANTON_TOUCH_PAD) },
1064
995 /* Atmel panels */ 1065 /* Atmel panels */
996 { .driver_data = MT_CLS_SERIAL, 1066 { .driver_data = MT_CLS_SERIAL,
997 MT_USB_DEVICE(USB_VENDOR_ID_ATMEL, 1067 MT_USB_DEVICE(USB_VENDOR_ID_ATMEL,
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 5eb282e0dff7..e224516cc565 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -201,6 +201,7 @@ struct hid_item {
201#define HID_GD_VBRZ 0x00010045 201#define HID_GD_VBRZ 0x00010045
202#define HID_GD_VNO 0x00010046 202#define HID_GD_VNO 0x00010046
203#define HID_GD_FEATURE 0x00010047 203#define HID_GD_FEATURE 0x00010047
204#define HID_GD_SYSTEM_CONTROL 0x00010080
204#define HID_GD_UP 0x00010090 205#define HID_GD_UP 0x00010090
205#define HID_GD_DOWN 0x00010091 206#define HID_GD_DOWN 0x00010091
206#define HID_GD_RIGHT 0x00010092 207#define HID_GD_RIGHT 0x00010092
@@ -208,6 +209,8 @@ struct hid_item {
208 209
209#define HID_DC_BATTERYSTRENGTH 0x00060020 210#define HID_DC_BATTERYSTRENGTH 0x00060020
210 211
212#define HID_CP_CONSUMER_CONTROL 0x000c0001
213
211#define HID_DG_DIGITIZER 0x000d0001 214#define HID_DG_DIGITIZER 0x000d0001
212#define HID_DG_PEN 0x000d0002 215#define HID_DG_PEN 0x000d0002
213#define HID_DG_LIGHTPEN 0x000d0003 216#define HID_DG_LIGHTPEN 0x000d0003