diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-02 21:07:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-02 21:07:04 -0400 |
commit | 7af4c727c7b6104f94f2ffc3d0899e75a9cc1e55 (patch) | |
tree | dc93871a09965c976b19247e4a8832dae0cc7e20 | |
parent | 68fed41e0ff6c0332520a0d70ac05be2a7d9130e (diff) | |
parent | 4d6ca227c768b50b05cf183974b40abe444e9d0c (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID subsystem updates from Jiri Kosina:
- The need for HID_QUIRK_NO_INIT_REPORTS per-device quirk has been
growing dramatically during past years, so the time has come to
switch over the default, and perform the pro-active reading only in
cases where it's really needed (multitouch, wacom).
The only place where this behavior is (in some form) preserved is
hiddev so that we don't introduce userspace-visible change of
behavior.
From Benjamin Tissoires
- HID++ support for power_supply / baterry reporting.
From Benjamin Tissoires and Bastien Nocera
- Vast improvements / rework of DS3 and DS4 in Sony driver.
From Roderick Colenbrander
- Improvment (in terms of getting closer to the Microsoft's
interpretation of slightly ambiguous specification) of logical range
interpretation in case null-state is set in the rdesc.
From Valtteri Heikkilä and Tomasz Kramkowski
- A lot of newly supported device IDs and small assorted fixes
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (71 commits)
HID: usbhid: Add HID_QUIRK_NOGET for Aten CS-1758 KVM switch
HID: asus: support backlight on USB keyboards
HID: wacom: Move wacom_remote_irq and wacom_remote_status_irq
HID: wacom: generic: sync pad events only for actual packets
HID: sony: remove redundant check for -ve err
HID: sony: Make sure to unregister sensors on failure
HID: sony: Make DS4 bt poll interval adjustable
HID: sony: Set proper bit flags on DS4 output report
HID: sony: DS4 use brighter LED colors
HID: sony: Improve navigation controller axis/button mapping
HID: sony: Use DS3 MAC address as unique identifier on USB
HID: logitech-hidpp: add a sysfs file to tell we support power_supply
HID: logitech-hidpp: enable HID++ 1.0 battery reporting
HID: logitech-hidpp: add support for battery status for the K750
HID: logitech-hidpp: battery: provide CAPACITY_LEVEL
HID: logitech-hidpp: rename battery level into capacity
HID: logitech-hidpp: battery: provide ONLINE property
HID: logitech-hidpp: notify battery on connect
HID: logitech-hidpp: return an error if the queried feature is not present
HID: logitech-hidpp: create the battery for all types of HID++ devices
...
30 files changed, 2490 insertions, 1129 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 8d676d2a48ac..e4c9e0e46b95 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -4127,6 +4127,9 @@ | |||
4127 | usbhid.mousepoll= | 4127 | usbhid.mousepoll= |
4128 | [USBHID] The interval which mice are to be polled at. | 4128 | [USBHID] The interval which mice are to be polled at. |
4129 | 4129 | ||
4130 | usbhid.jspoll= | ||
4131 | [USBHID] The interval which joysticks are to be polled at. | ||
4132 | |||
4130 | usb-storage.delay_use= | 4133 | usb-storage.delay_use= |
4131 | [UMS] The delay in seconds before a new device is | 4134 | [UMS] The delay in seconds before a new device is |
4132 | scanned for Logical Units (default 1). | 4135 | scanned for Logical Units (default 1). |
diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt b/Documentation/devicetree/bindings/input/hid-over-i2c.txt index 488edcb264c4..28e8bd8b7d64 100644 --- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt +++ b/Documentation/devicetree/bindings/input/hid-over-i2c.txt | |||
@@ -17,6 +17,22 @@ Required properties: | |||
17 | - interrupt-parent: the phandle for the interrupt controller | 17 | - interrupt-parent: the phandle for the interrupt controller |
18 | - interrupts: interrupt line | 18 | - interrupts: interrupt line |
19 | 19 | ||
20 | Additional optional properties: | ||
21 | |||
22 | Some devices may support additional optional properties to help with, e.g., | ||
23 | power sequencing. The following properties can be supported by one or more | ||
24 | device-specific compatible properties, which should be used in addition to the | ||
25 | "hid-over-i2c" string. | ||
26 | |||
27 | - compatible: | ||
28 | * "wacom,w9013" (Wacom W9013 digitizer). Supports: | ||
29 | - vdd-supply | ||
30 | - post-power-on-delay-ms | ||
31 | |||
32 | - vdd-supply: phandle of the regulator that provides the supply voltage. | ||
33 | - post-power-on-delay-ms: time required by the device after enabling its regulators | ||
34 | before it is ready for communication. Must be used with 'vdd-supply'. | ||
35 | |||
20 | Example: | 36 | Example: |
21 | 37 | ||
22 | i2c-hid-dev@2c { | 38 | i2c-hid-dev@2c { |
diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt index 36ea940e5bb9..575415f4cef0 100644 --- a/Documentation/input/event-codes.txt +++ b/Documentation/input/event-codes.txt | |||
@@ -301,7 +301,10 @@ them as any other INPUT_PROP_BUTTONPAD device. | |||
301 | INPUT_PROP_ACCELEROMETER | 301 | INPUT_PROP_ACCELEROMETER |
302 | ------------------------- | 302 | ------------------------- |
303 | Directional axes on this device (absolute and/or relative x, y, z) represent | 303 | Directional axes on this device (absolute and/or relative x, y, z) represent |
304 | accelerometer data. All other axes retain their meaning. A device must not mix | 304 | accelerometer data. Some devices also report gyroscope data, which devices |
305 | can report through the rotational axes (absolute and/or relative rx, ry, rz). | ||
306 | |||
307 | All other axes retain their meaning. A device must not mix | ||
305 | regular directional axes and accelerometer axes on the same event node. | 308 | regular directional axes and accelerometer axes on the same event node. |
306 | 309 | ||
307 | Guidelines: | 310 | Guidelines: |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8c54cb8f5d6d..fe40e5e499dd 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -98,6 +98,18 @@ config HID_A4TECH | |||
98 | ---help--- | 98 | ---help--- |
99 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. | 99 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. |
100 | 100 | ||
101 | config HID_ACCUTOUCH | ||
102 | tristate "Accutouch touch device" | ||
103 | depends on USB_HID | ||
104 | ---help--- | ||
105 | This selects a driver for the Accutouch 2216 touch controller. | ||
106 | |||
107 | The driver works around a problem in the reported device capabilities | ||
108 | which causes userspace to detect the device as a mouse rather than | ||
109 | a touchscreen. | ||
110 | |||
111 | Say Y here if you have a Accutouch 2216 touch controller. | ||
112 | |||
101 | config HID_ACRUX | 113 | config HID_ACRUX |
102 | tristate "ACRUX game controller support" | 114 | tristate "ACRUX game controller support" |
103 | depends on HID | 115 | depends on HID |
@@ -136,13 +148,16 @@ config HID_APPLEIR | |||
136 | 148 | ||
137 | config HID_ASUS | 149 | config HID_ASUS |
138 | tristate "Asus" | 150 | tristate "Asus" |
139 | depends on I2C_HID | 151 | depends on LEDS_CLASS |
140 | ---help--- | 152 | ---help--- |
141 | Support for Asus notebook built-in keyboard and touchpad via i2c. | 153 | Support for Asus notebook built-in keyboard and touchpad via i2c, and |
154 | the Asus Republic of Gamers laptop keyboard special keys. | ||
142 | 155 | ||
143 | Supported devices: | 156 | Supported devices: |
144 | - EeeBook X205TA | 157 | - EeeBook X205TA |
145 | - VivoBook E200HA | 158 | - VivoBook E200HA |
159 | - GL553V series | ||
160 | - GL753V series | ||
146 | 161 | ||
147 | config HID_AUREAL | 162 | config HID_AUREAL |
148 | tristate "Aureal" | 163 | tristate "Aureal" |
@@ -215,7 +230,8 @@ config HID_CMEDIA | |||
215 | 230 | ||
216 | config HID_CP2112 | 231 | config HID_CP2112 |
217 | tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support" | 232 | tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support" |
218 | depends on USB_HID && I2C && GPIOLIB && GPIOLIB_IRQCHIP | 233 | depends on USB_HID && I2C && GPIOLIB |
234 | select GPIOLIB_IRQCHIP | ||
219 | ---help--- | 235 | ---help--- |
220 | Support for Silicon Labs CP2112 HID USB to SMBus Master Bridge. | 236 | Support for Silicon Labs CP2112 HID USB to SMBus Master Bridge. |
221 | This is a HID device driver which registers as an i2c adapter | 237 | This is a HID device driver which registers as an i2c adapter |
@@ -441,6 +457,7 @@ config HID_LOGITECH_DJ | |||
441 | config HID_LOGITECH_HIDPP | 457 | config HID_LOGITECH_HIDPP |
442 | tristate "Logitech HID++ devices support" | 458 | tristate "Logitech HID++ devices support" |
443 | depends on HID_LOGITECH | 459 | depends on HID_LOGITECH |
460 | select POWER_SUPPLY | ||
444 | ---help--- | 461 | ---help--- |
445 | Support for Logitech devices relyingon the HID++ Logitech specification | 462 | Support for Logitech devices relyingon the HID++ Logitech specification |
446 | 463 | ||
@@ -581,6 +598,12 @@ config HID_MULTITOUCH | |||
581 | To compile this driver as a module, choose M here: the | 598 | To compile this driver as a module, choose M here: the |
582 | module will be called hid-multitouch. | 599 | module will be called hid-multitouch. |
583 | 600 | ||
601 | config HID_NTI | ||
602 | tristate "NTI keyboard adapters" | ||
603 | ---help--- | ||
604 | Support for the "extra" Sun keyboard keys on keyboards attached | ||
605 | through Network Technologies USB-SUN keyboard adapters. | ||
606 | |||
584 | config HID_NTRIG | 607 | config HID_NTRIG |
585 | tristate "N-Trig touch screen" | 608 | tristate "N-Trig touch screen" |
586 | depends on USB_HID | 609 | depends on USB_HID |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 4d111f23e801..fef027bc7fa3 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -21,6 +21,7 @@ hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o | |||
21 | hid-wiimote-$(CONFIG_DEBUG_FS) += hid-wiimote-debug.o | 21 | hid-wiimote-$(CONFIG_DEBUG_FS) += hid-wiimote-debug.o |
22 | 22 | ||
23 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 23 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
24 | obj-$(CONFIG_HID_ACCUTOUCH) += hid-accutouch.o | ||
24 | obj-$(CONFIG_HID_ALPS) += hid-alps.o | 25 | obj-$(CONFIG_HID_ALPS) += hid-alps.o |
25 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o | 26 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o |
26 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 27 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
@@ -62,6 +63,7 @@ obj-$(CONFIG_HID_MAYFLASH) += hid-mf.o | |||
62 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | 63 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o |
63 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 64 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
64 | obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o | 65 | obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o |
66 | obj-$(CONFIG_HID_NTI) += hid-nti.o | ||
65 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o | 67 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o |
66 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o | 68 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o |
67 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o | 69 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o |
diff --git a/drivers/hid/hid-accutouch.c b/drivers/hid/hid-accutouch.c new file mode 100644 index 000000000000..4e287160c50a --- /dev/null +++ b/drivers/hid/hid-accutouch.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * HID driver for Elo Accutouch touchscreens | ||
3 | * | ||
4 | * Copyright (c) 2016, Collabora Ltd. | ||
5 | * Copyright (c) 2016, General Electric Company | ||
6 | * | ||
7 | * based on hid-penmount.c | ||
8 | * Copyright (c) 2014 Christian Gmeiner <christian.gmeiner <at> gmail.com> | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the Free | ||
14 | * Software Foundation; either version 2 of the License, or (at your option) | ||
15 | * any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/hid.h> | ||
19 | #include <linux/module.h> | ||
20 | #include "hid-ids.h" | ||
21 | |||
22 | static int accutouch_input_mapping(struct hid_device *hdev, | ||
23 | struct hid_input *hi, | ||
24 | struct hid_field *field, | ||
25 | struct hid_usage *usage, | ||
26 | unsigned long **bit, int *max) | ||
27 | { | ||
28 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { | ||
29 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
30 | return 1; | ||
31 | } | ||
32 | |||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static const struct hid_device_id accutouch_devices[] = { | ||
37 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) }, | ||
38 | { } | ||
39 | }; | ||
40 | MODULE_DEVICE_TABLE(hid, accutouch_devices); | ||
41 | |||
42 | static struct hid_driver accutouch_driver = { | ||
43 | .name = "hid-accutouch", | ||
44 | .id_table = accutouch_devices, | ||
45 | .input_mapping = accutouch_input_mapping, | ||
46 | }; | ||
47 | |||
48 | module_hid_driver(accutouch_driver); | ||
49 | |||
50 | MODULE_AUTHOR("Martyn Welch <martyn.welch@collabora.co.uk"); | ||
51 | MODULE_DESCRIPTION("Elo Accutouch HID TouchScreen driver"); | ||
52 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 70b12f89a193..16df6cc90235 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c | |||
@@ -40,8 +40,12 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); | |||
40 | 40 | ||
41 | #define FEATURE_REPORT_ID 0x0d | 41 | #define FEATURE_REPORT_ID 0x0d |
42 | #define INPUT_REPORT_ID 0x5d | 42 | #define INPUT_REPORT_ID 0x5d |
43 | #define FEATURE_KBD_REPORT_ID 0x5a | ||
43 | 44 | ||
44 | #define INPUT_REPORT_SIZE 28 | 45 | #define INPUT_REPORT_SIZE 28 |
46 | #define FEATURE_KBD_REPORT_SIZE 16 | ||
47 | |||
48 | #define SUPPORT_KBD_BACKLIGHT BIT(0) | ||
45 | 49 | ||
46 | #define MAX_CONTACTS 5 | 50 | #define MAX_CONTACTS 5 |
47 | 51 | ||
@@ -63,18 +67,31 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); | |||
63 | #define QUIRK_NO_INIT_REPORTS BIT(1) | 67 | #define QUIRK_NO_INIT_REPORTS BIT(1) |
64 | #define QUIRK_SKIP_INPUT_MAPPING BIT(2) | 68 | #define QUIRK_SKIP_INPUT_MAPPING BIT(2) |
65 | #define QUIRK_IS_MULTITOUCH BIT(3) | 69 | #define QUIRK_IS_MULTITOUCH BIT(3) |
70 | #define QUIRK_NO_CONSUMER_USAGES BIT(4) | ||
71 | #define QUIRK_USE_KBD_BACKLIGHT BIT(5) | ||
66 | 72 | ||
67 | #define KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ | 73 | #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ |
68 | QUIRK_NO_INIT_REPORTS) | 74 | QUIRK_NO_INIT_REPORTS | \ |
69 | #define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \ | 75 | QUIRK_NO_CONSUMER_USAGES) |
76 | #define I2C_TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \ | ||
70 | QUIRK_SKIP_INPUT_MAPPING | \ | 77 | QUIRK_SKIP_INPUT_MAPPING | \ |
71 | QUIRK_IS_MULTITOUCH) | 78 | QUIRK_IS_MULTITOUCH) |
72 | 79 | ||
73 | #define TRKID_SGN ((TRKID_MAX + 1) >> 1) | 80 | #define TRKID_SGN ((TRKID_MAX + 1) >> 1) |
74 | 81 | ||
82 | struct asus_kbd_leds { | ||
83 | struct led_classdev cdev; | ||
84 | struct hid_device *hdev; | ||
85 | struct work_struct work; | ||
86 | unsigned int brightness; | ||
87 | bool removed; | ||
88 | }; | ||
89 | |||
75 | struct asus_drvdata { | 90 | struct asus_drvdata { |
76 | unsigned long quirks; | 91 | unsigned long quirks; |
77 | struct input_dev *input; | 92 | struct input_dev *input; |
93 | struct asus_kbd_leds *kbd_backlight; | ||
94 | bool enable_backlight; | ||
78 | }; | 95 | }; |
79 | 96 | ||
80 | static void asus_report_contact_down(struct input_dev *input, | 97 | static void asus_report_contact_down(struct input_dev *input, |
@@ -169,6 +186,148 @@ static int asus_raw_event(struct hid_device *hdev, | |||
169 | return 0; | 186 | return 0; |
170 | } | 187 | } |
171 | 188 | ||
189 | static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) | ||
190 | { | ||
191 | unsigned char *dmabuf; | ||
192 | int ret; | ||
193 | |||
194 | dmabuf = kmemdup(buf, buf_size, GFP_KERNEL); | ||
195 | if (!dmabuf) | ||
196 | return -ENOMEM; | ||
197 | |||
198 | ret = hid_hw_raw_request(hdev, FEATURE_KBD_REPORT_ID, dmabuf, | ||
199 | buf_size, HID_FEATURE_REPORT, | ||
200 | HID_REQ_SET_REPORT); | ||
201 | kfree(dmabuf); | ||
202 | |||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | static int asus_kbd_init(struct hid_device *hdev) | ||
207 | { | ||
208 | u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, | ||
209 | 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; | ||
210 | int ret; | ||
211 | |||
212 | ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); | ||
213 | if (ret < 0) | ||
214 | hid_err(hdev, "Asus failed to send init command: %d\n", ret); | ||
215 | |||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static int asus_kbd_get_functions(struct hid_device *hdev, | ||
220 | unsigned char *kbd_func) | ||
221 | { | ||
222 | u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; | ||
223 | u8 *readbuf; | ||
224 | int ret; | ||
225 | |||
226 | ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); | ||
227 | if (ret < 0) { | ||
228 | hid_err(hdev, "Asus failed to send configuration command: %d\n", ret); | ||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | readbuf = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL); | ||
233 | if (!readbuf) | ||
234 | return -ENOMEM; | ||
235 | |||
236 | ret = hid_hw_raw_request(hdev, FEATURE_KBD_REPORT_ID, readbuf, | ||
237 | FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT, | ||
238 | HID_REQ_GET_REPORT); | ||
239 | if (ret < 0) { | ||
240 | hid_err(hdev, "Asus failed to request functions: %d\n", ret); | ||
241 | kfree(readbuf); | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | *kbd_func = readbuf[6]; | ||
246 | |||
247 | kfree(readbuf); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static void asus_kbd_backlight_set(struct led_classdev *led_cdev, | ||
252 | enum led_brightness brightness) | ||
253 | { | ||
254 | struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, | ||
255 | cdev); | ||
256 | if (led->brightness == brightness) | ||
257 | return; | ||
258 | |||
259 | led->brightness = brightness; | ||
260 | schedule_work(&led->work); | ||
261 | } | ||
262 | |||
263 | static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev) | ||
264 | { | ||
265 | struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, | ||
266 | cdev); | ||
267 | |||
268 | return led->brightness; | ||
269 | } | ||
270 | |||
271 | static void asus_kbd_backlight_work(struct work_struct *work) | ||
272 | { | ||
273 | struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work); | ||
274 | u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 }; | ||
275 | int ret; | ||
276 | |||
277 | if (led->removed) | ||
278 | return; | ||
279 | |||
280 | buf[4] = led->brightness; | ||
281 | |||
282 | ret = asus_kbd_set_report(led->hdev, buf, sizeof(buf)); | ||
283 | if (ret < 0) | ||
284 | hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret); | ||
285 | } | ||
286 | |||
287 | static int asus_kbd_register_leds(struct hid_device *hdev) | ||
288 | { | ||
289 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); | ||
290 | unsigned char kbd_func; | ||
291 | int ret; | ||
292 | |||
293 | /* Initialize keyboard */ | ||
294 | ret = asus_kbd_init(hdev); | ||
295 | if (ret < 0) | ||
296 | return ret; | ||
297 | |||
298 | /* Get keyboard functions */ | ||
299 | ret = asus_kbd_get_functions(hdev, &kbd_func); | ||
300 | if (ret < 0) | ||
301 | return ret; | ||
302 | |||
303 | /* Check for backlight support */ | ||
304 | if (!(kbd_func & SUPPORT_KBD_BACKLIGHT)) | ||
305 | return -ENODEV; | ||
306 | |||
307 | drvdata->kbd_backlight = devm_kzalloc(&hdev->dev, | ||
308 | sizeof(struct asus_kbd_leds), | ||
309 | GFP_KERNEL); | ||
310 | if (!drvdata->kbd_backlight) | ||
311 | return -ENOMEM; | ||
312 | |||
313 | drvdata->kbd_backlight->removed = false; | ||
314 | drvdata->kbd_backlight->brightness = 0; | ||
315 | drvdata->kbd_backlight->hdev = hdev; | ||
316 | drvdata->kbd_backlight->cdev.name = "asus::kbd_backlight"; | ||
317 | drvdata->kbd_backlight->cdev.max_brightness = 3; | ||
318 | drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set; | ||
319 | drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get; | ||
320 | INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work); | ||
321 | |||
322 | ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev); | ||
323 | if (ret < 0) { | ||
324 | /* No need to have this still around */ | ||
325 | devm_kfree(&hdev->dev, drvdata->kbd_backlight); | ||
326 | } | ||
327 | |||
328 | return ret; | ||
329 | } | ||
330 | |||
172 | static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) | 331 | static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) |
173 | { | 332 | { |
174 | struct input_dev *input = hi->input; | 333 | struct input_dev *input = hi->input; |
@@ -196,9 +355,14 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) | |||
196 | 355 | ||
197 | drvdata->input = input; | 356 | drvdata->input = input; |
198 | 357 | ||
358 | if (drvdata->enable_backlight && asus_kbd_register_leds(hdev)) | ||
359 | hid_warn(hdev, "Failed to initialize backlight.\n"); | ||
360 | |||
199 | return 0; | 361 | return 0; |
200 | } | 362 | } |
201 | 363 | ||
364 | #define asus_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, \ | ||
365 | max, EV_KEY, (c)) | ||
202 | static int asus_input_mapping(struct hid_device *hdev, | 366 | static int asus_input_mapping(struct hid_device *hdev, |
203 | struct hid_input *hi, struct hid_field *field, | 367 | struct hid_input *hi, struct hid_field *field, |
204 | struct hid_usage *usage, unsigned long **bit, | 368 | struct hid_usage *usage, unsigned long **bit, |
@@ -213,6 +377,65 @@ static int asus_input_mapping(struct hid_device *hdev, | |||
213 | return -1; | 377 | return -1; |
214 | } | 378 | } |
215 | 379 | ||
380 | /* ASUS-specific keyboard hotkeys */ | ||
381 | if ((usage->hid & HID_USAGE_PAGE) == 0xff310000) { | ||
382 | set_bit(EV_REP, hi->input->evbit); | ||
383 | switch (usage->hid & HID_USAGE) { | ||
384 | case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break; | ||
385 | case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break; | ||
386 | case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF); break; | ||
387 | case 0x6c: asus_map_key_clear(KEY_SLEEP); break; | ||
388 | case 0x82: asus_map_key_clear(KEY_CAMERA); break; | ||
389 | case 0x88: asus_map_key_clear(KEY_RFKILL); break; | ||
390 | case 0xb5: asus_map_key_clear(KEY_CALC); break; | ||
391 | case 0xc4: asus_map_key_clear(KEY_KBDILLUMUP); break; | ||
392 | case 0xc5: asus_map_key_clear(KEY_KBDILLUMDOWN); break; | ||
393 | |||
394 | /* ASUS touchpad toggle */ | ||
395 | case 0x6b: asus_map_key_clear(KEY_F21); break; | ||
396 | |||
397 | /* ROG key */ | ||
398 | case 0x38: asus_map_key_clear(KEY_PROG1); break; | ||
399 | |||
400 | /* Fn+C ASUS Splendid */ | ||
401 | case 0xba: asus_map_key_clear(KEY_PROG2); break; | ||
402 | |||
403 | /* Fn+Space Power4Gear Hybrid */ | ||
404 | case 0x5c: asus_map_key_clear(KEY_PROG3); break; | ||
405 | |||
406 | default: | ||
407 | /* ASUS lazily declares 256 usages, ignore the rest, | ||
408 | * as some make the keyboard appear as a pointer device. */ | ||
409 | return -1; | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | * Check and enable backlight only on devices with UsagePage == | ||
414 | * 0xff31 to avoid initializing the keyboard firmware multiple | ||
415 | * times on devices with multiple HID descriptors but same | ||
416 | * PID/VID. | ||
417 | */ | ||
418 | if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) | ||
419 | drvdata->enable_backlight = true; | ||
420 | |||
421 | return 1; | ||
422 | } | ||
423 | |||
424 | if (drvdata->quirks & QUIRK_NO_CONSUMER_USAGES && | ||
425 | (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) { | ||
426 | switch (usage->hid & HID_USAGE) { | ||
427 | case 0xe2: /* Mute */ | ||
428 | case 0xe9: /* Volume up */ | ||
429 | case 0xea: /* Volume down */ | ||
430 | return 0; | ||
431 | default: | ||
432 | /* Ignore dummy Consumer usages which make the | ||
433 | * keyboard incorrectly appear as a pointer device. | ||
434 | */ | ||
435 | return -1; | ||
436 | } | ||
437 | } | ||
438 | |||
216 | return 0; | 439 | return 0; |
217 | } | 440 | } |
218 | 441 | ||
@@ -305,6 +528,16 @@ err_stop_hw: | |||
305 | return ret; | 528 | return ret; |
306 | } | 529 | } |
307 | 530 | ||
531 | static void asus_remove(struct hid_device *hdev) | ||
532 | { | ||
533 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); | ||
534 | |||
535 | if (drvdata->kbd_backlight) { | ||
536 | drvdata->kbd_backlight->removed = true; | ||
537 | cancel_work_sync(&drvdata->kbd_backlight->work); | ||
538 | } | ||
539 | } | ||
540 | |||
308 | static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 541 | static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
309 | unsigned int *rsize) | 542 | unsigned int *rsize) |
310 | { | 543 | { |
@@ -320,9 +553,13 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
320 | 553 | ||
321 | static const struct hid_device_id asus_devices[] = { | 554 | static const struct hid_device_id asus_devices[] = { |
322 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, | 555 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, |
323 | USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), KEYBOARD_QUIRKS}, | 556 | USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD), I2C_KEYBOARD_QUIRKS}, |
324 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, | 557 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, |
325 | USB_DEVICE_ID_ASUSTEK_TOUCHPAD), TOUCHPAD_QUIRKS }, | 558 | USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD), I2C_TOUCHPAD_QUIRKS }, |
559 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, | ||
560 | USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) }, | ||
561 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, | ||
562 | USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT }, | ||
326 | { } | 563 | { } |
327 | }; | 564 | }; |
328 | MODULE_DEVICE_TABLE(hid, asus_devices); | 565 | MODULE_DEVICE_TABLE(hid, asus_devices); |
@@ -332,6 +569,7 @@ static struct hid_driver asus_driver = { | |||
332 | .id_table = asus_devices, | 569 | .id_table = asus_devices, |
333 | .report_fixup = asus_report_fixup, | 570 | .report_fixup = asus_report_fixup, |
334 | .probe = asus_probe, | 571 | .probe = asus_probe, |
572 | .remove = asus_remove, | ||
335 | .input_mapping = asus_input_mapping, | 573 | .input_mapping = asus_input_mapping, |
336 | .input_configured = asus_input_configured, | 574 | .input_configured = asus_input_configured, |
337 | #ifdef CONFIG_PM | 575 | #ifdef CONFIG_PM |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d162f0dc76e3..37084b645785 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1694,7 +1694,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | |||
1694 | len += sprintf(buf + len, "input"); | 1694 | len += sprintf(buf + len, "input"); |
1695 | if (hdev->claimed & HID_CLAIMED_HIDDEV) | 1695 | if (hdev->claimed & HID_CLAIMED_HIDDEV) |
1696 | len += sprintf(buf + len, "%shiddev%d", len ? "," : "", | 1696 | len += sprintf(buf + len, "%shiddev%d", len ? "," : "", |
1697 | hdev->minor); | 1697 | ((struct hiddev *)hdev->hiddev)->minor); |
1698 | if (hdev->claimed & HID_CLAIMED_HIDRAW) | 1698 | if (hdev->claimed & HID_CLAIMED_HIDRAW) |
1699 | len += sprintf(buf + len, "%shidraw%d", len ? "," : "", | 1699 | len += sprintf(buf + len, "%shidraw%d", len ? "," : "", |
1700 | ((struct hidraw *)hdev->hidraw)->minor); | 1700 | ((struct hidraw *)hdev->hidraw)->minor); |
@@ -1851,8 +1851,10 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1851 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) }, | 1851 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) }, |
1852 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1852 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1853 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1853 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1854 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) }, | 1854 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) }, |
1855 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_TOUCHPAD) }, | 1855 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) }, |
1856 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) }, | ||
1857 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2) }, | ||
1856 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, | 1858 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, |
1857 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1859 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1858 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, | 1860 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, |
@@ -1891,6 +1893,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1891 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1893 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
1892 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, | 1894 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, |
1893 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) }, | 1895 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) }, |
1896 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) }, | ||
1894 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, | 1897 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, |
1895 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1898 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1896 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1899 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
@@ -1991,6 +1994,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1991 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, | 1994 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, |
1992 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1995 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1993 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, | 1996 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, |
1997 | { HID_USB_DEVICE(USB_VENDOR_ID_NTI, USB_DEVICE_ID_USB_SUN) }, | ||
1994 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, | 1998 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, |
1995 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, | 1999 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, |
1996 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) }, | 2000 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) }, |
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index b22d0f83f8e3..078026f63b6f 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/gpio/driver.h> | 28 | #include <linux/gpio/driver.h> |
29 | #include <linux/hid.h> | 29 | #include <linux/hid.h> |
30 | #include <linux/hidraw.h> | ||
30 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
31 | #include <linux/module.h> | 32 | #include <linux/module.h> |
32 | #include <linux/nls.h> | 33 | #include <linux/nls.h> |
@@ -1297,7 +1298,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1297 | dev->adap.algo_data = dev; | 1298 | dev->adap.algo_data = dev; |
1298 | dev->adap.dev.parent = &hdev->dev; | 1299 | dev->adap.dev.parent = &hdev->dev; |
1299 | snprintf(dev->adap.name, sizeof(dev->adap.name), | 1300 | snprintf(dev->adap.name, sizeof(dev->adap.name), |
1300 | "CP2112 SMBus Bridge on hiddev%d", hdev->minor); | 1301 | "CP2112 SMBus Bridge on hidraw%d", |
1302 | ((struct hidraw *)hdev->hidraw)->minor); | ||
1301 | dev->hwversion = buf[2]; | 1303 | dev->hwversion = buf[2]; |
1302 | init_waitqueue_head(&dev->wait); | 1304 | init_waitqueue_head(&dev->wait); |
1303 | 1305 | ||
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index c6c9c51c806f..5271db593478 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c | |||
@@ -140,9 +140,11 @@ static const struct hid_usage_entry hid_usage_table[] = { | |||
140 | {0, 0x03, "LightPen"}, | 140 | {0, 0x03, "LightPen"}, |
141 | {0, 0x04, "TouchScreen"}, | 141 | {0, 0x04, "TouchScreen"}, |
142 | {0, 0x05, "TouchPad"}, | 142 | {0, 0x05, "TouchPad"}, |
143 | {0, 0x0e, "DeviceConfiguration"}, | ||
143 | {0, 0x20, "Stylus"}, | 144 | {0, 0x20, "Stylus"}, |
144 | {0, 0x21, "Puck"}, | 145 | {0, 0x21, "Puck"}, |
145 | {0, 0x22, "Finger"}, | 146 | {0, 0x22, "Finger"}, |
147 | {0, 0x23, "DeviceSettings"}, | ||
146 | {0, 0x30, "TipPressure"}, | 148 | {0, 0x30, "TipPressure"}, |
147 | {0, 0x31, "BarrelPressure"}, | 149 | {0, 0x31, "BarrelPressure"}, |
148 | {0, 0x32, "InRange"}, | 150 | {0, 0x32, "InRange"}, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b26c030926c1..643390ba749d 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -173,8 +173,10 @@ | |||
173 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 | 173 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 |
174 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 | 174 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 |
175 | #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b | 175 | #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b |
176 | #define USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD 0x8585 | 176 | #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585 |
177 | #define USB_DEVICE_ID_ASUSTEK_TOUCHPAD 0x0101 | 177 | #define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101 |
178 | #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854 | ||
179 | #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2 0x1837 | ||
178 | 180 | ||
179 | #define USB_VENDOR_ID_ATEN 0x0557 | 181 | #define USB_VENDOR_ID_ATEN 0x0557 |
180 | #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 | 182 | #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 |
@@ -184,6 +186,7 @@ | |||
184 | #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 | 186 | #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 |
185 | #define USB_DEVICE_ID_ATEN_CS682 0x2213 | 187 | #define USB_DEVICE_ID_ATEN_CS682 0x2213 |
186 | #define USB_DEVICE_ID_ATEN_CS692 0x8021 | 188 | #define USB_DEVICE_ID_ATEN_CS692 0x8021 |
189 | #define USB_DEVICE_ID_ATEN_CS1758 0x2220 | ||
187 | 190 | ||
188 | #define USB_VENDOR_ID_ATMEL 0x03eb | 191 | #define USB_VENDOR_ID_ATMEL 0x03eb |
189 | #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c | 192 | #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c |
@@ -366,6 +369,7 @@ | |||
366 | #define USB_VENDOR_ID_ELO 0x04E7 | 369 | #define USB_VENDOR_ID_ELO 0x04E7 |
367 | #define USB_DEVICE_ID_ELO_TS2515 0x0022 | 370 | #define USB_DEVICE_ID_ELO_TS2515 0x0022 |
368 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 | 371 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 |
372 | #define USB_DEVICE_ID_ELO_ACCUTOUCH_2216 0x0050 | ||
369 | 373 | ||
370 | #define USB_VENDOR_ID_EMS 0x2006 | 374 | #define USB_VENDOR_ID_EMS 0x2006 |
371 | #define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118 | 375 | #define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118 |
@@ -548,6 +552,9 @@ | |||
548 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 | 552 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 |
549 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 | 553 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 |
550 | 554 | ||
555 | #define USB_VENDOR_ID_INNOMEDIA 0x1292 | ||
556 | #define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745 | ||
557 | |||
551 | #define USB_VENDOR_ID_ITE 0x048d | 558 | #define USB_VENDOR_ID_ITE 0x048d |
552 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 | 559 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 |
553 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 | 560 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 |
@@ -771,6 +778,9 @@ | |||
771 | #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 | 778 | #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 |
772 | #define USB_DEVICE_ID_NOVATEK_MOUSE 0x1602 | 779 | #define USB_DEVICE_ID_NOVATEK_MOUSE 0x1602 |
773 | 780 | ||
781 | #define USB_VENDOR_ID_NTI 0x0757 | ||
782 | #define USB_DEVICE_ID_USB_SUN 0x0a00 | ||
783 | |||
774 | #define USB_VENDOR_ID_NTRIG 0x1b96 | 784 | #define USB_VENDOR_ID_NTRIG 0x1b96 |
775 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 | 785 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 |
776 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 | 786 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d05f903c7614..a1ebdd7d4d4d 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -1150,18 +1150,26 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
1150 | 1150 | ||
1151 | /* | 1151 | /* |
1152 | * Ignore out-of-range values as per HID specification, | 1152 | * Ignore out-of-range values as per HID specification, |
1153 | * section 5.10 and 6.2.25. | 1153 | * section 5.10 and 6.2.25, when NULL state bit is present. |
1154 | * When it's not, clamp the value to match Microsoft's input | ||
1155 | * driver as mentioned in "Required HID usages for digitizers": | ||
1156 | * https://msdn.microsoft.com/en-us/library/windows/hardware/dn672278(v=vs.85).asp | ||
1154 | * | 1157 | * |
1155 | * The logical_minimum < logical_maximum check is done so that we | 1158 | * The logical_minimum < logical_maximum check is done so that we |
1156 | * don't unintentionally discard values sent by devices which | 1159 | * don't unintentionally discard values sent by devices which |
1157 | * don't specify logical min and max. | 1160 | * don't specify logical min and max. |
1158 | */ | 1161 | */ |
1159 | if ((field->flags & HID_MAIN_ITEM_VARIABLE) && | 1162 | if ((field->flags & HID_MAIN_ITEM_VARIABLE) && |
1160 | (field->logical_minimum < field->logical_maximum) && | 1163 | (field->logical_minimum < field->logical_maximum)) { |
1161 | (value < field->logical_minimum || | 1164 | if (field->flags & HID_MAIN_ITEM_NULL_STATE && |
1162 | value > field->logical_maximum)) { | 1165 | (value < field->logical_minimum || |
1163 | dbg_hid("Ignoring out-of-range value %x\n", value); | 1166 | value > field->logical_maximum)) { |
1164 | return; | 1167 | dbg_hid("Ignoring out-of-range value %x\n", value); |
1168 | return; | ||
1169 | } | ||
1170 | value = clamp(value, | ||
1171 | field->logical_minimum, | ||
1172 | field->logical_maximum); | ||
1165 | } | 1173 | } |
1166 | 1174 | ||
1167 | /* | 1175 | /* |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 5bc6d80d5be7..826fa1e1c8d9 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -692,8 +692,12 @@ static void logi_dj_ll_close(struct hid_device *hid) | |||
692 | dbg_hid("%s:%s\n", __func__, hid->phys); | 692 | dbg_hid("%s:%s\n", __func__, hid->phys); |
693 | } | 693 | } |
694 | 694 | ||
695 | static u8 unifying_name_query[] = {0x10, 0xff, 0x83, 0xb5, 0x40, 0x00, 0x00}; | 695 | /* |
696 | static u8 unifying_name_answer[] = {0x11, 0xff, 0x83, 0xb5}; | 696 | * Register 0xB5 is "pairing information". It is solely intended for the |
697 | * receiver, so do not overwrite the device index. | ||
698 | */ | ||
699 | static u8 unifying_pairing_query[] = {0x10, 0xff, 0x83, 0xb5}; | ||
700 | static u8 unifying_pairing_answer[] = {0x11, 0xff, 0x83, 0xb5}; | ||
697 | 701 | ||
698 | static int logi_dj_ll_raw_request(struct hid_device *hid, | 702 | static int logi_dj_ll_raw_request(struct hid_device *hid, |
699 | unsigned char reportnum, __u8 *buf, | 703 | unsigned char reportnum, __u8 *buf, |
@@ -712,9 +716,9 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, | |||
712 | 716 | ||
713 | /* special case where we should not overwrite | 717 | /* special case where we should not overwrite |
714 | * the device_index */ | 718 | * the device_index */ |
715 | if (count == 7 && !memcmp(buf, unifying_name_query, | 719 | if (count == 7 && !memcmp(buf, unifying_pairing_query, |
716 | sizeof(unifying_name_query))) | 720 | sizeof(unifying_pairing_query))) |
717 | buf[4] |= djdev->device_index - 1; | 721 | buf[4] = (buf[4] & 0xf0) | (djdev->device_index - 1); |
718 | else | 722 | else |
719 | buf[1] = djdev->device_index; | 723 | buf[1] = djdev->device_index; |
720 | return hid_hw_raw_request(djrcv_dev->hdev, reportnum, buf, | 724 | return hid_hw_raw_request(djrcv_dev->hdev, reportnum, buf, |
@@ -911,9 +915,8 @@ static int logi_dj_hidpp_event(struct hid_device *hdev, | |||
911 | /* special case were the device wants to know its unifying | 915 | /* special case were the device wants to know its unifying |
912 | * name */ | 916 | * name */ |
913 | if (size == HIDPP_REPORT_LONG_LENGTH && | 917 | if (size == HIDPP_REPORT_LONG_LENGTH && |
914 | !memcmp(data, unifying_name_answer, | 918 | !memcmp(data, unifying_pairing_answer, |
915 | sizeof(unifying_name_answer)) && | 919 | sizeof(unifying_pairing_answer))) |
916 | ((data[4] & 0xF0) == 0x40)) | ||
917 | device_index = (data[4] & 0x0F) + 1; | 920 | device_index = (data[4] & 0x0F) + 1; |
918 | else | 921 | else |
919 | return false; | 922 | return false; |
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 2e2515a4c070..41b39464ded8 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c | |||
@@ -56,15 +56,21 @@ MODULE_PARM_DESC(disable_tap_to_click, | |||
56 | #define HIDPP_QUIRK_CLASS_M560 BIT(1) | 56 | #define HIDPP_QUIRK_CLASS_M560 BIT(1) |
57 | #define HIDPP_QUIRK_CLASS_K400 BIT(2) | 57 | #define HIDPP_QUIRK_CLASS_K400 BIT(2) |
58 | #define HIDPP_QUIRK_CLASS_G920 BIT(3) | 58 | #define HIDPP_QUIRK_CLASS_G920 BIT(3) |
59 | #define HIDPP_QUIRK_CLASS_K750 BIT(4) | ||
59 | 60 | ||
60 | /* bits 2..20 are reserved for classes */ | 61 | /* bits 2..20 are reserved for classes */ |
61 | #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) | 62 | /* #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) disabled */ |
62 | #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) | 63 | #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) |
63 | #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) | 64 | #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) |
64 | #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) | 65 | #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) |
66 | #define HIDPP_QUIRK_UNIFYING BIT(25) | ||
65 | 67 | ||
66 | #define HIDPP_QUIRK_DELAYED_INIT (HIDPP_QUIRK_NO_HIDINPUT | \ | 68 | #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT |
67 | HIDPP_QUIRK_CONNECT_EVENTS) | 69 | |
70 | #define HIDPP_CAPABILITY_HIDPP10_BATTERY BIT(0) | ||
71 | #define HIDPP_CAPABILITY_HIDPP20_BATTERY BIT(1) | ||
72 | #define HIDPP_CAPABILITY_BATTERY_MILEAGE BIT(2) | ||
73 | #define HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS BIT(3) | ||
68 | 74 | ||
69 | /* | 75 | /* |
70 | * There are two hidpp protocols in use, the first version hidpp10 is known | 76 | * There are two hidpp protocols in use, the first version hidpp10 is known |
@@ -110,6 +116,18 @@ struct hidpp_report { | |||
110 | }; | 116 | }; |
111 | } __packed; | 117 | } __packed; |
112 | 118 | ||
119 | struct hidpp_battery { | ||
120 | u8 feature_index; | ||
121 | u8 solar_feature_index; | ||
122 | struct power_supply_desc desc; | ||
123 | struct power_supply *ps; | ||
124 | char name[64]; | ||
125 | int status; | ||
126 | int capacity; | ||
127 | int level; | ||
128 | bool online; | ||
129 | }; | ||
130 | |||
113 | struct hidpp_device { | 131 | struct hidpp_device { |
114 | struct hid_device *hid_dev; | 132 | struct hid_device *hid_dev; |
115 | struct mutex send_mutex; | 133 | struct mutex send_mutex; |
@@ -128,8 +146,10 @@ struct hidpp_device { | |||
128 | struct input_dev *delayed_input; | 146 | struct input_dev *delayed_input; |
129 | 147 | ||
130 | unsigned long quirks; | 148 | unsigned long quirks; |
131 | }; | 149 | unsigned long capabilities; |
132 | 150 | ||
151 | struct hidpp_battery battery; | ||
152 | }; | ||
133 | 153 | ||
134 | /* HID++ 1.0 error codes */ | 154 | /* HID++ 1.0 error codes */ |
135 | #define HIDPP_ERROR 0x8f | 155 | #define HIDPP_ERROR 0x8f |
@@ -380,15 +400,220 @@ static void hidpp_prefix_name(char **name, int name_length) | |||
380 | #define HIDPP_SET_LONG_REGISTER 0x82 | 400 | #define HIDPP_SET_LONG_REGISTER 0x82 |
381 | #define HIDPP_GET_LONG_REGISTER 0x83 | 401 | #define HIDPP_GET_LONG_REGISTER 0x83 |
382 | 402 | ||
403 | #define HIDPP_REG_GENERAL 0x00 | ||
404 | |||
405 | static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) | ||
406 | { | ||
407 | struct hidpp_report response; | ||
408 | int ret; | ||
409 | u8 params[3] = { 0 }; | ||
410 | |||
411 | ret = hidpp_send_rap_command_sync(hidpp_dev, | ||
412 | REPORT_ID_HIDPP_SHORT, | ||
413 | HIDPP_GET_REGISTER, | ||
414 | HIDPP_REG_GENERAL, | ||
415 | NULL, 0, &response); | ||
416 | if (ret) | ||
417 | return ret; | ||
418 | |||
419 | memcpy(params, response.rap.params, 3); | ||
420 | |||
421 | /* Set the battery bit */ | ||
422 | params[0] |= BIT(4); | ||
423 | |||
424 | return hidpp_send_rap_command_sync(hidpp_dev, | ||
425 | REPORT_ID_HIDPP_SHORT, | ||
426 | HIDPP_SET_REGISTER, | ||
427 | HIDPP_REG_GENERAL, | ||
428 | params, 3, &response); | ||
429 | } | ||
430 | |||
431 | #define HIDPP_REG_BATTERY_STATUS 0x07 | ||
432 | |||
433 | static int hidpp10_battery_status_map_level(u8 param) | ||
434 | { | ||
435 | int level; | ||
436 | |||
437 | switch (param) { | ||
438 | case 1 ... 2: | ||
439 | level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; | ||
440 | break; | ||
441 | case 3 ... 4: | ||
442 | level = POWER_SUPPLY_CAPACITY_LEVEL_LOW; | ||
443 | break; | ||
444 | case 5 ... 6: | ||
445 | level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; | ||
446 | break; | ||
447 | case 7: | ||
448 | level = POWER_SUPPLY_CAPACITY_LEVEL_HIGH; | ||
449 | break; | ||
450 | default: | ||
451 | level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; | ||
452 | } | ||
453 | |||
454 | return level; | ||
455 | } | ||
456 | |||
457 | static int hidpp10_battery_status_map_status(u8 param) | ||
458 | { | ||
459 | int status; | ||
460 | |||
461 | switch (param) { | ||
462 | case 0x00: | ||
463 | /* discharging (in use) */ | ||
464 | status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
465 | break; | ||
466 | case 0x21: /* (standard) charging */ | ||
467 | case 0x24: /* fast charging */ | ||
468 | case 0x25: /* slow charging */ | ||
469 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
470 | break; | ||
471 | case 0x26: /* topping charge */ | ||
472 | case 0x22: /* charge complete */ | ||
473 | status = POWER_SUPPLY_STATUS_FULL; | ||
474 | break; | ||
475 | case 0x20: /* unknown */ | ||
476 | status = POWER_SUPPLY_STATUS_UNKNOWN; | ||
477 | break; | ||
478 | /* | ||
479 | * 0x01...0x1F = reserved (not charging) | ||
480 | * 0x23 = charging error | ||
481 | * 0x27..0xff = reserved | ||
482 | */ | ||
483 | default: | ||
484 | status = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
485 | break; | ||
486 | } | ||
487 | |||
488 | return status; | ||
489 | } | ||
490 | |||
491 | static int hidpp10_query_battery_status(struct hidpp_device *hidpp) | ||
492 | { | ||
493 | struct hidpp_report response; | ||
494 | int ret, status; | ||
495 | |||
496 | ret = hidpp_send_rap_command_sync(hidpp, | ||
497 | REPORT_ID_HIDPP_SHORT, | ||
498 | HIDPP_GET_REGISTER, | ||
499 | HIDPP_REG_BATTERY_STATUS, | ||
500 | NULL, 0, &response); | ||
501 | if (ret) | ||
502 | return ret; | ||
503 | |||
504 | hidpp->battery.level = | ||
505 | hidpp10_battery_status_map_level(response.rap.params[0]); | ||
506 | status = hidpp10_battery_status_map_status(response.rap.params[1]); | ||
507 | hidpp->battery.status = status; | ||
508 | /* the capacity is only available when discharging or full */ | ||
509 | hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || | ||
510 | status == POWER_SUPPLY_STATUS_FULL; | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | #define HIDPP_REG_BATTERY_MILEAGE 0x0D | ||
516 | |||
517 | static int hidpp10_battery_mileage_map_status(u8 param) | ||
518 | { | ||
519 | int status; | ||
520 | |||
521 | switch (param >> 6) { | ||
522 | case 0x00: | ||
523 | /* discharging (in use) */ | ||
524 | status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
525 | break; | ||
526 | case 0x01: /* charging */ | ||
527 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
528 | break; | ||
529 | case 0x02: /* charge complete */ | ||
530 | status = POWER_SUPPLY_STATUS_FULL; | ||
531 | break; | ||
532 | /* | ||
533 | * 0x03 = charging error | ||
534 | */ | ||
535 | default: | ||
536 | status = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
537 | break; | ||
538 | } | ||
539 | |||
540 | return status; | ||
541 | } | ||
542 | |||
543 | static int hidpp10_query_battery_mileage(struct hidpp_device *hidpp) | ||
544 | { | ||
545 | struct hidpp_report response; | ||
546 | int ret, status; | ||
547 | |||
548 | ret = hidpp_send_rap_command_sync(hidpp, | ||
549 | REPORT_ID_HIDPP_SHORT, | ||
550 | HIDPP_GET_REGISTER, | ||
551 | HIDPP_REG_BATTERY_MILEAGE, | ||
552 | NULL, 0, &response); | ||
553 | if (ret) | ||
554 | return ret; | ||
555 | |||
556 | hidpp->battery.capacity = response.rap.params[0]; | ||
557 | status = hidpp10_battery_mileage_map_status(response.rap.params[2]); | ||
558 | hidpp->battery.status = status; | ||
559 | /* the capacity is only available when discharging or full */ | ||
560 | hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || | ||
561 | status == POWER_SUPPLY_STATUS_FULL; | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static int hidpp10_battery_event(struct hidpp_device *hidpp, u8 *data, int size) | ||
567 | { | ||
568 | struct hidpp_report *report = (struct hidpp_report *)data; | ||
569 | int status, capacity, level; | ||
570 | bool changed; | ||
571 | |||
572 | if (report->report_id != REPORT_ID_HIDPP_SHORT) | ||
573 | return 0; | ||
574 | |||
575 | switch (report->rap.sub_id) { | ||
576 | case HIDPP_REG_BATTERY_STATUS: | ||
577 | capacity = hidpp->battery.capacity; | ||
578 | level = hidpp10_battery_status_map_level(report->rawbytes[1]); | ||
579 | status = hidpp10_battery_status_map_status(report->rawbytes[2]); | ||
580 | break; | ||
581 | case HIDPP_REG_BATTERY_MILEAGE: | ||
582 | capacity = report->rap.params[0]; | ||
583 | level = hidpp->battery.level; | ||
584 | status = hidpp10_battery_mileage_map_status(report->rawbytes[3]); | ||
585 | break; | ||
586 | default: | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | changed = capacity != hidpp->battery.capacity || | ||
591 | level != hidpp->battery.level || | ||
592 | status != hidpp->battery.status; | ||
593 | |||
594 | /* the capacity is only available when discharging or full */ | ||
595 | hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || | ||
596 | status == POWER_SUPPLY_STATUS_FULL; | ||
597 | |||
598 | if (changed) { | ||
599 | hidpp->battery.level = level; | ||
600 | hidpp->battery.status = status; | ||
601 | if (hidpp->battery.ps) | ||
602 | power_supply_changed(hidpp->battery.ps); | ||
603 | } | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
383 | #define HIDPP_REG_PAIRING_INFORMATION 0xB5 | 608 | #define HIDPP_REG_PAIRING_INFORMATION 0xB5 |
384 | #define DEVICE_NAME 0x40 | 609 | #define HIDPP_EXTENDED_PAIRING 0x30 |
610 | #define HIDPP_DEVICE_NAME 0x40 | ||
385 | 611 | ||
386 | static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) | 612 | static char *hidpp_unifying_get_name(struct hidpp_device *hidpp_dev) |
387 | { | 613 | { |
388 | struct hidpp_report response; | 614 | struct hidpp_report response; |
389 | int ret; | 615 | int ret; |
390 | /* hid-logitech-dj is in charge of setting the right device index */ | 616 | u8 params[1] = { HIDPP_DEVICE_NAME }; |
391 | u8 params[1] = { DEVICE_NAME }; | ||
392 | char *name; | 617 | char *name; |
393 | int len; | 618 | int len; |
394 | 619 | ||
@@ -417,6 +642,54 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) | |||
417 | return name; | 642 | return name; |
418 | } | 643 | } |
419 | 644 | ||
645 | static int hidpp_unifying_get_serial(struct hidpp_device *hidpp, u32 *serial) | ||
646 | { | ||
647 | struct hidpp_report response; | ||
648 | int ret; | ||
649 | u8 params[1] = { HIDPP_EXTENDED_PAIRING }; | ||
650 | |||
651 | ret = hidpp_send_rap_command_sync(hidpp, | ||
652 | REPORT_ID_HIDPP_SHORT, | ||
653 | HIDPP_GET_LONG_REGISTER, | ||
654 | HIDPP_REG_PAIRING_INFORMATION, | ||
655 | params, 1, &response); | ||
656 | if (ret) | ||
657 | return ret; | ||
658 | |||
659 | /* | ||
660 | * We don't care about LE or BE, we will output it as a string | ||
661 | * with %4phD, so we need to keep the order. | ||
662 | */ | ||
663 | *serial = *((u32 *)&response.rap.params[1]); | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static int hidpp_unifying_init(struct hidpp_device *hidpp) | ||
668 | { | ||
669 | struct hid_device *hdev = hidpp->hid_dev; | ||
670 | const char *name; | ||
671 | u32 serial; | ||
672 | int ret; | ||
673 | |||
674 | ret = hidpp_unifying_get_serial(hidpp, &serial); | ||
675 | if (ret) | ||
676 | return ret; | ||
677 | |||
678 | snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD", | ||
679 | hdev->product, &serial); | ||
680 | dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq); | ||
681 | |||
682 | name = hidpp_unifying_get_name(hidpp); | ||
683 | if (!name) | ||
684 | return -EIO; | ||
685 | |||
686 | snprintf(hdev->name, sizeof(hdev->name), "%s", name); | ||
687 | dbg_hid("HID++ Unifying: Got name: %s\n", name); | ||
688 | |||
689 | kfree(name); | ||
690 | return 0; | ||
691 | } | ||
692 | |||
420 | /* -------------------------------------------------------------------------- */ | 693 | /* -------------------------------------------------------------------------- */ |
421 | /* 0x0000: Root */ | 694 | /* 0x0000: Root */ |
422 | /* -------------------------------------------------------------------------- */ | 695 | /* -------------------------------------------------------------------------- */ |
@@ -441,6 +714,9 @@ static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature, | |||
441 | if (ret) | 714 | if (ret) |
442 | return ret; | 715 | return ret; |
443 | 716 | ||
717 | if (response.fap.params[0] == 0) | ||
718 | return -ENOENT; | ||
719 | |||
444 | *feature_index = response.fap.params[0]; | 720 | *feature_index = response.fap.params[0]; |
445 | *feature_type = response.fap.params[1]; | 721 | *feature_type = response.fap.params[1]; |
446 | 722 | ||
@@ -607,6 +883,355 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp) | |||
607 | } | 883 | } |
608 | 884 | ||
609 | /* -------------------------------------------------------------------------- */ | 885 | /* -------------------------------------------------------------------------- */ |
886 | /* 0x1000: Battery level status */ | ||
887 | /* -------------------------------------------------------------------------- */ | ||
888 | |||
889 | #define HIDPP_PAGE_BATTERY_LEVEL_STATUS 0x1000 | ||
890 | |||
891 | #define CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS 0x00 | ||
892 | #define CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_CAPABILITY 0x10 | ||
893 | |||
894 | #define EVENT_BATTERY_LEVEL_STATUS_BROADCAST 0x00 | ||
895 | |||
896 | #define FLAG_BATTERY_LEVEL_DISABLE_OSD BIT(0) | ||
897 | #define FLAG_BATTERY_LEVEL_MILEAGE BIT(1) | ||
898 | #define FLAG_BATTERY_LEVEL_RECHARGEABLE BIT(2) | ||
899 | |||
900 | static int hidpp_map_battery_level(int capacity) | ||
901 | { | ||
902 | if (capacity < 11) | ||
903 | return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; | ||
904 | else if (capacity < 31) | ||
905 | return POWER_SUPPLY_CAPACITY_LEVEL_LOW; | ||
906 | else if (capacity < 81) | ||
907 | return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; | ||
908 | return POWER_SUPPLY_CAPACITY_LEVEL_FULL; | ||
909 | } | ||
910 | |||
911 | static int hidpp20_batterylevel_map_status_capacity(u8 data[3], int *capacity, | ||
912 | int *next_capacity, | ||
913 | int *level) | ||
914 | { | ||
915 | int status; | ||
916 | |||
917 | *capacity = data[0]; | ||
918 | *next_capacity = data[1]; | ||
919 | *level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; | ||
920 | |||
921 | /* When discharging, we can rely on the device reported capacity. | ||
922 | * For all other states the device reports 0 (unknown). | ||
923 | */ | ||
924 | switch (data[2]) { | ||
925 | case 0: /* discharging (in use) */ | ||
926 | status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
927 | *level = hidpp_map_battery_level(*capacity); | ||
928 | break; | ||
929 | case 1: /* recharging */ | ||
930 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
931 | break; | ||
932 | case 2: /* charge in final stage */ | ||
933 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
934 | break; | ||
935 | case 3: /* charge complete */ | ||
936 | status = POWER_SUPPLY_STATUS_FULL; | ||
937 | *level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; | ||
938 | *capacity = 100; | ||
939 | break; | ||
940 | case 4: /* recharging below optimal speed */ | ||
941 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
942 | break; | ||
943 | /* 5 = invalid battery type | ||
944 | 6 = thermal error | ||
945 | 7 = other charging error */ | ||
946 | default: | ||
947 | status = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
948 | break; | ||
949 | } | ||
950 | |||
951 | return status; | ||
952 | } | ||
953 | |||
954 | static int hidpp20_batterylevel_get_battery_capacity(struct hidpp_device *hidpp, | ||
955 | u8 feature_index, | ||
956 | int *status, | ||
957 | int *capacity, | ||
958 | int *next_capacity, | ||
959 | int *level) | ||
960 | { | ||
961 | struct hidpp_report response; | ||
962 | int ret; | ||
963 | u8 *params = (u8 *)response.fap.params; | ||
964 | |||
965 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
966 | CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS, | ||
967 | NULL, 0, &response); | ||
968 | if (ret > 0) { | ||
969 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
970 | __func__, ret); | ||
971 | return -EPROTO; | ||
972 | } | ||
973 | if (ret) | ||
974 | return ret; | ||
975 | |||
976 | *status = hidpp20_batterylevel_map_status_capacity(params, capacity, | ||
977 | next_capacity, | ||
978 | level); | ||
979 | |||
980 | return 0; | ||
981 | } | ||
982 | |||
983 | static int hidpp20_batterylevel_get_battery_info(struct hidpp_device *hidpp, | ||
984 | u8 feature_index) | ||
985 | { | ||
986 | struct hidpp_report response; | ||
987 | int ret; | ||
988 | u8 *params = (u8 *)response.fap.params; | ||
989 | unsigned int level_count, flags; | ||
990 | |||
991 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
992 | CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_CAPABILITY, | ||
993 | NULL, 0, &response); | ||
994 | if (ret > 0) { | ||
995 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
996 | __func__, ret); | ||
997 | return -EPROTO; | ||
998 | } | ||
999 | if (ret) | ||
1000 | return ret; | ||
1001 | |||
1002 | level_count = params[0]; | ||
1003 | flags = params[1]; | ||
1004 | |||
1005 | if (level_count < 10 || !(flags & FLAG_BATTERY_LEVEL_MILEAGE)) | ||
1006 | hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS; | ||
1007 | else | ||
1008 | hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_MILEAGE; | ||
1009 | |||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | static int hidpp20_query_battery_info(struct hidpp_device *hidpp) | ||
1014 | { | ||
1015 | u8 feature_type; | ||
1016 | int ret; | ||
1017 | int status, capacity, next_capacity, level; | ||
1018 | |||
1019 | if (hidpp->battery.feature_index == 0xff) { | ||
1020 | ret = hidpp_root_get_feature(hidpp, | ||
1021 | HIDPP_PAGE_BATTERY_LEVEL_STATUS, | ||
1022 | &hidpp->battery.feature_index, | ||
1023 | &feature_type); | ||
1024 | if (ret) | ||
1025 | return ret; | ||
1026 | } | ||
1027 | |||
1028 | ret = hidpp20_batterylevel_get_battery_capacity(hidpp, | ||
1029 | hidpp->battery.feature_index, | ||
1030 | &status, &capacity, | ||
1031 | &next_capacity, &level); | ||
1032 | if (ret) | ||
1033 | return ret; | ||
1034 | |||
1035 | ret = hidpp20_batterylevel_get_battery_info(hidpp, | ||
1036 | hidpp->battery.feature_index); | ||
1037 | if (ret) | ||
1038 | return ret; | ||
1039 | |||
1040 | hidpp->battery.status = status; | ||
1041 | hidpp->battery.capacity = capacity; | ||
1042 | hidpp->battery.level = level; | ||
1043 | /* the capacity is only available when discharging or full */ | ||
1044 | hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || | ||
1045 | status == POWER_SUPPLY_STATUS_FULL; | ||
1046 | |||
1047 | return 0; | ||
1048 | } | ||
1049 | |||
1050 | static int hidpp20_battery_event(struct hidpp_device *hidpp, | ||
1051 | u8 *data, int size) | ||
1052 | { | ||
1053 | struct hidpp_report *report = (struct hidpp_report *)data; | ||
1054 | int status, capacity, next_capacity, level; | ||
1055 | bool changed; | ||
1056 | |||
1057 | if (report->fap.feature_index != hidpp->battery.feature_index || | ||
1058 | report->fap.funcindex_clientid != EVENT_BATTERY_LEVEL_STATUS_BROADCAST) | ||
1059 | return 0; | ||
1060 | |||
1061 | status = hidpp20_batterylevel_map_status_capacity(report->fap.params, | ||
1062 | &capacity, | ||
1063 | &next_capacity, | ||
1064 | &level); | ||
1065 | |||
1066 | /* the capacity is only available when discharging or full */ | ||
1067 | hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || | ||
1068 | status == POWER_SUPPLY_STATUS_FULL; | ||
1069 | |||
1070 | changed = capacity != hidpp->battery.capacity || | ||
1071 | level != hidpp->battery.level || | ||
1072 | status != hidpp->battery.status; | ||
1073 | |||
1074 | if (changed) { | ||
1075 | hidpp->battery.level = level; | ||
1076 | hidpp->battery.capacity = capacity; | ||
1077 | hidpp->battery.status = status; | ||
1078 | if (hidpp->battery.ps) | ||
1079 | power_supply_changed(hidpp->battery.ps); | ||
1080 | } | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static enum power_supply_property hidpp_battery_props[] = { | ||
1086 | POWER_SUPPLY_PROP_ONLINE, | ||
1087 | POWER_SUPPLY_PROP_STATUS, | ||
1088 | POWER_SUPPLY_PROP_SCOPE, | ||
1089 | POWER_SUPPLY_PROP_MODEL_NAME, | ||
1090 | POWER_SUPPLY_PROP_MANUFACTURER, | ||
1091 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | ||
1092 | 0, /* placeholder for POWER_SUPPLY_PROP_CAPACITY, */ | ||
1093 | 0, /* placeholder for POWER_SUPPLY_PROP_CAPACITY_LEVEL, */ | ||
1094 | }; | ||
1095 | |||
1096 | static int hidpp_battery_get_property(struct power_supply *psy, | ||
1097 | enum power_supply_property psp, | ||
1098 | union power_supply_propval *val) | ||
1099 | { | ||
1100 | struct hidpp_device *hidpp = power_supply_get_drvdata(psy); | ||
1101 | int ret = 0; | ||
1102 | |||
1103 | switch(psp) { | ||
1104 | case POWER_SUPPLY_PROP_STATUS: | ||
1105 | val->intval = hidpp->battery.status; | ||
1106 | break; | ||
1107 | case POWER_SUPPLY_PROP_CAPACITY: | ||
1108 | val->intval = hidpp->battery.capacity; | ||
1109 | break; | ||
1110 | case POWER_SUPPLY_PROP_CAPACITY_LEVEL: | ||
1111 | val->intval = hidpp->battery.level; | ||
1112 | break; | ||
1113 | case POWER_SUPPLY_PROP_SCOPE: | ||
1114 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
1115 | break; | ||
1116 | case POWER_SUPPLY_PROP_ONLINE: | ||
1117 | val->intval = hidpp->battery.online; | ||
1118 | break; | ||
1119 | case POWER_SUPPLY_PROP_MODEL_NAME: | ||
1120 | if (!strncmp(hidpp->name, "Logitech ", 9)) | ||
1121 | val->strval = hidpp->name + 9; | ||
1122 | else | ||
1123 | val->strval = hidpp->name; | ||
1124 | break; | ||
1125 | case POWER_SUPPLY_PROP_MANUFACTURER: | ||
1126 | val->strval = "Logitech"; | ||
1127 | break; | ||
1128 | case POWER_SUPPLY_PROP_SERIAL_NUMBER: | ||
1129 | val->strval = hidpp->hid_dev->uniq; | ||
1130 | break; | ||
1131 | default: | ||
1132 | ret = -EINVAL; | ||
1133 | break; | ||
1134 | } | ||
1135 | |||
1136 | return ret; | ||
1137 | } | ||
1138 | |||
1139 | /* -------------------------------------------------------------------------- */ | ||
1140 | /* 0x4301: Solar Keyboard */ | ||
1141 | /* -------------------------------------------------------------------------- */ | ||
1142 | |||
1143 | #define HIDPP_PAGE_SOLAR_KEYBOARD 0x4301 | ||
1144 | |||
1145 | #define CMD_SOLAR_SET_LIGHT_MEASURE 0x00 | ||
1146 | |||
1147 | #define EVENT_SOLAR_BATTERY_BROADCAST 0x00 | ||
1148 | #define EVENT_SOLAR_BATTERY_LIGHT_MEASURE 0x10 | ||
1149 | #define EVENT_SOLAR_CHECK_LIGHT_BUTTON 0x20 | ||
1150 | |||
1151 | static int hidpp_solar_request_battery_event(struct hidpp_device *hidpp) | ||
1152 | { | ||
1153 | struct hidpp_report response; | ||
1154 | u8 params[2] = { 1, 1 }; | ||
1155 | u8 feature_type; | ||
1156 | int ret; | ||
1157 | |||
1158 | if (hidpp->battery.feature_index == 0xff) { | ||
1159 | ret = hidpp_root_get_feature(hidpp, | ||
1160 | HIDPP_PAGE_SOLAR_KEYBOARD, | ||
1161 | &hidpp->battery.solar_feature_index, | ||
1162 | &feature_type); | ||
1163 | if (ret) | ||
1164 | return ret; | ||
1165 | } | ||
1166 | |||
1167 | ret = hidpp_send_fap_command_sync(hidpp, | ||
1168 | hidpp->battery.solar_feature_index, | ||
1169 | CMD_SOLAR_SET_LIGHT_MEASURE, | ||
1170 | params, 2, &response); | ||
1171 | if (ret > 0) { | ||
1172 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
1173 | __func__, ret); | ||
1174 | return -EPROTO; | ||
1175 | } | ||
1176 | if (ret) | ||
1177 | return ret; | ||
1178 | |||
1179 | hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_MILEAGE; | ||
1180 | |||
1181 | return 0; | ||
1182 | } | ||
1183 | |||
1184 | static int hidpp_solar_battery_event(struct hidpp_device *hidpp, | ||
1185 | u8 *data, int size) | ||
1186 | { | ||
1187 | struct hidpp_report *report = (struct hidpp_report *)data; | ||
1188 | int capacity, lux, status; | ||
1189 | u8 function; | ||
1190 | |||
1191 | function = report->fap.funcindex_clientid; | ||
1192 | |||
1193 | |||
1194 | if (report->fap.feature_index != hidpp->battery.solar_feature_index || | ||
1195 | !(function == EVENT_SOLAR_BATTERY_BROADCAST || | ||
1196 | function == EVENT_SOLAR_BATTERY_LIGHT_MEASURE || | ||
1197 | function == EVENT_SOLAR_CHECK_LIGHT_BUTTON)) | ||
1198 | return 0; | ||
1199 | |||
1200 | capacity = report->fap.params[0]; | ||
1201 | |||
1202 | switch (function) { | ||
1203 | case EVENT_SOLAR_BATTERY_LIGHT_MEASURE: | ||
1204 | lux = (report->fap.params[1] << 8) | report->fap.params[2]; | ||
1205 | if (lux > 200) | ||
1206 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
1207 | else | ||
1208 | status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
1209 | break; | ||
1210 | case EVENT_SOLAR_CHECK_LIGHT_BUTTON: | ||
1211 | default: | ||
1212 | if (capacity < hidpp->battery.capacity) | ||
1213 | status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
1214 | else | ||
1215 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
1216 | |||
1217 | } | ||
1218 | |||
1219 | if (capacity == 100) | ||
1220 | status = POWER_SUPPLY_STATUS_FULL; | ||
1221 | |||
1222 | hidpp->battery.online = true; | ||
1223 | if (capacity != hidpp->battery.capacity || | ||
1224 | status != hidpp->battery.status) { | ||
1225 | hidpp->battery.capacity = capacity; | ||
1226 | hidpp->battery.status = status; | ||
1227 | if (hidpp->battery.ps) | ||
1228 | power_supply_changed(hidpp->battery.ps); | ||
1229 | } | ||
1230 | |||
1231 | return 0; | ||
1232 | } | ||
1233 | |||
1234 | /* -------------------------------------------------------------------------- */ | ||
610 | /* 0x6010: Touchpad FW items */ | 1235 | /* 0x6010: Touchpad FW items */ |
611 | /* -------------------------------------------------------------------------- */ | 1236 | /* -------------------------------------------------------------------------- */ |
612 | 1237 | ||
@@ -1599,9 +2224,6 @@ static int wtp_connect(struct hid_device *hdev, bool connected) | |||
1599 | struct wtp_data *wd = hidpp->private_data; | 2224 | struct wtp_data *wd = hidpp->private_data; |
1600 | int ret; | 2225 | int ret; |
1601 | 2226 | ||
1602 | if (!connected) | ||
1603 | return 0; | ||
1604 | |||
1605 | if (!wd->x_size) { | 2227 | if (!wd->x_size) { |
1606 | ret = wtp_get_config(hidpp); | 2228 | ret = wtp_get_config(hidpp); |
1607 | if (ret) { | 2229 | if (ret) { |
@@ -1669,9 +2291,6 @@ static int m560_send_config_command(struct hid_device *hdev, bool connected) | |||
1669 | 2291 | ||
1670 | hidpp_dev = hid_get_drvdata(hdev); | 2292 | hidpp_dev = hid_get_drvdata(hdev); |
1671 | 2293 | ||
1672 | if (!connected) | ||
1673 | return -ENODEV; | ||
1674 | |||
1675 | return hidpp_send_rap_command_sync( | 2294 | return hidpp_send_rap_command_sync( |
1676 | hidpp_dev, | 2295 | hidpp_dev, |
1677 | REPORT_ID_HIDPP_SHORT, | 2296 | REPORT_ID_HIDPP_SHORT, |
@@ -1875,9 +2494,6 @@ static int k400_connect(struct hid_device *hdev, bool connected) | |||
1875 | { | 2494 | { |
1876 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | 2495 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); |
1877 | 2496 | ||
1878 | if (!connected) | ||
1879 | return 0; | ||
1880 | |||
1881 | if (!disable_tap_to_click) | 2497 | if (!disable_tap_to_click) |
1882 | return 0; | 2498 | return 0; |
1883 | 2499 | ||
@@ -1974,6 +2590,7 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | |||
1974 | struct hidpp_report *question = hidpp->send_receive_buf; | 2590 | struct hidpp_report *question = hidpp->send_receive_buf; |
1975 | struct hidpp_report *answer = hidpp->send_receive_buf; | 2591 | struct hidpp_report *answer = hidpp->send_receive_buf; |
1976 | struct hidpp_report *report = (struct hidpp_report *)data; | 2592 | struct hidpp_report *report = (struct hidpp_report *)data; |
2593 | int ret; | ||
1977 | 2594 | ||
1978 | /* | 2595 | /* |
1979 | * If the mutex is locked then we have a pending answer from a | 2596 | * If the mutex is locked then we have a pending answer from a |
@@ -2002,12 +2619,26 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | |||
2002 | if (unlikely(hidpp_report_is_connect_event(report))) { | 2619 | if (unlikely(hidpp_report_is_connect_event(report))) { |
2003 | atomic_set(&hidpp->connected, | 2620 | atomic_set(&hidpp->connected, |
2004 | !(report->rap.params[0] & (1 << 6))); | 2621 | !(report->rap.params[0] & (1 << 6))); |
2005 | if ((hidpp->quirks & HIDPP_QUIRK_CONNECT_EVENTS) && | 2622 | if (schedule_work(&hidpp->work) == 0) |
2006 | (schedule_work(&hidpp->work) == 0)) | ||
2007 | dbg_hid("%s: connect event already queued\n", __func__); | 2623 | dbg_hid("%s: connect event already queued\n", __func__); |
2008 | return 1; | 2624 | return 1; |
2009 | } | 2625 | } |
2010 | 2626 | ||
2627 | if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { | ||
2628 | ret = hidpp20_battery_event(hidpp, data, size); | ||
2629 | if (ret != 0) | ||
2630 | return ret; | ||
2631 | ret = hidpp_solar_battery_event(hidpp, data, size); | ||
2632 | if (ret != 0) | ||
2633 | return ret; | ||
2634 | } | ||
2635 | |||
2636 | if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) { | ||
2637 | ret = hidpp10_battery_event(hidpp, data, size); | ||
2638 | if (ret != 0) | ||
2639 | return ret; | ||
2640 | } | ||
2641 | |||
2011 | return 0; | 2642 | return 0; |
2012 | } | 2643 | } |
2013 | 2644 | ||
@@ -2058,20 +2689,90 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
2058 | return 0; | 2689 | return 0; |
2059 | } | 2690 | } |
2060 | 2691 | ||
2061 | static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) | 2692 | static int hidpp_initialize_battery(struct hidpp_device *hidpp) |
2693 | { | ||
2694 | static atomic_t battery_no = ATOMIC_INIT(0); | ||
2695 | struct power_supply_config cfg = { .drv_data = hidpp }; | ||
2696 | struct power_supply_desc *desc = &hidpp->battery.desc; | ||
2697 | enum power_supply_property *battery_props; | ||
2698 | struct hidpp_battery *battery; | ||
2699 | unsigned int num_battery_props; | ||
2700 | unsigned long n; | ||
2701 | int ret; | ||
2702 | |||
2703 | if (hidpp->battery.ps) | ||
2704 | return 0; | ||
2705 | |||
2706 | hidpp->battery.feature_index = 0xff; | ||
2707 | hidpp->battery.solar_feature_index = 0xff; | ||
2708 | |||
2709 | if (hidpp->protocol_major >= 2) { | ||
2710 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_K750) | ||
2711 | ret = hidpp_solar_request_battery_event(hidpp); | ||
2712 | else | ||
2713 | ret = hidpp20_query_battery_info(hidpp); | ||
2714 | |||
2715 | if (ret) | ||
2716 | return ret; | ||
2717 | hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP20_BATTERY; | ||
2718 | } else { | ||
2719 | ret = hidpp10_query_battery_status(hidpp); | ||
2720 | if (ret) { | ||
2721 | ret = hidpp10_query_battery_mileage(hidpp); | ||
2722 | if (ret) | ||
2723 | return -ENOENT; | ||
2724 | hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_MILEAGE; | ||
2725 | } else { | ||
2726 | hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS; | ||
2727 | } | ||
2728 | hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP10_BATTERY; | ||
2729 | } | ||
2730 | |||
2731 | battery_props = devm_kmemdup(&hidpp->hid_dev->dev, | ||
2732 | hidpp_battery_props, | ||
2733 | sizeof(hidpp_battery_props), | ||
2734 | GFP_KERNEL); | ||
2735 | num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 2; | ||
2736 | |||
2737 | if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE) | ||
2738 | battery_props[num_battery_props++] = | ||
2739 | POWER_SUPPLY_PROP_CAPACITY; | ||
2740 | |||
2741 | if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS) | ||
2742 | battery_props[num_battery_props++] = | ||
2743 | POWER_SUPPLY_PROP_CAPACITY_LEVEL; | ||
2744 | |||
2745 | battery = &hidpp->battery; | ||
2746 | |||
2747 | n = atomic_inc_return(&battery_no) - 1; | ||
2748 | desc->properties = battery_props; | ||
2749 | desc->num_properties = num_battery_props; | ||
2750 | desc->get_property = hidpp_battery_get_property; | ||
2751 | sprintf(battery->name, "hidpp_battery_%ld", n); | ||
2752 | desc->name = battery->name; | ||
2753 | desc->type = POWER_SUPPLY_TYPE_BATTERY; | ||
2754 | desc->use_for_apm = 0; | ||
2755 | |||
2756 | battery->ps = devm_power_supply_register(&hidpp->hid_dev->dev, | ||
2757 | &battery->desc, | ||
2758 | &cfg); | ||
2759 | if (IS_ERR(battery->ps)) | ||
2760 | return PTR_ERR(battery->ps); | ||
2761 | |||
2762 | power_supply_powers(battery->ps, &hidpp->hid_dev->dev); | ||
2763 | |||
2764 | return ret; | ||
2765 | } | ||
2766 | |||
2767 | static void hidpp_overwrite_name(struct hid_device *hdev) | ||
2062 | { | 2768 | { |
2063 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | 2769 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); |
2064 | char *name; | 2770 | char *name; |
2065 | 2771 | ||
2066 | if (use_unifying) | 2772 | if (hidpp->protocol_major < 2) |
2067 | /* | 2773 | return; |
2068 | * the device is connected through an Unifying receiver, and | 2774 | |
2069 | * might not be already connected. | 2775 | name = hidpp_get_device_name(hidpp); |
2070 | * Ask the receiver for its name. | ||
2071 | */ | ||
2072 | name = hidpp_get_unifying_name(hidpp); | ||
2073 | else | ||
2074 | name = hidpp_get_device_name(hidpp); | ||
2075 | 2776 | ||
2076 | if (!name) { | 2777 | if (!name) { |
2077 | hid_err(hdev, "unable to retrieve the name of the device"); | 2778 | hid_err(hdev, "unable to retrieve the name of the device"); |
@@ -2129,6 +2830,16 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
2129 | struct input_dev *input; | 2830 | struct input_dev *input; |
2130 | char *name, *devm_name; | 2831 | char *name, *devm_name; |
2131 | 2832 | ||
2833 | if (!connected) { | ||
2834 | if (hidpp->battery.ps) { | ||
2835 | hidpp->battery.online = false; | ||
2836 | hidpp->battery.status = POWER_SUPPLY_STATUS_UNKNOWN; | ||
2837 | hidpp->battery.level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; | ||
2838 | power_supply_changed(hidpp->battery.ps); | ||
2839 | } | ||
2840 | return; | ||
2841 | } | ||
2842 | |||
2132 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { | 2843 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { |
2133 | ret = wtp_connect(hdev, connected); | 2844 | ret = wtp_connect(hdev, connected); |
2134 | if (ret) | 2845 | if (ret) |
@@ -2143,9 +2854,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
2143 | return; | 2854 | return; |
2144 | } | 2855 | } |
2145 | 2856 | ||
2146 | if (!connected || hidpp->delayed_input) | ||
2147 | return; | ||
2148 | |||
2149 | /* the device is already connected, we can ask for its name and | 2857 | /* the device is already connected, we can ask for its name and |
2150 | * protocol */ | 2858 | * protocol */ |
2151 | if (!hidpp->protocol_major) { | 2859 | if (!hidpp->protocol_major) { |
@@ -2158,11 +2866,7 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
2158 | hidpp->protocol_major, hidpp->protocol_minor); | 2866 | hidpp->protocol_major, hidpp->protocol_minor); |
2159 | } | 2867 | } |
2160 | 2868 | ||
2161 | if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)) | 2869 | if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) { |
2162 | /* if HID created the input nodes for us, we can stop now */ | ||
2163 | return; | ||
2164 | |||
2165 | if (!hidpp->name || hidpp->name == hdev->name) { | ||
2166 | name = hidpp_get_device_name(hidpp); | 2870 | name = hidpp_get_device_name(hidpp); |
2167 | if (!name) { | 2871 | if (!name) { |
2168 | hid_err(hdev, | 2872 | hid_err(hdev, |
@@ -2178,6 +2882,25 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
2178 | hidpp->name = devm_name; | 2882 | hidpp->name = devm_name; |
2179 | } | 2883 | } |
2180 | 2884 | ||
2885 | hidpp_initialize_battery(hidpp); | ||
2886 | |||
2887 | /* forward current battery state */ | ||
2888 | if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) { | ||
2889 | hidpp10_enable_battery_reporting(hidpp); | ||
2890 | if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE) | ||
2891 | hidpp10_query_battery_mileage(hidpp); | ||
2892 | else | ||
2893 | hidpp10_query_battery_status(hidpp); | ||
2894 | } else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { | ||
2895 | hidpp20_query_battery_info(hidpp); | ||
2896 | } | ||
2897 | if (hidpp->battery.ps) | ||
2898 | power_supply_changed(hidpp->battery.ps); | ||
2899 | |||
2900 | if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) | ||
2901 | /* if the input nodes are already created, we can stop now */ | ||
2902 | return; | ||
2903 | |||
2181 | input = hidpp_allocate_input(hdev); | 2904 | input = hidpp_allocate_input(hdev); |
2182 | if (!input) { | 2905 | if (!input) { |
2183 | hid_err(hdev, "cannot allocate new input device: %d\n", ret); | 2906 | hid_err(hdev, "cannot allocate new input device: %d\n", ret); |
@@ -2193,6 +2916,17 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
2193 | hidpp->delayed_input = input; | 2916 | hidpp->delayed_input = input; |
2194 | } | 2917 | } |
2195 | 2918 | ||
2919 | static DEVICE_ATTR(builtin_power_supply, 0000, NULL, NULL); | ||
2920 | |||
2921 | static struct attribute *sysfs_attrs[] = { | ||
2922 | &dev_attr_builtin_power_supply.attr, | ||
2923 | NULL | ||
2924 | }; | ||
2925 | |||
2926 | static struct attribute_group ps_attribute_group = { | ||
2927 | .attrs = sysfs_attrs | ||
2928 | }; | ||
2929 | |||
2196 | static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | 2930 | static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) |
2197 | { | 2931 | { |
2198 | struct hidpp_device *hidpp; | 2932 | struct hidpp_device *hidpp; |
@@ -2211,9 +2945,11 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
2211 | 2945 | ||
2212 | hidpp->quirks = id->driver_data; | 2946 | hidpp->quirks = id->driver_data; |
2213 | 2947 | ||
2948 | if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) | ||
2949 | hidpp->quirks |= HIDPP_QUIRK_UNIFYING; | ||
2950 | |||
2214 | if (disable_raw_mode) { | 2951 | if (disable_raw_mode) { |
2215 | hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP; | 2952 | hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP; |
2216 | hidpp->quirks &= ~HIDPP_QUIRK_CONNECT_EVENTS; | ||
2217 | hidpp->quirks &= ~HIDPP_QUIRK_NO_HIDINPUT; | 2953 | hidpp->quirks &= ~HIDPP_QUIRK_NO_HIDINPUT; |
2218 | } | 2954 | } |
2219 | 2955 | ||
@@ -2235,6 +2971,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
2235 | mutex_init(&hidpp->send_mutex); | 2971 | mutex_init(&hidpp->send_mutex); |
2236 | init_waitqueue_head(&hidpp->wait); | 2972 | init_waitqueue_head(&hidpp->wait); |
2237 | 2973 | ||
2974 | /* indicates we are handling the battery properties in the kernel */ | ||
2975 | ret = sysfs_create_group(&hdev->dev.kobj, &ps_attribute_group); | ||
2976 | if (ret) | ||
2977 | hid_warn(hdev, "Cannot allocate sysfs group for %s\n", | ||
2978 | hdev->name); | ||
2979 | |||
2238 | ret = hid_parse(hdev); | 2980 | ret = hid_parse(hdev); |
2239 | if (ret) { | 2981 | if (ret) { |
2240 | hid_err(hdev, "%s:parse failed\n", __func__); | 2982 | hid_err(hdev, "%s:parse failed\n", __func__); |
@@ -2263,8 +3005,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
2263 | /* Allow incoming packets */ | 3005 | /* Allow incoming packets */ |
2264 | hid_device_io_start(hdev); | 3006 | hid_device_io_start(hdev); |
2265 | 3007 | ||
3008 | if (hidpp->quirks & HIDPP_QUIRK_UNIFYING) | ||
3009 | hidpp_unifying_init(hidpp); | ||
3010 | |||
2266 | connected = hidpp_is_connected(hidpp); | 3011 | connected = hidpp_is_connected(hidpp); |
2267 | if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE) { | 3012 | atomic_set(&hidpp->connected, connected); |
3013 | if (!(hidpp->quirks & HIDPP_QUIRK_UNIFYING)) { | ||
2268 | if (!connected) { | 3014 | if (!connected) { |
2269 | ret = -ENODEV; | 3015 | ret = -ENODEV; |
2270 | hid_err(hdev, "Device not connected"); | 3016 | hid_err(hdev, "Device not connected"); |
@@ -2273,10 +3019,9 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
2273 | 3019 | ||
2274 | hid_info(hdev, "HID++ %u.%u device connected.\n", | 3020 | hid_info(hdev, "HID++ %u.%u device connected.\n", |
2275 | hidpp->protocol_major, hidpp->protocol_minor); | 3021 | hidpp->protocol_major, hidpp->protocol_minor); |
2276 | } | ||
2277 | 3022 | ||
2278 | hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE); | 3023 | hidpp_overwrite_name(hdev); |
2279 | atomic_set(&hidpp->connected, connected); | 3024 | } |
2280 | 3025 | ||
2281 | if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { | 3026 | if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { |
2282 | ret = wtp_get_config(hidpp); | 3027 | ret = wtp_get_config(hidpp); |
@@ -2299,12 +3044,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
2299 | } | 3044 | } |
2300 | } | 3045 | } |
2301 | 3046 | ||
2302 | if (hidpp->quirks & HIDPP_QUIRK_CONNECT_EVENTS) { | 3047 | /* Allow incoming packets */ |
2303 | /* Allow incoming packets */ | 3048 | hid_device_io_start(hdev); |
2304 | hid_device_io_start(hdev); | ||
2305 | 3049 | ||
2306 | hidpp_connect_event(hidpp); | 3050 | hidpp_connect_event(hidpp); |
2307 | } | ||
2308 | 3051 | ||
2309 | return ret; | 3052 | return ret; |
2310 | 3053 | ||
@@ -2316,6 +3059,7 @@ hid_hw_open_failed: | |||
2316 | } | 3059 | } |
2317 | hid_hw_start_fail: | 3060 | hid_hw_start_fail: |
2318 | hid_parse_fail: | 3061 | hid_parse_fail: |
3062 | sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); | ||
2319 | cancel_work_sync(&hidpp->work); | 3063 | cancel_work_sync(&hidpp->work); |
2320 | mutex_destroy(&hidpp->send_mutex); | 3064 | mutex_destroy(&hidpp->send_mutex); |
2321 | allocate_fail: | 3065 | allocate_fail: |
@@ -2327,6 +3071,8 @@ static void hidpp_remove(struct hid_device *hdev) | |||
2327 | { | 3071 | { |
2328 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | 3072 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); |
2329 | 3073 | ||
3074 | sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); | ||
3075 | |||
2330 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { | 3076 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { |
2331 | hidpp_ff_deinit(hdev); | 3077 | hidpp_ff_deinit(hdev); |
2332 | hid_hw_close(hdev); | 3078 | hid_hw_close(hdev); |
@@ -2357,7 +3103,11 @@ static const struct hid_device_id hidpp_devices[] = { | |||
2357 | { /* Keyboard logitech K400 */ | 3103 | { /* Keyboard logitech K400 */ |
2358 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, | 3104 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
2359 | USB_VENDOR_ID_LOGITECH, 0x4024), | 3105 | USB_VENDOR_ID_LOGITECH, 0x4024), |
2360 | .driver_data = HIDPP_QUIRK_CONNECT_EVENTS | HIDPP_QUIRK_CLASS_K400 }, | 3106 | .driver_data = HIDPP_QUIRK_CLASS_K400 }, |
3107 | { /* Solar Keyboard Logitech K750 */ | ||
3108 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, | ||
3109 | USB_VENDOR_ID_LOGITECH, 0x4002), | ||
3110 | .driver_data = HIDPP_QUIRK_CLASS_K750 }, | ||
2361 | 3111 | ||
2362 | { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, | 3112 | { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
2363 | USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, | 3113 | USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 692647485a53..24d5b6deb571 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -69,6 +69,7 @@ MODULE_LICENSE("GPL"); | |||
69 | #define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) | 69 | #define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) |
70 | #define MT_QUIRK_FORCE_GET_FEATURE (1 << 13) | 70 | #define MT_QUIRK_FORCE_GET_FEATURE (1 << 13) |
71 | #define MT_QUIRK_FIX_CONST_CONTACT_ID (1 << 14) | 71 | #define MT_QUIRK_FIX_CONST_CONTACT_ID (1 << 14) |
72 | #define MT_QUIRK_TOUCH_SIZE_SCALING (1 << 15) | ||
72 | 73 | ||
73 | #define MT_INPUTMODE_TOUCHSCREEN 0x02 | 74 | #define MT_INPUTMODE_TOUCHSCREEN 0x02 |
74 | #define MT_INPUTMODE_TOUCHPAD 0x03 | 75 | #define MT_INPUTMODE_TOUCHPAD 0x03 |
@@ -222,7 +223,8 @@ static struct mt_class mt_classes[] = { | |||
222 | */ | 223 | */ |
223 | { .name = MT_CLS_3M, | 224 | { .name = MT_CLS_3M, |
224 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | | 225 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | |
225 | MT_QUIRK_SLOT_IS_CONTACTID, | 226 | MT_QUIRK_SLOT_IS_CONTACTID | |
227 | MT_QUIRK_TOUCH_SIZE_SCALING, | ||
226 | .sn_move = 2048, | 228 | .sn_move = 2048, |
227 | .sn_width = 128, | 229 | .sn_width = 128, |
228 | .sn_height = 128, | 230 | .sn_height = 128, |
@@ -658,9 +660,17 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) | |||
658 | if (active) { | 660 | if (active) { |
659 | /* this finger is in proximity of the sensor */ | 661 | /* this finger is in proximity of the sensor */ |
660 | int wide = (s->w > s->h); | 662 | int wide = (s->w > s->h); |
661 | /* divided by two to match visual scale of touch */ | 663 | int major = max(s->w, s->h); |
662 | int major = max(s->w, s->h) >> 1; | 664 | int minor = min(s->w, s->h); |
663 | int minor = min(s->w, s->h) >> 1; | 665 | |
666 | /* | ||
667 | * divided by two to match visual scale of touch | ||
668 | * for devices with this quirk | ||
669 | */ | ||
670 | if (td->mtclass.quirks & MT_QUIRK_TOUCH_SIZE_SCALING) { | ||
671 | major = major >> 1; | ||
672 | minor = minor >> 1; | ||
673 | } | ||
664 | 674 | ||
665 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); | 675 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); |
666 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); | 676 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); |
diff --git a/drivers/hid/hid-nti.c b/drivers/hid/hid-nti.c new file mode 100644 index 000000000000..5bb827b223ba --- /dev/null +++ b/drivers/hid/hid-nti.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * USB HID quirks support for Network Technologies, Inc. "USB-SUN" USB | ||
3 | * adapter for pre-USB Sun keyboards | ||
4 | * | ||
5 | * Copyright (c) 2011 Google, Inc. | ||
6 | * | ||
7 | * Based on HID apple driver by | ||
8 | * Copyright (c) 1999 Andreas Gal | ||
9 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | ||
10 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | ||
11 | * Copyright (c) 2006-2007 Jiri Kosina | ||
12 | * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * This program is free software; you can redistribute it and/or modify it | ||
17 | * under the terms of the GNU General Public License as published by the Free | ||
18 | * Software Foundation; either version 2 of the License, or (at your option) | ||
19 | * any later version. | ||
20 | */ | ||
21 | |||
22 | #include <linux/device.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/hid.h> | ||
25 | #include <linux/module.h> | ||
26 | |||
27 | #include "hid-ids.h" | ||
28 | |||
29 | MODULE_AUTHOR("Jonathan Klabunde Tomer <jktomer@google.com>"); | ||
30 | MODULE_DESCRIPTION("HID driver for Network Technologies USB-SUN keyboard adapter"); | ||
31 | |||
32 | /* | ||
33 | * NTI Sun keyboard adapter has wrong logical maximum in report descriptor | ||
34 | */ | ||
35 | static __u8 *nti_usbsun_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
36 | unsigned int *rsize) | ||
37 | { | ||
38 | if (*rsize >= 60 && rdesc[53] == 0x65 && rdesc[59] == 0x65) { | ||
39 | hid_info(hdev, "fixing up NTI USB-SUN keyboard adapter report descriptor\n"); | ||
40 | rdesc[53] = rdesc[59] = 0xe7; | ||
41 | } | ||
42 | return rdesc; | ||
43 | } | ||
44 | |||
45 | static const struct hid_device_id nti_devices[] = { | ||
46 | { HID_USB_DEVICE(USB_VENDOR_ID_NTI, USB_DEVICE_ID_USB_SUN) }, | ||
47 | { } | ||
48 | }; | ||
49 | MODULE_DEVICE_TABLE(hid, nti_devices); | ||
50 | |||
51 | static struct hid_driver nti_driver = { | ||
52 | .name = "nti", | ||
53 | .id_table = nti_devices, | ||
54 | .report_fixup = nti_usbsun_report_fixup | ||
55 | }; | ||
56 | |||
57 | module_hid_driver(nti_driver); | ||
58 | |||
59 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 740996f9bdd4..d03203a82e8f 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -48,19 +48,21 @@ | |||
48 | #define PS3REMOTE BIT(4) | 48 | #define PS3REMOTE BIT(4) |
49 | #define DUALSHOCK4_CONTROLLER_USB BIT(5) | 49 | #define DUALSHOCK4_CONTROLLER_USB BIT(5) |
50 | #define DUALSHOCK4_CONTROLLER_BT BIT(6) | 50 | #define DUALSHOCK4_CONTROLLER_BT BIT(6) |
51 | #define MOTION_CONTROLLER_USB BIT(7) | 51 | #define DUALSHOCK4_DONGLE BIT(7) |
52 | #define MOTION_CONTROLLER_BT BIT(8) | 52 | #define MOTION_CONTROLLER_USB BIT(8) |
53 | #define NAVIGATION_CONTROLLER_USB BIT(9) | 53 | #define MOTION_CONTROLLER_BT BIT(9) |
54 | #define NAVIGATION_CONTROLLER_BT BIT(10) | 54 | #define NAVIGATION_CONTROLLER_USB BIT(10) |
55 | #define SINO_LITE_CONTROLLER BIT(11) | 55 | #define NAVIGATION_CONTROLLER_BT BIT(11) |
56 | #define FUTUREMAX_DANCE_MAT BIT(12) | 56 | #define SINO_LITE_CONTROLLER BIT(12) |
57 | #define FUTUREMAX_DANCE_MAT BIT(13) | ||
57 | 58 | ||
58 | #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) | 59 | #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) |
59 | #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) | 60 | #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) |
60 | #define NAVIGATION_CONTROLLER (NAVIGATION_CONTROLLER_USB |\ | 61 | #define NAVIGATION_CONTROLLER (NAVIGATION_CONTROLLER_USB |\ |
61 | NAVIGATION_CONTROLLER_BT) | 62 | NAVIGATION_CONTROLLER_BT) |
62 | #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ | 63 | #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ |
63 | DUALSHOCK4_CONTROLLER_BT) | 64 | DUALSHOCK4_CONTROLLER_BT | \ |
65 | DUALSHOCK4_DONGLE) | ||
64 | #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ | 66 | #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ |
65 | DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER |\ | 67 | DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER |\ |
66 | NAVIGATION_CONTROLLER) | 68 | NAVIGATION_CONTROLLER) |
@@ -73,89 +75,6 @@ | |||
73 | 75 | ||
74 | #define MAX_LEDS 4 | 76 | #define MAX_LEDS 4 |
75 | 77 | ||
76 | /* | ||
77 | * The Sixaxis reports both digital and analog values for each button on the | ||
78 | * controller except for Start, Select and the PS button. The controller ends | ||
79 | * up reporting 27 axes which causes them to spill over into the multi-touch | ||
80 | * axis values. Additionally, the controller only has 20 actual, physical axes | ||
81 | * so there are several unused axes in between the used ones. | ||
82 | */ | ||
83 | static u8 sixaxis_rdesc[] = { | ||
84 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
85 | 0x09, 0x04, /* Usage (Joystick), */ | ||
86 | 0xA1, 0x01, /* Collection (Application), */ | ||
87 | 0xA1, 0x02, /* Collection (Logical), */ | ||
88 | 0x85, 0x01, /* Report ID (1), */ | ||
89 | 0x75, 0x08, /* Report Size (8), */ | ||
90 | 0x95, 0x01, /* Report Count (1), */ | ||
91 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
92 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
93 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
94 | 0x75, 0x01, /* Report Size (1), */ | ||
95 | 0x95, 0x13, /* Report Count (19), */ | ||
96 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
97 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
98 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
99 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
100 | 0x05, 0x09, /* Usage Page (Button), */ | ||
101 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
102 | 0x29, 0x13, /* Usage Maximum (13h), */ | ||
103 | 0x81, 0x02, /* Input (Variable), */ | ||
104 | 0x75, 0x01, /* Report Size (1), */ | ||
105 | 0x95, 0x0D, /* Report Count (13), */ | ||
106 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
107 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
108 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
109 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
110 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
111 | 0x09, 0x01, /* Usage (Pointer), */ | ||
112 | 0xA1, 0x00, /* Collection (Physical), */ | ||
113 | 0x75, 0x08, /* Report Size (8), */ | ||
114 | 0x95, 0x04, /* Report Count (4), */ | ||
115 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
116 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
117 | 0x09, 0x30, /* Usage (X), */ | ||
118 | 0x09, 0x31, /* Usage (Y), */ | ||
119 | 0x09, 0x32, /* Usage (Z), */ | ||
120 | 0x09, 0x35, /* Usage (Rz), */ | ||
121 | 0x81, 0x02, /* Input (Variable), */ | ||
122 | 0xC0, /* End Collection, */ | ||
123 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
124 | 0x95, 0x13, /* Report Count (19), */ | ||
125 | 0x09, 0x01, /* Usage (Pointer), */ | ||
126 | 0x81, 0x02, /* Input (Variable), */ | ||
127 | 0x95, 0x0C, /* Report Count (12), */ | ||
128 | 0x81, 0x01, /* Input (Constant), */ | ||
129 | 0x75, 0x10, /* Report Size (16), */ | ||
130 | 0x95, 0x04, /* Report Count (4), */ | ||
131 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
132 | 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ | ||
133 | 0x09, 0x01, /* Usage (Pointer), */ | ||
134 | 0x81, 0x02, /* Input (Variable), */ | ||
135 | 0xC0, /* End Collection, */ | ||
136 | 0xA1, 0x02, /* Collection (Logical), */ | ||
137 | 0x85, 0x02, /* Report ID (2), */ | ||
138 | 0x75, 0x08, /* Report Size (8), */ | ||
139 | 0x95, 0x30, /* Report Count (48), */ | ||
140 | 0x09, 0x01, /* Usage (Pointer), */ | ||
141 | 0xB1, 0x02, /* Feature (Variable), */ | ||
142 | 0xC0, /* End Collection, */ | ||
143 | 0xA1, 0x02, /* Collection (Logical), */ | ||
144 | 0x85, 0xEE, /* Report ID (238), */ | ||
145 | 0x75, 0x08, /* Report Size (8), */ | ||
146 | 0x95, 0x30, /* Report Count (48), */ | ||
147 | 0x09, 0x01, /* Usage (Pointer), */ | ||
148 | 0xB1, 0x02, /* Feature (Variable), */ | ||
149 | 0xC0, /* End Collection, */ | ||
150 | 0xA1, 0x02, /* Collection (Logical), */ | ||
151 | 0x85, 0xEF, /* Report ID (239), */ | ||
152 | 0x75, 0x08, /* Report Size (8), */ | ||
153 | 0x95, 0x30, /* Report Count (48), */ | ||
154 | 0x09, 0x01, /* Usage (Pointer), */ | ||
155 | 0xB1, 0x02, /* Feature (Variable), */ | ||
156 | 0xC0, /* End Collection, */ | ||
157 | 0xC0 /* End Collection */ | ||
158 | }; | ||
159 | 78 | ||
160 | /* PS/3 Motion controller */ | 79 | /* PS/3 Motion controller */ |
161 | static u8 motion_rdesc[] = { | 80 | static u8 motion_rdesc[] = { |
@@ -254,567 +173,6 @@ static u8 motion_rdesc[] = { | |||
254 | 0xC0 /* End Collection */ | 173 | 0xC0 /* End Collection */ |
255 | }; | 174 | }; |
256 | 175 | ||
257 | /* PS/3 Navigation controller */ | ||
258 | static u8 navigation_rdesc[] = { | ||
259 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
260 | 0x09, 0x04, /* Usage (Joystick), */ | ||
261 | 0xA1, 0x01, /* Collection (Application), */ | ||
262 | 0xA1, 0x02, /* Collection (Logical), */ | ||
263 | 0x85, 0x01, /* Report ID (1), */ | ||
264 | 0x75, 0x08, /* Report Size (8), */ | ||
265 | 0x95, 0x01, /* Report Count (1), */ | ||
266 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
267 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
268 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
269 | 0x75, 0x01, /* Report Size (1), */ | ||
270 | 0x95, 0x13, /* Report Count (19), */ | ||
271 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
272 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
273 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
274 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
275 | 0x05, 0x09, /* Usage Page (Button), */ | ||
276 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
277 | 0x29, 0x13, /* Usage Maximum (13h), */ | ||
278 | 0x81, 0x02, /* Input (Variable), */ | ||
279 | 0x75, 0x01, /* Report Size (1), */ | ||
280 | 0x95, 0x0D, /* Report Count (13), */ | ||
281 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
282 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
283 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
284 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
285 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
286 | 0x09, 0x01, /* Usage (Pointer), */ | ||
287 | 0xA1, 0x00, /* Collection (Physical), */ | ||
288 | 0x75, 0x08, /* Report Size (8), */ | ||
289 | 0x95, 0x02, /* Report Count (2), */ | ||
290 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
291 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
292 | 0x09, 0x30, /* Usage (X), */ | ||
293 | 0x09, 0x31, /* Usage (Y), */ | ||
294 | 0x81, 0x02, /* Input (Variable), */ | ||
295 | 0xC0, /* End Collection, */ | ||
296 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
297 | 0x95, 0x06, /* Report Count (6), */ | ||
298 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
299 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
300 | 0x75, 0x08, /* Report Size (8), */ | ||
301 | 0x95, 0x05, /* Report Count (5), */ | ||
302 | 0x09, 0x01, /* Usage (Pointer), */ | ||
303 | 0x81, 0x02, /* Input (Variable), */ | ||
304 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
305 | 0x95, 0x01, /* Report Count (1), */ | ||
306 | 0x81, 0x02, /* Input (Variable), */ | ||
307 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
308 | 0x95, 0x01, /* Report Count (1), */ | ||
309 | 0x09, 0x01, /* Usage (Pointer), */ | ||
310 | 0x81, 0x02, /* Input (Variable), */ | ||
311 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
312 | 0x95, 0x1E, /* Report Count (24), */ | ||
313 | 0x81, 0x02, /* Input (Variable), */ | ||
314 | 0x75, 0x08, /* Report Size (8), */ | ||
315 | 0x95, 0x30, /* Report Count (48), */ | ||
316 | 0x09, 0x01, /* Usage (Pointer), */ | ||
317 | 0x91, 0x02, /* Output (Variable), */ | ||
318 | 0x75, 0x08, /* Report Size (8), */ | ||
319 | 0x95, 0x30, /* Report Count (48), */ | ||
320 | 0x09, 0x01, /* Usage (Pointer), */ | ||
321 | 0xB1, 0x02, /* Feature (Variable), */ | ||
322 | 0xC0, /* End Collection, */ | ||
323 | 0xA1, 0x02, /* Collection (Logical), */ | ||
324 | 0x85, 0x02, /* Report ID (2), */ | ||
325 | 0x75, 0x08, /* Report Size (8), */ | ||
326 | 0x95, 0x30, /* Report Count (48), */ | ||
327 | 0x09, 0x01, /* Usage (Pointer), */ | ||
328 | 0xB1, 0x02, /* Feature (Variable), */ | ||
329 | 0xC0, /* End Collection, */ | ||
330 | 0xA1, 0x02, /* Collection (Logical), */ | ||
331 | 0x85, 0xEE, /* Report ID (238), */ | ||
332 | 0x75, 0x08, /* Report Size (8), */ | ||
333 | 0x95, 0x30, /* Report Count (48), */ | ||
334 | 0x09, 0x01, /* Usage (Pointer), */ | ||
335 | 0xB1, 0x02, /* Feature (Variable), */ | ||
336 | 0xC0, /* End Collection, */ | ||
337 | 0xA1, 0x02, /* Collection (Logical), */ | ||
338 | 0x85, 0xEF, /* Report ID (239), */ | ||
339 | 0x75, 0x08, /* Report Size (8), */ | ||
340 | 0x95, 0x30, /* Report Count (48), */ | ||
341 | 0x09, 0x01, /* Usage (Pointer), */ | ||
342 | 0xB1, 0x02, /* Feature (Variable), */ | ||
343 | 0xC0, /* End Collection, */ | ||
344 | 0xC0 /* End Collection */ | ||
345 | }; | ||
346 | |||
347 | /* | ||
348 | * The default descriptor doesn't provide mapping for the accelerometers | ||
349 | * or orientation sensors. This fixed descriptor maps the accelerometers | ||
350 | * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors | ||
351 | * to usage values 0x43, 0x44 and 0x45. | ||
352 | */ | ||
353 | static u8 dualshock4_usb_rdesc[] = { | ||
354 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
355 | 0x09, 0x05, /* Usage (Gamepad), */ | ||
356 | 0xA1, 0x01, /* Collection (Application), */ | ||
357 | 0x85, 0x01, /* Report ID (1), */ | ||
358 | 0x09, 0x30, /* Usage (X), */ | ||
359 | 0x09, 0x31, /* Usage (Y), */ | ||
360 | 0x09, 0x32, /* Usage (Z), */ | ||
361 | 0x09, 0x35, /* Usage (Rz), */ | ||
362 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
363 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
364 | 0x75, 0x08, /* Report Size (8), */ | ||
365 | 0x95, 0x04, /* Report Count (4), */ | ||
366 | 0x81, 0x02, /* Input (Variable), */ | ||
367 | 0x09, 0x39, /* Usage (Hat Switch), */ | ||
368 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
369 | 0x25, 0x07, /* Logical Maximum (7), */ | ||
370 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
371 | 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ | ||
372 | 0x65, 0x14, /* Unit (Degrees), */ | ||
373 | 0x75, 0x04, /* Report Size (4), */ | ||
374 | 0x95, 0x01, /* Report Count (1), */ | ||
375 | 0x81, 0x42, /* Input (Variable, Null State), */ | ||
376 | 0x65, 0x00, /* Unit, */ | ||
377 | 0x05, 0x09, /* Usage Page (Button), */ | ||
378 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
379 | 0x29, 0x0D, /* Usage Maximum (0Dh), */ | ||
380 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
381 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
382 | 0x75, 0x01, /* Report Size (1), */ | ||
383 | 0x95, 0x0E, /* Report Count (14), */ | ||
384 | 0x81, 0x02, /* Input (Variable), */ | ||
385 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
386 | 0x09, 0x20, /* Usage (20h), */ | ||
387 | 0x75, 0x06, /* Report Size (6), */ | ||
388 | 0x95, 0x01, /* Report Count (1), */ | ||
389 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
390 | 0x25, 0x3F, /* Logical Maximum (63), */ | ||
391 | 0x81, 0x02, /* Input (Variable), */ | ||
392 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
393 | 0x09, 0x33, /* Usage (Rx), */ | ||
394 | 0x09, 0x34, /* Usage (Ry), */ | ||
395 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
396 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
397 | 0x75, 0x08, /* Report Size (8), */ | ||
398 | 0x95, 0x02, /* Report Count (2), */ | ||
399 | 0x81, 0x02, /* Input (Variable), */ | ||
400 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
401 | 0x09, 0x21, /* Usage (21h), */ | ||
402 | 0x95, 0x03, /* Report Count (3), */ | ||
403 | 0x81, 0x02, /* Input (Variable), */ | ||
404 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
405 | 0x19, 0x40, /* Usage Minimum (40h), */ | ||
406 | 0x29, 0x42, /* Usage Maximum (42h), */ | ||
407 | 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ | ||
408 | 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ | ||
409 | 0x75, 0x10, /* Report Size (16), */ | ||
410 | 0x95, 0x03, /* Report Count (3), */ | ||
411 | 0x81, 0x02, /* Input (Variable), */ | ||
412 | 0x19, 0x43, /* Usage Minimum (43h), */ | ||
413 | 0x29, 0x45, /* Usage Maximum (45h), */ | ||
414 | 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ | ||
415 | 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ | ||
416 | 0x95, 0x03, /* Report Count (3), */ | ||
417 | 0x81, 0x02, /* Input (Variable), */ | ||
418 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
419 | 0x09, 0x21, /* Usage (21h), */ | ||
420 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
421 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
422 | 0x75, 0x08, /* Report Size (8), */ | ||
423 | 0x95, 0x27, /* Report Count (39), */ | ||
424 | 0x81, 0x02, /* Input (Variable), */ | ||
425 | 0x85, 0x05, /* Report ID (5), */ | ||
426 | 0x09, 0x22, /* Usage (22h), */ | ||
427 | 0x95, 0x1F, /* Report Count (31), */ | ||
428 | 0x91, 0x02, /* Output (Variable), */ | ||
429 | 0x85, 0x04, /* Report ID (4), */ | ||
430 | 0x09, 0x23, /* Usage (23h), */ | ||
431 | 0x95, 0x24, /* Report Count (36), */ | ||
432 | 0xB1, 0x02, /* Feature (Variable), */ | ||
433 | 0x85, 0x02, /* Report ID (2), */ | ||
434 | 0x09, 0x24, /* Usage (24h), */ | ||
435 | 0x95, 0x24, /* Report Count (36), */ | ||
436 | 0xB1, 0x02, /* Feature (Variable), */ | ||
437 | 0x85, 0x08, /* Report ID (8), */ | ||
438 | 0x09, 0x25, /* Usage (25h), */ | ||
439 | 0x95, 0x03, /* Report Count (3), */ | ||
440 | 0xB1, 0x02, /* Feature (Variable), */ | ||
441 | 0x85, 0x10, /* Report ID (16), */ | ||
442 | 0x09, 0x26, /* Usage (26h), */ | ||
443 | 0x95, 0x04, /* Report Count (4), */ | ||
444 | 0xB1, 0x02, /* Feature (Variable), */ | ||
445 | 0x85, 0x11, /* Report ID (17), */ | ||
446 | 0x09, 0x27, /* Usage (27h), */ | ||
447 | 0x95, 0x02, /* Report Count (2), */ | ||
448 | 0xB1, 0x02, /* Feature (Variable), */ | ||
449 | 0x85, 0x12, /* Report ID (18), */ | ||
450 | 0x06, 0x02, 0xFF, /* Usage Page (FF02h), */ | ||
451 | 0x09, 0x21, /* Usage (21h), */ | ||
452 | 0x95, 0x0F, /* Report Count (15), */ | ||
453 | 0xB1, 0x02, /* Feature (Variable), */ | ||
454 | 0x85, 0x13, /* Report ID (19), */ | ||
455 | 0x09, 0x22, /* Usage (22h), */ | ||
456 | 0x95, 0x16, /* Report Count (22), */ | ||
457 | 0xB1, 0x02, /* Feature (Variable), */ | ||
458 | 0x85, 0x14, /* Report ID (20), */ | ||
459 | 0x06, 0x05, 0xFF, /* Usage Page (FF05h), */ | ||
460 | 0x09, 0x20, /* Usage (20h), */ | ||
461 | 0x95, 0x10, /* Report Count (16), */ | ||
462 | 0xB1, 0x02, /* Feature (Variable), */ | ||
463 | 0x85, 0x15, /* Report ID (21), */ | ||
464 | 0x09, 0x21, /* Usage (21h), */ | ||
465 | 0x95, 0x2C, /* Report Count (44), */ | ||
466 | 0xB1, 0x02, /* Feature (Variable), */ | ||
467 | 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ | ||
468 | 0x85, 0x80, /* Report ID (128), */ | ||
469 | 0x09, 0x20, /* Usage (20h), */ | ||
470 | 0x95, 0x06, /* Report Count (6), */ | ||
471 | 0xB1, 0x02, /* Feature (Variable), */ | ||
472 | 0x85, 0x81, /* Report ID (129), */ | ||
473 | 0x09, 0x21, /* Usage (21h), */ | ||
474 | 0x95, 0x06, /* Report Count (6), */ | ||
475 | 0xB1, 0x02, /* Feature (Variable), */ | ||
476 | 0x85, 0x82, /* Report ID (130), */ | ||
477 | 0x09, 0x22, /* Usage (22h), */ | ||
478 | 0x95, 0x05, /* Report Count (5), */ | ||
479 | 0xB1, 0x02, /* Feature (Variable), */ | ||
480 | 0x85, 0x83, /* Report ID (131), */ | ||
481 | 0x09, 0x23, /* Usage (23h), */ | ||
482 | 0x95, 0x01, /* Report Count (1), */ | ||
483 | 0xB1, 0x02, /* Feature (Variable), */ | ||
484 | 0x85, 0x84, /* Report ID (132), */ | ||
485 | 0x09, 0x24, /* Usage (24h), */ | ||
486 | 0x95, 0x04, /* Report Count (4), */ | ||
487 | 0xB1, 0x02, /* Feature (Variable), */ | ||
488 | 0x85, 0x85, /* Report ID (133), */ | ||
489 | 0x09, 0x25, /* Usage (25h), */ | ||
490 | 0x95, 0x06, /* Report Count (6), */ | ||
491 | 0xB1, 0x02, /* Feature (Variable), */ | ||
492 | 0x85, 0x86, /* Report ID (134), */ | ||
493 | 0x09, 0x26, /* Usage (26h), */ | ||
494 | 0x95, 0x06, /* Report Count (6), */ | ||
495 | 0xB1, 0x02, /* Feature (Variable), */ | ||
496 | 0x85, 0x87, /* Report ID (135), */ | ||
497 | 0x09, 0x27, /* Usage (27h), */ | ||
498 | 0x95, 0x23, /* Report Count (35), */ | ||
499 | 0xB1, 0x02, /* Feature (Variable), */ | ||
500 | 0x85, 0x88, /* Report ID (136), */ | ||
501 | 0x09, 0x28, /* Usage (28h), */ | ||
502 | 0x95, 0x22, /* Report Count (34), */ | ||
503 | 0xB1, 0x02, /* Feature (Variable), */ | ||
504 | 0x85, 0x89, /* Report ID (137), */ | ||
505 | 0x09, 0x29, /* Usage (29h), */ | ||
506 | 0x95, 0x02, /* Report Count (2), */ | ||
507 | 0xB1, 0x02, /* Feature (Variable), */ | ||
508 | 0x85, 0x90, /* Report ID (144), */ | ||
509 | 0x09, 0x30, /* Usage (30h), */ | ||
510 | 0x95, 0x05, /* Report Count (5), */ | ||
511 | 0xB1, 0x02, /* Feature (Variable), */ | ||
512 | 0x85, 0x91, /* Report ID (145), */ | ||
513 | 0x09, 0x31, /* Usage (31h), */ | ||
514 | 0x95, 0x03, /* Report Count (3), */ | ||
515 | 0xB1, 0x02, /* Feature (Variable), */ | ||
516 | 0x85, 0x92, /* Report ID (146), */ | ||
517 | 0x09, 0x32, /* Usage (32h), */ | ||
518 | 0x95, 0x03, /* Report Count (3), */ | ||
519 | 0xB1, 0x02, /* Feature (Variable), */ | ||
520 | 0x85, 0x93, /* Report ID (147), */ | ||
521 | 0x09, 0x33, /* Usage (33h), */ | ||
522 | 0x95, 0x0C, /* Report Count (12), */ | ||
523 | 0xB1, 0x02, /* Feature (Variable), */ | ||
524 | 0x85, 0xA0, /* Report ID (160), */ | ||
525 | 0x09, 0x40, /* Usage (40h), */ | ||
526 | 0x95, 0x06, /* Report Count (6), */ | ||
527 | 0xB1, 0x02, /* Feature (Variable), */ | ||
528 | 0x85, 0xA1, /* Report ID (161), */ | ||
529 | 0x09, 0x41, /* Usage (41h), */ | ||
530 | 0x95, 0x01, /* Report Count (1), */ | ||
531 | 0xB1, 0x02, /* Feature (Variable), */ | ||
532 | 0x85, 0xA2, /* Report ID (162), */ | ||
533 | 0x09, 0x42, /* Usage (42h), */ | ||
534 | 0x95, 0x01, /* Report Count (1), */ | ||
535 | 0xB1, 0x02, /* Feature (Variable), */ | ||
536 | 0x85, 0xA3, /* Report ID (163), */ | ||
537 | 0x09, 0x43, /* Usage (43h), */ | ||
538 | 0x95, 0x30, /* Report Count (48), */ | ||
539 | 0xB1, 0x02, /* Feature (Variable), */ | ||
540 | 0x85, 0xA4, /* Report ID (164), */ | ||
541 | 0x09, 0x44, /* Usage (44h), */ | ||
542 | 0x95, 0x0D, /* Report Count (13), */ | ||
543 | 0xB1, 0x02, /* Feature (Variable), */ | ||
544 | 0x85, 0xA5, /* Report ID (165), */ | ||
545 | 0x09, 0x45, /* Usage (45h), */ | ||
546 | 0x95, 0x15, /* Report Count (21), */ | ||
547 | 0xB1, 0x02, /* Feature (Variable), */ | ||
548 | 0x85, 0xA6, /* Report ID (166), */ | ||
549 | 0x09, 0x46, /* Usage (46h), */ | ||
550 | 0x95, 0x15, /* Report Count (21), */ | ||
551 | 0xB1, 0x02, /* Feature (Variable), */ | ||
552 | 0x85, 0xF0, /* Report ID (240), */ | ||
553 | 0x09, 0x47, /* Usage (47h), */ | ||
554 | 0x95, 0x3F, /* Report Count (63), */ | ||
555 | 0xB1, 0x02, /* Feature (Variable), */ | ||
556 | 0x85, 0xF1, /* Report ID (241), */ | ||
557 | 0x09, 0x48, /* Usage (48h), */ | ||
558 | 0x95, 0x3F, /* Report Count (63), */ | ||
559 | 0xB1, 0x02, /* Feature (Variable), */ | ||
560 | 0x85, 0xF2, /* Report ID (242), */ | ||
561 | 0x09, 0x49, /* Usage (49h), */ | ||
562 | 0x95, 0x0F, /* Report Count (15), */ | ||
563 | 0xB1, 0x02, /* Feature (Variable), */ | ||
564 | 0x85, 0xA7, /* Report ID (167), */ | ||
565 | 0x09, 0x4A, /* Usage (4Ah), */ | ||
566 | 0x95, 0x01, /* Report Count (1), */ | ||
567 | 0xB1, 0x02, /* Feature (Variable), */ | ||
568 | 0x85, 0xA8, /* Report ID (168), */ | ||
569 | 0x09, 0x4B, /* Usage (4Bh), */ | ||
570 | 0x95, 0x01, /* Report Count (1), */ | ||
571 | 0xB1, 0x02, /* Feature (Variable), */ | ||
572 | 0x85, 0xA9, /* Report ID (169), */ | ||
573 | 0x09, 0x4C, /* Usage (4Ch), */ | ||
574 | 0x95, 0x08, /* Report Count (8), */ | ||
575 | 0xB1, 0x02, /* Feature (Variable), */ | ||
576 | 0x85, 0xAA, /* Report ID (170), */ | ||
577 | 0x09, 0x4E, /* Usage (4Eh), */ | ||
578 | 0x95, 0x01, /* Report Count (1), */ | ||
579 | 0xB1, 0x02, /* Feature (Variable), */ | ||
580 | 0x85, 0xAB, /* Report ID (171), */ | ||
581 | 0x09, 0x4F, /* Usage (4Fh), */ | ||
582 | 0x95, 0x39, /* Report Count (57), */ | ||
583 | 0xB1, 0x02, /* Feature (Variable), */ | ||
584 | 0x85, 0xAC, /* Report ID (172), */ | ||
585 | 0x09, 0x50, /* Usage (50h), */ | ||
586 | 0x95, 0x39, /* Report Count (57), */ | ||
587 | 0xB1, 0x02, /* Feature (Variable), */ | ||
588 | 0x85, 0xAD, /* Report ID (173), */ | ||
589 | 0x09, 0x51, /* Usage (51h), */ | ||
590 | 0x95, 0x0B, /* Report Count (11), */ | ||
591 | 0xB1, 0x02, /* Feature (Variable), */ | ||
592 | 0x85, 0xAE, /* Report ID (174), */ | ||
593 | 0x09, 0x52, /* Usage (52h), */ | ||
594 | 0x95, 0x01, /* Report Count (1), */ | ||
595 | 0xB1, 0x02, /* Feature (Variable), */ | ||
596 | 0x85, 0xAF, /* Report ID (175), */ | ||
597 | 0x09, 0x53, /* Usage (53h), */ | ||
598 | 0x95, 0x02, /* Report Count (2), */ | ||
599 | 0xB1, 0x02, /* Feature (Variable), */ | ||
600 | 0x85, 0xB0, /* Report ID (176), */ | ||
601 | 0x09, 0x54, /* Usage (54h), */ | ||
602 | 0x95, 0x3F, /* Report Count (63), */ | ||
603 | 0xB1, 0x02, /* Feature (Variable), */ | ||
604 | 0xC0 /* End Collection */ | ||
605 | }; | ||
606 | |||
607 | /* | ||
608 | * The default behavior of the Dualshock 4 is to send reports using report | ||
609 | * type 1 when running over Bluetooth. However, when feature report 2 is | ||
610 | * requested during the controller initialization it starts sending input | ||
611 | * reports in report 17. Since report 17 is undefined in the default HID | ||
612 | * descriptor the button and axis definitions must be moved to report 17 or | ||
613 | * the HID layer won't process the received input. | ||
614 | */ | ||
615 | static u8 dualshock4_bt_rdesc[] = { | ||
616 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
617 | 0x09, 0x05, /* Usage (Gamepad), */ | ||
618 | 0xA1, 0x01, /* Collection (Application), */ | ||
619 | 0x85, 0x01, /* Report ID (1), */ | ||
620 | 0x75, 0x08, /* Report Size (8), */ | ||
621 | 0x95, 0x0A, /* Report Count (9), */ | ||
622 | 0x81, 0x02, /* Input (Variable), */ | ||
623 | 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */ | ||
624 | 0x85, 0x02, /* Report ID (2), */ | ||
625 | 0x09, 0x24, /* Usage (24h), */ | ||
626 | 0x95, 0x24, /* Report Count (36), */ | ||
627 | 0xB1, 0x02, /* Feature (Variable), */ | ||
628 | 0x85, 0xA3, /* Report ID (163), */ | ||
629 | 0x09, 0x25, /* Usage (25h), */ | ||
630 | 0x95, 0x30, /* Report Count (48), */ | ||
631 | 0xB1, 0x02, /* Feature (Variable), */ | ||
632 | 0x85, 0x05, /* Report ID (5), */ | ||
633 | 0x09, 0x26, /* Usage (26h), */ | ||
634 | 0x95, 0x28, /* Report Count (40), */ | ||
635 | 0xB1, 0x02, /* Feature (Variable), */ | ||
636 | 0x85, 0x06, /* Report ID (6), */ | ||
637 | 0x09, 0x27, /* Usage (27h), */ | ||
638 | 0x95, 0x34, /* Report Count (52), */ | ||
639 | 0xB1, 0x02, /* Feature (Variable), */ | ||
640 | 0x85, 0x07, /* Report ID (7), */ | ||
641 | 0x09, 0x28, /* Usage (28h), */ | ||
642 | 0x95, 0x30, /* Report Count (48), */ | ||
643 | 0xB1, 0x02, /* Feature (Variable), */ | ||
644 | 0x85, 0x08, /* Report ID (8), */ | ||
645 | 0x09, 0x29, /* Usage (29h), */ | ||
646 | 0x95, 0x2F, /* Report Count (47), */ | ||
647 | 0xB1, 0x02, /* Feature (Variable), */ | ||
648 | 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */ | ||
649 | 0x85, 0x03, /* Report ID (3), */ | ||
650 | 0x09, 0x21, /* Usage (21h), */ | ||
651 | 0x95, 0x26, /* Report Count (38), */ | ||
652 | 0xB1, 0x02, /* Feature (Variable), */ | ||
653 | 0x85, 0x04, /* Report ID (4), */ | ||
654 | 0x09, 0x22, /* Usage (22h), */ | ||
655 | 0x95, 0x2E, /* Report Count (46), */ | ||
656 | 0xB1, 0x02, /* Feature (Variable), */ | ||
657 | 0x85, 0xF0, /* Report ID (240), */ | ||
658 | 0x09, 0x47, /* Usage (47h), */ | ||
659 | 0x95, 0x3F, /* Report Count (63), */ | ||
660 | 0xB1, 0x02, /* Feature (Variable), */ | ||
661 | 0x85, 0xF1, /* Report ID (241), */ | ||
662 | 0x09, 0x48, /* Usage (48h), */ | ||
663 | 0x95, 0x3F, /* Report Count (63), */ | ||
664 | 0xB1, 0x02, /* Feature (Variable), */ | ||
665 | 0x85, 0xF2, /* Report ID (242), */ | ||
666 | 0x09, 0x49, /* Usage (49h), */ | ||
667 | 0x95, 0x0F, /* Report Count (15), */ | ||
668 | 0xB1, 0x02, /* Feature (Variable), */ | ||
669 | 0x85, 0x11, /* Report ID (17), */ | ||
670 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
671 | 0x09, 0x20, /* Usage (20h), */ | ||
672 | 0x95, 0x02, /* Report Count (2), */ | ||
673 | 0x81, 0x02, /* Input (Variable), */ | ||
674 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
675 | 0x09, 0x30, /* Usage (X), */ | ||
676 | 0x09, 0x31, /* Usage (Y), */ | ||
677 | 0x09, 0x32, /* Usage (Z), */ | ||
678 | 0x09, 0x35, /* Usage (Rz), */ | ||
679 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
680 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
681 | 0x75, 0x08, /* Report Size (8), */ | ||
682 | 0x95, 0x04, /* Report Count (4), */ | ||
683 | 0x81, 0x02, /* Input (Variable), */ | ||
684 | 0x09, 0x39, /* Usage (Hat Switch), */ | ||
685 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
686 | 0x25, 0x07, /* Logical Maximum (7), */ | ||
687 | 0x75, 0x04, /* Report Size (4), */ | ||
688 | 0x95, 0x01, /* Report Count (1), */ | ||
689 | 0x81, 0x42, /* Input (Variable, Null State), */ | ||
690 | 0x05, 0x09, /* Usage Page (Button), */ | ||
691 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
692 | 0x29, 0x0D, /* Usage Maximum (0Dh), */ | ||
693 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
694 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
695 | 0x75, 0x01, /* Report Size (1), */ | ||
696 | 0x95, 0x0E, /* Report Count (14), */ | ||
697 | 0x81, 0x02, /* Input (Variable), */ | ||
698 | 0x75, 0x06, /* Report Size (6), */ | ||
699 | 0x95, 0x01, /* Report Count (1), */ | ||
700 | 0x81, 0x01, /* Input (Constant), */ | ||
701 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
702 | 0x09, 0x33, /* Usage (Rx), */ | ||
703 | 0x09, 0x34, /* Usage (Ry), */ | ||
704 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
705 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
706 | 0x75, 0x08, /* Report Size (8), */ | ||
707 | 0x95, 0x02, /* Report Count (2), */ | ||
708 | 0x81, 0x02, /* Input (Variable), */ | ||
709 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
710 | 0x09, 0x20, /* Usage (20h), */ | ||
711 | 0x95, 0x03, /* Report Count (3), */ | ||
712 | 0x81, 0x02, /* Input (Variable), */ | ||
713 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
714 | 0x19, 0x40, /* Usage Minimum (40h), */ | ||
715 | 0x29, 0x42, /* Usage Maximum (42h), */ | ||
716 | 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ | ||
717 | 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ | ||
718 | 0x75, 0x10, /* Report Size (16), */ | ||
719 | 0x95, 0x03, /* Report Count (3), */ | ||
720 | 0x81, 0x02, /* Input (Variable), */ | ||
721 | 0x19, 0x43, /* Usage Minimum (43h), */ | ||
722 | 0x29, 0x45, /* Usage Maximum (45h), */ | ||
723 | 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ | ||
724 | 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ | ||
725 | 0x95, 0x03, /* Report Count (3), */ | ||
726 | 0x81, 0x02, /* Input (Variable), */ | ||
727 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
728 | 0x09, 0x20, /* Usage (20h), */ | ||
729 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
730 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
731 | 0x75, 0x08, /* Report Size (8), */ | ||
732 | 0x95, 0x31, /* Report Count (51), */ | ||
733 | 0x81, 0x02, /* Input (Variable), */ | ||
734 | 0x09, 0x21, /* Usage (21h), */ | ||
735 | 0x75, 0x08, /* Report Size (8), */ | ||
736 | 0x95, 0x4D, /* Report Count (77), */ | ||
737 | 0x91, 0x02, /* Output (Variable), */ | ||
738 | 0x85, 0x12, /* Report ID (18), */ | ||
739 | 0x09, 0x22, /* Usage (22h), */ | ||
740 | 0x95, 0x8D, /* Report Count (141), */ | ||
741 | 0x81, 0x02, /* Input (Variable), */ | ||
742 | 0x09, 0x23, /* Usage (23h), */ | ||
743 | 0x91, 0x02, /* Output (Variable), */ | ||
744 | 0x85, 0x13, /* Report ID (19), */ | ||
745 | 0x09, 0x24, /* Usage (24h), */ | ||
746 | 0x95, 0xCD, /* Report Count (205), */ | ||
747 | 0x81, 0x02, /* Input (Variable), */ | ||
748 | 0x09, 0x25, /* Usage (25h), */ | ||
749 | 0x91, 0x02, /* Output (Variable), */ | ||
750 | 0x85, 0x14, /* Report ID (20), */ | ||
751 | 0x09, 0x26, /* Usage (26h), */ | ||
752 | 0x96, 0x0D, 0x01, /* Report Count (269), */ | ||
753 | 0x81, 0x02, /* Input (Variable), */ | ||
754 | 0x09, 0x27, /* Usage (27h), */ | ||
755 | 0x91, 0x02, /* Output (Variable), */ | ||
756 | 0x85, 0x15, /* Report ID (21), */ | ||
757 | 0x09, 0x28, /* Usage (28h), */ | ||
758 | 0x96, 0x4D, 0x01, /* Report Count (333), */ | ||
759 | 0x81, 0x02, /* Input (Variable), */ | ||
760 | 0x09, 0x29, /* Usage (29h), */ | ||
761 | 0x91, 0x02, /* Output (Variable), */ | ||
762 | 0x85, 0x16, /* Report ID (22), */ | ||
763 | 0x09, 0x2A, /* Usage (2Ah), */ | ||
764 | 0x96, 0x8D, 0x01, /* Report Count (397), */ | ||
765 | 0x81, 0x02, /* Input (Variable), */ | ||
766 | 0x09, 0x2B, /* Usage (2Bh), */ | ||
767 | 0x91, 0x02, /* Output (Variable), */ | ||
768 | 0x85, 0x17, /* Report ID (23), */ | ||
769 | 0x09, 0x2C, /* Usage (2Ch), */ | ||
770 | 0x96, 0xCD, 0x01, /* Report Count (461), */ | ||
771 | 0x81, 0x02, /* Input (Variable), */ | ||
772 | 0x09, 0x2D, /* Usage (2Dh), */ | ||
773 | 0x91, 0x02, /* Output (Variable), */ | ||
774 | 0x85, 0x18, /* Report ID (24), */ | ||
775 | 0x09, 0x2E, /* Usage (2Eh), */ | ||
776 | 0x96, 0x0D, 0x02, /* Report Count (525), */ | ||
777 | 0x81, 0x02, /* Input (Variable), */ | ||
778 | 0x09, 0x2F, /* Usage (2Fh), */ | ||
779 | 0x91, 0x02, /* Output (Variable), */ | ||
780 | 0x85, 0x19, /* Report ID (25), */ | ||
781 | 0x09, 0x30, /* Usage (30h), */ | ||
782 | 0x96, 0x22, 0x02, /* Report Count (546), */ | ||
783 | 0x81, 0x02, /* Input (Variable), */ | ||
784 | 0x09, 0x31, /* Usage (31h), */ | ||
785 | 0x91, 0x02, /* Output (Variable), */ | ||
786 | 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ | ||
787 | 0x85, 0x82, /* Report ID (130), */ | ||
788 | 0x09, 0x22, /* Usage (22h), */ | ||
789 | 0x95, 0x3F, /* Report Count (63), */ | ||
790 | 0xB1, 0x02, /* Feature (Variable), */ | ||
791 | 0x85, 0x83, /* Report ID (131), */ | ||
792 | 0x09, 0x23, /* Usage (23h), */ | ||
793 | 0xB1, 0x02, /* Feature (Variable), */ | ||
794 | 0x85, 0x84, /* Report ID (132), */ | ||
795 | 0x09, 0x24, /* Usage (24h), */ | ||
796 | 0xB1, 0x02, /* Feature (Variable), */ | ||
797 | 0x85, 0x90, /* Report ID (144), */ | ||
798 | 0x09, 0x30, /* Usage (30h), */ | ||
799 | 0xB1, 0x02, /* Feature (Variable), */ | ||
800 | 0x85, 0x91, /* Report ID (145), */ | ||
801 | 0x09, 0x31, /* Usage (31h), */ | ||
802 | 0xB1, 0x02, /* Feature (Variable), */ | ||
803 | 0x85, 0x92, /* Report ID (146), */ | ||
804 | 0x09, 0x32, /* Usage (32h), */ | ||
805 | 0xB1, 0x02, /* Feature (Variable), */ | ||
806 | 0x85, 0x93, /* Report ID (147), */ | ||
807 | 0x09, 0x33, /* Usage (33h), */ | ||
808 | 0xB1, 0x02, /* Feature (Variable), */ | ||
809 | 0x85, 0xA0, /* Report ID (160), */ | ||
810 | 0x09, 0x40, /* Usage (40h), */ | ||
811 | 0xB1, 0x02, /* Feature (Variable), */ | ||
812 | 0x85, 0xA4, /* Report ID (164), */ | ||
813 | 0x09, 0x44, /* Usage (44h), */ | ||
814 | 0xB1, 0x02, /* Feature (Variable), */ | ||
815 | 0xC0 /* End Collection */ | ||
816 | }; | ||
817 | |||
818 | static u8 ps3remote_rdesc[] = { | 176 | static u8 ps3remote_rdesc[] = { |
819 | 0x05, 0x01, /* GUsagePage Generic Desktop */ | 177 | 0x05, 0x01, /* GUsagePage Generic Desktop */ |
820 | 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ | 178 | 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ |
@@ -977,6 +335,67 @@ static const unsigned int buzz_keymap[] = { | |||
977 | [20] = BTN_TRIGGER_HAPPY20, | 335 | [20] = BTN_TRIGGER_HAPPY20, |
978 | }; | 336 | }; |
979 | 337 | ||
338 | /* The Navigation controller is a partial DS3 and uses the same HID report | ||
339 | * and hence the same keymap indices, however not not all axes/buttons | ||
340 | * are physically present. We use the same axis and button mapping as | ||
341 | * the DS3, which uses the Linux gamepad spec. | ||
342 | */ | ||
343 | static const unsigned int navigation_absmap[] = { | ||
344 | [0x30] = ABS_X, | ||
345 | [0x31] = ABS_Y, | ||
346 | [0x33] = ABS_Z, /* L2 */ | ||
347 | }; | ||
348 | |||
349 | /* Buttons not physically available on the device, but still available | ||
350 | * in the reports are explicitly set to 0 for documentation purposes. | ||
351 | */ | ||
352 | static const unsigned int navigation_keymap[] = { | ||
353 | [0x01] = 0, /* Select */ | ||
354 | [0x02] = BTN_THUMBL, /* L3 */ | ||
355 | [0x03] = 0, /* R3 */ | ||
356 | [0x04] = 0, /* Start */ | ||
357 | [0x05] = BTN_DPAD_UP, /* Up */ | ||
358 | [0x06] = BTN_DPAD_RIGHT, /* Right */ | ||
359 | [0x07] = BTN_DPAD_DOWN, /* Down */ | ||
360 | [0x08] = BTN_DPAD_LEFT, /* Left */ | ||
361 | [0x09] = BTN_TL2, /* L2 */ | ||
362 | [0x0a] = 0, /* R2 */ | ||
363 | [0x0b] = BTN_TL, /* L1 */ | ||
364 | [0x0c] = 0, /* R1 */ | ||
365 | [0x0d] = BTN_NORTH, /* Triangle */ | ||
366 | [0x0e] = BTN_EAST, /* Circle */ | ||
367 | [0x0f] = BTN_SOUTH, /* Cross */ | ||
368 | [0x10] = BTN_WEST, /* Square */ | ||
369 | [0x11] = BTN_MODE, /* PS */ | ||
370 | }; | ||
371 | |||
372 | static const unsigned int sixaxis_absmap[] = { | ||
373 | [0x30] = ABS_X, | ||
374 | [0x31] = ABS_Y, | ||
375 | [0x32] = ABS_RX, /* right stick X */ | ||
376 | [0x35] = ABS_RY, /* right stick Y */ | ||
377 | }; | ||
378 | |||
379 | static const unsigned int sixaxis_keymap[] = { | ||
380 | [0x01] = BTN_SELECT, /* Select */ | ||
381 | [0x02] = BTN_THUMBL, /* L3 */ | ||
382 | [0x03] = BTN_THUMBR, /* R3 */ | ||
383 | [0x04] = BTN_START, /* Start */ | ||
384 | [0x05] = BTN_DPAD_UP, /* Up */ | ||
385 | [0x06] = BTN_DPAD_RIGHT, /* Right */ | ||
386 | [0x07] = BTN_DPAD_DOWN, /* Down */ | ||
387 | [0x08] = BTN_DPAD_LEFT, /* Left */ | ||
388 | [0x09] = BTN_TL2, /* L2 */ | ||
389 | [0x0a] = BTN_TR2, /* R2 */ | ||
390 | [0x0b] = BTN_TL, /* L1 */ | ||
391 | [0x0c] = BTN_TR, /* R1 */ | ||
392 | [0x0d] = BTN_NORTH, /* Triangle */ | ||
393 | [0x0e] = BTN_EAST, /* Circle */ | ||
394 | [0x0f] = BTN_SOUTH, /* Cross */ | ||
395 | [0x10] = BTN_WEST, /* Square */ | ||
396 | [0x11] = BTN_MODE, /* PS */ | ||
397 | }; | ||
398 | |||
980 | static const unsigned int ds4_absmap[] = { | 399 | static const unsigned int ds4_absmap[] = { |
981 | [0x30] = ABS_X, | 400 | [0x30] = ABS_X, |
982 | [0x31] = ABS_Y, | 401 | [0x31] = ABS_Y, |
@@ -1002,6 +421,10 @@ static const unsigned int ds4_keymap[] = { | |||
1002 | [0xd] = BTN_MODE, /* PS */ | 421 | [0xd] = BTN_MODE, /* PS */ |
1003 | }; | 422 | }; |
1004 | 423 | ||
424 | static const struct {int x; int y; } ds4_hat_mapping[] = { | ||
425 | {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, | ||
426 | {0, 0} | ||
427 | }; | ||
1005 | 428 | ||
1006 | static enum power_supply_property sony_battery_props[] = { | 429 | static enum power_supply_property sony_battery_props[] = { |
1007 | POWER_SUPPLY_PROP_PRESENT, | 430 | POWER_SUPPLY_PROP_PRESENT, |
@@ -1048,6 +471,7 @@ struct motion_output_report_02 { | |||
1048 | }; | 471 | }; |
1049 | 472 | ||
1050 | #define DS4_FEATURE_REPORT_0x02_SIZE 37 | 473 | #define DS4_FEATURE_REPORT_0x02_SIZE 37 |
474 | #define DS4_FEATURE_REPORT_0x05_SIZE 41 | ||
1051 | #define DS4_FEATURE_REPORT_0x81_SIZE 7 | 475 | #define DS4_FEATURE_REPORT_0x81_SIZE 7 |
1052 | #define DS4_INPUT_REPORT_0x11_SIZE 78 | 476 | #define DS4_INPUT_REPORT_0x11_SIZE 78 |
1053 | #define DS4_OUTPUT_REPORT_0x05_SIZE 32 | 477 | #define DS4_OUTPUT_REPORT_0x05_SIZE 32 |
@@ -1059,23 +483,62 @@ struct motion_output_report_02 { | |||
1059 | /* Offsets relative to USB input report (0x1). Bluetooth (0x11) requires an | 483 | /* Offsets relative to USB input report (0x1). Bluetooth (0x11) requires an |
1060 | * additional +2. | 484 | * additional +2. |
1061 | */ | 485 | */ |
486 | #define DS4_INPUT_REPORT_AXIS_OFFSET 1 | ||
1062 | #define DS4_INPUT_REPORT_BUTTON_OFFSET 5 | 487 | #define DS4_INPUT_REPORT_BUTTON_OFFSET 5 |
488 | #define DS4_INPUT_REPORT_TIMESTAMP_OFFSET 10 | ||
489 | #define DS4_INPUT_REPORT_GYRO_X_OFFSET 13 | ||
1063 | #define DS4_INPUT_REPORT_BATTERY_OFFSET 30 | 490 | #define DS4_INPUT_REPORT_BATTERY_OFFSET 30 |
1064 | #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33 | 491 | #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33 |
1065 | 492 | ||
493 | #define SENSOR_SUFFIX " Motion Sensors" | ||
1066 | #define DS4_TOUCHPAD_SUFFIX " Touchpad" | 494 | #define DS4_TOUCHPAD_SUFFIX " Touchpad" |
1067 | 495 | ||
496 | /* Default to 4ms poll interval, which is same as USB (not adjustable). */ | ||
497 | #define DS4_BT_DEFAULT_POLL_INTERVAL_MS 4 | ||
498 | #define DS4_BT_MAX_POLL_INTERVAL_MS 62 | ||
499 | #define DS4_GYRO_RES_PER_DEG_S 1024 | ||
500 | #define DS4_ACC_RES_PER_G 8192 | ||
501 | |||
502 | #define SIXAXIS_INPUT_REPORT_ACC_X_OFFSET 41 | ||
503 | #define SIXAXIS_ACC_RES_PER_G 113 | ||
504 | |||
1068 | static DEFINE_SPINLOCK(sony_dev_list_lock); | 505 | static DEFINE_SPINLOCK(sony_dev_list_lock); |
1069 | static LIST_HEAD(sony_device_list); | 506 | static LIST_HEAD(sony_device_list); |
1070 | static DEFINE_IDA(sony_device_id_allocator); | 507 | static DEFINE_IDA(sony_device_id_allocator); |
1071 | 508 | ||
509 | /* Used for calibration of DS4 accelerometer and gyro. */ | ||
510 | struct ds4_calibration_data { | ||
511 | int abs_code; | ||
512 | short bias; | ||
513 | /* Calibration requires scaling against a sensitivity value, which is a | ||
514 | * float. Store sensitivity as a fraction to limit floating point | ||
515 | * calculations until final calibration. | ||
516 | */ | ||
517 | int sens_numer; | ||
518 | int sens_denom; | ||
519 | }; | ||
520 | |||
521 | enum ds4_dongle_state { | ||
522 | DONGLE_DISCONNECTED, | ||
523 | DONGLE_CALIBRATING, | ||
524 | DONGLE_CONNECTED, | ||
525 | DONGLE_DISABLED | ||
526 | }; | ||
527 | |||
528 | enum sony_worker { | ||
529 | SONY_WORKER_STATE, | ||
530 | SONY_WORKER_HOTPLUG | ||
531 | }; | ||
532 | |||
1072 | struct sony_sc { | 533 | struct sony_sc { |
1073 | spinlock_t lock; | 534 | spinlock_t lock; |
1074 | struct list_head list_node; | 535 | struct list_head list_node; |
1075 | struct hid_device *hdev; | 536 | struct hid_device *hdev; |
1076 | struct input_dev *touchpad; | 537 | struct input_dev *touchpad; |
538 | struct input_dev *sensor_dev; | ||
1077 | struct led_classdev *leds[MAX_LEDS]; | 539 | struct led_classdev *leds[MAX_LEDS]; |
1078 | unsigned long quirks; | 540 | unsigned long quirks; |
541 | struct work_struct hotplug_worker; | ||
1079 | struct work_struct state_worker; | 542 | struct work_struct state_worker; |
1080 | void (*send_output_report)(struct sony_sc *); | 543 | void (*send_output_report)(struct sony_sc *); |
1081 | struct power_supply *battery; | 544 | struct power_supply *battery; |
@@ -1089,46 +552,87 @@ struct sony_sc { | |||
1089 | #endif | 552 | #endif |
1090 | 553 | ||
1091 | u8 mac_address[6]; | 554 | u8 mac_address[6]; |
1092 | u8 worker_initialized; | 555 | u8 hotplug_worker_initialized; |
556 | u8 state_worker_initialized; | ||
1093 | u8 defer_initialization; | 557 | u8 defer_initialization; |
1094 | u8 cable_state; | 558 | u8 cable_state; |
1095 | u8 battery_charging; | 559 | u8 battery_charging; |
1096 | u8 battery_capacity; | 560 | u8 battery_capacity; |
1097 | u8 led_state[MAX_LEDS]; | 561 | u8 led_state[MAX_LEDS]; |
1098 | u8 resume_led_state[MAX_LEDS]; | ||
1099 | u8 led_delay_on[MAX_LEDS]; | 562 | u8 led_delay_on[MAX_LEDS]; |
1100 | u8 led_delay_off[MAX_LEDS]; | 563 | u8 led_delay_off[MAX_LEDS]; |
1101 | u8 led_count; | 564 | u8 led_count; |
1102 | bool ds4_dongle_connected; | 565 | |
566 | bool timestamp_initialized; | ||
567 | u16 prev_timestamp; | ||
568 | unsigned int timestamp_us; | ||
569 | |||
570 | u8 ds4_bt_poll_interval; | ||
571 | enum ds4_dongle_state ds4_dongle_state; | ||
572 | /* DS4 calibration data */ | ||
573 | struct ds4_calibration_data ds4_calib_data[6]; | ||
1103 | }; | 574 | }; |
1104 | 575 | ||
1105 | static void sony_set_leds(struct sony_sc *sc); | 576 | static void sony_set_leds(struct sony_sc *sc); |
1106 | 577 | ||
1107 | static inline void sony_schedule_work(struct sony_sc *sc) | 578 | static inline void sony_schedule_work(struct sony_sc *sc, |
579 | enum sony_worker which) | ||
1108 | { | 580 | { |
1109 | if (!sc->defer_initialization) | 581 | switch (which) { |
1110 | schedule_work(&sc->state_worker); | 582 | case SONY_WORKER_STATE: |
583 | if (!sc->defer_initialization) | ||
584 | schedule_work(&sc->state_worker); | ||
585 | break; | ||
586 | case SONY_WORKER_HOTPLUG: | ||
587 | if (sc->hotplug_worker_initialized) | ||
588 | schedule_work(&sc->hotplug_worker); | ||
589 | break; | ||
590 | } | ||
1111 | } | 591 | } |
1112 | 592 | ||
1113 | static u8 *sixaxis_fixup(struct hid_device *hdev, u8 *rdesc, | 593 | static ssize_t ds4_show_poll_interval(struct device *dev, |
1114 | unsigned int *rsize) | 594 | struct device_attribute |
595 | *attr, char *buf) | ||
1115 | { | 596 | { |
1116 | *rsize = sizeof(sixaxis_rdesc); | 597 | struct hid_device *hdev = to_hid_device(dev); |
1117 | return sixaxis_rdesc; | 598 | struct sony_sc *sc = hid_get_drvdata(hdev); |
599 | |||
600 | return snprintf(buf, PAGE_SIZE, "%i\n", sc->ds4_bt_poll_interval); | ||
1118 | } | 601 | } |
1119 | 602 | ||
1120 | static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc, | 603 | static ssize_t ds4_store_poll_interval(struct device *dev, |
1121 | unsigned int *rsize) | 604 | struct device_attribute *attr, |
605 | const char *buf, size_t count) | ||
1122 | { | 606 | { |
1123 | *rsize = sizeof(motion_rdesc); | 607 | struct hid_device *hdev = to_hid_device(dev); |
1124 | return motion_rdesc; | 608 | struct sony_sc *sc = hid_get_drvdata(hdev); |
609 | unsigned long flags; | ||
610 | u8 interval; | ||
611 | |||
612 | if (kstrtou8(buf, 0, &interval)) | ||
613 | return -EINVAL; | ||
614 | |||
615 | if (interval > DS4_BT_MAX_POLL_INTERVAL_MS) | ||
616 | return -EINVAL; | ||
617 | |||
618 | spin_lock_irqsave(&sc->lock, flags); | ||
619 | sc->ds4_bt_poll_interval = interval; | ||
620 | spin_unlock_irqrestore(&sc->lock, flags); | ||
621 | |||
622 | sony_schedule_work(sc, SONY_WORKER_STATE); | ||
623 | |||
624 | return count; | ||
1125 | } | 625 | } |
1126 | 626 | ||
1127 | static u8 *navigation_fixup(struct hid_device *hdev, u8 *rdesc, | 627 | static DEVICE_ATTR(bt_poll_interval, 0644, ds4_show_poll_interval, |
628 | ds4_store_poll_interval); | ||
629 | |||
630 | |||
631 | static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc, | ||
1128 | unsigned int *rsize) | 632 | unsigned int *rsize) |
1129 | { | 633 | { |
1130 | *rsize = sizeof(navigation_rdesc); | 634 | *rsize = sizeof(motion_rdesc); |
1131 | return navigation_rdesc; | 635 | return motion_rdesc; |
1132 | } | 636 | } |
1133 | 637 | ||
1134 | static u8 *ps3remote_fixup(struct hid_device *hdev, u8 *rdesc, | 638 | static u8 *ps3remote_fixup(struct hid_device *hdev, u8 *rdesc, |
@@ -1172,6 +676,102 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
1172 | return 1; | 676 | return 1; |
1173 | } | 677 | } |
1174 | 678 | ||
679 | static int navigation_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
680 | struct hid_field *field, struct hid_usage *usage, | ||
681 | unsigned long **bit, int *max) | ||
682 | { | ||
683 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { | ||
684 | unsigned int key = usage->hid & HID_USAGE; | ||
685 | |||
686 | if (key >= ARRAY_SIZE(sixaxis_keymap)) | ||
687 | return -1; | ||
688 | |||
689 | key = navigation_keymap[key]; | ||
690 | if (!key) | ||
691 | return -1; | ||
692 | |||
693 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); | ||
694 | return 1; | ||
695 | } else if (usage->hid == HID_GD_POINTER) { | ||
696 | /* See comment in sixaxis_mapping, basically the L2 (and R2) | ||
697 | * triggers are reported through GD Pointer. | ||
698 | * In addition we ignore any analog button 'axes' and only | ||
699 | * support digital buttons. | ||
700 | */ | ||
701 | switch (usage->usage_index) { | ||
702 | case 8: /* L2 */ | ||
703 | usage->hid = HID_GD_Z; | ||
704 | break; | ||
705 | default: | ||
706 | return -1; | ||
707 | } | ||
708 | |||
709 | hid_map_usage_clear(hi, usage, bit, max, EV_ABS, usage->hid & 0xf); | ||
710 | return 1; | ||
711 | } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { | ||
712 | unsigned int abs = usage->hid & HID_USAGE; | ||
713 | |||
714 | if (abs >= ARRAY_SIZE(navigation_absmap)) | ||
715 | return -1; | ||
716 | |||
717 | abs = navigation_absmap[abs]; | ||
718 | |||
719 | hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs); | ||
720 | return 1; | ||
721 | } | ||
722 | |||
723 | return -1; | ||
724 | } | ||
725 | |||
726 | |||
727 | static int sixaxis_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
728 | struct hid_field *field, struct hid_usage *usage, | ||
729 | unsigned long **bit, int *max) | ||
730 | { | ||
731 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { | ||
732 | unsigned int key = usage->hid & HID_USAGE; | ||
733 | |||
734 | if (key >= ARRAY_SIZE(sixaxis_keymap)) | ||
735 | return -1; | ||
736 | |||
737 | key = sixaxis_keymap[key]; | ||
738 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); | ||
739 | return 1; | ||
740 | } else if (usage->hid == HID_GD_POINTER) { | ||
741 | /* The DS3 provides analog values for most buttons and even | ||
742 | * for HAT axes through GD Pointer. L2 and R2 are reported | ||
743 | * among these as well instead of as GD Z / RZ. Remap L2 | ||
744 | * and R2 and ignore other analog 'button axes' as there is | ||
745 | * no good way for reporting them. | ||
746 | */ | ||
747 | switch (usage->usage_index) { | ||
748 | case 8: /* L2 */ | ||
749 | usage->hid = HID_GD_Z; | ||
750 | break; | ||
751 | case 9: /* R2 */ | ||
752 | usage->hid = HID_GD_RZ; | ||
753 | break; | ||
754 | default: | ||
755 | return -1; | ||
756 | } | ||
757 | |||
758 | hid_map_usage_clear(hi, usage, bit, max, EV_ABS, usage->hid & 0xf); | ||
759 | return 1; | ||
760 | } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { | ||
761 | unsigned int abs = usage->hid & HID_USAGE; | ||
762 | |||
763 | if (abs >= ARRAY_SIZE(sixaxis_absmap)) | ||
764 | return -1; | ||
765 | |||
766 | abs = sixaxis_absmap[abs]; | ||
767 | |||
768 | hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs); | ||
769 | return 1; | ||
770 | } | ||
771 | |||
772 | return -1; | ||
773 | } | ||
774 | |||
1175 | static int ds4_mapping(struct hid_device *hdev, struct hid_input *hi, | 775 | static int ds4_mapping(struct hid_device *hdev, struct hid_input *hi, |
1176 | struct hid_field *field, struct hid_usage *usage, | 776 | struct hid_field *field, struct hid_usage *usage, |
1177 | unsigned long **bit, int *max) | 777 | unsigned long **bit, int *max) |
@@ -1227,30 +827,9 @@ static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc, | |||
1227 | rdesc[55] = 0x06; | 827 | rdesc[55] = 0x06; |
1228 | } | 828 | } |
1229 | 829 | ||
1230 | /* | ||
1231 | * The default Dualshock 4 USB descriptor doesn't assign | ||
1232 | * the gyroscope values to corresponding axes so we need a | ||
1233 | * modified one. | ||
1234 | */ | ||
1235 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { | ||
1236 | hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); | ||
1237 | rdesc = dualshock4_usb_rdesc; | ||
1238 | *rsize = sizeof(dualshock4_usb_rdesc); | ||
1239 | } else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { | ||
1240 | hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); | ||
1241 | rdesc = dualshock4_bt_rdesc; | ||
1242 | *rsize = sizeof(dualshock4_bt_rdesc); | ||
1243 | } | ||
1244 | |||
1245 | if (sc->quirks & SIXAXIS_CONTROLLER) | ||
1246 | return sixaxis_fixup(hdev, rdesc, rsize); | ||
1247 | |||
1248 | if (sc->quirks & MOTION_CONTROLLER) | 830 | if (sc->quirks & MOTION_CONTROLLER) |
1249 | return motion_fixup(hdev, rdesc, rsize); | 831 | return motion_fixup(hdev, rdesc, rsize); |
1250 | 832 | ||
1251 | if (sc->quirks & NAVIGATION_CONTROLLER) | ||
1252 | return navigation_fixup(hdev, rdesc, rsize); | ||
1253 | |||
1254 | if (sc->quirks & PS3REMOTE) | 833 | if (sc->quirks & PS3REMOTE) |
1255 | return ps3remote_fixup(hdev, rdesc, rsize); | 834 | return ps3remote_fixup(hdev, rdesc, rsize); |
1256 | 835 | ||
@@ -1288,22 +867,132 @@ static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size) | |||
1288 | sc->battery_capacity = battery_capacity; | 867 | sc->battery_capacity = battery_capacity; |
1289 | sc->battery_charging = battery_charging; | 868 | sc->battery_charging = battery_charging; |
1290 | spin_unlock_irqrestore(&sc->lock, flags); | 869 | spin_unlock_irqrestore(&sc->lock, flags); |
870 | |||
871 | if (sc->quirks & SIXAXIS_CONTROLLER) { | ||
872 | int val; | ||
873 | |||
874 | offset = SIXAXIS_INPUT_REPORT_ACC_X_OFFSET; | ||
875 | val = ((rd[offset+1] << 8) | rd[offset]) - 511; | ||
876 | input_report_abs(sc->sensor_dev, ABS_X, val); | ||
877 | |||
878 | /* Y and Z are swapped and inversed */ | ||
879 | val = 511 - ((rd[offset+5] << 8) | rd[offset+4]); | ||
880 | input_report_abs(sc->sensor_dev, ABS_Y, val); | ||
881 | |||
882 | val = 511 - ((rd[offset+3] << 8) | rd[offset+2]); | ||
883 | input_report_abs(sc->sensor_dev, ABS_Z, val); | ||
884 | |||
885 | input_sync(sc->sensor_dev); | ||
886 | } | ||
1291 | } | 887 | } |
1292 | 888 | ||
1293 | static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) | 889 | static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) |
1294 | { | 890 | { |
891 | struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, | ||
892 | struct hid_input, list); | ||
893 | struct input_dev *input_dev = hidinput->input; | ||
1295 | unsigned long flags; | 894 | unsigned long flags; |
1296 | int n, m, offset, num_touch_data, max_touch_data; | 895 | int n, m, offset, num_touch_data, max_touch_data; |
1297 | u8 cable_state, battery_capacity, battery_charging; | 896 | u8 cable_state, battery_capacity, battery_charging; |
897 | u16 timestamp; | ||
1298 | 898 | ||
1299 | /* When using Bluetooth the header is 2 bytes longer, so skip these. */ | 899 | /* When using Bluetooth the header is 2 bytes longer, so skip these. */ |
1300 | int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 0 : 2; | 900 | int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 2 : 0; |
1301 | 901 | ||
1302 | /* Second bit of third button byte is for the touchpad button. */ | 902 | /* Second bit of third button byte is for the touchpad button. */ |
1303 | offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET; | 903 | offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET; |
1304 | input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2); | 904 | input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2); |
1305 | 905 | ||
1306 | /* | 906 | /* |
907 | * The default behavior of the Dualshock 4 is to send reports using | ||
908 | * report type 1 when running over Bluetooth. However, when feature | ||
909 | * report 2 is requested during the controller initialization it starts | ||
910 | * sending input reports in report 17. Since report 17 is undefined | ||
911 | * in the default HID descriptor, the HID layer won't generate events. | ||
912 | * While it is possible (and this was done before) to fixup the HID | ||
913 | * descriptor to add this mapping, it was better to do this manually. | ||
914 | * The reason is there were various pieces software both open and closed | ||
915 | * source, relying on the descriptors to be the same across various | ||
916 | * operating systems. If the descriptors wouldn't match some | ||
917 | * applications e.g. games on Wine would not be able to function due | ||
918 | * to different descriptors, which such applications are not parsing. | ||
919 | */ | ||
920 | if (rd[0] == 17) { | ||
921 | int value; | ||
922 | |||
923 | offset = data_offset + DS4_INPUT_REPORT_AXIS_OFFSET; | ||
924 | input_report_abs(input_dev, ABS_X, rd[offset]); | ||
925 | input_report_abs(input_dev, ABS_Y, rd[offset+1]); | ||
926 | input_report_abs(input_dev, ABS_RX, rd[offset+2]); | ||
927 | input_report_abs(input_dev, ABS_RY, rd[offset+3]); | ||
928 | |||
929 | value = rd[offset+4] & 0xf; | ||
930 | if (value > 7) | ||
931 | value = 8; /* Center 0, 0 */ | ||
932 | input_report_abs(input_dev, ABS_HAT0X, ds4_hat_mapping[value].x); | ||
933 | input_report_abs(input_dev, ABS_HAT0Y, ds4_hat_mapping[value].y); | ||
934 | |||
935 | input_report_key(input_dev, BTN_WEST, rd[offset+4] & 0x10); | ||
936 | input_report_key(input_dev, BTN_SOUTH, rd[offset+4] & 0x20); | ||
937 | input_report_key(input_dev, BTN_EAST, rd[offset+4] & 0x40); | ||
938 | input_report_key(input_dev, BTN_NORTH, rd[offset+4] & 0x80); | ||
939 | |||
940 | input_report_key(input_dev, BTN_TL, rd[offset+5] & 0x1); | ||
941 | input_report_key(input_dev, BTN_TR, rd[offset+5] & 0x2); | ||
942 | input_report_key(input_dev, BTN_TL2, rd[offset+5] & 0x4); | ||
943 | input_report_key(input_dev, BTN_TR2, rd[offset+5] & 0x8); | ||
944 | input_report_key(input_dev, BTN_SELECT, rd[offset+5] & 0x10); | ||
945 | input_report_key(input_dev, BTN_START, rd[offset+5] & 0x20); | ||
946 | input_report_key(input_dev, BTN_THUMBL, rd[offset+5] & 0x40); | ||
947 | input_report_key(input_dev, BTN_THUMBR, rd[offset+5] & 0x80); | ||
948 | |||
949 | input_report_key(input_dev, BTN_MODE, rd[offset+6] & 0x1); | ||
950 | |||
951 | input_report_abs(input_dev, ABS_Z, rd[offset+7]); | ||
952 | input_report_abs(input_dev, ABS_RZ, rd[offset+8]); | ||
953 | |||
954 | input_sync(input_dev); | ||
955 | } | ||
956 | |||
957 | /* Convert timestamp (in 5.33us unit) to timestamp_us */ | ||
958 | offset = data_offset + DS4_INPUT_REPORT_TIMESTAMP_OFFSET; | ||
959 | timestamp = get_unaligned_le16(&rd[offset]); | ||
960 | if (!sc->timestamp_initialized) { | ||
961 | sc->timestamp_us = ((unsigned int)timestamp * 16) / 3; | ||
962 | sc->timestamp_initialized = true; | ||
963 | } else { | ||
964 | u16 delta; | ||
965 | |||
966 | if (sc->prev_timestamp > timestamp) | ||
967 | delta = (U16_MAX - sc->prev_timestamp + timestamp + 1); | ||
968 | else | ||
969 | delta = timestamp - sc->prev_timestamp; | ||
970 | sc->timestamp_us += (delta * 16) / 3; | ||
971 | } | ||
972 | sc->prev_timestamp = timestamp; | ||
973 | input_event(sc->sensor_dev, EV_MSC, MSC_TIMESTAMP, sc->timestamp_us); | ||
974 | |||
975 | offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET; | ||
976 | for (n = 0; n < 6; n++) { | ||
977 | /* Store data in int for more precision during mult_frac. */ | ||
978 | int raw_data = (short)((rd[offset+1] << 8) | rd[offset]); | ||
979 | struct ds4_calibration_data *calib = &sc->ds4_calib_data[n]; | ||
980 | |||
981 | /* High precision is needed during calibration, but the | ||
982 | * calibrated values are within 32-bit. | ||
983 | * Note: we swap numerator 'x' and 'numer' in mult_frac for | ||
984 | * precision reasons so we don't need 64-bit. | ||
985 | */ | ||
986 | int calib_data = mult_frac(calib->sens_numer, | ||
987 | raw_data - calib->bias, | ||
988 | calib->sens_denom); | ||
989 | |||
990 | input_report_abs(sc->sensor_dev, calib->abs_code, calib_data); | ||
991 | offset += 2; | ||
992 | } | ||
993 | input_sync(sc->sensor_dev); | ||
994 | |||
995 | /* | ||
1307 | * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level | 996 | * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level |
1308 | * and the 5th bit contains the USB cable state. | 997 | * and the 5th bit contains the USB cable state. |
1309 | */ | 998 | */ |
@@ -1341,7 +1030,7 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) | |||
1341 | * Trackpad data starts 2 bytes later (e.g. 35 for USB). | 1030 | * Trackpad data starts 2 bytes later (e.g. 35 for USB). |
1342 | */ | 1031 | */ |
1343 | offset = data_offset + DS4_INPUT_REPORT_TOUCHPAD_OFFSET; | 1032 | offset = data_offset + DS4_INPUT_REPORT_TOUCHPAD_OFFSET; |
1344 | max_touch_data = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 3 : 4; | 1033 | max_touch_data = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 4 : 3; |
1345 | if (rd[offset] > 0 && rd[offset] <= max_touch_data) | 1034 | if (rd[offset] > 0 && rd[offset] <= max_touch_data) |
1346 | num_touch_data = rd[offset]; | 1035 | num_touch_data = rd[offset]; |
1347 | else | 1036 | else |
@@ -1415,47 +1104,79 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
1415 | } else if ((sc->quirks & NAVIGATION_CONTROLLER) && rd[0] == 0x01 && | 1104 | } else if ((sc->quirks & NAVIGATION_CONTROLLER) && rd[0] == 0x01 && |
1416 | size == 49) { | 1105 | size == 49) { |
1417 | sixaxis_parse_report(sc, rd, size); | 1106 | sixaxis_parse_report(sc, rd, size); |
1418 | } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && | 1107 | } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && |
1419 | size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) | 1108 | size == 64) { |
1420 | && rd[0] == 0x11 && size == 78)) { | 1109 | dualshock4_parse_report(sc, rd, size); |
1421 | if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { | 1110 | } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && rd[0] == 0x11 && |
1422 | /* CRC check */ | 1111 | size == 78)) { |
1423 | u8 bthdr = 0xA1; | 1112 | /* CRC check */ |
1424 | u32 crc; | 1113 | u8 bthdr = 0xA1; |
1425 | u32 report_crc; | 1114 | u32 crc; |
1115 | u32 report_crc; | ||
1426 | 1116 | ||
1427 | crc = crc32_le(0xFFFFFFFF, &bthdr, 1); | 1117 | crc = crc32_le(0xFFFFFFFF, &bthdr, 1); |
1428 | crc = ~crc32_le(crc, rd, DS4_INPUT_REPORT_0x11_SIZE-4); | 1118 | crc = ~crc32_le(crc, rd, DS4_INPUT_REPORT_0x11_SIZE-4); |
1429 | report_crc = get_unaligned_le32(&rd[DS4_INPUT_REPORT_0x11_SIZE-4]); | 1119 | report_crc = get_unaligned_le32(&rd[DS4_INPUT_REPORT_0x11_SIZE-4]); |
1430 | if (crc != report_crc) { | 1120 | if (crc != report_crc) { |
1431 | hid_dbg(sc->hdev, "DualShock 4 input report's CRC check failed, received crc 0x%0x != 0x%0x\n", | 1121 | hid_dbg(sc->hdev, "DualShock 4 input report's CRC check failed, received crc 0x%0x != 0x%0x\n", |
1432 | report_crc, crc); | 1122 | report_crc, crc); |
1433 | return -EILSEQ; | 1123 | return -EILSEQ; |
1434 | } | ||
1435 | } | 1124 | } |
1436 | 1125 | ||
1126 | dualshock4_parse_report(sc, rd, size); | ||
1127 | } else if ((sc->quirks & DUALSHOCK4_DONGLE) && rd[0] == 0x01 && | ||
1128 | size == 64) { | ||
1129 | unsigned long flags; | ||
1130 | enum ds4_dongle_state dongle_state; | ||
1131 | |||
1437 | /* | 1132 | /* |
1438 | * In the case of a DS4 USB dongle, bit[2] of byte 31 indicates | 1133 | * In the case of a DS4 USB dongle, bit[2] of byte 31 indicates |
1439 | * if a DS4 is actually connected (indicated by '0'). | 1134 | * if a DS4 is actually connected (indicated by '0'). |
1440 | * For non-dongle, this bit is always 0 (connected). | 1135 | * For non-dongle, this bit is always 0 (connected). |
1441 | */ | 1136 | */ |
1442 | if (sc->hdev->vendor == USB_VENDOR_ID_SONY && | 1137 | bool connected = (rd[31] & 0x04) ? false : true; |
1443 | sc->hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) { | 1138 | |
1444 | bool connected = (rd[31] & 0x04) ? false : true; | 1139 | spin_lock_irqsave(&sc->lock, flags); |
1445 | 1140 | dongle_state = sc->ds4_dongle_state; | |
1446 | if (!sc->ds4_dongle_connected && connected) { | 1141 | spin_unlock_irqrestore(&sc->lock, flags); |
1447 | hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected\n"); | 1142 | |
1448 | sony_set_leds(sc); | 1143 | /* |
1449 | sc->ds4_dongle_connected = true; | 1144 | * The dongle always sends input reports even when no |
1450 | } else if (sc->ds4_dongle_connected && !connected) { | 1145 | * DS4 is attached. When a DS4 is connected, we need to |
1451 | hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected\n"); | 1146 | * obtain calibration data before we can use it. |
1452 | sc->ds4_dongle_connected = false; | 1147 | * The code below tracks dongle state and kicks of |
1453 | /* Return 0, so hidraw can get the report. */ | 1148 | * calibration when needed and only allows us to process |
1454 | return 0; | 1149 | * input if a DS4 is actually connected. |
1455 | } else if (!sc->ds4_dongle_connected) { | 1150 | */ |
1456 | /* Return 0, so hidraw can get the report. */ | 1151 | if (dongle_state == DONGLE_DISCONNECTED && connected) { |
1457 | return 0; | 1152 | hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected\n"); |
1458 | } | 1153 | sony_set_leds(sc); |
1154 | |||
1155 | spin_lock_irqsave(&sc->lock, flags); | ||
1156 | sc->ds4_dongle_state = DONGLE_CALIBRATING; | ||
1157 | spin_unlock_irqrestore(&sc->lock, flags); | ||
1158 | |||
1159 | sony_schedule_work(sc, SONY_WORKER_HOTPLUG); | ||
1160 | |||
1161 | /* Don't process the report since we don't have | ||
1162 | * calibration data, but let hidraw have it anyway. | ||
1163 | */ | ||
1164 | return 0; | ||
1165 | } else if ((dongle_state == DONGLE_CONNECTED || | ||
1166 | dongle_state == DONGLE_DISABLED) && !connected) { | ||
1167 | hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected\n"); | ||
1168 | |||
1169 | spin_lock_irqsave(&sc->lock, flags); | ||
1170 | sc->ds4_dongle_state = DONGLE_DISCONNECTED; | ||
1171 | spin_unlock_irqrestore(&sc->lock, flags); | ||
1172 | |||
1173 | /* Return 0, so hidraw can get the report. */ | ||
1174 | return 0; | ||
1175 | } else if (dongle_state == DONGLE_CALIBRATING || | ||
1176 | dongle_state == DONGLE_DISABLED || | ||
1177 | dongle_state == DONGLE_DISCONNECTED) { | ||
1178 | /* Return 0, so hidraw can get the report. */ | ||
1179 | return 0; | ||
1459 | } | 1180 | } |
1460 | 1181 | ||
1461 | dualshock4_parse_report(sc, rd, size); | 1182 | dualshock4_parse_report(sc, rd, size); |
@@ -1463,7 +1184,7 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
1463 | 1184 | ||
1464 | if (sc->defer_initialization) { | 1185 | if (sc->defer_initialization) { |
1465 | sc->defer_initialization = 0; | 1186 | sc->defer_initialization = 0; |
1466 | sony_schedule_work(sc); | 1187 | sony_schedule_work(sc, SONY_WORKER_STATE); |
1467 | } | 1188 | } |
1468 | 1189 | ||
1469 | return 0; | 1190 | return 0; |
@@ -1501,10 +1222,16 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
1501 | if (sc->quirks & PS3REMOTE) | 1222 | if (sc->quirks & PS3REMOTE) |
1502 | return ps3remote_mapping(hdev, hi, field, usage, bit, max); | 1223 | return ps3remote_mapping(hdev, hi, field, usage, bit, max); |
1503 | 1224 | ||
1225 | if (sc->quirks & NAVIGATION_CONTROLLER) | ||
1226 | return navigation_mapping(hdev, hi, field, usage, bit, max); | ||
1227 | |||
1228 | if (sc->quirks & SIXAXIS_CONTROLLER) | ||
1229 | return sixaxis_mapping(hdev, hi, field, usage, bit, max); | ||
1504 | 1230 | ||
1505 | if (sc->quirks & DUALSHOCK4_CONTROLLER) | 1231 | if (sc->quirks & DUALSHOCK4_CONTROLLER) |
1506 | return ds4_mapping(hdev, hi, field, usage, bit, max); | 1232 | return ds4_mapping(hdev, hi, field, usage, bit, max); |
1507 | 1233 | ||
1234 | |||
1508 | /* Let hid-core decide for the others */ | 1235 | /* Let hid-core decide for the others */ |
1509 | return 0; | 1236 | return 0; |
1510 | } | 1237 | } |
@@ -1541,7 +1268,7 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count, | |||
1541 | snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name); | 1268 | snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name); |
1542 | sc->touchpad->name = name; | 1269 | sc->touchpad->name = name; |
1543 | 1270 | ||
1544 | ret = input_mt_init_slots(sc->touchpad, touch_count, 0); | 1271 | ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER); |
1545 | if (ret < 0) | 1272 | if (ret < 0) |
1546 | goto err; | 1273 | goto err; |
1547 | 1274 | ||
@@ -1581,6 +1308,103 @@ static void sony_unregister_touchpad(struct sony_sc *sc) | |||
1581 | sc->touchpad = NULL; | 1308 | sc->touchpad = NULL; |
1582 | } | 1309 | } |
1583 | 1310 | ||
1311 | static int sony_register_sensors(struct sony_sc *sc) | ||
1312 | { | ||
1313 | size_t name_sz; | ||
1314 | char *name; | ||
1315 | int ret; | ||
1316 | int range; | ||
1317 | |||
1318 | sc->sensor_dev = input_allocate_device(); | ||
1319 | if (!sc->sensor_dev) | ||
1320 | return -ENOMEM; | ||
1321 | |||
1322 | input_set_drvdata(sc->sensor_dev, sc); | ||
1323 | sc->sensor_dev->dev.parent = &sc->hdev->dev; | ||
1324 | sc->sensor_dev->phys = sc->hdev->phys; | ||
1325 | sc->sensor_dev->uniq = sc->hdev->uniq; | ||
1326 | sc->sensor_dev->id.bustype = sc->hdev->bus; | ||
1327 | sc->sensor_dev->id.vendor = sc->hdev->vendor; | ||
1328 | sc->sensor_dev->id.product = sc->hdev->product; | ||
1329 | sc->sensor_dev->id.version = sc->hdev->version; | ||
1330 | |||
1331 | /* Append a suffix to the controller name as there are various | ||
1332 | * DS4 compatible non-Sony devices with different names. | ||
1333 | */ | ||
1334 | name_sz = strlen(sc->hdev->name) + sizeof(SENSOR_SUFFIX); | ||
1335 | name = kzalloc(name_sz, GFP_KERNEL); | ||
1336 | if (!name) { | ||
1337 | ret = -ENOMEM; | ||
1338 | goto err; | ||
1339 | } | ||
1340 | snprintf(name, name_sz, "%s" SENSOR_SUFFIX, sc->hdev->name); | ||
1341 | sc->sensor_dev->name = name; | ||
1342 | |||
1343 | if (sc->quirks & SIXAXIS_CONTROLLER) { | ||
1344 | /* For the DS3 we only support the accelerometer, which works | ||
1345 | * quite well even without calibration. The device also has | ||
1346 | * a 1-axis gyro, but it is very difficult to manage from within | ||
1347 | * the driver even to get data, the sensor is inaccurate and | ||
1348 | * the behavior is very different between hardware revisions. | ||
1349 | */ | ||
1350 | input_set_abs_params(sc->sensor_dev, ABS_X, -512, 511, 4, 0); | ||
1351 | input_set_abs_params(sc->sensor_dev, ABS_Y, -512, 511, 4, 0); | ||
1352 | input_set_abs_params(sc->sensor_dev, ABS_Z, -512, 511, 4, 0); | ||
1353 | input_abs_set_res(sc->sensor_dev, ABS_X, SIXAXIS_ACC_RES_PER_G); | ||
1354 | input_abs_set_res(sc->sensor_dev, ABS_Y, SIXAXIS_ACC_RES_PER_G); | ||
1355 | input_abs_set_res(sc->sensor_dev, ABS_Z, SIXAXIS_ACC_RES_PER_G); | ||
1356 | } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { | ||
1357 | range = DS4_ACC_RES_PER_G*4; | ||
1358 | input_set_abs_params(sc->sensor_dev, ABS_X, -range, range, 16, 0); | ||
1359 | input_set_abs_params(sc->sensor_dev, ABS_Y, -range, range, 16, 0); | ||
1360 | input_set_abs_params(sc->sensor_dev, ABS_Z, -range, range, 16, 0); | ||
1361 | input_abs_set_res(sc->sensor_dev, ABS_X, DS4_ACC_RES_PER_G); | ||
1362 | input_abs_set_res(sc->sensor_dev, ABS_Y, DS4_ACC_RES_PER_G); | ||
1363 | input_abs_set_res(sc->sensor_dev, ABS_Z, DS4_ACC_RES_PER_G); | ||
1364 | |||
1365 | range = DS4_GYRO_RES_PER_DEG_S*2048; | ||
1366 | input_set_abs_params(sc->sensor_dev, ABS_RX, -range, range, 16, 0); | ||
1367 | input_set_abs_params(sc->sensor_dev, ABS_RY, -range, range, 16, 0); | ||
1368 | input_set_abs_params(sc->sensor_dev, ABS_RZ, -range, range, 16, 0); | ||
1369 | input_abs_set_res(sc->sensor_dev, ABS_RX, DS4_GYRO_RES_PER_DEG_S); | ||
1370 | input_abs_set_res(sc->sensor_dev, ABS_RY, DS4_GYRO_RES_PER_DEG_S); | ||
1371 | input_abs_set_res(sc->sensor_dev, ABS_RZ, DS4_GYRO_RES_PER_DEG_S); | ||
1372 | |||
1373 | __set_bit(EV_MSC, sc->sensor_dev->evbit); | ||
1374 | __set_bit(MSC_TIMESTAMP, sc->sensor_dev->mscbit); | ||
1375 | } | ||
1376 | |||
1377 | __set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit); | ||
1378 | |||
1379 | ret = input_register_device(sc->sensor_dev); | ||
1380 | if (ret < 0) | ||
1381 | goto err; | ||
1382 | |||
1383 | return 0; | ||
1384 | |||
1385 | err: | ||
1386 | kfree(sc->sensor_dev->name); | ||
1387 | sc->sensor_dev->name = NULL; | ||
1388 | |||
1389 | input_free_device(sc->sensor_dev); | ||
1390 | sc->sensor_dev = NULL; | ||
1391 | |||
1392 | return ret; | ||
1393 | } | ||
1394 | |||
1395 | static void sony_unregister_sensors(struct sony_sc *sc) | ||
1396 | { | ||
1397 | if (!sc->sensor_dev) | ||
1398 | return; | ||
1399 | |||
1400 | kfree(sc->sensor_dev->name); | ||
1401 | sc->sensor_dev->name = NULL; | ||
1402 | |||
1403 | input_unregister_device(sc->sensor_dev); | ||
1404 | sc->sensor_dev = NULL; | ||
1405 | } | ||
1406 | |||
1407 | |||
1584 | /* | 1408 | /* |
1585 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | 1409 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller |
1586 | * to "operational". Without this, the ps3 controller will not report any | 1410 | * to "operational". Without this, the ps3 controller will not report any |
@@ -1646,26 +1470,176 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev) | |||
1646 | } | 1470 | } |
1647 | 1471 | ||
1648 | /* | 1472 | /* |
1649 | * Requesting feature report 0x02 in Bluetooth mode changes the state of the | 1473 | * Request DS4 calibration data for the motion sensors. |
1650 | * controller so that it sends full input reports of type 0x11. | 1474 | * For Bluetooth this also affects the operating mode (see below). |
1651 | */ | 1475 | */ |
1652 | static int dualshock4_set_operational_bt(struct hid_device *hdev) | 1476 | static int dualshock4_get_calibration_data(struct sony_sc *sc) |
1653 | { | 1477 | { |
1654 | u8 *buf; | 1478 | u8 *buf; |
1655 | int ret; | 1479 | int ret; |
1480 | short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus; | ||
1481 | short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus; | ||
1482 | short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus; | ||
1483 | short gyro_speed_plus, gyro_speed_minus; | ||
1484 | short acc_x_plus, acc_x_minus; | ||
1485 | short acc_y_plus, acc_y_minus; | ||
1486 | short acc_z_plus, acc_z_minus; | ||
1487 | int speed_2x; | ||
1488 | int range_2g; | ||
1489 | |||
1490 | /* For Bluetooth we use a different request, which supports CRC. | ||
1491 | * Note: in Bluetooth mode feature report 0x02 also changes the state | ||
1492 | * of the controller, so that it sends input reports of type 0x11. | ||
1493 | */ | ||
1494 | if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { | ||
1495 | buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL); | ||
1496 | if (!buf) | ||
1497 | return -ENOMEM; | ||
1656 | 1498 | ||
1657 | buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL); | 1499 | ret = hid_hw_raw_request(sc->hdev, 0x02, buf, |
1658 | if (!buf) | 1500 | DS4_FEATURE_REPORT_0x02_SIZE, |
1659 | return -ENOMEM; | 1501 | HID_FEATURE_REPORT, |
1502 | HID_REQ_GET_REPORT); | ||
1503 | if (ret < 0) | ||
1504 | goto err_stop; | ||
1505 | } else { | ||
1506 | u8 bthdr = 0xA3; | ||
1507 | u32 crc; | ||
1508 | u32 report_crc; | ||
1509 | int retries; | ||
1510 | |||
1511 | buf = kmalloc(DS4_FEATURE_REPORT_0x05_SIZE, GFP_KERNEL); | ||
1512 | if (!buf) | ||
1513 | return -ENOMEM; | ||
1660 | 1514 | ||
1661 | ret = hid_hw_raw_request(hdev, 0x02, buf, DS4_FEATURE_REPORT_0x02_SIZE, | 1515 | for (retries = 0; retries < 3; retries++) { |
1662 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); | 1516 | ret = hid_hw_raw_request(sc->hdev, 0x05, buf, |
1517 | DS4_FEATURE_REPORT_0x05_SIZE, | ||
1518 | HID_FEATURE_REPORT, | ||
1519 | HID_REQ_GET_REPORT); | ||
1520 | if (ret < 0) | ||
1521 | goto err_stop; | ||
1663 | 1522 | ||
1664 | kfree(buf); | 1523 | /* CRC check */ |
1524 | crc = crc32_le(0xFFFFFFFF, &bthdr, 1); | ||
1525 | crc = ~crc32_le(crc, buf, DS4_FEATURE_REPORT_0x05_SIZE-4); | ||
1526 | report_crc = get_unaligned_le32(&buf[DS4_FEATURE_REPORT_0x05_SIZE-4]); | ||
1527 | if (crc != report_crc) { | ||
1528 | hid_warn(sc->hdev, "DualShock 4 calibration report's CRC check failed, received crc 0x%0x != 0x%0x\n", | ||
1529 | report_crc, crc); | ||
1530 | if (retries < 2) { | ||
1531 | hid_warn(sc->hdev, "Retrying DualShock 4 get calibration report request\n"); | ||
1532 | continue; | ||
1533 | } else { | ||
1534 | ret = -EILSEQ; | ||
1535 | goto err_stop; | ||
1536 | } | ||
1537 | } else { | ||
1538 | break; | ||
1539 | } | ||
1540 | } | ||
1541 | } | ||
1665 | 1542 | ||
1543 | gyro_pitch_bias = get_unaligned_le16(&buf[1]); | ||
1544 | gyro_yaw_bias = get_unaligned_le16(&buf[3]); | ||
1545 | gyro_roll_bias = get_unaligned_le16(&buf[5]); | ||
1546 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { | ||
1547 | gyro_pitch_plus = get_unaligned_le16(&buf[7]); | ||
1548 | gyro_pitch_minus = get_unaligned_le16(&buf[9]); | ||
1549 | gyro_yaw_plus = get_unaligned_le16(&buf[11]); | ||
1550 | gyro_yaw_minus = get_unaligned_le16(&buf[13]); | ||
1551 | gyro_roll_plus = get_unaligned_le16(&buf[15]); | ||
1552 | gyro_roll_minus = get_unaligned_le16(&buf[17]); | ||
1553 | } else { | ||
1554 | /* BT + Dongle */ | ||
1555 | gyro_pitch_plus = get_unaligned_le16(&buf[7]); | ||
1556 | gyro_yaw_plus = get_unaligned_le16(&buf[9]); | ||
1557 | gyro_roll_plus = get_unaligned_le16(&buf[11]); | ||
1558 | gyro_pitch_minus = get_unaligned_le16(&buf[13]); | ||
1559 | gyro_yaw_minus = get_unaligned_le16(&buf[15]); | ||
1560 | gyro_roll_minus = get_unaligned_le16(&buf[17]); | ||
1561 | } | ||
1562 | gyro_speed_plus = get_unaligned_le16(&buf[19]); | ||
1563 | gyro_speed_minus = get_unaligned_le16(&buf[21]); | ||
1564 | acc_x_plus = get_unaligned_le16(&buf[23]); | ||
1565 | acc_x_minus = get_unaligned_le16(&buf[25]); | ||
1566 | acc_y_plus = get_unaligned_le16(&buf[27]); | ||
1567 | acc_y_minus = get_unaligned_le16(&buf[29]); | ||
1568 | acc_z_plus = get_unaligned_le16(&buf[31]); | ||
1569 | acc_z_minus = get_unaligned_le16(&buf[33]); | ||
1570 | |||
1571 | /* Set gyroscope calibration and normalization parameters. | ||
1572 | * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s. | ||
1573 | */ | ||
1574 | speed_2x = (gyro_speed_plus + gyro_speed_minus); | ||
1575 | sc->ds4_calib_data[0].abs_code = ABS_RX; | ||
1576 | sc->ds4_calib_data[0].bias = gyro_pitch_bias; | ||
1577 | sc->ds4_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; | ||
1578 | sc->ds4_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus; | ||
1579 | |||
1580 | sc->ds4_calib_data[1].abs_code = ABS_RY; | ||
1581 | sc->ds4_calib_data[1].bias = gyro_yaw_bias; | ||
1582 | sc->ds4_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; | ||
1583 | sc->ds4_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus; | ||
1584 | |||
1585 | sc->ds4_calib_data[2].abs_code = ABS_RZ; | ||
1586 | sc->ds4_calib_data[2].bias = gyro_roll_bias; | ||
1587 | sc->ds4_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; | ||
1588 | sc->ds4_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus; | ||
1589 | |||
1590 | /* Set accelerometer calibration and normalization parameters. | ||
1591 | * Data values will be normalized to 1/DS4_ACC_RES_PER_G G. | ||
1592 | */ | ||
1593 | range_2g = acc_x_plus - acc_x_minus; | ||
1594 | sc->ds4_calib_data[3].abs_code = ABS_X; | ||
1595 | sc->ds4_calib_data[3].bias = acc_x_plus - range_2g / 2; | ||
1596 | sc->ds4_calib_data[3].sens_numer = 2*DS4_ACC_RES_PER_G; | ||
1597 | sc->ds4_calib_data[3].sens_denom = range_2g; | ||
1598 | |||
1599 | range_2g = acc_y_plus - acc_y_minus; | ||
1600 | sc->ds4_calib_data[4].abs_code = ABS_Y; | ||
1601 | sc->ds4_calib_data[4].bias = acc_y_plus - range_2g / 2; | ||
1602 | sc->ds4_calib_data[4].sens_numer = 2*DS4_ACC_RES_PER_G; | ||
1603 | sc->ds4_calib_data[4].sens_denom = range_2g; | ||
1604 | |||
1605 | range_2g = acc_z_plus - acc_z_minus; | ||
1606 | sc->ds4_calib_data[5].abs_code = ABS_Z; | ||
1607 | sc->ds4_calib_data[5].bias = acc_z_plus - range_2g / 2; | ||
1608 | sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G; | ||
1609 | sc->ds4_calib_data[5].sens_denom = range_2g; | ||
1610 | |||
1611 | err_stop: | ||
1612 | kfree(buf); | ||
1666 | return ret; | 1613 | return ret; |
1667 | } | 1614 | } |
1668 | 1615 | ||
1616 | static void dualshock4_calibration_work(struct work_struct *work) | ||
1617 | { | ||
1618 | struct sony_sc *sc = container_of(work, struct sony_sc, hotplug_worker); | ||
1619 | unsigned long flags; | ||
1620 | enum ds4_dongle_state dongle_state; | ||
1621 | int ret; | ||
1622 | |||
1623 | ret = dualshock4_get_calibration_data(sc); | ||
1624 | if (ret < 0) { | ||
1625 | /* This call is very unlikely to fail for the dongle. When it | ||
1626 | * fails we are probably in a very bad state, so mark the | ||
1627 | * dongle as disabled. We will re-enable the dongle if a new | ||
1628 | * DS4 hotplug is detect from sony_raw_event as any issues | ||
1629 | * are likely resolved then (the dongle is quite stupid). | ||
1630 | */ | ||
1631 | hid_err(sc->hdev, "DualShock 4 USB dongle: calibration failed, disabling device\n"); | ||
1632 | dongle_state = DONGLE_DISABLED; | ||
1633 | } else { | ||
1634 | hid_info(sc->hdev, "DualShock 4 USB dongle: calibration completed\n"); | ||
1635 | dongle_state = DONGLE_CONNECTED; | ||
1636 | } | ||
1637 | |||
1638 | spin_lock_irqsave(&sc->lock, flags); | ||
1639 | sc->ds4_dongle_state = dongle_state; | ||
1640 | spin_unlock_irqrestore(&sc->lock, flags); | ||
1641 | } | ||
1642 | |||
1669 | static void sixaxis_set_leds_from_id(struct sony_sc *sc) | 1643 | static void sixaxis_set_leds_from_id(struct sony_sc *sc) |
1670 | { | 1644 | { |
1671 | static const u8 sixaxis_leds[10][4] = { | 1645 | static const u8 sixaxis_leds[10][4] = { |
@@ -1696,10 +1670,10 @@ static void dualshock4_set_leds_from_id(struct sony_sc *sc) | |||
1696 | { | 1670 | { |
1697 | /* The first 4 color/index entries match what the PS4 assigns */ | 1671 | /* The first 4 color/index entries match what the PS4 assigns */ |
1698 | static const u8 color_code[7][3] = { | 1672 | static const u8 color_code[7][3] = { |
1699 | /* Blue */ { 0x00, 0x00, 0x01 }, | 1673 | /* Blue */ { 0x00, 0x00, 0x40 }, |
1700 | /* Red */ { 0x01, 0x00, 0x00 }, | 1674 | /* Red */ { 0x40, 0x00, 0x00 }, |
1701 | /* Green */ { 0x00, 0x01, 0x00 }, | 1675 | /* Green */ { 0x00, 0x40, 0x00 }, |
1702 | /* Pink */ { 0x02, 0x00, 0x01 }, | 1676 | /* Pink */ { 0x20, 0x00, 0x20 }, |
1703 | /* Orange */ { 0x02, 0x01, 0x00 }, | 1677 | /* Orange */ { 0x02, 0x01, 0x00 }, |
1704 | /* Teal */ { 0x00, 0x01, 0x01 }, | 1678 | /* Teal */ { 0x00, 0x01, 0x01 }, |
1705 | /* White */ { 0x01, 0x01, 0x01 } | 1679 | /* White */ { 0x01, 0x01, 0x01 } |
@@ -1740,7 +1714,7 @@ static void buzz_set_leds(struct sony_sc *sc) | |||
1740 | static void sony_set_leds(struct sony_sc *sc) | 1714 | static void sony_set_leds(struct sony_sc *sc) |
1741 | { | 1715 | { |
1742 | if (!(sc->quirks & BUZZ_CONTROLLER)) | 1716 | if (!(sc->quirks & BUZZ_CONTROLLER)) |
1743 | sony_schedule_work(sc); | 1717 | sony_schedule_work(sc, SONY_WORKER_STATE); |
1744 | else | 1718 | else |
1745 | buzz_set_leds(sc); | 1719 | buzz_set_leds(sc); |
1746 | } | 1720 | } |
@@ -1851,7 +1825,7 @@ static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on, | |||
1851 | new_off != drv_data->led_delay_off[n]) { | 1825 | new_off != drv_data->led_delay_off[n]) { |
1852 | drv_data->led_delay_on[n] = new_on; | 1826 | drv_data->led_delay_on[n] = new_on; |
1853 | drv_data->led_delay_off[n] = new_off; | 1827 | drv_data->led_delay_off[n] = new_off; |
1854 | sony_schedule_work(drv_data); | 1828 | sony_schedule_work(drv_data, SONY_WORKER_STATE); |
1855 | } | 1829 | } |
1856 | 1830 | ||
1857 | return 0; | 1831 | return 0; |
@@ -1964,6 +1938,7 @@ static int sony_leds_init(struct sony_sc *sc) | |||
1964 | led->name = name; | 1938 | led->name = name; |
1965 | led->brightness = sc->led_state[n]; | 1939 | led->brightness = sc->led_state[n]; |
1966 | led->max_brightness = max_brightness[n]; | 1940 | led->max_brightness = max_brightness[n]; |
1941 | led->flags = LED_CORE_SUSPENDRESUME; | ||
1967 | led->brightness_get = sony_led_get_brightness; | 1942 | led->brightness_get = sony_led_get_brightness; |
1968 | led->brightness_set = sony_led_set_brightness; | 1943 | led->brightness_set = sony_led_set_brightness; |
1969 | 1944 | ||
@@ -2052,26 +2027,24 @@ static void dualshock4_send_output_report(struct sony_sc *sc) | |||
2052 | int offset; | 2027 | int offset; |
2053 | 2028 | ||
2054 | /* | 2029 | /* |
2055 | * NOTE: The buf[1] field of the Bluetooth report controls | 2030 | * NOTE: The lower 6 bits of buf[1] field of the Bluetooth report |
2056 | * the Dualshock 4 reporting rate. | 2031 | * control the interval at which Dualshock 4 reports data: |
2057 | * | 2032 | * 0x00 - 1ms |
2058 | * Known values include: | 2033 | * 0x01 - 1ms |
2059 | * | 2034 | * 0x02 - 2ms |
2060 | * 0x80 - 1000hz (full speed) | 2035 | * 0x3E - 62ms |
2061 | * 0xA0 - 31hz | 2036 | * 0x3F - disabled |
2062 | * 0xB0 - 20hz | ||
2063 | * 0xD0 - 66hz | ||
2064 | */ | 2037 | */ |
2065 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { | 2038 | if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { |
2066 | memset(buf, 0, DS4_OUTPUT_REPORT_0x05_SIZE); | 2039 | memset(buf, 0, DS4_OUTPUT_REPORT_0x05_SIZE); |
2067 | buf[0] = 0x05; | 2040 | buf[0] = 0x05; |
2068 | buf[1] = 0xFF; | 2041 | buf[1] = 0x07; /* blink + LEDs + motor */ |
2069 | offset = 4; | 2042 | offset = 4; |
2070 | } else { | 2043 | } else { |
2071 | memset(buf, 0, DS4_OUTPUT_REPORT_0x11_SIZE); | 2044 | memset(buf, 0, DS4_OUTPUT_REPORT_0x11_SIZE); |
2072 | buf[0] = 0x11; | 2045 | buf[0] = 0x11; |
2073 | buf[1] = 0xC0; /* HID + CRC */ | 2046 | buf[1] = 0xC0 /* HID + CRC */ | sc->ds4_bt_poll_interval; |
2074 | buf[3] = 0x0F; | 2047 | buf[3] = 0x07; /* blink + LEDs + motor */ |
2075 | offset = 6; | 2048 | offset = 6; |
2076 | } | 2049 | } |
2077 | 2050 | ||
@@ -2095,7 +2068,7 @@ static void dualshock4_send_output_report(struct sony_sc *sc) | |||
2095 | buf[offset++] = sc->led_delay_on[3]; | 2068 | buf[offset++] = sc->led_delay_on[3]; |
2096 | buf[offset++] = sc->led_delay_off[3]; | 2069 | buf[offset++] = sc->led_delay_off[3]; |
2097 | 2070 | ||
2098 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) | 2071 | if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) |
2099 | hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x05_SIZE); | 2072 | hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x05_SIZE); |
2100 | else { | 2073 | else { |
2101 | /* CRC generation */ | 2074 | /* CRC generation */ |
@@ -2152,7 +2125,7 @@ static int sony_allocate_output_report(struct sony_sc *sc) | |||
2152 | else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) | 2125 | else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) |
2153 | sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x11_SIZE, | 2126 | sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x11_SIZE, |
2154 | GFP_KERNEL); | 2127 | GFP_KERNEL); |
2155 | else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) | 2128 | else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) |
2156 | sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x05_SIZE, | 2129 | sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x05_SIZE, |
2157 | GFP_KERNEL); | 2130 | GFP_KERNEL); |
2158 | else if (sc->quirks & MOTION_CONTROLLER) | 2131 | else if (sc->quirks & MOTION_CONTROLLER) |
@@ -2180,7 +2153,7 @@ static int sony_play_effect(struct input_dev *dev, void *data, | |||
2180 | sc->left = effect->u.rumble.strong_magnitude / 256; | 2153 | sc->left = effect->u.rumble.strong_magnitude / 256; |
2181 | sc->right = effect->u.rumble.weak_magnitude / 256; | 2154 | sc->right = effect->u.rumble.weak_magnitude / 256; |
2182 | 2155 | ||
2183 | sony_schedule_work(sc); | 2156 | sony_schedule_work(sc, SONY_WORKER_STATE); |
2184 | return 0; | 2157 | return 0; |
2185 | } | 2158 | } |
2186 | 2159 | ||
@@ -2397,7 +2370,7 @@ static int sony_check_add(struct sony_sc *sc) | |||
2397 | hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n"); | 2370 | hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n"); |
2398 | return 0; | 2371 | return 0; |
2399 | } | 2372 | } |
2400 | } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { | 2373 | } else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { |
2401 | buf = kmalloc(DS4_FEATURE_REPORT_0x81_SIZE, GFP_KERNEL); | 2374 | buf = kmalloc(DS4_FEATURE_REPORT_0x81_SIZE, GFP_KERNEL); |
2402 | if (!buf) | 2375 | if (!buf) |
2403 | return -ENOMEM; | 2376 | return -ENOMEM; |
@@ -2451,6 +2424,12 @@ static int sony_check_add(struct sony_sc *sc) | |||
2451 | */ | 2424 | */ |
2452 | for (n = 0; n < 6; n++) | 2425 | for (n = 0; n < 6; n++) |
2453 | sc->mac_address[5-n] = buf[4+n]; | 2426 | sc->mac_address[5-n] = buf[4+n]; |
2427 | |||
2428 | snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq), | ||
2429 | "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", | ||
2430 | sc->mac_address[5], sc->mac_address[4], | ||
2431 | sc->mac_address[3], sc->mac_address[2], | ||
2432 | sc->mac_address[1], sc->mac_address[0]); | ||
2454 | } else { | 2433 | } else { |
2455 | return 0; | 2434 | return 0; |
2456 | } | 2435 | } |
@@ -2501,18 +2480,21 @@ static inline void sony_init_output_report(struct sony_sc *sc, | |||
2501 | { | 2480 | { |
2502 | sc->send_output_report = send_output_report; | 2481 | sc->send_output_report = send_output_report; |
2503 | 2482 | ||
2504 | if (!sc->worker_initialized) | 2483 | if (!sc->state_worker_initialized) |
2505 | INIT_WORK(&sc->state_worker, sony_state_worker); | 2484 | INIT_WORK(&sc->state_worker, sony_state_worker); |
2506 | 2485 | ||
2507 | sc->worker_initialized = 1; | 2486 | sc->state_worker_initialized = 1; |
2508 | } | 2487 | } |
2509 | 2488 | ||
2510 | static inline void sony_cancel_work_sync(struct sony_sc *sc) | 2489 | static inline void sony_cancel_work_sync(struct sony_sc *sc) |
2511 | { | 2490 | { |
2512 | if (sc->worker_initialized) | 2491 | if (sc->hotplug_worker_initialized) |
2492 | cancel_work_sync(&sc->hotplug_worker); | ||
2493 | if (sc->state_worker_initialized) | ||
2513 | cancel_work_sync(&sc->state_worker); | 2494 | cancel_work_sync(&sc->state_worker); |
2514 | } | 2495 | } |
2515 | 2496 | ||
2497 | |||
2516 | static int sony_input_configured(struct hid_device *hdev, | 2498 | static int sony_input_configured(struct hid_device *hdev, |
2517 | struct hid_input *hidinput) | 2499 | struct hid_input *hidinput) |
2518 | { | 2500 | { |
@@ -2526,14 +2508,17 @@ static int sony_input_configured(struct hid_device *hdev, | |||
2526 | goto err_stop; | 2508 | goto err_stop; |
2527 | } | 2509 | } |
2528 | 2510 | ||
2511 | ret = append_dev_id = sony_check_add(sc); | ||
2512 | if (ret < 0) | ||
2513 | goto err_stop; | ||
2514 | |||
2529 | ret = sony_allocate_output_report(sc); | 2515 | ret = sony_allocate_output_report(sc); |
2530 | if (ret < 0) { | 2516 | if (ret < 0) { |
2531 | hid_err(hdev, "failed to allocate the output report buffer\n"); | 2517 | hid_err(hdev, "failed to allocate the output report buffer\n"); |
2532 | goto err_stop; | 2518 | goto err_stop; |
2533 | } | 2519 | } |
2534 | 2520 | ||
2535 | if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || | 2521 | if (sc->quirks & NAVIGATION_CONTROLLER_USB) { |
2536 | (sc->quirks & NAVIGATION_CONTROLLER_USB)) { | ||
2537 | /* | 2522 | /* |
2538 | * The Sony Sixaxis does not handle HID Output Reports on the | 2523 | * The Sony Sixaxis does not handle HID Output Reports on the |
2539 | * Interrupt EP like it could, so we need to force HID Output | 2524 | * Interrupt EP like it could, so we need to force HID Output |
@@ -2553,24 +2538,79 @@ static int sony_input_configured(struct hid_device *hdev, | |||
2553 | hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; | 2538 | hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; |
2554 | hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; | 2539 | hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; |
2555 | sc->defer_initialization = 1; | 2540 | sc->defer_initialization = 1; |
2541 | |||
2556 | ret = sixaxis_set_operational_usb(hdev); | 2542 | ret = sixaxis_set_operational_usb(hdev); |
2543 | if (ret < 0) { | ||
2544 | hid_err(hdev, "Failed to set controller into operational mode\n"); | ||
2545 | goto err_stop; | ||
2546 | } | ||
2547 | |||
2548 | sony_init_output_report(sc, sixaxis_send_output_report); | ||
2549 | } else if (sc->quirks & NAVIGATION_CONTROLLER_BT) { | ||
2550 | /* | ||
2551 | * The Navigation controller wants output reports sent on the ctrl | ||
2552 | * endpoint when connected via Bluetooth. | ||
2553 | */ | ||
2554 | hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; | ||
2555 | |||
2556 | ret = sixaxis_set_operational_bt(hdev); | ||
2557 | if (ret < 0) { | ||
2558 | hid_err(hdev, "Failed to set controller into operational mode\n"); | ||
2559 | goto err_stop; | ||
2560 | } | ||
2561 | |||
2557 | sony_init_output_report(sc, sixaxis_send_output_report); | 2562 | sony_init_output_report(sc, sixaxis_send_output_report); |
2558 | } else if ((sc->quirks & SIXAXIS_CONTROLLER_BT) || | 2563 | } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { |
2559 | (sc->quirks & NAVIGATION_CONTROLLER_BT)) { | 2564 | /* |
2565 | * The Sony Sixaxis does not handle HID Output Reports on the | ||
2566 | * Interrupt EP and the device only becomes active when the | ||
2567 | * PS button is pressed. See comment for Navigation controller | ||
2568 | * above for more details. | ||
2569 | */ | ||
2570 | hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; | ||
2571 | hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; | ||
2572 | sc->defer_initialization = 1; | ||
2573 | |||
2574 | ret = sixaxis_set_operational_usb(hdev); | ||
2575 | if (ret < 0) { | ||
2576 | hid_err(hdev, "Failed to set controller into operational mode\n"); | ||
2577 | goto err_stop; | ||
2578 | } | ||
2579 | |||
2580 | ret = sony_register_sensors(sc); | ||
2581 | if (ret) { | ||
2582 | hid_err(sc->hdev, | ||
2583 | "Unable to initialize motion sensors: %d\n", ret); | ||
2584 | goto err_stop; | ||
2585 | } | ||
2586 | |||
2587 | sony_init_output_report(sc, sixaxis_send_output_report); | ||
2588 | } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) { | ||
2560 | /* | 2589 | /* |
2561 | * The Sixaxis wants output reports sent on the ctrl endpoint | 2590 | * The Sixaxis wants output reports sent on the ctrl endpoint |
2562 | * when connected via Bluetooth. | 2591 | * when connected via Bluetooth. |
2563 | */ | 2592 | */ |
2564 | hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; | 2593 | hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; |
2594 | |||
2565 | ret = sixaxis_set_operational_bt(hdev); | 2595 | ret = sixaxis_set_operational_bt(hdev); |
2596 | if (ret < 0) { | ||
2597 | hid_err(hdev, "Failed to set controller into operational mode\n"); | ||
2598 | goto err_stop; | ||
2599 | } | ||
2600 | |||
2601 | ret = sony_register_sensors(sc); | ||
2602 | if (ret) { | ||
2603 | hid_err(sc->hdev, | ||
2604 | "Unable to initialize motion sensors: %d\n", ret); | ||
2605 | goto err_stop; | ||
2606 | } | ||
2607 | |||
2566 | sony_init_output_report(sc, sixaxis_send_output_report); | 2608 | sony_init_output_report(sc, sixaxis_send_output_report); |
2567 | } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { | 2609 | } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { |
2568 | if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { | 2610 | ret = dualshock4_get_calibration_data(sc); |
2569 | ret = dualshock4_set_operational_bt(hdev); | 2611 | if (ret < 0) { |
2570 | if (ret < 0) { | 2612 | hid_err(hdev, "Failed to get calibration data from Dualshock 4\n"); |
2571 | hid_err(hdev, "failed to set the Dualshock 4 operational mode\n"); | 2613 | goto err_stop; |
2572 | goto err_stop; | ||
2573 | } | ||
2574 | } | 2614 | } |
2575 | 2615 | ||
2576 | /* | 2616 | /* |
@@ -2585,6 +2625,28 @@ static int sony_input_configured(struct hid_device *hdev, | |||
2585 | goto err_stop; | 2625 | goto err_stop; |
2586 | } | 2626 | } |
2587 | 2627 | ||
2628 | ret = sony_register_sensors(sc); | ||
2629 | if (ret) { | ||
2630 | hid_err(sc->hdev, | ||
2631 | "Unable to initialize motion sensors: %d\n", ret); | ||
2632 | goto err_stop; | ||
2633 | } | ||
2634 | |||
2635 | if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { | ||
2636 | sc->ds4_bt_poll_interval = DS4_BT_DEFAULT_POLL_INTERVAL_MS; | ||
2637 | ret = device_create_file(&sc->hdev->dev, &dev_attr_bt_poll_interval); | ||
2638 | if (ret) | ||
2639 | hid_warn(sc->hdev, | ||
2640 | "can't create sysfs bt_poll_interval attribute err: %d\n", | ||
2641 | ret); | ||
2642 | } | ||
2643 | |||
2644 | if (sc->quirks & DUALSHOCK4_DONGLE) { | ||
2645 | INIT_WORK(&sc->hotplug_worker, dualshock4_calibration_work); | ||
2646 | sc->hotplug_worker_initialized = 1; | ||
2647 | sc->ds4_dongle_state = DONGLE_DISCONNECTED; | ||
2648 | } | ||
2649 | |||
2588 | sony_init_output_report(sc, dualshock4_send_output_report); | 2650 | sony_init_output_report(sc, dualshock4_send_output_report); |
2589 | } else if (sc->quirks & MOTION_CONTROLLER) { | 2651 | } else if (sc->quirks & MOTION_CONTROLLER) { |
2590 | sony_init_output_report(sc, motion_send_output_report); | 2652 | sony_init_output_report(sc, motion_send_output_report); |
@@ -2592,13 +2654,6 @@ static int sony_input_configured(struct hid_device *hdev, | |||
2592 | ret = 0; | 2654 | ret = 0; |
2593 | } | 2655 | } |
2594 | 2656 | ||
2595 | if (ret < 0) | ||
2596 | goto err_stop; | ||
2597 | |||
2598 | ret = append_dev_id = sony_check_add(sc); | ||
2599 | if (ret < 0) | ||
2600 | goto err_stop; | ||
2601 | |||
2602 | if (sc->quirks & SONY_LED_SUPPORT) { | 2657 | if (sc->quirks & SONY_LED_SUPPORT) { |
2603 | ret = sony_leds_init(sc); | 2658 | ret = sony_leds_init(sc); |
2604 | if (ret < 0) | 2659 | if (ret < 0) |
@@ -2628,12 +2683,20 @@ static int sony_input_configured(struct hid_device *hdev, | |||
2628 | err_close: | 2683 | err_close: |
2629 | hid_hw_close(hdev); | 2684 | hid_hw_close(hdev); |
2630 | err_stop: | 2685 | err_stop: |
2686 | /* Piggy back on the default ds4_bt_ poll_interval to determine | ||
2687 | * if we need to remove the file as we don't know for sure if we | ||
2688 | * executed that logic. | ||
2689 | */ | ||
2690 | if (sc->ds4_bt_poll_interval) | ||
2691 | device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval); | ||
2631 | if (sc->quirks & SONY_LED_SUPPORT) | 2692 | if (sc->quirks & SONY_LED_SUPPORT) |
2632 | sony_leds_remove(sc); | 2693 | sony_leds_remove(sc); |
2633 | if (sc->quirks & SONY_BATTERY_SUPPORT) | 2694 | if (sc->quirks & SONY_BATTERY_SUPPORT) |
2634 | sony_battery_remove(sc); | 2695 | sony_battery_remove(sc); |
2635 | if (sc->touchpad) | 2696 | if (sc->touchpad) |
2636 | sony_unregister_touchpad(sc); | 2697 | sony_unregister_touchpad(sc); |
2698 | if (sc->sensor_dev) | ||
2699 | sony_unregister_sensors(sc); | ||
2637 | sony_cancel_work_sync(sc); | 2700 | sony_cancel_work_sync(sc); |
2638 | kfree(sc->output_report_dmabuf); | 2701 | kfree(sc->output_report_dmabuf); |
2639 | sony_remove_dev_list(sc); | 2702 | sony_remove_dev_list(sc); |
@@ -2675,13 +2738,13 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
2675 | else if (sc->quirks & SIXAXIS_CONTROLLER) | 2738 | else if (sc->quirks & SIXAXIS_CONTROLLER) |
2676 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; | 2739 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; |
2677 | 2740 | ||
2678 | /* Patch the hw version on DS4 compatible devices, so applications can | 2741 | /* Patch the hw version on DS3/4 compatible devices, so applications can |
2679 | * distinguish between the default HID mappings and the mappings defined | 2742 | * distinguish between the default HID mappings and the mappings defined |
2680 | * by the Linux game controller spec. This is important for the SDL2 | 2743 | * by the Linux game controller spec. This is important for the SDL2 |
2681 | * library, which has a game controller database, which uses device ids | 2744 | * library, which has a game controller database, which uses device ids |
2682 | * in combination with version as a key. | 2745 | * in combination with version as a key. |
2683 | */ | 2746 | */ |
2684 | if (sc->quirks & DUALSHOCK4_CONTROLLER) | 2747 | if (sc->quirks & (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)) |
2685 | hdev->version |= 0x8000; | 2748 | hdev->version |= 0x8000; |
2686 | 2749 | ||
2687 | ret = hid_hw_start(hdev, connect_mask); | 2750 | ret = hid_hw_start(hdev, connect_mask); |
@@ -2721,6 +2784,12 @@ static void sony_remove(struct hid_device *hdev) | |||
2721 | if (sc->touchpad) | 2784 | if (sc->touchpad) |
2722 | sony_unregister_touchpad(sc); | 2785 | sony_unregister_touchpad(sc); |
2723 | 2786 | ||
2787 | if (sc->sensor_dev) | ||
2788 | sony_unregister_sensors(sc); | ||
2789 | |||
2790 | if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) | ||
2791 | device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval); | ||
2792 | |||
2724 | sony_cancel_work_sync(sc); | 2793 | sony_cancel_work_sync(sc); |
2725 | 2794 | ||
2726 | kfree(sc->output_report_dmabuf); | 2795 | kfree(sc->output_report_dmabuf); |
@@ -2736,47 +2805,32 @@ static void sony_remove(struct hid_device *hdev) | |||
2736 | 2805 | ||
2737 | static int sony_suspend(struct hid_device *hdev, pm_message_t message) | 2806 | static int sony_suspend(struct hid_device *hdev, pm_message_t message) |
2738 | { | 2807 | { |
2739 | /* | ||
2740 | * On suspend save the current LED state, | ||
2741 | * stop running force-feedback and blank the LEDS. | ||
2742 | */ | ||
2743 | if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) { | ||
2744 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
2745 | |||
2746 | #ifdef CONFIG_SONY_FF | 2808 | #ifdef CONFIG_SONY_FF |
2747 | sc->left = sc->right = 0; | ||
2748 | #endif | ||
2749 | 2809 | ||
2750 | memcpy(sc->resume_led_state, sc->led_state, | 2810 | /* On suspend stop any running force-feedback events */ |
2751 | sizeof(sc->resume_led_state)); | 2811 | if (SONY_FF_SUPPORT) { |
2752 | memset(sc->led_state, 0, sizeof(sc->led_state)); | 2812 | struct sony_sc *sc = hid_get_drvdata(hdev); |
2753 | 2813 | ||
2814 | sc->left = sc->right = 0; | ||
2754 | sony_send_output_report(sc); | 2815 | sony_send_output_report(sc); |
2755 | } | 2816 | } |
2756 | 2817 | ||
2818 | #endif | ||
2757 | return 0; | 2819 | return 0; |
2758 | } | 2820 | } |
2759 | 2821 | ||
2760 | static int sony_resume(struct hid_device *hdev) | 2822 | static int sony_resume(struct hid_device *hdev) |
2761 | { | 2823 | { |
2762 | /* Restore the state of controller LEDs on resume */ | 2824 | struct sony_sc *sc = hid_get_drvdata(hdev); |
2763 | if (SONY_LED_SUPPORT) { | ||
2764 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
2765 | |||
2766 | memcpy(sc->led_state, sc->resume_led_state, | ||
2767 | sizeof(sc->led_state)); | ||
2768 | |||
2769 | /* | ||
2770 | * The Sixaxis and navigation controllers on USB need to be | ||
2771 | * reinitialized on resume or they won't behave properly. | ||
2772 | */ | ||
2773 | if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || | ||
2774 | (sc->quirks & NAVIGATION_CONTROLLER_USB)) { | ||
2775 | sixaxis_set_operational_usb(sc->hdev); | ||
2776 | sc->defer_initialization = 1; | ||
2777 | } | ||
2778 | 2825 | ||
2779 | sony_set_leds(sc); | 2826 | /* |
2827 | * The Sixaxis and navigation controllers on USB need to be | ||
2828 | * reinitialized on resume or they won't behave properly. | ||
2829 | */ | ||
2830 | if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || | ||
2831 | (sc->quirks & NAVIGATION_CONTROLLER_USB)) { | ||
2832 | sixaxis_set_operational_usb(sc->hdev); | ||
2833 | sc->defer_initialization = 1; | ||
2780 | } | 2834 | } |
2781 | 2835 | ||
2782 | return 0; | 2836 | return 0; |
@@ -2828,7 +2882,7 @@ static const struct hid_device_id sony_devices[] = { | |||
2828 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2), | 2882 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2), |
2829 | .driver_data = DUALSHOCK4_CONTROLLER_BT }, | 2883 | .driver_data = DUALSHOCK4_CONTROLLER_BT }, |
2830 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE), | 2884 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE), |
2831 | .driver_data = DUALSHOCK4_CONTROLLER_USB }, | 2885 | .driver_data = DUALSHOCK4_DONGLE }, |
2832 | /* Nyko Core Controller for PS3 */ | 2886 | /* Nyko Core Controller for PS3 */ |
2833 | { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER), | 2887 | { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER), |
2834 | .driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER }, | 2888 | .driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER }, |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index ea3c3546cef7..8daa8ce64ebb 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -508,66 +508,6 @@ static int i2c_hid_get_report_length(struct hid_report *report) | |||
508 | report->device->report_enum[report->type].numbered + 2; | 508 | report->device->report_enum[report->type].numbered + 2; |
509 | } | 509 | } |
510 | 510 | ||
511 | static void i2c_hid_init_report(struct hid_report *report, u8 *buffer, | ||
512 | size_t bufsize) | ||
513 | { | ||
514 | struct hid_device *hid = report->device; | ||
515 | struct i2c_client *client = hid->driver_data; | ||
516 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
517 | unsigned int size, ret_size; | ||
518 | |||
519 | size = i2c_hid_get_report_length(report); | ||
520 | if (i2c_hid_get_report(client, | ||
521 | report->type == HID_FEATURE_REPORT ? 0x03 : 0x01, | ||
522 | report->id, buffer, size)) | ||
523 | return; | ||
524 | |||
525 | i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, buffer); | ||
526 | |||
527 | ret_size = buffer[0] | (buffer[1] << 8); | ||
528 | |||
529 | if (ret_size != size) { | ||
530 | dev_err(&client->dev, "error in %s size:%d / ret_size:%d\n", | ||
531 | __func__, size, ret_size); | ||
532 | return; | ||
533 | } | ||
534 | |||
535 | /* hid->driver_lock is held as we are in probe function, | ||
536 | * we just need to setup the input fields, so using | ||
537 | * hid_report_raw_event is safe. */ | ||
538 | hid_report_raw_event(hid, report->type, buffer + 2, size - 2, 1); | ||
539 | } | ||
540 | |||
541 | /* | ||
542 | * Initialize all reports | ||
543 | */ | ||
544 | static void i2c_hid_init_reports(struct hid_device *hid) | ||
545 | { | ||
546 | struct hid_report *report; | ||
547 | struct i2c_client *client = hid->driver_data; | ||
548 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
549 | u8 *inbuf = kzalloc(ihid->bufsize, GFP_KERNEL); | ||
550 | |||
551 | if (!inbuf) { | ||
552 | dev_err(&client->dev, "can not retrieve initial reports\n"); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * The device must be powered on while we fetch initial reports | ||
558 | * from it. | ||
559 | */ | ||
560 | pm_runtime_get_sync(&client->dev); | ||
561 | |||
562 | list_for_each_entry(report, | ||
563 | &hid->report_enum[HID_FEATURE_REPORT].report_list, list) | ||
564 | i2c_hid_init_report(report, inbuf, ihid->bufsize); | ||
565 | |||
566 | pm_runtime_put(&client->dev); | ||
567 | |||
568 | kfree(inbuf); | ||
569 | } | ||
570 | |||
571 | /* | 511 | /* |
572 | * Traverse the supplied list of reports and find the longest | 512 | * Traverse the supplied list of reports and find the longest |
573 | */ | 513 | */ |
@@ -789,9 +729,6 @@ static int i2c_hid_start(struct hid_device *hid) | |||
789 | return ret; | 729 | return ret; |
790 | } | 730 | } |
791 | 731 | ||
792 | if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS)) | ||
793 | i2c_hid_init_reports(hid); | ||
794 | |||
795 | return 0; | 732 | return 0; |
796 | } | 733 | } |
797 | 734 | ||
@@ -994,6 +931,11 @@ static int i2c_hid_of_probe(struct i2c_client *client, | |||
994 | } | 931 | } |
995 | pdata->hid_descriptor_address = val; | 932 | pdata->hid_descriptor_address = val; |
996 | 933 | ||
934 | ret = of_property_read_u32(dev->of_node, "post-power-on-delay-ms", | ||
935 | &val); | ||
936 | if (!ret) | ||
937 | pdata->post_power_delay_ms = val; | ||
938 | |||
997 | return 0; | 939 | return 0; |
998 | } | 940 | } |
999 | 941 | ||
@@ -1053,6 +995,24 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
1053 | ihid->pdata = *platform_data; | 995 | ihid->pdata = *platform_data; |
1054 | } | 996 | } |
1055 | 997 | ||
998 | ihid->pdata.supply = devm_regulator_get(&client->dev, "vdd"); | ||
999 | if (IS_ERR(ihid->pdata.supply)) { | ||
1000 | ret = PTR_ERR(ihid->pdata.supply); | ||
1001 | if (ret != -EPROBE_DEFER) | ||
1002 | dev_err(&client->dev, "Failed to get regulator: %d\n", | ||
1003 | ret); | ||
1004 | goto err; | ||
1005 | } | ||
1006 | |||
1007 | ret = regulator_enable(ihid->pdata.supply); | ||
1008 | if (ret < 0) { | ||
1009 | dev_err(&client->dev, "Failed to enable regulator: %d\n", | ||
1010 | ret); | ||
1011 | goto err; | ||
1012 | } | ||
1013 | if (ihid->pdata.post_power_delay_ms) | ||
1014 | msleep(ihid->pdata.post_power_delay_ms); | ||
1015 | |||
1056 | i2c_set_clientdata(client, ihid); | 1016 | i2c_set_clientdata(client, ihid); |
1057 | 1017 | ||
1058 | ihid->client = client; | 1018 | ihid->client = client; |
@@ -1068,7 +1028,7 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
1068 | * real computation later. */ | 1028 | * real computation later. */ |
1069 | ret = i2c_hid_alloc_buffers(ihid, HID_MIN_BUFFER_SIZE); | 1029 | ret = i2c_hid_alloc_buffers(ihid, HID_MIN_BUFFER_SIZE); |
1070 | if (ret < 0) | 1030 | if (ret < 0) |
1071 | goto err; | 1031 | goto err_regulator; |
1072 | 1032 | ||
1073 | pm_runtime_get_noresume(&client->dev); | 1033 | pm_runtime_get_noresume(&client->dev); |
1074 | pm_runtime_set_active(&client->dev); | 1034 | pm_runtime_set_active(&client->dev); |
@@ -1125,6 +1085,9 @@ err_pm: | |||
1125 | pm_runtime_put_noidle(&client->dev); | 1085 | pm_runtime_put_noidle(&client->dev); |
1126 | pm_runtime_disable(&client->dev); | 1086 | pm_runtime_disable(&client->dev); |
1127 | 1087 | ||
1088 | err_regulator: | ||
1089 | regulator_disable(ihid->pdata.supply); | ||
1090 | |||
1128 | err: | 1091 | err: |
1129 | i2c_hid_free_buffers(ihid); | 1092 | i2c_hid_free_buffers(ihid); |
1130 | kfree(ihid); | 1093 | kfree(ihid); |
@@ -1149,6 +1112,8 @@ static int i2c_hid_remove(struct i2c_client *client) | |||
1149 | if (ihid->bufsize) | 1112 | if (ihid->bufsize) |
1150 | i2c_hid_free_buffers(ihid); | 1113 | i2c_hid_free_buffers(ihid); |
1151 | 1114 | ||
1115 | regulator_disable(ihid->pdata.supply); | ||
1116 | |||
1152 | kfree(ihid); | 1117 | kfree(ihid); |
1153 | 1118 | ||
1154 | return 0; | 1119 | return 0; |
@@ -1199,6 +1164,10 @@ static int i2c_hid_suspend(struct device *dev) | |||
1199 | else | 1164 | else |
1200 | hid_warn(hid, "Failed to enable irq wake: %d\n", | 1165 | hid_warn(hid, "Failed to enable irq wake: %d\n", |
1201 | wake_status); | 1166 | wake_status); |
1167 | } else { | ||
1168 | ret = regulator_disable(ihid->pdata.supply); | ||
1169 | if (ret < 0) | ||
1170 | hid_warn(hid, "Failed to disable supply: %d\n", ret); | ||
1202 | } | 1171 | } |
1203 | 1172 | ||
1204 | return 0; | 1173 | return 0; |
@@ -1212,7 +1181,13 @@ static int i2c_hid_resume(struct device *dev) | |||
1212 | struct hid_device *hid = ihid->hid; | 1181 | struct hid_device *hid = ihid->hid; |
1213 | int wake_status; | 1182 | int wake_status; |
1214 | 1183 | ||
1215 | if (device_may_wakeup(&client->dev) && ihid->irq_wake_enabled) { | 1184 | if (!device_may_wakeup(&client->dev)) { |
1185 | ret = regulator_enable(ihid->pdata.supply); | ||
1186 | if (ret < 0) | ||
1187 | hid_warn(hid, "Failed to enable supply: %d\n", ret); | ||
1188 | if (ihid->pdata.post_power_delay_ms) | ||
1189 | msleep(ihid->pdata.post_power_delay_ms); | ||
1190 | } else if (ihid->irq_wake_enabled) { | ||
1216 | wake_status = disable_irq_wake(client->irq); | 1191 | wake_status = disable_irq_wake(client->irq); |
1217 | if (!wake_status) | 1192 | if (!wake_status) |
1218 | ihid->irq_wake_enabled = false; | 1193 | ihid->irq_wake_enabled = false; |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 961bc6fdd2d9..83772fa7d92a 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -52,6 +52,10 @@ static unsigned int hid_mousepoll_interval; | |||
52 | module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); | 52 | module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); |
53 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); | 53 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); |
54 | 54 | ||
55 | static unsigned int hid_jspoll_interval; | ||
56 | module_param_named(jspoll, hid_jspoll_interval, uint, 0644); | ||
57 | MODULE_PARM_DESC(jspoll, "Polling interval of joysticks"); | ||
58 | |||
55 | static unsigned int ignoreled; | 59 | static unsigned int ignoreled; |
56 | module_param_named(ignoreled, ignoreled, uint, 0644); | 60 | module_param_named(ignoreled, ignoreled, uint, 0644); |
57 | MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds"); | 61 | MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds"); |
@@ -753,11 +757,9 @@ void usbhid_init_reports(struct hid_device *hid) | |||
753 | struct hid_report_enum *report_enum; | 757 | struct hid_report_enum *report_enum; |
754 | int err, ret; | 758 | int err, ret; |
755 | 759 | ||
756 | if (!(hid->quirks & HID_QUIRK_NO_INIT_INPUT_REPORTS)) { | 760 | report_enum = &hid->report_enum[HID_INPUT_REPORT]; |
757 | report_enum = &hid->report_enum[HID_INPUT_REPORT]; | 761 | list_for_each_entry(report, &report_enum->report_list, list) |
758 | list_for_each_entry(report, &report_enum->report_list, list) | 762 | usbhid_submit_report(hid, report, USB_DIR_IN); |
759 | usbhid_submit_report(hid, report, USB_DIR_IN); | ||
760 | } | ||
761 | 763 | ||
762 | report_enum = &hid->report_enum[HID_FEATURE_REPORT]; | 764 | report_enum = &hid->report_enum[HID_FEATURE_REPORT]; |
763 | list_for_each_entry(report, &report_enum->report_list, list) | 765 | list_for_each_entry(report, &report_enum->report_list, list) |
@@ -1004,10 +1006,9 @@ static int usbhid_parse(struct hid_device *hid) | |||
1004 | return -EINVAL; | 1006 | return -EINVAL; |
1005 | } | 1007 | } |
1006 | 1008 | ||
1007 | if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { | 1009 | rdesc = kmalloc(rsize, GFP_KERNEL); |
1008 | dbg_hid("couldn't allocate rdesc memory\n"); | 1010 | if (!rdesc) |
1009 | return -ENOMEM; | 1011 | return -ENOMEM; |
1010 | } | ||
1011 | 1012 | ||
1012 | hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); | 1013 | hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); |
1013 | 1014 | ||
@@ -1077,13 +1078,21 @@ static int usbhid_start(struct hid_device *hid) | |||
1077 | if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL && | 1078 | if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL && |
1078 | dev->speed == USB_SPEED_HIGH) { | 1079 | dev->speed == USB_SPEED_HIGH) { |
1079 | interval = fls(endpoint->bInterval*8); | 1080 | interval = fls(endpoint->bInterval*8); |
1080 | printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n", | 1081 | pr_info("%s: Fixing fullspeed to highspeed interval: %d -> %d\n", |
1081 | hid->name, endpoint->bInterval, interval); | 1082 | hid->name, endpoint->bInterval, interval); |
1082 | } | 1083 | } |
1083 | 1084 | ||
1084 | /* Change the polling interval of mice. */ | 1085 | /* Change the polling interval of mice and joysticks. */ |
1085 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) | 1086 | switch (hid->collection->usage) { |
1086 | interval = hid_mousepoll_interval; | 1087 | case HID_GD_MOUSE: |
1088 | if (hid_mousepoll_interval > 0) | ||
1089 | interval = hid_mousepoll_interval; | ||
1090 | break; | ||
1091 | case HID_GD_JOYSTICK: | ||
1092 | if (hid_jspoll_interval > 0) | ||
1093 | interval = hid_jspoll_interval; | ||
1094 | break; | ||
1095 | } | ||
1087 | 1096 | ||
1088 | ret = -ENOMEM; | 1097 | ret = -ENOMEM; |
1089 | if (usb_endpoint_dir_in(endpoint)) { | 1098 | if (usb_endpoint_dir_in(endpoint)) { |
@@ -1120,9 +1129,6 @@ static int usbhid_start(struct hid_device *hid) | |||
1120 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; | 1129 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; |
1121 | usbhid->urbctrl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1130 | usbhid->urbctrl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1122 | 1131 | ||
1123 | if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS)) | ||
1124 | usbhid_init_reports(hid); | ||
1125 | |||
1126 | set_bit(HID_STARTED, &usbhid->iofl); | 1132 | set_bit(HID_STARTED, &usbhid->iofl); |
1127 | 1133 | ||
1128 | if (hid->quirks & HID_QUIRK_ALWAYS_POLL) { | 1134 | if (hid->quirks & HID_QUIRK_ALWAYS_POLL) { |
@@ -1456,10 +1462,9 @@ static int hid_post_reset(struct usb_interface *intf) | |||
1456 | * the size of the HID report descriptor has not changed. | 1462 | * the size of the HID report descriptor has not changed. |
1457 | */ | 1463 | */ |
1458 | rdesc = kmalloc(hid->dev_rsize, GFP_KERNEL); | 1464 | rdesc = kmalloc(hid->dev_rsize, GFP_KERNEL); |
1459 | if (!rdesc) { | 1465 | if (!rdesc) |
1460 | dbg_hid("couldn't allocate rdesc memory (post_reset)\n"); | ||
1461 | return -ENOMEM; | 1466 | return -ENOMEM; |
1462 | } | 1467 | |
1463 | status = hid_get_class_descriptor(dev, | 1468 | status = hid_get_class_descriptor(dev, |
1464 | interface->desc.bInterfaceNumber, | 1469 | interface->desc.bInterfaceNumber, |
1465 | HID_DT_REPORT, rdesc, hid->dev_rsize); | 1470 | HID_DT_REPORT, rdesc, hid->dev_rsize); |
@@ -1637,7 +1642,7 @@ static int __init hid_init(void) | |||
1637 | retval = usb_register(&hid_driver); | 1642 | retval = usb_register(&hid_driver); |
1638 | if (retval) | 1643 | if (retval) |
1639 | goto usb_register_fail; | 1644 | goto usb_register_fail; |
1640 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); | 1645 | pr_info(KBUILD_MODNAME ": " DRIVER_DESC "\n"); |
1641 | 1646 | ||
1642 | return 0; | 1647 | return 0; |
1643 | usb_register_fail: | 1648 | usb_register_fail: |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a69a3c88ab29..6316498b7812 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -65,6 +65,7 @@ static const struct hid_blacklist { | |||
65 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, | 65 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, |
66 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET }, | 66 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET }, |
67 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET }, | 67 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET }, |
68 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS1758, HID_QUIRK_NOGET }, | ||
68 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET }, | 69 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET }, |
69 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, |
70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET }, | 71 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET }, |
@@ -161,10 +162,11 @@ static const struct hid_blacklist { | |||
161 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS }, | 162 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS }, |
162 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS }, | 163 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS }, |
163 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS }, | 164 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS }, |
164 | { USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096, HID_QUIRK_NO_INIT_INPUT_REPORTS }, | 165 | { USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096, HID_QUIRK_NO_INIT_REPORTS }, |
165 | { USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD, HID_QUIRK_MULTI_INPUT }, | 166 | { USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD, HID_QUIRK_MULTI_INPUT }, |
166 | { USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES, HID_QUIRK_MULTI_INPUT }, | 167 | { USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES, HID_QUIRK_MULTI_INPUT }, |
167 | { USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES, HID_QUIRK_MULTI_INPUT }, | 168 | { USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES, HID_QUIRK_MULTI_INPUT }, |
169 | { USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI, HID_QUIRK_MULTI_INPUT }, | ||
168 | 170 | ||
169 | { 0, 0 } | 171 | { 0, 0 } |
170 | }; | 172 | }; |
@@ -240,10 +242,8 @@ static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, | |||
240 | } | 242 | } |
241 | 243 | ||
242 | q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL); | 244 | q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL); |
243 | if (!q_new) { | 245 | if (!q_new) |
244 | dbg_hid("Could not allocate quirks_list_struct\n"); | ||
245 | return -ENOMEM; | 246 | return -ENOMEM; |
246 | } | ||
247 | 247 | ||
248 | q_new->hid_bl_item.idVendor = idVendor; | 248 | q_new->hid_bl_item.idVendor = idVendor; |
249 | q_new->hid_bl_item.idProduct = idProduct; | 249 | q_new->hid_bl_item.idProduct = idProduct; |
@@ -309,10 +309,9 @@ int usbhid_quirks_init(char **quirks_param) | |||
309 | &idVendor, &idProduct, &quirks); | 309 | &idVendor, &idProduct, &quirks); |
310 | 310 | ||
311 | if (m != 3 || | 311 | if (m != 3 || |
312 | usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) { | 312 | usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) { |
313 | printk(KERN_WARNING | 313 | pr_warn("Could not parse HID quirk module param %s\n", |
314 | "Could not parse HID quirk module param %s\n", | 314 | quirks_param[n]); |
315 | quirks_param[n]); | ||
316 | } | 315 | } |
317 | } | 316 | } |
318 | 317 | ||
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 774bd701dae0..0e06368d1fbb 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -47,16 +47,6 @@ | |||
47 | #endif | 47 | #endif |
48 | #define HIDDEV_BUFFER_SIZE 2048 | 48 | #define HIDDEV_BUFFER_SIZE 2048 |
49 | 49 | ||
50 | struct hiddev { | ||
51 | int exist; | ||
52 | int open; | ||
53 | struct mutex existancelock; | ||
54 | wait_queue_head_t wait; | ||
55 | struct hid_device *hid; | ||
56 | struct list_head list; | ||
57 | spinlock_t list_lock; | ||
58 | }; | ||
59 | |||
60 | struct hiddev_list { | 50 | struct hiddev_list { |
61 | struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE]; | 51 | struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE]; |
62 | int head; | 52 | int head; |
@@ -690,6 +680,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
690 | 680 | ||
691 | case HIDIOCINITREPORT: | 681 | case HIDIOCINITREPORT: |
692 | usbhid_init_reports(hid); | 682 | usbhid_init_reports(hid); |
683 | hiddev->initialized = true; | ||
693 | r = 0; | 684 | r = 0; |
694 | break; | 685 | break; |
695 | 686 | ||
@@ -791,6 +782,10 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
791 | case HIDIOCGUSAGES: | 782 | case HIDIOCGUSAGES: |
792 | case HIDIOCSUSAGES: | 783 | case HIDIOCSUSAGES: |
793 | case HIDIOCGCOLLECTIONINDEX: | 784 | case HIDIOCGCOLLECTIONINDEX: |
785 | if (!hiddev->initialized) { | ||
786 | usbhid_init_reports(hid); | ||
787 | hiddev->initialized = true; | ||
788 | } | ||
794 | r = hiddev_ioctl_usage(hiddev, cmd, user_arg); | 789 | r = hiddev_ioctl_usage(hiddev, cmd, user_arg); |
795 | break; | 790 | break; |
796 | 791 | ||
@@ -911,6 +906,15 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) | |||
911 | kfree(hiddev); | 906 | kfree(hiddev); |
912 | return -1; | 907 | return -1; |
913 | } | 908 | } |
909 | |||
910 | /* | ||
911 | * If HID_QUIRK_NO_INIT_REPORTS is set, make sure we don't initialize | ||
912 | * the reports. | ||
913 | */ | ||
914 | hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS; | ||
915 | |||
916 | hiddev->minor = usbhid->intf->minor; | ||
917 | |||
914 | return 0; | 918 | return 0; |
915 | } | 919 | } |
916 | 920 | ||
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 38ee2125412f..c7b9ab1907d8 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h | |||
@@ -110,6 +110,7 @@ enum wacom_worker { | |||
110 | WACOM_WORKER_WIRELESS, | 110 | WACOM_WORKER_WIRELESS, |
111 | WACOM_WORKER_BATTERY, | 111 | WACOM_WORKER_BATTERY, |
112 | WACOM_WORKER_REMOTE, | 112 | WACOM_WORKER_REMOTE, |
113 | WACOM_WORKER_MODE_CHANGE, | ||
113 | }; | 114 | }; |
114 | 115 | ||
115 | struct wacom; | 116 | struct wacom; |
@@ -167,6 +168,7 @@ struct wacom { | |||
167 | struct work_struct remote_work; | 168 | struct work_struct remote_work; |
168 | struct delayed_work init_work; | 169 | struct delayed_work init_work; |
169 | struct wacom_remote *remote; | 170 | struct wacom_remote *remote; |
171 | struct work_struct mode_change_work; | ||
170 | bool generic_has_leds; | 172 | bool generic_has_leds; |
171 | struct wacom_leds { | 173 | struct wacom_leds { |
172 | struct wacom_group_leds *groups; | 174 | struct wacom_group_leds *groups; |
@@ -196,6 +198,9 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac, | |||
196 | case WACOM_WORKER_REMOTE: | 198 | case WACOM_WORKER_REMOTE: |
197 | schedule_work(&wacom->remote_work); | 199 | schedule_work(&wacom->remote_work); |
198 | break; | 200 | break; |
201 | case WACOM_WORKER_MODE_CHANGE: | ||
202 | schedule_work(&wacom->mode_change_work); | ||
203 | break; | ||
199 | } | 204 | } |
200 | } | 205 | } |
201 | 206 | ||
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e2666ef84dc1..0022c0dac88a 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -325,6 +325,13 @@ static void wacom_post_parse_hid(struct hid_device *hdev, | |||
325 | 325 | ||
326 | if (features->type == HID_GENERIC) { | 326 | if (features->type == HID_GENERIC) { |
327 | /* Any last-minute generic device setup */ | 327 | /* Any last-minute generic device setup */ |
328 | if (wacom_wac->has_mode_change) { | ||
329 | if (wacom_wac->is_direct_mode) | ||
330 | features->device_type |= WACOM_DEVICETYPE_DIRECT; | ||
331 | else | ||
332 | features->device_type &= ~WACOM_DEVICETYPE_DIRECT; | ||
333 | } | ||
334 | |||
328 | if (features->touch_max > 1) { | 335 | if (features->touch_max > 1) { |
329 | if (features->device_type & WACOM_DEVICETYPE_DIRECT) | 336 | if (features->device_type & WACOM_DEVICETYPE_DIRECT) |
330 | input_mt_init_slots(wacom_wac->touch_input, | 337 | input_mt_init_slots(wacom_wac->touch_input, |
@@ -2093,8 +2100,10 @@ static void wacom_set_shared_values(struct wacom_wac *wacom_wac) | |||
2093 | wacom_wac->shared->touch_input = wacom_wac->touch_input; | 2100 | wacom_wac->shared->touch_input = wacom_wac->touch_input; |
2094 | } | 2101 | } |
2095 | 2102 | ||
2096 | if (wacom_wac->has_mute_touch_switch) | 2103 | if (wacom_wac->has_mute_touch_switch) { |
2097 | wacom_wac->shared->has_mute_touch_switch = true; | 2104 | wacom_wac->shared->has_mute_touch_switch = true; |
2105 | wacom_wac->shared->is_touch_on = true; | ||
2106 | } | ||
2098 | 2107 | ||
2099 | if (wacom_wac->shared->has_mute_touch_switch && | 2108 | if (wacom_wac->shared->has_mute_touch_switch && |
2100 | wacom_wac->shared->touch_input) { | 2109 | wacom_wac->shared->touch_input) { |
@@ -2490,6 +2499,46 @@ static void wacom_remote_work(struct work_struct *work) | |||
2490 | } | 2499 | } |
2491 | } | 2500 | } |
2492 | 2501 | ||
2502 | static void wacom_mode_change_work(struct work_struct *work) | ||
2503 | { | ||
2504 | struct wacom *wacom = container_of(work, struct wacom, mode_change_work); | ||
2505 | struct wacom_shared *shared = wacom->wacom_wac.shared; | ||
2506 | struct wacom *wacom1 = NULL; | ||
2507 | struct wacom *wacom2 = NULL; | ||
2508 | bool is_direct = wacom->wacom_wac.is_direct_mode; | ||
2509 | int error = 0; | ||
2510 | |||
2511 | if (shared->pen) { | ||
2512 | wacom1 = hid_get_drvdata(shared->pen); | ||
2513 | wacom_release_resources(wacom1); | ||
2514 | hid_hw_stop(wacom1->hdev); | ||
2515 | wacom1->wacom_wac.has_mode_change = true; | ||
2516 | wacom1->wacom_wac.is_direct_mode = is_direct; | ||
2517 | } | ||
2518 | |||
2519 | if (shared->touch) { | ||
2520 | wacom2 = hid_get_drvdata(shared->touch); | ||
2521 | wacom_release_resources(wacom2); | ||
2522 | hid_hw_stop(wacom2->hdev); | ||
2523 | wacom2->wacom_wac.has_mode_change = true; | ||
2524 | wacom2->wacom_wac.is_direct_mode = is_direct; | ||
2525 | } | ||
2526 | |||
2527 | if (wacom1) { | ||
2528 | error = wacom_parse_and_register(wacom1, false); | ||
2529 | if (error) | ||
2530 | return; | ||
2531 | } | ||
2532 | |||
2533 | if (wacom2) { | ||
2534 | error = wacom_parse_and_register(wacom2, false); | ||
2535 | if (error) | ||
2536 | return; | ||
2537 | } | ||
2538 | |||
2539 | return; | ||
2540 | } | ||
2541 | |||
2493 | static int wacom_probe(struct hid_device *hdev, | 2542 | static int wacom_probe(struct hid_device *hdev, |
2494 | const struct hid_device_id *id) | 2543 | const struct hid_device_id *id) |
2495 | { | 2544 | { |
@@ -2534,6 +2583,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
2534 | INIT_WORK(&wacom->wireless_work, wacom_wireless_work); | 2583 | INIT_WORK(&wacom->wireless_work, wacom_wireless_work); |
2535 | INIT_WORK(&wacom->battery_work, wacom_battery_work); | 2584 | INIT_WORK(&wacom->battery_work, wacom_battery_work); |
2536 | INIT_WORK(&wacom->remote_work, wacom_remote_work); | 2585 | INIT_WORK(&wacom->remote_work, wacom_remote_work); |
2586 | INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work); | ||
2537 | 2587 | ||
2538 | /* ask for the report descriptor to be loaded by HID */ | 2588 | /* ask for the report descriptor to be loaded by HID */ |
2539 | error = hid_parse(hdev); | 2589 | error = hid_parse(hdev); |
@@ -2576,6 +2626,7 @@ static void wacom_remove(struct hid_device *hdev) | |||
2576 | cancel_work_sync(&wacom->wireless_work); | 2626 | cancel_work_sync(&wacom->wireless_work); |
2577 | cancel_work_sync(&wacom->battery_work); | 2627 | cancel_work_sync(&wacom->battery_work); |
2578 | cancel_work_sync(&wacom->remote_work); | 2628 | cancel_work_sync(&wacom->remote_work); |
2629 | cancel_work_sync(&wacom->mode_change_work); | ||
2579 | if (hdev->bus == BUS_BLUETOOTH) | 2630 | if (hdev->bus == BUS_BLUETOOTH) |
2580 | device_remove_file(&hdev->dev, &dev_attr_speed); | 2631 | device_remove_file(&hdev->dev, &dev_attr_speed); |
2581 | 2632 | ||
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c68ac65db7ff..4b225fb19a16 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -773,131 +773,6 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
773 | return 0; | 773 | return 0; |
774 | } | 774 | } |
775 | 775 | ||
776 | static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) | ||
777 | { | ||
778 | unsigned char *data = wacom_wac->data; | ||
779 | struct input_dev *input; | ||
780 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
781 | struct wacom_remote *remote = wacom->remote; | ||
782 | int bat_charging, bat_percent, touch_ring_mode; | ||
783 | __u32 serial; | ||
784 | int i, index = -1; | ||
785 | unsigned long flags; | ||
786 | |||
787 | if (data[0] != WACOM_REPORT_REMOTE) { | ||
788 | hid_dbg(wacom->hdev, "%s: received unknown report #%d", | ||
789 | __func__, data[0]); | ||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | serial = data[3] + (data[4] << 8) + (data[5] << 16); | ||
794 | wacom_wac->id[0] = PAD_DEVICE_ID; | ||
795 | |||
796 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
797 | |||
798 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
799 | if (remote->remotes[i].serial == serial) { | ||
800 | index = i; | ||
801 | break; | ||
802 | } | ||
803 | } | ||
804 | |||
805 | if (index < 0 || !remote->remotes[index].registered) | ||
806 | goto out; | ||
807 | |||
808 | input = remote->remotes[index].input; | ||
809 | |||
810 | input_report_key(input, BTN_0, (data[9] & 0x01)); | ||
811 | input_report_key(input, BTN_1, (data[9] & 0x02)); | ||
812 | input_report_key(input, BTN_2, (data[9] & 0x04)); | ||
813 | input_report_key(input, BTN_3, (data[9] & 0x08)); | ||
814 | input_report_key(input, BTN_4, (data[9] & 0x10)); | ||
815 | input_report_key(input, BTN_5, (data[9] & 0x20)); | ||
816 | input_report_key(input, BTN_6, (data[9] & 0x40)); | ||
817 | input_report_key(input, BTN_7, (data[9] & 0x80)); | ||
818 | |||
819 | input_report_key(input, BTN_8, (data[10] & 0x01)); | ||
820 | input_report_key(input, BTN_9, (data[10] & 0x02)); | ||
821 | input_report_key(input, BTN_A, (data[10] & 0x04)); | ||
822 | input_report_key(input, BTN_B, (data[10] & 0x08)); | ||
823 | input_report_key(input, BTN_C, (data[10] & 0x10)); | ||
824 | input_report_key(input, BTN_X, (data[10] & 0x20)); | ||
825 | input_report_key(input, BTN_Y, (data[10] & 0x40)); | ||
826 | input_report_key(input, BTN_Z, (data[10] & 0x80)); | ||
827 | |||
828 | input_report_key(input, BTN_BASE, (data[11] & 0x01)); | ||
829 | input_report_key(input, BTN_BASE2, (data[11] & 0x02)); | ||
830 | |||
831 | if (data[12] & 0x80) | ||
832 | input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); | ||
833 | else | ||
834 | input_report_abs(input, ABS_WHEEL, 0); | ||
835 | |||
836 | bat_percent = data[7] & 0x7f; | ||
837 | bat_charging = !!(data[7] & 0x80); | ||
838 | |||
839 | if (data[9] | data[10] | (data[11] & 0x03) | data[12]) | ||
840 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
841 | else | ||
842 | input_report_abs(input, ABS_MISC, 0); | ||
843 | |||
844 | input_event(input, EV_MSC, MSC_SERIAL, serial); | ||
845 | |||
846 | input_sync(input); | ||
847 | |||
848 | /*Which mode select (LED light) is currently on?*/ | ||
849 | touch_ring_mode = (data[11] & 0xC0) >> 6; | ||
850 | |||
851 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
852 | if (remote->remotes[i].serial == serial) | ||
853 | wacom->led.groups[i].select = touch_ring_mode; | ||
854 | } | ||
855 | |||
856 | __wacom_notify_battery(&remote->remotes[index].battery, bat_percent, | ||
857 | bat_charging, 1, bat_charging); | ||
858 | |||
859 | out: | ||
860 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) | ||
865 | { | ||
866 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
867 | unsigned char *data = wacom_wac->data; | ||
868 | struct wacom_remote *remote = wacom->remote; | ||
869 | struct wacom_remote_data remote_data; | ||
870 | unsigned long flags; | ||
871 | int i, ret; | ||
872 | |||
873 | if (data[0] != WACOM_REPORT_DEVICE_LIST) | ||
874 | return; | ||
875 | |||
876 | memset(&remote_data, 0, sizeof(struct wacom_remote_data)); | ||
877 | |||
878 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
879 | int j = i * 6; | ||
880 | int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4]; | ||
881 | bool connected = data[j+2]; | ||
882 | |||
883 | remote_data.remote[i].serial = serial; | ||
884 | remote_data.remote[i].connected = connected; | ||
885 | } | ||
886 | |||
887 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
888 | |||
889 | ret = kfifo_in(&remote->remote_fifo, &remote_data, sizeof(remote_data)); | ||
890 | if (ret != sizeof(remote_data)) { | ||
891 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
892 | hid_err(wacom->hdev, "Can't queue Remote status event.\n"); | ||
893 | return; | ||
894 | } | ||
895 | |||
896 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
897 | |||
898 | wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE); | ||
899 | } | ||
900 | |||
901 | static inline bool report_touch_events(struct wacom_wac *wacom) | 776 | static inline bool report_touch_events(struct wacom_wac *wacom) |
902 | { | 777 | { |
903 | return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1); | 778 | return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1); |
@@ -1116,6 +991,131 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
1116 | return 0; | 991 | return 0; |
1117 | } | 992 | } |
1118 | 993 | ||
994 | static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) | ||
995 | { | ||
996 | unsigned char *data = wacom_wac->data; | ||
997 | struct input_dev *input; | ||
998 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
999 | struct wacom_remote *remote = wacom->remote; | ||
1000 | int bat_charging, bat_percent, touch_ring_mode; | ||
1001 | __u32 serial; | ||
1002 | int i, index = -1; | ||
1003 | unsigned long flags; | ||
1004 | |||
1005 | if (data[0] != WACOM_REPORT_REMOTE) { | ||
1006 | hid_dbg(wacom->hdev, "%s: received unknown report #%d", | ||
1007 | __func__, data[0]); | ||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
1011 | serial = data[3] + (data[4] << 8) + (data[5] << 16); | ||
1012 | wacom_wac->id[0] = PAD_DEVICE_ID; | ||
1013 | |||
1014 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
1015 | |||
1016 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
1017 | if (remote->remotes[i].serial == serial) { | ||
1018 | index = i; | ||
1019 | break; | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | if (index < 0 || !remote->remotes[index].registered) | ||
1024 | goto out; | ||
1025 | |||
1026 | input = remote->remotes[index].input; | ||
1027 | |||
1028 | input_report_key(input, BTN_0, (data[9] & 0x01)); | ||
1029 | input_report_key(input, BTN_1, (data[9] & 0x02)); | ||
1030 | input_report_key(input, BTN_2, (data[9] & 0x04)); | ||
1031 | input_report_key(input, BTN_3, (data[9] & 0x08)); | ||
1032 | input_report_key(input, BTN_4, (data[9] & 0x10)); | ||
1033 | input_report_key(input, BTN_5, (data[9] & 0x20)); | ||
1034 | input_report_key(input, BTN_6, (data[9] & 0x40)); | ||
1035 | input_report_key(input, BTN_7, (data[9] & 0x80)); | ||
1036 | |||
1037 | input_report_key(input, BTN_8, (data[10] & 0x01)); | ||
1038 | input_report_key(input, BTN_9, (data[10] & 0x02)); | ||
1039 | input_report_key(input, BTN_A, (data[10] & 0x04)); | ||
1040 | input_report_key(input, BTN_B, (data[10] & 0x08)); | ||
1041 | input_report_key(input, BTN_C, (data[10] & 0x10)); | ||
1042 | input_report_key(input, BTN_X, (data[10] & 0x20)); | ||
1043 | input_report_key(input, BTN_Y, (data[10] & 0x40)); | ||
1044 | input_report_key(input, BTN_Z, (data[10] & 0x80)); | ||
1045 | |||
1046 | input_report_key(input, BTN_BASE, (data[11] & 0x01)); | ||
1047 | input_report_key(input, BTN_BASE2, (data[11] & 0x02)); | ||
1048 | |||
1049 | if (data[12] & 0x80) | ||
1050 | input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); | ||
1051 | else | ||
1052 | input_report_abs(input, ABS_WHEEL, 0); | ||
1053 | |||
1054 | bat_percent = data[7] & 0x7f; | ||
1055 | bat_charging = !!(data[7] & 0x80); | ||
1056 | |||
1057 | if (data[9] | data[10] | (data[11] & 0x03) | data[12]) | ||
1058 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
1059 | else | ||
1060 | input_report_abs(input, ABS_MISC, 0); | ||
1061 | |||
1062 | input_event(input, EV_MSC, MSC_SERIAL, serial); | ||
1063 | |||
1064 | input_sync(input); | ||
1065 | |||
1066 | /*Which mode select (LED light) is currently on?*/ | ||
1067 | touch_ring_mode = (data[11] & 0xC0) >> 6; | ||
1068 | |||
1069 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
1070 | if (remote->remotes[i].serial == serial) | ||
1071 | wacom->led.groups[i].select = touch_ring_mode; | ||
1072 | } | ||
1073 | |||
1074 | __wacom_notify_battery(&remote->remotes[index].battery, bat_percent, | ||
1075 | bat_charging, 1, bat_charging); | ||
1076 | |||
1077 | out: | ||
1078 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
1079 | return 0; | ||
1080 | } | ||
1081 | |||
1082 | static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) | ||
1083 | { | ||
1084 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
1085 | unsigned char *data = wacom_wac->data; | ||
1086 | struct wacom_remote *remote = wacom->remote; | ||
1087 | struct wacom_remote_data remote_data; | ||
1088 | unsigned long flags; | ||
1089 | int i, ret; | ||
1090 | |||
1091 | if (data[0] != WACOM_REPORT_DEVICE_LIST) | ||
1092 | return; | ||
1093 | |||
1094 | memset(&remote_data, 0, sizeof(struct wacom_remote_data)); | ||
1095 | |||
1096 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
1097 | int j = i * 6; | ||
1098 | int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4]; | ||
1099 | bool connected = data[j+2]; | ||
1100 | |||
1101 | remote_data.remote[i].serial = serial; | ||
1102 | remote_data.remote[i].connected = connected; | ||
1103 | } | ||
1104 | |||
1105 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
1106 | |||
1107 | ret = kfifo_in(&remote->remote_fifo, &remote_data, sizeof(remote_data)); | ||
1108 | if (ret != sizeof(remote_data)) { | ||
1109 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
1110 | hid_err(wacom->hdev, "Can't queue Remote status event.\n"); | ||
1111 | return; | ||
1112 | } | ||
1113 | |||
1114 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
1115 | |||
1116 | wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE); | ||
1117 | } | ||
1118 | |||
1119 | static int int_dist(int x1, int y1, int x2, int y2) | 1119 | static int int_dist(int x1, int y1, int x2, int y2) |
1120 | { | 1120 | { |
1121 | int x = x2 - x1; | 1121 | int x = x2 - x1; |
@@ -1739,6 +1739,7 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, | |||
1739 | features->device_type |= WACOM_DEVICETYPE_PAD; | 1739 | features->device_type |= WACOM_DEVICETYPE_PAD; |
1740 | break; | 1740 | break; |
1741 | case WACOM_HID_WD_TOUCHONOFF: | 1741 | case WACOM_HID_WD_TOUCHONOFF: |
1742 | case WACOM_HID_WD_MUTE_DEVICE: | ||
1742 | /* | 1743 | /* |
1743 | * This usage, which is used to mute touch events, comes | 1744 | * This usage, which is used to mute touch events, comes |
1744 | * from the pad packet, but is reported on the touch | 1745 | * from the pad packet, but is reported on the touch |
@@ -1768,6 +1769,26 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, | |||
1768 | wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); | 1769 | wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); |
1769 | features->device_type |= WACOM_DEVICETYPE_PAD; | 1770 | features->device_type |= WACOM_DEVICETYPE_PAD; |
1770 | break; | 1771 | break; |
1772 | case WACOM_HID_WD_BUTTONCONFIG: | ||
1773 | wacom_map_usage(input, usage, field, EV_KEY, KEY_BUTTONCONFIG, 0); | ||
1774 | features->device_type |= WACOM_DEVICETYPE_PAD; | ||
1775 | break; | ||
1776 | case WACOM_HID_WD_ONSCREEN_KEYBOARD: | ||
1777 | wacom_map_usage(input, usage, field, EV_KEY, KEY_ONSCREEN_KEYBOARD, 0); | ||
1778 | features->device_type |= WACOM_DEVICETYPE_PAD; | ||
1779 | break; | ||
1780 | case WACOM_HID_WD_CONTROLPANEL: | ||
1781 | wacom_map_usage(input, usage, field, EV_KEY, KEY_CONTROLPANEL, 0); | ||
1782 | features->device_type |= WACOM_DEVICETYPE_PAD; | ||
1783 | break; | ||
1784 | case WACOM_HID_WD_MODE_CHANGE: | ||
1785 | /* do not overwrite previous data */ | ||
1786 | if (!wacom_wac->has_mode_change) { | ||
1787 | wacom_wac->has_mode_change = true; | ||
1788 | wacom_wac->is_direct_mode = true; | ||
1789 | } | ||
1790 | features->device_type |= WACOM_DEVICETYPE_PAD; | ||
1791 | break; | ||
1771 | } | 1792 | } |
1772 | 1793 | ||
1773 | switch (equivalent_usage & 0xfffffff0) { | 1794 | switch (equivalent_usage & 0xfffffff0) { |
@@ -1811,12 +1832,13 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
1811 | struct wacom_features *features = &wacom_wac->features; | 1832 | struct wacom_features *features = &wacom_wac->features; |
1812 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); | 1833 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); |
1813 | int i; | 1834 | int i; |
1835 | bool is_touch_on = value; | ||
1814 | 1836 | ||
1815 | /* | 1837 | /* |
1816 | * Avoid reporting this event and setting inrange_state if this usage | 1838 | * Avoid reporting this event and setting inrange_state if this usage |
1817 | * hasn't been mapped. | 1839 | * hasn't been mapped. |
1818 | */ | 1840 | */ |
1819 | if (!usage->type) | 1841 | if (!usage->type && equivalent_usage != WACOM_HID_WD_MODE_CHANGE) |
1820 | return; | 1842 | return; |
1821 | 1843 | ||
1822 | if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) { | 1844 | if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) { |
@@ -1830,14 +1852,28 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
1830 | input_event(input, usage->type, usage->code, 0); | 1852 | input_event(input, usage->type, usage->code, 0); |
1831 | break; | 1853 | break; |
1832 | 1854 | ||
1855 | case WACOM_HID_WD_MUTE_DEVICE: | ||
1856 | if (wacom_wac->shared->touch_input && value) { | ||
1857 | wacom_wac->shared->is_touch_on = !wacom_wac->shared->is_touch_on; | ||
1858 | is_touch_on = wacom_wac->shared->is_touch_on; | ||
1859 | } | ||
1860 | |||
1861 | /* fall through*/ | ||
1833 | case WACOM_HID_WD_TOUCHONOFF: | 1862 | case WACOM_HID_WD_TOUCHONOFF: |
1834 | if (wacom_wac->shared->touch_input) { | 1863 | if (wacom_wac->shared->touch_input) { |
1835 | input_report_switch(wacom_wac->shared->touch_input, | 1864 | input_report_switch(wacom_wac->shared->touch_input, |
1836 | SW_MUTE_DEVICE, !value); | 1865 | SW_MUTE_DEVICE, !is_touch_on); |
1837 | input_sync(wacom_wac->shared->touch_input); | 1866 | input_sync(wacom_wac->shared->touch_input); |
1838 | } | 1867 | } |
1839 | break; | 1868 | break; |
1840 | 1869 | ||
1870 | case WACOM_HID_WD_MODE_CHANGE: | ||
1871 | if (wacom_wac->is_direct_mode != value) { | ||
1872 | wacom_wac->is_direct_mode = value; | ||
1873 | wacom_schedule_work(&wacom->wacom_wac, WACOM_WORKER_MODE_CHANGE); | ||
1874 | } | ||
1875 | break; | ||
1876 | |||
1841 | case WACOM_HID_WD_BUTTONCENTER: | 1877 | case WACOM_HID_WD_BUTTONCENTER: |
1842 | for (i = 0; i < wacom->led.count; i++) | 1878 | for (i = 0; i < wacom->led.count; i++) |
1843 | wacom_update_led(wacom, features->numbered_buttons, | 1879 | wacom_update_led(wacom, features->numbered_buttons, |
@@ -1845,6 +1881,8 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
1845 | /* fall through*/ | 1881 | /* fall through*/ |
1846 | default: | 1882 | default: |
1847 | input_event(input, usage->type, usage->code, value); | 1883 | input_event(input, usage->type, usage->code, value); |
1884 | if (value) | ||
1885 | wacom_wac->hid_data.pad_input_event_flag = true; | ||
1848 | break; | 1886 | break; |
1849 | } | 1887 | } |
1850 | } | 1888 | } |
@@ -1885,9 +1923,12 @@ static void wacom_wac_pad_report(struct hid_device *hdev, | |||
1885 | bool active = wacom_wac->hid_data.inrange_state != 0; | 1923 | bool active = wacom_wac->hid_data.inrange_state != 0; |
1886 | 1924 | ||
1887 | /* report prox for expresskey events */ | 1925 | /* report prox for expresskey events */ |
1888 | if (wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) { | 1926 | if ((wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) && |
1927 | wacom_wac->hid_data.pad_input_event_flag) { | ||
1889 | input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); | 1928 | input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); |
1890 | input_sync(input); | 1929 | input_sync(input); |
1930 | if (!active) | ||
1931 | wacom_wac->hid_data.pad_input_event_flag = false; | ||
1891 | } | 1932 | } |
1892 | 1933 | ||
1893 | } | 1934 | } |
@@ -2197,6 +2238,13 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, | |||
2197 | bool prox = hid_data->tipswitch && | 2238 | bool prox = hid_data->tipswitch && |
2198 | report_touch_events(wacom_wac); | 2239 | report_touch_events(wacom_wac); |
2199 | 2240 | ||
2241 | if (wacom_wac->shared->has_mute_touch_switch && | ||
2242 | !wacom_wac->shared->is_touch_on) { | ||
2243 | if (!wacom_wac->shared->touch_down) | ||
2244 | return; | ||
2245 | prox = 0; | ||
2246 | } | ||
2247 | |||
2200 | wacom_wac->hid_data.num_received++; | 2248 | wacom_wac->hid_data.num_received++; |
2201 | if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected) | 2249 | if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected) |
2202 | return; | 2250 | return; |
@@ -4127,7 +4175,7 @@ static const struct wacom_features wacom_features_0x300 = | |||
4127 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 4175 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
4128 | static const struct wacom_features wacom_features_0x301 = | 4176 | static const struct wacom_features wacom_features_0x301 = |
4129 | { "Wacom Bamboo One M", 21648, 13530, 1023, 31, | 4177 | { "Wacom Bamboo One M", 21648, 13530, 1023, 31, |
4130 | BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 4178 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
4131 | static const struct wacom_features wacom_features_0x302 = | 4179 | static const struct wacom_features wacom_features_0x302 = |
4132 | { "Wacom Intuos PT S", 15200, 9500, 1023, 31, | 4180 | { "Wacom Intuos PT S", 15200, 9500, 1023, 31, |
4133 | INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, | 4181 | INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 857ccee16f38..570d29582b82 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -120,6 +120,11 @@ | |||
120 | #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) | 120 | #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) |
121 | #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) | 121 | #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) |
122 | #define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) | 122 | #define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) |
123 | #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980) | ||
124 | #define WACOM_HID_WD_MUTE_DEVICE (WACOM_HID_UP_WACOMDIGITIZER | 0x0981) | ||
125 | #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) | ||
126 | #define WACOM_HID_WD_ONSCREEN_KEYBOARD (WACOM_HID_UP_WACOMDIGITIZER | 0x0983) | ||
127 | #define WACOM_HID_WD_BUTTONCONFIG (WACOM_HID_UP_WACOMDIGITIZER | 0x0986) | ||
123 | #define WACOM_HID_WD_BUTTONHOME (WACOM_HID_UP_WACOMDIGITIZER | 0x0990) | 128 | #define WACOM_HID_WD_BUTTONHOME (WACOM_HID_UP_WACOMDIGITIZER | 0x0990) |
124 | #define WACOM_HID_WD_BUTTONUP (WACOM_HID_UP_WACOMDIGITIZER | 0x0991) | 129 | #define WACOM_HID_WD_BUTTONUP (WACOM_HID_UP_WACOMDIGITIZER | 0x0991) |
125 | #define WACOM_HID_WD_BUTTONDOWN (WACOM_HID_UP_WACOMDIGITIZER | 0x0992) | 130 | #define WACOM_HID_WD_BUTTONDOWN (WACOM_HID_UP_WACOMDIGITIZER | 0x0992) |
@@ -270,6 +275,7 @@ struct wacom_shared { | |||
270 | struct hid_device *pen; | 275 | struct hid_device *pen; |
271 | struct hid_device *touch; | 276 | struct hid_device *touch; |
272 | bool has_mute_touch_switch; | 277 | bool has_mute_touch_switch; |
278 | bool is_touch_on; | ||
273 | }; | 279 | }; |
274 | 280 | ||
275 | struct hid_data { | 281 | struct hid_data { |
@@ -295,6 +301,7 @@ struct hid_data { | |||
295 | int bat_charging; | 301 | int bat_charging; |
296 | int bat_connected; | 302 | int bat_connected; |
297 | int ps_connected; | 303 | int ps_connected; |
304 | bool pad_input_event_flag; | ||
298 | }; | 305 | }; |
299 | 306 | ||
300 | struct wacom_remote_data { | 307 | struct wacom_remote_data { |
@@ -327,6 +334,9 @@ struct wacom_wac { | |||
327 | int mode_value; | 334 | int mode_value; |
328 | struct hid_data hid_data; | 335 | struct hid_data hid_data; |
329 | bool has_mute_touch_switch; | 336 | bool has_mute_touch_switch; |
337 | bool has_mode_change; | ||
338 | bool is_direct_mode; | ||
339 | |||
330 | }; | 340 | }; |
331 | 341 | ||
332 | #endif | 342 | #endif |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 28f38e2b8f30..5be325d890d9 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -268,6 +268,8 @@ struct hid_item { | |||
268 | #define HID_CP_APPLICATIONLAUNCHBUTTONS 0x000c0180 | 268 | #define HID_CP_APPLICATIONLAUNCHBUTTONS 0x000c0180 |
269 | #define HID_CP_GENERICGUIAPPLICATIONCONTROLS 0x000c0200 | 269 | #define HID_CP_GENERICGUIAPPLICATIONCONTROLS 0x000c0200 |
270 | 270 | ||
271 | #define HID_DG_DEVICECONFIG 0x000d000e | ||
272 | #define HID_DG_DEVICESETTINGS 0x000d0023 | ||
271 | #define HID_DG_CONFIDENCE 0x000d0047 | 273 | #define HID_DG_CONFIDENCE 0x000d0047 |
272 | #define HID_DG_WIDTH 0x000d0048 | 274 | #define HID_DG_WIDTH 0x000d0048 |
273 | #define HID_DG_HEIGHT 0x000d0049 | 275 | #define HID_DG_HEIGHT 0x000d0049 |
@@ -322,7 +324,7 @@ struct hid_item { | |||
322 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 324 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
323 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 | 325 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 |
324 | #define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 | 326 | #define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 |
325 | #define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200 | 327 | /* 0x00000200 reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */ |
326 | #define HID_QUIRK_ALWAYS_POLL 0x00000400 | 328 | #define HID_QUIRK_ALWAYS_POLL 0x00000400 |
327 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 329 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
328 | #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000 | 330 | #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000 |
@@ -541,7 +543,6 @@ struct hid_device { /* device report descriptor */ | |||
541 | struct list_head inputs; /* The list of inputs */ | 543 | struct list_head inputs; /* The list of inputs */ |
542 | void *hiddev; /* The hiddev structure */ | 544 | void *hiddev; /* The hiddev structure */ |
543 | void *hidraw; | 545 | void *hidraw; |
544 | int minor; /* Hiddev minor number */ | ||
545 | 546 | ||
546 | int open; /* is the device open by anyone? */ | 547 | int open; /* is the device open by anyone? */ |
547 | char name[128]; /* Device name */ | 548 | char name[128]; /* Device name */ |
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h index a5dd8148660b..921622222957 100644 --- a/include/linux/hiddev.h +++ b/include/linux/hiddev.h | |||
@@ -32,6 +32,18 @@ | |||
32 | * In-kernel definitions. | 32 | * In-kernel definitions. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | struct hiddev { | ||
36 | int minor; | ||
37 | int exist; | ||
38 | int open; | ||
39 | struct mutex existancelock; | ||
40 | wait_queue_head_t wait; | ||
41 | struct hid_device *hid; | ||
42 | struct list_head list; | ||
43 | spinlock_t list_lock; | ||
44 | bool initialized; | ||
45 | }; | ||
46 | |||
35 | struct hid_device; | 47 | struct hid_device; |
36 | struct hid_usage; | 48 | struct hid_usage; |
37 | struct hid_field; | 49 | struct hid_field; |
diff --git a/include/linux/i2c/i2c-hid.h b/include/linux/i2c/i2c-hid.h index 7aa901d92058..1fb088239d12 100644 --- a/include/linux/i2c/i2c-hid.h +++ b/include/linux/i2c/i2c-hid.h | |||
@@ -14,9 +14,13 @@ | |||
14 | 14 | ||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | 16 | ||
17 | struct regulator; | ||
18 | |||
17 | /** | 19 | /** |
18 | * struct i2chid_platform_data - used by hid over i2c implementation. | 20 | * struct i2chid_platform_data - used by hid over i2c implementation. |
19 | * @hid_descriptor_address: i2c register where the HID descriptor is stored. | 21 | * @hid_descriptor_address: i2c register where the HID descriptor is stored. |
22 | * @supply: regulator for powering on the device. | ||
23 | * @post_power_delay_ms: delay after powering on before device is usable. | ||
20 | * | 24 | * |
21 | * Note that it is the responsibility of the platform driver (or the acpi 5.0 | 25 | * Note that it is the responsibility of the platform driver (or the acpi 5.0 |
22 | * driver, or the flattened device tree) to setup the irq related to the gpio in | 26 | * driver, or the flattened device tree) to setup the irq related to the gpio in |
@@ -31,6 +35,8 @@ | |||
31 | */ | 35 | */ |
32 | struct i2c_hid_platform_data { | 36 | struct i2c_hid_platform_data { |
33 | u16 hid_descriptor_address; | 37 | u16 hid_descriptor_address; |
38 | struct regulator *supply; | ||
39 | int post_power_delay_ms; | ||
34 | }; | 40 | }; |
35 | 41 | ||
36 | #endif /* __LINUX_I2C_HID_H */ | 42 | #endif /* __LINUX_I2C_HID_H */ |
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 3af60ee69053..f5a8d96e1e09 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h | |||
@@ -641,6 +641,7 @@ | |||
641 | * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) | 641 | * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) |
642 | */ | 642 | */ |
643 | #define KEY_DATA 0x277 | 643 | #define KEY_DATA 0x277 |
644 | #define KEY_ONSCREEN_KEYBOARD 0x278 | ||
644 | 645 | ||
645 | #define BTN_TRIGGER_HAPPY 0x2c0 | 646 | #define BTN_TRIGGER_HAPPY 0x2c0 |
646 | #define BTN_TRIGGER_HAPPY1 0x2c0 | 647 | #define BTN_TRIGGER_HAPPY1 0x2c0 |
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index e794f7bee22f..f561c0eb7d63 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h | |||
@@ -61,9 +61,14 @@ struct input_id { | |||
61 | * Note that input core does not clamp reported values to the | 61 | * Note that input core does not clamp reported values to the |
62 | * [minimum, maximum] limits, such task is left to userspace. | 62 | * [minimum, maximum] limits, such task is left to userspace. |
63 | * | 63 | * |
64 | * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in | 64 | * The default resolution for main axes (ABS_X, ABS_Y, ABS_Z) |
65 | * units per millimeter (units/mm), resolution for rotational axes | 65 | * is reported in units per millimeter (units/mm), resolution |
66 | * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian. | 66 | * for rotational axes (ABS_RX, ABS_RY, ABS_RZ) is reported |
67 | * in units per radian. | ||
68 | * When INPUT_PROP_ACCELEROMETER is set the resolution changes. | ||
69 | * The main axes (ABS_X, ABS_Y, ABS_Z) are then reported in | ||
70 | * in units per g (units/g) and in units per degree per second | ||
71 | * (units/deg/s) for rotational axes (ABS_RX, ABS_RY, ABS_RZ). | ||
67 | */ | 72 | */ |
68 | struct input_absinfo { | 73 | struct input_absinfo { |
69 | __s32 value; | 74 | __s32 value; |