diff options
29 files changed, 755 insertions, 1351 deletions
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus new file mode 100644 index 000000000000..c2a270b45b03 --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus | |||
@@ -0,0 +1,10 @@ | |||
1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile | ||
2 | Date: October 2010 | ||
3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
4 | Description: The integer value of this attribute ranges from 0-4. | ||
5 | When read, this attribute returns the number of the actual | ||
6 | profile. This value is persistent, so its equivalent to the | ||
7 | profile that's active when the mouse is powered on next time. | ||
8 | When written, this file sets the number of the startup profile | ||
9 | and the mouse activates this profile immediately. | ||
10 | Please use actual_profile, it does the same thing. | ||
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus index 326e05452da7..c1b53b8bc2ae 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus | |||
@@ -1,9 +1,12 @@ | |||
1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile | 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile |
2 | Date: October 2010 | 2 | Date: October 2010 |
3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
4 | Description: When read, this file returns the number of the actual profile in | 4 | Description: The integer value of this attribute ranges from 0-4. |
5 | range 0-4. | 5 | When read, this attribute returns the number of the actual |
6 | This file is readonly. | 6 | profile. This value is persistent, so its equivalent to the |
7 | profile that's active when the mouse is powered on next time. | ||
8 | When written, this file sets the number of the startup profile | ||
9 | and the mouse activates this profile immediately. | ||
7 | Users: http://roccat.sourceforge.net | 10 | Users: http://roccat.sourceforge.net |
8 | 11 | ||
9 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version | 12 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version |
@@ -89,16 +92,6 @@ Description: The mouse has a tracking- and a distance-control-unit. These | |||
89 | This file is writeonly. | 92 | This file is writeonly. |
90 | Users: http://roccat.sourceforge.net | 93 | Users: http://roccat.sourceforge.net |
91 | 94 | ||
92 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile | ||
93 | Date: October 2010 | ||
94 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
95 | Description: The integer value of this attribute ranges from 0-4. | ||
96 | When read, this attribute returns the number of the profile | ||
97 | that's active when the mouse is powered on. | ||
98 | When written, this file sets the number of the startup profile | ||
99 | and the mouse activates this profile immediately. | ||
100 | Users: http://roccat.sourceforge.net | ||
101 | |||
102 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu | 95 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu |
103 | Date: October 2010 | 96 | Date: October 2010 |
104 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 97 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
diff --git a/Documentation/usb/hiddev.txt b/Documentation/hid/hiddev.txt index 6e8c9f1d2f22..6e8c9f1d2f22 100644 --- a/Documentation/usb/hiddev.txt +++ b/Documentation/hid/hiddev.txt | |||
diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt new file mode 100644 index 000000000000..029e6cb9a7e8 --- /dev/null +++ b/Documentation/hid/hidraw.txt | |||
@@ -0,0 +1,119 @@ | |||
1 | HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices | ||
2 | ================================================================== | ||
3 | |||
4 | The hidraw driver provides a raw interface to USB and Bluetooth Human | ||
5 | Interface Devices (HIDs). It differs from hiddev in that reports sent and | ||
6 | received are not parsed by the HID parser, but are sent to and received from | ||
7 | the device unmodified. | ||
8 | |||
9 | Hidraw should be used if the userspace application knows exactly how to | ||
10 | communicate with the hardware device, and is able to construct the HID | ||
11 | reports manually. This is often the case when making userspace drivers for | ||
12 | custom HID devices. | ||
13 | |||
14 | Hidraw is also useful for communicating with non-conformant HID devices | ||
15 | which send and receive data in a way that is inconsistent with their report | ||
16 | descriptors. Because hiddev parses reports which are sent and received | ||
17 | through it, checking them against the device's report descriptor, such | ||
18 | communication with these non-conformant devices is impossible using hiddev. | ||
19 | Hidraw is the only alternative, short of writing a custom kernel driver, for | ||
20 | these non-conformant devices. | ||
21 | |||
22 | A benefit of hidraw is that its use by userspace applications is independent | ||
23 | of the underlying hardware type. Currently, Hidraw is implemented for USB | ||
24 | and Bluetooth. In the future, as new hardware bus types are developed which | ||
25 | use the HID specification, hidraw will be expanded to add support for these | ||
26 | new bus types. | ||
27 | |||
28 | Hidraw uses a dynamic major number, meaning that udev should be relied on to | ||
29 | create hidraw device nodes. Udev will typically create the device nodes | ||
30 | directly under /dev (eg: /dev/hidraw0). As this location is distribution- | ||
31 | and udev rule-dependent, applications should use libudev to locate hidraw | ||
32 | devices attached to the system. There is a tutorial on libudev with a | ||
33 | working example at: | ||
34 | http://www.signal11.us/oss/udev/ | ||
35 | |||
36 | The HIDRAW API | ||
37 | --------------- | ||
38 | |||
39 | read() | ||
40 | ------- | ||
41 | read() will read a queued report received from the HID device. On USB | ||
42 | devices, the reports read using read() are the reports sent from the device | ||
43 | on the INTERRUPT IN endpoint. By default, read() will block until there is | ||
44 | a report available to be read. read() can be made non-blocking, by passing | ||
45 | the O_NONBLOCK flag to open(), or by setting the O_NONBLOCK flag using | ||
46 | fcntl(). | ||
47 | |||
48 | On a device which uses numbered reports, the first byte of the returned data | ||
49 | will be the report number; the report data follows, beginning in the second | ||
50 | byte. For devices which do not use numbered reports, the report data | ||
51 | will begin at the first byte. | ||
52 | |||
53 | write() | ||
54 | -------- | ||
55 | The write() function will write a report to the device. For USB devices, if | ||
56 | the device has an INTERRUPT OUT endpoint, the report will be sent on that | ||
57 | endpoint. If it does not, the report will be sent over the control endpoint, | ||
58 | using a SET_REPORT transfer. | ||
59 | |||
60 | The first byte of the buffer passed to write() should be set to the report | ||
61 | number. If the device does not use numbered reports, the first byte should | ||
62 | be set to 0. The report data itself should begin at the second byte. | ||
63 | |||
64 | ioctl() | ||
65 | -------- | ||
66 | Hidraw supports the following ioctls: | ||
67 | |||
68 | HIDIOCGRDESCSIZE: Get Report Descriptor Size | ||
69 | This ioctl will get the size of the device's report descriptor. | ||
70 | |||
71 | HIDIOCGRDESC: Get Report Descriptor | ||
72 | This ioctl returns the device's report descriptor using a | ||
73 | hidraw_report_descriptor struct. Make sure to set the size field of the | ||
74 | hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE. | ||
75 | |||
76 | HIDIOCGRAWINFO: Get Raw Info | ||
77 | This ioctl will return a hidraw_devinfo struct containing the bus type, the | ||
78 | vendor ID (VID), and product ID (PID) of the device. The bus type can be one | ||
79 | of: | ||
80 | BUS_USB | ||
81 | BUS_HIL | ||
82 | BUS_BLUETOOTH | ||
83 | BUS_VIRTUAL | ||
84 | which are defined in linux/input.h. | ||
85 | |||
86 | HIDIOCGRAWNAME(len): Get Raw Name | ||
87 | This ioctl returns a string containing the vendor and product strings of | ||
88 | the device. The returned string is Unicode, UTF-8 encoded. | ||
89 | |||
90 | HIDIOCGRAWPHYS(len): Get Physical Address | ||
91 | This ioctl returns a string representing the physical address of the device. | ||
92 | For USB devices, the string contains the physical path to the device (the | ||
93 | USB controller, hubs, ports, etc). For Bluetooth devices, the string | ||
94 | contains the hardware (MAC) address of the device. | ||
95 | |||
96 | HIDIOCSFEATURE(len): Send a Feature Report | ||
97 | This ioctl will send a feature report to the device. Per the HID | ||
98 | specification, feature reports are always sent using the control endpoint. | ||
99 | Set the first byte of the supplied buffer to the report number. For devices | ||
100 | which do not use numbered reports, set the first byte to 0. The report data | ||
101 | begins in the second byte. Make sure to set len accordingly, to one more | ||
102 | than the length of the report (to account for the report number). | ||
103 | |||
104 | HIDIOCGFEATURE(len): Get a Feature Report | ||
105 | This ioctl will request a feature report from the device using the control | ||
106 | endpoint. The first byte of the supplied buffer should be set to the report | ||
107 | number of the requested report. For devices which do not use numbered | ||
108 | reports, set the first byte to 0. The report will be returned starting at | ||
109 | the first byte of the buffer (ie: the report number is not returned). | ||
110 | |||
111 | Example | ||
112 | --------- | ||
113 | In samples/, find hid-example.c, which shows examples of read(), write(), | ||
114 | and all the ioctls for hidraw. The code may be used by anyone for any | ||
115 | purpose, and can serve as a starting point for developing applications using | ||
116 | hidraw. | ||
117 | |||
118 | Document by: | ||
119 | Alan Ott <alan@signal11.us>, Signal 11 Software | ||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 9de9e97149ec..67d2a7585934 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -55,12 +55,6 @@ source "drivers/hid/usbhid/Kconfig" | |||
55 | menu "Special HID drivers" | 55 | menu "Special HID drivers" |
56 | depends on HID | 56 | depends on HID |
57 | 57 | ||
58 | config HID_3M_PCT | ||
59 | tristate "3M PCT touchscreen" | ||
60 | depends on USB_HID | ||
61 | ---help--- | ||
62 | Support for 3M PCT touch screens. | ||
63 | |||
64 | config HID_A4TECH | 58 | config HID_A4TECH |
65 | tristate "A4 tech mice" if EXPERT | 59 | tristate "A4 tech mice" if EXPERT |
66 | depends on USB_HID | 60 | depends on USB_HID |
@@ -100,12 +94,6 @@ config HID_BELKIN | |||
100 | ---help--- | 94 | ---help--- |
101 | Support for Belkin Flip KVM and Wireless keyboard. | 95 | Support for Belkin Flip KVM and Wireless keyboard. |
102 | 96 | ||
103 | config HID_CANDO | ||
104 | tristate "Cando dual touch panel" | ||
105 | depends on USB_HID | ||
106 | ---help--- | ||
107 | Support for Cando dual touch panel. | ||
108 | |||
109 | config HID_CHERRY | 97 | config HID_CHERRY |
110 | tristate "Cherry Cymotion keyboard" if EXPERT | 98 | tristate "Cherry Cymotion keyboard" if EXPERT |
111 | depends on USB_HID | 99 | depends on USB_HID |
@@ -300,12 +288,6 @@ config HID_MICROSOFT | |||
300 | ---help--- | 288 | ---help--- |
301 | Support for Microsoft devices that are not fully compliant with HID standard. | 289 | Support for Microsoft devices that are not fully compliant with HID standard. |
302 | 290 | ||
303 | config HID_MOSART | ||
304 | tristate "MosArt dual-touch panels" | ||
305 | depends on USB_HID | ||
306 | ---help--- | ||
307 | Support for MosArt dual-touch panels. | ||
308 | |||
309 | config HID_MONTEREY | 291 | config HID_MONTEREY |
310 | tristate "Monterey Genius KB29E keyboard" if EXPERT | 292 | tristate "Monterey Genius KB29E keyboard" if EXPERT |
311 | depends on USB_HID | 293 | depends on USB_HID |
@@ -320,13 +302,25 @@ config HID_MULTITOUCH | |||
320 | Generic support for HID multitouch panels. | 302 | Generic support for HID multitouch panels. |
321 | 303 | ||
322 | Say Y here if you have one of the following devices: | 304 | Say Y here if you have one of the following devices: |
305 | - 3M PCT touch screens | ||
306 | - ActionStar dual touch panels | ||
307 | - Cando dual touch panels | ||
308 | - CVTouch panels | ||
323 | - Cypress TrueTouch panels | 309 | - Cypress TrueTouch panels |
310 | - Elo TouchSystems IntelliTouch Plus panels | ||
311 | - GeneralTouch 'Sensing Win7-TwoFinger' panels | ||
312 | - GoodTouch panels | ||
324 | - Hanvon dual touch panels | 313 | - Hanvon dual touch panels |
314 | - Ilitek dual touch panels | ||
325 | - IrTouch Infrared USB panels | 315 | - IrTouch Infrared USB panels |
316 | - Lumio CrystalTouch panels | ||
317 | - MosArt dual-touch panels | ||
318 | - PenMount dual touch panels | ||
326 | - Pixcir dual touch panels | 319 | - Pixcir dual touch panels |
327 | - 'Sensing Win7-TwoFinger' panel by GeneralTouch | 320 | - eGalax dual-touch panels, including the Joojoo and Wetab tablets |
328 | - eGalax dual-touch panels, including the | 321 | - Stantum multitouch panels |
329 | Joojoo and Wetab tablets | 322 | - Touch International Panels |
323 | - Unitec Panels | ||
330 | 324 | ||
331 | If unsure, say N. | 325 | If unsure, say N. |
332 | 326 | ||
@@ -500,12 +494,6 @@ config HID_SONY | |||
500 | ---help--- | 494 | ---help--- |
501 | Support for Sony PS3 controller. | 495 | Support for Sony PS3 controller. |
502 | 496 | ||
503 | config HID_STANTUM | ||
504 | tristate "Stantum multitouch panel" | ||
505 | depends on USB_HID | ||
506 | ---help--- | ||
507 | Support for Stantum multitouch panel. | ||
508 | |||
509 | config HID_SUNPLUS | 497 | config HID_SUNPLUS |
510 | tristate "Sunplus wireless desktop" | 498 | tristate "Sunplus wireless desktop" |
511 | depends on USB_HID | 499 | depends on USB_HID |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 06c68ae3abee..f8cc4ea7335a 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -25,12 +25,10 @@ ifdef CONFIG_LOGIWII_FF | |||
25 | hid-logitech-y += hid-lg4ff.o | 25 | hid-logitech-y += hid-lg4ff.o |
26 | endif | 26 | endif |
27 | 27 | ||
28 | obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o | ||
29 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 28 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
30 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o | 29 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o |
31 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 30 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
32 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | 31 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o |
33 | obj-$(CONFIG_HID_CANDO) += hid-cando.o | ||
34 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 32 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
35 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | 33 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o |
36 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | 34 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o |
@@ -47,7 +45,6 @@ obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o | |||
47 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o | 45 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o |
48 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | 46 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o |
49 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 47 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
50 | obj-$(CONFIG_HID_MOSART) += hid-mosart.o | ||
51 | obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o | 48 | obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o |
52 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o | 49 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o |
53 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o | 50 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o |
@@ -66,7 +63,6 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o | |||
66 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 63 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
67 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 64 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o |
68 | obj-$(CONFIG_HID_SONY) += hid-sony.o | 65 | obj-$(CONFIG_HID_SONY) += hid-sony.o |
69 | obj-$(CONFIG_HID_STANTUM) += hid-stantum.o | ||
70 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o | 66 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o |
71 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o | 67 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o |
72 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o | 68 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o |
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c deleted file mode 100644 index 5243ae2d3730..000000000000 --- a/drivers/hid/hid-3m-pct.c +++ /dev/null | |||
@@ -1,305 +0,0 @@ | |||
1 | /* | ||
2 | * HID driver for 3M PCT multitouch panels | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> | ||
5 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | ||
6 | * Copyright (c) 2010 Canonical, Ltd. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License, or (at your option) | ||
14 | * any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/device.h> | ||
18 | #include <linux/hid.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/usb.h> | ||
22 | #include <linux/input/mt.h> | ||
23 | |||
24 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | ||
25 | MODULE_DESCRIPTION("3M PCT multitouch panels"); | ||
26 | MODULE_LICENSE("GPL"); | ||
27 | |||
28 | #include "hid-ids.h" | ||
29 | |||
30 | #define MAX_SLOTS 60 | ||
31 | |||
32 | /* estimated signal-to-noise ratios */ | ||
33 | #define SN_MOVE 2048 | ||
34 | #define SN_WIDTH 128 | ||
35 | |||
36 | struct mmm_finger { | ||
37 | __s32 x, y, w, h; | ||
38 | bool touch, valid; | ||
39 | }; | ||
40 | |||
41 | struct mmm_data { | ||
42 | struct mmm_finger f[MAX_SLOTS]; | ||
43 | __u8 curid; | ||
44 | __u8 nexp, nreal; | ||
45 | bool touch, valid; | ||
46 | }; | ||
47 | |||
48 | static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
49 | struct hid_field *field, struct hid_usage *usage, | ||
50 | unsigned long **bit, int *max) | ||
51 | { | ||
52 | int f1 = field->logical_minimum; | ||
53 | int f2 = field->logical_maximum; | ||
54 | int df = f2 - f1; | ||
55 | |||
56 | switch (usage->hid & HID_USAGE_PAGE) { | ||
57 | |||
58 | case HID_UP_BUTTON: | ||
59 | return -1; | ||
60 | |||
61 | case HID_UP_GENDESK: | ||
62 | switch (usage->hid) { | ||
63 | case HID_GD_X: | ||
64 | hid_map_usage(hi, usage, bit, max, | ||
65 | EV_ABS, ABS_MT_POSITION_X); | ||
66 | input_set_abs_params(hi->input, ABS_MT_POSITION_X, | ||
67 | f1, f2, df / SN_MOVE, 0); | ||
68 | /* touchscreen emulation */ | ||
69 | input_set_abs_params(hi->input, ABS_X, | ||
70 | f1, f2, df / SN_MOVE, 0); | ||
71 | return 1; | ||
72 | case HID_GD_Y: | ||
73 | hid_map_usage(hi, usage, bit, max, | ||
74 | EV_ABS, ABS_MT_POSITION_Y); | ||
75 | input_set_abs_params(hi->input, ABS_MT_POSITION_Y, | ||
76 | f1, f2, df / SN_MOVE, 0); | ||
77 | /* touchscreen emulation */ | ||
78 | input_set_abs_params(hi->input, ABS_Y, | ||
79 | f1, f2, df / SN_MOVE, 0); | ||
80 | return 1; | ||
81 | } | ||
82 | return 0; | ||
83 | |||
84 | case HID_UP_DIGITIZER: | ||
85 | switch (usage->hid) { | ||
86 | /* we do not want to map these: no input-oriented meaning */ | ||
87 | case 0x14: | ||
88 | case 0x23: | ||
89 | case HID_DG_INPUTMODE: | ||
90 | case HID_DG_DEVICEINDEX: | ||
91 | case HID_DG_CONTACTCOUNT: | ||
92 | case HID_DG_CONTACTMAX: | ||
93 | case HID_DG_INRANGE: | ||
94 | case HID_DG_CONFIDENCE: | ||
95 | return -1; | ||
96 | case HID_DG_TIPSWITCH: | ||
97 | /* touchscreen emulation */ | ||
98 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
99 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | ||
100 | return 1; | ||
101 | case HID_DG_WIDTH: | ||
102 | hid_map_usage(hi, usage, bit, max, | ||
103 | EV_ABS, ABS_MT_TOUCH_MAJOR); | ||
104 | input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR, | ||
105 | f1, f2, df / SN_WIDTH, 0); | ||
106 | return 1; | ||
107 | case HID_DG_HEIGHT: | ||
108 | hid_map_usage(hi, usage, bit, max, | ||
109 | EV_ABS, ABS_MT_TOUCH_MINOR); | ||
110 | input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR, | ||
111 | f1, f2, df / SN_WIDTH, 0); | ||
112 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, | ||
113 | 0, 1, 0, 0); | ||
114 | return 1; | ||
115 | case HID_DG_CONTACTID: | ||
116 | input_mt_init_slots(hi->input, MAX_SLOTS); | ||
117 | return 1; | ||
118 | } | ||
119 | /* let hid-input decide for the others */ | ||
120 | return 0; | ||
121 | |||
122 | case 0xff000000: | ||
123 | /* we do not want to map these: no input-oriented meaning */ | ||
124 | return -1; | ||
125 | } | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
131 | struct hid_field *field, struct hid_usage *usage, | ||
132 | unsigned long **bit, int *max) | ||
133 | { | ||
134 | /* tell hid-input to skip setup of these event types */ | ||
135 | if (usage->type == EV_KEY || usage->type == EV_ABS) | ||
136 | set_bit(usage->type, hi->input->evbit); | ||
137 | return -1; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * this function is called when a whole packet has been received and processed, | ||
142 | * so that it can decide what to send to the input layer. | ||
143 | */ | ||
144 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) | ||
145 | { | ||
146 | int i; | ||
147 | for (i = 0; i < MAX_SLOTS; ++i) { | ||
148 | struct mmm_finger *f = &md->f[i]; | ||
149 | if (!f->valid) { | ||
150 | /* this finger is just placeholder data, ignore */ | ||
151 | continue; | ||
152 | } | ||
153 | input_mt_slot(input, i); | ||
154 | input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch); | ||
155 | if (f->touch) { | ||
156 | /* this finger is on the screen */ | ||
157 | int wide = (f->w > f->h); | ||
158 | /* divided by two to match visual scale of touch */ | ||
159 | int major = max(f->w, f->h) >> 1; | ||
160 | int minor = min(f->w, f->h) >> 1; | ||
161 | |||
162 | input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); | ||
163 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); | ||
164 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | ||
165 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); | ||
166 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); | ||
167 | } | ||
168 | f->valid = 0; | ||
169 | } | ||
170 | |||
171 | input_mt_report_pointer_emulation(input, true); | ||
172 | input_sync(input); | ||
173 | } | ||
174 | |||
175 | /* | ||
176 | * this function is called upon all reports | ||
177 | * so that we can accumulate contact point information, | ||
178 | * and call input_mt_sync after each point. | ||
179 | */ | ||
180 | static int mmm_event(struct hid_device *hid, struct hid_field *field, | ||
181 | struct hid_usage *usage, __s32 value) | ||
182 | { | ||
183 | struct mmm_data *md = hid_get_drvdata(hid); | ||
184 | /* | ||
185 | * strangely, this function can be called before | ||
186 | * field->hidinput is initialized! | ||
187 | */ | ||
188 | if (hid->claimed & HID_CLAIMED_INPUT) { | ||
189 | struct input_dev *input = field->hidinput->input; | ||
190 | switch (usage->hid) { | ||
191 | case HID_DG_TIPSWITCH: | ||
192 | md->touch = value; | ||
193 | break; | ||
194 | case HID_DG_CONFIDENCE: | ||
195 | md->valid = value; | ||
196 | break; | ||
197 | case HID_DG_WIDTH: | ||
198 | if (md->valid) | ||
199 | md->f[md->curid].w = value; | ||
200 | break; | ||
201 | case HID_DG_HEIGHT: | ||
202 | if (md->valid) | ||
203 | md->f[md->curid].h = value; | ||
204 | break; | ||
205 | case HID_DG_CONTACTID: | ||
206 | value = clamp_val(value, 0, MAX_SLOTS - 1); | ||
207 | if (md->valid) { | ||
208 | md->curid = value; | ||
209 | md->f[value].touch = md->touch; | ||
210 | md->f[value].valid = 1; | ||
211 | md->nreal++; | ||
212 | } | ||
213 | break; | ||
214 | case HID_GD_X: | ||
215 | if (md->valid) | ||
216 | md->f[md->curid].x = value; | ||
217 | break; | ||
218 | case HID_GD_Y: | ||
219 | if (md->valid) | ||
220 | md->f[md->curid].y = value; | ||
221 | break; | ||
222 | case HID_DG_CONTACTCOUNT: | ||
223 | if (value) | ||
224 | md->nexp = value; | ||
225 | if (md->nreal >= md->nexp) { | ||
226 | mmm_filter_event(md, input); | ||
227 | md->nreal = 0; | ||
228 | } | ||
229 | break; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | /* we have handled the hidinput part, now remains hiddev */ | ||
234 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | ||
235 | hid->hiddev_hid_event(hid, field, usage, value); | ||
236 | |||
237 | return 1; | ||
238 | } | ||
239 | |||
240 | static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
241 | { | ||
242 | int ret; | ||
243 | struct mmm_data *md; | ||
244 | |||
245 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | ||
246 | |||
247 | md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); | ||
248 | if (!md) { | ||
249 | hid_err(hdev, "cannot allocate 3M data\n"); | ||
250 | return -ENOMEM; | ||
251 | } | ||
252 | hid_set_drvdata(hdev, md); | ||
253 | |||
254 | ret = hid_parse(hdev); | ||
255 | if (!ret) | ||
256 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
257 | |||
258 | if (ret) | ||
259 | kfree(md); | ||
260 | return ret; | ||
261 | } | ||
262 | |||
263 | static void mmm_remove(struct hid_device *hdev) | ||
264 | { | ||
265 | hid_hw_stop(hdev); | ||
266 | kfree(hid_get_drvdata(hdev)); | ||
267 | hid_set_drvdata(hdev, NULL); | ||
268 | } | ||
269 | |||
270 | static const struct hid_device_id mmm_devices[] = { | ||
271 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, | ||
272 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, | ||
273 | { } | ||
274 | }; | ||
275 | MODULE_DEVICE_TABLE(hid, mmm_devices); | ||
276 | |||
277 | static const struct hid_usage_id mmm_grabbed_usages[] = { | ||
278 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | ||
279 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | ||
280 | }; | ||
281 | |||
282 | static struct hid_driver mmm_driver = { | ||
283 | .name = "3m-pct", | ||
284 | .id_table = mmm_devices, | ||
285 | .probe = mmm_probe, | ||
286 | .remove = mmm_remove, | ||
287 | .input_mapping = mmm_input_mapping, | ||
288 | .input_mapped = mmm_input_mapped, | ||
289 | .usage_table = mmm_grabbed_usages, | ||
290 | .event = mmm_event, | ||
291 | }; | ||
292 | |||
293 | static int __init mmm_init(void) | ||
294 | { | ||
295 | return hid_register_driver(&mmm_driver); | ||
296 | } | ||
297 | |||
298 | static void __exit mmm_exit(void) | ||
299 | { | ||
300 | hid_unregister_driver(&mmm_driver); | ||
301 | } | ||
302 | |||
303 | module_init(mmm_init); | ||
304 | module_exit(mmm_exit); | ||
305 | |||
diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c deleted file mode 100644 index 1ea066c55201..000000000000 --- a/drivers/hid/hid-cando.c +++ /dev/null | |||
@@ -1,276 +0,0 @@ | |||
1 | /* | ||
2 | * HID driver for Cando dual-touch panels | ||
3 | * | ||
4 | * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/hid.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | ||
21 | MODULE_DESCRIPTION("Cando dual-touch panel"); | ||
22 | MODULE_LICENSE("GPL"); | ||
23 | |||
24 | #include "hid-ids.h" | ||
25 | |||
26 | struct cando_data { | ||
27 | __u16 x, y; | ||
28 | __u8 id; | ||
29 | __s8 oldest; /* id of the oldest finger in previous frame */ | ||
30 | bool valid; /* valid finger data, or just placeholder? */ | ||
31 | bool first; /* is this the first finger in this frame? */ | ||
32 | __s8 firstid; /* id of the first finger in the frame */ | ||
33 | __u16 firstx, firsty; /* (x, y) of the first finger in the frame */ | ||
34 | }; | ||
35 | |||
36 | static int cando_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
37 | struct hid_field *field, struct hid_usage *usage, | ||
38 | unsigned long **bit, int *max) | ||
39 | { | ||
40 | switch (usage->hid & HID_USAGE_PAGE) { | ||
41 | |||
42 | case HID_UP_GENDESK: | ||
43 | switch (usage->hid) { | ||
44 | case HID_GD_X: | ||
45 | hid_map_usage(hi, usage, bit, max, | ||
46 | EV_ABS, ABS_MT_POSITION_X); | ||
47 | /* touchscreen emulation */ | ||
48 | input_set_abs_params(hi->input, ABS_X, | ||
49 | field->logical_minimum, | ||
50 | field->logical_maximum, 0, 0); | ||
51 | return 1; | ||
52 | case HID_GD_Y: | ||
53 | hid_map_usage(hi, usage, bit, max, | ||
54 | EV_ABS, ABS_MT_POSITION_Y); | ||
55 | /* touchscreen emulation */ | ||
56 | input_set_abs_params(hi->input, ABS_Y, | ||
57 | field->logical_minimum, | ||
58 | field->logical_maximum, 0, 0); | ||
59 | return 1; | ||
60 | } | ||
61 | return 0; | ||
62 | |||
63 | case HID_UP_DIGITIZER: | ||
64 | switch (usage->hid) { | ||
65 | case HID_DG_TIPSWITCH: | ||
66 | case HID_DG_CONTACTMAX: | ||
67 | return -1; | ||
68 | case HID_DG_INRANGE: | ||
69 | /* touchscreen emulation */ | ||
70 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
71 | return 1; | ||
72 | case HID_DG_CONTACTID: | ||
73 | hid_map_usage(hi, usage, bit, max, | ||
74 | EV_ABS, ABS_MT_TRACKING_ID); | ||
75 | return 1; | ||
76 | } | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int cando_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
84 | struct hid_field *field, struct hid_usage *usage, | ||
85 | unsigned long **bit, int *max) | ||
86 | { | ||
87 | if (usage->type == EV_KEY || usage->type == EV_ABS) | ||
88 | clear_bit(usage->code, *bit); | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * this function is called when a whole finger has been parsed, | ||
95 | * so that it can decide what to send to the input layer. | ||
96 | */ | ||
97 | static void cando_filter_event(struct cando_data *td, struct input_dev *input) | ||
98 | { | ||
99 | td->first = !td->first; /* touchscreen emulation */ | ||
100 | |||
101 | if (!td->valid) { | ||
102 | /* | ||
103 | * touchscreen emulation: if this is the second finger and | ||
104 | * the first was valid, the first was the oldest; if the | ||
105 | * first was not valid and there was a valid finger in the | ||
106 | * previous frame, this is a release. | ||
107 | */ | ||
108 | if (td->first) { | ||
109 | td->firstid = -1; | ||
110 | } else if (td->firstid >= 0) { | ||
111 | input_event(input, EV_ABS, ABS_X, td->firstx); | ||
112 | input_event(input, EV_ABS, ABS_Y, td->firsty); | ||
113 | td->oldest = td->firstid; | ||
114 | } else if (td->oldest >= 0) { | ||
115 | input_event(input, EV_KEY, BTN_TOUCH, 0); | ||
116 | td->oldest = -1; | ||
117 | } | ||
118 | |||
119 | return; | ||
120 | } | ||
121 | |||
122 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); | ||
123 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); | ||
124 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); | ||
125 | |||
126 | input_mt_sync(input); | ||
127 | |||
128 | /* | ||
129 | * touchscreen emulation: if there was no touching finger previously, | ||
130 | * emit touch event | ||
131 | */ | ||
132 | if (td->oldest < 0) { | ||
133 | input_event(input, EV_KEY, BTN_TOUCH, 1); | ||
134 | td->oldest = td->id; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * touchscreen emulation: if this is the first finger, wait for the | ||
139 | * second; the oldest is then the second if it was the oldest already | ||
140 | * or if there was no first, the first otherwise. | ||
141 | */ | ||
142 | if (td->first) { | ||
143 | td->firstx = td->x; | ||
144 | td->firsty = td->y; | ||
145 | td->firstid = td->id; | ||
146 | } else { | ||
147 | int x, y, oldest; | ||
148 | if (td->id == td->oldest || td->firstid < 0) { | ||
149 | x = td->x; | ||
150 | y = td->y; | ||
151 | oldest = td->id; | ||
152 | } else { | ||
153 | x = td->firstx; | ||
154 | y = td->firsty; | ||
155 | oldest = td->firstid; | ||
156 | } | ||
157 | input_event(input, EV_ABS, ABS_X, x); | ||
158 | input_event(input, EV_ABS, ABS_Y, y); | ||
159 | td->oldest = oldest; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | |||
164 | static int cando_event(struct hid_device *hid, struct hid_field *field, | ||
165 | struct hid_usage *usage, __s32 value) | ||
166 | { | ||
167 | struct cando_data *td = hid_get_drvdata(hid); | ||
168 | |||
169 | if (hid->claimed & HID_CLAIMED_INPUT) { | ||
170 | struct input_dev *input = field->hidinput->input; | ||
171 | |||
172 | switch (usage->hid) { | ||
173 | case HID_DG_INRANGE: | ||
174 | td->valid = value; | ||
175 | break; | ||
176 | case HID_DG_CONTACTID: | ||
177 | td->id = value; | ||
178 | break; | ||
179 | case HID_GD_X: | ||
180 | td->x = value; | ||
181 | break; | ||
182 | case HID_GD_Y: | ||
183 | td->y = value; | ||
184 | cando_filter_event(td, input); | ||
185 | break; | ||
186 | case HID_DG_TIPSWITCH: | ||
187 | /* avoid interference from generic hidinput handling */ | ||
188 | break; | ||
189 | |||
190 | default: | ||
191 | /* fallback to the generic hidinput handling */ | ||
192 | return 0; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | /* we have handled the hidinput part, now remains hiddev */ | ||
197 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | ||
198 | hid->hiddev_hid_event(hid, field, usage, value); | ||
199 | |||
200 | return 1; | ||
201 | } | ||
202 | |||
203 | static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
204 | { | ||
205 | int ret; | ||
206 | struct cando_data *td; | ||
207 | |||
208 | td = kmalloc(sizeof(struct cando_data), GFP_KERNEL); | ||
209 | if (!td) { | ||
210 | hid_err(hdev, "cannot allocate Cando Touch data\n"); | ||
211 | return -ENOMEM; | ||
212 | } | ||
213 | hid_set_drvdata(hdev, td); | ||
214 | td->first = false; | ||
215 | td->oldest = -1; | ||
216 | td->valid = false; | ||
217 | |||
218 | ret = hid_parse(hdev); | ||
219 | if (!ret) | ||
220 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
221 | |||
222 | if (ret) | ||
223 | kfree(td); | ||
224 | |||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | static void cando_remove(struct hid_device *hdev) | ||
229 | { | ||
230 | hid_hw_stop(hdev); | ||
231 | kfree(hid_get_drvdata(hdev)); | ||
232 | hid_set_drvdata(hdev, NULL); | ||
233 | } | ||
234 | |||
235 | static const struct hid_device_id cando_devices[] = { | ||
236 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
237 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | ||
238 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
239 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | ||
240 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
241 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | ||
242 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
243 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | ||
244 | { } | ||
245 | }; | ||
246 | MODULE_DEVICE_TABLE(hid, cando_devices); | ||
247 | |||
248 | static const struct hid_usage_id cando_grabbed_usages[] = { | ||
249 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | ||
250 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | ||
251 | }; | ||
252 | |||
253 | static struct hid_driver cando_driver = { | ||
254 | .name = "cando-touch", | ||
255 | .id_table = cando_devices, | ||
256 | .probe = cando_probe, | ||
257 | .remove = cando_remove, | ||
258 | .input_mapping = cando_input_mapping, | ||
259 | .input_mapped = cando_input_mapped, | ||
260 | .usage_table = cando_grabbed_usages, | ||
261 | .event = cando_event, | ||
262 | }; | ||
263 | |||
264 | static int __init cando_init(void) | ||
265 | { | ||
266 | return hid_register_driver(&cando_driver); | ||
267 | } | ||
268 | |||
269 | static void __exit cando_exit(void) | ||
270 | { | ||
271 | hid_unregister_driver(&cando_driver); | ||
272 | } | ||
273 | |||
274 | module_init(cando_init); | ||
275 | module_exit(cando_exit); | ||
276 | |||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 408c4bea4d8d..4140fd271417 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1045,6 +1045,9 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | |||
1045 | 1045 | ||
1046 | rsize = ((report->size - 1) >> 3) + 1; | 1046 | rsize = ((report->size - 1) >> 3) + 1; |
1047 | 1047 | ||
1048 | if (rsize > HID_MAX_BUFFER_SIZE) | ||
1049 | rsize = HID_MAX_BUFFER_SIZE; | ||
1050 | |||
1048 | if (csize < rsize) { | 1051 | if (csize < rsize) { |
1049 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, | 1052 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, |
1050 | csize, rsize); | 1053 | csize, rsize); |
@@ -1290,6 +1293,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1290 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | 1293 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, |
1291 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, | 1294 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, |
1292 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, | 1295 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, |
1296 | { HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, USB_DEVICE_ID_ACTIONSTAR_1011) }, | ||
1293 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, | 1297 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, |
1294 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | 1298 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, |
1295 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | 1299 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, |
@@ -1356,6 +1360,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1356 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, | 1360 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, |
1357 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, | 1361 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, |
1358 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, | 1362 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, |
1363 | { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, | ||
1359 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, | 1364 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, |
1360 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, | 1365 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, |
1361 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, | 1366 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, |
@@ -1369,17 +1374,20 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1369 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, | 1374 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, |
1370 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, | 1375 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, |
1371 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1376 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
1377 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) }, | ||
1372 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, | 1378 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, |
1373 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1379 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1374 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1380 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
1375 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | 1381 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, |
1376 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | 1382 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, |
1383 | { HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, USB_DEVICE_ID_GOODTOUCH_000f) }, | ||
1377 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | 1384 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, |
1378 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, | 1385 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, |
1379 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1386 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
1380 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1387 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
1381 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, | 1388 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, |
1382 | { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, | 1389 | { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, |
1390 | { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) }, | ||
1383 | { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, | 1391 | { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, |
1384 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1392 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
1385 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, | 1393 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, |
@@ -1408,10 +1416,12 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1408 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, | 1416 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, |
1409 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) }, | 1417 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) }, |
1410 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, | 1418 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, |
1419 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) }, | ||
1411 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) }, | 1420 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) }, |
1412 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, | 1421 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, |
1413 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, | 1422 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, |
1414 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, | 1423 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, |
1424 | { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) }, | ||
1415 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, | 1425 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, |
1416 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, | 1426 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, |
1417 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, | 1427 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, |
@@ -1441,6 +1451,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1441 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, | 1451 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, |
1442 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, | 1452 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, |
1443 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1453 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
1454 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, | ||
1444 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1455 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1445 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, | 1456 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, |
1446 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, | 1457 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, |
@@ -1454,6 +1465,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1454 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, | 1465 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, |
1455 | { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, | 1466 | { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, |
1456 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1467 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
1468 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, | ||
1457 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1469 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
1458 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 1470 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
1459 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, | 1471 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, |
@@ -1470,12 +1482,15 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1470 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, | 1482 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, |
1471 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 1483 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
1472 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, | 1484 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, |
1485 | { HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, | ||
1473 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, | 1486 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, |
1474 | { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | 1487 | { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, |
1475 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, | 1488 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, |
1476 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, | 1489 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, |
1477 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, | 1490 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, |
1478 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, | 1491 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, |
1492 | { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, | ||
1493 | { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, | ||
1479 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, | 1494 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, |
1480 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, | 1495 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, |
1481 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, | 1496 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 00a94b535d28..e715c43aa013 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -37,6 +37,9 @@ | |||
37 | 37 | ||
38 | #define USB_VENDOR_ID_ACRUX 0x1a34 | 38 | #define USB_VENDOR_ID_ACRUX 0x1a34 |
39 | 39 | ||
40 | #define USB_VENDOR_ID_ACTIONSTAR 0x2101 | ||
41 | #define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011 | ||
42 | |||
40 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 | 43 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 |
41 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 | 44 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 |
42 | 45 | ||
@@ -182,6 +185,9 @@ | |||
182 | #define USB_VENDOR_ID_CREATIVELABS 0x041e | 185 | #define USB_VENDOR_ID_CREATIVELABS 0x041e |
183 | #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 | 186 | #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 |
184 | 187 | ||
188 | #define USB_VENDOR_ID_CVTOUCH 0x1ff7 | ||
189 | #define USB_DEVICE_ID_CVTOUCH_SCREEN 0x0013 | ||
190 | |||
185 | #define USB_VENDOR_ID_CYGNAL 0x10c4 | 191 | #define USB_VENDOR_ID_CYGNAL 0x10c4 |
186 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a | 192 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a |
187 | 193 | ||
@@ -220,6 +226,7 @@ | |||
220 | #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 | 226 | #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 |
221 | 227 | ||
222 | #define USB_VENDOR_ID_ELO 0x04E7 | 228 | #define USB_VENDOR_ID_ELO 0x04E7 |
229 | #define USB_DEVICE_ID_ELO_TS2515 0x0022 | ||
223 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 | 230 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 |
224 | 231 | ||
225 | #define USB_VENDOR_ID_EMS 0x2006 | 232 | #define USB_VENDOR_ID_EMS 0x2006 |
@@ -255,6 +262,9 @@ | |||
255 | #define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 | 262 | #define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 |
256 | #define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 | 263 | #define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 |
257 | 264 | ||
265 | #define USB_VENDOR_ID_GOODTOUCH 0x1aad | ||
266 | #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f | ||
267 | |||
258 | #define USB_VENDOR_ID_GOTOP 0x08f2 | 268 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
259 | #define USB_DEVICE_ID_SUPER_Q2 0x007f | 269 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
260 | #define USB_DEVICE_ID_GOGOPEN 0x00ce | 270 | #define USB_DEVICE_ID_GOGOPEN 0x00ce |
@@ -334,6 +344,9 @@ | |||
334 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 | 344 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 |
335 | #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 | 345 | #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 |
336 | 346 | ||
347 | #define USB_VENDOR_ID_ILITEK 0x222a | ||
348 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 | ||
349 | |||
337 | #define USB_VENDOR_ID_IMATION 0x0718 | 350 | #define USB_VENDOR_ID_IMATION 0x0718 |
338 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 | 351 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 |
339 | 352 | ||
@@ -398,6 +411,7 @@ | |||
398 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 | 411 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 |
399 | #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 | 412 | #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 |
400 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 | 413 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 |
414 | #define USB_DEVICE_ID_LOGITECH_G27_WHEEL 0xc29b | ||
401 | #define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c | 415 | #define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c |
402 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a | 416 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a |
403 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c | 417 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c |
@@ -411,6 +425,9 @@ | |||
411 | #define USB_DEVICE_ID_DINOVO_MINI 0xc71f | 425 | #define USB_DEVICE_ID_DINOVO_MINI 0xc71f |
412 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 | 426 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 |
413 | 427 | ||
428 | #define USB_VENDOR_ID_LUMIO 0x202e | ||
429 | #define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 | ||
430 | |||
414 | #define USB_VENDOR_ID_MCC 0x09db | 431 | #define USB_VENDOR_ID_MCC 0x09db |
415 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 | 432 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 |
416 | #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a | 433 | #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a |
@@ -488,6 +505,9 @@ | |||
488 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 | 505 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 |
489 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 | 506 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 |
490 | 507 | ||
508 | #define USB_VENDOR_ID_PENMOUNT 0x14e1 | ||
509 | #define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 | ||
510 | |||
491 | #define USB_VENDOR_ID_PETALYNX 0x18b1 | 511 | #define USB_VENDOR_ID_PETALYNX 0x18b1 |
492 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 | 512 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 |
493 | 513 | ||
@@ -531,6 +551,7 @@ | |||
531 | #define USB_VENDOR_ID_SONY 0x054c | 551 | #define USB_VENDOR_ID_SONY 0x054c |
532 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b | 552 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b |
533 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 553 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
554 | #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f | ||
534 | 555 | ||
535 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 | 556 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 |
536 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 | 557 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 |
@@ -551,6 +572,10 @@ | |||
551 | #define USB_VENDOR_ID_SUNPLUS 0x04fc | 572 | #define USB_VENDOR_ID_SUNPLUS 0x04fc |
552 | #define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 | 573 | #define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 |
553 | 574 | ||
575 | #define USB_VENDOR_ID_SYMBOL 0x05e0 | ||
576 | #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 | ||
577 | #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 | ||
578 | |||
554 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f | 579 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f |
555 | 580 | ||
556 | #define USB_VENDOR_ID_TOPSEED 0x0766 | 581 | #define USB_VENDOR_ID_TOPSEED 0x0766 |
@@ -562,6 +587,9 @@ | |||
562 | #define USB_VENDOR_ID_TOPMAX 0x0663 | 587 | #define USB_VENDOR_ID_TOPMAX 0x0663 |
563 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 | 588 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 |
564 | 589 | ||
590 | #define USB_VENDOR_ID_TOUCH_INTL 0x1e5e | ||
591 | #define USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH 0x0313 | ||
592 | |||
565 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd | 593 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd |
566 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 | 594 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 |
567 | 595 | ||
@@ -579,6 +607,10 @@ | |||
579 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 | 607 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 |
580 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 | 608 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 |
581 | 609 | ||
610 | #define USB_VENDOR_ID_UNITEC 0x227d | ||
611 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 | ||
612 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19 | ||
613 | |||
582 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 614 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
583 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | 615 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 |
584 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 | 616 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 33dde8724e02..6559e2e3364e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -44,11 +44,11 @@ static const unsigned char hid_keyboard[256] = { | |||
44 | 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, | 44 | 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, |
45 | 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, | 45 | 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, |
46 | 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, | 46 | 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, |
47 | 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 47 | 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk, |
48 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 48 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, |
49 | unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk, | 49 | unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk, |
50 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 50 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, |
51 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | 51 | unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk, |
52 | 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, | 52 | 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, |
53 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk | 53 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk |
54 | }; | 54 | }; |
@@ -357,6 +357,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
357 | case 0x1: map_key_clear(KEY_POWER); break; | 357 | case 0x1: map_key_clear(KEY_POWER); break; |
358 | case 0x2: map_key_clear(KEY_SLEEP); break; | 358 | case 0x2: map_key_clear(KEY_SLEEP); break; |
359 | case 0x3: map_key_clear(KEY_WAKEUP); break; | 359 | case 0x3: map_key_clear(KEY_WAKEUP); break; |
360 | case 0x4: map_key_clear(KEY_CONTEXT_MENU); break; | ||
361 | case 0x5: map_key_clear(KEY_MENU); break; | ||
362 | case 0x6: map_key_clear(KEY_PROG1); break; | ||
363 | case 0x7: map_key_clear(KEY_HELP); break; | ||
364 | case 0x8: map_key_clear(KEY_EXIT); break; | ||
365 | case 0x9: map_key_clear(KEY_SELECT); break; | ||
366 | case 0xa: map_key_clear(KEY_RIGHT); break; | ||
367 | case 0xb: map_key_clear(KEY_LEFT); break; | ||
368 | case 0xc: map_key_clear(KEY_UP); break; | ||
369 | case 0xd: map_key_clear(KEY_DOWN); break; | ||
370 | case 0xe: map_key_clear(KEY_POWER2); break; | ||
371 | case 0xf: map_key_clear(KEY_RESTART); break; | ||
360 | default: goto unknown; | 372 | default: goto unknown; |
361 | } | 373 | } |
362 | break; | 374 | break; |
@@ -466,16 +478,39 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
466 | } | 478 | } |
467 | break; | 479 | break; |
468 | 480 | ||
469 | case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ | 481 | case HID_UP_CONSUMER: /* USB HUT v1.12, pages 75-84 */ |
470 | switch (usage->hid & HID_USAGE) { | 482 | switch (usage->hid & HID_USAGE) { |
471 | case 0x000: goto ignore; | 483 | case 0x000: goto ignore; |
484 | case 0x030: map_key_clear(KEY_POWER); break; | ||
485 | case 0x031: map_key_clear(KEY_RESTART); break; | ||
486 | case 0x032: map_key_clear(KEY_SLEEP); break; | ||
472 | case 0x034: map_key_clear(KEY_SLEEP); break; | 487 | case 0x034: map_key_clear(KEY_SLEEP); break; |
488 | case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE); break; | ||
473 | case 0x036: map_key_clear(BTN_MISC); break; | 489 | case 0x036: map_key_clear(BTN_MISC); break; |
474 | 490 | ||
475 | case 0x040: map_key_clear(KEY_MENU); break; | 491 | case 0x040: map_key_clear(KEY_MENU); break; /* Menu */ |
476 | case 0x045: map_key_clear(KEY_RADIO); break; | 492 | case 0x041: map_key_clear(KEY_SELECT); break; /* Menu Pick */ |
477 | 493 | case 0x042: map_key_clear(KEY_UP); break; /* Menu Up */ | |
494 | case 0x043: map_key_clear(KEY_DOWN); break; /* Menu Down */ | ||
495 | case 0x044: map_key_clear(KEY_LEFT); break; /* Menu Left */ | ||
496 | case 0x045: map_key_clear(KEY_RIGHT); break; /* Menu Right */ | ||
497 | case 0x046: map_key_clear(KEY_ESC); break; /* Menu Escape */ | ||
498 | case 0x047: map_key_clear(KEY_KPPLUS); break; /* Menu Value Increase */ | ||
499 | case 0x048: map_key_clear(KEY_KPMINUS); break; /* Menu Value Decrease */ | ||
500 | |||
501 | case 0x060: map_key_clear(KEY_INFO); break; /* Data On Screen */ | ||
502 | case 0x061: map_key_clear(KEY_SUBTITLE); break; /* Closed Caption */ | ||
503 | case 0x063: map_key_clear(KEY_VCR); break; /* VCR/TV */ | ||
504 | case 0x065: map_key_clear(KEY_CAMERA); break; /* Snapshot */ | ||
505 | case 0x069: map_key_clear(KEY_RED); break; | ||
506 | case 0x06a: map_key_clear(KEY_GREEN); break; | ||
507 | case 0x06b: map_key_clear(KEY_BLUE); break; | ||
508 | case 0x06c: map_key_clear(KEY_YELLOW); break; | ||
509 | case 0x06d: map_key_clear(KEY_ZOOM); break; | ||
510 | |||
511 | case 0x082: map_key_clear(KEY_VIDEO_NEXT); break; | ||
478 | case 0x083: map_key_clear(KEY_LAST); break; | 512 | case 0x083: map_key_clear(KEY_LAST); break; |
513 | case 0x084: map_key_clear(KEY_ENTER); break; | ||
479 | case 0x088: map_key_clear(KEY_PC); break; | 514 | case 0x088: map_key_clear(KEY_PC); break; |
480 | case 0x089: map_key_clear(KEY_TV); break; | 515 | case 0x089: map_key_clear(KEY_TV); break; |
481 | case 0x08a: map_key_clear(KEY_WWW); break; | 516 | case 0x08a: map_key_clear(KEY_WWW); break; |
@@ -509,6 +544,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
509 | case 0x0b7: map_key_clear(KEY_STOPCD); break; | 544 | case 0x0b7: map_key_clear(KEY_STOPCD); break; |
510 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; | 545 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; |
511 | case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; | 546 | case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; |
547 | case 0x0b9: map_key_clear(KEY_SHUFFLE); break; | ||
548 | case 0x0bf: map_key_clear(KEY_SLOW); break; | ||
512 | 549 | ||
513 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; | 550 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; |
514 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; | 551 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; |
@@ -516,6 +553,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
516 | case 0x0e5: map_key_clear(KEY_BASSBOOST); break; | 553 | case 0x0e5: map_key_clear(KEY_BASSBOOST); break; |
517 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; | 554 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; |
518 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; | 555 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; |
556 | case 0x0f5: map_key_clear(KEY_SLOW); break; | ||
519 | 557 | ||
520 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; | 558 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; |
521 | case 0x183: map_key_clear(KEY_CONFIG); break; | 559 | case 0x183: map_key_clear(KEY_CONFIG); break; |
@@ -532,6 +570,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
532 | case 0x18e: map_key_clear(KEY_CALENDAR); break; | 570 | case 0x18e: map_key_clear(KEY_CALENDAR); break; |
533 | case 0x191: map_key_clear(KEY_FINANCE); break; | 571 | case 0x191: map_key_clear(KEY_FINANCE); break; |
534 | case 0x192: map_key_clear(KEY_CALC); break; | 572 | case 0x192: map_key_clear(KEY_CALC); break; |
573 | case 0x193: map_key_clear(KEY_PLAYER); break; | ||
535 | case 0x194: map_key_clear(KEY_FILE); break; | 574 | case 0x194: map_key_clear(KEY_FILE); break; |
536 | case 0x196: map_key_clear(KEY_WWW); break; | 575 | case 0x196: map_key_clear(KEY_WWW); break; |
537 | case 0x199: map_key_clear(KEY_CHAT); break; | 576 | case 0x199: map_key_clear(KEY_CHAT); break; |
@@ -540,8 +579,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
540 | case 0x1a6: map_key_clear(KEY_HELP); break; | 579 | case 0x1a6: map_key_clear(KEY_HELP); break; |
541 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; | 580 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; |
542 | case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; | 581 | case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; |
543 | case 0x1b6: map_key_clear(KEY_MEDIA); break; | 582 | case 0x1ae: map_key_clear(KEY_KEYBOARD); break; |
544 | case 0x1b7: map_key_clear(KEY_SOUND); break; | 583 | case 0x1b6: map_key_clear(KEY_IMAGES); break; |
584 | case 0x1b7: map_key_clear(KEY_AUDIO); break; | ||
585 | case 0x1b8: map_key_clear(KEY_VIDEO); break; | ||
545 | case 0x1bc: map_key_clear(KEY_MESSENGER); break; | 586 | case 0x1bc: map_key_clear(KEY_MESSENGER); break; |
546 | case 0x1bd: map_key_clear(KEY_INFO); break; | 587 | case 0x1bd: map_key_clear(KEY_INFO); break; |
547 | case 0x201: map_key_clear(KEY_NEW); break; | 588 | case 0x201: map_key_clear(KEY_NEW); break; |
@@ -570,7 +611,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
570 | case 0x233: map_key_clear(KEY_SCROLLUP); break; | 611 | case 0x233: map_key_clear(KEY_SCROLLUP); break; |
571 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; | 612 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; |
572 | case 0x238: map_rel(REL_HWHEEL); break; | 613 | case 0x238: map_rel(REL_HWHEEL); break; |
614 | case 0x23d: map_key_clear(KEY_EDIT); break; | ||
573 | case 0x25f: map_key_clear(KEY_CANCEL); break; | 615 | case 0x25f: map_key_clear(KEY_CANCEL); break; |
616 | case 0x269: map_key_clear(KEY_INSERT); break; | ||
617 | case 0x26a: map_key_clear(KEY_DELETE); break; | ||
574 | case 0x279: map_key_clear(KEY_REDO); break; | 618 | case 0x279: map_key_clear(KEY_REDO); break; |
575 | 619 | ||
576 | case 0x289: map_key_clear(KEY_REPLY); break; | 620 | case 0x289: map_key_clear(KEY_REPLY); break; |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 3da90402ee81..21f205f09250 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
@@ -377,6 +377,8 @@ static const struct hid_device_id lg_devices[] = { | |||
377 | .driver_data = LG_FF }, | 377 | .driver_data = LG_FF }, |
378 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), | 378 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), |
379 | .driver_data = LG_FF }, | 379 | .driver_data = LG_FF }, |
380 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL), | ||
381 | .driver_data = LG_FF }, | ||
380 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), | 382 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), |
381 | .driver_data = LG_FF }, | 383 | .driver_data = LG_FF }, |
382 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), | 384 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), |
diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c index f099079ca6b9..088f85049290 100644 --- a/drivers/hid/hid-lgff.c +++ b/drivers/hid/hid-lgff.c | |||
@@ -72,6 +72,9 @@ static const struct dev_type devices[] = { | |||
72 | { 0x046d, 0xc287, ff_joystick_ac }, | 72 | { 0x046d, 0xc287, ff_joystick_ac }, |
73 | { 0x046d, 0xc293, ff_joystick }, | 73 | { 0x046d, 0xc293, ff_joystick }, |
74 | { 0x046d, 0xc294, ff_wheel }, | 74 | { 0x046d, 0xc294, ff_wheel }, |
75 | { 0x046d, 0xc298, ff_wheel }, | ||
76 | { 0x046d, 0xc299, ff_wheel }, | ||
77 | { 0x046d, 0xc29b, ff_wheel }, | ||
75 | { 0x046d, 0xc295, ff_joystick }, | 78 | { 0x046d, 0xc295, ff_joystick }, |
76 | { 0x046d, 0xc298, ff_wheel }, | 79 | { 0x046d, 0xc298, ff_wheel }, |
77 | { 0x046d, 0xc299, ff_wheel }, | 80 | { 0x046d, 0xc299, ff_wheel }, |
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 0ec91c18a421..a5eda4c8127a 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c | |||
@@ -501,9 +501,17 @@ static int magicmouse_probe(struct hid_device *hdev, | |||
501 | } | 501 | } |
502 | report->size = 6; | 502 | report->size = 6; |
503 | 503 | ||
504 | /* | ||
505 | * The device reponds with 'invalid report id' when feature | ||
506 | * report switching it into multitouch mode is sent to it. | ||
507 | * | ||
508 | * This results in -EIO from the _raw low-level transport callback, | ||
509 | * but there seems to be no other way of switching the mode. | ||
510 | * Thus the super-ugly hacky success check below. | ||
511 | */ | ||
504 | ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), | 512 | ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), |
505 | HID_FEATURE_REPORT); | 513 | HID_FEATURE_REPORT); |
506 | if (ret != sizeof(feature)) { | 514 | if (ret != -EIO) { |
507 | hid_err(hdev, "unable to request touch data (%d)\n", ret); | 515 | hid_err(hdev, "unable to request touch data (%d)\n", ret); |
508 | goto err_stop_hw; | 516 | goto err_stop_hw; |
509 | } | 517 | } |
diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c deleted file mode 100644 index aed7ffe36283..000000000000 --- a/drivers/hid/hid-mosart.c +++ /dev/null | |||
@@ -1,296 +0,0 @@ | |||
1 | /* | ||
2 | * HID driver for the multitouch panel on the ASUS EeePC T91MT | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> | ||
5 | * Copyright (c) 2010 Teemu Tuominen <teemu.tuominen@cybercom.com> | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation; either version 2 of the License, or (at your option) | ||
13 | * any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/device.h> | ||
17 | #include <linux/hid.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/usb.h> | ||
21 | #include "usbhid/usbhid.h" | ||
22 | |||
23 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | ||
24 | MODULE_DESCRIPTION("MosArt dual-touch panel"); | ||
25 | MODULE_LICENSE("GPL"); | ||
26 | |||
27 | #include "hid-ids.h" | ||
28 | |||
29 | struct mosart_data { | ||
30 | __u16 x, y; | ||
31 | __u8 id; | ||
32 | bool valid; /* valid finger data, or just placeholder? */ | ||
33 | bool first; /* is this the first finger in this frame? */ | ||
34 | bool activity_now; /* at least one active finger in this frame? */ | ||
35 | bool activity; /* at least one active finger previously? */ | ||
36 | }; | ||
37 | |||
38 | static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
39 | struct hid_field *field, struct hid_usage *usage, | ||
40 | unsigned long **bit, int *max) | ||
41 | { | ||
42 | switch (usage->hid & HID_USAGE_PAGE) { | ||
43 | |||
44 | case HID_UP_GENDESK: | ||
45 | switch (usage->hid) { | ||
46 | case HID_GD_X: | ||
47 | hid_map_usage(hi, usage, bit, max, | ||
48 | EV_ABS, ABS_MT_POSITION_X); | ||
49 | /* touchscreen emulation */ | ||
50 | input_set_abs_params(hi->input, ABS_X, | ||
51 | field->logical_minimum, | ||
52 | field->logical_maximum, 0, 0); | ||
53 | return 1; | ||
54 | case HID_GD_Y: | ||
55 | hid_map_usage(hi, usage, bit, max, | ||
56 | EV_ABS, ABS_MT_POSITION_Y); | ||
57 | /* touchscreen emulation */ | ||
58 | input_set_abs_params(hi->input, ABS_Y, | ||
59 | field->logical_minimum, | ||
60 | field->logical_maximum, 0, 0); | ||
61 | return 1; | ||
62 | } | ||
63 | return 0; | ||
64 | |||
65 | case HID_UP_DIGITIZER: | ||
66 | switch (usage->hid) { | ||
67 | case HID_DG_CONFIDENCE: | ||
68 | case HID_DG_TIPSWITCH: | ||
69 | case HID_DG_INPUTMODE: | ||
70 | case HID_DG_DEVICEINDEX: | ||
71 | case HID_DG_CONTACTCOUNT: | ||
72 | case HID_DG_CONTACTMAX: | ||
73 | case HID_DG_TIPPRESSURE: | ||
74 | case HID_DG_WIDTH: | ||
75 | case HID_DG_HEIGHT: | ||
76 | return -1; | ||
77 | case HID_DG_INRANGE: | ||
78 | /* touchscreen emulation */ | ||
79 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
80 | return 1; | ||
81 | |||
82 | case HID_DG_CONTACTID: | ||
83 | hid_map_usage(hi, usage, bit, max, | ||
84 | EV_ABS, ABS_MT_TRACKING_ID); | ||
85 | return 1; | ||
86 | |||
87 | } | ||
88 | return 0; | ||
89 | |||
90 | case 0xff000000: | ||
91 | /* ignore HID features */ | ||
92 | return -1; | ||
93 | |||
94 | case HID_UP_BUTTON: | ||
95 | /* ignore buttons */ | ||
96 | return -1; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int mosart_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
103 | struct hid_field *field, struct hid_usage *usage, | ||
104 | unsigned long **bit, int *max) | ||
105 | { | ||
106 | if (usage->type == EV_KEY || usage->type == EV_ABS) | ||
107 | clear_bit(usage->code, *bit); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * this function is called when a whole finger has been parsed, | ||
114 | * so that it can decide what to send to the input layer. | ||
115 | */ | ||
116 | static void mosart_filter_event(struct mosart_data *td, struct input_dev *input) | ||
117 | { | ||
118 | td->first = !td->first; /* touchscreen emulation */ | ||
119 | |||
120 | if (!td->valid) { | ||
121 | /* | ||
122 | * touchscreen emulation: if no finger in this frame is valid | ||
123 | * and there previously was finger activity, this is a release | ||
124 | */ | ||
125 | if (!td->first && !td->activity_now && td->activity) { | ||
126 | input_event(input, EV_KEY, BTN_TOUCH, 0); | ||
127 | td->activity = false; | ||
128 | } | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); | ||
133 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); | ||
134 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); | ||
135 | |||
136 | input_mt_sync(input); | ||
137 | td->valid = false; | ||
138 | |||
139 | /* touchscreen emulation: if first active finger in this frame... */ | ||
140 | if (!td->activity_now) { | ||
141 | /* if there was no previous activity, emit touch event */ | ||
142 | if (!td->activity) { | ||
143 | input_event(input, EV_KEY, BTN_TOUCH, 1); | ||
144 | td->activity = true; | ||
145 | } | ||
146 | td->activity_now = true; | ||
147 | /* and in any case this is our preferred finger */ | ||
148 | input_event(input, EV_ABS, ABS_X, td->x); | ||
149 | input_event(input, EV_ABS, ABS_Y, td->y); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | |||
154 | static int mosart_event(struct hid_device *hid, struct hid_field *field, | ||
155 | struct hid_usage *usage, __s32 value) | ||
156 | { | ||
157 | struct mosart_data *td = hid_get_drvdata(hid); | ||
158 | |||
159 | if (hid->claimed & HID_CLAIMED_INPUT) { | ||
160 | struct input_dev *input = field->hidinput->input; | ||
161 | switch (usage->hid) { | ||
162 | case HID_DG_INRANGE: | ||
163 | td->valid = !!value; | ||
164 | break; | ||
165 | case HID_GD_X: | ||
166 | td->x = value; | ||
167 | break; | ||
168 | case HID_GD_Y: | ||
169 | td->y = value; | ||
170 | mosart_filter_event(td, input); | ||
171 | break; | ||
172 | case HID_DG_CONTACTID: | ||
173 | td->id = value; | ||
174 | break; | ||
175 | case HID_DG_CONTACTCOUNT: | ||
176 | /* touch emulation: this is the last field in a frame */ | ||
177 | td->first = false; | ||
178 | td->activity_now = false; | ||
179 | break; | ||
180 | case HID_DG_CONFIDENCE: | ||
181 | case HID_DG_TIPSWITCH: | ||
182 | /* avoid interference from generic hidinput handling */ | ||
183 | break; | ||
184 | |||
185 | default: | ||
186 | /* fallback to the generic hidinput handling */ | ||
187 | return 0; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | /* we have handled the hidinput part, now remains hiddev */ | ||
192 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | ||
193 | hid->hiddev_hid_event(hid, field, usage, value); | ||
194 | |||
195 | return 1; | ||
196 | } | ||
197 | |||
198 | static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
199 | { | ||
200 | int ret; | ||
201 | struct mosart_data *td; | ||
202 | |||
203 | |||
204 | td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL); | ||
205 | if (!td) { | ||
206 | hid_err(hdev, "cannot allocate MosArt data\n"); | ||
207 | return -ENOMEM; | ||
208 | } | ||
209 | td->valid = false; | ||
210 | td->activity = false; | ||
211 | td->activity_now = false; | ||
212 | td->first = false; | ||
213 | hid_set_drvdata(hdev, td); | ||
214 | |||
215 | /* currently, it's better to have one evdev device only */ | ||
216 | #if 0 | ||
217 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | ||
218 | #endif | ||
219 | |||
220 | ret = hid_parse(hdev); | ||
221 | if (ret == 0) | ||
222 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
223 | |||
224 | if (ret == 0) { | ||
225 | struct hid_report_enum *re = hdev->report_enum | ||
226 | + HID_FEATURE_REPORT; | ||
227 | struct hid_report *r = re->report_id_hash[7]; | ||
228 | |||
229 | r->field[0]->value[0] = 0x02; | ||
230 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | ||
231 | } else | ||
232 | kfree(td); | ||
233 | |||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | #ifdef CONFIG_PM | ||
238 | static int mosart_reset_resume(struct hid_device *hdev) | ||
239 | { | ||
240 | struct hid_report_enum *re = hdev->report_enum | ||
241 | + HID_FEATURE_REPORT; | ||
242 | struct hid_report *r = re->report_id_hash[7]; | ||
243 | |||
244 | r->field[0]->value[0] = 0x02; | ||
245 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | ||
246 | return 0; | ||
247 | } | ||
248 | #endif | ||
249 | |||
250 | static void mosart_remove(struct hid_device *hdev) | ||
251 | { | ||
252 | hid_hw_stop(hdev); | ||
253 | kfree(hid_get_drvdata(hdev)); | ||
254 | hid_set_drvdata(hdev, NULL); | ||
255 | } | ||
256 | |||
257 | static const struct hid_device_id mosart_devices[] = { | ||
258 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | ||
259 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
260 | { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | ||
261 | { } | ||
262 | }; | ||
263 | MODULE_DEVICE_TABLE(hid, mosart_devices); | ||
264 | |||
265 | static const struct hid_usage_id mosart_grabbed_usages[] = { | ||
266 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | ||
267 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | ||
268 | }; | ||
269 | |||
270 | static struct hid_driver mosart_driver = { | ||
271 | .name = "mosart", | ||
272 | .id_table = mosart_devices, | ||
273 | .probe = mosart_probe, | ||
274 | .remove = mosart_remove, | ||
275 | .input_mapping = mosart_input_mapping, | ||
276 | .input_mapped = mosart_input_mapped, | ||
277 | .usage_table = mosart_grabbed_usages, | ||
278 | .event = mosart_event, | ||
279 | #ifdef CONFIG_PM | ||
280 | .reset_resume = mosart_reset_resume, | ||
281 | #endif | ||
282 | }; | ||
283 | |||
284 | static int __init mosart_init(void) | ||
285 | { | ||
286 | return hid_register_driver(&mosart_driver); | ||
287 | } | ||
288 | |||
289 | static void __exit mosart_exit(void) | ||
290 | { | ||
291 | hid_unregister_driver(&mosart_driver); | ||
292 | } | ||
293 | |||
294 | module_init(mosart_init); | ||
295 | module_exit(mosart_exit); | ||
296 | |||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ee01e65e22d6..ecd4d2db9e80 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -11,6 +11,12 @@ | |||
11 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | 11 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> |
12 | * Copyright (c) 2010 Canonical, Ltd. | 12 | * Copyright (c) 2010 Canonical, Ltd. |
13 | * | 13 | * |
14 | * This code is partly based on hid-3m-pct.c: | ||
15 | * | ||
16 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> | ||
17 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | ||
18 | * Copyright (c) 2010 Canonical, Ltd. | ||
19 | * | ||
14 | */ | 20 | */ |
15 | 21 | ||
16 | /* | 22 | /* |
@@ -44,6 +50,7 @@ MODULE_LICENSE("GPL"); | |||
44 | #define MT_QUIRK_VALID_IS_INRANGE (1 << 4) | 50 | #define MT_QUIRK_VALID_IS_INRANGE (1 << 4) |
45 | #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) | 51 | #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) |
46 | #define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6) | 52 | #define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6) |
53 | #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 7) | ||
47 | 54 | ||
48 | struct mt_slot { | 55 | struct mt_slot { |
49 | __s32 x, y, p, w, h; | 56 | __s32 x, y, p, w, h; |
@@ -60,24 +67,36 @@ struct mt_device { | |||
60 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 67 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
61 | __u8 num_received; /* how many contacts we received */ | 68 | __u8 num_received; /* how many contacts we received */ |
62 | __u8 num_expected; /* expected last contact index */ | 69 | __u8 num_expected; /* expected last contact index */ |
70 | __u8 maxcontacts; | ||
63 | bool curvalid; /* is the current contact valid? */ | 71 | bool curvalid; /* is the current contact valid? */ |
64 | struct mt_slot slots[0]; /* first slot */ | 72 | struct mt_slot *slots; |
65 | }; | 73 | }; |
66 | 74 | ||
67 | struct mt_class { | 75 | struct mt_class { |
68 | __s32 name; /* MT_CLS */ | 76 | __s32 name; /* MT_CLS */ |
69 | __s32 quirks; | 77 | __s32 quirks; |
70 | __s32 sn_move; /* Signal/noise ratio for move events */ | 78 | __s32 sn_move; /* Signal/noise ratio for move events */ |
79 | __s32 sn_width; /* Signal/noise ratio for width events */ | ||
80 | __s32 sn_height; /* Signal/noise ratio for height events */ | ||
71 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ | 81 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ |
72 | __u8 maxcontacts; | 82 | __u8 maxcontacts; |
73 | }; | 83 | }; |
74 | 84 | ||
75 | /* classes of device behavior */ | 85 | /* classes of device behavior */ |
76 | #define MT_CLS_DEFAULT 1 | 86 | #define MT_CLS_DEFAULT 0x0001 |
77 | #define MT_CLS_DUAL_INRANGE_CONTACTID 2 | 87 | |
78 | #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3 | 88 | #define MT_CLS_CONFIDENCE 0x0002 |
79 | #define MT_CLS_CYPRESS 4 | 89 | #define MT_CLS_CONFIDENCE_MINUS_ONE 0x0003 |
80 | #define MT_CLS_EGALAX 5 | 90 | #define MT_CLS_DUAL_INRANGE_CONTACTID 0x0004 |
91 | #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0005 | ||
92 | #define MT_CLS_DUAL_NSMU_CONTACTID 0x0006 | ||
93 | |||
94 | /* vendor specific classes */ | ||
95 | #define MT_CLS_3M 0x0101 | ||
96 | #define MT_CLS_CYPRESS 0x0102 | ||
97 | #define MT_CLS_EGALAX 0x0103 | ||
98 | |||
99 | #define MT_DEFAULT_MAXCONTACT 10 | ||
81 | 100 | ||
82 | /* | 101 | /* |
83 | * these device-dependent functions determine what slot corresponds | 102 | * these device-dependent functions determine what slot corresponds |
@@ -95,12 +114,12 @@ static int cypress_compute_slot(struct mt_device *td) | |||
95 | static int find_slot_from_contactid(struct mt_device *td) | 114 | static int find_slot_from_contactid(struct mt_device *td) |
96 | { | 115 | { |
97 | int i; | 116 | int i; |
98 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | 117 | for (i = 0; i < td->maxcontacts; ++i) { |
99 | if (td->slots[i].contactid == td->curdata.contactid && | 118 | if (td->slots[i].contactid == td->curdata.contactid && |
100 | td->slots[i].touch_state) | 119 | td->slots[i].touch_state) |
101 | return i; | 120 | return i; |
102 | } | 121 | } |
103 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | 122 | for (i = 0; i < td->maxcontacts; ++i) { |
104 | if (!td->slots[i].seen_in_this_frame && | 123 | if (!td->slots[i].seen_in_this_frame && |
105 | !td->slots[i].touch_state) | 124 | !td->slots[i].touch_state) |
106 | return i; | 125 | return i; |
@@ -113,8 +132,12 @@ static int find_slot_from_contactid(struct mt_device *td) | |||
113 | 132 | ||
114 | struct mt_class mt_classes[] = { | 133 | struct mt_class mt_classes[] = { |
115 | { .name = MT_CLS_DEFAULT, | 134 | { .name = MT_CLS_DEFAULT, |
116 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, | 135 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, |
117 | .maxcontacts = 10 }, | 136 | { .name = MT_CLS_CONFIDENCE, |
137 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, | ||
138 | { .name = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
139 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | | ||
140 | MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, | ||
118 | { .name = MT_CLS_DUAL_INRANGE_CONTACTID, | 141 | { .name = MT_CLS_DUAL_INRANGE_CONTACTID, |
119 | .quirks = MT_QUIRK_VALID_IS_INRANGE | | 142 | .quirks = MT_QUIRK_VALID_IS_INRANGE | |
120 | MT_QUIRK_SLOT_IS_CONTACTID, | 143 | MT_QUIRK_SLOT_IS_CONTACTID, |
@@ -123,11 +146,24 @@ struct mt_class mt_classes[] = { | |||
123 | .quirks = MT_QUIRK_VALID_IS_INRANGE | | 146 | .quirks = MT_QUIRK_VALID_IS_INRANGE | |
124 | MT_QUIRK_SLOT_IS_CONTACTNUMBER, | 147 | MT_QUIRK_SLOT_IS_CONTACTNUMBER, |
125 | .maxcontacts = 2 }, | 148 | .maxcontacts = 2 }, |
149 | { .name = MT_CLS_DUAL_NSMU_CONTACTID, | ||
150 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | | ||
151 | MT_QUIRK_SLOT_IS_CONTACTID, | ||
152 | .maxcontacts = 2 }, | ||
153 | |||
154 | /* | ||
155 | * vendor specific classes | ||
156 | */ | ||
157 | { .name = MT_CLS_3M, | ||
158 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | | ||
159 | MT_QUIRK_SLOT_IS_CONTACTID, | ||
160 | .sn_move = 2048, | ||
161 | .sn_width = 128, | ||
162 | .sn_height = 128 }, | ||
126 | { .name = MT_CLS_CYPRESS, | 163 | { .name = MT_CLS_CYPRESS, |
127 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | | 164 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | |
128 | MT_QUIRK_CYPRESS, | 165 | MT_QUIRK_CYPRESS, |
129 | .maxcontacts = 10 }, | 166 | .maxcontacts = 10 }, |
130 | |||
131 | { .name = MT_CLS_EGALAX, | 167 | { .name = MT_CLS_EGALAX, |
132 | .quirks = MT_QUIRK_SLOT_IS_CONTACTID | | 168 | .quirks = MT_QUIRK_SLOT_IS_CONTACTID | |
133 | MT_QUIRK_VALID_IS_INRANGE | | 169 | MT_QUIRK_VALID_IS_INRANGE | |
@@ -136,15 +172,26 @@ struct mt_class mt_classes[] = { | |||
136 | .sn_move = 4096, | 172 | .sn_move = 4096, |
137 | .sn_pressure = 32, | 173 | .sn_pressure = 32, |
138 | }, | 174 | }, |
175 | |||
139 | { } | 176 | { } |
140 | }; | 177 | }; |
141 | 178 | ||
142 | static void mt_feature_mapping(struct hid_device *hdev, | 179 | static void mt_feature_mapping(struct hid_device *hdev, |
143 | struct hid_field *field, struct hid_usage *usage) | 180 | struct hid_field *field, struct hid_usage *usage) |
144 | { | 181 | { |
145 | if (usage->hid == HID_DG_INPUTMODE) { | 182 | struct mt_device *td = hid_get_drvdata(hdev); |
146 | struct mt_device *td = hid_get_drvdata(hdev); | 183 | |
184 | switch (usage->hid) { | ||
185 | case HID_DG_INPUTMODE: | ||
147 | td->inputmode = field->report->id; | 186 | td->inputmode = field->report->id; |
187 | break; | ||
188 | case HID_DG_CONTACTMAX: | ||
189 | td->maxcontacts = field->value[0]; | ||
190 | if (td->mtclass->maxcontacts) | ||
191 | /* check if the maxcontacts is given by the class */ | ||
192 | td->maxcontacts = td->mtclass->maxcontacts; | ||
193 | |||
194 | break; | ||
148 | } | 195 | } |
149 | } | 196 | } |
150 | 197 | ||
@@ -179,6 +226,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
179 | /* touchscreen emulation */ | 226 | /* touchscreen emulation */ |
180 | set_abs(hi->input, ABS_X, field, cls->sn_move); | 227 | set_abs(hi->input, ABS_X, field, cls->sn_move); |
181 | td->last_slot_field = usage->hid; | 228 | td->last_slot_field = usage->hid; |
229 | td->last_field_index = field->index; | ||
182 | return 1; | 230 | return 1; |
183 | case HID_GD_Y: | 231 | case HID_GD_Y: |
184 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) | 232 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) |
@@ -190,6 +238,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
190 | /* touchscreen emulation */ | 238 | /* touchscreen emulation */ |
191 | set_abs(hi->input, ABS_Y, field, cls->sn_move); | 239 | set_abs(hi->input, ABS_Y, field, cls->sn_move); |
192 | td->last_slot_field = usage->hid; | 240 | td->last_slot_field = usage->hid; |
241 | td->last_field_index = field->index; | ||
193 | return 1; | 242 | return 1; |
194 | } | 243 | } |
195 | return 0; | 244 | return 0; |
@@ -198,32 +247,40 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
198 | switch (usage->hid) { | 247 | switch (usage->hid) { |
199 | case HID_DG_INRANGE: | 248 | case HID_DG_INRANGE: |
200 | td->last_slot_field = usage->hid; | 249 | td->last_slot_field = usage->hid; |
250 | td->last_field_index = field->index; | ||
201 | return 1; | 251 | return 1; |
202 | case HID_DG_CONFIDENCE: | 252 | case HID_DG_CONFIDENCE: |
203 | td->last_slot_field = usage->hid; | 253 | td->last_slot_field = usage->hid; |
254 | td->last_field_index = field->index; | ||
204 | return 1; | 255 | return 1; |
205 | case HID_DG_TIPSWITCH: | 256 | case HID_DG_TIPSWITCH: |
206 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 257 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
207 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 258 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
208 | td->last_slot_field = usage->hid; | 259 | td->last_slot_field = usage->hid; |
260 | td->last_field_index = field->index; | ||
209 | return 1; | 261 | return 1; |
210 | case HID_DG_CONTACTID: | 262 | case HID_DG_CONTACTID: |
211 | input_mt_init_slots(hi->input, | 263 | input_mt_init_slots(hi->input, td->maxcontacts); |
212 | td->mtclass->maxcontacts); | ||
213 | td->last_slot_field = usage->hid; | 264 | td->last_slot_field = usage->hid; |
265 | td->last_field_index = field->index; | ||
214 | return 1; | 266 | return 1; |
215 | case HID_DG_WIDTH: | 267 | case HID_DG_WIDTH: |
216 | hid_map_usage(hi, usage, bit, max, | 268 | hid_map_usage(hi, usage, bit, max, |
217 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 269 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
270 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | ||
271 | cls->sn_width); | ||
218 | td->last_slot_field = usage->hid; | 272 | td->last_slot_field = usage->hid; |
273 | td->last_field_index = field->index; | ||
219 | return 1; | 274 | return 1; |
220 | case HID_DG_HEIGHT: | 275 | case HID_DG_HEIGHT: |
221 | hid_map_usage(hi, usage, bit, max, | 276 | hid_map_usage(hi, usage, bit, max, |
222 | EV_ABS, ABS_MT_TOUCH_MINOR); | 277 | EV_ABS, ABS_MT_TOUCH_MINOR); |
223 | field->logical_maximum = 1; | 278 | set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, |
224 | field->logical_minimum = 0; | 279 | cls->sn_height); |
225 | set_abs(hi->input, ABS_MT_ORIENTATION, field, 0); | 280 | input_set_abs_params(hi->input, |
281 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | ||
226 | td->last_slot_field = usage->hid; | 282 | td->last_slot_field = usage->hid; |
283 | td->last_field_index = field->index; | ||
227 | return 1; | 284 | return 1; |
228 | case HID_DG_TIPPRESSURE: | 285 | case HID_DG_TIPPRESSURE: |
229 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) | 286 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) |
@@ -236,13 +293,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
236 | set_abs(hi->input, ABS_PRESSURE, field, | 293 | set_abs(hi->input, ABS_PRESSURE, field, |
237 | cls->sn_pressure); | 294 | cls->sn_pressure); |
238 | td->last_slot_field = usage->hid; | 295 | td->last_slot_field = usage->hid; |
296 | td->last_field_index = field->index; | ||
239 | return 1; | 297 | return 1; |
240 | case HID_DG_CONTACTCOUNT: | 298 | case HID_DG_CONTACTCOUNT: |
241 | td->last_field_index = field->report->maxfield - 1; | 299 | td->last_field_index = field->index; |
242 | return 1; | 300 | return 1; |
243 | case HID_DG_CONTACTMAX: | 301 | case HID_DG_CONTACTMAX: |
244 | /* we don't set td->last_slot_field as contactcount and | 302 | /* we don't set td->last_slot_field as contactcount and |
245 | * contact max are global to the report */ | 303 | * contact max are global to the report */ |
304 | td->last_field_index = field->index; | ||
246 | return -1; | 305 | return -1; |
247 | } | 306 | } |
248 | /* let hid-input decide for the others */ | 307 | /* let hid-input decide for the others */ |
@@ -279,6 +338,9 @@ static int mt_compute_slot(struct mt_device *td) | |||
279 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) | 338 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) |
280 | return td->num_received; | 339 | return td->num_received; |
281 | 340 | ||
341 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) | ||
342 | return td->curdata.contactid - 1; | ||
343 | |||
282 | return find_slot_from_contactid(td); | 344 | return find_slot_from_contactid(td); |
283 | } | 345 | } |
284 | 346 | ||
@@ -292,7 +354,7 @@ static void mt_complete_slot(struct mt_device *td) | |||
292 | if (td->curvalid) { | 354 | if (td->curvalid) { |
293 | int slotnum = mt_compute_slot(td); | 355 | int slotnum = mt_compute_slot(td); |
294 | 356 | ||
295 | if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts) | 357 | if (slotnum >= 0 && slotnum < td->maxcontacts) |
296 | td->slots[slotnum] = td->curdata; | 358 | td->slots[slotnum] = td->curdata; |
297 | } | 359 | } |
298 | td->num_received++; | 360 | td->num_received++; |
@@ -307,7 +369,7 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) | |||
307 | { | 369 | { |
308 | int i; | 370 | int i; |
309 | 371 | ||
310 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | 372 | for (i = 0; i < td->maxcontacts; ++i) { |
311 | struct mt_slot *s = &(td->slots[i]); | 373 | struct mt_slot *s = &(td->slots[i]); |
312 | if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && | 374 | if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && |
313 | !s->seen_in_this_frame) { | 375 | !s->seen_in_this_frame) { |
@@ -318,11 +380,18 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) | |||
318 | input_mt_report_slot_state(input, MT_TOOL_FINGER, | 380 | input_mt_report_slot_state(input, MT_TOOL_FINGER, |
319 | s->touch_state); | 381 | s->touch_state); |
320 | if (s->touch_state) { | 382 | if (s->touch_state) { |
383 | /* this finger is on the screen */ | ||
384 | int wide = (s->w > s->h); | ||
385 | /* divided by two to match visual scale of touch */ | ||
386 | int major = max(s->w, s->h) >> 1; | ||
387 | int minor = min(s->w, s->h) >> 1; | ||
388 | |||
321 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); | 389 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); |
322 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); | 390 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); |
391 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | ||
323 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); | 392 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); |
324 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); | 393 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); |
325 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); | 394 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); |
326 | } | 395 | } |
327 | s->seen_in_this_frame = false; | 396 | s->seen_in_this_frame = false; |
328 | 397 | ||
@@ -341,7 +410,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
341 | struct mt_device *td = hid_get_drvdata(hid); | 410 | struct mt_device *td = hid_get_drvdata(hid); |
342 | __s32 quirks = td->mtclass->quirks; | 411 | __s32 quirks = td->mtclass->quirks; |
343 | 412 | ||
344 | if (hid->claimed & HID_CLAIMED_INPUT) { | 413 | if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { |
345 | switch (usage->hid) { | 414 | switch (usage->hid) { |
346 | case HID_DG_INRANGE: | 415 | case HID_DG_INRANGE: |
347 | if (quirks & MT_QUIRK_VALID_IS_INRANGE) | 416 | if (quirks & MT_QUIRK_VALID_IS_INRANGE) |
@@ -390,8 +459,6 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
390 | 459 | ||
391 | if (usage->hid == td->last_slot_field) { | 460 | if (usage->hid == td->last_slot_field) { |
392 | mt_complete_slot(td); | 461 | mt_complete_slot(td); |
393 | if (!td->last_field_index) | ||
394 | mt_emit_event(td, field->hidinput->input); | ||
395 | } | 462 | } |
396 | 463 | ||
397 | if (field->index == td->last_field_index | 464 | if (field->index == td->last_field_index |
@@ -442,9 +509,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
442 | */ | 509 | */ |
443 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | 510 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
444 | 511 | ||
445 | td = kzalloc(sizeof(struct mt_device) + | 512 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); |
446 | mtclass->maxcontacts * sizeof(struct mt_slot), | ||
447 | GFP_KERNEL); | ||
448 | if (!td) { | 513 | if (!td) { |
449 | dev_err(&hdev->dev, "cannot allocate multitouch data\n"); | 514 | dev_err(&hdev->dev, "cannot allocate multitouch data\n"); |
450 | return -ENOMEM; | 515 | return -ENOMEM; |
@@ -461,6 +526,18 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
461 | if (ret) | 526 | if (ret) |
462 | goto fail; | 527 | goto fail; |
463 | 528 | ||
529 | if (!td->maxcontacts) | ||
530 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | ||
531 | |||
532 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), | ||
533 | GFP_KERNEL); | ||
534 | if (!td->slots) { | ||
535 | dev_err(&hdev->dev, "cannot allocate multitouch slots\n"); | ||
536 | hid_hw_stop(hdev); | ||
537 | ret = -ENOMEM; | ||
538 | goto fail; | ||
539 | } | ||
540 | |||
464 | mt_set_input_mode(hdev); | 541 | mt_set_input_mode(hdev); |
465 | 542 | ||
466 | return 0; | 543 | return 0; |
@@ -482,27 +559,115 @@ static void mt_remove(struct hid_device *hdev) | |||
482 | { | 559 | { |
483 | struct mt_device *td = hid_get_drvdata(hdev); | 560 | struct mt_device *td = hid_get_drvdata(hdev); |
484 | hid_hw_stop(hdev); | 561 | hid_hw_stop(hdev); |
562 | kfree(td->slots); | ||
485 | kfree(td); | 563 | kfree(td); |
486 | hid_set_drvdata(hdev, NULL); | 564 | hid_set_drvdata(hdev, NULL); |
487 | } | 565 | } |
488 | 566 | ||
489 | static const struct hid_device_id mt_devices[] = { | 567 | static const struct hid_device_id mt_devices[] = { |
490 | 568 | ||
569 | /* 3M panels */ | ||
570 | { .driver_data = MT_CLS_3M, | ||
571 | HID_USB_DEVICE(USB_VENDOR_ID_3M, | ||
572 | USB_DEVICE_ID_3M1968) }, | ||
573 | { .driver_data = MT_CLS_3M, | ||
574 | HID_USB_DEVICE(USB_VENDOR_ID_3M, | ||
575 | USB_DEVICE_ID_3M2256) }, | ||
576 | |||
577 | /* ActionStar panels */ | ||
578 | { .driver_data = MT_CLS_DEFAULT, | ||
579 | HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, | ||
580 | USB_DEVICE_ID_ACTIONSTAR_1011) }, | ||
581 | |||
582 | /* Cando panels */ | ||
583 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
584 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
585 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | ||
586 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
587 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
588 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | ||
589 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
590 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
591 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | ||
592 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
593 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
594 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | ||
595 | |||
596 | /* CVTouch panels */ | ||
597 | { .driver_data = MT_CLS_DEFAULT, | ||
598 | HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, | ||
599 | USB_DEVICE_ID_CVTOUCH_SCREEN) }, | ||
600 | |||
491 | /* Cypress panel */ | 601 | /* Cypress panel */ |
492 | { .driver_data = MT_CLS_CYPRESS, | 602 | { .driver_data = MT_CLS_CYPRESS, |
493 | HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, | 603 | HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, |
494 | USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, | 604 | USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, |
495 | 605 | ||
606 | /* eGalax devices (resistive) */ | ||
607 | { .driver_data = MT_CLS_EGALAX, | ||
608 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
609 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | ||
610 | { .driver_data = MT_CLS_EGALAX, | ||
611 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
612 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, | ||
613 | |||
614 | /* eGalax devices (capacitive) */ | ||
615 | { .driver_data = MT_CLS_EGALAX, | ||
616 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
617 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | ||
618 | { .driver_data = MT_CLS_EGALAX, | ||
619 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
620 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, | ||
621 | { .driver_data = MT_CLS_EGALAX, | ||
622 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
623 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, | ||
624 | |||
625 | /* Elo TouchSystems IntelliTouch Plus panel */ | ||
626 | { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, | ||
627 | HID_USB_DEVICE(USB_VENDOR_ID_ELO, | ||
628 | USB_DEVICE_ID_ELO_TS2515) }, | ||
629 | |||
496 | /* GeneralTouch panel */ | 630 | /* GeneralTouch panel */ |
497 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 631 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
498 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, | 632 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, |
499 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | 633 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, |
500 | 634 | ||
635 | /* GoodTouch panels */ | ||
636 | { .driver_data = MT_CLS_DEFAULT, | ||
637 | HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, | ||
638 | USB_DEVICE_ID_GOODTOUCH_000f) }, | ||
639 | |||
640 | /* Ilitek dual touch panel */ | ||
641 | { .driver_data = MT_CLS_DEFAULT, | ||
642 | HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, | ||
643 | USB_DEVICE_ID_ILITEK_MULTITOUCH) }, | ||
644 | |||
501 | /* IRTOUCH panels */ | 645 | /* IRTOUCH panels */ |
502 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 646 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
503 | HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, | 647 | HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, |
504 | USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, | 648 | USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, |
505 | 649 | ||
650 | /* Lumio panels */ | ||
651 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
652 | HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, | ||
653 | USB_DEVICE_ID_CRYSTALTOUCH) }, | ||
654 | |||
655 | /* MosArt panels */ | ||
656 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
657 | HID_USB_DEVICE(USB_VENDOR_ID_ASUS, | ||
658 | USB_DEVICE_ID_ASUS_T91MT)}, | ||
659 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
660 | HID_USB_DEVICE(USB_VENDOR_ID_ASUS, | ||
661 | USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
662 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
663 | HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, | ||
664 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | ||
665 | |||
666 | /* PenMount panels */ | ||
667 | { .driver_data = MT_CLS_CONFIDENCE, | ||
668 | HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, | ||
669 | USB_DEVICE_ID_PENMOUNT_PCI) }, | ||
670 | |||
506 | /* PixCir-based panels */ | 671 | /* PixCir-based panels */ |
507 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 672 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
508 | HID_USB_DEVICE(USB_VENDOR_ID_HANVON, | 673 | HID_USB_DEVICE(USB_VENDOR_ID_HANVON, |
@@ -511,24 +676,29 @@ static const struct hid_device_id mt_devices[] = { | |||
511 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 676 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
512 | USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, | 677 | USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, |
513 | 678 | ||
514 | /* Resistive eGalax devices */ | 679 | /* Stantum panels */ |
515 | { .driver_data = MT_CLS_EGALAX, | 680 | { .driver_data = MT_CLS_CONFIDENCE, |
516 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 681 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
517 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 682 | USB_DEVICE_ID_MTP)}, |
518 | { .driver_data = MT_CLS_EGALAX, | 683 | { .driver_data = MT_CLS_CONFIDENCE, |
519 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 684 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
520 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, | 685 | USB_DEVICE_ID_MTP_STM)}, |
521 | 686 | { .driver_data = MT_CLS_CONFIDENCE, | |
522 | /* Capacitive eGalax devices */ | 687 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
523 | { .driver_data = MT_CLS_EGALAX, | 688 | USB_DEVICE_ID_MTP_SITRONIX)}, |
524 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 689 | |
525 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | 690 | /* Touch International panels */ |
526 | { .driver_data = MT_CLS_EGALAX, | 691 | { .driver_data = MT_CLS_DEFAULT, |
527 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 692 | HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, |
528 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, | 693 | USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, |
529 | { .driver_data = MT_CLS_EGALAX, | 694 | |
530 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 695 | /* Unitec panels */ |
531 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, | 696 | { .driver_data = MT_CLS_DEFAULT, |
697 | HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, | ||
698 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, | ||
699 | { .driver_data = MT_CLS_DEFAULT, | ||
700 | HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, | ||
701 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, | ||
532 | 702 | ||
533 | { } | 703 | { } |
534 | }; | 704 | }; |
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index b2f56a13bcf5..9d8710f8bc79 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c | |||
@@ -1585,11 +1585,11 @@ static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u, | |||
1585 | memset(raw_data, 0, sizeof(raw_data)); | 1585 | memset(raw_data, 0, sizeof(raw_data)); |
1586 | raw_data[0] = *off & 0xff; | 1586 | raw_data[0] = *off & 0xff; |
1587 | raw_data[1] = (*off >> 8) & 0xff; | 1587 | raw_data[1] = (*off >> 8) & 0xff; |
1588 | raw_data[2] = s < 20 ? s : 20; | 1588 | raw_data[2] = min((size_t)20, s); |
1589 | if (*off + raw_data[2] > 0xff) | 1589 | if (*off + raw_data[2] > 0xff) |
1590 | raw_data[2] = 0x100 - *off; | 1590 | raw_data[2] = 0x100 - *off; |
1591 | 1591 | ||
1592 | if (copy_from_user(raw_data+3, u, raw_data[2])) | 1592 | if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2]))) |
1593 | return -EFAULT; | 1593 | return -EFAULT; |
1594 | resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data, | 1594 | resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data, |
1595 | sizeof(raw_data)); | 1595 | sizeof(raw_data)); |
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 33eec74e0615..5b640a7a15a7 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c | |||
@@ -167,28 +167,28 @@ static int koneplus_set_profile_buttons(struct usb_device *usb_dev, | |||
167 | } | 167 | } |
168 | 168 | ||
169 | /* retval is 0-4 on success, < 0 on error */ | 169 | /* retval is 0-4 on success, < 0 on error */ |
170 | static int koneplus_get_startup_profile(struct usb_device *usb_dev) | 170 | static int koneplus_get_actual_profile(struct usb_device *usb_dev) |
171 | { | 171 | { |
172 | struct koneplus_startup_profile buf; | 172 | struct koneplus_actual_profile buf; |
173 | int retval; | 173 | int retval; |
174 | 174 | ||
175 | retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, | 175 | retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE, |
176 | &buf, sizeof(struct koneplus_startup_profile)); | 176 | &buf, sizeof(struct koneplus_actual_profile)); |
177 | 177 | ||
178 | return retval ? retval : buf.startup_profile; | 178 | return retval ? retval : buf.actual_profile; |
179 | } | 179 | } |
180 | 180 | ||
181 | static int koneplus_set_startup_profile(struct usb_device *usb_dev, | 181 | static int koneplus_set_actual_profile(struct usb_device *usb_dev, |
182 | int startup_profile) | 182 | int new_profile) |
183 | { | 183 | { |
184 | struct koneplus_startup_profile buf; | 184 | struct koneplus_actual_profile buf; |
185 | 185 | ||
186 | buf.command = KONEPLUS_COMMAND_STARTUP_PROFILE; | 186 | buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; |
187 | buf.size = sizeof(struct koneplus_startup_profile); | 187 | buf.size = sizeof(struct koneplus_actual_profile); |
188 | buf.startup_profile = startup_profile; | 188 | buf.actual_profile = new_profile; |
189 | 189 | ||
190 | return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, | 190 | return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE, |
191 | &buf, sizeof(struct koneplus_profile_buttons)); | 191 | &buf, sizeof(struct koneplus_actual_profile)); |
192 | } | 192 | } |
193 | 193 | ||
194 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, | 194 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, |
@@ -398,21 +398,22 @@ static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, | |||
398 | return sizeof(struct koneplus_profile_buttons); | 398 | return sizeof(struct koneplus_profile_buttons); |
399 | } | 399 | } |
400 | 400 | ||
401 | static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev, | 401 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, |
402 | struct device_attribute *attr, char *buf) | 402 | struct device_attribute *attr, char *buf) |
403 | { | 403 | { |
404 | struct koneplus_device *koneplus = | 404 | struct koneplus_device *koneplus = |
405 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 405 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
406 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->startup_profile); | 406 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); |
407 | } | 407 | } |
408 | 408 | ||
409 | static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, | 409 | static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev, |
410 | struct device_attribute *attr, char const *buf, size_t size) | 410 | struct device_attribute *attr, char const *buf, size_t size) |
411 | { | 411 | { |
412 | struct koneplus_device *koneplus; | 412 | struct koneplus_device *koneplus; |
413 | struct usb_device *usb_dev; | 413 | struct usb_device *usb_dev; |
414 | unsigned long profile; | 414 | unsigned long profile; |
415 | int retval; | 415 | int retval; |
416 | struct koneplus_roccat_report roccat_report; | ||
416 | 417 | ||
417 | dev = dev->parent->parent; | 418 | dev = dev->parent->parent; |
418 | koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 419 | koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
@@ -423,20 +424,25 @@ static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, | |||
423 | return retval; | 424 | return retval; |
424 | 425 | ||
425 | mutex_lock(&koneplus->koneplus_lock); | 426 | mutex_lock(&koneplus->koneplus_lock); |
426 | retval = koneplus_set_startup_profile(usb_dev, profile); | 427 | |
427 | mutex_unlock(&koneplus->koneplus_lock); | 428 | retval = koneplus_set_actual_profile(usb_dev, profile); |
428 | if (retval) | 429 | if (retval) { |
430 | mutex_unlock(&koneplus->koneplus_lock); | ||
429 | return retval; | 431 | return retval; |
432 | } | ||
430 | 433 | ||
431 | return size; | 434 | koneplus->actual_profile = profile; |
432 | } | ||
433 | 435 | ||
434 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, | 436 | roccat_report.type = KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE; |
435 | struct device_attribute *attr, char *buf) | 437 | roccat_report.data1 = profile + 1; |
436 | { | 438 | roccat_report.data2 = 0; |
437 | struct koneplus_device *koneplus = | 439 | roccat_report.profile = profile + 1; |
438 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 440 | roccat_report_event(koneplus->chrdev_minor, |
439 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); | 441 | (uint8_t const *)&roccat_report); |
442 | |||
443 | mutex_unlock(&koneplus->koneplus_lock); | ||
444 | |||
445 | return size; | ||
440 | } | 446 | } |
441 | 447 | ||
442 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, | 448 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, |
@@ -448,11 +454,12 @@ static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, | |||
448 | } | 454 | } |
449 | 455 | ||
450 | static struct device_attribute koneplus_attributes[] = { | 456 | static struct device_attribute koneplus_attributes[] = { |
457 | __ATTR(actual_profile, 0660, | ||
458 | koneplus_sysfs_show_actual_profile, | ||
459 | koneplus_sysfs_set_actual_profile), | ||
451 | __ATTR(startup_profile, 0660, | 460 | __ATTR(startup_profile, 0660, |
452 | koneplus_sysfs_show_startup_profile, | 461 | koneplus_sysfs_show_actual_profile, |
453 | koneplus_sysfs_set_startup_profile), | 462 | koneplus_sysfs_set_actual_profile), |
454 | __ATTR(actual_profile, 0440, | ||
455 | koneplus_sysfs_show_actual_profile, NULL), | ||
456 | __ATTR(firmware_version, 0440, | 463 | __ATTR(firmware_version, 0440, |
457 | koneplus_sysfs_show_firmware_version, NULL), | 464 | koneplus_sysfs_show_firmware_version, NULL), |
458 | __ATTR_NULL | 465 | __ATTR_NULL |
@@ -557,15 +564,10 @@ static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, | |||
557 | struct koneplus_device *koneplus) | 564 | struct koneplus_device *koneplus) |
558 | { | 565 | { |
559 | int retval, i; | 566 | int retval, i; |
560 | static uint wait = 100; /* device will freeze with just 60 */ | 567 | static uint wait = 200; |
561 | 568 | ||
562 | mutex_init(&koneplus->koneplus_lock); | 569 | mutex_init(&koneplus->koneplus_lock); |
563 | 570 | ||
564 | koneplus->startup_profile = koneplus_get_startup_profile(usb_dev); | ||
565 | if (koneplus->startup_profile < 0) | ||
566 | return koneplus->startup_profile; | ||
567 | |||
568 | msleep(wait); | ||
569 | retval = koneplus_get_info(usb_dev, &koneplus->info); | 571 | retval = koneplus_get_info(usb_dev, &koneplus->info); |
570 | if (retval) | 572 | if (retval) |
571 | return retval; | 573 | return retval; |
@@ -584,7 +586,11 @@ static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, | |||
584 | return retval; | 586 | return retval; |
585 | } | 587 | } |
586 | 588 | ||
587 | koneplus_profile_activated(koneplus, koneplus->startup_profile); | 589 | msleep(wait); |
590 | retval = koneplus_get_actual_profile(usb_dev); | ||
591 | if (retval < 0) | ||
592 | return retval; | ||
593 | koneplus_profile_activated(koneplus, retval); | ||
588 | 594 | ||
589 | return 0; | 595 | return 0; |
590 | } | 596 | } |
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h index 57a5c1ab7b05..c57a376ab8ae 100644 --- a/drivers/hid/hid-roccat-koneplus.h +++ b/drivers/hid/hid-roccat-koneplus.h | |||
@@ -40,10 +40,10 @@ enum koneplus_control_values { | |||
40 | KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, | 40 | KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | struct koneplus_startup_profile { | 43 | struct koneplus_actual_profile { |
44 | uint8_t command; /* KONEPLUS_COMMAND_STARTUP_PROFILE */ | 44 | uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */ |
45 | uint8_t size; /* always 3 */ | 45 | uint8_t size; /* always 3 */ |
46 | uint8_t startup_profile; /* Range 0-4! */ | 46 | uint8_t actual_profile; /* Range 0-4! */ |
47 | } __attribute__ ((__packed__)); | 47 | } __attribute__ ((__packed__)); |
48 | 48 | ||
49 | struct koneplus_profile_settings { | 49 | struct koneplus_profile_settings { |
@@ -132,7 +132,7 @@ struct koneplus_tcu_image { | |||
132 | 132 | ||
133 | enum koneplus_commands { | 133 | enum koneplus_commands { |
134 | KONEPLUS_COMMAND_CONTROL = 0x4, | 134 | KONEPLUS_COMMAND_CONTROL = 0x4, |
135 | KONEPLUS_COMMAND_STARTUP_PROFILE = 0x5, | 135 | KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, |
136 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, | 136 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, |
137 | KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, | 137 | KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, |
138 | KONEPLUS_COMMAND_MACRO = 0x8, | 138 | KONEPLUS_COMMAND_MACRO = 0x8, |
@@ -145,7 +145,7 @@ enum koneplus_commands { | |||
145 | 145 | ||
146 | enum koneplus_usb_commands { | 146 | enum koneplus_usb_commands { |
147 | KONEPLUS_USB_COMMAND_CONTROL = 0x304, | 147 | KONEPLUS_USB_COMMAND_CONTROL = 0x304, |
148 | KONEPLUS_USB_COMMAND_STARTUP_PROFILE = 0x305, | 148 | KONEPLUS_USB_COMMAND_ACTUAL_PROFILE = 0x305, |
149 | KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306, | 149 | KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306, |
150 | KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307, | 150 | KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307, |
151 | KONEPLUS_USB_COMMAND_MACRO = 0x308, | 151 | KONEPLUS_USB_COMMAND_MACRO = 0x308, |
@@ -215,7 +215,6 @@ struct koneplus_device { | |||
215 | 215 | ||
216 | struct mutex koneplus_lock; | 216 | struct mutex koneplus_lock; |
217 | 217 | ||
218 | int startup_profile; | ||
219 | struct koneplus_info info; | 218 | struct koneplus_info info; |
220 | struct koneplus_profile_settings profile_settings[5]; | 219 | struct koneplus_profile_settings profile_settings[5]; |
221 | struct koneplus_profile_buttons profile_buttons[5]; | 220 | struct koneplus_profile_buttons profile_buttons[5]; |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 93819a08121a..936c911fdca6 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -178,6 +178,8 @@ static void sony_remove(struct hid_device *hdev) | |||
178 | static const struct hid_device_id sony_devices[] = { | 178 | static const struct hid_device_id sony_devices[] = { |
179 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), | 179 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), |
180 | .driver_data = SIXAXIS_CONTROLLER_USB }, | 180 | .driver_data = SIXAXIS_CONTROLLER_USB }, |
181 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), | ||
182 | .driver_data = SIXAXIS_CONTROLLER_USB }, | ||
181 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), | 183 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), |
182 | .driver_data = SIXAXIS_CONTROLLER_BT }, | 184 | .driver_data = SIXAXIS_CONTROLLER_BT }, |
183 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), | 185 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), |
diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c deleted file mode 100644 index b2be1d11916b..000000000000 --- a/drivers/hid/hid-stantum.c +++ /dev/null | |||
@@ -1,286 +0,0 @@ | |||
1 | /* | ||
2 | * HID driver for Stantum multitouch panels | ||
3 | * | ||
4 | * Copyright (c) 2009 Stephane Chatty <chatty@enac.fr> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/hid.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | ||
21 | MODULE_DESCRIPTION("Stantum HID multitouch panels"); | ||
22 | MODULE_LICENSE("GPL"); | ||
23 | |||
24 | #include "hid-ids.h" | ||
25 | |||
26 | struct stantum_data { | ||
27 | __s32 x, y, z, w, h; /* x, y, pressure, width, height */ | ||
28 | __u16 id; /* touch id */ | ||
29 | bool valid; /* valid finger data, or just placeholder? */ | ||
30 | bool first; /* first finger in the HID packet? */ | ||
31 | bool activity; /* at least one active finger so far? */ | ||
32 | }; | ||
33 | |||
34 | static int stantum_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
35 | struct hid_field *field, struct hid_usage *usage, | ||
36 | unsigned long **bit, int *max) | ||
37 | { | ||
38 | switch (usage->hid & HID_USAGE_PAGE) { | ||
39 | |||
40 | case HID_UP_GENDESK: | ||
41 | switch (usage->hid) { | ||
42 | case HID_GD_X: | ||
43 | hid_map_usage(hi, usage, bit, max, | ||
44 | EV_ABS, ABS_MT_POSITION_X); | ||
45 | /* touchscreen emulation */ | ||
46 | input_set_abs_params(hi->input, ABS_X, | ||
47 | field->logical_minimum, | ||
48 | field->logical_maximum, 0, 0); | ||
49 | return 1; | ||
50 | case HID_GD_Y: | ||
51 | hid_map_usage(hi, usage, bit, max, | ||
52 | EV_ABS, ABS_MT_POSITION_Y); | ||
53 | /* touchscreen emulation */ | ||
54 | input_set_abs_params(hi->input, ABS_Y, | ||
55 | field->logical_minimum, | ||
56 | field->logical_maximum, 0, 0); | ||
57 | return 1; | ||
58 | } | ||
59 | return 0; | ||
60 | |||
61 | case HID_UP_DIGITIZER: | ||
62 | switch (usage->hid) { | ||
63 | case HID_DG_INRANGE: | ||
64 | case HID_DG_CONFIDENCE: | ||
65 | case HID_DG_INPUTMODE: | ||
66 | case HID_DG_DEVICEINDEX: | ||
67 | case HID_DG_CONTACTCOUNT: | ||
68 | case HID_DG_CONTACTMAX: | ||
69 | return -1; | ||
70 | |||
71 | case HID_DG_TIPSWITCH: | ||
72 | /* touchscreen emulation */ | ||
73 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
74 | return 1; | ||
75 | |||
76 | case HID_DG_WIDTH: | ||
77 | hid_map_usage(hi, usage, bit, max, | ||
78 | EV_ABS, ABS_MT_TOUCH_MAJOR); | ||
79 | return 1; | ||
80 | case HID_DG_HEIGHT: | ||
81 | hid_map_usage(hi, usage, bit, max, | ||
82 | EV_ABS, ABS_MT_TOUCH_MINOR); | ||
83 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, | ||
84 | 1, 1, 0, 0); | ||
85 | return 1; | ||
86 | case HID_DG_TIPPRESSURE: | ||
87 | hid_map_usage(hi, usage, bit, max, | ||
88 | EV_ABS, ABS_MT_PRESSURE); | ||
89 | return 1; | ||
90 | |||
91 | case HID_DG_CONTACTID: | ||
92 | hid_map_usage(hi, usage, bit, max, | ||
93 | EV_ABS, ABS_MT_TRACKING_ID); | ||
94 | return 1; | ||
95 | |||
96 | } | ||
97 | return 0; | ||
98 | |||
99 | case 0xff000000: | ||
100 | /* no input-oriented meaning */ | ||
101 | return -1; | ||
102 | } | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int stantum_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
108 | struct hid_field *field, struct hid_usage *usage, | ||
109 | unsigned long **bit, int *max) | ||
110 | { | ||
111 | if (usage->type == EV_KEY || usage->type == EV_ABS) | ||
112 | clear_bit(usage->code, *bit); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * this function is called when a whole finger has been parsed, | ||
119 | * so that it can decide what to send to the input layer. | ||
120 | */ | ||
121 | static void stantum_filter_event(struct stantum_data *sd, | ||
122 | struct input_dev *input) | ||
123 | { | ||
124 | bool wide; | ||
125 | |||
126 | if (!sd->valid) { | ||
127 | /* | ||
128 | * touchscreen emulation: if the first finger is not valid and | ||
129 | * there previously was finger activity, this is a release | ||
130 | */ | ||
131 | if (sd->first && sd->activity) { | ||
132 | input_event(input, EV_KEY, BTN_TOUCH, 0); | ||
133 | sd->activity = false; | ||
134 | } | ||
135 | return; | ||
136 | } | ||
137 | |||
138 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, sd->id); | ||
139 | input_event(input, EV_ABS, ABS_MT_POSITION_X, sd->x); | ||
140 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, sd->y); | ||
141 | |||
142 | wide = (sd->w > sd->h); | ||
143 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | ||
144 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, wide ? sd->w : sd->h); | ||
145 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, wide ? sd->h : sd->w); | ||
146 | |||
147 | input_event(input, EV_ABS, ABS_MT_PRESSURE, sd->z); | ||
148 | |||
149 | input_mt_sync(input); | ||
150 | sd->valid = false; | ||
151 | |||
152 | /* touchscreen emulation */ | ||
153 | if (sd->first) { | ||
154 | if (!sd->activity) { | ||
155 | input_event(input, EV_KEY, BTN_TOUCH, 1); | ||
156 | sd->activity = true; | ||
157 | } | ||
158 | input_event(input, EV_ABS, ABS_X, sd->x); | ||
159 | input_event(input, EV_ABS, ABS_Y, sd->y); | ||
160 | } | ||
161 | sd->first = false; | ||
162 | } | ||
163 | |||
164 | |||
165 | static int stantum_event(struct hid_device *hid, struct hid_field *field, | ||
166 | struct hid_usage *usage, __s32 value) | ||
167 | { | ||
168 | struct stantum_data *sd = hid_get_drvdata(hid); | ||
169 | |||
170 | if (hid->claimed & HID_CLAIMED_INPUT) { | ||
171 | struct input_dev *input = field->hidinput->input; | ||
172 | |||
173 | switch (usage->hid) { | ||
174 | case HID_DG_INRANGE: | ||
175 | /* this is the last field in a finger */ | ||
176 | stantum_filter_event(sd, input); | ||
177 | break; | ||
178 | case HID_DG_WIDTH: | ||
179 | sd->w = value; | ||
180 | break; | ||
181 | case HID_DG_HEIGHT: | ||
182 | sd->h = value; | ||
183 | break; | ||
184 | case HID_GD_X: | ||
185 | sd->x = value; | ||
186 | break; | ||
187 | case HID_GD_Y: | ||
188 | sd->y = value; | ||
189 | break; | ||
190 | case HID_DG_TIPPRESSURE: | ||
191 | sd->z = value; | ||
192 | break; | ||
193 | case HID_DG_CONTACTID: | ||
194 | sd->id = value; | ||
195 | break; | ||
196 | case HID_DG_CONFIDENCE: | ||
197 | sd->valid = !!value; | ||
198 | break; | ||
199 | case 0xff000002: | ||
200 | /* this comes only before the first finger */ | ||
201 | sd->first = true; | ||
202 | break; | ||
203 | |||
204 | default: | ||
205 | /* ignore the others */ | ||
206 | return 1; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* we have handled the hidinput part, now remains hiddev */ | ||
211 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | ||
212 | hid->hiddev_hid_event(hid, field, usage, value); | ||
213 | |||
214 | return 1; | ||
215 | } | ||
216 | |||
217 | static int stantum_probe(struct hid_device *hdev, | ||
218 | const struct hid_device_id *id) | ||
219 | { | ||
220 | int ret; | ||
221 | struct stantum_data *sd; | ||
222 | |||
223 | sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL); | ||
224 | if (!sd) { | ||
225 | hid_err(hdev, "cannot allocate Stantum data\n"); | ||
226 | return -ENOMEM; | ||
227 | } | ||
228 | sd->valid = false; | ||
229 | sd->first = false; | ||
230 | sd->activity = false; | ||
231 | hid_set_drvdata(hdev, sd); | ||
232 | |||
233 | ret = hid_parse(hdev); | ||
234 | if (!ret) | ||
235 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
236 | |||
237 | if (ret) | ||
238 | kfree(sd); | ||
239 | |||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | static void stantum_remove(struct hid_device *hdev) | ||
244 | { | ||
245 | hid_hw_stop(hdev); | ||
246 | kfree(hid_get_drvdata(hdev)); | ||
247 | hid_set_drvdata(hdev, NULL); | ||
248 | } | ||
249 | |||
250 | static const struct hid_device_id stantum_devices[] = { | ||
251 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, | ||
252 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, | ||
253 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, | ||
254 | { } | ||
255 | }; | ||
256 | MODULE_DEVICE_TABLE(hid, stantum_devices); | ||
257 | |||
258 | static const struct hid_usage_id stantum_grabbed_usages[] = { | ||
259 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | ||
260 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | ||
261 | }; | ||
262 | |||
263 | static struct hid_driver stantum_driver = { | ||
264 | .name = "stantum", | ||
265 | .id_table = stantum_devices, | ||
266 | .probe = stantum_probe, | ||
267 | .remove = stantum_remove, | ||
268 | .input_mapping = stantum_input_mapping, | ||
269 | .input_mapped = stantum_input_mapped, | ||
270 | .usage_table = stantum_grabbed_usages, | ||
271 | .event = stantum_event, | ||
272 | }; | ||
273 | |||
274 | static int __init stantum_init(void) | ||
275 | { | ||
276 | return hid_register_driver(&stantum_driver); | ||
277 | } | ||
278 | |||
279 | static void __exit stantum_exit(void) | ||
280 | { | ||
281 | hid_unregister_driver(&stantum_driver); | ||
282 | } | ||
283 | |||
284 | module_init(stantum_init); | ||
285 | module_exit(stantum_exit); | ||
286 | |||
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 54409cba018c..c79578b5a788 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -101,8 +101,8 @@ out: | |||
101 | return ret; | 101 | return ret; |
102 | } | 102 | } |
103 | 103 | ||
104 | /* the first byte is expected to be a report number */ | 104 | /* The first byte is expected to be a report number. |
105 | /* This function is to be called with the minors_lock mutex held */ | 105 | * This function is to be called with the minors_lock mutex held */ |
106 | static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type) | 106 | static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type) |
107 | { | 107 | { |
108 | unsigned int minor = iminor(file->f_path.dentry->d_inode); | 108 | unsigned int minor = iminor(file->f_path.dentry->d_inode); |
@@ -166,11 +166,11 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t | |||
166 | 166 | ||
167 | 167 | ||
168 | /* This function performs a Get_Report transfer over the control endpoint | 168 | /* This function performs a Get_Report transfer over the control endpoint |
169 | per section 7.2.1 of the HID specification, version 1.1. The first byte | 169 | * per section 7.2.1 of the HID specification, version 1.1. The first byte |
170 | of buffer is the report number to request, or 0x0 if the defice does not | 170 | * of buffer is the report number to request, or 0x0 if the defice does not |
171 | use numbered reports. The report_type parameter can be HID_FEATURE_REPORT | 171 | * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT |
172 | or HID_INPUT_REPORT. This function is to be called with the minors_lock | 172 | * or HID_INPUT_REPORT. This function is to be called with the minors_lock |
173 | mutex held. */ | 173 | * mutex held. */ |
174 | static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type) | 174 | static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type) |
175 | { | 175 | { |
176 | unsigned int minor = iminor(file->f_path.dentry->d_inode); | 176 | unsigned int minor = iminor(file->f_path.dentry->d_inode); |
@@ -207,7 +207,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t | |||
207 | } | 207 | } |
208 | 208 | ||
209 | /* Read the first byte from the user. This is the report number, | 209 | /* Read the first byte from the user. This is the report number, |
210 | which is passed to dev->hid_get_raw_report(). */ | 210 | * which is passed to dev->hid_get_raw_report(). */ |
211 | if (copy_from_user(&report_number, buffer, 1)) { | 211 | if (copy_from_user(&report_number, buffer, 1)) { |
212 | ret = -EFAULT; | 212 | ret = -EFAULT; |
213 | goto out_free; | 213 | goto out_free; |
@@ -395,12 +395,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, | |||
395 | } | 395 | } |
396 | 396 | ||
397 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) { | 397 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) { |
398 | int len; | 398 | int len = strlen(hid->name) + 1; |
399 | if (!hid->name) { | ||
400 | ret = 0; | ||
401 | break; | ||
402 | } | ||
403 | len = strlen(hid->name) + 1; | ||
404 | if (len > _IOC_SIZE(cmd)) | 399 | if (len > _IOC_SIZE(cmd)) |
405 | len = _IOC_SIZE(cmd); | 400 | len = _IOC_SIZE(cmd); |
406 | ret = copy_to_user(user_arg, hid->name, len) ? | 401 | ret = copy_to_user(user_arg, hid->name, len) ? |
@@ -409,12 +404,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, | |||
409 | } | 404 | } |
410 | 405 | ||
411 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) { | 406 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) { |
412 | int len; | 407 | int len = strlen(hid->phys) + 1; |
413 | if (!hid->phys) { | ||
414 | ret = 0; | ||
415 | break; | ||
416 | } | ||
417 | len = strlen(hid->phys) + 1; | ||
418 | if (len > _IOC_SIZE(cmd)) | 408 | if (len > _IOC_SIZE(cmd)) |
419 | len = _IOC_SIZE(cmd); | 409 | len = _IOC_SIZE(cmd); |
420 | ret = copy_to_user(user_arg, hid->phys, len) ? | 410 | ret = copy_to_user(user_arg, hid->phys, len) ? |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a8426f15e9ab..0e30b140edca 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -68,6 +68,8 @@ static const struct hid_blacklist { | |||
68 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, | 68 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, |
69 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, | 69 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, |
70 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
71 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, | ||
72 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, | ||
71 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 73 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
72 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, | 74 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, |
73 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, | 75 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index af0a7c1002af..ff3c644888b1 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -242,6 +242,7 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
242 | list_del(&list->node); | 242 | list_del(&list->node); |
243 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); | 243 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); |
244 | 244 | ||
245 | mutex_lock(&list->hiddev->existancelock); | ||
245 | if (!--list->hiddev->open) { | 246 | if (!--list->hiddev->open) { |
246 | if (list->hiddev->exist) { | 247 | if (list->hiddev->exist) { |
247 | usbhid_close(list->hiddev->hid); | 248 | usbhid_close(list->hiddev->hid); |
@@ -252,6 +253,7 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
252 | } | 253 | } |
253 | 254 | ||
254 | kfree(list); | 255 | kfree(list); |
256 | mutex_unlock(&list->hiddev->existancelock); | ||
255 | 257 | ||
256 | return 0; | 258 | return 0; |
257 | } | 259 | } |
@@ -300,17 +302,21 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
300 | list_add_tail(&list->node, &hiddev->list); | 302 | list_add_tail(&list->node, &hiddev->list); |
301 | spin_unlock_irq(&list->hiddev->list_lock); | 303 | spin_unlock_irq(&list->hiddev->list_lock); |
302 | 304 | ||
305 | mutex_lock(&hiddev->existancelock); | ||
303 | if (!list->hiddev->open++) | 306 | if (!list->hiddev->open++) |
304 | if (list->hiddev->exist) { | 307 | if (list->hiddev->exist) { |
305 | struct hid_device *hid = hiddev->hid; | 308 | struct hid_device *hid = hiddev->hid; |
306 | res = usbhid_get_power(hid); | 309 | res = usbhid_get_power(hid); |
307 | if (res < 0) { | 310 | if (res < 0) { |
308 | res = -EIO; | 311 | res = -EIO; |
309 | goto bail; | 312 | goto bail_unlock; |
310 | } | 313 | } |
311 | usbhid_open(hid); | 314 | usbhid_open(hid); |
312 | } | 315 | } |
316 | mutex_unlock(&hiddev->existancelock); | ||
313 | return 0; | 317 | return 0; |
318 | bail_unlock: | ||
319 | mutex_unlock(&hiddev->existancelock); | ||
314 | bail: | 320 | bail: |
315 | file->private_data = NULL; | 321 | file->private_data = NULL; |
316 | kfree(list); | 322 | kfree(list); |
@@ -367,8 +373,10 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
367 | /* let O_NONBLOCK tasks run */ | 373 | /* let O_NONBLOCK tasks run */ |
368 | mutex_unlock(&list->thread_lock); | 374 | mutex_unlock(&list->thread_lock); |
369 | schedule(); | 375 | schedule(); |
370 | if (mutex_lock_interruptible(&list->thread_lock)) | 376 | if (mutex_lock_interruptible(&list->thread_lock)) { |
377 | finish_wait(&list->hiddev->wait, &wait); | ||
371 | return -EINTR; | 378 | return -EINTR; |
379 | } | ||
372 | set_current_state(TASK_INTERRUPTIBLE); | 380 | set_current_state(TASK_INTERRUPTIBLE); |
373 | } | 381 | } |
374 | finish_wait(&list->hiddev->wait, &wait); | 382 | finish_wait(&list->hiddev->wait, &wait); |
@@ -509,7 +517,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
509 | (uref_multi->num_values > HID_MAX_MULTI_USAGES || | 517 | (uref_multi->num_values > HID_MAX_MULTI_USAGES || |
510 | uref->usage_index + uref_multi->num_values > field->report_count)) | 518 | uref->usage_index + uref_multi->num_values > field->report_count)) |
511 | goto inval; | 519 | goto inval; |
512 | } | 520 | } |
513 | 521 | ||
514 | switch (cmd) { | 522 | switch (cmd) { |
515 | case HIDIOCGUSAGE: | 523 | case HIDIOCGUSAGE: |
@@ -801,14 +809,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
801 | break; | 809 | break; |
802 | 810 | ||
803 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) { | 811 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) { |
804 | int len; | 812 | int len = strlen(hid->name) + 1; |
805 | |||
806 | if (!hid->name) { | ||
807 | r = 0; | ||
808 | break; | ||
809 | } | ||
810 | |||
811 | len = strlen(hid->name) + 1; | ||
812 | if (len > _IOC_SIZE(cmd)) | 813 | if (len > _IOC_SIZE(cmd)) |
813 | len = _IOC_SIZE(cmd); | 814 | len = _IOC_SIZE(cmd); |
814 | r = copy_to_user(user_arg, hid->name, len) ? | 815 | r = copy_to_user(user_arg, hid->name, len) ? |
@@ -817,14 +818,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
817 | } | 818 | } |
818 | 819 | ||
819 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) { | 820 | if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) { |
820 | int len; | 821 | int len = strlen(hid->phys) + 1; |
821 | |||
822 | if (!hid->phys) { | ||
823 | r = 0; | ||
824 | break; | ||
825 | } | ||
826 | |||
827 | len = strlen(hid->phys) + 1; | ||
828 | if (len > _IOC_SIZE(cmd)) | 822 | if (len > _IOC_SIZE(cmd)) |
829 | len = _IOC_SIZE(cmd); | 823 | len = _IOC_SIZE(cmd); |
830 | r = copy_to_user(user_arg, hid->phys, len) ? | 824 | r = copy_to_user(user_arg, hid->phys, len) ? |
@@ -925,7 +919,6 @@ void hiddev_disconnect(struct hid_device *hid) | |||
925 | 919 | ||
926 | mutex_lock(&hiddev->existancelock); | 920 | mutex_lock(&hiddev->existancelock); |
927 | hiddev->exist = 0; | 921 | hiddev->exist = 0; |
928 | mutex_unlock(&hiddev->existancelock); | ||
929 | 922 | ||
930 | usb_deregister_dev(usbhid->intf, &hiddev_class); | 923 | usb_deregister_dev(usbhid->intf, &hiddev_class); |
931 | 924 | ||
@@ -935,4 +928,5 @@ void hiddev_disconnect(struct hid_device *hid) | |||
935 | } else { | 928 | } else { |
936 | kfree(hiddev); | 929 | kfree(hiddev); |
937 | } | 930 | } |
931 | mutex_unlock(&hiddev->existancelock); | ||
938 | } | 932 | } |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index 12822cde4b49..19e95004b286 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
@@ -80,7 +80,7 @@ | |||
80 | #define HIDP_VIRTUAL_CABLE_UNPLUG 0 | 80 | #define HIDP_VIRTUAL_CABLE_UNPLUG 0 |
81 | #define HIDP_BOOT_PROTOCOL_MODE 1 | 81 | #define HIDP_BOOT_PROTOCOL_MODE 1 |
82 | #define HIDP_BLUETOOTH_VENDOR_ID 9 | 82 | #define HIDP_BLUETOOTH_VENDOR_ID 9 |
83 | #define HIDP_WAITING_FOR_RETURN 10 | 83 | #define HIDP_WAITING_FOR_RETURN 10 |
84 | #define HIDP_WAITING_FOR_SEND_ACK 11 | 84 | #define HIDP_WAITING_FOR_SEND_ACK 11 |
85 | 85 | ||
86 | struct hidp_connadd_req { | 86 | struct hidp_connadd_req { |
diff --git a/samples/Kconfig b/samples/Kconfig index 41063e7592d2..96a7572853f7 100644 --- a/samples/Kconfig +++ b/samples/Kconfig | |||
@@ -61,4 +61,10 @@ config SAMPLE_KDB | |||
61 | Build an example of how to dynamically add the hello | 61 | Build an example of how to dynamically add the hello |
62 | command to the kdb shell. | 62 | command to the kdb shell. |
63 | 63 | ||
64 | config SAMPLE_HIDRAW | ||
65 | bool "Build simple hidraw example" | ||
66 | depends on HIDRAW && HEADERS_CHECK | ||
67 | help | ||
68 | Build an example of how to use hidraw from userspace. | ||
69 | |||
64 | endif # SAMPLES | 70 | endif # SAMPLES |
diff --git a/samples/Makefile b/samples/Makefile index f26c0959fd86..6280817c2b7e 100644 --- a/samples/Makefile +++ b/samples/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # Makefile for Linux samples code | 1 | # Makefile for Linux samples code |
2 | 2 | ||
3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ | 3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ |
4 | hw_breakpoint/ kfifo/ kdb/ | 4 | hw_breakpoint/ kfifo/ kdb/ hidraw/ |
diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile new file mode 100644 index 000000000000..382eeae77bd6 --- /dev/null +++ b/samples/hidraw/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # kbuild trick to avoid linker error. Can be omitted if a module is built. | ||
2 | obj- := dummy.o | ||
3 | |||
4 | # List of programs to build | ||
5 | hostprogs-y := hid-example | ||
6 | |||
7 | # Tell kbuild to always build the programs | ||
8 | always := $(hostprogs-y) | ||
9 | |||
10 | HOSTCFLAGS_hid-example.o += -I$(objtree)/usr/include | ||
diff --git a/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c new file mode 100644 index 000000000000..816e2dcda7ca --- /dev/null +++ b/samples/hidraw/hid-example.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | * Hidraw Userspace Example | ||
3 | * | ||
4 | * Copyright (c) 2010 Alan Ott <alan@signal11.us> | ||
5 | * Copyright (c) 2010 Signal 11 Software | ||
6 | * | ||
7 | * The code may be used by anyone for any purpose, | ||
8 | * and can serve as a starting point for developing | ||
9 | * applications using hidraw. | ||
10 | */ | ||
11 | |||
12 | /* Linux */ | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/hidraw.h> | ||
16 | |||
17 | /* | ||
18 | * Ugly hack to work around failing compilation on systems that don't | ||
19 | * yet populate new version of hidraw.h to userspace. | ||
20 | * | ||
21 | * If you need this, please have your distro update the kernel headers. | ||
22 | */ | ||
23 | #ifndef HIDIOCSFEATURE | ||
24 | #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) | ||
25 | #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) | ||
26 | #endif | ||
27 | |||
28 | /* Unix */ | ||
29 | #include <sys/ioctl.h> | ||
30 | #include <sys/types.h> | ||
31 | #include <sys/stat.h> | ||
32 | #include <fcntl.h> | ||
33 | #include <unistd.h> | ||
34 | |||
35 | /* C */ | ||
36 | #include <stdio.h> | ||
37 | #include <string.h> | ||
38 | #include <stdlib.h> | ||
39 | #include <errno.h> | ||
40 | |||
41 | const char *bus_str(int bus); | ||
42 | |||
43 | int main(int argc, char **argv) | ||
44 | { | ||
45 | int fd; | ||
46 | int i, res, desc_size = 0; | ||
47 | char buf[256]; | ||
48 | struct hidraw_report_descriptor rpt_desc; | ||
49 | struct hidraw_devinfo info; | ||
50 | |||
51 | /* Open the Device with non-blocking reads. In real life, | ||
52 | don't use a hard coded path; use libudev instead. */ | ||
53 | fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK); | ||
54 | |||
55 | if (fd < 0) { | ||
56 | perror("Unable to open device"); | ||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | memset(&rpt_desc, 0x0, sizeof(rpt_desc)); | ||
61 | memset(&info, 0x0, sizeof(info)); | ||
62 | memset(buf, 0x0, sizeof(buf)); | ||
63 | |||
64 | /* Get Report Descriptor Size */ | ||
65 | res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); | ||
66 | if (res < 0) | ||
67 | perror("HIDIOCGRDESCSIZE"); | ||
68 | else | ||
69 | printf("Report Descriptor Size: %d\n", desc_size); | ||
70 | |||
71 | /* Get Report Descriptor */ | ||
72 | rpt_desc.size = desc_size; | ||
73 | res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); | ||
74 | if (res < 0) { | ||
75 | perror("HIDIOCGRDESC"); | ||
76 | } else { | ||
77 | printf("Report Descriptor:\n"); | ||
78 | for (i = 0; i < rpt_desc.size; i++) | ||
79 | printf("%hhx ", rpt_desc.value[i]); | ||
80 | puts("\n"); | ||
81 | } | ||
82 | |||
83 | /* Get Raw Name */ | ||
84 | res = ioctl(fd, HIDIOCGRAWNAME(256), buf); | ||
85 | if (res < 0) | ||
86 | perror("HIDIOCGRAWNAME"); | ||
87 | else | ||
88 | printf("Raw Name: %s\n", buf); | ||
89 | |||
90 | /* Get Physical Location */ | ||
91 | res = ioctl(fd, HIDIOCGRAWPHYS(256), buf); | ||
92 | if (res < 0) | ||
93 | perror("HIDIOCGRAWPHYS"); | ||
94 | else | ||
95 | printf("Raw Phys: %s\n", buf); | ||
96 | |||
97 | /* Get Raw Info */ | ||
98 | res = ioctl(fd, HIDIOCGRAWINFO, &info); | ||
99 | if (res < 0) { | ||
100 | perror("HIDIOCGRAWINFO"); | ||
101 | } else { | ||
102 | printf("Raw Info:\n"); | ||
103 | printf("\tbustype: %d (%s)\n", | ||
104 | info.bustype, bus_str(info.bustype)); | ||
105 | printf("\tvendor: 0x%04hx\n", info.vendor); | ||
106 | printf("\tproduct: 0x%04hx\n", info.product); | ||
107 | } | ||
108 | |||
109 | /* Set Feature */ | ||
110 | buf[0] = 0x9; /* Report Number */ | ||
111 | buf[1] = 0xff; | ||
112 | buf[2] = 0xff; | ||
113 | buf[3] = 0xff; | ||
114 | res = ioctl(fd, HIDIOCSFEATURE(4), buf); | ||
115 | if (res < 0) | ||
116 | perror("HIDIOCSFEATURE"); | ||
117 | else | ||
118 | printf("ioctl HIDIOCGFEATURE returned: %d\n", res); | ||
119 | |||
120 | /* Get Feature */ | ||
121 | buf[0] = 0x9; /* Report Number */ | ||
122 | res = ioctl(fd, HIDIOCGFEATURE(256), buf); | ||
123 | if (res < 0) { | ||
124 | perror("HIDIOCGFEATURE"); | ||
125 | } else { | ||
126 | printf("ioctl HIDIOCGFEATURE returned: %d\n", res); | ||
127 | printf("Report data (not containing the report number):\n\t"); | ||
128 | for (i = 0; i < res; i++) | ||
129 | printf("%hhx ", buf[i]); | ||
130 | puts("\n"); | ||
131 | } | ||
132 | |||
133 | /* Send a Report to the Device */ | ||
134 | buf[0] = 0x1; /* Report Number */ | ||
135 | buf[1] = 0x77; | ||
136 | res = write(fd, buf, 2); | ||
137 | if (res < 0) { | ||
138 | printf("Error: %d\n", errno); | ||
139 | perror("write"); | ||
140 | } else { | ||
141 | printf("write() wrote %d bytes\n", res); | ||
142 | } | ||
143 | |||
144 | /* Get a report from the device */ | ||
145 | res = read(fd, buf, 16); | ||
146 | if (res < 0) { | ||
147 | perror("read"); | ||
148 | } else { | ||
149 | printf("read() read %d bytes:\n\t", res); | ||
150 | for (i = 0; i < res; i++) | ||
151 | printf("%hhx ", buf[i]); | ||
152 | puts("\n"); | ||
153 | } | ||
154 | close(fd); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | const char * | ||
159 | bus_str(int bus) | ||
160 | { | ||
161 | switch (bus) { | ||
162 | case BUS_USB: | ||
163 | return "USB"; | ||
164 | break; | ||
165 | case BUS_HIL: | ||
166 | return "HIL"; | ||
167 | break; | ||
168 | case BUS_BLUETOOTH: | ||
169 | return "Bluetooth"; | ||
170 | break; | ||
171 | case BUS_VIRTUAL: | ||
172 | return "Virtual"; | ||
173 | break; | ||
174 | default: | ||
175 | return "Other"; | ||
176 | break; | ||
177 | } | ||
178 | } | ||