diff options
-rw-r--r-- | Documentation/hid/uhid.txt | 179 | ||||
-rw-r--r-- | drivers/hid/Kconfig | 11 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 7 | ||||
-rw-r--r-- | drivers/hid/hid-holtek-mouse.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 7 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 6 | ||||
-rw-r--r-- | drivers/hid/hid-penmount.c | 49 | ||||
-rw-r--r-- | drivers/hid/hid-picolcd_core.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-rmi.c | 44 | ||||
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 100 | ||||
-rw-r--r-- | drivers/hid/hid-thingm.c | 7 | ||||
-rw-r--r-- | drivers/hid/uhid.c | 394 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 60 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 3 | ||||
-rw-r--r-- | drivers/hid/wacom.h | 6 | ||||
-rw-r--r-- | drivers/hid/wacom_sys.c | 271 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 312 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 17 | ||||
-rw-r--r-- | include/linux/hid.h | 3 | ||||
-rw-r--r-- | include/uapi/linux/uhid.h | 120 |
22 files changed, 1166 insertions, 442 deletions
diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.txt index 54c8f9706a95..c8656dd029a9 100644 --- a/Documentation/hid/uhid.txt +++ b/Documentation/hid/uhid.txt | |||
@@ -1,28 +1,13 @@ | |||
1 | UHID - User-space I/O driver support for HID subsystem | 1 | UHID - User-space I/O driver support for HID subsystem |
2 | ======================================================== | 2 | ======================================================== |
3 | 3 | ||
4 | The HID subsystem needs two kinds of drivers. In this document we call them: | 4 | UHID allows user-space to implement HID transport drivers. Please see |
5 | hid-transport.txt for an introduction into HID transport drivers. This document | ||
6 | relies heavily on the definitions declared there. | ||
5 | 7 | ||
6 | 1. The "HID I/O Driver" is the driver that performs raw data I/O to the | 8 | With UHID, a user-space transport driver can create kernel hid-devices for each |
7 | low-level device. Internally, they register an hid_ll_driver structure with | 9 | device connected to the user-space controlled bus. The UHID API defines the I/O |
8 | the HID core. They perform device setup, read raw data from the device and | 10 | events provided from the kernel to user-space and vice versa. |
9 | push it into the HID subsystem and they provide a callback so the HID | ||
10 | subsystem can send data to the device. | ||
11 | |||
12 | 2. The "HID Device Driver" is the driver that parses HID reports and reacts on | ||
13 | them. There are generic drivers like "generic-usb" and "generic-bluetooth" | ||
14 | which adhere to the HID specification and provide the standardizes features. | ||
15 | But there may be special drivers and quirks for each non-standard device out | ||
16 | there. Internally, they use the hid_driver structure. | ||
17 | |||
18 | Historically, the USB stack was the first subsystem to provide an HID I/O | ||
19 | Driver. However, other standards like Bluetooth have adopted the HID specs and | ||
20 | may provide HID I/O Drivers, too. The UHID driver allows to implement HID I/O | ||
21 | Drivers in user-space and feed the data into the kernel HID-subsystem. | ||
22 | |||
23 | This allows user-space to operate on the same level as USB-HID, Bluetooth-HID | ||
24 | and similar. It does not provide a way to write HID Device Drivers, though. Use | ||
25 | hidraw for this purpose. | ||
26 | 11 | ||
27 | There is an example user-space application in ./samples/uhid/uhid-example.c | 12 | There is an example user-space application in ./samples/uhid/uhid-example.c |
28 | 13 | ||
@@ -42,8 +27,9 @@ by setting O_NONBLOCK. | |||
42 | struct uhid_event { | 27 | struct uhid_event { |
43 | __u32 type; | 28 | __u32 type; |
44 | union { | 29 | union { |
45 | struct uhid_create_req create; | 30 | struct uhid_create2_req create2; |
46 | struct uhid_data_req data; | 31 | struct uhid_output_req output; |
32 | struct uhid_input2_req input2; | ||
47 | ... | 33 | ... |
48 | } u; | 34 | } u; |
49 | }; | 35 | }; |
@@ -54,8 +40,11 @@ multiple write()'s. A single event must always be sent as a whole. Furthermore, | |||
54 | only a single event can be sent per read() or write(). Pending data is ignored. | 40 | only a single event can be sent per read() or write(). Pending data is ignored. |
55 | If you want to handle multiple events in a single syscall, then use vectored | 41 | If you want to handle multiple events in a single syscall, then use vectored |
56 | I/O with readv()/writev(). | 42 | I/O with readv()/writev(). |
43 | The "type" field defines the payload. For each type, there is a | ||
44 | payload-structure available in the union "u" (except for empty payloads). This | ||
45 | payload contains management and/or device data. | ||
57 | 46 | ||
58 | The first thing you should do is sending an UHID_CREATE event. This will | 47 | The first thing you should do is sending an UHID_CREATE2 event. This will |
59 | register the device. UHID will respond with an UHID_START event. You can now | 48 | register the device. UHID will respond with an UHID_START event. You can now |
60 | start sending data to and reading data from UHID. However, unless UHID sends the | 49 | start sending data to and reading data from UHID. However, unless UHID sends the |
61 | UHID_OPEN event, the internally attached HID Device Driver has no user attached. | 50 | UHID_OPEN event, the internally attached HID Device Driver has no user attached. |
@@ -69,12 +58,20 @@ ref-counting for you. | |||
69 | You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even | 58 | You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even |
70 | though the device may have no users. | 59 | though the device may have no users. |
71 | 60 | ||
72 | If you want to send data to the HID subsystem, you send an HID_INPUT event with | 61 | If you want to send data on the interrupt channel to the HID subsystem, you send |
73 | your raw data payload. If the kernel wants to send data to the device, you will | 62 | an HID_INPUT2 event with your raw data payload. If the kernel wants to send data |
74 | read an UHID_OUTPUT or UHID_OUTPUT_EV event. | 63 | on the interrupt channel to the device, you will read an UHID_OUTPUT event. |
64 | Data requests on the control channel are currently limited to GET_REPORT and | ||
65 | SET_REPORT (no other data reports on the control channel are defined so far). | ||
66 | Those requests are always synchronous. That means, the kernel sends | ||
67 | UHID_GET_REPORT and UHID_SET_REPORT events and requires you to forward them to | ||
68 | the device on the control channel. Once the device responds, you must forward | ||
69 | the response via UHID_GET_REPORT_REPLY and UHID_SET_REPORT_REPLY to the kernel. | ||
70 | The kernel blocks internal driver-execution during such round-trips (times out | ||
71 | after a hard-coded period). | ||
75 | 72 | ||
76 | If your device disconnects, you should send an UHID_DESTROY event. This will | 73 | If your device disconnects, you should send an UHID_DESTROY event. This will |
77 | unregister the device. You can now send UHID_CREATE again to register a new | 74 | unregister the device. You can now send UHID_CREATE2 again to register a new |
78 | device. | 75 | device. |
79 | If you close() the fd, the device is automatically unregistered and destroyed | 76 | If you close() the fd, the device is automatically unregistered and destroyed |
80 | internally. | 77 | internally. |
@@ -82,73 +79,79 @@ internally. | |||
82 | write() | 79 | write() |
83 | ------- | 80 | ------- |
84 | write() allows you to modify the state of the device and feed input data into | 81 | write() allows you to modify the state of the device and feed input data into |
85 | the kernel. The following types are supported: UHID_CREATE, UHID_DESTROY and | 82 | the kernel. The kernel will parse the event immediately and if the event ID is |
86 | UHID_INPUT. The kernel will parse the event immediately and if the event ID is | ||
87 | not supported, it will return -EOPNOTSUPP. If the payload is invalid, then | 83 | not supported, it will return -EOPNOTSUPP. If the payload is invalid, then |
88 | -EINVAL is returned, otherwise, the amount of data that was read is returned and | 84 | -EINVAL is returned, otherwise, the amount of data that was read is returned and |
89 | the request was handled successfully. | 85 | the request was handled successfully. O_NONBLOCK does not affect write() as |
86 | writes are always handled immediately in a non-blocking fashion. Future requests | ||
87 | might make use of O_NONBLOCK, though. | ||
90 | 88 | ||
91 | UHID_CREATE: | 89 | UHID_CREATE2: |
92 | This creates the internal HID device. No I/O is possible until you send this | 90 | This creates the internal HID device. No I/O is possible until you send this |
93 | event to the kernel. The payload is of type struct uhid_create_req and | 91 | event to the kernel. The payload is of type struct uhid_create2_req and |
94 | contains information about your device. You can start I/O now. | 92 | contains information about your device. You can start I/O now. |
95 | 93 | ||
96 | UHID_CREATE2: | ||
97 | Same as UHID_CREATE, but the HID report descriptor data (rd_data) is an array | ||
98 | inside struct uhid_create2_req, instead of a pointer to a separate array. | ||
99 | Enables use from languages that don't support pointers, e.g. Python. | ||
100 | |||
101 | UHID_DESTROY: | 94 | UHID_DESTROY: |
102 | This destroys the internal HID device. No further I/O will be accepted. There | 95 | This destroys the internal HID device. No further I/O will be accepted. There |
103 | may still be pending messages that you can receive with read() but no further | 96 | may still be pending messages that you can receive with read() but no further |
104 | UHID_INPUT events can be sent to the kernel. | 97 | UHID_INPUT events can be sent to the kernel. |
105 | You can create a new device by sending UHID_CREATE again. There is no need to | 98 | You can create a new device by sending UHID_CREATE2 again. There is no need to |
106 | reopen the character device. | 99 | reopen the character device. |
107 | 100 | ||
108 | UHID_INPUT: | ||
109 | You must send UHID_CREATE before sending input to the kernel! This event | ||
110 | contains a data-payload. This is the raw data that you read from your device. | ||
111 | The kernel will parse the HID reports and react on it. | ||
112 | |||
113 | UHID_INPUT2: | 101 | UHID_INPUT2: |
114 | Same as UHID_INPUT, but the data array is the last field of uhid_input2_req. | 102 | You must send UHID_CREATE2 before sending input to the kernel! This event |
115 | Enables userspace to write only the required bytes to kernel (ev.type + | 103 | contains a data-payload. This is the raw data that you read from your device |
116 | ev.u.input2.size + the part of the data array that matters), instead of | 104 | on the interrupt channel. The kernel will parse the HID reports. |
117 | the entire struct uhid_input2_req. | 105 | |
118 | 106 | UHID_GET_REPORT_REPLY: | |
119 | UHID_FEATURE_ANSWER: | 107 | If you receive a UHID_GET_REPORT request you must answer with this request. |
120 | If you receive a UHID_FEATURE request you must answer with this request. You | 108 | You must copy the "id" field from the request into the answer. Set the "err" |
121 | must copy the "id" field from the request into the answer. Set the "err" field | 109 | field to 0 if no error occurred or to EIO if an I/O error occurred. |
122 | to 0 if no error occurred or to EIO if an I/O error occurred. | ||
123 | If "err" is 0 then you should fill the buffer of the answer with the results | 110 | If "err" is 0 then you should fill the buffer of the answer with the results |
124 | of the feature request and set "size" correspondingly. | 111 | of the GET_REPORT request and set "size" correspondingly. |
112 | |||
113 | UHID_SET_REPORT_REPLY: | ||
114 | This is the SET_REPORT equivalent of UHID_GET_REPORT_REPLY. Unlike GET_REPORT, | ||
115 | SET_REPORT never returns a data buffer, therefore, it's sufficient to set the | ||
116 | "id" and "err" fields correctly. | ||
125 | 117 | ||
126 | read() | 118 | read() |
127 | ------ | 119 | ------ |
128 | read() will return a queued output report. These output reports can be of type | 120 | read() will return a queued output report. No reaction is required to any of |
129 | UHID_START, UHID_STOP, UHID_OPEN, UHID_CLOSE, UHID_OUTPUT or UHID_OUTPUT_EV. No | 121 | them but you should handle them according to your needs. |
130 | reaction is required to any of them but you should handle them according to your | ||
131 | needs. Only UHID_OUTPUT and UHID_OUTPUT_EV have payloads. | ||
132 | 122 | ||
133 | UHID_START: | 123 | UHID_START: |
134 | This is sent when the HID device is started. Consider this as an answer to | 124 | This is sent when the HID device is started. Consider this as an answer to |
135 | UHID_CREATE. This is always the first event that is sent. | 125 | UHID_CREATE2. This is always the first event that is sent. Note that this |
126 | event might not be available immediately after write(UHID_CREATE2) returns. | ||
127 | Device drivers might required delayed setups. | ||
128 | This event contains a payload of type uhid_start_req. The "dev_flags" field | ||
129 | describes special behaviors of a device. The following flags are defined: | ||
130 | UHID_DEV_NUMBERED_FEATURE_REPORTS: | ||
131 | UHID_DEV_NUMBERED_OUTPUT_REPORTS: | ||
132 | UHID_DEV_NUMBERED_INPUT_REPORTS: | ||
133 | Each of these flags defines whether a given report-type uses numbered | ||
134 | reports. If numbered reports are used for a type, all messages from | ||
135 | the kernel already have the report-number as prefix. Otherwise, no | ||
136 | prefix is added by the kernel. | ||
137 | For messages sent by user-space to the kernel, you must adjust the | ||
138 | prefixes according to these flags. | ||
136 | 139 | ||
137 | UHID_STOP: | 140 | UHID_STOP: |
138 | This is sent when the HID device is stopped. Consider this as an answer to | 141 | This is sent when the HID device is stopped. Consider this as an answer to |
139 | UHID_DESTROY. | 142 | UHID_DESTROY. |
140 | If the kernel HID device driver closes the device manually (that is, you | 143 | If you didn't destroy your device via UHID_DESTROY, but the kernel sends an |
141 | didn't send UHID_DESTROY) then you should consider this device closed and send | 144 | UHID_STOP event, this should usually be ignored. It means that the kernel |
142 | an UHID_DESTROY event. You may want to reregister your device, though. This is | 145 | reloaded/changed the device driver loaded on your HID device (or some other |
143 | always the last message that is sent to you unless you reopen the device with | 146 | maintenance actions happened). |
144 | UHID_CREATE. | 147 | You can usually ignored any UHID_STOP events safely. |
145 | 148 | ||
146 | UHID_OPEN: | 149 | UHID_OPEN: |
147 | This is sent when the HID device is opened. That is, the data that the HID | 150 | This is sent when the HID device is opened. That is, the data that the HID |
148 | device provides is read by some other process. You may ignore this event but | 151 | device provides is read by some other process. You may ignore this event but |
149 | it is useful for power-management. As long as you haven't received this event | 152 | it is useful for power-management. As long as you haven't received this event |
150 | there is actually no other process that reads your data so there is no need to | 153 | there is actually no other process that reads your data so there is no need to |
151 | send UHID_INPUT events to the kernel. | 154 | send UHID_INPUT2 events to the kernel. |
152 | 155 | ||
153 | UHID_CLOSE: | 156 | UHID_CLOSE: |
154 | This is sent when there are no more processes which read the HID data. It is | 157 | This is sent when there are no more processes which read the HID data. It is |
@@ -156,27 +159,29 @@ needs. Only UHID_OUTPUT and UHID_OUTPUT_EV have payloads. | |||
156 | 159 | ||
157 | UHID_OUTPUT: | 160 | UHID_OUTPUT: |
158 | This is sent if the HID device driver wants to send raw data to the I/O | 161 | This is sent if the HID device driver wants to send raw data to the I/O |
159 | device. You should read the payload and forward it to the device. The payload | 162 | device on the interrupt channel. You should read the payload and forward it to |
160 | is of type "struct uhid_data_req". | 163 | the device. The payload is of type "struct uhid_data_req". |
161 | This may be received even though you haven't received UHID_OPEN, yet. | 164 | This may be received even though you haven't received UHID_OPEN, yet. |
162 | 165 | ||
163 | UHID_OUTPUT_EV (obsolete): | 166 | UHID_GET_REPORT: |
164 | Same as UHID_OUTPUT but this contains a "struct input_event" as payload. This | 167 | This event is sent if the kernel driver wants to perform a GET_REPORT request |
165 | is called for force-feedback, LED or similar events which are received through | 168 | on the control channeld as described in the HID specs. The report-type and |
166 | an input device by the HID subsystem. You should convert this into raw reports | 169 | report-number are available in the payload. |
167 | and send them to your device similar to events of type UHID_OUTPUT. | 170 | The kernel serializes GET_REPORT requests so there will never be two in |
168 | This is no longer sent by newer kernels. Instead, HID core converts it into a | 171 | parallel. However, if you fail to respond with a UHID_GET_REPORT_REPLY, the |
169 | raw output report and sends it via UHID_OUTPUT. | 172 | request might silently time out. |
170 | 173 | Once you read a GET_REPORT request, you shall forward it to the hid device and | |
171 | UHID_FEATURE: | 174 | remember the "id" field in the payload. Once your hid device responds to the |
172 | This event is sent if the kernel driver wants to perform a feature request as | 175 | GET_REPORT (or if it fails), you must send a UHID_GET_REPORT_REPLY to the |
173 | described in the HID specs. The report-type and report-number are available in | 176 | kernel with the exact same "id" as in the request. If the request already |
174 | the payload. | 177 | timed out, the kernel will ignore the response silently. The "id" field is |
175 | The kernel serializes feature requests so there will never be two in parallel. | 178 | never re-used, so conflicts cannot happen. |
176 | However, if you fail to respond with a UHID_FEATURE_ANSWER in a time-span of 5 | 179 | |
177 | seconds, then the requests will be dropped and a new one might be sent. | 180 | UHID_SET_REPORT: |
178 | Therefore, the payload also contains an "id" field that identifies every | 181 | This is the SET_REPORT equivalent of UHID_GET_REPORT. On receipt, you shall |
179 | request. | 182 | send a SET_REPORT request to your hid device. Once it replies, you must tell |
180 | 183 | the kernel about it via UHID_SET_REPORT_REPLY. | |
181 | Document by: | 184 | The same restrictions as for UHID_GET_REPORT apply. |
182 | David Herrmann <dh.herrmann@googlemail.com> | 185 | |
186 | ---------------------------------------------------- | ||
187 | Written 2012, David Herrmann <dh.herrmann@gmail.com> | ||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index c18d5d71062d..f42df4dd58d2 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -530,6 +530,17 @@ config PANTHERLORD_FF | |||
530 | Say Y here if you have a PantherLord/GreenAsia based game controller | 530 | Say Y here if you have a PantherLord/GreenAsia based game controller |
531 | or adapter and want to enable force feedback support for it. | 531 | or adapter and want to enable force feedback support for it. |
532 | 532 | ||
533 | config HID_PENMOUNT | ||
534 | tristate "Penmount touch device" | ||
535 | depends on USB_HID | ||
536 | ---help--- | ||
537 | This selects a driver for the PenMount 6000 touch controller. | ||
538 | |||
539 | The driver works around a problem in the report descript allowing | ||
540 | the userspace to touch events instead of mouse events. | ||
541 | |||
542 | Say Y here if you have a Penmount based touch controller. | ||
543 | |||
533 | config HID_PETALYNX | 544 | config HID_PETALYNX |
534 | tristate "Petalynx Maxter remote control" | 545 | tristate "Petalynx Maxter remote control" |
535 | depends on HID | 546 | depends on HID |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 4dbac7f8530c..e2850d8af9ca 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -71,6 +71,7 @@ obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o | |||
71 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o | 71 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o |
72 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o | 72 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o |
73 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o | 73 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o |
74 | obj-$(CONFIG_HID_PENMOUNT) += hid-penmount.o | ||
74 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o | 75 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o |
75 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o | 76 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o |
76 | hid-picolcd-y += hid-picolcd_core.o | 77 | hid-picolcd-y += hid-picolcd_core.o |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 12b6e67d9de0..73bd9e2e42bc 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -52,7 +52,7 @@ EXPORT_SYMBOL_GPL(hid_debug); | |||
52 | 52 | ||
53 | static int hid_ignore_special_drivers = 0; | 53 | static int hid_ignore_special_drivers = 0; |
54 | module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600); | 54 | module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600); |
55 | MODULE_PARM_DESC(debug, "Ignore any special drivers and handle all devices by generic driver"); | 55 | MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle all devices by generic driver"); |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * Register a new report for a device. | 58 | * Register a new report for a device. |
@@ -1591,6 +1591,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | |||
1591 | if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) | 1591 | if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) |
1592 | hdev->claimed |= HID_CLAIMED_HIDRAW; | 1592 | hdev->claimed |= HID_CLAIMED_HIDRAW; |
1593 | 1593 | ||
1594 | if (connect_mask & HID_CONNECT_DRIVER) | ||
1595 | hdev->claimed |= HID_CLAIMED_DRIVER; | ||
1596 | |||
1594 | /* Drivers with the ->raw_event callback set are not required to connect | 1597 | /* Drivers with the ->raw_event callback set are not required to connect |
1595 | * to any other listener. */ | 1598 | * to any other listener. */ |
1596 | if (!hdev->claimed && !hdev->driver->raw_event) { | 1599 | if (!hdev->claimed && !hdev->driver->raw_event) { |
@@ -1793,6 +1796,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1793 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) }, | 1796 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) }, |
1794 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) }, | 1797 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) }, |
1795 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, | 1798 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, |
1799 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) }, | ||
1796 | { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) }, | 1800 | { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) }, |
1797 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, | 1801 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, |
1798 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, | 1802 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, |
@@ -1880,6 +1884,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1880 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, | 1884 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, |
1881 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, | 1885 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, |
1882 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1886 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
1887 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, | ||
1883 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1888 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1884 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, | 1889 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, |
1885 | #if IS_ENABLED(CONFIG_HID_ROCCAT) | 1890 | #if IS_ENABLED(CONFIG_HID_ROCCAT) |
diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c index d60fbd0adc0c..78b3a0c76775 100644 --- a/drivers/hid/hid-holtek-mouse.c +++ b/drivers/hid/hid-holtek-mouse.c | |||
@@ -29,6 +29,7 @@ | |||
29 | * and Zalman ZM-GM1 | 29 | * and Zalman ZM-GM1 |
30 | * - USB ID 04d9:a081, sold as SHARKOON DarkGlider Gaming mouse | 30 | * - USB ID 04d9:a081, sold as SHARKOON DarkGlider Gaming mouse |
31 | * - USB ID 04d9:a072, sold as LEETGION Hellion Gaming Mouse | 31 | * - USB ID 04d9:a072, sold as LEETGION Hellion Gaming Mouse |
32 | * - USB ID 04d9:a0c2, sold as ETEKCITY Scroll T-140 Gaming Mouse | ||
32 | */ | 33 | */ |
33 | 34 | ||
34 | static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 35 | static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
@@ -42,6 +43,7 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
42 | switch (hdev->product) { | 43 | switch (hdev->product) { |
43 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067: | 44 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067: |
44 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072: | 45 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072: |
46 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2: | ||
45 | if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f | 47 | if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f |
46 | && rdesc[120] == 0xff && rdesc[121] == 0x7f) { | 48 | && rdesc[120] == 0xff && rdesc[121] == 0x7f) { |
47 | hid_info(hdev, "Fixing up report descriptor\n"); | 49 | hid_info(hdev, "Fixing up report descriptor\n"); |
@@ -74,6 +76,8 @@ static const struct hid_device_id holtek_mouse_devices[] = { | |||
74 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) }, | 76 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) }, |
75 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, | 77 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, |
76 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, | 78 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, |
79 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, | ||
80 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) }, | ||
77 | { } | 81 | { } |
78 | }; | 82 | }; |
79 | MODULE_DEVICE_TABLE(hid, holtek_mouse_devices); | 83 | MODULE_DEVICE_TABLE(hid, holtek_mouse_devices); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 25cd674d6064..cd9c9e96cf0e 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -296,6 +296,9 @@ | |||
296 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 | 296 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 |
297 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 | 297 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 |
298 | 298 | ||
299 | #define USB_VENDOR_ID_ELAN 0x04f3 | ||
300 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089 | ||
301 | |||
299 | #define USB_VENDOR_ID_ELECOM 0x056e | 302 | #define USB_VENDOR_ID_ELECOM 0x056e |
300 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | 303 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 |
301 | 304 | ||
@@ -479,6 +482,7 @@ | |||
479 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 0xa070 | 482 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 0xa070 |
480 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072 | 483 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072 |
481 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081 | 484 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081 |
485 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2 0xa0c2 | ||
482 | #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096 | 486 | #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096 |
483 | 487 | ||
484 | #define USB_VENDOR_ID_IMATION 0x0718 | 488 | #define USB_VENDOR_ID_IMATION 0x0718 |
@@ -722,6 +726,7 @@ | |||
722 | #define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 | 726 | #define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 |
723 | #define USB_DEVICE_ID_PENMOUNT_1610 0x1610 | 727 | #define USB_DEVICE_ID_PENMOUNT_1610 0x1610 |
724 | #define USB_DEVICE_ID_PENMOUNT_1640 0x1640 | 728 | #define USB_DEVICE_ID_PENMOUNT_1640 0x1640 |
729 | #define USB_DEVICE_ID_PENMOUNT_6000 0x6000 | ||
725 | 730 | ||
726 | #define USB_VENDOR_ID_PETALYNX 0x18b1 | 731 | #define USB_VENDOR_ID_PETALYNX 0x18b1 |
727 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 | 732 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 |
@@ -733,6 +738,8 @@ | |||
733 | #define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff | 738 | #define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff |
734 | 739 | ||
735 | #define USB_VENDOR_ID_PIXART 0x093a | 740 | #define USB_VENDOR_ID_PIXART 0x093a |
741 | #define USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2 0x0137 | ||
742 | #define USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE 0x2510 | ||
736 | #define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN 0x8001 | 743 | #define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN 0x8001 |
737 | #define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1 0x8002 | 744 | #define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1 0x8002 |
738 | #define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2 0x8003 | 745 | #define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2 0x8003 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2619f7f4517a..2df7fddbd119 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -599,6 +599,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
599 | /* These usage IDs map directly to the usage codes. */ | 599 | /* These usage IDs map directly to the usage codes. */ |
600 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: | 600 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: |
601 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: | 601 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: |
602 | if (field->flags & HID_MAIN_ITEM_RELATIVE) | ||
603 | map_rel(usage->hid & 0xf); | ||
604 | else | ||
605 | map_abs_clear(usage->hid & 0xf); | ||
606 | break; | ||
607 | |||
602 | case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: | 608 | case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: |
603 | if (field->flags & HID_MAIN_ITEM_RELATIVE) | 609 | if (field->flags & HID_MAIN_ITEM_RELATIVE) |
604 | map_rel(usage->hid & 0xf); | 610 | map_rel(usage->hid & 0xf); |
diff --git a/drivers/hid/hid-penmount.c b/drivers/hid/hid-penmount.c new file mode 100644 index 000000000000..c11dce85cd18 --- /dev/null +++ b/drivers/hid/hid-penmount.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * HID driver for PenMount touchscreens | ||
3 | * | ||
4 | * Copyright (c) 2014 Christian Gmeiner <christian.gmeiner <at> gmail.com> | ||
5 | * | ||
6 | * based on hid-penmount copyrighted by | ||
7 | * PenMount Touch Solutions <penmount <at> seed.net.tw> | ||
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/module.h> | ||
18 | #include <linux/hid.h> | ||
19 | #include "hid-ids.h" | ||
20 | |||
21 | static int penmount_input_mapping(struct hid_device *hdev, | ||
22 | struct hid_input *hi, struct hid_field *field, | ||
23 | struct hid_usage *usage, unsigned long **bit, int *max) | ||
24 | { | ||
25 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { | ||
26 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
27 | return 1; | ||
28 | } | ||
29 | |||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static const struct hid_device_id penmount_devices[] = { | ||
34 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, | ||
35 | { } | ||
36 | }; | ||
37 | MODULE_DEVICE_TABLE(hid, penmount_devices); | ||
38 | |||
39 | static struct hid_driver penmount_driver = { | ||
40 | .name = "hid-penmount", | ||
41 | .id_table = penmount_devices, | ||
42 | .input_mapping = penmount_input_mapping, | ||
43 | }; | ||
44 | |||
45 | module_hid_driver(penmount_driver); | ||
46 | |||
47 | MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>"); | ||
48 | MODULE_DESCRIPTION("PenMount HID TouchScreen driver"); | ||
49 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c index 020df3c2e8b4..c1b29a9eb41a 100644 --- a/drivers/hid/hid-picolcd_core.c +++ b/drivers/hid/hid-picolcd_core.c | |||
@@ -351,8 +351,8 @@ static int picolcd_raw_event(struct hid_device *hdev, | |||
351 | return 1; | 351 | return 1; |
352 | 352 | ||
353 | if (size > 64) { | 353 | if (size > 64) { |
354 | hid_warn(hdev, "invalid size value (%d) for picolcd raw event\n", | 354 | hid_warn(hdev, "invalid size value (%d) for picolcd raw event (%d)\n", |
355 | size); | 355 | size, report->id); |
356 | return 0; | 356 | return 0; |
357 | } | 357 | } |
358 | 358 | ||
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 8389e8109218..3cccff73b9b9 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
@@ -320,10 +320,7 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data, | |||
320 | int offset; | 320 | int offset; |
321 | int i; | 321 | int i; |
322 | 322 | ||
323 | if (size < hdata->f11.report_size) | 323 | if (!(irq & hdata->f11.irq_mask) || size <= 0) |
324 | return 0; | ||
325 | |||
326 | if (!(irq & hdata->f11.irq_mask)) | ||
327 | return 0; | 324 | return 0; |
328 | 325 | ||
329 | offset = (hdata->max_fingers >> 2) + 1; | 326 | offset = (hdata->max_fingers >> 2) + 1; |
@@ -332,9 +329,19 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data, | |||
332 | int fs_bit_position = (i & 0x3) << 1; | 329 | int fs_bit_position = (i & 0x3) << 1; |
333 | int finger_state = (data[fs_byte_position] >> fs_bit_position) & | 330 | int finger_state = (data[fs_byte_position] >> fs_bit_position) & |
334 | 0x03; | 331 | 0x03; |
332 | int position = offset + 5 * i; | ||
333 | |||
334 | if (position + 5 > size) { | ||
335 | /* partial report, go on with what we received */ | ||
336 | printk_once(KERN_WARNING | ||
337 | "%s %s: Detected incomplete finger report. Finger reports may occasionally get dropped on this platform.\n", | ||
338 | dev_driver_string(&hdev->dev), | ||
339 | dev_name(&hdev->dev)); | ||
340 | hid_dbg(hdev, "Incomplete finger report\n"); | ||
341 | break; | ||
342 | } | ||
335 | 343 | ||
336 | rmi_f11_process_touch(hdata, i, finger_state, | 344 | rmi_f11_process_touch(hdata, i, finger_state, &data[position]); |
337 | &data[offset + 5 * i]); | ||
338 | } | 345 | } |
339 | input_mt_sync_frame(hdata->input); | 346 | input_mt_sync_frame(hdata->input); |
340 | input_sync(hdata->input); | 347 | input_sync(hdata->input); |
@@ -352,6 +359,11 @@ static int rmi_f30_input_event(struct hid_device *hdev, u8 irq, u8 *data, | |||
352 | if (!(irq & hdata->f30.irq_mask)) | 359 | if (!(irq & hdata->f30.irq_mask)) |
353 | return 0; | 360 | return 0; |
354 | 361 | ||
362 | if (size < (int)hdata->f30.report_size) { | ||
363 | hid_warn(hdev, "Click Button pressed, but the click data is missing\n"); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
355 | for (i = 0; i < hdata->gpio_led_count; i++) { | 367 | for (i = 0; i < hdata->gpio_led_count; i++) { |
356 | if (test_bit(i, &hdata->button_mask)) { | 368 | if (test_bit(i, &hdata->button_mask)) { |
357 | value = (data[i / 8] >> (i & 0x07)) & BIT(0); | 369 | value = (data[i / 8] >> (i & 0x07)) & BIT(0); |
@@ -412,9 +424,29 @@ static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size) | |||
412 | return 1; | 424 | return 1; |
413 | } | 425 | } |
414 | 426 | ||
427 | static int rmi_check_sanity(struct hid_device *hdev, u8 *data, int size) | ||
428 | { | ||
429 | int valid_size = size; | ||
430 | /* | ||
431 | * On the Dell XPS 13 9333, the bus sometimes get confused and fills | ||
432 | * the report with a sentinel value "ff". Synaptics told us that such | ||
433 | * behavior does not comes from the touchpad itself, so we filter out | ||
434 | * such reports here. | ||
435 | */ | ||
436 | |||
437 | while ((data[valid_size - 1] == 0xff) && valid_size > 0) | ||
438 | valid_size--; | ||
439 | |||
440 | return valid_size; | ||
441 | } | ||
442 | |||
415 | static int rmi_raw_event(struct hid_device *hdev, | 443 | static int rmi_raw_event(struct hid_device *hdev, |
416 | struct hid_report *report, u8 *data, int size) | 444 | struct hid_report *report, u8 *data, int size) |
417 | { | 445 | { |
446 | size = rmi_check_sanity(hdev, data, size); | ||
447 | if (size < 2) | ||
448 | return 0; | ||
449 | |||
418 | switch (data[0]) { | 450 | switch (data[0]) { |
419 | case RMI_READ_DATA_REPORT_ID: | 451 | case RMI_READ_DATA_REPORT_ID: |
420 | return rmi_read_data_event(hdev, data, size); | 452 | return rmi_read_data_event(hdev, data, size); |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 2ac25760a9a9..e6d8e18dae97 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -709,6 +709,9 @@ static const struct hid_device_id sensor_hub_devices[] = { | |||
709 | USB_DEVICE_ID_MS_TYPE_COVER_2), | 709 | USB_DEVICE_ID_MS_TYPE_COVER_2), |
710 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | 710 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
711 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, | 711 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, |
712 | USB_DEVICE_ID_STM_HID_SENSOR), | ||
713 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
714 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, | ||
712 | USB_DEVICE_ID_STM_HID_SENSOR_1), | 715 | USB_DEVICE_ID_STM_HID_SENSOR_1), |
713 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | 716 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
714 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS, | 717 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS, |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index c372368e438c..bc4269e559f1 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * HID driver for Sony / PS2 / PS3 BD devices. | 2 | * HID driver for Sony / PS2 / PS3 / PS4 BD devices. |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
@@ -8,6 +8,7 @@ | |||
8 | * Copyright (c) 2012 David Dillow <dave@thedillows.org> | 8 | * Copyright (c) 2012 David Dillow <dave@thedillows.org> |
9 | * Copyright (c) 2006-2013 Jiri Kosina | 9 | * Copyright (c) 2006-2013 Jiri Kosina |
10 | * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> | 10 | * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> |
11 | * Copyright (c) 2014 Frank Praznik <frank.praznik@gmail.com> | ||
11 | */ | 12 | */ |
12 | 13 | ||
13 | /* | 14 | /* |
@@ -176,7 +177,7 @@ static u8 dualshock4_usb_rdesc[] = { | |||
176 | 0x75, 0x06, /* Report Size (6), */ | 177 | 0x75, 0x06, /* Report Size (6), */ |
177 | 0x95, 0x01, /* Report Count (1), */ | 178 | 0x95, 0x01, /* Report Count (1), */ |
178 | 0x15, 0x00, /* Logical Minimum (0), */ | 179 | 0x15, 0x00, /* Logical Minimum (0), */ |
179 | 0x25, 0x7F, /* Logical Maximum (127), */ | 180 | 0x25, 0x3F, /* Logical Maximum (63), */ |
180 | 0x81, 0x02, /* Input (Variable), */ | 181 | 0x81, 0x02, /* Input (Variable), */ |
181 | 0x05, 0x01, /* Usage Page (Desktop), */ | 182 | 0x05, 0x01, /* Usage Page (Desktop), */ |
182 | 0x09, 0x33, /* Usage (Rx), */ | 183 | 0x09, 0x33, /* Usage (Rx), */ |
@@ -200,14 +201,14 @@ static u8 dualshock4_usb_rdesc[] = { | |||
200 | 0x81, 0x02, /* Input (Variable), */ | 201 | 0x81, 0x02, /* Input (Variable), */ |
201 | 0x19, 0x43, /* Usage Minimum (43h), */ | 202 | 0x19, 0x43, /* Usage Minimum (43h), */ |
202 | 0x29, 0x45, /* Usage Maximum (45h), */ | 203 | 0x29, 0x45, /* Usage Maximum (45h), */ |
203 | 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ | 204 | 0x16, 0x00, 0xE0, /* Logical Minimum (-8192), */ |
204 | 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ | 205 | 0x26, 0xFF, 0x1F, /* Logical Maximum (8191), */ |
205 | 0x95, 0x03, /* Report Count (3), */ | 206 | 0x95, 0x03, /* Report Count (3), */ |
206 | 0x81, 0x02, /* Input (Variable), */ | 207 | 0x81, 0x02, /* Input (Variable), */ |
207 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | 208 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ |
208 | 0x09, 0x21, /* Usage (21h), */ | 209 | 0x09, 0x21, /* Usage (21h), */ |
209 | 0x15, 0x00, /* Logical Minimum (0), */ | 210 | 0x15, 0x00, /* Logical Minimum (0), */ |
210 | 0x25, 0xFF, /* Logical Maximum (255), */ | 211 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ |
211 | 0x75, 0x08, /* Report Size (8), */ | 212 | 0x75, 0x08, /* Report Size (8), */ |
212 | 0x95, 0x27, /* Report Count (39), */ | 213 | 0x95, 0x27, /* Report Count (39), */ |
213 | 0x81, 0x02, /* Input (Variable), */ | 214 | 0x81, 0x02, /* Input (Variable), */ |
@@ -395,11 +396,11 @@ static u8 dualshock4_usb_rdesc[] = { | |||
395 | 396 | ||
396 | /* | 397 | /* |
397 | * The default behavior of the Dualshock 4 is to send reports using report | 398 | * The default behavior of the Dualshock 4 is to send reports using report |
398 | * type 1 when running over Bluetooth. However, as soon as it receives a | 399 | * type 1 when running over Bluetooth. However, when feature report 2 is |
399 | * report of type 17 to set the LEDs or rumble it starts returning it's state | 400 | * requested during the controller initialization it starts sending input |
400 | * in report 17 instead of 1. Since report 17 is undefined in the default HID | 401 | * reports in report 17. Since report 17 is undefined in the default HID |
401 | * descriptor the button and axis definitions must be moved to report 17 or | 402 | * descriptor the button and axis definitions must be moved to report 17 or |
402 | * the HID layer won't process the received input once a report is sent. | 403 | * the HID layer won't process the received input. |
403 | */ | 404 | */ |
404 | static u8 dualshock4_bt_rdesc[] = { | 405 | static u8 dualshock4_bt_rdesc[] = { |
405 | 0x05, 0x01, /* Usage Page (Desktop), */ | 406 | 0x05, 0x01, /* Usage Page (Desktop), */ |
@@ -509,8 +510,8 @@ static u8 dualshock4_bt_rdesc[] = { | |||
509 | 0x81, 0x02, /* Input (Variable), */ | 510 | 0x81, 0x02, /* Input (Variable), */ |
510 | 0x19, 0x43, /* Usage Minimum (43h), */ | 511 | 0x19, 0x43, /* Usage Minimum (43h), */ |
511 | 0x29, 0x45, /* Usage Maximum (45h), */ | 512 | 0x29, 0x45, /* Usage Maximum (45h), */ |
512 | 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ | 513 | 0x16, 0x00, 0xE0, /* Logical Minimum (-8192), */ |
513 | 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ | 514 | 0x26, 0xFF, 0x1F, /* Logical Maximum (8191), */ |
514 | 0x95, 0x03, /* Report Count (3), */ | 515 | 0x95, 0x03, /* Report Count (3), */ |
515 | 0x81, 0x02, /* Input (Variable), */ | 516 | 0x81, 0x02, /* Input (Variable), */ |
516 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | 517 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ |
@@ -935,12 +936,13 @@ static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) | |||
935 | if (rd[30] >= 0xee) { | 936 | if (rd[30] >= 0xee) { |
936 | battery_capacity = 100; | 937 | battery_capacity = 100; |
937 | battery_charging = !(rd[30] & 0x01); | 938 | battery_charging = !(rd[30] & 0x01); |
939 | cable_state = 1; | ||
938 | } else { | 940 | } else { |
939 | __u8 index = rd[30] <= 5 ? rd[30] : 5; | 941 | __u8 index = rd[30] <= 5 ? rd[30] : 5; |
940 | battery_capacity = sixaxis_battery_capacity[index]; | 942 | battery_capacity = sixaxis_battery_capacity[index]; |
941 | battery_charging = 0; | 943 | battery_charging = 0; |
944 | cable_state = 0; | ||
942 | } | 945 | } |
943 | cable_state = !(rd[31] & 0x04); | ||
944 | 946 | ||
945 | spin_lock_irqsave(&sc->lock, flags); | 947 | spin_lock_irqsave(&sc->lock, flags); |
946 | sc->cable_state = cable_state; | 948 | sc->cable_state = cable_state; |
@@ -1082,6 +1084,38 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
1082 | return 0; | 1084 | return 0; |
1083 | } | 1085 | } |
1084 | 1086 | ||
1087 | static int sony_register_touchpad(struct hid_input *hi, int touch_count, | ||
1088 | int w, int h) | ||
1089 | { | ||
1090 | struct input_dev *input_dev = hi->input; | ||
1091 | int ret; | ||
1092 | |||
1093 | ret = input_mt_init_slots(input_dev, touch_count, 0); | ||
1094 | if (ret < 0) | ||
1095 | return ret; | ||
1096 | |||
1097 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0); | ||
1098 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0); | ||
1099 | |||
1100 | return 0; | ||
1101 | } | ||
1102 | |||
1103 | static void sony_input_configured(struct hid_device *hdev, | ||
1104 | struct hid_input *hidinput) | ||
1105 | { | ||
1106 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
1107 | |||
1108 | /* | ||
1109 | * The Dualshock 4 touchpad supports 2 touches and has a | ||
1110 | * resolution of 1920x942 (44.86 dots/mm). | ||
1111 | */ | ||
1112 | if (sc->quirks & DUALSHOCK4_CONTROLLER) { | ||
1113 | if (sony_register_touchpad(hidinput, 2, 1920, 942) != 0) | ||
1114 | hid_err(sc->hdev, | ||
1115 | "Unable to initialize multi-touch slots\n"); | ||
1116 | } | ||
1117 | } | ||
1118 | |||
1085 | /* | 1119 | /* |
1086 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | 1120 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller |
1087 | * to "operational". Without this, the ps3 controller will not report any | 1121 | * to "operational". Without this, the ps3 controller will not report any |
@@ -1654,26 +1688,6 @@ static void sony_battery_remove(struct sony_sc *sc) | |||
1654 | sc->battery.name = NULL; | 1688 | sc->battery.name = NULL; |
1655 | } | 1689 | } |
1656 | 1690 | ||
1657 | static int sony_register_touchpad(struct sony_sc *sc, int touch_count, | ||
1658 | int w, int h) | ||
1659 | { | ||
1660 | struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, | ||
1661 | struct hid_input, list); | ||
1662 | struct input_dev *input_dev = hidinput->input; | ||
1663 | int ret; | ||
1664 | |||
1665 | ret = input_mt_init_slots(input_dev, touch_count, 0); | ||
1666 | if (ret < 0) { | ||
1667 | hid_err(sc->hdev, "Unable to initialize multi-touch slots\n"); | ||
1668 | return ret; | ||
1669 | } | ||
1670 | |||
1671 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0); | ||
1672 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0); | ||
1673 | |||
1674 | return 0; | ||
1675 | } | ||
1676 | |||
1677 | /* | 1691 | /* |
1678 | * If a controller is plugged in via USB while already connected via Bluetooth | 1692 | * If a controller is plugged in via USB while already connected via Bluetooth |
1679 | * it will show up as two devices. A global list of connected controllers and | 1693 | * it will show up as two devices. A global list of connected controllers and |
@@ -1923,13 +1937,6 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1923 | goto err_stop; | 1937 | goto err_stop; |
1924 | } | 1938 | } |
1925 | } | 1939 | } |
1926 | /* | ||
1927 | * The Dualshock 4 touchpad supports 2 touches and has a | ||
1928 | * resolution of 1920x940. | ||
1929 | */ | ||
1930 | ret = sony_register_touchpad(sc, 2, 1920, 940); | ||
1931 | if (ret < 0) | ||
1932 | goto err_stop; | ||
1933 | 1940 | ||
1934 | sony_init_work(sc, dualshock4_state_worker); | 1941 | sony_init_work(sc, dualshock4_state_worker); |
1935 | } else { | 1942 | } else { |
@@ -2037,13 +2044,14 @@ static const struct hid_device_id sony_devices[] = { | |||
2037 | MODULE_DEVICE_TABLE(hid, sony_devices); | 2044 | MODULE_DEVICE_TABLE(hid, sony_devices); |
2038 | 2045 | ||
2039 | static struct hid_driver sony_driver = { | 2046 | static struct hid_driver sony_driver = { |
2040 | .name = "sony", | 2047 | .name = "sony", |
2041 | .id_table = sony_devices, | 2048 | .id_table = sony_devices, |
2042 | .input_mapping = sony_mapping, | 2049 | .input_mapping = sony_mapping, |
2043 | .probe = sony_probe, | 2050 | .input_configured = sony_input_configured, |
2044 | .remove = sony_remove, | 2051 | .probe = sony_probe, |
2045 | .report_fixup = sony_report_fixup, | 2052 | .remove = sony_remove, |
2046 | .raw_event = sony_raw_event | 2053 | .report_fixup = sony_report_fixup, |
2054 | .raw_event = sony_raw_event | ||
2047 | }; | 2055 | }; |
2048 | 2056 | ||
2049 | static int __init sony_init(void) | 2057 | static int __init sony_init(void) |
diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 134be89b15ea..b95d3978c272 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c | |||
@@ -208,10 +208,10 @@ unregister_red: | |||
208 | 208 | ||
209 | static void thingm_remove_rgb(struct thingm_rgb *rgb) | 209 | static void thingm_remove_rgb(struct thingm_rgb *rgb) |
210 | { | 210 | { |
211 | flush_work(&rgb->work); | ||
212 | led_classdev_unregister(&rgb->red.ldev); | 211 | led_classdev_unregister(&rgb->red.ldev); |
213 | led_classdev_unregister(&rgb->green.ldev); | 212 | led_classdev_unregister(&rgb->green.ldev); |
214 | led_classdev_unregister(&rgb->blue.ldev); | 213 | led_classdev_unregister(&rgb->blue.ldev); |
214 | flush_work(&rgb->work); | ||
215 | } | 215 | } |
216 | 216 | ||
217 | static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) | 217 | static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) |
@@ -250,6 +250,7 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
250 | 250 | ||
251 | if (!tdev->fwinfo) { | 251 | if (!tdev->fwinfo) { |
252 | hid_err(hdev, "unsupported firmware %c\n", tdev->version.major); | 252 | hid_err(hdev, "unsupported firmware %c\n", tdev->version.major); |
253 | err = -ENODEV; | ||
253 | goto stop; | 254 | goto stop; |
254 | } | 255 | } |
255 | 256 | ||
@@ -286,10 +287,10 @@ static void thingm_remove(struct hid_device *hdev) | |||
286 | struct thingm_device *tdev = hid_get_drvdata(hdev); | 287 | struct thingm_device *tdev = hid_get_drvdata(hdev); |
287 | int i; | 288 | int i; |
288 | 289 | ||
290 | hid_hw_stop(hdev); | ||
291 | |||
289 | for (i = 0; i < tdev->fwinfo->numrgb; ++i) | 292 | for (i = 0; i < tdev->fwinfo->numrgb; ++i) |
290 | thingm_remove_rgb(tdev->rgb + i); | 293 | thingm_remove_rgb(tdev->rgb + i); |
291 | |||
292 | hid_hw_stop(hdev); | ||
293 | } | 294 | } |
294 | 295 | ||
295 | static const struct hid_device_id thingm_table[] = { | 296 | static const struct hid_device_id thingm_table[] = { |
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 0cb92e347258..e094c572b86e 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
@@ -44,10 +44,12 @@ struct uhid_device { | |||
44 | __u8 tail; | 44 | __u8 tail; |
45 | struct uhid_event *outq[UHID_BUFSIZE]; | 45 | struct uhid_event *outq[UHID_BUFSIZE]; |
46 | 46 | ||
47 | /* blocking GET_REPORT support; state changes protected by qlock */ | ||
47 | struct mutex report_lock; | 48 | struct mutex report_lock; |
48 | wait_queue_head_t report_wait; | 49 | wait_queue_head_t report_wait; |
49 | atomic_t report_done; | 50 | bool report_running; |
50 | atomic_t report_id; | 51 | u32 report_id; |
52 | u32 report_type; | ||
51 | struct uhid_event report_buf; | 53 | struct uhid_event report_buf; |
52 | }; | 54 | }; |
53 | 55 | ||
@@ -90,8 +92,27 @@ static int uhid_queue_event(struct uhid_device *uhid, __u32 event) | |||
90 | static int uhid_hid_start(struct hid_device *hid) | 92 | static int uhid_hid_start(struct hid_device *hid) |
91 | { | 93 | { |
92 | struct uhid_device *uhid = hid->driver_data; | 94 | struct uhid_device *uhid = hid->driver_data; |
95 | struct uhid_event *ev; | ||
96 | unsigned long flags; | ||
97 | |||
98 | ev = kzalloc(sizeof(*ev), GFP_KERNEL); | ||
99 | if (!ev) | ||
100 | return -ENOMEM; | ||
101 | |||
102 | ev->type = UHID_START; | ||
93 | 103 | ||
94 | return uhid_queue_event(uhid, UHID_START); | 104 | if (hid->report_enum[HID_FEATURE_REPORT].numbered) |
105 | ev->u.start.dev_flags |= UHID_DEV_NUMBERED_FEATURE_REPORTS; | ||
106 | if (hid->report_enum[HID_OUTPUT_REPORT].numbered) | ||
107 | ev->u.start.dev_flags |= UHID_DEV_NUMBERED_OUTPUT_REPORTS; | ||
108 | if (hid->report_enum[HID_INPUT_REPORT].numbered) | ||
109 | ev->u.start.dev_flags |= UHID_DEV_NUMBERED_INPUT_REPORTS; | ||
110 | |||
111 | spin_lock_irqsave(&uhid->qlock, flags); | ||
112 | uhid_queue(uhid, ev); | ||
113 | spin_unlock_irqrestore(&uhid->qlock, flags); | ||
114 | |||
115 | return 0; | ||
95 | } | 116 | } |
96 | 117 | ||
97 | static void uhid_hid_stop(struct hid_device *hid) | 118 | static void uhid_hid_stop(struct hid_device *hid) |
@@ -123,87 +144,169 @@ static int uhid_hid_parse(struct hid_device *hid) | |||
123 | return hid_parse_report(hid, uhid->rd_data, uhid->rd_size); | 144 | return hid_parse_report(hid, uhid->rd_data, uhid->rd_size); |
124 | } | 145 | } |
125 | 146 | ||
126 | static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, | 147 | /* must be called with report_lock held */ |
127 | __u8 *buf, size_t count, unsigned char rtype) | 148 | static int __uhid_report_queue_and_wait(struct uhid_device *uhid, |
149 | struct uhid_event *ev, | ||
150 | __u32 *report_id) | ||
151 | { | ||
152 | unsigned long flags; | ||
153 | int ret; | ||
154 | |||
155 | spin_lock_irqsave(&uhid->qlock, flags); | ||
156 | *report_id = ++uhid->report_id; | ||
157 | uhid->report_type = ev->type + 1; | ||
158 | uhid->report_running = true; | ||
159 | uhid_queue(uhid, ev); | ||
160 | spin_unlock_irqrestore(&uhid->qlock, flags); | ||
161 | |||
162 | ret = wait_event_interruptible_timeout(uhid->report_wait, | ||
163 | !uhid->report_running || !uhid->running, | ||
164 | 5 * HZ); | ||
165 | if (!ret || !uhid->running || uhid->report_running) | ||
166 | ret = -EIO; | ||
167 | else if (ret < 0) | ||
168 | ret = -ERESTARTSYS; | ||
169 | else | ||
170 | ret = 0; | ||
171 | |||
172 | uhid->report_running = false; | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | static void uhid_report_wake_up(struct uhid_device *uhid, u32 id, | ||
178 | const struct uhid_event *ev) | ||
179 | { | ||
180 | unsigned long flags; | ||
181 | |||
182 | spin_lock_irqsave(&uhid->qlock, flags); | ||
183 | |||
184 | /* id for old report; drop it silently */ | ||
185 | if (uhid->report_type != ev->type || uhid->report_id != id) | ||
186 | goto unlock; | ||
187 | if (!uhid->report_running) | ||
188 | goto unlock; | ||
189 | |||
190 | memcpy(&uhid->report_buf, ev, sizeof(*ev)); | ||
191 | uhid->report_running = false; | ||
192 | wake_up_interruptible(&uhid->report_wait); | ||
193 | |||
194 | unlock: | ||
195 | spin_unlock_irqrestore(&uhid->qlock, flags); | ||
196 | } | ||
197 | |||
198 | static int uhid_hid_get_report(struct hid_device *hid, unsigned char rnum, | ||
199 | u8 *buf, size_t count, u8 rtype) | ||
128 | { | 200 | { |
129 | struct uhid_device *uhid = hid->driver_data; | 201 | struct uhid_device *uhid = hid->driver_data; |
130 | __u8 report_type; | 202 | struct uhid_get_report_reply_req *req; |
131 | struct uhid_event *ev; | 203 | struct uhid_event *ev; |
132 | unsigned long flags; | ||
133 | int ret; | 204 | int ret; |
134 | size_t uninitialized_var(len); | ||
135 | struct uhid_feature_answer_req *req; | ||
136 | 205 | ||
137 | if (!uhid->running) | 206 | if (!uhid->running) |
138 | return -EIO; | 207 | return -EIO; |
139 | 208 | ||
140 | switch (rtype) { | 209 | ev = kzalloc(sizeof(*ev), GFP_KERNEL); |
141 | case HID_FEATURE_REPORT: | 210 | if (!ev) |
142 | report_type = UHID_FEATURE_REPORT; | 211 | return -ENOMEM; |
143 | break; | 212 | |
144 | case HID_OUTPUT_REPORT: | 213 | ev->type = UHID_GET_REPORT; |
145 | report_type = UHID_OUTPUT_REPORT; | 214 | ev->u.get_report.rnum = rnum; |
146 | break; | 215 | ev->u.get_report.rtype = rtype; |
147 | case HID_INPUT_REPORT: | ||
148 | report_type = UHID_INPUT_REPORT; | ||
149 | break; | ||
150 | default: | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | 216 | ||
154 | ret = mutex_lock_interruptible(&uhid->report_lock); | 217 | ret = mutex_lock_interruptible(&uhid->report_lock); |
155 | if (ret) | 218 | if (ret) { |
219 | kfree(ev); | ||
156 | return ret; | 220 | return ret; |
221 | } | ||
157 | 222 | ||
158 | ev = kzalloc(sizeof(*ev), GFP_KERNEL); | 223 | /* this _always_ takes ownership of @ev */ |
159 | if (!ev) { | 224 | ret = __uhid_report_queue_and_wait(uhid, ev, &ev->u.get_report.id); |
160 | ret = -ENOMEM; | 225 | if (ret) |
161 | goto unlock; | 226 | goto unlock; |
227 | |||
228 | req = &uhid->report_buf.u.get_report_reply; | ||
229 | if (req->err) { | ||
230 | ret = -EIO; | ||
231 | } else { | ||
232 | ret = min3(count, (size_t)req->size, (size_t)UHID_DATA_MAX); | ||
233 | memcpy(buf, req->data, ret); | ||
162 | } | 234 | } |
163 | 235 | ||
164 | spin_lock_irqsave(&uhid->qlock, flags); | 236 | unlock: |
165 | ev->type = UHID_FEATURE; | 237 | mutex_unlock(&uhid->report_lock); |
166 | ev->u.feature.id = atomic_inc_return(&uhid->report_id); | 238 | return ret; |
167 | ev->u.feature.rnum = rnum; | 239 | } |
168 | ev->u.feature.rtype = report_type; | ||
169 | 240 | ||
170 | atomic_set(&uhid->report_done, 0); | 241 | static int uhid_hid_set_report(struct hid_device *hid, unsigned char rnum, |
171 | uhid_queue(uhid, ev); | 242 | const u8 *buf, size_t count, u8 rtype) |
172 | spin_unlock_irqrestore(&uhid->qlock, flags); | 243 | { |
244 | struct uhid_device *uhid = hid->driver_data; | ||
245 | struct uhid_event *ev; | ||
246 | int ret; | ||
173 | 247 | ||
174 | ret = wait_event_interruptible_timeout(uhid->report_wait, | 248 | if (!uhid->running || count > UHID_DATA_MAX) |
175 | atomic_read(&uhid->report_done), 5 * HZ); | 249 | return -EIO; |
176 | |||
177 | /* | ||
178 | * Make sure "uhid->running" is cleared on shutdown before | ||
179 | * "uhid->report_done" is set. | ||
180 | */ | ||
181 | smp_rmb(); | ||
182 | if (!ret || !uhid->running) { | ||
183 | ret = -EIO; | ||
184 | } else if (ret < 0) { | ||
185 | ret = -ERESTARTSYS; | ||
186 | } else { | ||
187 | spin_lock_irqsave(&uhid->qlock, flags); | ||
188 | req = &uhid->report_buf.u.feature_answer; | ||
189 | 250 | ||
190 | if (req->err) { | 251 | ev = kzalloc(sizeof(*ev), GFP_KERNEL); |
191 | ret = -EIO; | 252 | if (!ev) |
192 | } else { | 253 | return -ENOMEM; |
193 | ret = 0; | 254 | |
194 | len = min(count, | 255 | ev->type = UHID_SET_REPORT; |
195 | min_t(size_t, req->size, UHID_DATA_MAX)); | 256 | ev->u.set_report.rnum = rnum; |
196 | memcpy(buf, req->data, len); | 257 | ev->u.set_report.rtype = rtype; |
197 | } | 258 | ev->u.set_report.size = count; |
259 | memcpy(ev->u.set_report.data, buf, count); | ||
198 | 260 | ||
199 | spin_unlock_irqrestore(&uhid->qlock, flags); | 261 | ret = mutex_lock_interruptible(&uhid->report_lock); |
262 | if (ret) { | ||
263 | kfree(ev); | ||
264 | return ret; | ||
200 | } | 265 | } |
201 | 266 | ||
202 | atomic_set(&uhid->report_done, 1); | 267 | /* this _always_ takes ownership of @ev */ |
268 | ret = __uhid_report_queue_and_wait(uhid, ev, &ev->u.set_report.id); | ||
269 | if (ret) | ||
270 | goto unlock; | ||
271 | |||
272 | if (uhid->report_buf.u.set_report_reply.err) | ||
273 | ret = -EIO; | ||
274 | else | ||
275 | ret = count; | ||
203 | 276 | ||
204 | unlock: | 277 | unlock: |
205 | mutex_unlock(&uhid->report_lock); | 278 | mutex_unlock(&uhid->report_lock); |
206 | return ret ? ret : len; | 279 | return ret; |
280 | } | ||
281 | |||
282 | static int uhid_hid_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
283 | __u8 *buf, size_t len, unsigned char rtype, | ||
284 | int reqtype) | ||
285 | { | ||
286 | u8 u_rtype; | ||
287 | |||
288 | switch (rtype) { | ||
289 | case HID_FEATURE_REPORT: | ||
290 | u_rtype = UHID_FEATURE_REPORT; | ||
291 | break; | ||
292 | case HID_OUTPUT_REPORT: | ||
293 | u_rtype = UHID_OUTPUT_REPORT; | ||
294 | break; | ||
295 | case HID_INPUT_REPORT: | ||
296 | u_rtype = UHID_INPUT_REPORT; | ||
297 | break; | ||
298 | default: | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | |||
302 | switch (reqtype) { | ||
303 | case HID_REQ_GET_REPORT: | ||
304 | return uhid_hid_get_report(hid, reportnum, buf, len, u_rtype); | ||
305 | case HID_REQ_SET_REPORT: | ||
306 | return uhid_hid_set_report(hid, reportnum, buf, len, u_rtype); | ||
307 | default: | ||
308 | return -EIO; | ||
309 | } | ||
207 | } | 310 | } |
208 | 311 | ||
209 | static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, | 312 | static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, |
@@ -250,29 +353,14 @@ static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf, | |||
250 | return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT); | 353 | return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT); |
251 | } | 354 | } |
252 | 355 | ||
253 | static int uhid_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
254 | __u8 *buf, size_t len, unsigned char rtype, | ||
255 | int reqtype) | ||
256 | { | ||
257 | switch (reqtype) { | ||
258 | case HID_REQ_GET_REPORT: | ||
259 | return uhid_hid_get_raw(hid, reportnum, buf, len, rtype); | ||
260 | case HID_REQ_SET_REPORT: | ||
261 | /* TODO: implement proper SET_REPORT functionality */ | ||
262 | return -ENOSYS; | ||
263 | default: | ||
264 | return -EIO; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | static struct hid_ll_driver uhid_hid_driver = { | 356 | static struct hid_ll_driver uhid_hid_driver = { |
269 | .start = uhid_hid_start, | 357 | .start = uhid_hid_start, |
270 | .stop = uhid_hid_stop, | 358 | .stop = uhid_hid_stop, |
271 | .open = uhid_hid_open, | 359 | .open = uhid_hid_open, |
272 | .close = uhid_hid_close, | 360 | .close = uhid_hid_close, |
273 | .parse = uhid_hid_parse, | 361 | .parse = uhid_hid_parse, |
362 | .raw_request = uhid_hid_raw_request, | ||
274 | .output_report = uhid_hid_output_report, | 363 | .output_report = uhid_hid_output_report, |
275 | .raw_request = uhid_raw_request, | ||
276 | }; | 364 | }; |
277 | 365 | ||
278 | #ifdef CONFIG_COMPAT | 366 | #ifdef CONFIG_COMPAT |
@@ -363,28 +451,27 @@ static int uhid_event_from_user(const char __user *buffer, size_t len, | |||
363 | } | 451 | } |
364 | #endif | 452 | #endif |
365 | 453 | ||
366 | static int uhid_dev_create(struct uhid_device *uhid, | 454 | static int uhid_dev_create2(struct uhid_device *uhid, |
367 | const struct uhid_event *ev) | 455 | const struct uhid_event *ev) |
368 | { | 456 | { |
369 | struct hid_device *hid; | 457 | struct hid_device *hid; |
458 | size_t rd_size, len; | ||
459 | void *rd_data; | ||
370 | int ret; | 460 | int ret; |
371 | 461 | ||
372 | if (uhid->running) | 462 | if (uhid->running) |
373 | return -EALREADY; | 463 | return -EALREADY; |
374 | 464 | ||
375 | uhid->rd_size = ev->u.create.rd_size; | 465 | rd_size = ev->u.create2.rd_size; |
376 | if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE) | 466 | if (rd_size <= 0 || rd_size > HID_MAX_DESCRIPTOR_SIZE) |
377 | return -EINVAL; | 467 | return -EINVAL; |
378 | 468 | ||
379 | uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL); | 469 | rd_data = kmemdup(ev->u.create2.rd_data, rd_size, GFP_KERNEL); |
380 | if (!uhid->rd_data) | 470 | if (!rd_data) |
381 | return -ENOMEM; | 471 | return -ENOMEM; |
382 | 472 | ||
383 | if (copy_from_user(uhid->rd_data, ev->u.create.rd_data, | 473 | uhid->rd_size = rd_size; |
384 | uhid->rd_size)) { | 474 | uhid->rd_data = rd_data; |
385 | ret = -EFAULT; | ||
386 | goto err_free; | ||
387 | } | ||
388 | 475 | ||
389 | hid = hid_allocate_device(); | 476 | hid = hid_allocate_device(); |
390 | if (IS_ERR(hid)) { | 477 | if (IS_ERR(hid)) { |
@@ -392,19 +479,19 @@ static int uhid_dev_create(struct uhid_device *uhid, | |||
392 | goto err_free; | 479 | goto err_free; |
393 | } | 480 | } |
394 | 481 | ||
395 | strncpy(hid->name, ev->u.create.name, 127); | 482 | len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1; |
396 | hid->name[127] = 0; | 483 | strncpy(hid->name, ev->u.create2.name, len); |
397 | strncpy(hid->phys, ev->u.create.phys, 63); | 484 | len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1; |
398 | hid->phys[63] = 0; | 485 | strncpy(hid->phys, ev->u.create2.phys, len); |
399 | strncpy(hid->uniq, ev->u.create.uniq, 63); | 486 | len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1; |
400 | hid->uniq[63] = 0; | 487 | strncpy(hid->uniq, ev->u.create2.uniq, len); |
401 | 488 | ||
402 | hid->ll_driver = &uhid_hid_driver; | 489 | hid->ll_driver = &uhid_hid_driver; |
403 | hid->bus = ev->u.create.bus; | 490 | hid->bus = ev->u.create2.bus; |
404 | hid->vendor = ev->u.create.vendor; | 491 | hid->vendor = ev->u.create2.vendor; |
405 | hid->product = ev->u.create.product; | 492 | hid->product = ev->u.create2.product; |
406 | hid->version = ev->u.create.version; | 493 | hid->version = ev->u.create2.version; |
407 | hid->country = ev->u.create.country; | 494 | hid->country = ev->u.create2.country; |
408 | hid->driver_data = uhid; | 495 | hid->driver_data = uhid; |
409 | hid->dev.parent = uhid_misc.this_device; | 496 | hid->dev.parent = uhid_misc.this_device; |
410 | 497 | ||
@@ -425,67 +512,34 @@ err_hid: | |||
425 | uhid->running = false; | 512 | uhid->running = false; |
426 | err_free: | 513 | err_free: |
427 | kfree(uhid->rd_data); | 514 | kfree(uhid->rd_data); |
515 | uhid->rd_data = NULL; | ||
516 | uhid->rd_size = 0; | ||
428 | return ret; | 517 | return ret; |
429 | } | 518 | } |
430 | 519 | ||
431 | static int uhid_dev_create2(struct uhid_device *uhid, | 520 | static int uhid_dev_create(struct uhid_device *uhid, |
432 | const struct uhid_event *ev) | 521 | struct uhid_event *ev) |
433 | { | 522 | { |
434 | struct hid_device *hid; | 523 | struct uhid_create_req orig; |
435 | int ret; | ||
436 | 524 | ||
437 | if (uhid->running) | 525 | orig = ev->u.create; |
438 | return -EALREADY; | ||
439 | 526 | ||
440 | uhid->rd_size = ev->u.create2.rd_size; | 527 | if (orig.rd_size <= 0 || orig.rd_size > HID_MAX_DESCRIPTOR_SIZE) |
441 | if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE) | ||
442 | return -EINVAL; | 528 | return -EINVAL; |
529 | if (copy_from_user(&ev->u.create2.rd_data, orig.rd_data, orig.rd_size)) | ||
530 | return -EFAULT; | ||
443 | 531 | ||
444 | uhid->rd_data = kmemdup(ev->u.create2.rd_data, uhid->rd_size, | 532 | memcpy(ev->u.create2.name, orig.name, sizeof(orig.name)); |
445 | GFP_KERNEL); | 533 | memcpy(ev->u.create2.phys, orig.phys, sizeof(orig.phys)); |
446 | if (!uhid->rd_data) | 534 | memcpy(ev->u.create2.uniq, orig.uniq, sizeof(orig.uniq)); |
447 | return -ENOMEM; | 535 | ev->u.create2.rd_size = orig.rd_size; |
448 | 536 | ev->u.create2.bus = orig.bus; | |
449 | hid = hid_allocate_device(); | 537 | ev->u.create2.vendor = orig.vendor; |
450 | if (IS_ERR(hid)) { | 538 | ev->u.create2.product = orig.product; |
451 | ret = PTR_ERR(hid); | 539 | ev->u.create2.version = orig.version; |
452 | goto err_free; | 540 | ev->u.create2.country = orig.country; |
453 | } | 541 | |
454 | 542 | return uhid_dev_create2(uhid, ev); | |
455 | strncpy(hid->name, ev->u.create2.name, 127); | ||
456 | hid->name[127] = 0; | ||
457 | strncpy(hid->phys, ev->u.create2.phys, 63); | ||
458 | hid->phys[63] = 0; | ||
459 | strncpy(hid->uniq, ev->u.create2.uniq, 63); | ||
460 | hid->uniq[63] = 0; | ||
461 | |||
462 | hid->ll_driver = &uhid_hid_driver; | ||
463 | hid->bus = ev->u.create2.bus; | ||
464 | hid->vendor = ev->u.create2.vendor; | ||
465 | hid->product = ev->u.create2.product; | ||
466 | hid->version = ev->u.create2.version; | ||
467 | hid->country = ev->u.create2.country; | ||
468 | hid->driver_data = uhid; | ||
469 | hid->dev.parent = uhid_misc.this_device; | ||
470 | |||
471 | uhid->hid = hid; | ||
472 | uhid->running = true; | ||
473 | |||
474 | ret = hid_add_device(hid); | ||
475 | if (ret) { | ||
476 | hid_err(hid, "Cannot register HID device\n"); | ||
477 | goto err_hid; | ||
478 | } | ||
479 | |||
480 | return 0; | ||
481 | |||
482 | err_hid: | ||
483 | hid_destroy_device(hid); | ||
484 | uhid->hid = NULL; | ||
485 | uhid->running = false; | ||
486 | err_free: | ||
487 | kfree(uhid->rd_data); | ||
488 | return ret; | ||
489 | } | 543 | } |
490 | 544 | ||
491 | static int uhid_dev_destroy(struct uhid_device *uhid) | 545 | static int uhid_dev_destroy(struct uhid_device *uhid) |
@@ -493,10 +547,7 @@ static int uhid_dev_destroy(struct uhid_device *uhid) | |||
493 | if (!uhid->running) | 547 | if (!uhid->running) |
494 | return -EINVAL; | 548 | return -EINVAL; |
495 | 549 | ||
496 | /* clear "running" before setting "report_done" */ | ||
497 | uhid->running = false; | 550 | uhid->running = false; |
498 | smp_wmb(); | ||
499 | atomic_set(&uhid->report_done, 1); | ||
500 | wake_up_interruptible(&uhid->report_wait); | 551 | wake_up_interruptible(&uhid->report_wait); |
501 | 552 | ||
502 | hid_destroy_device(uhid->hid); | 553 | hid_destroy_device(uhid->hid); |
@@ -527,28 +578,23 @@ static int uhid_dev_input2(struct uhid_device *uhid, struct uhid_event *ev) | |||
527 | return 0; | 578 | return 0; |
528 | } | 579 | } |
529 | 580 | ||
530 | static int uhid_dev_feature_answer(struct uhid_device *uhid, | 581 | static int uhid_dev_get_report_reply(struct uhid_device *uhid, |
531 | struct uhid_event *ev) | 582 | struct uhid_event *ev) |
532 | { | 583 | { |
533 | unsigned long flags; | ||
534 | |||
535 | if (!uhid->running) | 584 | if (!uhid->running) |
536 | return -EINVAL; | 585 | return -EINVAL; |
537 | 586 | ||
538 | spin_lock_irqsave(&uhid->qlock, flags); | 587 | uhid_report_wake_up(uhid, ev->u.get_report_reply.id, ev); |
539 | 588 | return 0; | |
540 | /* id for old report; drop it silently */ | 589 | } |
541 | if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id) | ||
542 | goto unlock; | ||
543 | if (atomic_read(&uhid->report_done)) | ||
544 | goto unlock; | ||
545 | 590 | ||
546 | memcpy(&uhid->report_buf, ev, sizeof(*ev)); | 591 | static int uhid_dev_set_report_reply(struct uhid_device *uhid, |
547 | atomic_set(&uhid->report_done, 1); | 592 | struct uhid_event *ev) |
548 | wake_up_interruptible(&uhid->report_wait); | 593 | { |
594 | if (!uhid->running) | ||
595 | return -EINVAL; | ||
549 | 596 | ||
550 | unlock: | 597 | uhid_report_wake_up(uhid, ev->u.set_report_reply.id, ev); |
551 | spin_unlock_irqrestore(&uhid->qlock, flags); | ||
552 | return 0; | 598 | return 0; |
553 | } | 599 | } |
554 | 600 | ||
@@ -566,7 +612,6 @@ static int uhid_char_open(struct inode *inode, struct file *file) | |||
566 | init_waitqueue_head(&uhid->waitq); | 612 | init_waitqueue_head(&uhid->waitq); |
567 | init_waitqueue_head(&uhid->report_wait); | 613 | init_waitqueue_head(&uhid->report_wait); |
568 | uhid->running = false; | 614 | uhid->running = false; |
569 | atomic_set(&uhid->report_done, 1); | ||
570 | 615 | ||
571 | file->private_data = uhid; | 616 | file->private_data = uhid; |
572 | nonseekable_open(inode, file); | 617 | nonseekable_open(inode, file); |
@@ -675,8 +720,11 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | |||
675 | case UHID_INPUT2: | 720 | case UHID_INPUT2: |
676 | ret = uhid_dev_input2(uhid, &uhid->input_buf); | 721 | ret = uhid_dev_input2(uhid, &uhid->input_buf); |
677 | break; | 722 | break; |
678 | case UHID_FEATURE_ANSWER: | 723 | case UHID_GET_REPORT_REPLY: |
679 | ret = uhid_dev_feature_answer(uhid, &uhid->input_buf); | 724 | ret = uhid_dev_get_report_reply(uhid, &uhid->input_buf); |
725 | break; | ||
726 | case UHID_SET_REPORT_REPLY: | ||
727 | ret = uhid_dev_set_report_reply(uhid, &uhid->input_buf); | ||
680 | break; | 728 | break; |
681 | default: | 729 | default: |
682 | ret = -EOPNOTSUPP; | 730 | ret = -EOPNOTSUPP; |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 79cf503e37bf..ca6849a0121e 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -82,7 +82,7 @@ static int hid_start_in(struct hid_device *hid) | |||
82 | struct usbhid_device *usbhid = hid->driver_data; | 82 | struct usbhid_device *usbhid = hid->driver_data; |
83 | 83 | ||
84 | spin_lock_irqsave(&usbhid->lock, flags); | 84 | spin_lock_irqsave(&usbhid->lock, flags); |
85 | if (hid->open > 0 && | 85 | if ((hid->open > 0 || hid->quirks & HID_QUIRK_ALWAYS_POLL) && |
86 | !test_bit(HID_DISCONNECTED, &usbhid->iofl) && | 86 | !test_bit(HID_DISCONNECTED, &usbhid->iofl) && |
87 | !test_bit(HID_SUSPENDED, &usbhid->iofl) && | 87 | !test_bit(HID_SUSPENDED, &usbhid->iofl) && |
88 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { | 88 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { |
@@ -116,40 +116,24 @@ static void hid_reset(struct work_struct *work) | |||
116 | struct usbhid_device *usbhid = | 116 | struct usbhid_device *usbhid = |
117 | container_of(work, struct usbhid_device, reset_work); | 117 | container_of(work, struct usbhid_device, reset_work); |
118 | struct hid_device *hid = usbhid->hid; | 118 | struct hid_device *hid = usbhid->hid; |
119 | int rc = 0; | 119 | int rc; |
120 | 120 | ||
121 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { | 121 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { |
122 | dev_dbg(&usbhid->intf->dev, "clear halt\n"); | 122 | dev_dbg(&usbhid->intf->dev, "clear halt\n"); |
123 | rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe); | 123 | rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe); |
124 | clear_bit(HID_CLEAR_HALT, &usbhid->iofl); | 124 | clear_bit(HID_CLEAR_HALT, &usbhid->iofl); |
125 | hid_start_in(hid); | ||
126 | } | ||
127 | |||
128 | else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { | ||
129 | dev_dbg(&usbhid->intf->dev, "resetting device\n"); | ||
130 | rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); | ||
131 | if (rc == 0) { | 125 | if (rc == 0) { |
132 | rc = usb_reset_device(hid_to_usb_dev(hid)); | 126 | hid_start_in(hid); |
133 | usb_unlock_device(hid_to_usb_dev(hid)); | 127 | } else { |
128 | dev_dbg(&usbhid->intf->dev, | ||
129 | "clear-halt failed: %d\n", rc); | ||
130 | set_bit(HID_RESET_PENDING, &usbhid->iofl); | ||
134 | } | 131 | } |
135 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | ||
136 | } | 132 | } |
137 | 133 | ||
138 | switch (rc) { | 134 | if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { |
139 | case 0: | 135 | dev_dbg(&usbhid->intf->dev, "resetting device\n"); |
140 | if (!test_bit(HID_IN_RUNNING, &usbhid->iofl)) | 136 | usb_queue_reset_device(usbhid->intf); |
141 | hid_io_error(hid); | ||
142 | break; | ||
143 | default: | ||
144 | hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n", | ||
145 | hid_to_usb_dev(hid)->bus->bus_name, | ||
146 | hid_to_usb_dev(hid)->devpath, | ||
147 | usbhid->ifnum, rc); | ||
148 | /* FALLTHROUGH */ | ||
149 | case -EHOSTUNREACH: | ||
150 | case -ENODEV: | ||
151 | case -EINTR: | ||
152 | break; | ||
153 | } | 137 | } |
154 | } | 138 | } |
155 | 139 | ||
@@ -292,6 +276,8 @@ static void hid_irq_in(struct urb *urb) | |||
292 | case 0: /* success */ | 276 | case 0: /* success */ |
293 | usbhid_mark_busy(usbhid); | 277 | usbhid_mark_busy(usbhid); |
294 | usbhid->retry_delay = 0; | 278 | usbhid->retry_delay = 0; |
279 | if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open) | ||
280 | break; | ||
295 | hid_input_report(urb->context, HID_INPUT_REPORT, | 281 | hid_input_report(urb->context, HID_INPUT_REPORT, |
296 | urb->transfer_buffer, | 282 | urb->transfer_buffer, |
297 | urb->actual_length, 1); | 283 | urb->actual_length, 1); |
@@ -735,8 +721,10 @@ void usbhid_close(struct hid_device *hid) | |||
735 | if (!--hid->open) { | 721 | if (!--hid->open) { |
736 | spin_unlock_irq(&usbhid->lock); | 722 | spin_unlock_irq(&usbhid->lock); |
737 | hid_cancel_delayed_stuff(usbhid); | 723 | hid_cancel_delayed_stuff(usbhid); |
738 | usb_kill_urb(usbhid->urbin); | 724 | if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) { |
739 | usbhid->intf->needs_remote_wakeup = 0; | 725 | usb_kill_urb(usbhid->urbin); |
726 | usbhid->intf->needs_remote_wakeup = 0; | ||
727 | } | ||
740 | } else { | 728 | } else { |
741 | spin_unlock_irq(&usbhid->lock); | 729 | spin_unlock_irq(&usbhid->lock); |
742 | } | 730 | } |
@@ -1134,6 +1122,19 @@ static int usbhid_start(struct hid_device *hid) | |||
1134 | 1122 | ||
1135 | set_bit(HID_STARTED, &usbhid->iofl); | 1123 | set_bit(HID_STARTED, &usbhid->iofl); |
1136 | 1124 | ||
1125 | if (hid->quirks & HID_QUIRK_ALWAYS_POLL) { | ||
1126 | ret = usb_autopm_get_interface(usbhid->intf); | ||
1127 | if (ret) | ||
1128 | goto fail; | ||
1129 | usbhid->intf->needs_remote_wakeup = 1; | ||
1130 | ret = hid_start_in(hid); | ||
1131 | if (ret) { | ||
1132 | dev_err(&hid->dev, | ||
1133 | "failed to start in urb: %d\n", ret); | ||
1134 | } | ||
1135 | usb_autopm_put_interface(usbhid->intf); | ||
1136 | } | ||
1137 | |||
1137 | /* Some keyboards don't work until their LEDs have been set. | 1138 | /* Some keyboards don't work until their LEDs have been set. |
1138 | * Since BIOSes do set the LEDs, it must be safe for any device | 1139 | * Since BIOSes do set the LEDs, it must be safe for any device |
1139 | * that supports the keyboard boot protocol. | 1140 | * that supports the keyboard boot protocol. |
@@ -1166,6 +1167,9 @@ static void usbhid_stop(struct hid_device *hid) | |||
1166 | if (WARN_ON(!usbhid)) | 1167 | if (WARN_ON(!usbhid)) |
1167 | return; | 1168 | return; |
1168 | 1169 | ||
1170 | if (hid->quirks & HID_QUIRK_ALWAYS_POLL) | ||
1171 | usbhid->intf->needs_remote_wakeup = 0; | ||
1172 | |||
1169 | clear_bit(HID_STARTED, &usbhid->iofl); | 1173 | clear_bit(HID_STARTED, &usbhid->iofl); |
1170 | spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */ | 1174 | spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */ |
1171 | set_bit(HID_DISCONNECTED, &usbhid->iofl); | 1175 | set_bit(HID_DISCONNECTED, &usbhid->iofl); |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 15225f3eaed1..f3cb5b0a4345 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -70,6 +70,7 @@ static const struct hid_blacklist { | |||
70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, |
71 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, | 71 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, |
72 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, | 72 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
73 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL }, | ||
73 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 74 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
74 | { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, | 75 | { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, |
75 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, | 76 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
@@ -79,6 +80,8 @@ static const struct hid_blacklist { | |||
79 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, | 80 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |
80 | { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610, HID_QUIRK_NOGET }, | 81 | { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610, HID_QUIRK_NOGET }, |
81 | { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640, HID_QUIRK_NOGET }, | 82 | { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640, HID_QUIRK_NOGET }, |
83 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, | ||
84 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2, HID_QUIRK_ALWAYS_POLL }, | ||
82 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, | 85 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, |
83 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, | 86 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, |
84 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, | 87 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 64bc1b296d91..0cc53440543a 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h | |||
@@ -89,6 +89,7 @@ | |||
89 | #include <linux/slab.h> | 89 | #include <linux/slab.h> |
90 | #include <linux/module.h> | 90 | #include <linux/module.h> |
91 | #include <linux/mod_devicetable.h> | 91 | #include <linux/mod_devicetable.h> |
92 | #include <linux/hid.h> | ||
92 | #include <linux/usb/input.h> | 93 | #include <linux/usb/input.h> |
93 | #include <linux/power_supply.h> | 94 | #include <linux/power_supply.h> |
94 | #include <asm/unaligned.h> | 95 | #include <asm/unaligned.h> |
@@ -143,4 +144,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
143 | struct wacom_wac *wacom_wac); | 144 | struct wacom_wac *wacom_wac); |
144 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | 145 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, |
145 | struct wacom_wac *wacom_wac); | 146 | struct wacom_wac *wacom_wac); |
147 | void wacom_wac_usage_mapping(struct hid_device *hdev, | ||
148 | struct hid_field *field, struct hid_usage *usage); | ||
149 | int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, | ||
150 | struct hid_usage *usage, __s32 value); | ||
151 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); | ||
146 | #endif | 152 | #endif |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index f0db7eca9023..8593047bb726 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -13,23 +13,26 @@ | |||
13 | 13 | ||
14 | #include "wacom_wac.h" | 14 | #include "wacom_wac.h" |
15 | #include "wacom.h" | 15 | #include "wacom.h" |
16 | #include <linux/hid.h> | ||
17 | 16 | ||
18 | #define WAC_MSG_RETRIES 5 | 17 | #define WAC_MSG_RETRIES 5 |
19 | 18 | ||
19 | #define WAC_CMD_WL_LED_CONTROL 0x03 | ||
20 | #define WAC_CMD_LED_CONTROL 0x20 | 20 | #define WAC_CMD_LED_CONTROL 0x20 |
21 | #define WAC_CMD_ICON_START 0x21 | 21 | #define WAC_CMD_ICON_START 0x21 |
22 | #define WAC_CMD_ICON_XFER 0x23 | 22 | #define WAC_CMD_ICON_XFER 0x23 |
23 | #define WAC_CMD_ICON_BT_XFER 0x26 | 23 | #define WAC_CMD_ICON_BT_XFER 0x26 |
24 | #define WAC_CMD_RETRIES 10 | 24 | #define WAC_CMD_RETRIES 10 |
25 | 25 | ||
26 | static int wacom_get_report(struct hid_device *hdev, u8 type, u8 id, | 26 | #define DEV_ATTR_RW_PERM (S_IRUGO | S_IWUSR | S_IWGRP) |
27 | void *buf, size_t size, unsigned int retries) | 27 | #define DEV_ATTR_WO_PERM (S_IWUSR | S_IWGRP) |
28 | |||
29 | static int wacom_get_report(struct hid_device *hdev, u8 type, u8 *buf, | ||
30 | size_t size, unsigned int retries) | ||
28 | { | 31 | { |
29 | int retval; | 32 | int retval; |
30 | 33 | ||
31 | do { | 34 | do { |
32 | retval = hid_hw_raw_request(hdev, id, buf, size, type, | 35 | retval = hid_hw_raw_request(hdev, buf[0], buf, size, type, |
33 | HID_REQ_GET_REPORT); | 36 | HID_REQ_GET_REPORT); |
34 | } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); | 37 | } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); |
35 | 38 | ||
@@ -106,12 +109,35 @@ static void wacom_feature_mapping(struct hid_device *hdev, | |||
106 | { | 109 | { |
107 | struct wacom *wacom = hid_get_drvdata(hdev); | 110 | struct wacom *wacom = hid_get_drvdata(hdev); |
108 | struct wacom_features *features = &wacom->wacom_wac.features; | 111 | struct wacom_features *features = &wacom->wacom_wac.features; |
112 | struct hid_data *hid_data = &wacom->wacom_wac.hid_data; | ||
113 | u8 *data; | ||
114 | int ret; | ||
109 | 115 | ||
110 | switch (usage->hid) { | 116 | switch (usage->hid) { |
111 | case HID_DG_CONTACTMAX: | 117 | case HID_DG_CONTACTMAX: |
112 | /* leave touch_max as is if predefined */ | 118 | /* leave touch_max as is if predefined */ |
113 | if (!features->touch_max) | 119 | if (!features->touch_max) { |
114 | features->touch_max = field->value[0]; | 120 | /* read manually */ |
121 | data = kzalloc(2, GFP_KERNEL); | ||
122 | if (!data) | ||
123 | break; | ||
124 | data[0] = field->report->id; | ||
125 | ret = wacom_get_report(hdev, HID_FEATURE_REPORT, | ||
126 | data, 2, 0); | ||
127 | if (ret == 2) | ||
128 | features->touch_max = data[1]; | ||
129 | kfree(data); | ||
130 | } | ||
131 | break; | ||
132 | case HID_DG_INPUTMODE: | ||
133 | /* Ignore if value index is out of bounds. */ | ||
134 | if (usage->usage_index >= field->report_count) { | ||
135 | dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n"); | ||
136 | break; | ||
137 | } | ||
138 | |||
139 | hid_data->inputmode = field->report->id; | ||
140 | hid_data->inputmode_index = usage->usage_index; | ||
115 | break; | 141 | break; |
116 | } | 142 | } |
117 | } | 143 | } |
@@ -199,6 +225,9 @@ static void wacom_usage_mapping(struct hid_device *hdev, | |||
199 | features->pressure_max = field->logical_maximum; | 225 | features->pressure_max = field->logical_maximum; |
200 | break; | 226 | break; |
201 | } | 227 | } |
228 | |||
229 | if (features->type == HID_GENERIC) | ||
230 | wacom_wac_usage_mapping(hdev, field, usage); | ||
202 | } | 231 | } |
203 | 232 | ||
204 | static void wacom_parse_hid(struct hid_device *hdev, | 233 | static void wacom_parse_hid(struct hid_device *hdev, |
@@ -237,6 +266,25 @@ static void wacom_parse_hid(struct hid_device *hdev, | |||
237 | } | 266 | } |
238 | } | 267 | } |
239 | 268 | ||
269 | static int wacom_hid_set_device_mode(struct hid_device *hdev) | ||
270 | { | ||
271 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
272 | struct hid_data *hid_data = &wacom->wacom_wac.hid_data; | ||
273 | struct hid_report *r; | ||
274 | struct hid_report_enum *re; | ||
275 | |||
276 | if (hid_data->inputmode < 0) | ||
277 | return 0; | ||
278 | |||
279 | re = &(hdev->report_enum[HID_FEATURE_REPORT]); | ||
280 | r = re->report_id_hash[hid_data->inputmode]; | ||
281 | if (r) { | ||
282 | r->field[0]->value[hid_data->inputmode_index] = 2; | ||
283 | hid_hw_request(hdev, r, HID_REQ_SET_REPORT); | ||
284 | } | ||
285 | return 0; | ||
286 | } | ||
287 | |||
240 | static int wacom_set_device_mode(struct hid_device *hdev, int report_id, | 288 | static int wacom_set_device_mode(struct hid_device *hdev, int report_id, |
241 | int length, int mode) | 289 | int length, int mode) |
242 | { | 290 | { |
@@ -255,7 +303,7 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id, | |||
255 | length, 1); | 303 | length, 1); |
256 | if (error >= 0) | 304 | if (error >= 0) |
257 | error = wacom_get_report(hdev, HID_FEATURE_REPORT, | 305 | error = wacom_get_report(hdev, HID_FEATURE_REPORT, |
258 | report_id, rep_data, length, 1); | 306 | rep_data, length, 1); |
259 | } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); | 307 | } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); |
260 | 308 | ||
261 | kfree(rep_data); | 309 | kfree(rep_data); |
@@ -329,6 +377,9 @@ static int wacom_query_tablet_data(struct hid_device *hdev, | |||
329 | if (hdev->bus == BUS_BLUETOOTH) | 377 | if (hdev->bus == BUS_BLUETOOTH) |
330 | return wacom_bt_query_tablet_data(hdev, 1, features); | 378 | return wacom_bt_query_tablet_data(hdev, 1, features); |
331 | 379 | ||
380 | if (features->type == HID_GENERIC) | ||
381 | return wacom_hid_set_device_mode(hdev); | ||
382 | |||
332 | if (features->device_type == BTN_TOOL_FINGER) { | 383 | if (features->device_type == BTN_TOOL_FINGER) { |
333 | if (features->type > TABLETPC) { | 384 | if (features->type > TABLETPC) { |
334 | /* MT Tablet PC touch */ | 385 | /* MT Tablet PC touch */ |
@@ -487,8 +538,14 @@ static int wacom_led_control(struct wacom *wacom) | |||
487 | { | 538 | { |
488 | unsigned char *buf; | 539 | unsigned char *buf; |
489 | int retval; | 540 | int retval; |
541 | unsigned char report_id = WAC_CMD_LED_CONTROL; | ||
542 | int buf_size = 9; | ||
490 | 543 | ||
491 | buf = kzalloc(9, GFP_KERNEL); | 544 | if (wacom->wacom_wac.pid) { /* wireless connected */ |
545 | report_id = WAC_CMD_WL_LED_CONTROL; | ||
546 | buf_size = 13; | ||
547 | } | ||
548 | buf = kzalloc(buf_size, GFP_KERNEL); | ||
492 | if (!buf) | 549 | if (!buf) |
493 | return -ENOMEM; | 550 | return -ENOMEM; |
494 | 551 | ||
@@ -502,9 +559,16 @@ static int wacom_led_control(struct wacom *wacom) | |||
502 | int ring_led = wacom->led.select[0] & 0x03; | 559 | int ring_led = wacom->led.select[0] & 0x03; |
503 | int ring_lum = (((wacom->led.llv & 0x60) >> 5) - 1) & 0x03; | 560 | int ring_lum = (((wacom->led.llv & 0x60) >> 5) - 1) & 0x03; |
504 | int crop_lum = 0; | 561 | int crop_lum = 0; |
505 | 562 | unsigned char led_bits = (crop_lum << 4) | (ring_lum << 2) | (ring_led); | |
506 | buf[0] = WAC_CMD_LED_CONTROL; | 563 | |
507 | buf[1] = (crop_lum << 4) | (ring_lum << 2) | (ring_led); | 564 | buf[0] = report_id; |
565 | if (wacom->wacom_wac.pid) { | ||
566 | wacom_get_report(wacom->hdev, HID_FEATURE_REPORT, | ||
567 | buf, buf_size, WAC_CMD_RETRIES); | ||
568 | buf[0] = report_id; | ||
569 | buf[4] = led_bits; | ||
570 | } else | ||
571 | buf[1] = led_bits; | ||
508 | } | 572 | } |
509 | else { | 573 | else { |
510 | int led = wacom->led.select[0] | 0x4; | 574 | int led = wacom->led.select[0] | 0x4; |
@@ -513,14 +577,14 @@ static int wacom_led_control(struct wacom *wacom) | |||
513 | wacom->wacom_wac.features.type == WACOM_24HD) | 577 | wacom->wacom_wac.features.type == WACOM_24HD) |
514 | led |= (wacom->led.select[1] << 4) | 0x40; | 578 | led |= (wacom->led.select[1] << 4) | 0x40; |
515 | 579 | ||
516 | buf[0] = WAC_CMD_LED_CONTROL; | 580 | buf[0] = report_id; |
517 | buf[1] = led; | 581 | buf[1] = led; |
518 | buf[2] = wacom->led.llv; | 582 | buf[2] = wacom->led.llv; |
519 | buf[3] = wacom->led.hlv; | 583 | buf[3] = wacom->led.hlv; |
520 | buf[4] = wacom->led.img_lum; | 584 | buf[4] = wacom->led.img_lum; |
521 | } | 585 | } |
522 | 586 | ||
523 | retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 9, | 587 | retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, buf_size, |
524 | WAC_CMD_RETRIES); | 588 | WAC_CMD_RETRIES); |
525 | kfree(buf); | 589 | kfree(buf); |
526 | 590 | ||
@@ -602,9 +666,10 @@ static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \ | |||
602 | { \ | 666 | { \ |
603 | struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ | 667 | struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ |
604 | struct wacom *wacom = hid_get_drvdata(hdev); \ | 668 | struct wacom *wacom = hid_get_drvdata(hdev); \ |
605 | return snprintf(buf, 2, "%d\n", wacom->led.select[SET_ID]); \ | 669 | return scnprintf(buf, PAGE_SIZE, "%d\n", \ |
670 | wacom->led.select[SET_ID]); \ | ||
606 | } \ | 671 | } \ |
607 | static DEVICE_ATTR(status_led##SET_ID##_select, S_IWUSR | S_IRUSR, \ | 672 | static DEVICE_ATTR(status_led##SET_ID##_select, DEV_ATTR_RW_PERM, \ |
608 | wacom_led##SET_ID##_select_show, \ | 673 | wacom_led##SET_ID##_select_show, \ |
609 | wacom_led##SET_ID##_select_store) | 674 | wacom_led##SET_ID##_select_store) |
610 | 675 | ||
@@ -641,8 +706,15 @@ static ssize_t wacom_##name##_luminance_store(struct device *dev, \ | |||
641 | return wacom_luminance_store(wacom, &wacom->led.field, \ | 706 | return wacom_luminance_store(wacom, &wacom->led.field, \ |
642 | buf, count); \ | 707 | buf, count); \ |
643 | } \ | 708 | } \ |
644 | static DEVICE_ATTR(name##_luminance, S_IWUSR, \ | 709 | static ssize_t wacom_##name##_luminance_show(struct device *dev, \ |
645 | NULL, wacom_##name##_luminance_store) | 710 | struct device_attribute *attr, char *buf) \ |
711 | { \ | ||
712 | struct wacom *wacom = dev_get_drvdata(dev); \ | ||
713 | return scnprintf(buf, PAGE_SIZE, "%d\n", wacom->led.field); \ | ||
714 | } \ | ||
715 | static DEVICE_ATTR(name##_luminance, DEV_ATTR_RW_PERM, \ | ||
716 | wacom_##name##_luminance_show, \ | ||
717 | wacom_##name##_luminance_store) | ||
646 | 718 | ||
647 | DEVICE_LUMINANCE_ATTR(status0, llv); | 719 | DEVICE_LUMINANCE_ATTR(status0, llv); |
648 | DEVICE_LUMINANCE_ATTR(status1, hlv); | 720 | DEVICE_LUMINANCE_ATTR(status1, hlv); |
@@ -683,7 +755,7 @@ static ssize_t wacom_btnimg##BUTTON_ID##_store(struct device *dev, \ | |||
683 | { \ | 755 | { \ |
684 | return wacom_button_image_store(dev, BUTTON_ID, buf, count); \ | 756 | return wacom_button_image_store(dev, BUTTON_ID, buf, count); \ |
685 | } \ | 757 | } \ |
686 | static DEVICE_ATTR(button##BUTTON_ID##_rawimg, S_IWUSR, \ | 758 | static DEVICE_ATTR(button##BUTTON_ID##_rawimg, DEV_ATTR_WO_PERM, \ |
687 | NULL, wacom_btnimg##BUTTON_ID##_store) | 759 | NULL, wacom_btnimg##BUTTON_ID##_store) |
688 | 760 | ||
689 | DEVICE_BTNIMG_ATTR(0); | 761 | DEVICE_BTNIMG_ATTR(0); |
@@ -989,7 +1061,7 @@ static ssize_t wacom_store_speed(struct device *dev, | |||
989 | return count; | 1061 | return count; |
990 | } | 1062 | } |
991 | 1063 | ||
992 | static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP, | 1064 | static DEVICE_ATTR(speed, DEV_ATTR_RW_PERM, |
993 | wacom_show_speed, wacom_store_speed); | 1065 | wacom_show_speed, wacom_store_speed); |
994 | 1066 | ||
995 | static struct input_dev *wacom_allocate_input(struct wacom *wacom) | 1067 | static struct input_dev *wacom_allocate_input(struct wacom *wacom) |
@@ -1010,47 +1082,82 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) | |||
1010 | input_dev->uniq = hdev->uniq; | 1082 | input_dev->uniq = hdev->uniq; |
1011 | input_dev->id.bustype = hdev->bus; | 1083 | input_dev->id.bustype = hdev->bus; |
1012 | input_dev->id.vendor = hdev->vendor; | 1084 | input_dev->id.vendor = hdev->vendor; |
1013 | input_dev->id.product = hdev->product; | 1085 | input_dev->id.product = wacom_wac->pid ? wacom_wac->pid : hdev->product; |
1014 | input_dev->id.version = hdev->version; | 1086 | input_dev->id.version = hdev->version; |
1015 | input_set_drvdata(input_dev, wacom); | 1087 | input_set_drvdata(input_dev, wacom); |
1016 | 1088 | ||
1017 | return input_dev; | 1089 | return input_dev; |
1018 | } | 1090 | } |
1019 | 1091 | ||
1020 | static void wacom_unregister_inputs(struct wacom *wacom) | 1092 | static void wacom_free_inputs(struct wacom *wacom) |
1021 | { | 1093 | { |
1022 | if (wacom->wacom_wac.input) | 1094 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); |
1023 | input_unregister_device(wacom->wacom_wac.input); | 1095 | |
1024 | if (wacom->wacom_wac.pad_input) | 1096 | if (wacom_wac->input) |
1025 | input_unregister_device(wacom->wacom_wac.pad_input); | 1097 | input_free_device(wacom_wac->input); |
1026 | wacom->wacom_wac.input = NULL; | 1098 | if (wacom_wac->pad_input) |
1027 | wacom->wacom_wac.pad_input = NULL; | 1099 | input_free_device(wacom_wac->pad_input); |
1100 | wacom_wac->input = NULL; | ||
1101 | wacom_wac->pad_input = NULL; | ||
1028 | } | 1102 | } |
1029 | 1103 | ||
1030 | static int wacom_register_inputs(struct wacom *wacom) | 1104 | static int wacom_allocate_inputs(struct wacom *wacom) |
1031 | { | 1105 | { |
1032 | struct input_dev *input_dev, *pad_input_dev; | 1106 | struct input_dev *input_dev, *pad_input_dev; |
1033 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); | 1107 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); |
1034 | int error; | ||
1035 | 1108 | ||
1036 | input_dev = wacom_allocate_input(wacom); | 1109 | input_dev = wacom_allocate_input(wacom); |
1037 | pad_input_dev = wacom_allocate_input(wacom); | 1110 | pad_input_dev = wacom_allocate_input(wacom); |
1038 | if (!input_dev || !pad_input_dev) { | 1111 | if (!input_dev || !pad_input_dev) { |
1039 | error = -ENOMEM; | 1112 | wacom_free_inputs(wacom); |
1040 | goto fail1; | 1113 | return -ENOMEM; |
1041 | } | 1114 | } |
1042 | 1115 | ||
1043 | wacom_wac->input = input_dev; | 1116 | wacom_wac->input = input_dev; |
1044 | wacom_wac->pad_input = pad_input_dev; | 1117 | wacom_wac->pad_input = pad_input_dev; |
1045 | wacom_wac->pad_input->name = wacom_wac->pad_name; | 1118 | wacom_wac->pad_input->name = wacom_wac->pad_name; |
1046 | 1119 | ||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | static void wacom_clean_inputs(struct wacom *wacom) | ||
1124 | { | ||
1125 | if (wacom->wacom_wac.input) { | ||
1126 | if (wacom->wacom_wac.input_registered) | ||
1127 | input_unregister_device(wacom->wacom_wac.input); | ||
1128 | else | ||
1129 | input_free_device(wacom->wacom_wac.input); | ||
1130 | } | ||
1131 | if (wacom->wacom_wac.pad_input) { | ||
1132 | if (wacom->wacom_wac.input_registered) | ||
1133 | input_unregister_device(wacom->wacom_wac.pad_input); | ||
1134 | else | ||
1135 | input_free_device(wacom->wacom_wac.pad_input); | ||
1136 | } | ||
1137 | wacom->wacom_wac.input = NULL; | ||
1138 | wacom->wacom_wac.pad_input = NULL; | ||
1139 | wacom_destroy_leds(wacom); | ||
1140 | } | ||
1141 | |||
1142 | static int wacom_register_inputs(struct wacom *wacom) | ||
1143 | { | ||
1144 | struct input_dev *input_dev, *pad_input_dev; | ||
1145 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); | ||
1146 | int error; | ||
1147 | |||
1148 | input_dev = wacom_wac->input; | ||
1149 | pad_input_dev = wacom_wac->pad_input; | ||
1150 | |||
1151 | if (!input_dev || !pad_input_dev) | ||
1152 | return -EINVAL; | ||
1153 | |||
1047 | error = wacom_setup_input_capabilities(input_dev, wacom_wac); | 1154 | error = wacom_setup_input_capabilities(input_dev, wacom_wac); |
1048 | if (error) | 1155 | if (error) |
1049 | goto fail2; | 1156 | return error; |
1050 | 1157 | ||
1051 | error = input_register_device(input_dev); | 1158 | error = input_register_device(input_dev); |
1052 | if (error) | 1159 | if (error) |
1053 | goto fail2; | 1160 | return error; |
1054 | 1161 | ||
1055 | error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); | 1162 | error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); |
1056 | if (error) { | 1163 | if (error) { |
@@ -1061,22 +1168,23 @@ static int wacom_register_inputs(struct wacom *wacom) | |||
1061 | } else { | 1168 | } else { |
1062 | error = input_register_device(pad_input_dev); | 1169 | error = input_register_device(pad_input_dev); |
1063 | if (error) | 1170 | if (error) |
1064 | goto fail3; | 1171 | goto fail_register_pad_input; |
1172 | |||
1173 | error = wacom_initialize_leds(wacom); | ||
1174 | if (error) | ||
1175 | goto fail_leds; | ||
1065 | } | 1176 | } |
1066 | 1177 | ||
1178 | wacom_wac->input_registered = true; | ||
1179 | |||
1067 | return 0; | 1180 | return 0; |
1068 | 1181 | ||
1069 | fail3: | 1182 | fail_leds: |
1183 | input_unregister_device(pad_input_dev); | ||
1184 | pad_input_dev = NULL; | ||
1185 | fail_register_pad_input: | ||
1070 | input_unregister_device(input_dev); | 1186 | input_unregister_device(input_dev); |
1071 | input_dev = NULL; | ||
1072 | fail2: | ||
1073 | wacom_wac->input = NULL; | 1187 | wacom_wac->input = NULL; |
1074 | wacom_wac->pad_input = NULL; | ||
1075 | fail1: | ||
1076 | if (input_dev) | ||
1077 | input_free_device(input_dev); | ||
1078 | if (pad_input_dev) | ||
1079 | input_free_device(pad_input_dev); | ||
1080 | return error; | 1188 | return error; |
1081 | } | 1189 | } |
1082 | 1190 | ||
@@ -1101,13 +1209,13 @@ static void wacom_wireless_work(struct work_struct *work) | |||
1101 | hdev1 = usb_get_intfdata(usbdev->config->interface[1]); | 1209 | hdev1 = usb_get_intfdata(usbdev->config->interface[1]); |
1102 | wacom1 = hid_get_drvdata(hdev1); | 1210 | wacom1 = hid_get_drvdata(hdev1); |
1103 | wacom_wac1 = &(wacom1->wacom_wac); | 1211 | wacom_wac1 = &(wacom1->wacom_wac); |
1104 | wacom_unregister_inputs(wacom1); | 1212 | wacom_clean_inputs(wacom1); |
1105 | 1213 | ||
1106 | /* Touch interface */ | 1214 | /* Touch interface */ |
1107 | hdev2 = usb_get_intfdata(usbdev->config->interface[2]); | 1215 | hdev2 = usb_get_intfdata(usbdev->config->interface[2]); |
1108 | wacom2 = hid_get_drvdata(hdev2); | 1216 | wacom2 = hid_get_drvdata(hdev2); |
1109 | wacom_wac2 = &(wacom2->wacom_wac); | 1217 | wacom_wac2 = &(wacom2->wacom_wac); |
1110 | wacom_unregister_inputs(wacom2); | 1218 | wacom_clean_inputs(wacom2); |
1111 | 1219 | ||
1112 | if (wacom_wac->pid == 0) { | 1220 | if (wacom_wac->pid == 0) { |
1113 | hid_info(wacom->hdev, "wireless tablet disconnected\n"); | 1221 | hid_info(wacom->hdev, "wireless tablet disconnected\n"); |
@@ -1140,7 +1248,9 @@ static void wacom_wireless_work(struct work_struct *work) | |||
1140 | wacom_wac1->features.name); | 1248 | wacom_wac1->features.name); |
1141 | wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max; | 1249 | wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max; |
1142 | wacom_wac1->shared->type = wacom_wac1->features.type; | 1250 | wacom_wac1->shared->type = wacom_wac1->features.type; |
1143 | error = wacom_register_inputs(wacom1); | 1251 | wacom_wac1->pid = wacom_wac->pid; |
1252 | error = wacom_allocate_inputs(wacom1) || | ||
1253 | wacom_register_inputs(wacom1); | ||
1144 | if (error) | 1254 | if (error) |
1145 | goto fail; | 1255 | goto fail; |
1146 | 1256 | ||
@@ -1160,7 +1270,9 @@ static void wacom_wireless_work(struct work_struct *work) | |||
1160 | "%s (WL) Pad",wacom_wac2->features.name); | 1270 | "%s (WL) Pad",wacom_wac2->features.name); |
1161 | snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX, | 1271 | snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX, |
1162 | "%s (WL) Pad", wacom_wac2->features.name); | 1272 | "%s (WL) Pad", wacom_wac2->features.name); |
1163 | error = wacom_register_inputs(wacom2); | 1273 | wacom_wac2->pid = wacom_wac->pid; |
1274 | error = wacom_allocate_inputs(wacom2) || | ||
1275 | wacom_register_inputs(wacom2); | ||
1164 | if (error) | 1276 | if (error) |
1165 | goto fail; | 1277 | goto fail; |
1166 | 1278 | ||
@@ -1177,8 +1289,8 @@ static void wacom_wireless_work(struct work_struct *work) | |||
1177 | return; | 1289 | return; |
1178 | 1290 | ||
1179 | fail: | 1291 | fail: |
1180 | wacom_unregister_inputs(wacom1); | 1292 | wacom_clean_inputs(wacom1); |
1181 | wacom_unregister_inputs(wacom2); | 1293 | wacom_clean_inputs(wacom2); |
1182 | return; | 1294 | return; |
1183 | } | 1295 | } |
1184 | 1296 | ||
@@ -1241,10 +1353,13 @@ static int wacom_probe(struct hid_device *hdev, | |||
1241 | struct wacom_wac *wacom_wac; | 1353 | struct wacom_wac *wacom_wac; |
1242 | struct wacom_features *features; | 1354 | struct wacom_features *features; |
1243 | int error; | 1355 | int error; |
1356 | unsigned int connect_mask = HID_CONNECT_HIDRAW; | ||
1244 | 1357 | ||
1245 | if (!id->driver_data) | 1358 | if (!id->driver_data) |
1246 | return -EINVAL; | 1359 | return -EINVAL; |
1247 | 1360 | ||
1361 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | ||
1362 | |||
1248 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 1363 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
1249 | if (!wacom) | 1364 | if (!wacom) |
1250 | return -ENOMEM; | 1365 | return -ENOMEM; |
@@ -1256,7 +1371,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
1256 | error = hid_parse(hdev); | 1371 | error = hid_parse(hdev); |
1257 | if (error) { | 1372 | if (error) { |
1258 | hid_err(hdev, "parse failed\n"); | 1373 | hid_err(hdev, "parse failed\n"); |
1259 | goto fail1; | 1374 | goto fail_parse; |
1260 | } | 1375 | } |
1261 | 1376 | ||
1262 | wacom_wac = &wacom->wacom_wac; | 1377 | wacom_wac = &wacom->wacom_wac; |
@@ -1265,12 +1380,12 @@ static int wacom_probe(struct hid_device *hdev, | |||
1265 | features->pktlen = wacom_compute_pktlen(hdev); | 1380 | features->pktlen = wacom_compute_pktlen(hdev); |
1266 | if (features->pktlen > WACOM_PKGLEN_MAX) { | 1381 | if (features->pktlen > WACOM_PKGLEN_MAX) { |
1267 | error = -EINVAL; | 1382 | error = -EINVAL; |
1268 | goto fail1; | 1383 | goto fail_pktlen; |
1269 | } | 1384 | } |
1270 | 1385 | ||
1271 | if (features->check_for_hid_type && features->hid_type != hdev->type) { | 1386 | if (features->check_for_hid_type && features->hid_type != hdev->type) { |
1272 | error = -ENODEV; | 1387 | error = -ENODEV; |
1273 | goto fail1; | 1388 | goto fail_type; |
1274 | } | 1389 | } |
1275 | 1390 | ||
1276 | wacom->usbdev = dev; | 1391 | wacom->usbdev = dev; |
@@ -1278,6 +1393,12 @@ static int wacom_probe(struct hid_device *hdev, | |||
1278 | mutex_init(&wacom->lock); | 1393 | mutex_init(&wacom->lock); |
1279 | INIT_WORK(&wacom->work, wacom_wireless_work); | 1394 | INIT_WORK(&wacom->work, wacom_wireless_work); |
1280 | 1395 | ||
1396 | if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { | ||
1397 | error = wacom_allocate_inputs(wacom); | ||
1398 | if (error) | ||
1399 | goto fail_allocate_inputs; | ||
1400 | } | ||
1401 | |||
1281 | /* set the default size in case we do not get them from hid */ | 1402 | /* set the default size in case we do not get them from hid */ |
1282 | wacom_set_default_phy(features); | 1403 | wacom_set_default_phy(features); |
1283 | 1404 | ||
@@ -1339,24 +1460,20 @@ static int wacom_probe(struct hid_device *hdev, | |||
1339 | 1460 | ||
1340 | error = wacom_add_shared_data(hdev); | 1461 | error = wacom_add_shared_data(hdev); |
1341 | if (error) | 1462 | if (error) |
1342 | goto fail1; | 1463 | goto fail_shared_data; |
1343 | } | 1464 | } |
1344 | 1465 | ||
1345 | error = wacom_initialize_leds(wacom); | ||
1346 | if (error) | ||
1347 | goto fail2; | ||
1348 | |||
1349 | if (!(features->quirks & WACOM_QUIRK_MONITOR) && | 1466 | if (!(features->quirks & WACOM_QUIRK_MONITOR) && |
1350 | (features->quirks & WACOM_QUIRK_BATTERY)) { | 1467 | (features->quirks & WACOM_QUIRK_BATTERY)) { |
1351 | error = wacom_initialize_battery(wacom); | 1468 | error = wacom_initialize_battery(wacom); |
1352 | if (error) | 1469 | if (error) |
1353 | goto fail3; | 1470 | goto fail_battery; |
1354 | } | 1471 | } |
1355 | 1472 | ||
1356 | if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { | 1473 | if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { |
1357 | error = wacom_register_inputs(wacom); | 1474 | error = wacom_register_inputs(wacom); |
1358 | if (error) | 1475 | if (error) |
1359 | goto fail4; | 1476 | goto fail_register_inputs; |
1360 | } | 1477 | } |
1361 | 1478 | ||
1362 | if (hdev->bus == BUS_BLUETOOTH) { | 1479 | if (hdev->bus == BUS_BLUETOOTH) { |
@@ -1367,16 +1484,19 @@ static int wacom_probe(struct hid_device *hdev, | |||
1367 | error); | 1484 | error); |
1368 | } | 1485 | } |
1369 | 1486 | ||
1370 | /* Note that if query fails it is not a hard failure */ | 1487 | if (features->type == HID_GENERIC) |
1371 | wacom_query_tablet_data(hdev, features); | 1488 | connect_mask |= HID_CONNECT_DRIVER; |
1372 | 1489 | ||
1373 | /* Regular HID work starts now */ | 1490 | /* Regular HID work starts now */ |
1374 | error = hid_hw_start(hdev, HID_CONNECT_HIDRAW); | 1491 | error = hid_hw_start(hdev, connect_mask); |
1375 | if (error) { | 1492 | if (error) { |
1376 | hid_err(hdev, "hw start failed\n"); | 1493 | hid_err(hdev, "hw start failed\n"); |
1377 | goto fail5; | 1494 | goto fail_hw_start; |
1378 | } | 1495 | } |
1379 | 1496 | ||
1497 | /* Note that if query fails it is not a hard failure */ | ||
1498 | wacom_query_tablet_data(hdev, features); | ||
1499 | |||
1380 | if (features->quirks & WACOM_QUIRK_MONITOR) | 1500 | if (features->quirks & WACOM_QUIRK_MONITOR) |
1381 | error = hid_hw_open(hdev); | 1501 | error = hid_hw_open(hdev); |
1382 | 1502 | ||
@@ -1387,13 +1507,21 @@ static int wacom_probe(struct hid_device *hdev, | |||
1387 | 1507 | ||
1388 | return 0; | 1508 | return 0; |
1389 | 1509 | ||
1390 | fail5: if (hdev->bus == BUS_BLUETOOTH) | 1510 | fail_hw_start: |
1511 | if (hdev->bus == BUS_BLUETOOTH) | ||
1391 | device_remove_file(&hdev->dev, &dev_attr_speed); | 1512 | device_remove_file(&hdev->dev, &dev_attr_speed); |
1392 | wacom_unregister_inputs(wacom); | 1513 | fail_register_inputs: |
1393 | fail4: wacom_destroy_battery(wacom); | 1514 | wacom_clean_inputs(wacom); |
1394 | fail3: wacom_destroy_leds(wacom); | 1515 | wacom_destroy_battery(wacom); |
1395 | fail2: wacom_remove_shared_data(wacom_wac); | 1516 | fail_battery: |
1396 | fail1: kfree(wacom); | 1517 | wacom_remove_shared_data(wacom_wac); |
1518 | fail_shared_data: | ||
1519 | wacom_clean_inputs(wacom); | ||
1520 | fail_allocate_inputs: | ||
1521 | fail_type: | ||
1522 | fail_pktlen: | ||
1523 | fail_parse: | ||
1524 | kfree(wacom); | ||
1397 | hid_set_drvdata(hdev, NULL); | 1525 | hid_set_drvdata(hdev, NULL); |
1398 | return error; | 1526 | return error; |
1399 | } | 1527 | } |
@@ -1405,11 +1533,10 @@ static void wacom_remove(struct hid_device *hdev) | |||
1405 | hid_hw_stop(hdev); | 1533 | hid_hw_stop(hdev); |
1406 | 1534 | ||
1407 | cancel_work_sync(&wacom->work); | 1535 | cancel_work_sync(&wacom->work); |
1408 | wacom_unregister_inputs(wacom); | 1536 | wacom_clean_inputs(wacom); |
1409 | if (hdev->bus == BUS_BLUETOOTH) | 1537 | if (hdev->bus == BUS_BLUETOOTH) |
1410 | device_remove_file(&hdev->dev, &dev_attr_speed); | 1538 | device_remove_file(&hdev->dev, &dev_attr_speed); |
1411 | wacom_destroy_battery(wacom); | 1539 | wacom_destroy_battery(wacom); |
1412 | wacom_destroy_leds(wacom); | ||
1413 | wacom_remove_shared_data(&wacom->wacom_wac); | 1540 | wacom_remove_shared_data(&wacom->wacom_wac); |
1414 | 1541 | ||
1415 | hid_set_drvdata(hdev, NULL); | 1542 | hid_set_drvdata(hdev, NULL); |
@@ -1444,6 +1571,8 @@ static struct hid_driver wacom_driver = { | |||
1444 | .id_table = wacom_ids, | 1571 | .id_table = wacom_ids, |
1445 | .probe = wacom_probe, | 1572 | .probe = wacom_probe, |
1446 | .remove = wacom_remove, | 1573 | .remove = wacom_remove, |
1574 | .event = wacom_wac_event, | ||
1575 | .report = wacom_wac_report, | ||
1447 | #ifdef CONFIG_PM | 1576 | #ifdef CONFIG_PM |
1448 | .resume = wacom_resume, | 1577 | .resume = wacom_resume, |
1449 | .reset_resume = wacom_reset_resume, | 1578 | .reset_resume = wacom_reset_resume, |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index aa6a08eb7ad6..586b2405b0d4 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -1248,6 +1248,296 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
1248 | return 0; | 1248 | return 0; |
1249 | } | 1249 | } |
1250 | 1250 | ||
1251 | static void wacom_map_usage(struct wacom *wacom, struct hid_usage *usage, | ||
1252 | struct hid_field *field, __u8 type, __u16 code, int fuzz) | ||
1253 | { | ||
1254 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1255 | struct input_dev *input = wacom_wac->input; | ||
1256 | int fmin = field->logical_minimum; | ||
1257 | int fmax = field->logical_maximum; | ||
1258 | |||
1259 | usage->type = type; | ||
1260 | usage->code = code; | ||
1261 | |||
1262 | set_bit(type, input->evbit); | ||
1263 | |||
1264 | switch (type) { | ||
1265 | case EV_ABS: | ||
1266 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); | ||
1267 | input_abs_set_res(input, code, | ||
1268 | hidinput_calc_abs_res(field, code)); | ||
1269 | break; | ||
1270 | case EV_KEY: | ||
1271 | input_set_capability(input, EV_KEY, code); | ||
1272 | break; | ||
1273 | case EV_MSC: | ||
1274 | input_set_capability(input, EV_MSC, code); | ||
1275 | break; | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1279 | static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, | ||
1280 | struct hid_field *field, struct hid_usage *usage) | ||
1281 | { | ||
1282 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1283 | |||
1284 | switch (usage->hid) { | ||
1285 | case HID_GD_X: | ||
1286 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); | ||
1287 | break; | ||
1288 | case HID_GD_Y: | ||
1289 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); | ||
1290 | break; | ||
1291 | case HID_DG_TIPPRESSURE: | ||
1292 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_PRESSURE, 0); | ||
1293 | break; | ||
1294 | case HID_DG_INRANGE: | ||
1295 | wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOOL_PEN, 0); | ||
1296 | break; | ||
1297 | case HID_DG_INVERT: | ||
1298 | wacom_map_usage(wacom, usage, field, EV_KEY, | ||
1299 | BTN_TOOL_RUBBER, 0); | ||
1300 | break; | ||
1301 | case HID_DG_ERASER: | ||
1302 | case HID_DG_TIPSWITCH: | ||
1303 | wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); | ||
1304 | break; | ||
1305 | case HID_DG_BARRELSWITCH: | ||
1306 | wacom_map_usage(wacom, usage, field, EV_KEY, BTN_STYLUS, 0); | ||
1307 | break; | ||
1308 | case HID_DG_BARRELSWITCH2: | ||
1309 | wacom_map_usage(wacom, usage, field, EV_KEY, BTN_STYLUS2, 0); | ||
1310 | break; | ||
1311 | case HID_DG_TOOLSERIALNUMBER: | ||
1312 | wacom_map_usage(wacom, usage, field, EV_MSC, MSC_SERIAL, 0); | ||
1313 | break; | ||
1314 | } | ||
1315 | } | ||
1316 | |||
1317 | static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, | ||
1318 | struct hid_usage *usage, __s32 value) | ||
1319 | { | ||
1320 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1321 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1322 | struct input_dev *input = wacom_wac->input; | ||
1323 | |||
1324 | /* checking which Tool / tip switch to send */ | ||
1325 | switch (usage->hid) { | ||
1326 | case HID_DG_INRANGE: | ||
1327 | wacom_wac->hid_data.inrange_state = value; | ||
1328 | return 0; | ||
1329 | case HID_DG_INVERT: | ||
1330 | wacom_wac->hid_data.invert_state = value; | ||
1331 | return 0; | ||
1332 | case HID_DG_ERASER: | ||
1333 | case HID_DG_TIPSWITCH: | ||
1334 | wacom_wac->hid_data.tipswitch |= value; | ||
1335 | return 0; | ||
1336 | } | ||
1337 | |||
1338 | /* send pen events only when touch is up or forced out */ | ||
1339 | if (!usage->type || wacom_wac->shared->touch_down) | ||
1340 | return 0; | ||
1341 | |||
1342 | input_event(input, usage->type, usage->code, value); | ||
1343 | |||
1344 | return 0; | ||
1345 | } | ||
1346 | |||
1347 | static void wacom_wac_pen_report(struct hid_device *hdev, | ||
1348 | struct hid_report *report) | ||
1349 | { | ||
1350 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1351 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1352 | struct input_dev *input = wacom_wac->input; | ||
1353 | bool prox = wacom_wac->hid_data.inrange_state; | ||
1354 | |||
1355 | if (!wacom_wac->shared->stylus_in_proximity) /* first in prox */ | ||
1356 | /* Going into proximity select tool */ | ||
1357 | wacom_wac->tool[0] = wacom_wac->hid_data.invert_state ? | ||
1358 | BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
1359 | |||
1360 | /* keep pen state for touch events */ | ||
1361 | wacom_wac->shared->stylus_in_proximity = prox; | ||
1362 | |||
1363 | /* send pen events only when touch is up or forced out */ | ||
1364 | if (!wacom_wac->shared->touch_down) { | ||
1365 | input_report_key(input, BTN_TOUCH, | ||
1366 | wacom_wac->hid_data.tipswitch); | ||
1367 | input_report_key(input, wacom_wac->tool[0], prox); | ||
1368 | |||
1369 | wacom_wac->hid_data.tipswitch = false; | ||
1370 | |||
1371 | input_sync(input); | ||
1372 | } | ||
1373 | } | ||
1374 | |||
1375 | static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, | ||
1376 | struct hid_field *field, struct hid_usage *usage) | ||
1377 | { | ||
1378 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1379 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1380 | struct input_dev *input = wacom_wac->input; | ||
1381 | unsigned touch_max = wacom_wac->features.touch_max; | ||
1382 | |||
1383 | switch (usage->hid) { | ||
1384 | case HID_GD_X: | ||
1385 | if (touch_max == 1) | ||
1386 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); | ||
1387 | else | ||
1388 | wacom_map_usage(wacom, usage, field, EV_ABS, | ||
1389 | ABS_MT_POSITION_X, 4); | ||
1390 | break; | ||
1391 | case HID_GD_Y: | ||
1392 | if (touch_max == 1) | ||
1393 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); | ||
1394 | else | ||
1395 | wacom_map_usage(wacom, usage, field, EV_ABS, | ||
1396 | ABS_MT_POSITION_Y, 4); | ||
1397 | break; | ||
1398 | case HID_DG_CONTACTID: | ||
1399 | input_mt_init_slots(input, wacom_wac->features.touch_max, | ||
1400 | INPUT_MT_DIRECT); | ||
1401 | break; | ||
1402 | case HID_DG_INRANGE: | ||
1403 | break; | ||
1404 | case HID_DG_INVERT: | ||
1405 | break; | ||
1406 | case HID_DG_TIPSWITCH: | ||
1407 | wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); | ||
1408 | break; | ||
1409 | } | ||
1410 | } | ||
1411 | |||
1412 | static int wacom_wac_finger_event(struct hid_device *hdev, | ||
1413 | struct hid_field *field, struct hid_usage *usage, __s32 value) | ||
1414 | { | ||
1415 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1416 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1417 | |||
1418 | switch (usage->hid) { | ||
1419 | case HID_GD_X: | ||
1420 | wacom_wac->hid_data.x = value; | ||
1421 | break; | ||
1422 | case HID_GD_Y: | ||
1423 | wacom_wac->hid_data.y = value; | ||
1424 | break; | ||
1425 | case HID_DG_CONTACTID: | ||
1426 | wacom_wac->hid_data.id = value; | ||
1427 | break; | ||
1428 | case HID_DG_TIPSWITCH: | ||
1429 | wacom_wac->hid_data.tipswitch = value; | ||
1430 | break; | ||
1431 | } | ||
1432 | |||
1433 | |||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac, | ||
1438 | struct input_dev *input, bool touch) | ||
1439 | { | ||
1440 | int slot; | ||
1441 | struct hid_data *hid_data = &wacom_wac->hid_data; | ||
1442 | |||
1443 | slot = input_mt_get_slot_by_key(input, hid_data->id); | ||
1444 | |||
1445 | input_mt_slot(input, slot); | ||
1446 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | ||
1447 | if (touch) { | ||
1448 | input_report_abs(input, ABS_MT_POSITION_X, hid_data->x); | ||
1449 | input_report_abs(input, ABS_MT_POSITION_Y, hid_data->y); | ||
1450 | } | ||
1451 | input_mt_sync_frame(input); | ||
1452 | } | ||
1453 | |||
1454 | static void wacom_wac_finger_single_touch_report(struct wacom_wac *wacom_wac, | ||
1455 | struct input_dev *input, bool touch) | ||
1456 | { | ||
1457 | struct hid_data *hid_data = &wacom_wac->hid_data; | ||
1458 | |||
1459 | if (touch) { | ||
1460 | input_report_abs(input, ABS_X, hid_data->x); | ||
1461 | input_report_abs(input, ABS_Y, hid_data->y); | ||
1462 | } | ||
1463 | input_report_key(input, BTN_TOUCH, touch); | ||
1464 | } | ||
1465 | |||
1466 | static void wacom_wac_finger_report(struct hid_device *hdev, | ||
1467 | struct hid_report *report) | ||
1468 | { | ||
1469 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1470 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1471 | struct input_dev *input = wacom_wac->input; | ||
1472 | bool touch = wacom_wac->hid_data.tipswitch && | ||
1473 | !wacom_wac->shared->stylus_in_proximity; | ||
1474 | unsigned touch_max = wacom_wac->features.touch_max; | ||
1475 | |||
1476 | if (touch_max > 1) | ||
1477 | wacom_wac_finger_mt_report(wacom_wac, input, touch); | ||
1478 | else | ||
1479 | wacom_wac_finger_single_touch_report(wacom_wac, input, touch); | ||
1480 | input_sync(input); | ||
1481 | |||
1482 | /* keep touch state for pen event */ | ||
1483 | wacom_wac->shared->touch_down = touch; | ||
1484 | } | ||
1485 | |||
1486 | #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ | ||
1487 | ((f)->physical == HID_DG_STYLUS)) | ||
1488 | #define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \ | ||
1489 | ((f)->physical == HID_DG_FINGER)) | ||
1490 | |||
1491 | void wacom_wac_usage_mapping(struct hid_device *hdev, | ||
1492 | struct hid_field *field, struct hid_usage *usage) | ||
1493 | { | ||
1494 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1495 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1496 | struct input_dev *input = wacom_wac->input; | ||
1497 | |||
1498 | /* currently, only direct devices have proper hid report descriptors */ | ||
1499 | __set_bit(INPUT_PROP_DIRECT, input->propbit); | ||
1500 | |||
1501 | if (WACOM_PEN_FIELD(field)) | ||
1502 | return wacom_wac_pen_usage_mapping(hdev, field, usage); | ||
1503 | |||
1504 | if (WACOM_FINGER_FIELD(field)) | ||
1505 | return wacom_wac_finger_usage_mapping(hdev, field, usage); | ||
1506 | } | ||
1507 | |||
1508 | int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, | ||
1509 | struct hid_usage *usage, __s32 value) | ||
1510 | { | ||
1511 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1512 | |||
1513 | if (wacom->wacom_wac.features.type != HID_GENERIC) | ||
1514 | return 0; | ||
1515 | |||
1516 | if (WACOM_PEN_FIELD(field)) | ||
1517 | return wacom_wac_pen_event(hdev, field, usage, value); | ||
1518 | |||
1519 | if (WACOM_FINGER_FIELD(field)) | ||
1520 | return wacom_wac_finger_event(hdev, field, usage, value); | ||
1521 | |||
1522 | return 0; | ||
1523 | } | ||
1524 | |||
1525 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | ||
1526 | { | ||
1527 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1528 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1529 | struct hid_field *field = report->field[0]; | ||
1530 | |||
1531 | if (wacom_wac->features.type != HID_GENERIC) | ||
1532 | return; | ||
1533 | |||
1534 | if (WACOM_PEN_FIELD(field)) | ||
1535 | return wacom_wac_pen_report(hdev, report); | ||
1536 | |||
1537 | if (WACOM_FINGER_FIELD(field)) | ||
1538 | return wacom_wac_finger_report(hdev, report); | ||
1539 | } | ||
1540 | |||
1251 | static int wacom_bpt_touch(struct wacom_wac *wacom) | 1541 | static int wacom_bpt_touch(struct wacom_wac *wacom) |
1252 | { | 1542 | { |
1253 | struct wacom_features *features = &wacom->features; | 1543 | struct wacom_features *features = &wacom->features; |
@@ -1746,6 +2036,10 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1746 | 2036 | ||
1747 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 2037 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
1748 | 2038 | ||
2039 | if (features->type == HID_GENERIC) | ||
2040 | /* setup has already been done */ | ||
2041 | return 0; | ||
2042 | |||
1749 | __set_bit(BTN_TOUCH, input_dev->keybit); | 2043 | __set_bit(BTN_TOUCH, input_dev->keybit); |
1750 | __set_bit(ABS_MISC, input_dev->absbit); | 2044 | __set_bit(ABS_MISC, input_dev->absbit); |
1751 | 2045 | ||
@@ -1990,6 +2284,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
1990 | input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0); | 2284 | input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0); |
1991 | input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0); | 2285 | input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0); |
1992 | 2286 | ||
2287 | /* kept for making udev and libwacom accepting the pad */ | ||
2288 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
2289 | |||
1993 | switch (features->type) { | 2290 | switch (features->type) { |
1994 | case GRAPHIRE_BT: | 2291 | case GRAPHIRE_BT: |
1995 | __set_bit(BTN_0, input_dev->keybit); | 2292 | __set_bit(BTN_0, input_dev->keybit); |
@@ -2573,6 +2870,17 @@ static const struct wacom_features wacom_features_0x309 = | |||
2573 | { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ | 2870 | { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ |
2574 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10, | 2871 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10, |
2575 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2872 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2873 | static const struct wacom_features wacom_features_0x30A = | ||
2874 | { "Wacom ISDv5 30A", 59352, 33648, 2047, 63, | ||
2875 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, | ||
2876 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C }; | ||
2877 | static const struct wacom_features wacom_features_0x30C = | ||
2878 | { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */ | ||
2879 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, | ||
2880 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | ||
2881 | |||
2882 | static const struct wacom_features wacom_features_HID_ANY_ID = | ||
2883 | { "Wacom HID", .type = HID_GENERIC }; | ||
2576 | 2884 | ||
2577 | #define USB_DEVICE_WACOM(prod) \ | 2885 | #define USB_DEVICE_WACOM(prod) \ |
2578 | HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ | 2886 | HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ |
@@ -2708,6 +3016,8 @@ const struct hid_device_id wacom_ids[] = { | |||
2708 | { USB_DEVICE_WACOM(0x304) }, | 3016 | { USB_DEVICE_WACOM(0x304) }, |
2709 | { USB_DEVICE_WACOM(0x307) }, | 3017 | { USB_DEVICE_WACOM(0x307) }, |
2710 | { USB_DEVICE_WACOM(0x309) }, | 3018 | { USB_DEVICE_WACOM(0x309) }, |
3019 | { USB_DEVICE_WACOM(0x30A) }, | ||
3020 | { USB_DEVICE_WACOM(0x30C) }, | ||
2711 | { USB_DEVICE_WACOM(0x30E) }, | 3021 | { USB_DEVICE_WACOM(0x30E) }, |
2712 | { USB_DEVICE_WACOM(0x314) }, | 3022 | { USB_DEVICE_WACOM(0x314) }, |
2713 | { USB_DEVICE_WACOM(0x315) }, | 3023 | { USB_DEVICE_WACOM(0x315) }, |
@@ -2716,6 +3026,8 @@ const struct hid_device_id wacom_ids[] = { | |||
2716 | { USB_DEVICE_WACOM(0x4004) }, | 3026 | { USB_DEVICE_WACOM(0x4004) }, |
2717 | { USB_DEVICE_WACOM(0x5000) }, | 3027 | { USB_DEVICE_WACOM(0x5000) }, |
2718 | { USB_DEVICE_WACOM(0x5002) }, | 3028 | { USB_DEVICE_WACOM(0x5002) }, |
3029 | |||
3030 | { USB_DEVICE_WACOM(HID_ANY_ID) }, | ||
2719 | { } | 3031 | { } |
2720 | }; | 3032 | }; |
2721 | MODULE_DEVICE_TABLE(hid, wacom_ids); | 3033 | MODULE_DEVICE_TABLE(hid, wacom_ids); |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 339ab5d81a2d..0f0b85ec1322 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -113,6 +113,7 @@ enum { | |||
113 | MTSCREEN, | 113 | MTSCREEN, |
114 | MTTPC, | 114 | MTTPC, |
115 | MTTPC_B, | 115 | MTTPC_B, |
116 | HID_GENERIC, | ||
116 | MAX_TYPE | 117 | MAX_TYPE |
117 | }; | 118 | }; |
118 | 119 | ||
@@ -154,6 +155,20 @@ struct wacom_shared { | |||
154 | struct input_dev *touch_input; | 155 | struct input_dev *touch_input; |
155 | }; | 156 | }; |
156 | 157 | ||
158 | struct hid_data { | ||
159 | __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ | ||
160 | __s16 inputmode_index; /* InputMode HID feature index in the report */ | ||
161 | bool inrange_state; | ||
162 | bool invert_state; | ||
163 | bool tipswitch; | ||
164 | int x; | ||
165 | int y; | ||
166 | int pressure; | ||
167 | int width; | ||
168 | int height; | ||
169 | int id; | ||
170 | }; | ||
171 | |||
157 | struct wacom_wac { | 172 | struct wacom_wac { |
158 | char name[WACOM_NAME_MAX]; | 173 | char name[WACOM_NAME_MAX]; |
159 | char pad_name[WACOM_NAME_MAX]; | 174 | char pad_name[WACOM_NAME_MAX]; |
@@ -167,6 +182,7 @@ struct wacom_wac { | |||
167 | struct wacom_shared *shared; | 182 | struct wacom_shared *shared; |
168 | struct input_dev *input; | 183 | struct input_dev *input; |
169 | struct input_dev *pad_input; | 184 | struct input_dev *pad_input; |
185 | bool input_registered; | ||
170 | int pid; | 186 | int pid; |
171 | int battery_capacity; | 187 | int battery_capacity; |
172 | int num_contacts_left; | 188 | int num_contacts_left; |
@@ -174,6 +190,7 @@ struct wacom_wac { | |||
174 | int ps_connected; | 190 | int ps_connected; |
175 | u8 bt_features; | 191 | u8 bt_features; |
176 | u8 bt_high_speed; | 192 | u8 bt_high_speed; |
193 | struct hid_data hid_data; | ||
177 | }; | 194 | }; |
178 | 195 | ||
179 | #endif | 196 | #endif |
diff --git a/include/linux/hid.h b/include/linux/hid.h index f53c4a9cca1d..78ea9bf941cd 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -265,6 +265,7 @@ struct hid_item { | |||
265 | #define HID_CONNECT_HIDDEV 0x08 | 265 | #define HID_CONNECT_HIDDEV 0x08 |
266 | #define HID_CONNECT_HIDDEV_FORCE 0x10 | 266 | #define HID_CONNECT_HIDDEV_FORCE 0x10 |
267 | #define HID_CONNECT_FF 0x20 | 267 | #define HID_CONNECT_FF 0x20 |
268 | #define HID_CONNECT_DRIVER 0x40 | ||
268 | #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ | 269 | #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ |
269 | HID_CONNECT_HIDDEV|HID_CONNECT_FF) | 270 | HID_CONNECT_HIDDEV|HID_CONNECT_FF) |
270 | 271 | ||
@@ -287,6 +288,7 @@ struct hid_item { | |||
287 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 | 288 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 |
288 | #define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 | 289 | #define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 |
289 | #define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200 | 290 | #define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200 |
291 | #define HID_QUIRK_ALWAYS_POLL 0x00000400 | ||
290 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 292 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
291 | #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000 | 293 | #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000 |
292 | #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000 | 294 | #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000 |
@@ -440,6 +442,7 @@ struct hid_output_fifo { | |||
440 | #define HID_CLAIMED_INPUT 1 | 442 | #define HID_CLAIMED_INPUT 1 |
441 | #define HID_CLAIMED_HIDDEV 2 | 443 | #define HID_CLAIMED_HIDDEV 2 |
442 | #define HID_CLAIMED_HIDRAW 4 | 444 | #define HID_CLAIMED_HIDRAW 4 |
445 | #define HID_CLAIMED_DRIVER 8 | ||
443 | 446 | ||
444 | #define HID_STAT_ADDED 1 | 447 | #define HID_STAT_ADDED 1 |
445 | #define HID_STAT_PARSED 2 | 448 | #define HID_STAT_PARSED 2 |
diff --git a/include/uapi/linux/uhid.h b/include/uapi/linux/uhid.h index 1e3b09c191cd..aaa86d6bd1dd 100644 --- a/include/uapi/linux/uhid.h +++ b/include/uapi/linux/uhid.h | |||
@@ -24,35 +24,23 @@ | |||
24 | #include <linux/hid.h> | 24 | #include <linux/hid.h> |
25 | 25 | ||
26 | enum uhid_event_type { | 26 | enum uhid_event_type { |
27 | UHID_CREATE, | 27 | __UHID_LEGACY_CREATE, |
28 | UHID_DESTROY, | 28 | UHID_DESTROY, |
29 | UHID_START, | 29 | UHID_START, |
30 | UHID_STOP, | 30 | UHID_STOP, |
31 | UHID_OPEN, | 31 | UHID_OPEN, |
32 | UHID_CLOSE, | 32 | UHID_CLOSE, |
33 | UHID_OUTPUT, | 33 | UHID_OUTPUT, |
34 | UHID_OUTPUT_EV, /* obsolete! */ | 34 | __UHID_LEGACY_OUTPUT_EV, |
35 | UHID_INPUT, | 35 | __UHID_LEGACY_INPUT, |
36 | UHID_FEATURE, | 36 | UHID_GET_REPORT, |
37 | UHID_FEATURE_ANSWER, | 37 | UHID_GET_REPORT_REPLY, |
38 | UHID_CREATE2, | 38 | UHID_CREATE2, |
39 | UHID_INPUT2, | 39 | UHID_INPUT2, |
40 | UHID_SET_REPORT, | ||
41 | UHID_SET_REPORT_REPLY, | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | struct uhid_create_req { | ||
43 | __u8 name[128]; | ||
44 | __u8 phys[64]; | ||
45 | __u8 uniq[64]; | ||
46 | __u8 __user *rd_data; | ||
47 | __u16 rd_size; | ||
48 | |||
49 | __u16 bus; | ||
50 | __u32 vendor; | ||
51 | __u32 product; | ||
52 | __u32 version; | ||
53 | __u32 country; | ||
54 | } __attribute__((__packed__)); | ||
55 | |||
56 | struct uhid_create2_req { | 44 | struct uhid_create2_req { |
57 | __u8 name[128]; | 45 | __u8 name[128]; |
58 | __u8 phys[64]; | 46 | __u8 phys[64]; |
@@ -66,6 +54,16 @@ struct uhid_create2_req { | |||
66 | __u8 rd_data[HID_MAX_DESCRIPTOR_SIZE]; | 54 | __u8 rd_data[HID_MAX_DESCRIPTOR_SIZE]; |
67 | } __attribute__((__packed__)); | 55 | } __attribute__((__packed__)); |
68 | 56 | ||
57 | enum uhid_dev_flag { | ||
58 | UHID_DEV_NUMBERED_FEATURE_REPORTS = (1ULL << 0), | ||
59 | UHID_DEV_NUMBERED_OUTPUT_REPORTS = (1ULL << 1), | ||
60 | UHID_DEV_NUMBERED_INPUT_REPORTS = (1ULL << 2), | ||
61 | }; | ||
62 | |||
63 | struct uhid_start_req { | ||
64 | __u64 dev_flags; | ||
65 | }; | ||
66 | |||
69 | #define UHID_DATA_MAX 4096 | 67 | #define UHID_DATA_MAX 4096 |
70 | 68 | ||
71 | enum uhid_report_type { | 69 | enum uhid_report_type { |
@@ -74,36 +72,94 @@ enum uhid_report_type { | |||
74 | UHID_INPUT_REPORT, | 72 | UHID_INPUT_REPORT, |
75 | }; | 73 | }; |
76 | 74 | ||
77 | struct uhid_input_req { | 75 | struct uhid_input2_req { |
76 | __u16 size; | ||
77 | __u8 data[UHID_DATA_MAX]; | ||
78 | } __attribute__((__packed__)); | ||
79 | |||
80 | struct uhid_output_req { | ||
78 | __u8 data[UHID_DATA_MAX]; | 81 | __u8 data[UHID_DATA_MAX]; |
79 | __u16 size; | 82 | __u16 size; |
83 | __u8 rtype; | ||
80 | } __attribute__((__packed__)); | 84 | } __attribute__((__packed__)); |
81 | 85 | ||
82 | struct uhid_input2_req { | 86 | struct uhid_get_report_req { |
87 | __u32 id; | ||
88 | __u8 rnum; | ||
89 | __u8 rtype; | ||
90 | } __attribute__((__packed__)); | ||
91 | |||
92 | struct uhid_get_report_reply_req { | ||
93 | __u32 id; | ||
94 | __u16 err; | ||
83 | __u16 size; | 95 | __u16 size; |
84 | __u8 data[UHID_DATA_MAX]; | 96 | __u8 data[UHID_DATA_MAX]; |
85 | } __attribute__((__packed__)); | 97 | } __attribute__((__packed__)); |
86 | 98 | ||
87 | struct uhid_output_req { | 99 | struct uhid_set_report_req { |
100 | __u32 id; | ||
101 | __u8 rnum; | ||
102 | __u8 rtype; | ||
103 | __u16 size; | ||
104 | __u8 data[UHID_DATA_MAX]; | ||
105 | } __attribute__((__packed__)); | ||
106 | |||
107 | struct uhid_set_report_reply_req { | ||
108 | __u32 id; | ||
109 | __u16 err; | ||
110 | } __attribute__((__packed__)); | ||
111 | |||
112 | /* | ||
113 | * Compat Layer | ||
114 | * All these commands and requests are obsolete. You should avoid using them in | ||
115 | * new code. We support them for backwards-compatibility, but you might not get | ||
116 | * access to new feature in case you use them. | ||
117 | */ | ||
118 | |||
119 | enum uhid_legacy_event_type { | ||
120 | UHID_CREATE = __UHID_LEGACY_CREATE, | ||
121 | UHID_OUTPUT_EV = __UHID_LEGACY_OUTPUT_EV, | ||
122 | UHID_INPUT = __UHID_LEGACY_INPUT, | ||
123 | UHID_FEATURE = UHID_GET_REPORT, | ||
124 | UHID_FEATURE_ANSWER = UHID_GET_REPORT_REPLY, | ||
125 | }; | ||
126 | |||
127 | /* Obsolete! Use UHID_CREATE2. */ | ||
128 | struct uhid_create_req { | ||
129 | __u8 name[128]; | ||
130 | __u8 phys[64]; | ||
131 | __u8 uniq[64]; | ||
132 | __u8 __user *rd_data; | ||
133 | __u16 rd_size; | ||
134 | |||
135 | __u16 bus; | ||
136 | __u32 vendor; | ||
137 | __u32 product; | ||
138 | __u32 version; | ||
139 | __u32 country; | ||
140 | } __attribute__((__packed__)); | ||
141 | |||
142 | /* Obsolete! Use UHID_INPUT2. */ | ||
143 | struct uhid_input_req { | ||
88 | __u8 data[UHID_DATA_MAX]; | 144 | __u8 data[UHID_DATA_MAX]; |
89 | __u16 size; | 145 | __u16 size; |
90 | __u8 rtype; | ||
91 | } __attribute__((__packed__)); | 146 | } __attribute__((__packed__)); |
92 | 147 | ||
93 | /* Obsolete! Newer kernels will no longer send these events but instead convert | 148 | /* Obsolete! Kernel uses UHID_OUTPUT exclusively now. */ |
94 | * it into raw output reports via UHID_OUTPUT. */ | ||
95 | struct uhid_output_ev_req { | 149 | struct uhid_output_ev_req { |
96 | __u16 type; | 150 | __u16 type; |
97 | __u16 code; | 151 | __u16 code; |
98 | __s32 value; | 152 | __s32 value; |
99 | } __attribute__((__packed__)); | 153 | } __attribute__((__packed__)); |
100 | 154 | ||
155 | /* Obsolete! Kernel uses ABI compatible UHID_GET_REPORT. */ | ||
101 | struct uhid_feature_req { | 156 | struct uhid_feature_req { |
102 | __u32 id; | 157 | __u32 id; |
103 | __u8 rnum; | 158 | __u8 rnum; |
104 | __u8 rtype; | 159 | __u8 rtype; |
105 | } __attribute__((__packed__)); | 160 | } __attribute__((__packed__)); |
106 | 161 | ||
162 | /* Obsolete! Use ABI compatible UHID_GET_REPORT_REPLY. */ | ||
107 | struct uhid_feature_answer_req { | 163 | struct uhid_feature_answer_req { |
108 | __u32 id; | 164 | __u32 id; |
109 | __u16 err; | 165 | __u16 err; |
@@ -111,6 +167,15 @@ struct uhid_feature_answer_req { | |||
111 | __u8 data[UHID_DATA_MAX]; | 167 | __u8 data[UHID_DATA_MAX]; |
112 | } __attribute__((__packed__)); | 168 | } __attribute__((__packed__)); |
113 | 169 | ||
170 | /* | ||
171 | * UHID Events | ||
172 | * All UHID events from and to the kernel are encoded as "struct uhid_event". | ||
173 | * The "type" field contains a UHID_* type identifier. All payload depends on | ||
174 | * that type and can be accessed via ev->u.XYZ accordingly. | ||
175 | * If user-space writes short events, they're extended with 0s by the kernel. If | ||
176 | * the kernel writes short events, user-space shall extend them with 0s. | ||
177 | */ | ||
178 | |||
114 | struct uhid_event { | 179 | struct uhid_event { |
115 | __u32 type; | 180 | __u32 type; |
116 | 181 | ||
@@ -120,9 +185,14 @@ struct uhid_event { | |||
120 | struct uhid_output_req output; | 185 | struct uhid_output_req output; |
121 | struct uhid_output_ev_req output_ev; | 186 | struct uhid_output_ev_req output_ev; |
122 | struct uhid_feature_req feature; | 187 | struct uhid_feature_req feature; |
188 | struct uhid_get_report_req get_report; | ||
123 | struct uhid_feature_answer_req feature_answer; | 189 | struct uhid_feature_answer_req feature_answer; |
190 | struct uhid_get_report_reply_req get_report_reply; | ||
124 | struct uhid_create2_req create2; | 191 | struct uhid_create2_req create2; |
125 | struct uhid_input2_req input2; | 192 | struct uhid_input2_req input2; |
193 | struct uhid_set_report_req set_report; | ||
194 | struct uhid_set_report_reply_req set_report_reply; | ||
195 | struct uhid_start_req start; | ||
126 | } u; | 196 | } u; |
127 | } __attribute__((__packed__)); | 197 | } __attribute__((__packed__)); |
128 | 198 | ||