diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-01 21:39:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-01 21:39:09 -0400 |
commit | 851328feb8c1d4130d3a0acb004e474168702d6d (patch) | |
tree | d8518e8b4ba07419508b365f5e01484fee12ac60 | |
parent | 2d678b68e842e5b6fc46fc6914f7b7144bb2c23d (diff) | |
parent | f212bd95a9f62b7929c59b16e1d3bbde2fb4081d (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
"to receive patches queued for 4.3 merge window in HID tree. Highlights:
- a lot of improvements (regarding supported features and devices) to
Wacom driver, from Aaron Skomra and Jason Gerecke
- a lot of functional fixes and support for large I2C transfer to
cp2112 driver, from Ellen Wang
- HW support improvements to RMI driver, from Andrew Duggan
- quite some small fixes and device ID additions all over the place"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (44 commits)
HID: wacom: wacom_setup_numbered_buttons is local to wacom_wac
HID: wacom: Add support for Express Key Remote.
HID: wacom: Set button bits based on a new numbered_buttons
HID: quirks: add QUIRK_NOGET for an other TPV touchscreen
HID: usbhid: Fix the check for HID_RESET_PENDING in hid_io_error
HID: i2c-hid: Only disable irq wake if it was successfully enabled during suspend
HID: wacom: Use tablet-provided touch height/width values for INTUOSHT
HID: gembird: add new driver to fix Gembird JPD-DualForce 2
HID: lenovo: Hide middle-button press until release
HID: lenovo: Add missing return-value check
HID: lenovo: Use constants for axes names
HID: wacom: Simplify 'wacom_pl_irq'
HID: wacom: Do not repeatedly attempt to set device mode on error
HID: wacom: Do not repeatedly attempt to set device mode on error
HID: wacom: Remove WACOM_QUIRK_NO_INPUT
HID: wacom: Replace WACOM_QUIRK_MONITOR with WACOM_DEVICETYPE_WL_MONITOR
HID: wacom: Use calculated pkglen for wireless touch interface
HID: sony: Fix DS4 controller reporting rate issues
HID: chicony: Add support for Acer Aspire Switch 12
HID: hid-lg: Add USBID for Logitech G29 Wheel
...
-rw-r--r-- | Documentation/ABI/testing/sysfs-driver-wacom | 19 | ||||
-rw-r--r-- | drivers/hid/Kconfig | 7 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-chicony.c | 26 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 29 | ||||
-rw-r--r-- | drivers/hid/hid-cp2112.c | 107 | ||||
-rw-r--r-- | drivers/hid/hid-gembird.c | 116 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 20 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 5 | ||||
-rw-r--r-- | drivers/hid/hid-lenovo.c | 59 | ||||
-rw-r--r-- | drivers/hid/hid-lg.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-microsoft.c | 6 | ||||
-rw-r--r-- | drivers/hid/hid-multitouch.c | 8 | ||||
-rw-r--r-- | drivers/hid/hid-picolcd_backlight.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-picolcd_cir.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-picolcd_lcd.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-rmi.c | 163 | ||||
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 22 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 28 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 5 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 6 | ||||
-rw-r--r-- | drivers/hid/wacom.h | 7 | ||||
-rw-r--r-- | drivers/hid/wacom_sys.c | 285 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 504 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 15 |
26 files changed, 1144 insertions, 308 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-wacom b/Documentation/ABI/testing/sysfs-driver-wacom index c4f0fed64a6e..dca429340772 100644 --- a/Documentation/ABI/testing/sysfs-driver-wacom +++ b/Documentation/ABI/testing/sysfs-driver-wacom | |||
@@ -77,3 +77,22 @@ Description: | |||
77 | The format is also scrambled, like in the USB mode, and it can | 77 | The format is also scrambled, like in the USB mode, and it can |
78 | be summarized by converting 76543210 into GECA6420. | 78 | be summarized by converting 76543210 into GECA6420. |
79 | HGFEDCBA HFDB7531 | 79 | HGFEDCBA HFDB7531 |
80 | |||
81 | What: /sys/bus/hid/devices/<bus>:<vid>:<pid>.<n>/wacom_remote/unpair_remote | ||
82 | Date: July 2015 | ||
83 | Contact: linux-input@vger.kernel.org | ||
84 | Description: | ||
85 | Writing the character sequence '*' followed by a newline to | ||
86 | this file will delete all of the current pairings on the | ||
87 | device. Other character sequences are reserved. This file is | ||
88 | write only. | ||
89 | |||
90 | What: /sys/bus/hid/devices/<bus>:<vid>:<pid>.<n>/wacom_remote/<serial_number>/remote_mode | ||
91 | Date: July 2015 | ||
92 | Contact: linux-input@vger.kernel.org | ||
93 | Description: | ||
94 | Reading from this file reports the mode status of the | ||
95 | remote as indicated by the LED lights on the device. If no | ||
96 | reports have been received from the paired device, reading | ||
97 | from this file will report '-1'. The mode is read-only | ||
98 | and cannot be set through the driver. | ||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index cc4c6649d195..6ab51ae3c39d 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -251,6 +251,12 @@ config HID_EZKEY | |||
251 | ---help--- | 251 | ---help--- |
252 | Support for Ezkey BTC 8193 keyboard. | 252 | Support for Ezkey BTC 8193 keyboard. |
253 | 253 | ||
254 | config HID_GEMBIRD | ||
255 | tristate "Gembird Joypad" | ||
256 | depends on HID | ||
257 | ---help--- | ||
258 | Support for Gembird JPD-DualForce 2. | ||
259 | |||
254 | config HID_HOLTEK | 260 | config HID_HOLTEK |
255 | tristate "Holtek HID devices" | 261 | tristate "Holtek HID devices" |
256 | depends on USB_HID | 262 | depends on USB_HID |
@@ -480,6 +486,7 @@ config HID_MULTITOUCH | |||
480 | - Atmel panels | 486 | - Atmel panels |
481 | - Cando dual touch panels | 487 | - Cando dual touch panels |
482 | - Chunghwa panels | 488 | - Chunghwa panels |
489 | - CJTouch panels | ||
483 | - CVTouch panels | 490 | - CVTouch panels |
484 | - Cypress TrueTouch panels | 491 | - Cypress TrueTouch panels |
485 | - Elan Microelectronics touch panels | 492 | - Elan Microelectronics touch panels |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 2f8a41dc3cc8..e6441bc7dae4 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -36,6 +36,7 @@ obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o | |||
36 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o | 36 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o |
37 | obj-$(CONFIG_HID_ELO) += hid-elo.o | 37 | obj-$(CONFIG_HID_ELO) += hid-elo.o |
38 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o | 38 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o |
39 | obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o | ||
39 | obj-$(CONFIG_HID_GT683R) += hid-gt683r.o | 40 | obj-$(CONFIG_HID_GT683R) += hid-gt683r.o |
40 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | 41 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o |
41 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o | 42 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o |
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index b613d5a79684..bc3cec199fee 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/usb.h> | ||
23 | 24 | ||
24 | #include "hid-ids.h" | 25 | #include "hid-ids.h" |
25 | 26 | ||
@@ -57,10 +58,34 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
57 | return 1; | 58 | return 1; |
58 | } | 59 | } |
59 | 60 | ||
61 | static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
62 | unsigned int *rsize) | ||
63 | { | ||
64 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
65 | |||
66 | if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { | ||
67 | /* Change usage maximum and logical maximum from 0x7fff to | ||
68 | * 0x2fff, so they don't exceed HID_MAX_USAGES */ | ||
69 | switch (hdev->product) { | ||
70 | case USB_DEVICE_ID_CHICONY_ACER_SWITCH12: | ||
71 | if (*rsize >= 128 && rdesc[64] == 0xff && rdesc[65] == 0x7f | ||
72 | && rdesc[69] == 0xff && rdesc[70] == 0x7f) { | ||
73 | hid_info(hdev, "Fixing up report descriptor\n"); | ||
74 | rdesc[65] = rdesc[70] = 0x2f; | ||
75 | } | ||
76 | break; | ||
77 | } | ||
78 | |||
79 | } | ||
80 | return rdesc; | ||
81 | } | ||
82 | |||
83 | |||
60 | static const struct hid_device_id ch_devices[] = { | 84 | static const struct hid_device_id ch_devices[] = { |
61 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, | 85 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, |
62 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, | 86 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, |
63 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, | 87 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, |
88 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, | ||
64 | { } | 89 | { } |
65 | }; | 90 | }; |
66 | MODULE_DEVICE_TABLE(hid, ch_devices); | 91 | MODULE_DEVICE_TABLE(hid, ch_devices); |
@@ -68,6 +93,7 @@ MODULE_DEVICE_TABLE(hid, ch_devices); | |||
68 | static struct hid_driver ch_driver = { | 93 | static struct hid_driver ch_driver = { |
69 | .name = "chicony", | 94 | .name = "chicony", |
70 | .id_table = ch_devices, | 95 | .id_table = ch_devices, |
96 | .report_fixup = ch_switch12_report_fixup, | ||
71 | .input_mapping = ch_input_mapping, | 97 | .input_mapping = ch_input_mapping, |
72 | }; | 98 | }; |
73 | module_hid_driver(ch_driver); | 99 | module_hid_driver(ch_driver); |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e6fce23b121a..bcd914a63af2 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -427,6 +427,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) | |||
427 | { | 427 | { |
428 | __u32 data; | 428 | __u32 data; |
429 | unsigned n; | 429 | unsigned n; |
430 | __u32 count; | ||
430 | 431 | ||
431 | data = item_udata(item); | 432 | data = item_udata(item); |
432 | 433 | ||
@@ -490,6 +491,24 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) | |||
490 | if (item->size <= 2) | 491 | if (item->size <= 2) |
491 | data = (parser->global.usage_page << 16) + data; | 492 | data = (parser->global.usage_page << 16) + data; |
492 | 493 | ||
494 | count = data - parser->local.usage_minimum; | ||
495 | if (count + parser->local.usage_index >= HID_MAX_USAGES) { | ||
496 | /* | ||
497 | * We do not warn if the name is not set, we are | ||
498 | * actually pre-scanning the device. | ||
499 | */ | ||
500 | if (dev_name(&parser->device->dev)) | ||
501 | hid_warn(parser->device, | ||
502 | "ignoring exceeding usage max\n"); | ||
503 | data = HID_MAX_USAGES - parser->local.usage_index + | ||
504 | parser->local.usage_minimum - 1; | ||
505 | if (data <= 0) { | ||
506 | hid_err(parser->device, | ||
507 | "no more usage index available\n"); | ||
508 | return -1; | ||
509 | } | ||
510 | } | ||
511 | |||
493 | for (n = parser->local.usage_minimum; n <= data; n++) | 512 | for (n = parser->local.usage_minimum; n <= data; n++) |
494 | if (hid_add_usage(parser, n)) { | 513 | if (hid_add_usage(parser, n)) { |
495 | dbg_hid("hid_add_usage failed\n"); | 514 | dbg_hid("hid_add_usage failed\n"); |
@@ -705,8 +724,9 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) | |||
705 | hid->group = HID_GROUP_SENSOR_HUB; | 724 | hid->group = HID_GROUP_SENSOR_HUB; |
706 | 725 | ||
707 | if (hid->vendor == USB_VENDOR_ID_MICROSOFT && | 726 | if (hid->vendor == USB_VENDOR_ID_MICROSOFT && |
708 | (hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 || | 727 | (hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 || |
709 | hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3_JP || | 728 | hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP || |
729 | hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 || | ||
710 | hid->product == USB_DEVICE_ID_MS_POWER_COVER) && | 730 | hid->product == USB_DEVICE_ID_MS_POWER_COVER) && |
711 | hid->group == HID_GROUP_MULTITOUCH) | 731 | hid->group == HID_GROUP_MULTITOUCH) |
712 | hid->group = HID_GROUP_GENERIC; | 732 | hid->group = HID_GROUP_GENERIC; |
@@ -1807,6 +1827,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1807 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, | 1827 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, |
1808 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, | 1828 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, |
1809 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, | 1829 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, |
1830 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, | ||
1810 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, | 1831 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, |
1811 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) }, | 1832 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) }, |
1812 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, | 1833 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, |
@@ -1823,6 +1844,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1823 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1844 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1824 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1845 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
1825 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | 1846 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, |
1847 | { HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD, USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) }, | ||
1826 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | 1848 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, |
1827 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, | 1849 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, |
1828 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1850 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
@@ -1905,8 +1927,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1905 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, | 1927 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, |
1906 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, | 1928 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, |
1907 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, | 1929 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, |
1930 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3) }, | ||
1931 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, | ||
1908 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, | 1932 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, |
1909 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP) }, | ||
1910 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, | 1933 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, |
1911 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1934 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1912 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, | 1935 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, |
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index a2dbbbe0d8d7..7afc3fcc122c 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c | |||
@@ -156,6 +156,7 @@ struct cp2112_device { | |||
156 | wait_queue_head_t wait; | 156 | wait_queue_head_t wait; |
157 | u8 read_data[61]; | 157 | u8 read_data[61]; |
158 | u8 read_length; | 158 | u8 read_length; |
159 | u8 hwversion; | ||
159 | int xfer_status; | 160 | int xfer_status; |
160 | atomic_t read_avail; | 161 | atomic_t read_avail; |
161 | atomic_t xfer_avail; | 162 | atomic_t xfer_avail; |
@@ -446,6 +447,24 @@ static int cp2112_i2c_write_req(void *buf, u8 slave_address, u8 *data, | |||
446 | return data_length + 3; | 447 | return data_length + 3; |
447 | } | 448 | } |
448 | 449 | ||
450 | static int cp2112_i2c_write_read_req(void *buf, u8 slave_address, | ||
451 | u8 *addr, int addr_length, | ||
452 | int read_length) | ||
453 | { | ||
454 | struct cp2112_write_read_req_report *report = buf; | ||
455 | |||
456 | if (read_length < 1 || read_length > 512 || | ||
457 | addr_length > sizeof(report->target_address)) | ||
458 | return -EINVAL; | ||
459 | |||
460 | report->report = CP2112_DATA_WRITE_READ_REQUEST; | ||
461 | report->slave_address = slave_address << 1; | ||
462 | report->length = cpu_to_be16(read_length); | ||
463 | report->target_address_length = addr_length; | ||
464 | memcpy(report->target_address, addr, addr_length); | ||
465 | return addr_length + 5; | ||
466 | } | ||
467 | |||
449 | static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, | 468 | static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, |
450 | int num) | 469 | int num) |
451 | { | 470 | { |
@@ -453,26 +472,46 @@ static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, | |||
453 | struct hid_device *hdev = dev->hdev; | 472 | struct hid_device *hdev = dev->hdev; |
454 | u8 buf[64]; | 473 | u8 buf[64]; |
455 | ssize_t count; | 474 | ssize_t count; |
475 | ssize_t read_length = 0; | ||
476 | u8 *read_buf = NULL; | ||
456 | unsigned int retries; | 477 | unsigned int retries; |
457 | int ret; | 478 | int ret; |
458 | 479 | ||
459 | hid_dbg(hdev, "I2C %d messages\n", num); | 480 | hid_dbg(hdev, "I2C %d messages\n", num); |
460 | 481 | ||
461 | if (num != 1) { | 482 | if (num == 1) { |
483 | if (msgs->flags & I2C_M_RD) { | ||
484 | hid_dbg(hdev, "I2C read %#04x len %d\n", | ||
485 | msgs->addr, msgs->len); | ||
486 | read_length = msgs->len; | ||
487 | read_buf = msgs->buf; | ||
488 | count = cp2112_read_req(buf, msgs->addr, msgs->len); | ||
489 | } else { | ||
490 | hid_dbg(hdev, "I2C write %#04x len %d\n", | ||
491 | msgs->addr, msgs->len); | ||
492 | count = cp2112_i2c_write_req(buf, msgs->addr, | ||
493 | msgs->buf, msgs->len); | ||
494 | } | ||
495 | if (count < 0) | ||
496 | return count; | ||
497 | } else if (dev->hwversion > 1 && /* no repeated start in rev 1 */ | ||
498 | num == 2 && | ||
499 | msgs[0].addr == msgs[1].addr && | ||
500 | !(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD)) { | ||
501 | hid_dbg(hdev, "I2C write-read %#04x wlen %d rlen %d\n", | ||
502 | msgs[0].addr, msgs[0].len, msgs[1].len); | ||
503 | read_length = msgs[1].len; | ||
504 | read_buf = msgs[1].buf; | ||
505 | count = cp2112_i2c_write_read_req(buf, msgs[0].addr, | ||
506 | msgs[0].buf, msgs[0].len, msgs[1].len); | ||
507 | if (count < 0) | ||
508 | return count; | ||
509 | } else { | ||
462 | hid_err(hdev, | 510 | hid_err(hdev, |
463 | "Multi-message I2C transactions not supported\n"); | 511 | "Multi-message I2C transactions not supported\n"); |
464 | return -EOPNOTSUPP; | 512 | return -EOPNOTSUPP; |
465 | } | 513 | } |
466 | 514 | ||
467 | if (msgs->flags & I2C_M_RD) | ||
468 | count = cp2112_read_req(buf, msgs->addr, msgs->len); | ||
469 | else | ||
470 | count = cp2112_i2c_write_req(buf, msgs->addr, msgs->buf, | ||
471 | msgs->len); | ||
472 | |||
473 | if (count < 0) | ||
474 | return count; | ||
475 | |||
476 | ret = hid_hw_power(hdev, PM_HINT_FULLON); | 515 | ret = hid_hw_power(hdev, PM_HINT_FULLON); |
477 | if (ret < 0) { | 516 | if (ret < 0) { |
478 | hid_err(hdev, "power management error: %d\n", ret); | 517 | hid_err(hdev, "power management error: %d\n", ret); |
@@ -508,21 +547,34 @@ static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, | |||
508 | goto power_normal; | 547 | goto power_normal; |
509 | } | 548 | } |
510 | 549 | ||
511 | if (!(msgs->flags & I2C_M_RD)) | 550 | for (count = 0; count < read_length;) { |
512 | goto finish; | 551 | ret = cp2112_read(dev, read_buf + count, read_length - count); |
513 | 552 | if (ret < 0) | |
514 | ret = cp2112_read(dev, msgs->buf, msgs->len); | 553 | goto power_normal; |
515 | if (ret < 0) | 554 | if (ret == 0) { |
516 | goto power_normal; | 555 | hid_err(hdev, "read returned 0\n"); |
517 | if (ret != msgs->len) { | 556 | ret = -EIO; |
518 | hid_warn(hdev, "short read: %d < %d\n", ret, msgs->len); | 557 | goto power_normal; |
519 | ret = -EIO; | 558 | } |
520 | goto power_normal; | 559 | count += ret; |
560 | if (count > read_length) { | ||
561 | /* | ||
562 | * The hardware returned too much data. | ||
563 | * This is mostly harmless because cp2112_read() | ||
564 | * has a limit check so didn't overrun our | ||
565 | * buffer. Nevertheless, we return an error | ||
566 | * because something is seriously wrong and | ||
567 | * it shouldn't go unnoticed. | ||
568 | */ | ||
569 | hid_err(hdev, "long read: %d > %zd\n", | ||
570 | ret, read_length - count + ret); | ||
571 | ret = -EIO; | ||
572 | goto power_normal; | ||
573 | } | ||
521 | } | 574 | } |
522 | 575 | ||
523 | finish: | ||
524 | /* return the number of transferred messages */ | 576 | /* return the number of transferred messages */ |
525 | ret = 1; | 577 | ret = num; |
526 | 578 | ||
527 | power_normal: | 579 | power_normal: |
528 | hid_hw_power(hdev, PM_HINT_NORMAL); | 580 | hid_hw_power(hdev, PM_HINT_NORMAL); |
@@ -537,7 +589,7 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
537 | struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data; | 589 | struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data; |
538 | struct hid_device *hdev = dev->hdev; | 590 | struct hid_device *hdev = dev->hdev; |
539 | u8 buf[64]; | 591 | u8 buf[64]; |
540 | __be16 word; | 592 | __le16 word; |
541 | ssize_t count; | 593 | ssize_t count; |
542 | size_t read_length = 0; | 594 | size_t read_length = 0; |
543 | unsigned int retries; | 595 | unsigned int retries; |
@@ -554,7 +606,7 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
554 | if (I2C_SMBUS_READ == read_write) | 606 | if (I2C_SMBUS_READ == read_write) |
555 | count = cp2112_read_req(buf, addr, read_length); | 607 | count = cp2112_read_req(buf, addr, read_length); |
556 | else | 608 | else |
557 | count = cp2112_write_req(buf, addr, data->byte, NULL, | 609 | count = cp2112_write_req(buf, addr, command, NULL, |
558 | 0); | 610 | 0); |
559 | break; | 611 | break; |
560 | case I2C_SMBUS_BYTE_DATA: | 612 | case I2C_SMBUS_BYTE_DATA: |
@@ -569,7 +621,7 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
569 | break; | 621 | break; |
570 | case I2C_SMBUS_WORD_DATA: | 622 | case I2C_SMBUS_WORD_DATA: |
571 | read_length = 2; | 623 | read_length = 2; |
572 | word = cpu_to_be16(data->word); | 624 | word = cpu_to_le16(data->word); |
573 | 625 | ||
574 | if (I2C_SMBUS_READ == read_write) | 626 | if (I2C_SMBUS_READ == read_write) |
575 | count = cp2112_write_read_req(buf, addr, read_length, | 627 | count = cp2112_write_read_req(buf, addr, read_length, |
@@ -582,7 +634,7 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
582 | size = I2C_SMBUS_WORD_DATA; | 634 | size = I2C_SMBUS_WORD_DATA; |
583 | read_write = I2C_SMBUS_READ; | 635 | read_write = I2C_SMBUS_READ; |
584 | read_length = 2; | 636 | read_length = 2; |
585 | word = cpu_to_be16(data->word); | 637 | word = cpu_to_le16(data->word); |
586 | 638 | ||
587 | count = cp2112_write_read_req(buf, addr, read_length, command, | 639 | count = cp2112_write_read_req(buf, addr, read_length, command, |
588 | (u8 *)&word, 2); | 640 | (u8 *)&word, 2); |
@@ -675,7 +727,7 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
675 | data->byte = buf[0]; | 727 | data->byte = buf[0]; |
676 | break; | 728 | break; |
677 | case I2C_SMBUS_WORD_DATA: | 729 | case I2C_SMBUS_WORD_DATA: |
678 | data->word = be16_to_cpup((__be16 *)buf); | 730 | data->word = le16_to_cpup((__le16 *)buf); |
679 | break; | 731 | break; |
680 | case I2C_SMBUS_BLOCK_DATA: | 732 | case I2C_SMBUS_BLOCK_DATA: |
681 | if (read_length > I2C_SMBUS_BLOCK_MAX) { | 733 | if (read_length > I2C_SMBUS_BLOCK_MAX) { |
@@ -1030,6 +1082,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1030 | dev->adap.dev.parent = &hdev->dev; | 1082 | dev->adap.dev.parent = &hdev->dev; |
1031 | snprintf(dev->adap.name, sizeof(dev->adap.name), | 1083 | snprintf(dev->adap.name, sizeof(dev->adap.name), |
1032 | "CP2112 SMBus Bridge on hiddev%d", hdev->minor); | 1084 | "CP2112 SMBus Bridge on hiddev%d", hdev->minor); |
1085 | dev->hwversion = buf[2]; | ||
1033 | init_waitqueue_head(&dev->wait); | 1086 | init_waitqueue_head(&dev->wait); |
1034 | 1087 | ||
1035 | hid_device_io_start(hdev); | 1088 | hid_device_io_start(hdev); |
diff --git a/drivers/hid/hid-gembird.c b/drivers/hid/hid-gembird.c new file mode 100644 index 000000000000..e55e519f311e --- /dev/null +++ b/drivers/hid/hid-gembird.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * HID driver for Gembird Joypad, "PC Game Controller" | ||
3 | * | ||
4 | * Copyright (c) 2015 Red Hat, Inc | ||
5 | * Copyright (c) 2015 Benjamin Tissoires | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/hid.h> | ||
17 | #include <linux/module.h> | ||
18 | |||
19 | #include "hid-ids.h" | ||
20 | |||
21 | #define GEMBIRD_START_FAULTY_RDESC 8 | ||
22 | |||
23 | static const __u8 gembird_jpd_faulty_rdesc[] = { | ||
24 | 0x75, 0x08, /* Report Size (8) */ | ||
25 | 0x95, 0x05, /* Report Count (5) */ | ||
26 | 0x15, 0x00, /* Logical Minimum (0) */ | ||
27 | 0x26, 0xff, 0x00, /* Logical Maximum (255) */ | ||
28 | 0x35, 0x00, /* Physical Minimum (0) */ | ||
29 | 0x46, 0xff, 0x00, /* Physical Maximum (255) */ | ||
30 | 0x09, 0x30, /* Usage (X) */ | ||
31 | 0x09, 0x31, /* Usage (Y) */ | ||
32 | 0x09, 0x32, /* Usage (Z) */ | ||
33 | 0x09, 0x32, /* Usage (Z) */ | ||
34 | 0x09, 0x35, /* Usage (Rz) */ | ||
35 | 0x81, 0x02, /* Input (Data,Var,Abs) */ | ||
36 | }; | ||
37 | |||
38 | /* | ||
39 | * we fix the report descriptor by: | ||
40 | * - marking the first Z axis as constant (so it is ignored by HID) | ||
41 | * - assign the original second Z to Rx | ||
42 | * - assign the original Rz to Ry | ||
43 | */ | ||
44 | static const __u8 gembird_jpd_fixed_rdesc[] = { | ||
45 | 0x75, 0x08, /* Report Size (8) */ | ||
46 | 0x95, 0x02, /* Report Count (2) */ | ||
47 | 0x15, 0x00, /* Logical Minimum (0) */ | ||
48 | 0x26, 0xff, 0x00, /* Logical Maximum (255) */ | ||
49 | 0x35, 0x00, /* Physical Minimum (0) */ | ||
50 | 0x46, 0xff, 0x00, /* Physical Maximum (255) */ | ||
51 | 0x09, 0x30, /* Usage (X) */ | ||
52 | 0x09, 0x31, /* Usage (Y) */ | ||
53 | 0x81, 0x02, /* Input (Data,Var,Abs) */ | ||
54 | 0x95, 0x01, /* Report Count (1) */ | ||
55 | 0x09, 0x32, /* Usage (Z) */ | ||
56 | 0x81, 0x01, /* Input (Cnst,Arr,Abs) */ | ||
57 | 0x95, 0x02, /* Report Count (2) */ | ||
58 | 0x09, 0x33, /* Usage (Rx) */ | ||
59 | 0x09, 0x34, /* Usage (Ry) */ | ||
60 | 0x81, 0x02, /* Input (Data,Var,Abs) */ | ||
61 | }; | ||
62 | |||
63 | static __u8 *gembird_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
64 | unsigned int *rsize) | ||
65 | { | ||
66 | __u8 *new_rdesc; | ||
67 | /* delta_size is > 0 */ | ||
68 | size_t delta_size = sizeof(gembird_jpd_fixed_rdesc) - | ||
69 | sizeof(gembird_jpd_faulty_rdesc); | ||
70 | size_t new_size = *rsize + delta_size; | ||
71 | |||
72 | if (*rsize >= 31 && !memcmp(&rdesc[GEMBIRD_START_FAULTY_RDESC], | ||
73 | gembird_jpd_faulty_rdesc, | ||
74 | sizeof(gembird_jpd_faulty_rdesc))) { | ||
75 | new_rdesc = devm_kzalloc(&hdev->dev, new_size, GFP_KERNEL); | ||
76 | if (new_rdesc == NULL) | ||
77 | return rdesc; | ||
78 | |||
79 | dev_info(&hdev->dev, | ||
80 | "fixing Gembird JPD-DualForce 2 report descriptor.\n"); | ||
81 | |||
82 | /* start by copying the end of the rdesc */ | ||
83 | memcpy(new_rdesc + delta_size, rdesc, *rsize); | ||
84 | |||
85 | /* add the correct beginning */ | ||
86 | memcpy(new_rdesc, rdesc, GEMBIRD_START_FAULTY_RDESC); | ||
87 | |||
88 | /* replace the faulty part with the fixed one */ | ||
89 | memcpy(new_rdesc + GEMBIRD_START_FAULTY_RDESC, | ||
90 | gembird_jpd_fixed_rdesc, | ||
91 | sizeof(gembird_jpd_fixed_rdesc)); | ||
92 | |||
93 | *rsize = new_size; | ||
94 | rdesc = new_rdesc; | ||
95 | } | ||
96 | |||
97 | return rdesc; | ||
98 | } | ||
99 | |||
100 | static const struct hid_device_id gembird_devices[] = { | ||
101 | { HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD, | ||
102 | USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) }, | ||
103 | { } | ||
104 | }; | ||
105 | MODULE_DEVICE_TABLE(hid, gembird_devices); | ||
106 | |||
107 | static struct hid_driver gembird_driver = { | ||
108 | .name = "gembird", | ||
109 | .id_table = gembird_devices, | ||
110 | .report_fixup = gembird_report_fixup, | ||
111 | }; | ||
112 | module_hid_driver(gembird_driver); | ||
113 | |||
114 | MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); | ||
115 | MODULE_DESCRIPTION("HID Gembird joypad driver"); | ||
116 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b3b225b75d0a..f769208276ae 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -233,12 +233,17 @@ | |||
233 | #define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE 0x1053 | 233 | #define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE 0x1053 |
234 | #define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 | 234 | #define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 |
235 | #define USB_DEVICE_ID_CHICONY_AK1D 0x1125 | 235 | #define USB_DEVICE_ID_CHICONY_AK1D 0x1125 |
236 | #define USB_DEVICE_ID_CHICONY_ACER_SWITCH12 0x1421 | ||
236 | 237 | ||
237 | #define USB_VENDOR_ID_CHUNGHWAT 0x2247 | 238 | #define USB_VENDOR_ID_CHUNGHWAT 0x2247 |
238 | #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 | 239 | #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 |
239 | 240 | ||
240 | #define USB_VENDOR_ID_CIDC 0x1677 | 241 | #define USB_VENDOR_ID_CIDC 0x1677 |
241 | 242 | ||
243 | #define USB_VENDOR_ID_CJTOUCH 0x24b8 | ||
244 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 | ||
245 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 | ||
246 | |||
242 | #define USB_VENDOR_ID_CMEDIA 0x0d8c | 247 | #define USB_VENDOR_ID_CMEDIA 0x0d8c |
243 | #define USB_DEVICE_ID_CM109 0x000e | 248 | #define USB_DEVICE_ID_CM109 0x000e |
244 | 249 | ||
@@ -358,6 +363,9 @@ | |||
358 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 | 363 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 |
359 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 | 364 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 |
360 | 365 | ||
366 | #define USB_VENDOR_ID_GEMBIRD 0x11ff | ||
367 | #define USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2 0x3331 | ||
368 | |||
361 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc | 369 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc |
362 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003 | 370 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003 |
363 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100 | 371 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100 |
@@ -500,6 +508,9 @@ | |||
500 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 | 508 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 |
501 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 | 509 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 |
502 | 510 | ||
511 | #define USB_VENDOR_ID_ITE 0x048d | ||
512 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 | ||
513 | |||
503 | #define USB_VENDOR_ID_JABRA 0x0b0e | 514 | #define USB_VENDOR_ID_JABRA 0x0b0e |
504 | #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 | 515 | #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 |
505 | #define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420 | 516 | #define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420 |
@@ -602,6 +613,7 @@ | |||
602 | #define USB_DEVICE_ID_LOGITECH_DUAL_ACTION 0xc216 | 613 | #define USB_DEVICE_ID_LOGITECH_DUAL_ACTION 0xc216 |
603 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 | 614 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 |
604 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 | 615 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 |
616 | #define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f | ||
605 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 | 617 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 |
606 | #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 | 618 | #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 |
607 | #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 | 619 | #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 |
@@ -666,8 +678,9 @@ | |||
666 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 | 678 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 |
667 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 | 679 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 |
668 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | 680 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
669 | #define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07dc | 681 | #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 0x07dc |
670 | #define USB_DEVICE_ID_MS_TYPE_COVER_3_JP 0x07dd | 682 | #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP 0x07dd |
683 | #define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07de | ||
671 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da | 684 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da |
672 | 685 | ||
673 | #define USB_VENDOR_ID_MOJO 0x8282 | 686 | #define USB_VENDOR_ID_MOJO 0x8282 |
@@ -925,7 +938,8 @@ | |||
925 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 | 938 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 |
926 | 939 | ||
927 | #define USB_VENDOR_ID_TPV 0x25aa | 940 | #define USB_VENDOR_ID_TPV 0x25aa |
928 | #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN 0x8883 | 941 | #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882 0x8882 |
942 | #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883 0x8883 | ||
929 | 943 | ||
930 | #define USB_VENDOR_ID_TURBOX 0x062a | 944 | #define USB_VENDOR_ID_TURBOX 0x062a |
931 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 | 945 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e3c63640df73..53aeaf6252c7 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -1166,8 +1166,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
1166 | 1166 | ||
1167 | input_event(input, usage->type, usage->code, value); | 1167 | input_event(input, usage->type, usage->code, value); |
1168 | 1168 | ||
1169 | if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) | 1169 | if ((field->flags & HID_MAIN_ITEM_RELATIVE) && |
1170 | usage->type == EV_KEY && value) { | ||
1171 | input_sync(input); | ||
1170 | input_event(input, usage->type, usage->code, 0); | 1172 | input_event(input, usage->type, usage->code, 0); |
1173 | } | ||
1171 | } | 1174 | } |
1172 | 1175 | ||
1173 | void hidinput_report_event(struct hid_device *hid, struct hid_report *report) | 1176 | void hidinput_report_event(struct hid_device *hid, struct hid_report *report) |
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 4f59bffd0205..e4bc6cb6d7fa 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c | |||
@@ -37,6 +37,7 @@ struct lenovo_drvdata_tpkbd { | |||
37 | }; | 37 | }; |
38 | 38 | ||
39 | struct lenovo_drvdata_cptkbd { | 39 | struct lenovo_drvdata_cptkbd { |
40 | u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ | ||
40 | bool fn_lock; | 41 | bool fn_lock; |
41 | int sensitivity; | 42 | int sensitivity; |
42 | }; | 43 | }; |
@@ -146,10 +147,10 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, | |||
146 | 147 | ||
147 | switch (usage->hid & HID_USAGE) { | 148 | switch (usage->hid & HID_USAGE) { |
148 | case 0x0000: | 149 | case 0x0000: |
149 | hid_map_usage(hi, usage, bit, max, EV_REL, 0x06); | 150 | hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); |
150 | return 1; | 151 | return 1; |
151 | case 0x0001: | 152 | case 0x0001: |
152 | hid_map_usage(hi, usage, bit, max, EV_REL, 0x08); | 153 | hid_map_usage(hi, usage, bit, max, EV_REL, REL_WHEEL); |
153 | return 1; | 154 | return 1; |
154 | default: | 155 | default: |
155 | return -1; | 156 | return -1; |
@@ -207,9 +208,12 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev) | |||
207 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | 208 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); |
208 | 209 | ||
209 | ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); | 210 | ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); |
210 | ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity); | ||
211 | if (ret) | 211 | if (ret) |
212 | hid_err(hdev, "Fn-lock setting failed: %d\n", ret); | 212 | hid_err(hdev, "Fn-lock setting failed: %d\n", ret); |
213 | |||
214 | ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity); | ||
215 | if (ret) | ||
216 | hid_err(hdev, "Sensitivity setting failed: %d\n", ret); | ||
213 | } | 217 | } |
214 | 218 | ||
215 | static ssize_t attr_fn_lock_show_cptkbd(struct device *dev, | 219 | static ssize_t attr_fn_lock_show_cptkbd(struct device *dev, |
@@ -313,6 +317,53 @@ static int lenovo_raw_event(struct hid_device *hdev, | |||
313 | return 0; | 317 | return 0; |
314 | } | 318 | } |
315 | 319 | ||
320 | static int lenovo_event_cptkbd(struct hid_device *hdev, | ||
321 | struct hid_field *field, struct hid_usage *usage, __s32 value) | ||
322 | { | ||
323 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | ||
324 | |||
325 | /* "wheel" scroll events */ | ||
326 | if (usage->type == EV_REL && (usage->code == REL_WHEEL || | ||
327 | usage->code == REL_HWHEEL)) { | ||
328 | /* Scroll events disable middle-click event */ | ||
329 | cptkbd_data->middlebutton_state = 2; | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /* Middle click events */ | ||
334 | if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { | ||
335 | if (value == 1) { | ||
336 | cptkbd_data->middlebutton_state = 1; | ||
337 | } else if (value == 0) { | ||
338 | if (cptkbd_data->middlebutton_state == 1) { | ||
339 | /* No scrolling inbetween, send middle-click */ | ||
340 | input_event(field->hidinput->input, | ||
341 | EV_KEY, BTN_MIDDLE, 1); | ||
342 | input_sync(field->hidinput->input); | ||
343 | input_event(field->hidinput->input, | ||
344 | EV_KEY, BTN_MIDDLE, 0); | ||
345 | input_sync(field->hidinput->input); | ||
346 | } | ||
347 | cptkbd_data->middlebutton_state = 0; | ||
348 | } | ||
349 | return 1; | ||
350 | } | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int lenovo_event(struct hid_device *hdev, struct hid_field *field, | ||
356 | struct hid_usage *usage, __s32 value) | ||
357 | { | ||
358 | switch (hdev->product) { | ||
359 | case USB_DEVICE_ID_LENOVO_CUSBKBD: | ||
360 | case USB_DEVICE_ID_LENOVO_CBTKBD: | ||
361 | return lenovo_event_cptkbd(hdev, field, usage, value); | ||
362 | default: | ||
363 | return 0; | ||
364 | } | ||
365 | } | ||
366 | |||
316 | static int lenovo_features_set_tpkbd(struct hid_device *hdev) | 367 | static int lenovo_features_set_tpkbd(struct hid_device *hdev) |
317 | { | 368 | { |
318 | struct hid_report *report; | 369 | struct hid_report *report; |
@@ -705,6 +756,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev) | |||
705 | hid_warn(hdev, "Failed to switch middle button: %d\n", ret); | 756 | hid_warn(hdev, "Failed to switch middle button: %d\n", ret); |
706 | 757 | ||
707 | /* Set keyboard settings to known state */ | 758 | /* Set keyboard settings to known state */ |
759 | cptkbd_data->middlebutton_state = 0; | ||
708 | cptkbd_data->fn_lock = true; | 760 | cptkbd_data->fn_lock = true; |
709 | cptkbd_data->sensitivity = 0x05; | 761 | cptkbd_data->sensitivity = 0x05; |
710 | lenovo_features_set_cptkbd(hdev); | 762 | lenovo_features_set_cptkbd(hdev); |
@@ -832,6 +884,7 @@ static struct hid_driver lenovo_driver = { | |||
832 | .probe = lenovo_probe, | 884 | .probe = lenovo_probe, |
833 | .remove = lenovo_remove, | 885 | .remove = lenovo_remove, |
834 | .raw_event = lenovo_raw_event, | 886 | .raw_event = lenovo_raw_event, |
887 | .event = lenovo_event, | ||
835 | .report_fixup = lenovo_report_fixup, | 888 | .report_fixup = lenovo_report_fixup, |
836 | }; | 889 | }; |
837 | module_hid_driver(lenovo_driver); | 890 | module_hid_driver(lenovo_driver); |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 429340d809b5..5332fb7d072a 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
@@ -776,6 +776,8 @@ static const struct hid_device_id lg_devices[] = { | |||
776 | .driver_data = LG_FF }, | 776 | .driver_data = LG_FF }, |
777 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), | 777 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), |
778 | .driver_data = LG_FF }, | 778 | .driver_data = LG_FF }, |
779 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL), | ||
780 | .driver_data = LG_FF4 }, | ||
779 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), | 781 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), |
780 | .driver_data = LG_FF }, | 782 | .driver_data = LG_FF }, |
781 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), | 783 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 32a596f554af..9aa3515090a7 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
@@ -276,9 +276,11 @@ static const struct hid_device_id ms_devices[] = { | |||
276 | .driver_data = MS_NOGET }, | 276 | .driver_data = MS_NOGET }, |
277 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), | 277 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
278 | .driver_data = MS_DUPLICATE_USAGES }, | 278 | .driver_data = MS_DUPLICATE_USAGES }, |
279 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), | 279 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3), |
280 | .driver_data = MS_HIDINPUT }, | ||
281 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP), | ||
280 | .driver_data = MS_HIDINPUT }, | 282 | .driver_data = MS_HIDINPUT }, |
281 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP), | 283 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), |
282 | .driver_data = MS_HIDINPUT }, | 284 | .driver_data = MS_HIDINPUT }, |
283 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), | 285 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), |
284 | .driver_data = MS_HIDINPUT }, | 286 | .driver_data = MS_HIDINPUT }, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 7c811252c1ce..426b2f1a3450 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1145,6 +1145,14 @@ static const struct hid_device_id mt_devices[] = { | |||
1145 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, | 1145 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, |
1146 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | 1146 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, |
1147 | 1147 | ||
1148 | /* CJTouch panels */ | ||
1149 | { .driver_data = MT_CLS_NSMU, | ||
1150 | MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH, | ||
1151 | USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020) }, | ||
1152 | { .driver_data = MT_CLS_NSMU, | ||
1153 | MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH, | ||
1154 | USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040) }, | ||
1155 | |||
1148 | /* CVTouch panels */ | 1156 | /* CVTouch panels */ |
1149 | { .driver_data = MT_CLS_NSMU, | 1157 | { .driver_data = MT_CLS_NSMU, |
1150 | MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, | 1158 | MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, |
diff --git a/drivers/hid/hid-picolcd_backlight.c b/drivers/hid/hid-picolcd_backlight.c index a32c5f86b0b3..808807ad388f 100644 --- a/drivers/hid/hid-picolcd_backlight.c +++ b/drivers/hid/hid-picolcd_backlight.c | |||
@@ -94,8 +94,7 @@ void picolcd_exit_backlight(struct picolcd_data *data) | |||
94 | struct backlight_device *bdev = data->backlight; | 94 | struct backlight_device *bdev = data->backlight; |
95 | 95 | ||
96 | data->backlight = NULL; | 96 | data->backlight = NULL; |
97 | if (bdev) | 97 | backlight_device_unregister(bdev); |
98 | backlight_device_unregister(bdev); | ||
99 | } | 98 | } |
100 | 99 | ||
101 | int picolcd_resume_backlight(struct picolcd_data *data) | 100 | int picolcd_resume_backlight(struct picolcd_data *data) |
diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 045f8ebf16b5..96286510f42e 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c | |||
@@ -145,7 +145,6 @@ void picolcd_exit_cir(struct picolcd_data *data) | |||
145 | struct rc_dev *rdev = data->rc_dev; | 145 | struct rc_dev *rdev = data->rc_dev; |
146 | 146 | ||
147 | data->rc_dev = NULL; | 147 | data->rc_dev = NULL; |
148 | if (rdev) | 148 | rc_unregister_device(rdev); |
149 | rc_unregister_device(rdev); | ||
150 | } | 149 | } |
151 | 150 | ||
diff --git a/drivers/hid/hid-picolcd_lcd.c b/drivers/hid/hid-picolcd_lcd.c index 89821c2da6d7..22dcbe13da89 100644 --- a/drivers/hid/hid-picolcd_lcd.c +++ b/drivers/hid/hid-picolcd_lcd.c | |||
@@ -92,8 +92,7 @@ void picolcd_exit_lcd(struct picolcd_data *data) | |||
92 | struct lcd_device *ldev = data->lcd; | 92 | struct lcd_device *ldev = data->lcd; |
93 | 93 | ||
94 | data->lcd = NULL; | 94 | data->lcd = NULL; |
95 | if (ldev) | 95 | lcd_device_unregister(ldev); |
96 | lcd_device_unregister(ldev); | ||
97 | } | 96 | } |
98 | 97 | ||
99 | int picolcd_resume_lcd(struct picolcd_data *data) | 98 | int picolcd_resume_lcd(struct picolcd_data *data) |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 4cf80bb276dc..2c148129beb2 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
@@ -33,10 +33,21 @@ | |||
33 | #define RMI_READ_DATA_PENDING 1 | 33 | #define RMI_READ_DATA_PENDING 1 |
34 | #define RMI_STARTED 2 | 34 | #define RMI_STARTED 2 |
35 | 35 | ||
36 | #define RMI_SLEEP_NORMAL 0x0 | ||
37 | #define RMI_SLEEP_DEEP_SLEEP 0x1 | ||
38 | |||
36 | /* device flags */ | 39 | /* device flags */ |
37 | #define RMI_DEVICE BIT(0) | 40 | #define RMI_DEVICE BIT(0) |
38 | #define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1) | 41 | #define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1) |
39 | 42 | ||
43 | /* | ||
44 | * retrieve the ctrl registers | ||
45 | * the ctrl register has a size of 20 but a fw bug split it into 16 + 4, | ||
46 | * and there is no way to know if the first 20 bytes are here or not. | ||
47 | * We use only the first 12 bytes, so get only them. | ||
48 | */ | ||
49 | #define RMI_F11_CTRL_REG_COUNT 12 | ||
50 | |||
40 | enum rmi_mode_type { | 51 | enum rmi_mode_type { |
41 | RMI_MODE_OFF = 0, | 52 | RMI_MODE_OFF = 0, |
42 | RMI_MODE_ATTN_REPORTS = 1, | 53 | RMI_MODE_ATTN_REPORTS = 1, |
@@ -113,6 +124,8 @@ struct rmi_data { | |||
113 | unsigned int max_y; | 124 | unsigned int max_y; |
114 | unsigned int x_size_mm; | 125 | unsigned int x_size_mm; |
115 | unsigned int y_size_mm; | 126 | unsigned int y_size_mm; |
127 | bool read_f11_ctrl_regs; | ||
128 | u8 f11_ctrl_regs[RMI_F11_CTRL_REG_COUNT]; | ||
116 | 129 | ||
117 | unsigned int gpio_led_count; | 130 | unsigned int gpio_led_count; |
118 | unsigned int button_count; | 131 | unsigned int button_count; |
@@ -126,6 +139,10 @@ struct rmi_data { | |||
126 | 139 | ||
127 | unsigned long device_flags; | 140 | unsigned long device_flags; |
128 | unsigned long firmware_id; | 141 | unsigned long firmware_id; |
142 | |||
143 | u8 f01_ctrl0; | ||
144 | u8 interrupt_enable_mask; | ||
145 | bool restore_interrupt_mask; | ||
129 | }; | 146 | }; |
130 | 147 | ||
131 | #define RMI_PAGE(addr) (((addr) >> 8) & 0xff) | 148 | #define RMI_PAGE(addr) (((addr) >> 8) & 0xff) |
@@ -346,13 +363,34 @@ static void rmi_f11_process_touch(struct rmi_data *hdata, int slot, | |||
346 | } | 363 | } |
347 | } | 364 | } |
348 | 365 | ||
366 | static int rmi_reset_attn_mode(struct hid_device *hdev) | ||
367 | { | ||
368 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
369 | int ret; | ||
370 | |||
371 | ret = rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); | ||
372 | if (ret) | ||
373 | return ret; | ||
374 | |||
375 | if (data->restore_interrupt_mask) { | ||
376 | ret = rmi_write(hdev, data->f01.control_base_addr + 1, | ||
377 | &data->interrupt_enable_mask); | ||
378 | if (ret) { | ||
379 | hid_err(hdev, "can not write F01 control register\n"); | ||
380 | return ret; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
349 | static void rmi_reset_work(struct work_struct *work) | 387 | static void rmi_reset_work(struct work_struct *work) |
350 | { | 388 | { |
351 | struct rmi_data *hdata = container_of(work, struct rmi_data, | 389 | struct rmi_data *hdata = container_of(work, struct rmi_data, |
352 | reset_work); | 390 | reset_work); |
353 | 391 | ||
354 | /* switch the device to RMI if we receive a generic mouse report */ | 392 | /* switch the device to RMI if we receive a generic mouse report */ |
355 | rmi_set_mode(hdata->hdev, RMI_MODE_ATTN_REPORTS); | 393 | rmi_reset_attn_mode(hdata->hdev); |
356 | } | 394 | } |
357 | 395 | ||
358 | static inline int rmi_schedule_reset(struct hid_device *hdev) | 396 | static inline int rmi_schedule_reset(struct hid_device *hdev) |
@@ -532,14 +570,77 @@ static int rmi_event(struct hid_device *hdev, struct hid_field *field, | |||
532 | } | 570 | } |
533 | 571 | ||
534 | #ifdef CONFIG_PM | 572 | #ifdef CONFIG_PM |
573 | static int rmi_set_sleep_mode(struct hid_device *hdev, int sleep_mode) | ||
574 | { | ||
575 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
576 | int ret; | ||
577 | u8 f01_ctrl0; | ||
578 | |||
579 | f01_ctrl0 = (data->f01_ctrl0 & ~0x3) | sleep_mode; | ||
580 | |||
581 | ret = rmi_write(hdev, data->f01.control_base_addr, | ||
582 | &f01_ctrl0); | ||
583 | if (ret) { | ||
584 | hid_err(hdev, "can not write sleep mode\n"); | ||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static int rmi_suspend(struct hid_device *hdev, pm_message_t message) | ||
592 | { | ||
593 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
594 | int ret; | ||
595 | u8 buf[RMI_F11_CTRL_REG_COUNT]; | ||
596 | |||
597 | ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, | ||
598 | RMI_F11_CTRL_REG_COUNT); | ||
599 | if (ret) | ||
600 | hid_warn(hdev, "can not read F11 control registers\n"); | ||
601 | else | ||
602 | memcpy(data->f11_ctrl_regs, buf, RMI_F11_CTRL_REG_COUNT); | ||
603 | |||
604 | |||
605 | if (!device_may_wakeup(hdev->dev.parent)) | ||
606 | return rmi_set_sleep_mode(hdev, RMI_SLEEP_DEEP_SLEEP); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
535 | static int rmi_post_reset(struct hid_device *hdev) | 611 | static int rmi_post_reset(struct hid_device *hdev) |
536 | { | 612 | { |
537 | return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); | 613 | struct rmi_data *data = hid_get_drvdata(hdev); |
614 | int ret; | ||
615 | |||
616 | ret = rmi_reset_attn_mode(hdev); | ||
617 | if (ret) { | ||
618 | hid_err(hdev, "can not set rmi mode\n"); | ||
619 | return ret; | ||
620 | } | ||
621 | |||
622 | if (data->read_f11_ctrl_regs) { | ||
623 | ret = rmi_write_block(hdev, data->f11.control_base_addr, | ||
624 | data->f11_ctrl_regs, RMI_F11_CTRL_REG_COUNT); | ||
625 | if (ret) | ||
626 | hid_warn(hdev, | ||
627 | "can not write F11 control registers after reset\n"); | ||
628 | } | ||
629 | |||
630 | if (!device_may_wakeup(hdev->dev.parent)) { | ||
631 | ret = rmi_set_sleep_mode(hdev, RMI_SLEEP_NORMAL); | ||
632 | if (ret) { | ||
633 | hid_err(hdev, "can not write sleep mode\n"); | ||
634 | return ret; | ||
635 | } | ||
636 | } | ||
637 | |||
638 | return ret; | ||
538 | } | 639 | } |
539 | 640 | ||
540 | static int rmi_post_resume(struct hid_device *hdev) | 641 | static int rmi_post_resume(struct hid_device *hdev) |
541 | { | 642 | { |
542 | return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); | 643 | return rmi_reset_attn_mode(hdev); |
543 | } | 644 | } |
544 | #endif /* CONFIG_PM */ | 645 | #endif /* CONFIG_PM */ |
545 | 646 | ||
@@ -595,6 +696,7 @@ static void rmi_register_function(struct rmi_data *data, | |||
595 | f->interrupt_count = pdt_entry->interrupt_source_count; | 696 | f->interrupt_count = pdt_entry->interrupt_source_count; |
596 | f->irq_mask = rmi_gen_mask(f->interrupt_base, | 697 | f->irq_mask = rmi_gen_mask(f->interrupt_base, |
597 | f->interrupt_count); | 698 | f->interrupt_count); |
699 | data->interrupt_enable_mask |= f->irq_mask; | ||
598 | } | 700 | } |
599 | } | 701 | } |
600 | 702 | ||
@@ -732,6 +834,35 @@ static int rmi_populate_f01(struct hid_device *hdev) | |||
732 | data->firmware_id += info[2] * 65536; | 834 | data->firmware_id += info[2] * 65536; |
733 | } | 835 | } |
734 | 836 | ||
837 | ret = rmi_read_block(hdev, data->f01.control_base_addr, info, | ||
838 | 2); | ||
839 | |||
840 | if (ret) { | ||
841 | hid_err(hdev, "can not read f01 ctrl registers\n"); | ||
842 | return ret; | ||
843 | } | ||
844 | |||
845 | data->f01_ctrl0 = info[0]; | ||
846 | |||
847 | if (!info[1]) { | ||
848 | /* | ||
849 | * Do to a firmware bug in some touchpads the F01 interrupt | ||
850 | * enable control register will be cleared on reset. | ||
851 | * This will stop the touchpad from reporting data, so | ||
852 | * if F01 CTRL1 is 0 then we need to explicitly enable | ||
853 | * interrupts for the functions we want data for. | ||
854 | */ | ||
855 | data->restore_interrupt_mask = true; | ||
856 | |||
857 | ret = rmi_write(hdev, data->f01.control_base_addr + 1, | ||
858 | &data->interrupt_enable_mask); | ||
859 | if (ret) { | ||
860 | hid_err(hdev, "can not write to control reg 1: %d.\n", | ||
861 | ret); | ||
862 | return ret; | ||
863 | } | ||
864 | } | ||
865 | |||
735 | return 0; | 866 | return 0; |
736 | } | 867 | } |
737 | 868 | ||
@@ -904,24 +1035,23 @@ static int rmi_populate_f11(struct hid_device *hdev) | |||
904 | if (has_data40) | 1035 | if (has_data40) |
905 | data->f11.report_size += data->max_fingers * 2; | 1036 | data->f11.report_size += data->max_fingers * 2; |
906 | 1037 | ||
907 | /* | 1038 | ret = rmi_read_block(hdev, data->f11.control_base_addr, |
908 | * retrieve the ctrl registers | 1039 | data->f11_ctrl_regs, RMI_F11_CTRL_REG_COUNT); |
909 | * the ctrl register has a size of 20 but a fw bug split it into 16 + 4, | ||
910 | * and there is no way to know if the first 20 bytes are here or not. | ||
911 | * We use only the first 12 bytes, so get only them. | ||
912 | */ | ||
913 | ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, 12); | ||
914 | if (ret) { | 1040 | if (ret) { |
915 | hid_err(hdev, "can not read ctrl block of size 11: %d.\n", ret); | 1041 | hid_err(hdev, "can not read ctrl block of size 11: %d.\n", ret); |
916 | return ret; | 1042 | return ret; |
917 | } | 1043 | } |
918 | 1044 | ||
919 | data->max_x = buf[6] | (buf[7] << 8); | 1045 | /* data->f11_ctrl_regs now contains valid register data */ |
920 | data->max_y = buf[8] | (buf[9] << 8); | 1046 | data->read_f11_ctrl_regs = true; |
1047 | |||
1048 | data->max_x = data->f11_ctrl_regs[6] | (data->f11_ctrl_regs[7] << 8); | ||
1049 | data->max_y = data->f11_ctrl_regs[8] | (data->f11_ctrl_regs[9] << 8); | ||
921 | 1050 | ||
922 | if (has_dribble) { | 1051 | if (has_dribble) { |
923 | buf[0] = buf[0] & ~BIT(6); | 1052 | data->f11_ctrl_regs[0] = data->f11_ctrl_regs[0] & ~BIT(6); |
924 | ret = rmi_write(hdev, data->f11.control_base_addr, buf); | 1053 | ret = rmi_write(hdev, data->f11.control_base_addr, |
1054 | data->f11_ctrl_regs); | ||
925 | if (ret) { | 1055 | if (ret) { |
926 | hid_err(hdev, "can not write to control reg 0: %d.\n", | 1056 | hid_err(hdev, "can not write to control reg 0: %d.\n", |
927 | ret); | 1057 | ret); |
@@ -930,9 +1060,9 @@ static int rmi_populate_f11(struct hid_device *hdev) | |||
930 | } | 1060 | } |
931 | 1061 | ||
932 | if (has_palm_detect) { | 1062 | if (has_palm_detect) { |
933 | buf[11] = buf[11] & ~BIT(0); | 1063 | data->f11_ctrl_regs[11] = data->f11_ctrl_regs[11] & ~BIT(0); |
934 | ret = rmi_write(hdev, data->f11.control_base_addr + 11, | 1064 | ret = rmi_write(hdev, data->f11.control_base_addr + 11, |
935 | &buf[11]); | 1065 | &data->f11_ctrl_regs[11]); |
936 | if (ret) { | 1066 | if (ret) { |
937 | hid_err(hdev, "can not write to control reg 11: %d.\n", | 1067 | hid_err(hdev, "can not write to control reg 11: %d.\n", |
938 | ret); | 1068 | ret); |
@@ -1273,6 +1403,7 @@ static struct hid_driver rmi_driver = { | |||
1273 | .input_mapping = rmi_input_mapping, | 1403 | .input_mapping = rmi_input_mapping, |
1274 | .input_configured = rmi_input_configured, | 1404 | .input_configured = rmi_input_configured, |
1275 | #ifdef CONFIG_PM | 1405 | #ifdef CONFIG_PM |
1406 | .suspend = rmi_suspend, | ||
1276 | .resume = rmi_post_resume, | 1407 | .resume = rmi_post_resume, |
1277 | .reset_resume = rmi_post_reset, | 1408 | .reset_resume = rmi_post_reset, |
1278 | #endif | 1409 | #endif |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 090a1ba0abb6..a76eb2a0a987 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -774,6 +774,9 @@ static const struct hid_device_id sensor_hub_devices[] = { | |||
774 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS, | 774 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS, |
775 | USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA), | 775 | USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA), |
776 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | 776 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
777 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, | ||
778 | USB_DEVICE_ID_ITE_LENOVO_YOGA), | ||
779 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
777 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, | 780 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
778 | HID_ANY_ID) }, | 781 | HID_ANY_ID) }, |
779 | { } | 782 | { } |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index ed2f008f8403..661f94f8ab8b 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -296,7 +296,14 @@ static __u8 navigation_rdesc[] = { | |||
296 | 0x09, 0x01, /* Usage (Pointer), */ | 296 | 0x09, 0x01, /* Usage (Pointer), */ |
297 | 0x81, 0x02, /* Input (Variable), */ | 297 | 0x81, 0x02, /* Input (Variable), */ |
298 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | 298 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ |
299 | 0x95, 0x20, /* Report Count (26), */ | 299 | 0x95, 0x01, /* Report Count (1), */ |
300 | 0x81, 0x02, /* Input (Variable), */ | ||
301 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
302 | 0x95, 0x01, /* Report Count (1), */ | ||
303 | 0x09, 0x01, /* Usage (Pointer), */ | ||
304 | 0x81, 0x02, /* Input (Variable), */ | ||
305 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
306 | 0x95, 0x1E, /* Report Count (24), */ | ||
300 | 0x81, 0x02, /* Input (Variable), */ | 307 | 0x81, 0x02, /* Input (Variable), */ |
301 | 0x75, 0x08, /* Report Size (8), */ | 308 | 0x75, 0x08, /* Report Size (8), */ |
302 | 0x95, 0x30, /* Report Count (48), */ | 309 | 0x95, 0x30, /* Report Count (48), */ |
@@ -1270,6 +1277,17 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
1270 | * has to be BYTE_SWAPPED before passing up to joystick interface | 1277 | * has to be BYTE_SWAPPED before passing up to joystick interface |
1271 | */ | 1278 | */ |
1272 | if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) { | 1279 | if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) { |
1280 | /* | ||
1281 | * When connected via Bluetooth the Sixaxis occasionally sends | ||
1282 | * a report with the second byte 0xff and the rest zeroed. | ||
1283 | * | ||
1284 | * This report does not reflect the actual state of the | ||
1285 | * controller must be ignored to avoid generating false input | ||
1286 | * events. | ||
1287 | */ | ||
1288 | if (rd[1] == 0xff) | ||
1289 | return -EINVAL; | ||
1290 | |||
1273 | swap(rd[41], rd[42]); | 1291 | swap(rd[41], rd[42]); |
1274 | swap(rd[43], rd[44]); | 1292 | swap(rd[43], rd[44]); |
1275 | swap(rd[45], rd[46]); | 1293 | swap(rd[45], rd[46]); |
@@ -1836,7 +1854,7 @@ static void dualshock4_state_worker(struct work_struct *work) | |||
1836 | } else { | 1854 | } else { |
1837 | memset(buf, 0, DS4_REPORT_0x11_SIZE); | 1855 | memset(buf, 0, DS4_REPORT_0x11_SIZE); |
1838 | buf[0] = 0x11; | 1856 | buf[0] = 0x11; |
1839 | buf[1] = 0xB0; | 1857 | buf[1] = 0x80; |
1840 | buf[3] = 0x0F; | 1858 | buf[3] = 0x0F; |
1841 | offset = 6; | 1859 | offset = 6; |
1842 | } | 1860 | } |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index f77469d4edfb..2871f3c81a4c 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -149,6 +149,8 @@ struct i2c_hid { | |||
149 | int irq; | 149 | int irq; |
150 | 150 | ||
151 | struct i2c_hid_platform_data pdata; | 151 | struct i2c_hid_platform_data pdata; |
152 | |||
153 | bool irq_wake_enabled; | ||
152 | }; | 154 | }; |
153 | 155 | ||
154 | static int __i2c_hid_command(struct i2c_client *client, | 156 | static int __i2c_hid_command(struct i2c_client *client, |
@@ -1091,14 +1093,21 @@ static int i2c_hid_suspend(struct device *dev) | |||
1091 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 1093 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
1092 | struct hid_device *hid = ihid->hid; | 1094 | struct hid_device *hid = ihid->hid; |
1093 | int ret = 0; | 1095 | int ret = 0; |
1094 | 1096 | int wake_status; | |
1095 | disable_irq(ihid->irq); | ||
1096 | if (device_may_wakeup(&client->dev)) | ||
1097 | enable_irq_wake(ihid->irq); | ||
1098 | 1097 | ||
1099 | if (hid->driver && hid->driver->suspend) | 1098 | if (hid->driver && hid->driver->suspend) |
1100 | ret = hid->driver->suspend(hid, PMSG_SUSPEND); | 1099 | ret = hid->driver->suspend(hid, PMSG_SUSPEND); |
1101 | 1100 | ||
1101 | disable_irq(ihid->irq); | ||
1102 | if (device_may_wakeup(&client->dev)) { | ||
1103 | wake_status = enable_irq_wake(ihid->irq); | ||
1104 | if (!wake_status) | ||
1105 | ihid->irq_wake_enabled = true; | ||
1106 | else | ||
1107 | hid_warn(hid, "Failed to enable irq wake: %d\n", | ||
1108 | wake_status); | ||
1109 | } | ||
1110 | |||
1102 | /* Save some power */ | 1111 | /* Save some power */ |
1103 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | 1112 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
1104 | 1113 | ||
@@ -1111,14 +1120,21 @@ static int i2c_hid_resume(struct device *dev) | |||
1111 | struct i2c_client *client = to_i2c_client(dev); | 1120 | struct i2c_client *client = to_i2c_client(dev); |
1112 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 1121 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
1113 | struct hid_device *hid = ihid->hid; | 1122 | struct hid_device *hid = ihid->hid; |
1123 | int wake_status; | ||
1114 | 1124 | ||
1115 | enable_irq(ihid->irq); | 1125 | enable_irq(ihid->irq); |
1116 | ret = i2c_hid_hwreset(client); | 1126 | ret = i2c_hid_hwreset(client); |
1117 | if (ret) | 1127 | if (ret) |
1118 | return ret; | 1128 | return ret; |
1119 | 1129 | ||
1120 | if (device_may_wakeup(&client->dev)) | 1130 | if (device_may_wakeup(&client->dev) && ihid->irq_wake_enabled) { |
1121 | disable_irq_wake(ihid->irq); | 1131 | wake_status = disable_irq_wake(ihid->irq); |
1132 | if (!wake_status) | ||
1133 | ihid->irq_wake_enabled = false; | ||
1134 | else | ||
1135 | hid_warn(hid, "Failed to disable irq wake: %d\n", | ||
1136 | wake_status); | ||
1137 | } | ||
1122 | 1138 | ||
1123 | if (hid->driver && hid->driver->reset_resume) { | 1139 | if (hid->driver && hid->driver->reset_resume) { |
1124 | ret = hid->driver->reset_resume(hid); | 1140 | ret = hid->driver->reset_resume(hid); |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index bfbe1bedda7f..36712e9f56c2 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -164,7 +164,7 @@ static void hid_io_error(struct hid_device *hid) | |||
164 | if (time_after(jiffies, usbhid->stop_retry)) { | 164 | if (time_after(jiffies, usbhid->stop_retry)) { |
165 | 165 | ||
166 | /* Retries failed, so do a port reset unless we lack bandwidth*/ | 166 | /* Retries failed, so do a port reset unless we lack bandwidth*/ |
167 | if (test_bit(HID_NO_BANDWIDTH, &usbhid->iofl) | 167 | if (!test_bit(HID_NO_BANDWIDTH, &usbhid->iofl) |
168 | && !test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { | 168 | && !test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { |
169 | 169 | ||
170 | schedule_work(&usbhid->reset_work); | 170 | schedule_work(&usbhid->reset_work); |
@@ -710,7 +710,8 @@ int usbhid_open(struct hid_device *hid) | |||
710 | * Wait 50 msec for the queue to empty before allowing events | 710 | * Wait 50 msec for the queue to empty before allowing events |
711 | * to go through hid. | 711 | * to go through hid. |
712 | */ | 712 | */ |
713 | msleep(50); | 713 | if (res == 0 && !(hid->quirks & HID_QUIRK_ALWAYS_POLL)) |
714 | msleep(50); | ||
714 | clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); | 715 | clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); |
715 | } | 716 | } |
716 | done: | 717 | done: |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 20f9a653444c..1dff8f0015ba 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -90,8 +90,9 @@ static const struct hid_blacklist { | |||
90 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2, HID_QUIRK_NO_INIT_REPORTS }, | 90 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2, HID_QUIRK_NO_INIT_REPORTS }, |
91 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, HID_QUIRK_NO_INIT_REPORTS }, | 91 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, HID_QUIRK_NO_INIT_REPORTS }, |
92 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, HID_QUIRK_NO_INIT_REPORTS }, | 92 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, HID_QUIRK_NO_INIT_REPORTS }, |
93 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3, HID_QUIRK_NO_INIT_REPORTS }, | ||
94 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP, HID_QUIRK_NO_INIT_REPORTS }, | ||
93 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, | 95 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, |
94 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS }, | ||
95 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS }, | 96 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS }, |
96 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, | 97 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, |
97 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, | 98 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, |
@@ -117,7 +118,8 @@ static const struct hid_blacklist { | |||
117 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 118 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
118 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, | 119 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, |
119 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, | 120 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, |
120 | { USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN, HID_QUIRK_NOGET }, | 121 | { USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882, HID_QUIRK_NOGET }, |
122 | { USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883, HID_QUIRK_NOGET }, | ||
121 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 123 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
122 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, | 124 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, |
123 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT }, | 125 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT }, |
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index a533787a6d85..4681a65a4579 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h | |||
@@ -113,7 +113,7 @@ struct wacom { | |||
113 | struct mutex lock; | 113 | struct mutex lock; |
114 | struct work_struct work; | 114 | struct work_struct work; |
115 | struct wacom_led { | 115 | struct wacom_led { |
116 | u8 select[2]; /* status led selector (0..3) */ | 116 | u8 select[5]; /* status led selector (0..3) */ |
117 | u8 llv; /* status led brightness no button (1..127) */ | 117 | u8 llv; /* status led brightness no button (1..127) */ |
118 | u8 hlv; /* status led brightness button pressed (1..127) */ | 118 | u8 hlv; /* status led brightness button pressed (1..127) */ |
119 | u8 img_lum; /* OLED matrix display brightness */ | 119 | u8 img_lum; /* OLED matrix display brightness */ |
@@ -123,6 +123,8 @@ struct wacom { | |||
123 | struct power_supply *ac; | 123 | struct power_supply *ac; |
124 | struct power_supply_desc battery_desc; | 124 | struct power_supply_desc battery_desc; |
125 | struct power_supply_desc ac_desc; | 125 | struct power_supply_desc ac_desc; |
126 | struct kobject *remote_dir; | ||
127 | struct attribute_group remote_group[5]; | ||
126 | }; | 128 | }; |
127 | 129 | ||
128 | static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) | 130 | static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) |
@@ -147,4 +149,7 @@ int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, | |||
147 | struct hid_usage *usage, __s32 value); | 149 | struct hid_usage *usage, __s32 value); |
148 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); | 150 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); |
149 | void wacom_battery_work(struct work_struct *work); | 151 | void wacom_battery_work(struct work_struct *work); |
152 | int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, | ||
153 | int index); | ||
154 | void wacom_remote_destroy_attr_group(struct wacom *wacom, __u32 serial); | ||
150 | #endif | 155 | #endif |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 01b937e63cf3..9a4912c1828d 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -23,9 +23,13 @@ | |||
23 | #define WAC_CMD_ICON_XFER 0x23 | 23 | #define WAC_CMD_ICON_XFER 0x23 |
24 | #define WAC_CMD_ICON_BT_XFER 0x26 | 24 | #define WAC_CMD_ICON_BT_XFER 0x26 |
25 | #define WAC_CMD_RETRIES 10 | 25 | #define WAC_CMD_RETRIES 10 |
26 | #define WAC_CMD_DELETE_PAIRING 0x20 | ||
27 | #define WAC_CMD_UNPAIR_ALL 0xFF | ||
28 | #define WAC_REMOTE_SERIAL_MAX_STRLEN 9 | ||
26 | 29 | ||
27 | #define DEV_ATTR_RW_PERM (S_IRUGO | S_IWUSR | S_IWGRP) | 30 | #define DEV_ATTR_RW_PERM (S_IRUGO | S_IWUSR | S_IWGRP) |
28 | #define DEV_ATTR_WO_PERM (S_IWUSR | S_IWGRP) | 31 | #define DEV_ATTR_WO_PERM (S_IWUSR | S_IWGRP) |
32 | #define DEV_ATTR_RO_PERM (S_IRUSR | S_IRGRP) | ||
29 | 33 | ||
30 | static int wacom_get_report(struct hid_device *hdev, u8 type, u8 *buf, | 34 | static int wacom_get_report(struct hid_device *hdev, u8 type, u8 *buf, |
31 | size_t size, unsigned int retries) | 35 | size_t size, unsigned int retries) |
@@ -335,7 +339,7 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id, | |||
335 | if (error >= 0) | 339 | if (error >= 0) |
336 | error = wacom_get_report(hdev, HID_FEATURE_REPORT, | 340 | error = wacom_get_report(hdev, HID_FEATURE_REPORT, |
337 | rep_data, length, 1); | 341 | rep_data, length, 1); |
338 | } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); | 342 | } while (error >= 0 && rep_data[1] != mode && limit++ < WAC_MSG_RETRIES); |
339 | 343 | ||
340 | kfree(rep_data); | 344 | kfree(rep_data); |
341 | 345 | ||
@@ -453,12 +457,11 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, | |||
453 | * interface number. | 457 | * interface number. |
454 | */ | 458 | */ |
455 | if (features->type == WIRELESS) { | 459 | if (features->type == WIRELESS) { |
456 | if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { | 460 | if (intf->cur_altsetting->desc.bInterfaceNumber == 0) |
461 | features->device_type = WACOM_DEVICETYPE_WL_MONITOR; | ||
462 | else | ||
457 | features->device_type = WACOM_DEVICETYPE_NONE; | 463 | features->device_type = WACOM_DEVICETYPE_NONE; |
458 | } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) { | 464 | return; |
459 | features->device_type |= WACOM_DEVICETYPE_TOUCH; | ||
460 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; | ||
461 | } | ||
462 | } | 465 | } |
463 | 466 | ||
464 | wacom_parse_hid(hdev, features); | 467 | wacom_parse_hid(hdev, features); |
@@ -1120,6 +1123,189 @@ static ssize_t wacom_store_speed(struct device *dev, | |||
1120 | static DEVICE_ATTR(speed, DEV_ATTR_RW_PERM, | 1123 | static DEVICE_ATTR(speed, DEV_ATTR_RW_PERM, |
1121 | wacom_show_speed, wacom_store_speed); | 1124 | wacom_show_speed, wacom_store_speed); |
1122 | 1125 | ||
1126 | |||
1127 | static ssize_t wacom_show_remote_mode(struct kobject *kobj, | ||
1128 | struct kobj_attribute *kattr, | ||
1129 | char *buf, int index) | ||
1130 | { | ||
1131 | struct device *dev = container_of(kobj->parent, struct device, kobj); | ||
1132 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
1133 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1134 | u8 mode; | ||
1135 | |||
1136 | mode = wacom->led.select[index]; | ||
1137 | if (mode >= 0 && mode < 3) | ||
1138 | return snprintf(buf, PAGE_SIZE, "%d\n", mode); | ||
1139 | else | ||
1140 | return snprintf(buf, PAGE_SIZE, "%d\n", -1); | ||
1141 | } | ||
1142 | |||
1143 | #define DEVICE_EKR_ATTR_GROUP(SET_ID) \ | ||
1144 | static ssize_t wacom_show_remote##SET_ID##_mode(struct kobject *kobj, \ | ||
1145 | struct kobj_attribute *kattr, char *buf) \ | ||
1146 | { \ | ||
1147 | return wacom_show_remote_mode(kobj, kattr, buf, SET_ID); \ | ||
1148 | } \ | ||
1149 | static struct kobj_attribute remote##SET_ID##_mode_attr = { \ | ||
1150 | .attr = {.name = "remote_mode", \ | ||
1151 | .mode = DEV_ATTR_RO_PERM}, \ | ||
1152 | .show = wacom_show_remote##SET_ID##_mode, \ | ||
1153 | }; \ | ||
1154 | static struct attribute *remote##SET_ID##_serial_attrs[] = { \ | ||
1155 | &remote##SET_ID##_mode_attr.attr, \ | ||
1156 | NULL \ | ||
1157 | }; \ | ||
1158 | static struct attribute_group remote##SET_ID##_serial_group = { \ | ||
1159 | .name = NULL, \ | ||
1160 | .attrs = remote##SET_ID##_serial_attrs, \ | ||
1161 | } | ||
1162 | |||
1163 | DEVICE_EKR_ATTR_GROUP(0); | ||
1164 | DEVICE_EKR_ATTR_GROUP(1); | ||
1165 | DEVICE_EKR_ATTR_GROUP(2); | ||
1166 | DEVICE_EKR_ATTR_GROUP(3); | ||
1167 | DEVICE_EKR_ATTR_GROUP(4); | ||
1168 | |||
1169 | int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, int index) | ||
1170 | { | ||
1171 | int error = 0; | ||
1172 | char *buf; | ||
1173 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1174 | |||
1175 | wacom_wac->serial[index] = serial; | ||
1176 | |||
1177 | buf = kzalloc(WAC_REMOTE_SERIAL_MAX_STRLEN, GFP_KERNEL); | ||
1178 | if (!buf) | ||
1179 | return -ENOMEM; | ||
1180 | snprintf(buf, WAC_REMOTE_SERIAL_MAX_STRLEN, "%d", serial); | ||
1181 | wacom->remote_group[index].name = buf; | ||
1182 | |||
1183 | error = sysfs_create_group(wacom->remote_dir, | ||
1184 | &wacom->remote_group[index]); | ||
1185 | if (error) { | ||
1186 | hid_err(wacom->hdev, | ||
1187 | "cannot create sysfs group err: %d\n", error); | ||
1188 | kobject_put(wacom->remote_dir); | ||
1189 | return error; | ||
1190 | } | ||
1191 | |||
1192 | return 0; | ||
1193 | } | ||
1194 | |||
1195 | void wacom_remote_destroy_attr_group(struct wacom *wacom, __u32 serial) | ||
1196 | { | ||
1197 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1198 | int i; | ||
1199 | |||
1200 | if (!serial) | ||
1201 | return; | ||
1202 | |||
1203 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
1204 | if (wacom_wac->serial[i] == serial) { | ||
1205 | wacom_wac->serial[i] = 0; | ||
1206 | wacom->led.select[i] = WACOM_STATUS_UNKNOWN; | ||
1207 | if (wacom->remote_group[i].name) { | ||
1208 | sysfs_remove_group(wacom->remote_dir, | ||
1209 | &wacom->remote_group[i]); | ||
1210 | kfree(wacom->remote_group[i].name); | ||
1211 | wacom->remote_group[i].name = NULL; | ||
1212 | } | ||
1213 | } | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1217 | static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char selector) | ||
1218 | { | ||
1219 | const size_t buf_size = 2; | ||
1220 | unsigned char *buf; | ||
1221 | int retval; | ||
1222 | |||
1223 | buf = kzalloc(buf_size, GFP_KERNEL); | ||
1224 | if (!buf) | ||
1225 | return -ENOMEM; | ||
1226 | |||
1227 | buf[0] = WAC_CMD_DELETE_PAIRING; | ||
1228 | buf[1] = selector; | ||
1229 | |||
1230 | retval = wacom_set_report(wacom->hdev, HID_OUTPUT_REPORT, buf, | ||
1231 | buf_size, WAC_CMD_RETRIES); | ||
1232 | kfree(buf); | ||
1233 | |||
1234 | return retval; | ||
1235 | } | ||
1236 | |||
1237 | static ssize_t wacom_store_unpair_remote(struct kobject *kobj, | ||
1238 | struct kobj_attribute *attr, | ||
1239 | const char *buf, size_t count) | ||
1240 | { | ||
1241 | unsigned char selector = 0; | ||
1242 | struct device *dev = container_of(kobj->parent, struct device, kobj); | ||
1243 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
1244 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1245 | int err; | ||
1246 | |||
1247 | if (!strncmp(buf, "*\n", 2)) { | ||
1248 | selector = WAC_CMD_UNPAIR_ALL; | ||
1249 | } else { | ||
1250 | hid_info(wacom->hdev, "remote: unrecognized unpair code: %s\n", | ||
1251 | buf); | ||
1252 | return -1; | ||
1253 | } | ||
1254 | |||
1255 | mutex_lock(&wacom->lock); | ||
1256 | |||
1257 | err = wacom_cmd_unpair_remote(wacom, selector); | ||
1258 | mutex_unlock(&wacom->lock); | ||
1259 | |||
1260 | return err < 0 ? err : count; | ||
1261 | } | ||
1262 | |||
1263 | static struct kobj_attribute unpair_remote_attr = { | ||
1264 | .attr = {.name = "unpair_remote", .mode = 0200}, | ||
1265 | .store = wacom_store_unpair_remote, | ||
1266 | }; | ||
1267 | |||
1268 | static const struct attribute *remote_unpair_attrs[] = { | ||
1269 | &unpair_remote_attr.attr, | ||
1270 | NULL | ||
1271 | }; | ||
1272 | |||
1273 | static int wacom_initialize_remote(struct wacom *wacom) | ||
1274 | { | ||
1275 | int error = 0; | ||
1276 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); | ||
1277 | int i; | ||
1278 | |||
1279 | if (wacom->wacom_wac.features.type != REMOTE) | ||
1280 | return 0; | ||
1281 | |||
1282 | wacom->remote_group[0] = remote0_serial_group; | ||
1283 | wacom->remote_group[1] = remote1_serial_group; | ||
1284 | wacom->remote_group[2] = remote2_serial_group; | ||
1285 | wacom->remote_group[3] = remote3_serial_group; | ||
1286 | wacom->remote_group[4] = remote4_serial_group; | ||
1287 | |||
1288 | wacom->remote_dir = kobject_create_and_add("wacom_remote", | ||
1289 | &wacom->hdev->dev.kobj); | ||
1290 | if (!wacom->remote_dir) | ||
1291 | return -ENOMEM; | ||
1292 | |||
1293 | error = sysfs_create_files(wacom->remote_dir, remote_unpair_attrs); | ||
1294 | |||
1295 | if (error) { | ||
1296 | hid_err(wacom->hdev, | ||
1297 | "cannot create sysfs group err: %d\n", error); | ||
1298 | return error; | ||
1299 | } | ||
1300 | |||
1301 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
1302 | wacom->led.select[i] = WACOM_STATUS_UNKNOWN; | ||
1303 | wacom_wac->serial[i] = 0; | ||
1304 | } | ||
1305 | |||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1123 | static struct input_dev *wacom_allocate_input(struct wacom *wacom) | 1309 | static struct input_dev *wacom_allocate_input(struct wacom *wacom) |
1124 | { | 1310 | { |
1125 | struct input_dev *input_dev; | 1311 | struct input_dev *input_dev; |
@@ -1130,7 +1316,7 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) | |||
1130 | if (!input_dev) | 1316 | if (!input_dev) |
1131 | return NULL; | 1317 | return NULL; |
1132 | 1318 | ||
1133 | input_dev->name = wacom_wac->pen_name; | 1319 | input_dev->name = wacom_wac->features.name; |
1134 | input_dev->phys = hdev->phys; | 1320 | input_dev->phys = hdev->phys; |
1135 | input_dev->dev.parent = &hdev->dev; | 1321 | input_dev->dev.parent = &hdev->dev; |
1136 | input_dev->open = wacom_open; | 1322 | input_dev->open = wacom_open; |
@@ -1145,43 +1331,6 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom) | |||
1145 | return input_dev; | 1331 | return input_dev; |
1146 | } | 1332 | } |
1147 | 1333 | ||
1148 | static void wacom_free_inputs(struct wacom *wacom) | ||
1149 | { | ||
1150 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); | ||
1151 | |||
1152 | if (wacom_wac->pen_input) | ||
1153 | input_free_device(wacom_wac->pen_input); | ||
1154 | if (wacom_wac->touch_input) | ||
1155 | input_free_device(wacom_wac->touch_input); | ||
1156 | if (wacom_wac->pad_input) | ||
1157 | input_free_device(wacom_wac->pad_input); | ||
1158 | wacom_wac->pen_input = NULL; | ||
1159 | wacom_wac->touch_input = NULL; | ||
1160 | wacom_wac->pad_input = NULL; | ||
1161 | } | ||
1162 | |||
1163 | static int wacom_allocate_inputs(struct wacom *wacom) | ||
1164 | { | ||
1165 | struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; | ||
1166 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); | ||
1167 | |||
1168 | pen_input_dev = wacom_allocate_input(wacom); | ||
1169 | touch_input_dev = wacom_allocate_input(wacom); | ||
1170 | pad_input_dev = wacom_allocate_input(wacom); | ||
1171 | if (!pen_input_dev || !touch_input_dev || !pad_input_dev) { | ||
1172 | wacom_free_inputs(wacom); | ||
1173 | return -ENOMEM; | ||
1174 | } | ||
1175 | |||
1176 | wacom_wac->pen_input = pen_input_dev; | ||
1177 | wacom_wac->touch_input = touch_input_dev; | ||
1178 | wacom_wac->touch_input->name = wacom_wac->touch_name; | ||
1179 | wacom_wac->pad_input = pad_input_dev; | ||
1180 | wacom_wac->pad_input->name = wacom_wac->pad_name; | ||
1181 | |||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1185 | static void wacom_clean_inputs(struct wacom *wacom) | 1334 | static void wacom_clean_inputs(struct wacom *wacom) |
1186 | { | 1335 | { |
1187 | if (wacom->wacom_wac.pen_input) { | 1336 | if (wacom->wacom_wac.pen_input) { |
@@ -1202,12 +1351,33 @@ static void wacom_clean_inputs(struct wacom *wacom) | |||
1202 | else | 1351 | else |
1203 | input_free_device(wacom->wacom_wac.pad_input); | 1352 | input_free_device(wacom->wacom_wac.pad_input); |
1204 | } | 1353 | } |
1354 | if (wacom->remote_dir) | ||
1355 | kobject_put(wacom->remote_dir); | ||
1205 | wacom->wacom_wac.pen_input = NULL; | 1356 | wacom->wacom_wac.pen_input = NULL; |
1206 | wacom->wacom_wac.touch_input = NULL; | 1357 | wacom->wacom_wac.touch_input = NULL; |
1207 | wacom->wacom_wac.pad_input = NULL; | 1358 | wacom->wacom_wac.pad_input = NULL; |
1208 | wacom_destroy_leds(wacom); | 1359 | wacom_destroy_leds(wacom); |
1209 | } | 1360 | } |
1210 | 1361 | ||
1362 | static int wacom_allocate_inputs(struct wacom *wacom) | ||
1363 | { | ||
1364 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); | ||
1365 | |||
1366 | wacom_wac->pen_input = wacom_allocate_input(wacom); | ||
1367 | wacom_wac->touch_input = wacom_allocate_input(wacom); | ||
1368 | wacom_wac->pad_input = wacom_allocate_input(wacom); | ||
1369 | if (!wacom_wac->pen_input || !wacom_wac->touch_input || !wacom_wac->pad_input) { | ||
1370 | wacom_clean_inputs(wacom); | ||
1371 | return -ENOMEM; | ||
1372 | } | ||
1373 | |||
1374 | wacom_wac->pen_input->name = wacom_wac->pen_name; | ||
1375 | wacom_wac->touch_input->name = wacom_wac->touch_name; | ||
1376 | wacom_wac->pad_input->name = wacom_wac->pad_name; | ||
1377 | |||
1378 | return 0; | ||
1379 | } | ||
1380 | |||
1211 | static int wacom_register_inputs(struct wacom *wacom) | 1381 | static int wacom_register_inputs(struct wacom *wacom) |
1212 | { | 1382 | { |
1213 | struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; | 1383 | struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; |
@@ -1262,10 +1432,16 @@ static int wacom_register_inputs(struct wacom *wacom) | |||
1262 | error = wacom_initialize_leds(wacom); | 1432 | error = wacom_initialize_leds(wacom); |
1263 | if (error) | 1433 | if (error) |
1264 | goto fail_leds; | 1434 | goto fail_leds; |
1435 | |||
1436 | error = wacom_initialize_remote(wacom); | ||
1437 | if (error) | ||
1438 | goto fail_remote; | ||
1265 | } | 1439 | } |
1266 | 1440 | ||
1267 | return 0; | 1441 | return 0; |
1268 | 1442 | ||
1443 | fail_remote: | ||
1444 | wacom_destroy_leds(wacom); | ||
1269 | fail_leds: | 1445 | fail_leds: |
1270 | input_unregister_device(pad_input_dev); | 1446 | input_unregister_device(pad_input_dev); |
1271 | pad_input_dev = NULL; | 1447 | pad_input_dev = NULL; |
@@ -1556,11 +1732,9 @@ static int wacom_probe(struct hid_device *hdev, | |||
1556 | mutex_init(&wacom->lock); | 1732 | mutex_init(&wacom->lock); |
1557 | INIT_WORK(&wacom->work, wacom_wireless_work); | 1733 | INIT_WORK(&wacom->work, wacom_wireless_work); |
1558 | 1734 | ||
1559 | if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { | 1735 | error = wacom_allocate_inputs(wacom); |
1560 | error = wacom_allocate_inputs(wacom); | 1736 | if (error) |
1561 | if (error) | 1737 | goto fail_allocate_inputs; |
1562 | goto fail_allocate_inputs; | ||
1563 | } | ||
1564 | 1738 | ||
1565 | /* | 1739 | /* |
1566 | * Bamboo Pad has a generic hid handling for the Pen, and we switch it | 1740 | * Bamboo Pad has a generic hid handling for the Pen, and we switch it |
@@ -1606,18 +1780,16 @@ static int wacom_probe(struct hid_device *hdev, | |||
1606 | if (error) | 1780 | if (error) |
1607 | goto fail_shared_data; | 1781 | goto fail_shared_data; |
1608 | 1782 | ||
1609 | if (!(features->quirks & WACOM_QUIRK_MONITOR) && | 1783 | if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) && |
1610 | (features->quirks & WACOM_QUIRK_BATTERY)) { | 1784 | (features->quirks & WACOM_QUIRK_BATTERY)) { |
1611 | error = wacom_initialize_battery(wacom); | 1785 | error = wacom_initialize_battery(wacom); |
1612 | if (error) | 1786 | if (error) |
1613 | goto fail_battery; | 1787 | goto fail_battery; |
1614 | } | 1788 | } |
1615 | 1789 | ||
1616 | if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { | 1790 | error = wacom_register_inputs(wacom); |
1617 | error = wacom_register_inputs(wacom); | 1791 | if (error) |
1618 | if (error) | 1792 | goto fail_register_inputs; |
1619 | goto fail_register_inputs; | ||
1620 | } | ||
1621 | 1793 | ||
1622 | if (hdev->bus == BUS_BLUETOOTH) { | 1794 | if (hdev->bus == BUS_BLUETOOTH) { |
1623 | error = device_create_file(&hdev->dev, &dev_attr_speed); | 1795 | error = device_create_file(&hdev->dev, &dev_attr_speed); |
@@ -1640,7 +1812,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
1640 | /* Note that if query fails it is not a hard failure */ | 1812 | /* Note that if query fails it is not a hard failure */ |
1641 | wacom_query_tablet_data(hdev, features); | 1813 | wacom_query_tablet_data(hdev, features); |
1642 | 1814 | ||
1643 | if (features->quirks & WACOM_QUIRK_MONITOR) | 1815 | if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) |
1644 | error = hid_hw_open(hdev); | 1816 | error = hid_hw_open(hdev); |
1645 | 1817 | ||
1646 | if (wacom_wac->features.type == INTUOSHT && | 1818 | if (wacom_wac->features.type == INTUOSHT && |
@@ -1714,7 +1886,6 @@ static struct hid_driver wacom_driver = { | |||
1714 | .id_table = wacom_ids, | 1886 | .id_table = wacom_ids, |
1715 | .probe = wacom_probe, | 1887 | .probe = wacom_probe, |
1716 | .remove = wacom_remove, | 1888 | .remove = wacom_remove, |
1717 | .event = wacom_wac_event, | ||
1718 | .report = wacom_wac_report, | 1889 | .report = wacom_wac_report, |
1719 | #ifdef CONFIG_PM | 1890 | #ifdef CONFIG_PM |
1720 | .resume = wacom_resume, | 1891 | .resume = wacom_resume, |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 0d244239e55d..0215ab62bb93 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -125,61 +125,47 @@ static int wacom_pl_irq(struct wacom_wac *wacom) | |||
125 | 125 | ||
126 | prox = data[1] & 0x40; | 126 | prox = data[1] & 0x40; |
127 | 127 | ||
128 | if (prox) { | 128 | if (!wacom->id[0]) { |
129 | wacom->id[0] = ERASER_DEVICE_ID; | 129 | if ((data[0] & 0x10) || (data[4] & 0x20)) { |
130 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 130 | wacom->tool[0] = BTN_TOOL_RUBBER; |
131 | if (features->pressure_max > 255) | 131 | wacom->id[0] = ERASER_DEVICE_ID; |
132 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); | ||
133 | pressure += (features->pressure_max + 1) / 2; | ||
134 | |||
135 | /* | ||
136 | * if going from out of proximity into proximity select between the eraser | ||
137 | * and the pen based on the state of the stylus2 button, choose eraser if | ||
138 | * pressed else choose pen. if not a proximity change from out to in, send | ||
139 | * an out of proximity for previous tool then a in for new tool. | ||
140 | */ | ||
141 | if (!wacom->tool[0]) { | ||
142 | /* Eraser bit set for DTF */ | ||
143 | if (data[1] & 0x10) | ||
144 | wacom->tool[1] = BTN_TOOL_RUBBER; | ||
145 | else | ||
146 | /* Going into proximity select tool */ | ||
147 | wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
148 | } else { | ||
149 | /* was entered with stylus2 pressed */ | ||
150 | if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { | ||
151 | /* report out proximity for previous tool */ | ||
152 | input_report_key(input, wacom->tool[1], 0); | ||
153 | input_sync(input); | ||
154 | wacom->tool[1] = BTN_TOOL_PEN; | ||
155 | return 0; | ||
156 | } | ||
157 | } | 132 | } |
158 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | 133 | else { |
159 | /* Unknown tool selected default to pen tool */ | 134 | wacom->tool[0] = BTN_TOOL_PEN; |
160 | wacom->tool[1] = BTN_TOOL_PEN; | ||
161 | wacom->id[0] = STYLUS_DEVICE_ID; | 135 | wacom->id[0] = STYLUS_DEVICE_ID; |
162 | } | 136 | } |
163 | input_report_key(input, wacom->tool[1], prox); /* report in proximity for tool */ | 137 | } |
164 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ | ||
165 | input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); | ||
166 | input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); | ||
167 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
168 | 138 | ||
169 | input_report_key(input, BTN_TOUCH, data[4] & 0x08); | 139 | /* If the eraser is in prox, STYLUS2 is always set. If we |
170 | input_report_key(input, BTN_STYLUS, data[4] & 0x10); | 140 | * mis-detected the type and notice that STYLUS2 isn't set |
171 | /* Only allow the stylus2 button to be reported for the pen tool. */ | 141 | * then force the eraser out of prox and let the pen in. |
172 | input_report_key(input, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); | 142 | */ |
173 | } else { | 143 | if (wacom->tool[0] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { |
174 | /* report proximity-out of a (valid) tool */ | 144 | input_report_key(input, BTN_TOOL_RUBBER, 0); |
175 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | 145 | input_report_abs(input, ABS_MISC, 0); |
176 | /* Unknown tool selected default to pen tool */ | 146 | input_sync(input); |
177 | wacom->tool[1] = BTN_TOOL_PEN; | 147 | wacom->tool[0] = BTN_TOOL_PEN; |
178 | } | 148 | wacom->id[0] = STYLUS_DEVICE_ID; |
179 | input_report_key(input, wacom->tool[1], prox); | ||
180 | } | 149 | } |
181 | 150 | ||
182 | wacom->tool[0] = prox; /* Save proximity state */ | 151 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
152 | if (features->pressure_max > 255) | ||
153 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); | ||
154 | pressure += (features->pressure_max + 1) / 2; | ||
155 | |||
156 | input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); | ||
157 | input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); | ||
158 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
159 | |||
160 | input_report_key(input, BTN_TOUCH, data[4] & 0x08); | ||
161 | input_report_key(input, BTN_STYLUS, data[4] & 0x10); | ||
162 | /* Only allow the stylus2 button to be reported for the pen tool. */ | ||
163 | input_report_key(input, BTN_STYLUS2, (wacom->tool[0] == BTN_TOOL_PEN) && (data[4] & 0x20)); | ||
164 | |||
165 | if (!prox) | ||
166 | wacom->id[0] = 0; | ||
167 | input_report_key(input, wacom->tool[0], prox); | ||
168 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
183 | return 1; | 169 | return 1; |
184 | } | 170 | } |
185 | 171 | ||
@@ -645,6 +631,130 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
645 | return 0; | 631 | return 0; |
646 | } | 632 | } |
647 | 633 | ||
634 | static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) | ||
635 | { | ||
636 | unsigned char *data = wacom_wac->data; | ||
637 | struct input_dev *input = wacom_wac->pad_input; | ||
638 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
639 | struct wacom_features *features = &wacom_wac->features; | ||
640 | int bat_charging, bat_percent, touch_ring_mode; | ||
641 | __u32 serial; | ||
642 | int i; | ||
643 | |||
644 | if (data[0] != WACOM_REPORT_REMOTE) { | ||
645 | dev_dbg(input->dev.parent, | ||
646 | "%s: received unknown report #%d", __func__, data[0]); | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | serial = data[3] + (data[4] << 8) + (data[5] << 16); | ||
651 | wacom_wac->id[0] = PAD_DEVICE_ID; | ||
652 | |||
653 | input_report_key(input, BTN_0, (data[9] & 0x01)); | ||
654 | input_report_key(input, BTN_1, (data[9] & 0x02)); | ||
655 | input_report_key(input, BTN_2, (data[9] & 0x04)); | ||
656 | input_report_key(input, BTN_3, (data[9] & 0x08)); | ||
657 | input_report_key(input, BTN_4, (data[9] & 0x10)); | ||
658 | input_report_key(input, BTN_5, (data[9] & 0x20)); | ||
659 | input_report_key(input, BTN_6, (data[9] & 0x40)); | ||
660 | input_report_key(input, BTN_7, (data[9] & 0x80)); | ||
661 | |||
662 | input_report_key(input, BTN_8, (data[10] & 0x01)); | ||
663 | input_report_key(input, BTN_9, (data[10] & 0x02)); | ||
664 | input_report_key(input, BTN_A, (data[10] & 0x04)); | ||
665 | input_report_key(input, BTN_B, (data[10] & 0x08)); | ||
666 | input_report_key(input, BTN_C, (data[10] & 0x10)); | ||
667 | input_report_key(input, BTN_X, (data[10] & 0x20)); | ||
668 | input_report_key(input, BTN_Y, (data[10] & 0x40)); | ||
669 | input_report_key(input, BTN_Z, (data[10] & 0x80)); | ||
670 | |||
671 | input_report_key(input, BTN_BASE, (data[11] & 0x01)); | ||
672 | input_report_key(input, BTN_BASE2, (data[11] & 0x02)); | ||
673 | |||
674 | if (data[12] & 0x80) | ||
675 | input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); | ||
676 | else | ||
677 | input_report_abs(input, ABS_WHEEL, 0); | ||
678 | |||
679 | bat_percent = data[7] & 0x7f; | ||
680 | bat_charging = !!(data[7] & 0x80); | ||
681 | |||
682 | if (data[9] | data[10] | (data[11] & 0x03) | data[12]) | ||
683 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
684 | else | ||
685 | input_report_abs(input, ABS_MISC, 0); | ||
686 | |||
687 | input_event(input, EV_MSC, MSC_SERIAL, serial); | ||
688 | |||
689 | /*Which mode select (LED light) is currently on?*/ | ||
690 | touch_ring_mode = (data[11] & 0xC0) >> 6; | ||
691 | |||
692 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
693 | if (wacom_wac->serial[i] == serial) | ||
694 | wacom->led.select[i] = touch_ring_mode; | ||
695 | } | ||
696 | |||
697 | if (!wacom->battery && | ||
698 | !(features->quirks & WACOM_QUIRK_BATTERY)) { | ||
699 | features->quirks |= WACOM_QUIRK_BATTERY; | ||
700 | INIT_WORK(&wacom->work, wacom_battery_work); | ||
701 | wacom_schedule_work(wacom_wac); | ||
702 | } | ||
703 | |||
704 | wacom_notify_battery(wacom_wac, bat_percent, bat_charging, 1, | ||
705 | bat_charging); | ||
706 | |||
707 | return 1; | ||
708 | } | ||
709 | |||
710 | static int wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) | ||
711 | { | ||
712 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
713 | unsigned char *data = wacom_wac->data; | ||
714 | int i; | ||
715 | |||
716 | if (data[0] != WACOM_REPORT_DEVICE_LIST) | ||
717 | return 0; | ||
718 | |||
719 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
720 | int j = i * 6; | ||
721 | int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4]; | ||
722 | bool connected = data[j+2]; | ||
723 | |||
724 | if (connected) { | ||
725 | int k; | ||
726 | |||
727 | if (wacom_wac->serial[i] == serial) | ||
728 | continue; | ||
729 | |||
730 | if (wacom_wac->serial[i]) { | ||
731 | wacom_remote_destroy_attr_group(wacom, | ||
732 | wacom_wac->serial[i]); | ||
733 | } | ||
734 | |||
735 | /* A remote can pair more than once with an EKR, | ||
736 | * check to make sure this serial isn't already paired. | ||
737 | */ | ||
738 | for (k = 0; k < WACOM_MAX_REMOTES; k++) { | ||
739 | if (wacom_wac->serial[k] == serial) | ||
740 | break; | ||
741 | } | ||
742 | |||
743 | if (k < WACOM_MAX_REMOTES) { | ||
744 | wacom_wac->serial[i] = serial; | ||
745 | continue; | ||
746 | } | ||
747 | wacom_remote_create_attr_group(wacom, serial, i); | ||
748 | |||
749 | } else if (wacom_wac->serial[i]) { | ||
750 | wacom_remote_destroy_attr_group(wacom, | ||
751 | wacom_wac->serial[i]); | ||
752 | } | ||
753 | } | ||
754 | |||
755 | return 0; | ||
756 | } | ||
757 | |||
648 | static void wacom_intuos_general(struct wacom_wac *wacom) | 758 | static void wacom_intuos_general(struct wacom_wac *wacom) |
649 | { | 759 | { |
650 | struct wacom_features *features = &wacom->features; | 760 | struct wacom_features *features = &wacom->features; |
@@ -1437,6 +1547,12 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, | |||
1437 | return 0; | 1547 | return 0; |
1438 | } | 1548 | } |
1439 | 1549 | ||
1550 | static void wacom_wac_pen_pre_report(struct hid_device *hdev, | ||
1551 | struct hid_report *report) | ||
1552 | { | ||
1553 | return; | ||
1554 | } | ||
1555 | |||
1440 | static void wacom_wac_pen_report(struct hid_device *hdev, | 1556 | static void wacom_wac_pen_report(struct hid_device *hdev, |
1441 | struct hid_report *report) | 1557 | struct hid_report *report) |
1442 | { | 1558 | { |
@@ -1491,6 +1607,13 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, | |||
1491 | wacom_map_usage(input, usage, field, EV_ABS, | 1607 | wacom_map_usage(input, usage, field, EV_ABS, |
1492 | ABS_MT_POSITION_Y, 4); | 1608 | ABS_MT_POSITION_Y, 4); |
1493 | break; | 1609 | break; |
1610 | case HID_DG_WIDTH: | ||
1611 | case HID_DG_HEIGHT: | ||
1612 | features->last_slot_field = usage->hid; | ||
1613 | wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MAJOR, 0); | ||
1614 | wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MINOR, 0); | ||
1615 | input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0); | ||
1616 | break; | ||
1494 | case HID_DG_CONTACTID: | 1617 | case HID_DG_CONTACTID: |
1495 | features->last_slot_field = usage->hid; | 1618 | features->last_slot_field = usage->hid; |
1496 | break; | 1619 | break; |
@@ -1504,6 +1627,10 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, | |||
1504 | features->last_slot_field = usage->hid; | 1627 | features->last_slot_field = usage->hid; |
1505 | wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); | 1628 | wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); |
1506 | break; | 1629 | break; |
1630 | case HID_DG_CONTACTCOUNT: | ||
1631 | wacom_wac->hid_data.cc_index = field->index; | ||
1632 | wacom_wac->hid_data.cc_value_index = usage->usage_index; | ||
1633 | break; | ||
1507 | } | 1634 | } |
1508 | } | 1635 | } |
1509 | 1636 | ||
@@ -1515,6 +1642,10 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, | |||
1515 | bool prox = hid_data->tipswitch && | 1642 | bool prox = hid_data->tipswitch && |
1516 | !wacom_wac->shared->stylus_in_proximity; | 1643 | !wacom_wac->shared->stylus_in_proximity; |
1517 | 1644 | ||
1645 | wacom_wac->hid_data.num_received++; | ||
1646 | if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected) | ||
1647 | return; | ||
1648 | |||
1518 | if (mt) { | 1649 | if (mt) { |
1519 | int slot; | 1650 | int slot; |
1520 | 1651 | ||
@@ -1531,6 +1662,13 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, | |||
1531 | hid_data->x); | 1662 | hid_data->x); |
1532 | input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y, | 1663 | input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y, |
1533 | hid_data->y); | 1664 | hid_data->y); |
1665 | |||
1666 | if (test_bit(ABS_MT_TOUCH_MAJOR, input->absbit)) { | ||
1667 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, max(hid_data->width, hid_data->height)); | ||
1668 | input_report_abs(input, ABS_MT_TOUCH_MINOR, min(hid_data->width, hid_data->height)); | ||
1669 | if (hid_data->width != hid_data->height) | ||
1670 | input_report_abs(input, ABS_MT_ORIENTATION, hid_data->width <= hid_data->height ? 0 : 1); | ||
1671 | } | ||
1534 | } | 1672 | } |
1535 | } | 1673 | } |
1536 | 1674 | ||
@@ -1547,6 +1685,12 @@ static int wacom_wac_finger_event(struct hid_device *hdev, | |||
1547 | case HID_GD_Y: | 1685 | case HID_GD_Y: |
1548 | wacom_wac->hid_data.y = value; | 1686 | wacom_wac->hid_data.y = value; |
1549 | break; | 1687 | break; |
1688 | case HID_DG_WIDTH: | ||
1689 | wacom_wac->hid_data.width = value; | ||
1690 | break; | ||
1691 | case HID_DG_HEIGHT: | ||
1692 | wacom_wac->hid_data.height = value; | ||
1693 | break; | ||
1550 | case HID_DG_CONTACTID: | 1694 | case HID_DG_CONTACTID: |
1551 | wacom_wac->hid_data.id = value; | 1695 | wacom_wac->hid_data.id = value; |
1552 | break; | 1696 | break; |
@@ -1564,6 +1708,24 @@ static int wacom_wac_finger_event(struct hid_device *hdev, | |||
1564 | return 0; | 1708 | return 0; |
1565 | } | 1709 | } |
1566 | 1710 | ||
1711 | static void wacom_wac_finger_pre_report(struct hid_device *hdev, | ||
1712 | struct hid_report *report) | ||
1713 | { | ||
1714 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
1715 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
1716 | struct hid_data* hid_data = &wacom_wac->hid_data; | ||
1717 | |||
1718 | if (hid_data->cc_index >= 0) { | ||
1719 | struct hid_field *field = report->field[hid_data->cc_index]; | ||
1720 | int value = field->value[hid_data->cc_value_index]; | ||
1721 | if (value) | ||
1722 | hid_data->num_expected = value; | ||
1723 | } | ||
1724 | else { | ||
1725 | hid_data->num_expected = wacom_wac->features.touch_max; | ||
1726 | } | ||
1727 | } | ||
1728 | |||
1567 | static void wacom_wac_finger_report(struct hid_device *hdev, | 1729 | static void wacom_wac_finger_report(struct hid_device *hdev, |
1568 | struct hid_report *report) | 1730 | struct hid_report *report) |
1569 | { | 1731 | { |
@@ -1572,10 +1734,18 @@ static void wacom_wac_finger_report(struct hid_device *hdev, | |||
1572 | struct input_dev *input = wacom_wac->touch_input; | 1734 | struct input_dev *input = wacom_wac->touch_input; |
1573 | unsigned touch_max = wacom_wac->features.touch_max; | 1735 | unsigned touch_max = wacom_wac->features.touch_max; |
1574 | 1736 | ||
1737 | /* If more packets of data are expected, give us a chance to | ||
1738 | * process them rather than immediately syncing a partial | ||
1739 | * update. | ||
1740 | */ | ||
1741 | if (wacom_wac->hid_data.num_received < wacom_wac->hid_data.num_expected) | ||
1742 | return; | ||
1743 | |||
1575 | if (touch_max > 1) | 1744 | if (touch_max > 1) |
1576 | input_mt_sync_frame(input); | 1745 | input_mt_sync_frame(input); |
1577 | 1746 | ||
1578 | input_sync(input); | 1747 | input_sync(input); |
1748 | wacom_wac->hid_data.num_received = 0; | ||
1579 | 1749 | ||
1580 | /* keep touch state for pen event */ | 1750 | /* keep touch state for pen event */ |
1581 | wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac); | 1751 | wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac); |
@@ -1615,6 +1785,25 @@ int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, | |||
1615 | return 0; | 1785 | return 0; |
1616 | } | 1786 | } |
1617 | 1787 | ||
1788 | static void wacom_report_events(struct hid_device *hdev, struct hid_report *report) | ||
1789 | { | ||
1790 | int r; | ||
1791 | |||
1792 | for (r = 0; r < report->maxfield; r++) { | ||
1793 | struct hid_field *field; | ||
1794 | unsigned count, n; | ||
1795 | |||
1796 | field = report->field[r]; | ||
1797 | count = field->report_count; | ||
1798 | |||
1799 | if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) | ||
1800 | continue; | ||
1801 | |||
1802 | for (n = 0; n < count; n++) | ||
1803 | wacom_wac_event(hdev, field, &field->usage[n], field->value[n]); | ||
1804 | } | ||
1805 | } | ||
1806 | |||
1618 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | 1807 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) |
1619 | { | 1808 | { |
1620 | struct wacom *wacom = hid_get_drvdata(hdev); | 1809 | struct wacom *wacom = hid_get_drvdata(hdev); |
@@ -1625,6 +1814,14 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | |||
1625 | return; | 1814 | return; |
1626 | 1815 | ||
1627 | if (WACOM_PEN_FIELD(field)) | 1816 | if (WACOM_PEN_FIELD(field)) |
1817 | wacom_wac_pen_pre_report(hdev, report); | ||
1818 | |||
1819 | if (WACOM_FINGER_FIELD(field)) | ||
1820 | wacom_wac_finger_pre_report(hdev, report); | ||
1821 | |||
1822 | wacom_report_events(hdev, report); | ||
1823 | |||
1824 | if (WACOM_PEN_FIELD(field)) | ||
1628 | return wacom_wac_pen_report(hdev, report); | 1825 | return wacom_wac_pen_report(hdev, report); |
1629 | 1826 | ||
1630 | if (WACOM_FINGER_FIELD(field)) | 1827 | if (WACOM_FINGER_FIELD(field)) |
@@ -1699,7 +1896,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) | |||
1699 | int y = (data[3] << 4) | (data[4] & 0x0f); | 1896 | int y = (data[3] << 4) | (data[4] & 0x0f); |
1700 | int width, height; | 1897 | int width, height; |
1701 | 1898 | ||
1702 | if (features->type >= INTUOSPS && features->type <= INTUOSPL) { | 1899 | if (features->type >= INTUOSPS && features->type <= INTUOSHT) { |
1703 | width = data[5] * 100; | 1900 | width = data[5] * 100; |
1704 | height = data[6] * 100; | 1901 | height = data[6] * 100; |
1705 | } else { | 1902 | } else { |
@@ -2118,6 +2315,13 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
2118 | sync = wacom_wireless_irq(wacom_wac, len); | 2315 | sync = wacom_wireless_irq(wacom_wac, len); |
2119 | break; | 2316 | break; |
2120 | 2317 | ||
2318 | case REMOTE: | ||
2319 | if (wacom_wac->data[0] == WACOM_REPORT_DEVICE_LIST) | ||
2320 | sync = wacom_remote_status_irq(wacom_wac, len); | ||
2321 | else | ||
2322 | sync = wacom_remote_irq(wacom_wac, len); | ||
2323 | break; | ||
2324 | |||
2121 | default: | 2325 | default: |
2122 | sync = false; | 2326 | sync = false; |
2123 | break; | 2327 | break; |
@@ -2223,10 +2427,13 @@ void wacom_setup_device_quirks(struct wacom *wacom) | |||
2223 | * 0, whose HID descriptor has an application usage of 0xFF0D | 2427 | * 0, whose HID descriptor has an application usage of 0xFF0D |
2224 | * (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back | 2428 | * (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back |
2225 | * out through the HID_GENERIC device created for interface 1, | 2429 | * out through the HID_GENERIC device created for interface 1, |
2226 | * so rewrite this one to be of type BTN_TOOL_FINGER. | 2430 | * so rewrite this one to be of type WACOM_DEVICETYPE_TOUCH. |
2227 | */ | 2431 | */ |
2228 | if (features->type == BAMBOO_PAD) | 2432 | if (features->type == BAMBOO_PAD) |
2229 | features->device_type |= WACOM_DEVICETYPE_TOUCH; | 2433 | features->device_type = WACOM_DEVICETYPE_TOUCH; |
2434 | |||
2435 | if (features->type == REMOTE) | ||
2436 | features->device_type = WACOM_DEVICETYPE_PAD; | ||
2230 | 2437 | ||
2231 | if (wacom->hdev->bus == BUS_BLUETOOTH) | 2438 | if (wacom->hdev->bus == BUS_BLUETOOTH) |
2232 | features->quirks |= WACOM_QUIRK_BATTERY; | 2439 | features->quirks |= WACOM_QUIRK_BATTERY; |
@@ -2242,13 +2449,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) | |||
2242 | } | 2449 | } |
2243 | 2450 | ||
2244 | if (features->type == WIRELESS) { | 2451 | if (features->type == WIRELESS) { |
2245 | 2452 | if (features->device_type == WACOM_DEVICETYPE_WL_MONITOR) { | |
2246 | /* monitor never has input and pen/touch have delayed create */ | ||
2247 | features->quirks |= WACOM_QUIRK_NO_INPUT; | ||
2248 | |||
2249 | /* must be monitor interface if no device_type set */ | ||
2250 | if (features->device_type == WACOM_DEVICETYPE_NONE) { | ||
2251 | features->quirks |= WACOM_QUIRK_MONITOR; | ||
2252 | features->quirks |= WACOM_QUIRK_BATTERY; | 2453 | features->quirks |= WACOM_QUIRK_BATTERY; |
2253 | } | 2454 | } |
2254 | } | 2455 | } |
@@ -2513,11 +2714,23 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, | |||
2513 | return 0; | 2714 | return 0; |
2514 | } | 2715 | } |
2515 | 2716 | ||
2717 | static void wacom_setup_numbered_buttons(struct input_dev *input_dev, | ||
2718 | int button_count) | ||
2719 | { | ||
2720 | int i; | ||
2721 | |||
2722 | for (i = 0; i < button_count && i < 10; i++) | ||
2723 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2724 | for (i = 10; i < button_count && i < 16; i++) | ||
2725 | __set_bit(BTN_A + (i-10), input_dev->keybit); | ||
2726 | for (i = 16; i < button_count && i < 18; i++) | ||
2727 | __set_bit(BTN_BASE + (i-16), input_dev->keybit); | ||
2728 | } | ||
2729 | |||
2516 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | 2730 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, |
2517 | struct wacom_wac *wacom_wac) | 2731 | struct wacom_wac *wacom_wac) |
2518 | { | 2732 | { |
2519 | struct wacom_features *features = &wacom_wac->features; | 2733 | struct wacom_features *features = &wacom_wac->features; |
2520 | int i; | ||
2521 | 2734 | ||
2522 | if (!(features->device_type & WACOM_DEVICETYPE_PAD)) | 2735 | if (!(features->device_type & WACOM_DEVICETYPE_PAD)) |
2523 | return -ENODEV; | 2736 | return -ENODEV; |
@@ -2534,10 +2747,14 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2534 | /* kept for making udev and libwacom accepting the pad */ | 2747 | /* kept for making udev and libwacom accepting the pad */ |
2535 | __set_bit(BTN_STYLUS, input_dev->keybit); | 2748 | __set_bit(BTN_STYLUS, input_dev->keybit); |
2536 | 2749 | ||
2750 | wacom_setup_numbered_buttons(input_dev, features->numbered_buttons); | ||
2751 | |||
2537 | switch (features->type) { | 2752 | switch (features->type) { |
2753 | |||
2754 | case CINTIQ_HYBRID: | ||
2755 | case DTK: | ||
2756 | case DTUS: | ||
2538 | case GRAPHIRE_BT: | 2757 | case GRAPHIRE_BT: |
2539 | __set_bit(BTN_0, input_dev->keybit); | ||
2540 | __set_bit(BTN_1, input_dev->keybit); | ||
2541 | break; | 2758 | break; |
2542 | 2759 | ||
2543 | case WACOM_MO: | 2760 | case WACOM_MO: |
@@ -2555,16 +2772,6 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2555 | break; | 2772 | break; |
2556 | 2773 | ||
2557 | case WACOM_24HD: | 2774 | case WACOM_24HD: |
2558 | __set_bit(BTN_A, input_dev->keybit); | ||
2559 | __set_bit(BTN_B, input_dev->keybit); | ||
2560 | __set_bit(BTN_C, input_dev->keybit); | ||
2561 | __set_bit(BTN_X, input_dev->keybit); | ||
2562 | __set_bit(BTN_Y, input_dev->keybit); | ||
2563 | __set_bit(BTN_Z, input_dev->keybit); | ||
2564 | |||
2565 | for (i = 0; i < 10; i++) | ||
2566 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2567 | |||
2568 | __set_bit(KEY_PROG1, input_dev->keybit); | 2775 | __set_bit(KEY_PROG1, input_dev->keybit); |
2569 | __set_bit(KEY_PROG2, input_dev->keybit); | 2776 | __set_bit(KEY_PROG2, input_dev->keybit); |
2570 | __set_bit(KEY_PROG3, input_dev->keybit); | 2777 | __set_bit(KEY_PROG3, input_dev->keybit); |
@@ -2586,12 +2793,6 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2586 | __set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit); | 2793 | __set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit); |
2587 | break; | 2794 | break; |
2588 | 2795 | ||
2589 | case DTK: | ||
2590 | for (i = 0; i < 6; i++) | ||
2591 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2592 | |||
2593 | break; | ||
2594 | |||
2595 | case WACOM_22HD: | 2796 | case WACOM_22HD: |
2596 | __set_bit(KEY_PROG1, input_dev->keybit); | 2797 | __set_bit(KEY_PROG1, input_dev->keybit); |
2597 | __set_bit(KEY_PROG2, input_dev->keybit); | 2798 | __set_bit(KEY_PROG2, input_dev->keybit); |
@@ -2599,52 +2800,22 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2599 | /* fall through */ | 2800 | /* fall through */ |
2600 | 2801 | ||
2601 | case WACOM_21UX2: | 2802 | case WACOM_21UX2: |
2602 | __set_bit(BTN_A, input_dev->keybit); | ||
2603 | __set_bit(BTN_B, input_dev->keybit); | ||
2604 | __set_bit(BTN_C, input_dev->keybit); | ||
2605 | __set_bit(BTN_X, input_dev->keybit); | ||
2606 | __set_bit(BTN_Y, input_dev->keybit); | ||
2607 | __set_bit(BTN_Z, input_dev->keybit); | ||
2608 | __set_bit(BTN_BASE, input_dev->keybit); | ||
2609 | __set_bit(BTN_BASE2, input_dev->keybit); | ||
2610 | /* fall through */ | ||
2611 | |||
2612 | case WACOM_BEE: | 2803 | case WACOM_BEE: |
2613 | __set_bit(BTN_8, input_dev->keybit); | ||
2614 | __set_bit(BTN_9, input_dev->keybit); | ||
2615 | /* fall through */ | ||
2616 | |||
2617 | case CINTIQ: | 2804 | case CINTIQ: |
2618 | for (i = 0; i < 8; i++) | ||
2619 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2620 | |||
2621 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | 2805 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
2622 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | 2806 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
2623 | break; | 2807 | break; |
2624 | 2808 | ||
2625 | case WACOM_13HD: | 2809 | case WACOM_13HD: |
2626 | for (i = 0; i < 9; i++) | ||
2627 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2628 | |||
2629 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 2810 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
2630 | break; | 2811 | break; |
2631 | 2812 | ||
2632 | case INTUOS3: | 2813 | case INTUOS3: |
2633 | case INTUOS3L: | 2814 | case INTUOS3L: |
2634 | __set_bit(BTN_4, input_dev->keybit); | ||
2635 | __set_bit(BTN_5, input_dev->keybit); | ||
2636 | __set_bit(BTN_6, input_dev->keybit); | ||
2637 | __set_bit(BTN_7, input_dev->keybit); | ||
2638 | |||
2639 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | 2815 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
2640 | /* fall through */ | 2816 | /* fall through */ |
2641 | 2817 | ||
2642 | case INTUOS3S: | 2818 | case INTUOS3S: |
2643 | __set_bit(BTN_0, input_dev->keybit); | ||
2644 | __set_bit(BTN_1, input_dev->keybit); | ||
2645 | __set_bit(BTN_2, input_dev->keybit); | ||
2646 | __set_bit(BTN_3, input_dev->keybit); | ||
2647 | |||
2648 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | 2819 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
2649 | break; | 2820 | break; |
2650 | 2821 | ||
@@ -2652,15 +2823,8 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2652 | case INTUOS5L: | 2823 | case INTUOS5L: |
2653 | case INTUOSPM: | 2824 | case INTUOSPM: |
2654 | case INTUOSPL: | 2825 | case INTUOSPL: |
2655 | __set_bit(BTN_7, input_dev->keybit); | ||
2656 | __set_bit(BTN_8, input_dev->keybit); | ||
2657 | /* fall through */ | ||
2658 | |||
2659 | case INTUOS5S: | 2826 | case INTUOS5S: |
2660 | case INTUOSPS: | 2827 | case INTUOSPS: |
2661 | for (i = 0; i < 7; i++) | ||
2662 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2663 | |||
2664 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 2828 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
2665 | break; | 2829 | break; |
2666 | 2830 | ||
@@ -2675,28 +2839,10 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2675 | 2839 | ||
2676 | case INTUOS4: | 2840 | case INTUOS4: |
2677 | case INTUOS4L: | 2841 | case INTUOS4L: |
2678 | __set_bit(BTN_7, input_dev->keybit); | ||
2679 | __set_bit(BTN_8, input_dev->keybit); | ||
2680 | /* fall through */ | ||
2681 | |||
2682 | case INTUOS4S: | 2842 | case INTUOS4S: |
2683 | for (i = 0; i < 7; i++) | ||
2684 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2685 | |||
2686 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 2843 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
2687 | break; | 2844 | break; |
2688 | 2845 | ||
2689 | case CINTIQ_HYBRID: | ||
2690 | for (i = 0; i < 9; i++) | ||
2691 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2692 | |||
2693 | break; | ||
2694 | |||
2695 | case DTUS: | ||
2696 | for (i = 0; i < 4; i++) | ||
2697 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
2698 | break; | ||
2699 | |||
2700 | case INTUOSHT: | 2846 | case INTUOSHT: |
2701 | case BAMBOO_PT: | 2847 | case BAMBOO_PT: |
2702 | __clear_bit(ABS_MISC, input_dev->absbit); | 2848 | __clear_bit(ABS_MISC, input_dev->absbit); |
@@ -2708,6 +2854,11 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2708 | 2854 | ||
2709 | break; | 2855 | break; |
2710 | 2856 | ||
2857 | case REMOTE: | ||
2858 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | ||
2859 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | ||
2860 | break; | ||
2861 | |||
2711 | default: | 2862 | default: |
2712 | /* no pad supported */ | 2863 | /* no pad supported */ |
2713 | return -ENODEV; | 2864 | return -ENODEV; |
@@ -2723,7 +2874,7 @@ static const struct wacom_features wacom_features_0x10 = | |||
2723 | GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | 2874 | GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; |
2724 | static const struct wacom_features wacom_features_0x81 = | 2875 | static const struct wacom_features wacom_features_0x81 = |
2725 | { "Wacom Graphire BT", 16704, 12064, 511, 32, | 2876 | { "Wacom Graphire BT", 16704, 12064, 511, 32, |
2726 | GRAPHIRE_BT, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | 2877 | GRAPHIRE_BT, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES, 2 }; |
2727 | static const struct wacom_features wacom_features_0x11 = | 2878 | static const struct wacom_features wacom_features_0x11 = |
2728 | { "Wacom Graphire2 4x5", 10206, 7422, 511, 63, | 2879 | { "Wacom Graphire2 4x5", 10206, 7422, 511, 63, |
2729 | GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | 2880 | GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; |
@@ -2849,77 +3000,77 @@ static const struct wacom_features wacom_features_0x45 = | |||
2849 | INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 3000 | INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2850 | static const struct wacom_features wacom_features_0xB0 = | 3001 | static const struct wacom_features wacom_features_0xB0 = |
2851 | { "Wacom Intuos3 4x5", 25400, 20320, 1023, 63, | 3002 | { "Wacom Intuos3 4x5", 25400, 20320, 1023, 63, |
2852 | INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3003 | INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 }; |
2853 | static const struct wacom_features wacom_features_0xB1 = | 3004 | static const struct wacom_features wacom_features_0xB1 = |
2854 | { "Wacom Intuos3 6x8", 40640, 30480, 1023, 63, | 3005 | { "Wacom Intuos3 6x8", 40640, 30480, 1023, 63, |
2855 | INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3006 | INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 }; |
2856 | static const struct wacom_features wacom_features_0xB2 = | 3007 | static const struct wacom_features wacom_features_0xB2 = |
2857 | { "Wacom Intuos3 9x12", 60960, 45720, 1023, 63, | 3008 | { "Wacom Intuos3 9x12", 60960, 45720, 1023, 63, |
2858 | INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3009 | INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 }; |
2859 | static const struct wacom_features wacom_features_0xB3 = | 3010 | static const struct wacom_features wacom_features_0xB3 = |
2860 | { "Wacom Intuos3 12x12", 60960, 60960, 1023, 63, | 3011 | { "Wacom Intuos3 12x12", 60960, 60960, 1023, 63, |
2861 | INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3012 | INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 }; |
2862 | static const struct wacom_features wacom_features_0xB4 = | 3013 | static const struct wacom_features wacom_features_0xB4 = |
2863 | { "Wacom Intuos3 12x19", 97536, 60960, 1023, 63, | 3014 | { "Wacom Intuos3 12x19", 97536, 60960, 1023, 63, |
2864 | INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3015 | INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 }; |
2865 | static const struct wacom_features wacom_features_0xB5 = | 3016 | static const struct wacom_features wacom_features_0xB5 = |
2866 | { "Wacom Intuos3 6x11", 54204, 31750, 1023, 63, | 3017 | { "Wacom Intuos3 6x11", 54204, 31750, 1023, 63, |
2867 | INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3018 | INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 }; |
2868 | static const struct wacom_features wacom_features_0xB7 = | 3019 | static const struct wacom_features wacom_features_0xB7 = |
2869 | { "Wacom Intuos3 4x6", 31496, 19685, 1023, 63, | 3020 | { "Wacom Intuos3 4x6", 31496, 19685, 1023, 63, |
2870 | INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3021 | INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 }; |
2871 | static const struct wacom_features wacom_features_0xB8 = | 3022 | static const struct wacom_features wacom_features_0xB8 = |
2872 | { "Wacom Intuos4 4x6", 31496, 19685, 2047, 63, | 3023 | { "Wacom Intuos4 4x6", 31496, 19685, 2047, 63, |
2873 | INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3024 | INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 }; |
2874 | static const struct wacom_features wacom_features_0xB9 = | 3025 | static const struct wacom_features wacom_features_0xB9 = |
2875 | { "Wacom Intuos4 6x9", 44704, 27940, 2047, 63, | 3026 | { "Wacom Intuos4 6x9", 44704, 27940, 2047, 63, |
2876 | INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3027 | INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 }; |
2877 | static const struct wacom_features wacom_features_0xBA = | 3028 | static const struct wacom_features wacom_features_0xBA = |
2878 | { "Wacom Intuos4 8x13", 65024, 40640, 2047, 63, | 3029 | { "Wacom Intuos4 8x13", 65024, 40640, 2047, 63, |
2879 | INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3030 | INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 }; |
2880 | static const struct wacom_features wacom_features_0xBB = | 3031 | static const struct wacom_features wacom_features_0xBB = |
2881 | { "Wacom Intuos4 12x19", 97536, 60960, 2047, 63, | 3032 | { "Wacom Intuos4 12x19", 97536, 60960, 2047, 63, |
2882 | INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3033 | INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 }; |
2883 | static const struct wacom_features wacom_features_0xBC = | 3034 | static const struct wacom_features wacom_features_0xBC = |
2884 | { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, | 3035 | { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, |
2885 | INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3036 | INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 }; |
2886 | static const struct wacom_features wacom_features_0xBD = | 3037 | static const struct wacom_features wacom_features_0xBD = |
2887 | { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, | 3038 | { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, |
2888 | INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3039 | INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 }; |
2889 | static const struct wacom_features wacom_features_0x26 = | 3040 | static const struct wacom_features wacom_features_0x26 = |
2890 | { "Wacom Intuos5 touch S", 31496, 19685, 2047, 63, | 3041 | { "Wacom Intuos5 touch S", 31496, 19685, 2047, 63, |
2891 | INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; | 3042 | INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 16 }; |
2892 | static const struct wacom_features wacom_features_0x27 = | 3043 | static const struct wacom_features wacom_features_0x27 = |
2893 | { "Wacom Intuos5 touch M", 44704, 27940, 2047, 63, | 3044 | { "Wacom Intuos5 touch M", 44704, 27940, 2047, 63, |
2894 | INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; | 3045 | INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16 }; |
2895 | static const struct wacom_features wacom_features_0x28 = | 3046 | static const struct wacom_features wacom_features_0x28 = |
2896 | { "Wacom Intuos5 touch L", 65024, 40640, 2047, 63, | 3047 | { "Wacom Intuos5 touch L", 65024, 40640, 2047, 63, |
2897 | INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; | 3048 | INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16 }; |
2898 | static const struct wacom_features wacom_features_0x29 = | 3049 | static const struct wacom_features wacom_features_0x29 = |
2899 | { "Wacom Intuos5 S", 31496, 19685, 2047, 63, | 3050 | { "Wacom Intuos5 S", 31496, 19685, 2047, 63, |
2900 | INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3051 | INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 }; |
2901 | static const struct wacom_features wacom_features_0x2A = | 3052 | static const struct wacom_features wacom_features_0x2A = |
2902 | { "Wacom Intuos5 M", 44704, 27940, 2047, 63, | 3053 | { "Wacom Intuos5 M", 44704, 27940, 2047, 63, |
2903 | INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3054 | INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 }; |
2904 | static const struct wacom_features wacom_features_0x314 = | 3055 | static const struct wacom_features wacom_features_0x314 = |
2905 | { "Wacom Intuos Pro S", 31496, 19685, 2047, 63, | 3056 | { "Wacom Intuos Pro S", 31496, 19685, 2047, 63, |
2906 | INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, | 3057 | INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 16, |
2907 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3058 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2908 | static const struct wacom_features wacom_features_0x315 = | 3059 | static const struct wacom_features wacom_features_0x315 = |
2909 | { "Wacom Intuos Pro M", 44704, 27940, 2047, 63, | 3060 | { "Wacom Intuos Pro M", 44704, 27940, 2047, 63, |
2910 | INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, | 3061 | INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16, |
2911 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3062 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2912 | static const struct wacom_features wacom_features_0x317 = | 3063 | static const struct wacom_features wacom_features_0x317 = |
2913 | { "Wacom Intuos Pro L", 65024, 40640, 2047, 63, | 3064 | { "Wacom Intuos Pro L", 65024, 40640, 2047, 63, |
2914 | INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, | 3065 | INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16, |
2915 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3066 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2916 | static const struct wacom_features wacom_features_0xF4 = | 3067 | static const struct wacom_features wacom_features_0xF4 = |
2917 | { "Wacom Cintiq 24HD", 104080, 65200, 2047, 63, | 3068 | { "Wacom Cintiq 24HD", 104080, 65200, 2047, 63, |
2918 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3069 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16, |
2919 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | 3070 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; |
2920 | static const struct wacom_features wacom_features_0xF8 = | 3071 | static const struct wacom_features wacom_features_0xF8 = |
2921 | { "Wacom Cintiq 24HD touch", 104080, 65200, 2047, 63, /* Pen */ | 3072 | { "Wacom Cintiq 24HD touch", 104080, 65200, 2047, 63, /* Pen */ |
2922 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3073 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16, |
2923 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | 3074 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, |
2924 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; | 3075 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; |
2925 | static const struct wacom_features wacom_features_0xF6 = | 3076 | static const struct wacom_features wacom_features_0xF6 = |
@@ -2928,11 +3079,11 @@ static const struct wacom_features wacom_features_0xF6 = | |||
2928 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3079 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2929 | static const struct wacom_features wacom_features_0x32A = | 3080 | static const struct wacom_features wacom_features_0x32A = |
2930 | { "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63, | 3081 | { "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63, |
2931 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3082 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, |
2932 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | 3083 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; |
2933 | static const struct wacom_features wacom_features_0x32B = | 3084 | static const struct wacom_features wacom_features_0x32B = |
2934 | { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, | 3085 | { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, |
2935 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3086 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0, |
2936 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | 3087 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, |
2937 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C }; | 3088 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C }; |
2938 | static const struct wacom_features wacom_features_0x32C = | 3089 | static const struct wacom_features wacom_features_0x32C = |
@@ -2940,20 +3091,20 @@ static const struct wacom_features wacom_features_0x32C = | |||
2940 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 }; | 3091 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 }; |
2941 | static const struct wacom_features wacom_features_0x3F = | 3092 | static const struct wacom_features wacom_features_0x3F = |
2942 | { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63, | 3093 | { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63, |
2943 | CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3094 | CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 }; |
2944 | static const struct wacom_features wacom_features_0xC5 = | 3095 | static const struct wacom_features wacom_features_0xC5 = |
2945 | { "Wacom Cintiq 20WSX", 86680, 54180, 1023, 63, | 3096 | { "Wacom Cintiq 20WSX", 86680, 54180, 1023, 63, |
2946 | WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3097 | WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 }; |
2947 | static const struct wacom_features wacom_features_0xC6 = | 3098 | static const struct wacom_features wacom_features_0xC6 = |
2948 | { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63, | 3099 | { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63, |
2949 | WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 3100 | WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 }; |
2950 | static const struct wacom_features wacom_features_0x304 = | 3101 | static const struct wacom_features wacom_features_0x304 = |
2951 | { "Wacom Cintiq 13HD", 59152, 33448, 1023, 63, | 3102 | { "Wacom Cintiq 13HD", 59152, 33448, 1023, 63, |
2952 | WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3103 | WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, |
2953 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | 3104 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; |
2954 | static const struct wacom_features wacom_features_0x333 = | 3105 | static const struct wacom_features wacom_features_0x333 = |
2955 | { "Wacom Cintiq 13HD touch", 59152, 33448, 2047, 63, | 3106 | { "Wacom Cintiq 13HD touch", 59152, 33448, 2047, 63, |
2956 | WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3107 | WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, |
2957 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | 3108 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, |
2958 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x335 }; | 3109 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x335 }; |
2959 | static const struct wacom_features wacom_features_0x335 = | 3110 | static const struct wacom_features wacom_features_0x335 = |
@@ -2972,22 +3123,22 @@ static const struct wacom_features wacom_features_0xF0 = | |||
2972 | DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 3123 | DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2973 | static const struct wacom_features wacom_features_0xFB = | 3124 | static const struct wacom_features wacom_features_0xFB = |
2974 | { "Wacom DTU1031", 21896, 13760, 511, 0, | 3125 | { "Wacom DTU1031", 21896, 13760, 511, 0, |
2975 | DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 3126 | DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4, |
2976 | WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; | 3127 | WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; |
2977 | static const struct wacom_features wacom_features_0x32F = | 3128 | static const struct wacom_features wacom_features_0x32F = |
2978 | { "Wacom DTU1031X", 22472, 12728, 511, 0, | 3129 | { "Wacom DTU1031X", 22472, 12728, 511, 0, |
2979 | DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 3130 | DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 0, |
2980 | WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; | 3131 | WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; |
2981 | static const struct wacom_features wacom_features_0x336 = | 3132 | static const struct wacom_features wacom_features_0x336 = |
2982 | { "Wacom DTU1141", 23472, 13203, 1023, 0, | 3133 | { "Wacom DTU1141", 23472, 13203, 1023, 0, |
2983 | DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 3134 | DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; |
2984 | static const struct wacom_features wacom_features_0x57 = | 3135 | static const struct wacom_features wacom_features_0x57 = |
2985 | { "Wacom DTK2241", 95640, 54060, 2047, 63, | 3136 | { "Wacom DTK2241", 95640, 54060, 2047, 63, |
2986 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3137 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6, |
2987 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | 3138 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; |
2988 | static const struct wacom_features wacom_features_0x59 = /* Pen */ | 3139 | static const struct wacom_features wacom_features_0x59 = /* Pen */ |
2989 | { "Wacom DTH2242", 95640, 54060, 2047, 63, | 3140 | { "Wacom DTH2242", 95640, 54060, 2047, 63, |
2990 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3141 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6, |
2991 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | 3142 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, |
2992 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; | 3143 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; |
2993 | static const struct wacom_features wacom_features_0x5D = /* Touch */ | 3144 | static const struct wacom_features wacom_features_0x5D = /* Touch */ |
@@ -2996,15 +3147,15 @@ static const struct wacom_features wacom_features_0x5D = /* Touch */ | |||
2996 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3147 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2997 | static const struct wacom_features wacom_features_0xCC = | 3148 | static const struct wacom_features wacom_features_0xCC = |
2998 | { "Wacom Cintiq 21UX2", 86800, 65200, 2047, 63, | 3149 | { "Wacom Cintiq 21UX2", 86800, 65200, 2047, 63, |
2999 | WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3150 | WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18, |
3000 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | 3151 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; |
3001 | static const struct wacom_features wacom_features_0xFA = | 3152 | static const struct wacom_features wacom_features_0xFA = |
3002 | { "Wacom Cintiq 22HD", 95440, 53860, 2047, 63, | 3153 | { "Wacom Cintiq 22HD", 95440, 53860, 2047, 63, |
3003 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3154 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18, |
3004 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | 3155 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; |
3005 | static const struct wacom_features wacom_features_0x5B = | 3156 | static const struct wacom_features wacom_features_0x5B = |
3006 | { "Wacom Cintiq 22HDT", 95440, 53860, 2047, 63, | 3157 | { "Wacom Cintiq 22HDT", 95440, 53860, 2047, 63, |
3007 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3158 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18, |
3008 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | 3159 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, |
3009 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; | 3160 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; |
3010 | static const struct wacom_features wacom_features_0x5E = | 3161 | static const struct wacom_features wacom_features_0x5E = |
@@ -3151,7 +3302,7 @@ static const struct wacom_features wacom_features_0x6004 = | |||
3151 | TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 3302 | TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
3152 | static const struct wacom_features wacom_features_0x307 = | 3303 | static const struct wacom_features wacom_features_0x307 = |
3153 | { "Wacom ISDv5 307", 59152, 33448, 2047, 63, | 3304 | { "Wacom ISDv5 307", 59152, 33448, 2047, 63, |
3154 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3305 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, |
3155 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | 3306 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, |
3156 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; | 3307 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; |
3157 | static const struct wacom_features wacom_features_0x309 = | 3308 | static const struct wacom_features wacom_features_0x309 = |
@@ -3160,7 +3311,7 @@ static const struct wacom_features wacom_features_0x309 = | |||
3160 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3311 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
3161 | static const struct wacom_features wacom_features_0x30A = | 3312 | static const struct wacom_features wacom_features_0x30A = |
3162 | { "Wacom ISDv5 30A", 59152, 33448, 2047, 63, | 3313 | { "Wacom ISDv5 30A", 59152, 33448, 2047, 63, |
3163 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 3314 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, |
3164 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | 3315 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, |
3165 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C }; | 3316 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C }; |
3166 | static const struct wacom_features wacom_features_0x30C = | 3317 | static const struct wacom_features wacom_features_0x30C = |
@@ -3177,6 +3328,10 @@ static const struct wacom_features wacom_features_0x323 = | |||
3177 | { "Wacom Intuos P M", 21600, 13500, 1023, 31, | 3328 | { "Wacom Intuos P M", 21600, 13500, 1023, 31, |
3178 | INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 3329 | INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
3179 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3330 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
3331 | static const struct wacom_features wacom_features_0x331 = | ||
3332 | { "Wacom Express Key Remote", 0, 0, 0, 0, | ||
3333 | REMOTE, 0, 0, 18, .check_for_hid_type = true, | ||
3334 | .hid_type = HID_TYPE_USBNONE }; | ||
3180 | 3335 | ||
3181 | static const struct wacom_features wacom_features_HID_ANY_ID = | 3336 | static const struct wacom_features wacom_features_HID_ANY_ID = |
3182 | { "Wacom HID", .type = HID_GENERIC }; | 3337 | { "Wacom HID", .type = HID_GENERIC }; |
@@ -3332,6 +3487,7 @@ const struct hid_device_id wacom_ids[] = { | |||
3332 | { USB_DEVICE_WACOM(0x32B) }, | 3487 | { USB_DEVICE_WACOM(0x32B) }, |
3333 | { USB_DEVICE_WACOM(0x32C) }, | 3488 | { USB_DEVICE_WACOM(0x32C) }, |
3334 | { USB_DEVICE_WACOM(0x32F) }, | 3489 | { USB_DEVICE_WACOM(0x32F) }, |
3490 | { USB_DEVICE_WACOM(0x331) }, | ||
3335 | { USB_DEVICE_WACOM(0x333) }, | 3491 | { USB_DEVICE_WACOM(0x333) }, |
3336 | { USB_DEVICE_WACOM(0x335) }, | 3492 | { USB_DEVICE_WACOM(0x335) }, |
3337 | { USB_DEVICE_WACOM(0x336) }, | 3493 | { USB_DEVICE_WACOM(0x336) }, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 2978c303909d..1e270d401e18 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #define WACOM_PKGLEN_MAX 192 | 16 | #define WACOM_PKGLEN_MAX 192 |
17 | 17 | ||
18 | #define WACOM_NAME_MAX 64 | 18 | #define WACOM_NAME_MAX 64 |
19 | #define WACOM_MAX_REMOTES 5 | ||
20 | #define WACOM_STATUS_UNKNOWN 255 | ||
19 | 21 | ||
20 | /* packet length for individual models */ | 22 | /* packet length for individual models */ |
21 | #define WACOM_PKGLEN_BBFUN 9 | 23 | #define WACOM_PKGLEN_BBFUN 9 |
@@ -65,11 +67,11 @@ | |||
65 | #define WACOM_REPORT_USB 192 | 67 | #define WACOM_REPORT_USB 192 |
66 | #define WACOM_REPORT_BPAD_PEN 3 | 68 | #define WACOM_REPORT_BPAD_PEN 3 |
67 | #define WACOM_REPORT_BPAD_TOUCH 16 | 69 | #define WACOM_REPORT_BPAD_TOUCH 16 |
70 | #define WACOM_REPORT_DEVICE_LIST 16 | ||
71 | #define WACOM_REPORT_REMOTE 17 | ||
68 | 72 | ||
69 | /* device quirks */ | 73 | /* device quirks */ |
70 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 | 74 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 |
71 | #define WACOM_QUIRK_NO_INPUT 0x0002 | ||
72 | #define WACOM_QUIRK_MONITOR 0x0004 | ||
73 | #define WACOM_QUIRK_BATTERY 0x0008 | 75 | #define WACOM_QUIRK_BATTERY 0x0008 |
74 | 76 | ||
75 | /* device types */ | 77 | /* device types */ |
@@ -77,6 +79,7 @@ | |||
77 | #define WACOM_DEVICETYPE_PEN 0x0001 | 79 | #define WACOM_DEVICETYPE_PEN 0x0001 |
78 | #define WACOM_DEVICETYPE_TOUCH 0x0002 | 80 | #define WACOM_DEVICETYPE_TOUCH 0x0002 |
79 | #define WACOM_DEVICETYPE_PAD 0x0004 | 81 | #define WACOM_DEVICETYPE_PAD 0x0004 |
82 | #define WACOM_DEVICETYPE_WL_MONITOR 0x0008 | ||
80 | 83 | ||
81 | #define WACOM_VENDORDEFINED_PEN 0xff0d0001 | 84 | #define WACOM_VENDORDEFINED_PEN 0xff0d0001 |
82 | 85 | ||
@@ -130,6 +133,7 @@ enum { | |||
130 | WACOM_24HDT, | 133 | WACOM_24HDT, |
131 | WACOM_27QHDT, | 134 | WACOM_27QHDT, |
132 | BAMBOO_PAD, | 135 | BAMBOO_PAD, |
136 | REMOTE, | ||
133 | TABLETPC, /* add new TPC below */ | 137 | TABLETPC, /* add new TPC below */ |
134 | TABLETPCE, | 138 | TABLETPCE, |
135 | TABLETPC2FG, | 139 | TABLETPC2FG, |
@@ -149,6 +153,7 @@ struct wacom_features { | |||
149 | int type; | 153 | int type; |
150 | int x_resolution; | 154 | int x_resolution; |
151 | int y_resolution; | 155 | int y_resolution; |
156 | int numbered_buttons; | ||
152 | int x_min; | 157 | int x_min; |
153 | int y_min; | 158 | int y_min; |
154 | int device_type; | 159 | int device_type; |
@@ -193,6 +198,10 @@ struct hid_data { | |||
193 | int width; | 198 | int width; |
194 | int height; | 199 | int height; |
195 | int id; | 200 | int id; |
201 | int cc_index; | ||
202 | int cc_value_index; | ||
203 | int num_expected; | ||
204 | int num_received; | ||
196 | }; | 205 | }; |
197 | 206 | ||
198 | struct wacom_wac { | 207 | struct wacom_wac { |
@@ -204,7 +213,7 @@ struct wacom_wac { | |||
204 | unsigned char data[WACOM_PKGLEN_MAX]; | 213 | unsigned char data[WACOM_PKGLEN_MAX]; |
205 | int tool[2]; | 214 | int tool[2]; |
206 | int id[2]; | 215 | int id[2]; |
207 | __u32 serial[2]; | 216 | __u32 serial[5]; |
208 | bool reporting_data; | 217 | bool reporting_data; |
209 | struct wacom_features features; | 218 | struct wacom_features features; |
210 | struct wacom_shared *shared; | 219 | struct wacom_shared *shared; |