aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus10
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus19
-rw-r--r--Documentation/hid/hiddev.txt (renamed from Documentation/usb/hiddev.txt)0
-rw-r--r--Documentation/hid/hidraw.txt119
-rw-r--r--drivers/hid/Kconfig42
-rw-r--r--drivers/hid/Makefile4
-rw-r--r--drivers/hid/hid-3m-pct.c305
-rw-r--r--drivers/hid/hid-cando.c276
-rw-r--r--drivers/hid/hid-core.c15
-rw-r--r--drivers/hid/hid-ids.h32
-rw-r--r--drivers/hid/hid-input.c60
-rw-r--r--drivers/hid/hid-lg.c2
-rw-r--r--drivers/hid/hid-lgff.c3
-rw-r--r--drivers/hid/hid-magicmouse.c10
-rw-r--r--drivers/hid/hid-mosart.c296
-rw-r--r--drivers/hid/hid-multitouch.c264
-rw-r--r--drivers/hid/hid-picolcd.c4
-rw-r--r--drivers/hid/hid-roccat-koneplus.c82
-rw-r--r--drivers/hid/hid-roccat-koneplus.h11
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hid/hid-stantum.c286
-rw-r--r--drivers/hid/hidraw.c30
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/hid/usbhid/hiddev.c34
-rw-r--r--net/bluetooth/hidp/hidp.h2
-rw-r--r--samples/Kconfig6
-rw-r--r--samples/Makefile2
-rw-r--r--samples/hidraw/Makefile10
-rw-r--r--samples/hidraw/hid-example.c178
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 00000000000..c2a270b45b0
--- /dev/null
+++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus
@@ -0,0 +1,10 @@
1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile
2Date: October 2010
3Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: 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 326e05452da..c1b53b8bc2a 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
@@ -1,9 +1,12 @@
1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile 1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile
2Date: October 2010 2Date: October 2010
3Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 3Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: When read, this file returns the number of the actual profile in 4Description: 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.
7Users: http://roccat.sourceforge.net 10Users: http://roccat.sourceforge.net
8 11
9What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version 12What: /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.
90Users: http://roccat.sourceforge.net 93Users: http://roccat.sourceforge.net
91 94
92What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile
93Date: October 2010
94Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
95Description: 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.
100Users: http://roccat.sourceforge.net
101
102What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu 95What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu
103Date: October 2010 96Date: October 2010
104Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 97Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
diff --git a/Documentation/usb/hiddev.txt b/Documentation/hid/hiddev.txt
index 6e8c9f1d2f2..6e8c9f1d2f2 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 00000000000..029e6cb9a7e
--- /dev/null
+++ b/Documentation/hid/hidraw.txt
@@ -0,0 +1,119 @@
1 HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices
2 ==================================================================
3
4The hidraw driver provides a raw interface to USB and Bluetooth Human
5Interface Devices (HIDs). It differs from hiddev in that reports sent and
6received are not parsed by the HID parser, but are sent to and received from
7the device unmodified.
8
9Hidraw should be used if the userspace application knows exactly how to
10communicate with the hardware device, and is able to construct the HID
11reports manually. This is often the case when making userspace drivers for
12custom HID devices.
13
14Hidraw is also useful for communicating with non-conformant HID devices
15which send and receive data in a way that is inconsistent with their report
16descriptors. Because hiddev parses reports which are sent and received
17through it, checking them against the device's report descriptor, such
18communication with these non-conformant devices is impossible using hiddev.
19Hidraw is the only alternative, short of writing a custom kernel driver, for
20these non-conformant devices.
21
22A benefit of hidraw is that its use by userspace applications is independent
23of the underlying hardware type. Currently, Hidraw is implemented for USB
24and Bluetooth. In the future, as new hardware bus types are developed which
25use the HID specification, hidraw will be expanded to add support for these
26new bus types.
27
28Hidraw uses a dynamic major number, meaning that udev should be relied on to
29create hidraw device nodes. Udev will typically create the device nodes
30directly under /dev (eg: /dev/hidraw0). As this location is distribution-
31and udev rule-dependent, applications should use libudev to locate hidraw
32devices attached to the system. There is a tutorial on libudev with a
33working example at:
34 http://www.signal11.us/oss/udev/
35
36The HIDRAW API
37---------------
38
39read()
40-------
41read() will read a queued report received from the HID device. On USB
42devices, the reports read using read() are the reports sent from the device
43on the INTERRUPT IN endpoint. By default, read() will block until there is
44a report available to be read. read() can be made non-blocking, by passing
45the O_NONBLOCK flag to open(), or by setting the O_NONBLOCK flag using
46fcntl().
47
48On a device which uses numbered reports, the first byte of the returned data
49will be the report number; the report data follows, beginning in the second
50byte. For devices which do not use numbered reports, the report data
51will begin at the first byte.
52
53write()
54--------
55The write() function will write a report to the device. For USB devices, if
56the device has an INTERRUPT OUT endpoint, the report will be sent on that
57endpoint. If it does not, the report will be sent over the control endpoint,
58using a SET_REPORT transfer.
59
60The first byte of the buffer passed to write() should be set to the report
61number. If the device does not use numbered reports, the first byte should
62be set to 0. The report data itself should begin at the second byte.
63
64ioctl()
65--------
66Hidraw supports the following ioctls:
67
68HIDIOCGRDESCSIZE: Get Report Descriptor Size
69This ioctl will get the size of the device's report descriptor.
70
71HIDIOCGRDESC: Get Report Descriptor
72This ioctl returns the device's report descriptor using a
73hidraw_report_descriptor struct. Make sure to set the size field of the
74hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE.
75
76HIDIOCGRAWINFO: Get Raw Info
77This ioctl will return a hidraw_devinfo struct containing the bus type, the
78vendor ID (VID), and product ID (PID) of the device. The bus type can be one
79of:
80 BUS_USB
81 BUS_HIL
82 BUS_BLUETOOTH
83 BUS_VIRTUAL
84which are defined in linux/input.h.
85
86HIDIOCGRAWNAME(len): Get Raw Name
87This ioctl returns a string containing the vendor and product strings of
88the device. The returned string is Unicode, UTF-8 encoded.
89
90HIDIOCGRAWPHYS(len): Get Physical Address
91This ioctl returns a string representing the physical address of the device.
92For USB devices, the string contains the physical path to the device (the
93USB controller, hubs, ports, etc). For Bluetooth devices, the string
94contains the hardware (MAC) address of the device.
95
96HIDIOCSFEATURE(len): Send a Feature Report
97This ioctl will send a feature report to the device. Per the HID
98specification, feature reports are always sent using the control endpoint.
99Set the first byte of the supplied buffer to the report number. For devices
100which do not use numbered reports, set the first byte to 0. The report data
101begins in the second byte. Make sure to set len accordingly, to one more
102than the length of the report (to account for the report number).
103
104HIDIOCGFEATURE(len): Get a Feature Report
105This ioctl will request a feature report from the device using the control
106endpoint. The first byte of the supplied buffer should be set to the report
107number of the requested report. For devices which do not use numbered
108reports, set the first byte to 0. The report will be returned starting at
109the first byte of the buffer (ie: the report number is not returned).
110
111Example
112---------
113In samples/, find hid-example.c, which shows examples of read(), write(),
114and all the ioctls for hidraw. The code may be used by anyone for any
115purpose, and can serve as a starting point for developing applications using
116hidraw.
117
118Document by:
119 Alan Ott <alan@signal11.us>, Signal 11 Software
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 9de9e97149e..67d2a758593 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -55,12 +55,6 @@ source "drivers/hid/usbhid/Kconfig"
55menu "Special HID drivers" 55menu "Special HID drivers"
56 depends on HID 56 depends on HID
57 57
58config HID_3M_PCT
59 tristate "3M PCT touchscreen"
60 depends on USB_HID
61 ---help---
62 Support for 3M PCT touch screens.
63
64config HID_A4TECH 58config 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
103config HID_CANDO
104 tristate "Cando dual touch panel"
105 depends on USB_HID
106 ---help---
107 Support for Cando dual touch panel.
108
109config HID_CHERRY 97config 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
303config HID_MOSART
304 tristate "MosArt dual-touch panels"
305 depends on USB_HID
306 ---help---
307 Support for MosArt dual-touch panels.
308
309config HID_MONTEREY 291config 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
503config HID_STANTUM
504 tristate "Stantum multitouch panel"
505 depends on USB_HID
506 ---help---
507 Support for Stantum multitouch panel.
508
509config HID_SUNPLUS 497config 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 06c68ae3abe..f8cc4ea7335 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
26endif 26endif
27 27
28obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
29obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o 28obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
30obj-$(CONFIG_HID_ACRUX) += hid-axff.o 29obj-$(CONFIG_HID_ACRUX) += hid-axff.o
31obj-$(CONFIG_HID_APPLE) += hid-apple.o 30obj-$(CONFIG_HID_APPLE) += hid-apple.o
32obj-$(CONFIG_HID_BELKIN) += hid-belkin.o 31obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
33obj-$(CONFIG_HID_CANDO) += hid-cando.o
34obj-$(CONFIG_HID_CHERRY) += hid-cherry.o 32obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
35obj-$(CONFIG_HID_CHICONY) += hid-chicony.o 33obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
36obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 34obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
@@ -47,7 +45,6 @@ obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
47obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o 45obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
48obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o 46obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
49obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o 47obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
50obj-$(CONFIG_HID_MOSART) += hid-mosart.o
51obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o 48obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
52obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o 49obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
53obj-$(CONFIG_HID_ORTEK) += hid-ortek.o 50obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
@@ -66,7 +63,6 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
66obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 63obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
67obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 64obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
68obj-$(CONFIG_HID_SONY) += hid-sony.o 65obj-$(CONFIG_HID_SONY) += hid-sony.o
69obj-$(CONFIG_HID_STANTUM) += hid-stantum.o
70obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o 66obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
71obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o 67obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
72obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o 68obj-$(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 5243ae2d373..00000000000
--- 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
24MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
25MODULE_DESCRIPTION("3M PCT multitouch panels");
26MODULE_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
36struct mmm_finger {
37 __s32 x, y, w, h;
38 bool touch, valid;
39};
40
41struct mmm_data {
42 struct mmm_finger f[MAX_SLOTS];
43 __u8 curid;
44 __u8 nexp, nreal;
45 bool touch, valid;
46};
47
48static 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
130static 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 */
144static 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 */
180static 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
240static 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
263static 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
270static 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};
275MODULE_DEVICE_TABLE(hid, mmm_devices);
276
277static 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
282static 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
293static int __init mmm_init(void)
294{
295 return hid_register_driver(&mmm_driver);
296}
297
298static void __exit mmm_exit(void)
299{
300 hid_unregister_driver(&mmm_driver);
301}
302
303module_init(mmm_init);
304module_exit(mmm_exit);
305
diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c
deleted file mode 100644
index 1ea066c5520..00000000000
--- 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
20MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
21MODULE_DESCRIPTION("Cando dual-touch panel");
22MODULE_LICENSE("GPL");
23
24#include "hid-ids.h"
25
26struct 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
36static 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
83static 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 */
97static 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
164static 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
203static 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
228static 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
235static 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};
246MODULE_DEVICE_TABLE(hid, cando_devices);
247
248static 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
253static 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
264static int __init cando_init(void)
265{
266 return hid_register_driver(&cando_driver);
267}
268
269static void __exit cando_exit(void)
270{
271 hid_unregister_driver(&cando_driver);
272}
273
274module_init(cando_init);
275module_exit(cando_exit);
276
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 408c4bea4d8..4140fd27141 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 00a94b535d2..e715c43aa01 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 33dde8724e0..6559e2e3364 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 3da90402ee8..21f205f0925 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 f099079ca6b..088f8504929 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 0ec91c18a42..a5eda4c8127 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 aed7ffe3628..00000000000
--- 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
23MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
24MODULE_DESCRIPTION("MosArt dual-touch panel");
25MODULE_LICENSE("GPL");
26
27#include "hid-ids.h"
28
29struct 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
38static 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
102static 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 */
116static 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
154static 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
198static 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
238static 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
250static 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
257static 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};
263MODULE_DEVICE_TABLE(hid, mosart_devices);
264
265static 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
270static 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
284static int __init mosart_init(void)
285{
286 return hid_register_driver(&mosart_driver);
287}
288
289static void __exit mosart_exit(void)
290{
291 hid_unregister_driver(&mosart_driver);
292}
293
294module_init(mosart_init);
295module_exit(mosart_exit);
296
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index ee01e65e22d..ecd4d2db9e8 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
48struct mt_slot { 55struct 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
67struct mt_class { 75struct 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)
95static int find_slot_from_contactid(struct mt_device *td) 114static 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
114struct mt_class mt_classes[] = { 133struct 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
142static void mt_feature_mapping(struct hid_device *hdev, 179static 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
489static const struct hid_device_id mt_devices[] = { 567static 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 b2f56a13bcf..9d8710f8bc7 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 33eec74e061..5b640a7a15a 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 */
170static int koneplus_get_startup_profile(struct usb_device *usb_dev) 170static 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
181static int koneplus_set_startup_profile(struct usb_device *usb_dev, 181static 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
194static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, 194static 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
401static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev, 401static 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
409static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, 409static 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
434static 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
442static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, 448static 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
450static struct device_attribute koneplus_attributes[] = { 456static 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 57a5c1ab7b0..c57a376ab8a 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
43struct koneplus_startup_profile { 43struct 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
49struct koneplus_profile_settings { 49struct koneplus_profile_settings {
@@ -132,7 +132,7 @@ struct koneplus_tcu_image {
132 132
133enum koneplus_commands { 133enum 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
146enum koneplus_usb_commands { 146enum 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 93819a08121..936c911fdca 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)
178static const struct hid_device_id sony_devices[] = { 178static 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 b2be1d11916..00000000000
--- 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
20MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
21MODULE_DESCRIPTION("Stantum HID multitouch panels");
22MODULE_LICENSE("GPL");
23
24#include "hid-ids.h"
25
26struct 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
34static 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
107static 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 */
121static 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
165static 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
217static 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
243static 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
250static 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};
256MODULE_DEVICE_TABLE(hid, stantum_devices);
257
258static 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
263static 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
274static int __init stantum_init(void)
275{
276 return hid_register_driver(&stantum_driver);
277}
278
279static void __exit stantum_exit(void)
280{
281 hid_unregister_driver(&stantum_driver);
282}
283
284module_init(stantum_init);
285module_exit(stantum_exit);
286
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 54409cba018..c79578b5a78 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 */
106static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type) 106static 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. */
174static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type) 174static 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 a8426f15e9a..0e30b140edc 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 af0a7c1002a..ff3c644888b 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;
318bail_unlock:
319 mutex_unlock(&hiddev->existancelock);
314bail: 320bail:
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 12822cde4b4..19e95004b28 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
86struct hidp_connadd_req { 86struct hidp_connadd_req {
diff --git a/samples/Kconfig b/samples/Kconfig
index 41063e7592d..96a7572853f 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
64config 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
64endif # SAMPLES 70endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index f26c0959fd8..6280817c2b7 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
3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ 3obj-$(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 00000000000..382eeae77bd
--- /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.
2obj- := dummy.o
3
4# List of programs to build
5hostprogs-y := hid-example
6
7# Tell kbuild to always build the programs
8always := $(hostprogs-y)
9
10HOSTCFLAGS_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 00000000000..816e2dcda7c
--- /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
41const char *bus_str(int bus);
42
43int 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
158const char *
159bus_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}