aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Magnaudet <mathieu.magnaudet@gmail.com>2014-11-22 06:02:07 -0500
committerJiri Kosina <jkosina@suse.cz>2014-11-25 09:28:12 -0500
commitda10bc252476a8d1d1bdf7b94502ad2cbd7f30b1 (patch)
tree1e330d6c6951f843da9b4b073369536e934b4f4b
parent6b07974af9698225766d42175470b1a5d7bf9f48 (diff)
HID: multitouch: Add quirk for VTL touch panels
VTL panels do not switch to the multitouch mode until the input mode feature is read by the host. This should normally be done by usbhid, but it looks like an other bug prevents usbhid to properly retrieve the feature state. As a workaround, we force the reading of the feature in mt_set_input_mode for such devices. Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Mathieu Magnaudet <mathieu.magnaudet@enac.fr> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-multitouch.c27
2 files changed, 30 insertions, 0 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 7c863738e419..d6cc6a9cf10f 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -931,6 +931,9 @@
931#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 931#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
932#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 932#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
933 933
934#define USB_VENDOR_ID_VTL 0x0306
935#define USB_DEVICE_ID_VTL_MULTITOUCH_FF3F 0xff3f
936
934#define USB_VENDOR_ID_WACOM 0x056a 937#define USB_VENDOR_ID_WACOM 0x056a
935#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 938#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
936#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD 939#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 51e25b9407f2..683cda6c60ce 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -67,6 +67,7 @@ MODULE_LICENSE("GPL");
67#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) 67#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10)
68#define MT_QUIRK_HOVERING (1 << 11) 68#define MT_QUIRK_HOVERING (1 << 11)
69#define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) 69#define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12)
70#define MT_QUIRK_FORCE_GET_FEATURE (1 << 13)
70 71
71#define MT_INPUTMODE_TOUCHSCREEN 0x02 72#define MT_INPUTMODE_TOUCHSCREEN 0x02
72#define MT_INPUTMODE_TOUCHPAD 0x03 73#define MT_INPUTMODE_TOUCHPAD 0x03
@@ -150,6 +151,7 @@ static void mt_post_parse(struct mt_device *td);
150#define MT_CLS_FLATFROG 0x0107 151#define MT_CLS_FLATFROG 0x0107
151#define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108 152#define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108
152#define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109 153#define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109
154#define MT_CLS_VTL 0x0110
153 155
154#define MT_DEFAULT_MAXCONTACT 10 156#define MT_DEFAULT_MAXCONTACT 10
155#define MT_MAX_MAXCONTACT 250 157#define MT_MAX_MAXCONTACT 250
@@ -255,6 +257,11 @@ static struct mt_class mt_classes[] = {
255 .sn_move = 2048, 257 .sn_move = 2048,
256 .maxcontacts = 40, 258 .maxcontacts = 40,
257 }, 259 },
260 { .name = MT_CLS_VTL,
261 .quirks = MT_QUIRK_ALWAYS_VALID |
262 MT_QUIRK_CONTACT_CNT_ACCURATE |
263 MT_QUIRK_FORCE_GET_FEATURE,
264 },
258 { } 265 { }
259}; 266};
260 267
@@ -809,6 +816,9 @@ static void mt_set_input_mode(struct hid_device *hdev)
809 struct mt_device *td = hid_get_drvdata(hdev); 816 struct mt_device *td = hid_get_drvdata(hdev);
810 struct hid_report *r; 817 struct hid_report *r;
811 struct hid_report_enum *re; 818 struct hid_report_enum *re;
819 struct mt_class *cls = &td->mtclass;
820 char *buf;
821 int report_len;
812 822
813 if (td->inputmode < 0) 823 if (td->inputmode < 0)
814 return; 824 return;
@@ -816,6 +826,18 @@ static void mt_set_input_mode(struct hid_device *hdev)
816 re = &(hdev->report_enum[HID_FEATURE_REPORT]); 826 re = &(hdev->report_enum[HID_FEATURE_REPORT]);
817 r = re->report_id_hash[td->inputmode]; 827 r = re->report_id_hash[td->inputmode];
818 if (r) { 828 if (r) {
829 if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
830 report_len = ((r->size - 1) >> 3) + 1 + (r->id > 0);
831 buf = hid_alloc_report_buf(r, GFP_KERNEL);
832 if (!buf) {
833 hid_err(hdev, "failed to allocate buffer for report\n");
834 return;
835 }
836 hid_hw_raw_request(hdev, r->id, buf, report_len,
837 HID_FEATURE_REPORT,
838 HID_REQ_GET_REPORT);
839 kfree(buf);
840 }
819 r->field[0]->value[td->inputmode_index] = td->inputmode_value; 841 r->field[0]->value[td->inputmode_index] = td->inputmode_value;
820 hid_hw_request(hdev, r, HID_REQ_SET_REPORT); 842 hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
821 } 843 }
@@ -1281,6 +1303,11 @@ static const struct hid_device_id mt_devices[] = {
1281 MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, 1303 MT_USB_DEVICE(USB_VENDOR_ID_UNITEC,
1282 USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, 1304 USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
1283 1305
1306 /* VTL panels */
1307 { .driver_data = MT_CLS_VTL,
1308 MT_USB_DEVICE(USB_VENDOR_ID_VTL,
1309 USB_DEVICE_ID_VTL_MULTITOUCH_FF3F) },
1310
1284 /* Wistron panels */ 1311 /* Wistron panels */
1285 { .driver_data = MT_CLS_NSMU, 1312 { .driver_data = MT_CLS_NSMU,
1286 MT_USB_DEVICE(USB_VENDOR_ID_WISTRON, 1313 MT_USB_DEVICE(USB_VENDOR_ID_WISTRON,