diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/Kconfig | 22 | ||||
-rw-r--r-- | drivers/hid/Makefile | 2 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 36 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 12 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-lenovo.c | 13 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-dj.c | 397 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-dj.h | 125 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-hidpp.c | 1241 | ||||
-rw-r--r-- | drivers/hid/hid-microsoft.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-multitouch.c | 27 | ||||
-rw-r--r-- | drivers/hid/hid-plantronics.c | 55 | ||||
-rw-r--r-- | drivers/hid/hid-rmi.c | 83 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-kone.c | 9 | ||||
-rw-r--r-- | drivers/hid/hid-saitek.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 150 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 16 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 39 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 1 | ||||
-rw-r--r-- | drivers/hid/wacom.h | 2 | ||||
-rw-r--r-- | drivers/hid/wacom_sys.c | 68 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 216 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 3 |
24 files changed, 2099 insertions, 430 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index f42df4dd58d2..230b6f887cd8 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -371,6 +371,7 @@ config HID_LOGITECH_DJ | |||
371 | tristate "Logitech Unifying receivers full support" | 371 | tristate "Logitech Unifying receivers full support" |
372 | depends on HIDRAW | 372 | depends on HIDRAW |
373 | depends on HID_LOGITECH | 373 | depends on HID_LOGITECH |
374 | select HID_LOGITECH_HIDPP | ||
374 | ---help--- | 375 | ---help--- |
375 | Say Y if you want support for Logitech Unifying receivers and devices. | 376 | Say Y if you want support for Logitech Unifying receivers and devices. |
376 | Unifying receivers are capable of pairing up to 6 Logitech compliant | 377 | Unifying receivers are capable of pairing up to 6 Logitech compliant |
@@ -378,6 +379,17 @@ config HID_LOGITECH_DJ | |||
378 | generic USB_HID driver and all incoming events will be multiplexed | 379 | generic USB_HID driver and all incoming events will be multiplexed |
379 | into a single mouse and a single keyboard device. | 380 | into a single mouse and a single keyboard device. |
380 | 381 | ||
382 | config HID_LOGITECH_HIDPP | ||
383 | tristate "Logitech HID++ devices support" | ||
384 | depends on HID_LOGITECH | ||
385 | ---help--- | ||
386 | Support for Logitech devices relyingon the HID++ Logitech specification | ||
387 | |||
388 | Say Y if you want support for Logitech devices relying on the HID++ | ||
389 | specification. Such devices are the various Logitech Touchpads (T650, | ||
390 | T651, TK820), some mice (Zone Touch mouse), or even keyboards (Solar | ||
391 | Keayboard). | ||
392 | |||
381 | config LOGITECH_FF | 393 | config LOGITECH_FF |
382 | bool "Logitech force feedback support" | 394 | bool "Logitech force feedback support" |
383 | depends on HID_LOGITECH | 395 | depends on HID_LOGITECH |
@@ -613,6 +625,13 @@ config HID_PICOLCD_CIR | |||
613 | ---help--- | 625 | ---help--- |
614 | Provide access to PicoLCD's CIR interface via remote control (LIRC). | 626 | Provide access to PicoLCD's CIR interface via remote control (LIRC). |
615 | 627 | ||
628 | config HID_PLANTRONICS | ||
629 | tristate "Plantronics USB HID Driver" | ||
630 | default !EXPERT | ||
631 | depends on HID | ||
632 | ---help--- | ||
633 | Provides HID support for Plantronics telephony devices. | ||
634 | |||
616 | config HID_PRIMAX | 635 | config HID_PRIMAX |
617 | tristate "Primax non-fully HID-compliant devices" | 636 | tristate "Primax non-fully HID-compliant devices" |
618 | depends on HID | 637 | depends on HID |
@@ -629,7 +648,7 @@ config HID_ROCCAT | |||
629 | support for its special functionalities. | 648 | support for its special functionalities. |
630 | 649 | ||
631 | config HID_SAITEK | 650 | config HID_SAITEK |
632 | tristate "Saitek non-fully HID-compliant devices" | 651 | tristate "Saitek (Mad Catz) non-fully HID-compliant devices" |
633 | depends on HID | 652 | depends on HID |
634 | ---help--- | 653 | ---help--- |
635 | Support for Saitek devices that are not fully compliant with the | 654 | Support for Saitek devices that are not fully compliant with the |
@@ -637,6 +656,7 @@ config HID_SAITEK | |||
637 | 656 | ||
638 | Supported devices: | 657 | Supported devices: |
639 | - PS1000 Dual Analog Pad | 658 | - PS1000 Dual Analog Pad |
659 | - R.A.T.9 Gaming Mouse | ||
640 | - R.A.T.7 Gaming Mouse | 660 | - R.A.T.7 Gaming Mouse |
641 | - M.M.O.7 Gaming Mouse | 661 | - M.M.O.7 Gaming Mouse |
642 | 662 | ||
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index e2850d8af9ca..debd15b44b59 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -63,6 +63,7 @@ obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o | |||
63 | obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o | 63 | obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o |
64 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o | 64 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o |
65 | obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o | 65 | obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o |
66 | obj-$(CONFIG_HID_LOGITECH_HIDPP) += hid-logitech-hidpp.o | ||
66 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o | 67 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o |
67 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | 68 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o |
68 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 69 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
@@ -94,6 +95,7 @@ ifdef CONFIG_DEBUG_FS | |||
94 | hid-picolcd-y += hid-picolcd_debugfs.o | 95 | hid-picolcd-y += hid-picolcd_debugfs.o |
95 | endif | 96 | endif |
96 | 97 | ||
98 | obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o | ||
97 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o | 99 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o |
98 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ | 100 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ |
99 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ | 101 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3402033fa52a..c3d0ac1a0988 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -702,6 +702,11 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) | |||
702 | if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && | 702 | if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && |
703 | type == HID_COLLECTION_PHYSICAL) | 703 | type == HID_COLLECTION_PHYSICAL) |
704 | hid->group = HID_GROUP_SENSOR_HUB; | 704 | hid->group = HID_GROUP_SENSOR_HUB; |
705 | |||
706 | if (hid->vendor == USB_VENDOR_ID_MICROSOFT && | ||
707 | hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 && | ||
708 | hid->group == HID_GROUP_MULTITOUCH) | ||
709 | hid->group = HID_GROUP_GENERIC; | ||
705 | } | 710 | } |
706 | 711 | ||
707 | static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) | 712 | static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) |
@@ -780,22 +785,19 @@ static int hid_scan_report(struct hid_device *hid) | |||
780 | hid->group = HID_GROUP_MULTITOUCH_WIN_8; | 785 | hid->group = HID_GROUP_MULTITOUCH_WIN_8; |
781 | 786 | ||
782 | /* | 787 | /* |
783 | * Vendor specific handlings | ||
784 | */ | ||
785 | if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) && | ||
786 | (hid->group == HID_GROUP_GENERIC) && | ||
787 | /* only bind to the mouse interface of composite USB devices */ | ||
788 | (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE)) | ||
789 | /* hid-rmi should take care of them, not hid-generic */ | ||
790 | hid->group = HID_GROUP_RMI; | ||
791 | |||
792 | /* | ||
793 | * Vendor specific handlings | 788 | * Vendor specific handlings |
794 | */ | 789 | */ |
795 | switch (hid->vendor) { | 790 | switch (hid->vendor) { |
796 | case USB_VENDOR_ID_WACOM: | 791 | case USB_VENDOR_ID_WACOM: |
797 | hid->group = HID_GROUP_WACOM; | 792 | hid->group = HID_GROUP_WACOM; |
798 | break; | 793 | break; |
794 | case USB_VENDOR_ID_SYNAPTICS: | ||
795 | if ((hid->group == HID_GROUP_GENERIC) && | ||
796 | (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE)) | ||
797 | /* hid-rmi should only bind to the mouse interface of | ||
798 | * composite USB devices */ | ||
799 | hid->group = HID_GROUP_RMI; | ||
800 | break; | ||
799 | } | 801 | } |
800 | 802 | ||
801 | vfree(parser); | 803 | vfree(parser); |
@@ -1280,12 +1282,6 @@ void hid_output_report(struct hid_report *report, __u8 *data) | |||
1280 | } | 1282 | } |
1281 | EXPORT_SYMBOL_GPL(hid_output_report); | 1283 | EXPORT_SYMBOL_GPL(hid_output_report); |
1282 | 1284 | ||
1283 | static int hid_report_len(struct hid_report *report) | ||
1284 | { | ||
1285 | /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ | ||
1286 | return ((report->size - 1) >> 3) + 1 + (report->id > 0); | ||
1287 | } | ||
1288 | |||
1289 | /* | 1285 | /* |
1290 | * Allocator for buffer that is going to be passed to hid_output_report() | 1286 | * Allocator for buffer that is going to be passed to hid_output_report() |
1291 | */ | 1287 | */ |
@@ -1822,6 +1818,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1822 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, | 1818 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, |
1823 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, | 1819 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, |
1824 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, | 1820 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, |
1821 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) }, | ||
1825 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, | 1822 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, |
1826 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, | 1823 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, |
1827 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, | 1824 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, |
@@ -1862,6 +1859,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1862 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, | 1859 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, |
1863 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, | 1860 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, |
1864 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, | 1861 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, |
1862 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, | ||
1865 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1863 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1866 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, | 1864 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, |
1867 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, | 1865 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, |
@@ -1887,6 +1885,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1887 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1885 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
1888 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, | 1886 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, |
1889 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1887 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1888 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, | ||
1890 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, | 1889 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, |
1891 | #if IS_ENABLED(CONFIG_HID_ROCCAT) | 1890 | #if IS_ENABLED(CONFIG_HID_ROCCAT) |
1892 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, | 1891 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, |
@@ -1910,10 +1909,12 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1910 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, | 1909 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, |
1911 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) }, | 1910 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) }, |
1912 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, | 1911 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, |
1912 | { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) }, | ||
1913 | #endif | 1913 | #endif |
1914 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, | 1914 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, |
1915 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, | 1915 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, |
1916 | { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, | 1916 | { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, |
1917 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) }, | ||
1917 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, | 1918 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, |
1918 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, | 1919 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, |
1919 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, | 1920 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, |
@@ -2539,7 +2540,8 @@ int hid_add_device(struct hid_device *hdev) | |||
2539 | * Scan generic devices for group information | 2540 | * Scan generic devices for group information |
2540 | */ | 2541 | */ |
2541 | if (hid_ignore_special_drivers || | 2542 | if (hid_ignore_special_drivers || |
2542 | !hid_match_id(hdev, hid_have_special_driver)) { | 2543 | (!hdev->group && |
2544 | !hid_match_id(hdev, hid_have_special_driver))) { | ||
2543 | ret = hid_scan_report(hdev); | 2545 | ret = hid_scan_report(hdev); |
2544 | if (ret) | 2546 | if (ret) |
2545 | hid_warn(hdev, "bad device descriptor (%d)\n", ret); | 2547 | hid_warn(hdev, "bad device descriptor (%d)\n", ret); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7c863738e419..7460f3402298 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -300,6 +300,7 @@ | |||
300 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089 | 300 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089 |
301 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b | 301 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b |
302 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103 0x0103 | 302 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103 0x0103 |
303 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c 0x010c | ||
303 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F 0x016f | 304 | #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F 0x016f |
304 | 305 | ||
305 | #define USB_VENDOR_ID_ELECOM 0x056e | 306 | #define USB_VENDOR_ID_ELECOM 0x056e |
@@ -578,6 +579,7 @@ | |||
578 | 579 | ||
579 | #define USB_VENDOR_ID_LOGITECH 0x046d | 580 | #define USB_VENDOR_ID_LOGITECH 0x046d |
580 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e | 581 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e |
582 | #define USB_DEVICE_ID_LOGITECH_T651 0xb00c | ||
581 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 | 583 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
582 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 | 584 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 |
583 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f | 585 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f |
@@ -620,6 +622,7 @@ | |||
620 | 622 | ||
621 | #define USB_VENDOR_ID_MADCATZ 0x0738 | 623 | #define USB_VENDOR_ID_MADCATZ 0x0738 |
622 | #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 | 624 | #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 |
625 | #define USB_DEVICE_ID_MADCATZ_RAT9 0x1709 | ||
623 | 626 | ||
624 | #define USB_VENDOR_ID_MCC 0x09db | 627 | #define USB_VENDOR_ID_MCC 0x09db |
625 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 | 628 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 |
@@ -649,6 +652,7 @@ | |||
649 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 | 652 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 |
650 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 | 653 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 |
651 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | 654 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
655 | #define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07dc | ||
652 | 656 | ||
653 | #define USB_VENDOR_ID_MOJO 0x8282 | 657 | #define USB_VENDOR_ID_MOJO 0x8282 |
654 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 | 658 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 |
@@ -716,6 +720,8 @@ | |||
716 | #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 | 720 | #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 |
717 | #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 | 721 | #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 |
718 | 722 | ||
723 | #define USB_VENDOR_ID_PLANTRONICS 0x047f | ||
724 | |||
719 | #define USB_VENDOR_ID_PANASONIC 0x04da | 725 | #define USB_VENDOR_ID_PANASONIC 0x04da |
720 | #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 | 726 | #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 |
721 | #define USB_DEVICE_ID_PANABOARD_UBT880 0x104d | 727 | #define USB_DEVICE_ID_PANABOARD_UBT880 0x104d |
@@ -813,6 +819,9 @@ | |||
813 | #define USB_VENDOR_ID_SKYCABLE 0x1223 | 819 | #define USB_VENDOR_ID_SKYCABLE 0x1223 |
814 | #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 | 820 | #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 |
815 | 821 | ||
822 | #define USB_VENDOR_ID_SMK 0x0609 | ||
823 | #define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306 | ||
824 | |||
816 | #define USB_VENDOR_ID_SONY 0x054c | 825 | #define USB_VENDOR_ID_SONY 0x054c |
817 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b | 826 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b |
818 | #define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374 | 827 | #define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374 |
@@ -931,6 +940,9 @@ | |||
931 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 940 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
932 | #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 | 941 | #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 |
933 | 942 | ||
943 | #define USB_VENDOR_ID_VTL 0x0306 | ||
944 | #define USB_DEVICE_ID_VTL_MULTITOUCH_FF3F 0xff3f | ||
945 | |||
934 | #define USB_VENDOR_ID_WACOM 0x056a | 946 | #define USB_VENDOR_ID_WACOM 0x056a |
935 | #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 | 947 | #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 |
936 | #define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD | 948 | #define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 725f22ca47fc..e0a0f06ac5ef 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -872,7 +872,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
872 | case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break; | 872 | case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break; |
873 | case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break; | 873 | case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break; |
874 | 874 | ||
875 | default: goto ignore; | 875 | default: map_key_clear(KEY_UNKNOWN); |
876 | } | 876 | } |
877 | break; | 877 | break; |
878 | 878 | ||
@@ -1215,7 +1215,7 @@ static void hidinput_led_worker(struct work_struct *work) | |||
1215 | return hid->ll_driver->request(hid, report, HID_REQ_SET_REPORT); | 1215 | return hid->ll_driver->request(hid, report, HID_REQ_SET_REPORT); |
1216 | 1216 | ||
1217 | /* fall back to generic raw-output-report */ | 1217 | /* fall back to generic raw-output-report */ |
1218 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 1218 | len = hid_report_len(report); |
1219 | buf = hid_alloc_report_buf(report, GFP_KERNEL); | 1219 | buf = hid_alloc_report_buf(report, GFP_KERNEL); |
1220 | if (!buf) | 1220 | if (!buf) |
1221 | return; | 1221 | return; |
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index bf227f7679af..4c55f4d95798 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c | |||
@@ -62,7 +62,6 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, | |||
62 | /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */ | 62 | /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */ |
63 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR || | 63 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR || |
64 | (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) { | 64 | (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) { |
65 | set_bit(EV_REP, hi->input->evbit); | ||
66 | switch (usage->hid & HID_USAGE) { | 65 | switch (usage->hid & HID_USAGE) { |
67 | case 0x00f1: /* Fn-F4: Mic mute */ | 66 | case 0x00f1: /* Fn-F4: Mic mute */ |
68 | map_key_clear(KEY_MICMUTE); | 67 | map_key_clear(KEY_MICMUTE); |
@@ -85,13 +84,13 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, | |||
85 | case 0x00f8: /* Fn-F11: View open applications (3 boxes) */ | 84 | case 0x00f8: /* Fn-F11: View open applications (3 boxes) */ |
86 | map_key_clear(KEY_SCALE); | 85 | map_key_clear(KEY_SCALE); |
87 | return 1; | 86 | return 1; |
88 | case 0x00fa: /* Fn-Esc: Fn-lock toggle */ | 87 | case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */ |
89 | map_key_clear(KEY_FN_ESC); | ||
90 | return 1; | ||
91 | case 0x00fb: /* Fn-F12: Open My computer (6 boxes) USB-only */ | ||
92 | /* NB: This mapping is invented in raw_event below */ | 88 | /* NB: This mapping is invented in raw_event below */ |
93 | map_key_clear(KEY_FILE); | 89 | map_key_clear(KEY_FILE); |
94 | return 1; | 90 | return 1; |
91 | case 0x00fa: /* Fn-Esc: Fn-lock toggle */ | ||
92 | map_key_clear(KEY_FN_ESC); | ||
93 | return 1; | ||
95 | } | 94 | } |
96 | } | 95 | } |
97 | 96 | ||
@@ -207,8 +206,8 @@ static int lenovo_raw_event(struct hid_device *hdev, | |||
207 | && data[0] == 0x15 | 206 | && data[0] == 0x15 |
208 | && data[1] == 0x94 | 207 | && data[1] == 0x94 |
209 | && data[2] == 0x01)) { | 208 | && data[2] == 0x01)) { |
210 | data[1] = 0x0; | 209 | data[1] = 0x00; |
211 | data[2] = 0x4; | 210 | data[2] = 0x01; |
212 | } | 211 | } |
213 | 212 | ||
214 | return 0; | 213 | return 0; |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 71f569292cab..c917ab61aafa 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -26,9 +26,104 @@ | |||
26 | #include <linux/hid.h> | 26 | #include <linux/hid.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
29 | #include <linux/kfifo.h> | ||
29 | #include <asm/unaligned.h> | 30 | #include <asm/unaligned.h> |
30 | #include "hid-ids.h" | 31 | #include "hid-ids.h" |
31 | #include "hid-logitech-dj.h" | 32 | |
33 | #define DJ_MAX_PAIRED_DEVICES 6 | ||
34 | #define DJ_MAX_NUMBER_NOTIFICATIONS 8 | ||
35 | #define DJ_RECEIVER_INDEX 0 | ||
36 | #define DJ_DEVICE_INDEX_MIN 1 | ||
37 | #define DJ_DEVICE_INDEX_MAX 6 | ||
38 | |||
39 | #define DJREPORT_SHORT_LENGTH 15 | ||
40 | #define DJREPORT_LONG_LENGTH 32 | ||
41 | |||
42 | #define REPORT_ID_DJ_SHORT 0x20 | ||
43 | #define REPORT_ID_DJ_LONG 0x21 | ||
44 | |||
45 | #define REPORT_ID_HIDPP_SHORT 0x10 | ||
46 | #define REPORT_ID_HIDPP_LONG 0x11 | ||
47 | |||
48 | #define HIDPP_REPORT_SHORT_LENGTH 7 | ||
49 | #define HIDPP_REPORT_LONG_LENGTH 20 | ||
50 | |||
51 | #define HIDPP_RECEIVER_INDEX 0xff | ||
52 | |||
53 | #define REPORT_TYPE_RFREPORT_FIRST 0x01 | ||
54 | #define REPORT_TYPE_RFREPORT_LAST 0x1F | ||
55 | |||
56 | /* Command Switch to DJ mode */ | ||
57 | #define REPORT_TYPE_CMD_SWITCH 0x80 | ||
58 | #define CMD_SWITCH_PARAM_DEVBITFIELD 0x00 | ||
59 | #define CMD_SWITCH_PARAM_TIMEOUT_SECONDS 0x01 | ||
60 | #define TIMEOUT_NO_KEEPALIVE 0x00 | ||
61 | |||
62 | /* Command to Get the list of Paired devices */ | ||
63 | #define REPORT_TYPE_CMD_GET_PAIRED_DEVICES 0x81 | ||
64 | |||
65 | /* Device Paired Notification */ | ||
66 | #define REPORT_TYPE_NOTIF_DEVICE_PAIRED 0x41 | ||
67 | #define SPFUNCTION_MORE_NOTIF_EXPECTED 0x01 | ||
68 | #define SPFUNCTION_DEVICE_LIST_EMPTY 0x02 | ||
69 | #define DEVICE_PAIRED_PARAM_SPFUNCTION 0x00 | ||
70 | #define DEVICE_PAIRED_PARAM_EQUAD_ID_LSB 0x01 | ||
71 | #define DEVICE_PAIRED_PARAM_EQUAD_ID_MSB 0x02 | ||
72 | #define DEVICE_PAIRED_RF_REPORT_TYPE 0x03 | ||
73 | |||
74 | /* Device Un-Paired Notification */ | ||
75 | #define REPORT_TYPE_NOTIF_DEVICE_UNPAIRED 0x40 | ||
76 | |||
77 | |||
78 | /* Connection Status Notification */ | ||
79 | #define REPORT_TYPE_NOTIF_CONNECTION_STATUS 0x42 | ||
80 | #define CONNECTION_STATUS_PARAM_STATUS 0x00 | ||
81 | #define STATUS_LINKLOSS 0x01 | ||
82 | |||
83 | /* Error Notification */ | ||
84 | #define REPORT_TYPE_NOTIF_ERROR 0x7F | ||
85 | #define NOTIF_ERROR_PARAM_ETYPE 0x00 | ||
86 | #define ETYPE_KEEPALIVE_TIMEOUT 0x01 | ||
87 | |||
88 | /* supported DJ HID && RF report types */ | ||
89 | #define REPORT_TYPE_KEYBOARD 0x01 | ||
90 | #define REPORT_TYPE_MOUSE 0x02 | ||
91 | #define REPORT_TYPE_CONSUMER_CONTROL 0x03 | ||
92 | #define REPORT_TYPE_SYSTEM_CONTROL 0x04 | ||
93 | #define REPORT_TYPE_MEDIA_CENTER 0x08 | ||
94 | #define REPORT_TYPE_LEDS 0x0E | ||
95 | |||
96 | /* RF Report types bitfield */ | ||
97 | #define STD_KEYBOARD 0x00000002 | ||
98 | #define STD_MOUSE 0x00000004 | ||
99 | #define MULTIMEDIA 0x00000008 | ||
100 | #define POWER_KEYS 0x00000010 | ||
101 | #define MEDIA_CENTER 0x00000100 | ||
102 | #define KBD_LEDS 0x00004000 | ||
103 | |||
104 | struct dj_report { | ||
105 | u8 report_id; | ||
106 | u8 device_index; | ||
107 | u8 report_type; | ||
108 | u8 report_params[DJREPORT_SHORT_LENGTH - 3]; | ||
109 | }; | ||
110 | |||
111 | struct dj_receiver_dev { | ||
112 | struct hid_device *hdev; | ||
113 | struct dj_device *paired_dj_devices[DJ_MAX_PAIRED_DEVICES + | ||
114 | DJ_DEVICE_INDEX_MIN]; | ||
115 | struct work_struct work; | ||
116 | struct kfifo notif_fifo; | ||
117 | spinlock_t lock; | ||
118 | bool querying_devices; | ||
119 | }; | ||
120 | |||
121 | struct dj_device { | ||
122 | struct hid_device *hdev; | ||
123 | struct dj_receiver_dev *dj_receiver_dev; | ||
124 | u32 reports_supported; | ||
125 | u8 device_index; | ||
126 | }; | ||
32 | 127 | ||
33 | /* Keyboard descriptor (1) */ | 128 | /* Keyboard descriptor (1) */ |
34 | static const char kbd_descriptor[] = { | 129 | static const char kbd_descriptor[] = { |
@@ -156,6 +251,57 @@ static const char media_descriptor[] = { | |||
156 | 0xc0, /* EndCollection */ | 251 | 0xc0, /* EndCollection */ |
157 | }; /* */ | 252 | }; /* */ |
158 | 253 | ||
254 | /* HIDPP descriptor */ | ||
255 | static const char hidpp_descriptor[] = { | ||
256 | 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ | ||
257 | 0x09, 0x01, /* Usage (Vendor Usage 1) */ | ||
258 | 0xa1, 0x01, /* Collection (Application) */ | ||
259 | 0x85, 0x10, /* Report ID (16) */ | ||
260 | 0x75, 0x08, /* Report Size (8) */ | ||
261 | 0x95, 0x06, /* Report Count (6) */ | ||
262 | 0x15, 0x00, /* Logical Minimum (0) */ | ||
263 | 0x26, 0xff, 0x00, /* Logical Maximum (255) */ | ||
264 | 0x09, 0x01, /* Usage (Vendor Usage 1) */ | ||
265 | 0x81, 0x00, /* Input (Data,Arr,Abs) */ | ||
266 | 0x09, 0x01, /* Usage (Vendor Usage 1) */ | ||
267 | 0x91, 0x00, /* Output (Data,Arr,Abs) */ | ||
268 | 0xc0, /* End Collection */ | ||
269 | 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ | ||
270 | 0x09, 0x02, /* Usage (Vendor Usage 2) */ | ||
271 | 0xa1, 0x01, /* Collection (Application) */ | ||
272 | 0x85, 0x11, /* Report ID (17) */ | ||
273 | 0x75, 0x08, /* Report Size (8) */ | ||
274 | 0x95, 0x13, /* Report Count (19) */ | ||
275 | 0x15, 0x00, /* Logical Minimum (0) */ | ||
276 | 0x26, 0xff, 0x00, /* Logical Maximum (255) */ | ||
277 | 0x09, 0x02, /* Usage (Vendor Usage 2) */ | ||
278 | 0x81, 0x00, /* Input (Data,Arr,Abs) */ | ||
279 | 0x09, 0x02, /* Usage (Vendor Usage 2) */ | ||
280 | 0x91, 0x00, /* Output (Data,Arr,Abs) */ | ||
281 | 0xc0, /* End Collection */ | ||
282 | 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ | ||
283 | 0x09, 0x04, /* Usage (Vendor Usage 0x04) */ | ||
284 | 0xa1, 0x01, /* Collection (Application) */ | ||
285 | 0x85, 0x20, /* Report ID (32) */ | ||
286 | 0x75, 0x08, /* Report Size (8) */ | ||
287 | 0x95, 0x0e, /* Report Count (14) */ | ||
288 | 0x15, 0x00, /* Logical Minimum (0) */ | ||
289 | 0x26, 0xff, 0x00, /* Logical Maximum (255) */ | ||
290 | 0x09, 0x41, /* Usage (Vendor Usage 0x41) */ | ||
291 | 0x81, 0x00, /* Input (Data,Arr,Abs) */ | ||
292 | 0x09, 0x41, /* Usage (Vendor Usage 0x41) */ | ||
293 | 0x91, 0x00, /* Output (Data,Arr,Abs) */ | ||
294 | 0x85, 0x21, /* Report ID (33) */ | ||
295 | 0x95, 0x1f, /* Report Count (31) */ | ||
296 | 0x15, 0x00, /* Logical Minimum (0) */ | ||
297 | 0x26, 0xff, 0x00, /* Logical Maximum (255) */ | ||
298 | 0x09, 0x42, /* Usage (Vendor Usage 0x42) */ | ||
299 | 0x81, 0x00, /* Input (Data,Arr,Abs) */ | ||
300 | 0x09, 0x42, /* Usage (Vendor Usage 0x42) */ | ||
301 | 0x91, 0x00, /* Output (Data,Arr,Abs) */ | ||
302 | 0xc0, /* End Collection */ | ||
303 | }; | ||
304 | |||
159 | /* Maximum size of all defined hid reports in bytes (including report id) */ | 305 | /* Maximum size of all defined hid reports in bytes (including report id) */ |
160 | #define MAX_REPORT_SIZE 8 | 306 | #define MAX_REPORT_SIZE 8 |
161 | 307 | ||
@@ -165,7 +311,8 @@ static const char media_descriptor[] = { | |||
165 | sizeof(mse_descriptor) + \ | 311 | sizeof(mse_descriptor) + \ |
166 | sizeof(consumer_descriptor) + \ | 312 | sizeof(consumer_descriptor) + \ |
167 | sizeof(syscontrol_descriptor) + \ | 313 | sizeof(syscontrol_descriptor) + \ |
168 | sizeof(media_descriptor)) | 314 | sizeof(media_descriptor) + \ |
315 | sizeof(hidpp_descriptor)) | ||
169 | 316 | ||
170 | /* Number of possible hid report types that can be created by this driver. | 317 | /* Number of possible hid report types that can be created by this driver. |
171 | * | 318 | * |
@@ -256,11 +403,15 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
256 | dj_hiddev->dev.parent = &djrcv_hdev->dev; | 403 | dj_hiddev->dev.parent = &djrcv_hdev->dev; |
257 | dj_hiddev->bus = BUS_USB; | 404 | dj_hiddev->bus = BUS_USB; |
258 | dj_hiddev->vendor = le16_to_cpu(usbdev->descriptor.idVendor); | 405 | dj_hiddev->vendor = le16_to_cpu(usbdev->descriptor.idVendor); |
259 | dj_hiddev->product = le16_to_cpu(usbdev->descriptor.idProduct); | 406 | dj_hiddev->product = |
407 | (dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_MSB] | ||
408 | << 8) | | ||
409 | dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB]; | ||
260 | snprintf(dj_hiddev->name, sizeof(dj_hiddev->name), | 410 | snprintf(dj_hiddev->name, sizeof(dj_hiddev->name), |
261 | "Logitech Unifying Device. Wireless PID:%02x%02x", | 411 | "Logitech Unifying Device. Wireless PID:%04x", |
262 | dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_MSB], | 412 | dj_hiddev->product); |
263 | dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB]); | 413 | |
414 | dj_hiddev->group = HID_GROUP_LOGITECH_DJ_DEVICE; | ||
264 | 415 | ||
265 | usb_make_path(usbdev, dj_hiddev->phys, sizeof(dj_hiddev->phys)); | 416 | usb_make_path(usbdev, dj_hiddev->phys, sizeof(dj_hiddev->phys)); |
266 | snprintf(tmpstr, sizeof(tmpstr), ":%d", dj_report->device_index); | 417 | snprintf(tmpstr, sizeof(tmpstr), ":%d", dj_report->device_index); |
@@ -422,6 +573,13 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev, | |||
422 | } | 573 | } |
423 | } | 574 | } |
424 | 575 | ||
576 | static void logi_dj_recv_forward_hidpp(struct dj_device *dj_dev, u8 *data, | ||
577 | int size) | ||
578 | { | ||
579 | /* We are called from atomic context (tasklet && djrcv->lock held) */ | ||
580 | if (hid_input_report(dj_dev->hdev, HID_INPUT_REPORT, data, size, 1)) | ||
581 | dbg_hid("hid_input_report error\n"); | ||
582 | } | ||
425 | 583 | ||
426 | static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, | 584 | static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, |
427 | struct dj_report *dj_report) | 585 | struct dj_report *dj_report) |
@@ -472,7 +630,9 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) | |||
472 | static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, | 630 | static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, |
473 | unsigned timeout) | 631 | unsigned timeout) |
474 | { | 632 | { |
633 | struct hid_device *hdev = djrcv_dev->hdev; | ||
475 | struct dj_report *dj_report; | 634 | struct dj_report *dj_report; |
635 | u8 *buf; | ||
476 | int retval; | 636 | int retval; |
477 | 637 | ||
478 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); | 638 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); |
@@ -484,7 +644,6 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, | |||
484 | dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; | 644 | dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; |
485 | dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; | 645 | dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; |
486 | retval = logi_dj_recv_send_report(djrcv_dev, dj_report); | 646 | retval = logi_dj_recv_send_report(djrcv_dev, dj_report); |
487 | kfree(dj_report); | ||
488 | 647 | ||
489 | /* | 648 | /* |
490 | * Ugly sleep to work around a USB 3.0 bug when the receiver is still | 649 | * Ugly sleep to work around a USB 3.0 bug when the receiver is still |
@@ -493,6 +652,30 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, | |||
493 | */ | 652 | */ |
494 | msleep(50); | 653 | msleep(50); |
495 | 654 | ||
655 | /* | ||
656 | * Magical bits to set up hidpp notifications when the dj devices | ||
657 | * are connected/disconnected. | ||
658 | * | ||
659 | * We can reuse dj_report because HIDPP_REPORT_SHORT_LENGTH is smaller | ||
660 | * than DJREPORT_SHORT_LENGTH. | ||
661 | */ | ||
662 | buf = (u8 *)dj_report; | ||
663 | |||
664 | memset(buf, 0, HIDPP_REPORT_SHORT_LENGTH); | ||
665 | |||
666 | buf[0] = REPORT_ID_HIDPP_SHORT; | ||
667 | buf[1] = 0xFF; | ||
668 | buf[2] = 0x80; | ||
669 | buf[3] = 0x00; | ||
670 | buf[4] = 0x00; | ||
671 | buf[5] = 0x09; | ||
672 | buf[6] = 0x00; | ||
673 | |||
674 | hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, | ||
675 | HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT, | ||
676 | HID_REQ_SET_REPORT); | ||
677 | |||
678 | kfree(dj_report); | ||
496 | return retval; | 679 | return retval; |
497 | } | 680 | } |
498 | 681 | ||
@@ -509,6 +692,9 @@ static void logi_dj_ll_close(struct hid_device *hid) | |||
509 | dbg_hid("%s:%s\n", __func__, hid->phys); | 692 | dbg_hid("%s:%s\n", __func__, hid->phys); |
510 | } | 693 | } |
511 | 694 | ||
695 | static u8 unifying_name_query[] = {0x10, 0xff, 0x83, 0xb5, 0x40, 0x00, 0x00}; | ||
696 | static u8 unifying_name_answer[] = {0x11, 0xff, 0x83, 0xb5}; | ||
697 | |||
512 | static int logi_dj_ll_raw_request(struct hid_device *hid, | 698 | static int logi_dj_ll_raw_request(struct hid_device *hid, |
513 | unsigned char reportnum, __u8 *buf, | 699 | unsigned char reportnum, __u8 *buf, |
514 | size_t count, unsigned char report_type, | 700 | size_t count, unsigned char report_type, |
@@ -519,6 +705,22 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, | |||
519 | u8 *out_buf; | 705 | u8 *out_buf; |
520 | int ret; | 706 | int ret; |
521 | 707 | ||
708 | if ((buf[0] == REPORT_ID_HIDPP_SHORT) || | ||
709 | (buf[0] == REPORT_ID_HIDPP_LONG)) { | ||
710 | if (count < 2) | ||
711 | return -EINVAL; | ||
712 | |||
713 | /* special case where we should not overwrite | ||
714 | * the device_index */ | ||
715 | if (count == 7 && !memcmp(buf, unifying_name_query, | ||
716 | sizeof(unifying_name_query))) | ||
717 | buf[4] |= djdev->device_index - 1; | ||
718 | else | ||
719 | buf[1] = djdev->device_index; | ||
720 | return hid_hw_raw_request(djrcv_dev->hdev, reportnum, buf, | ||
721 | count, report_type, reqtype); | ||
722 | } | ||
723 | |||
522 | if (buf[0] != REPORT_TYPE_LEDS) | 724 | if (buf[0] != REPORT_TYPE_LEDS) |
523 | return -EINVAL; | 725 | return -EINVAL; |
524 | 726 | ||
@@ -597,6 +799,8 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
597 | __func__, djdev->reports_supported); | 799 | __func__, djdev->reports_supported); |
598 | } | 800 | } |
599 | 801 | ||
802 | rdcat(rdesc, &rsize, hidpp_descriptor, sizeof(hidpp_descriptor)); | ||
803 | |||
600 | retval = hid_parse_report(hid, rdesc, rsize); | 804 | retval = hid_parse_report(hid, rdesc, rsize); |
601 | kfree(rdesc); | 805 | kfree(rdesc); |
602 | 806 | ||
@@ -624,8 +828,7 @@ static struct hid_ll_driver logi_dj_ll_driver = { | |||
624 | .raw_request = logi_dj_ll_raw_request, | 828 | .raw_request = logi_dj_ll_raw_request, |
625 | }; | 829 | }; |
626 | 830 | ||
627 | 831 | static int logi_dj_dj_event(struct hid_device *hdev, | |
628 | static int logi_dj_raw_event(struct hid_device *hdev, | ||
629 | struct hid_report *report, u8 *data, | 832 | struct hid_report *report, u8 *data, |
630 | int size) | 833 | int size) |
631 | { | 834 | { |
@@ -633,36 +836,24 @@ static int logi_dj_raw_event(struct hid_device *hdev, | |||
633 | struct dj_report *dj_report = (struct dj_report *) data; | 836 | struct dj_report *dj_report = (struct dj_report *) data; |
634 | unsigned long flags; | 837 | unsigned long flags; |
635 | 838 | ||
636 | dbg_hid("%s, size:%d\n", __func__, size); | 839 | /* |
637 | 840 | * Here we receive all data coming from iface 2, there are 3 cases: | |
638 | /* Here we receive all data coming from iface 2, there are 4 cases: | ||
639 | * | ||
640 | * 1) Data should continue its normal processing i.e. data does not | ||
641 | * come from the DJ collection, in which case we do nothing and | ||
642 | * return 0, so hid-core can continue normal processing (will forward | ||
643 | * to associated hidraw device) | ||
644 | * | 841 | * |
645 | * 2) Data is from DJ collection, and is intended for this driver i. e. | 842 | * 1) Data is intended for this driver i. e. data contains arrival, |
646 | * data contains arrival, departure, etc notifications, in which case | 843 | * departure, etc notifications, in which case we queue them for delayed |
647 | * we queue them for delayed processing by the work queue. We return 1 | 844 | * processing by the work queue. We return 1 to hid-core as no further |
648 | * to hid-core as no further processing is required from it. | 845 | * processing is required from it. |
649 | * | 846 | * |
650 | * 3) Data is from DJ collection, and informs a connection change, | 847 | * 2) Data informs a connection change, if the change means rf link |
651 | * if the change means rf link loss, then we must send a null report | 848 | * loss, then we must send a null report to the upper layer to discard |
652 | * to the upper layer to discard potentially pressed keys that may be | 849 | * potentially pressed keys that may be repeated forever by the input |
653 | * repeated forever by the input layer. Return 1 to hid-core as no | 850 | * layer. Return 1 to hid-core as no further processing is required. |
654 | * further processing is required. | ||
655 | * | 851 | * |
656 | * 4) Data is from DJ collection and is an actual input event from | 852 | * 3) Data is an actual input event from a paired DJ device in which |
657 | * a paired DJ device in which case we forward it to the correct hid | 853 | * case we forward it to the correct hid device (via hid_input_report() |
658 | * device (via hid_input_report() ) and return 1 so hid-core does not do | 854 | * ) and return 1 so hid-core does not anything else with it. |
659 | * anything else with it. | ||
660 | */ | 855 | */ |
661 | 856 | ||
662 | /* case 1) */ | ||
663 | if (data[0] != REPORT_ID_DJ_SHORT) | ||
664 | return false; | ||
665 | |||
666 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | 857 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || |
667 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | 858 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { |
668 | /* | 859 | /* |
@@ -707,6 +898,80 @@ out: | |||
707 | return true; | 898 | return true; |
708 | } | 899 | } |
709 | 900 | ||
901 | static int logi_dj_hidpp_event(struct hid_device *hdev, | ||
902 | struct hid_report *report, u8 *data, | ||
903 | int size) | ||
904 | { | ||
905 | struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); | ||
906 | struct dj_report *dj_report = (struct dj_report *) data; | ||
907 | unsigned long flags; | ||
908 | u8 device_index = dj_report->device_index; | ||
909 | |||
910 | if (device_index == HIDPP_RECEIVER_INDEX) { | ||
911 | /* special case were the device wants to know its unifying | ||
912 | * name */ | ||
913 | if (size == HIDPP_REPORT_LONG_LENGTH && | ||
914 | !memcmp(data, unifying_name_answer, | ||
915 | sizeof(unifying_name_answer)) && | ||
916 | ((data[4] & 0xF0) == 0x40)) | ||
917 | device_index = (data[4] & 0x0F) + 1; | ||
918 | else | ||
919 | return false; | ||
920 | } | ||
921 | |||
922 | /* | ||
923 | * Data is from the HID++ collection, in this case, we forward the | ||
924 | * data to the corresponding child dj device and return 0 to hid-core | ||
925 | * so he data also goes to the hidraw device of the receiver. This | ||
926 | * allows a user space application to implement the full HID++ routing | ||
927 | * via the receiver. | ||
928 | */ | ||
929 | |||
930 | if ((device_index < DJ_DEVICE_INDEX_MIN) || | ||
931 | (device_index > DJ_DEVICE_INDEX_MAX)) { | ||
932 | /* | ||
933 | * Device index is wrong, bail out. | ||
934 | * This driver can ignore safely the receiver notifications, | ||
935 | * so ignore those reports too. | ||
936 | */ | ||
937 | dev_err(&hdev->dev, "%s: invalid device index:%d\n", | ||
938 | __func__, dj_report->device_index); | ||
939 | return false; | ||
940 | } | ||
941 | |||
942 | spin_lock_irqsave(&djrcv_dev->lock, flags); | ||
943 | |||
944 | if (!djrcv_dev->paired_dj_devices[device_index]) | ||
945 | /* received an event for an unknown device, bail out */ | ||
946 | goto out; | ||
947 | |||
948 | logi_dj_recv_forward_hidpp(djrcv_dev->paired_dj_devices[device_index], | ||
949 | data, size); | ||
950 | |||
951 | out: | ||
952 | spin_unlock_irqrestore(&djrcv_dev->lock, flags); | ||
953 | |||
954 | return false; | ||
955 | } | ||
956 | |||
957 | static int logi_dj_raw_event(struct hid_device *hdev, | ||
958 | struct hid_report *report, u8 *data, | ||
959 | int size) | ||
960 | { | ||
961 | dbg_hid("%s, size:%d\n", __func__, size); | ||
962 | |||
963 | switch (data[0]) { | ||
964 | case REPORT_ID_DJ_SHORT: | ||
965 | return logi_dj_dj_event(hdev, report, data, size); | ||
966 | case REPORT_ID_HIDPP_SHORT: | ||
967 | /* intentional fallthrough */ | ||
968 | case REPORT_ID_HIDPP_LONG: | ||
969 | return logi_dj_hidpp_event(hdev, report, data, size); | ||
970 | } | ||
971 | |||
972 | return false; | ||
973 | } | ||
974 | |||
710 | static int logi_dj_probe(struct hid_device *hdev, | 975 | static int logi_dj_probe(struct hid_device *hdev, |
711 | const struct hid_device_id *id) | 976 | const struct hid_device_id *id) |
712 | { | 977 | { |
@@ -714,9 +979,6 @@ static int logi_dj_probe(struct hid_device *hdev, | |||
714 | struct dj_receiver_dev *djrcv_dev; | 979 | struct dj_receiver_dev *djrcv_dev; |
715 | int retval; | 980 | int retval; |
716 | 981 | ||
717 | if (is_dj_device((struct dj_device *)hdev->driver_data)) | ||
718 | return -ENODEV; | ||
719 | |||
720 | dbg_hid("%s called for ifnum %d\n", __func__, | 982 | dbg_hid("%s called for ifnum %d\n", __func__, |
721 | intf->cur_altsetting->desc.bInterfaceNumber); | 983 | intf->cur_altsetting->desc.bInterfaceNumber); |
722 | 984 | ||
@@ -869,22 +1131,6 @@ static void logi_dj_remove(struct hid_device *hdev) | |||
869 | hid_set_drvdata(hdev, NULL); | 1131 | hid_set_drvdata(hdev, NULL); |
870 | } | 1132 | } |
871 | 1133 | ||
872 | static int logi_djdevice_probe(struct hid_device *hdev, | ||
873 | const struct hid_device_id *id) | ||
874 | { | ||
875 | int ret; | ||
876 | struct dj_device *dj_dev = hdev->driver_data; | ||
877 | |||
878 | if (!is_dj_device(dj_dev)) | ||
879 | return -ENODEV; | ||
880 | |||
881 | ret = hid_parse(hdev); | ||
882 | if (!ret) | ||
883 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
884 | |||
885 | return ret; | ||
886 | } | ||
887 | |||
888 | static const struct hid_device_id logi_dj_receivers[] = { | 1134 | static const struct hid_device_id logi_dj_receivers[] = { |
889 | {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | 1135 | {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, |
890 | USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER)}, | 1136 | USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER)}, |
@@ -906,51 +1152,8 @@ static struct hid_driver logi_djreceiver_driver = { | |||
906 | #endif | 1152 | #endif |
907 | }; | 1153 | }; |
908 | 1154 | ||
1155 | module_hid_driver(logi_djreceiver_driver); | ||
909 | 1156 | ||
910 | static const struct hid_device_id logi_dj_devices[] = { | ||
911 | {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | ||
912 | USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER)}, | ||
913 | {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | ||
914 | USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2)}, | ||
915 | {} | ||
916 | }; | ||
917 | |||
918 | static struct hid_driver logi_djdevice_driver = { | ||
919 | .name = "logitech-djdevice", | ||
920 | .id_table = logi_dj_devices, | ||
921 | .probe = logi_djdevice_probe, | ||
922 | }; | ||
923 | |||
924 | |||
925 | static int __init logi_dj_init(void) | ||
926 | { | ||
927 | int retval; | ||
928 | |||
929 | dbg_hid("Logitech-DJ:%s\n", __func__); | ||
930 | |||
931 | retval = hid_register_driver(&logi_djreceiver_driver); | ||
932 | if (retval) | ||
933 | return retval; | ||
934 | |||
935 | retval = hid_register_driver(&logi_djdevice_driver); | ||
936 | if (retval) | ||
937 | hid_unregister_driver(&logi_djreceiver_driver); | ||
938 | |||
939 | return retval; | ||
940 | |||
941 | } | ||
942 | |||
943 | static void __exit logi_dj_exit(void) | ||
944 | { | ||
945 | dbg_hid("Logitech-DJ:%s\n", __func__); | ||
946 | |||
947 | hid_unregister_driver(&logi_djdevice_driver); | ||
948 | hid_unregister_driver(&logi_djreceiver_driver); | ||
949 | |||
950 | } | ||
951 | |||
952 | module_init(logi_dj_init); | ||
953 | module_exit(logi_dj_exit); | ||
954 | MODULE_LICENSE("GPL"); | 1157 | MODULE_LICENSE("GPL"); |
955 | MODULE_AUTHOR("Logitech"); | 1158 | MODULE_AUTHOR("Logitech"); |
956 | MODULE_AUTHOR("Nestor Lopez Casado"); | 1159 | MODULE_AUTHOR("Nestor Lopez Casado"); |
diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h deleted file mode 100644 index daeb0aa4bee9..000000000000 --- a/drivers/hid/hid-logitech-dj.h +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
1 | #ifndef __HID_LOGITECH_DJ_H | ||
2 | #define __HID_LOGITECH_DJ_H | ||
3 | |||
4 | /* | ||
5 | * HID driver for Logitech Unifying receivers | ||
6 | * | ||
7 | * Copyright (c) 2011 Logitech | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/kfifo.h> | ||
27 | |||
28 | #define DJ_MAX_PAIRED_DEVICES 6 | ||
29 | #define DJ_MAX_NUMBER_NOTIFICATIONS 8 | ||
30 | #define DJ_RECEIVER_INDEX 0 | ||
31 | #define DJ_DEVICE_INDEX_MIN 1 | ||
32 | #define DJ_DEVICE_INDEX_MAX 6 | ||
33 | |||
34 | #define DJREPORT_SHORT_LENGTH 15 | ||
35 | #define DJREPORT_LONG_LENGTH 32 | ||
36 | |||
37 | #define REPORT_ID_DJ_SHORT 0x20 | ||
38 | #define REPORT_ID_DJ_LONG 0x21 | ||
39 | |||
40 | #define REPORT_TYPE_RFREPORT_FIRST 0x01 | ||
41 | #define REPORT_TYPE_RFREPORT_LAST 0x1F | ||
42 | |||
43 | /* Command Switch to DJ mode */ | ||
44 | #define REPORT_TYPE_CMD_SWITCH 0x80 | ||
45 | #define CMD_SWITCH_PARAM_DEVBITFIELD 0x00 | ||
46 | #define CMD_SWITCH_PARAM_TIMEOUT_SECONDS 0x01 | ||
47 | #define TIMEOUT_NO_KEEPALIVE 0x00 | ||
48 | |||
49 | /* Command to Get the list of Paired devices */ | ||
50 | #define REPORT_TYPE_CMD_GET_PAIRED_DEVICES 0x81 | ||
51 | |||
52 | /* Device Paired Notification */ | ||
53 | #define REPORT_TYPE_NOTIF_DEVICE_PAIRED 0x41 | ||
54 | #define SPFUNCTION_MORE_NOTIF_EXPECTED 0x01 | ||
55 | #define SPFUNCTION_DEVICE_LIST_EMPTY 0x02 | ||
56 | #define DEVICE_PAIRED_PARAM_SPFUNCTION 0x00 | ||
57 | #define DEVICE_PAIRED_PARAM_EQUAD_ID_LSB 0x01 | ||
58 | #define DEVICE_PAIRED_PARAM_EQUAD_ID_MSB 0x02 | ||
59 | #define DEVICE_PAIRED_RF_REPORT_TYPE 0x03 | ||
60 | |||
61 | /* Device Un-Paired Notification */ | ||
62 | #define REPORT_TYPE_NOTIF_DEVICE_UNPAIRED 0x40 | ||
63 | |||
64 | |||
65 | /* Connection Status Notification */ | ||
66 | #define REPORT_TYPE_NOTIF_CONNECTION_STATUS 0x42 | ||
67 | #define CONNECTION_STATUS_PARAM_STATUS 0x00 | ||
68 | #define STATUS_LINKLOSS 0x01 | ||
69 | |||
70 | /* Error Notification */ | ||
71 | #define REPORT_TYPE_NOTIF_ERROR 0x7F | ||
72 | #define NOTIF_ERROR_PARAM_ETYPE 0x00 | ||
73 | #define ETYPE_KEEPALIVE_TIMEOUT 0x01 | ||
74 | |||
75 | /* supported DJ HID && RF report types */ | ||
76 | #define REPORT_TYPE_KEYBOARD 0x01 | ||
77 | #define REPORT_TYPE_MOUSE 0x02 | ||
78 | #define REPORT_TYPE_CONSUMER_CONTROL 0x03 | ||
79 | #define REPORT_TYPE_SYSTEM_CONTROL 0x04 | ||
80 | #define REPORT_TYPE_MEDIA_CENTER 0x08 | ||
81 | #define REPORT_TYPE_LEDS 0x0E | ||
82 | |||
83 | /* RF Report types bitfield */ | ||
84 | #define STD_KEYBOARD 0x00000002 | ||
85 | #define STD_MOUSE 0x00000004 | ||
86 | #define MULTIMEDIA 0x00000008 | ||
87 | #define POWER_KEYS 0x00000010 | ||
88 | #define MEDIA_CENTER 0x00000100 | ||
89 | #define KBD_LEDS 0x00004000 | ||
90 | |||
91 | struct dj_report { | ||
92 | u8 report_id; | ||
93 | u8 device_index; | ||
94 | u8 report_type; | ||
95 | u8 report_params[DJREPORT_SHORT_LENGTH - 3]; | ||
96 | }; | ||
97 | |||
98 | struct dj_receiver_dev { | ||
99 | struct hid_device *hdev; | ||
100 | struct dj_device *paired_dj_devices[DJ_MAX_PAIRED_DEVICES + | ||
101 | DJ_DEVICE_INDEX_MIN]; | ||
102 | struct work_struct work; | ||
103 | struct kfifo notif_fifo; | ||
104 | spinlock_t lock; | ||
105 | bool querying_devices; | ||
106 | }; | ||
107 | |||
108 | struct dj_device { | ||
109 | struct hid_device *hdev; | ||
110 | struct dj_receiver_dev *dj_receiver_dev; | ||
111 | u32 reports_supported; | ||
112 | u8 device_index; | ||
113 | }; | ||
114 | |||
115 | /** | ||
116 | * is_dj_device - know if the given dj_device is not the receiver. | ||
117 | * @dj_dev: the dj device to test | ||
118 | * | ||
119 | * This macro tests if a struct dj_device pointer is a device created | ||
120 | * by the bus enumarator. | ||
121 | */ | ||
122 | #define is_dj_device(dj_dev) \ | ||
123 | (&(dj_dev)->dj_receiver_dev->hdev->dev == (dj_dev)->hdev->dev.parent) | ||
124 | |||
125 | #endif | ||
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c new file mode 100644 index 000000000000..2f420c0b6609 --- /dev/null +++ b/drivers/hid/hid-logitech-hidpp.c | |||
@@ -0,0 +1,1241 @@ | |||
1 | /* | ||
2 | * HIDPP protocol for Logitech Unifying receivers | ||
3 | * | ||
4 | * Copyright (c) 2011 Logitech (c) | ||
5 | * Copyright (c) 2012-2013 Google (c) | ||
6 | * Copyright (c) 2013-2014 Red Hat Inc. | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation; version 2 of the License. | ||
13 | */ | ||
14 | |||
15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
16 | |||
17 | #include <linux/device.h> | ||
18 | #include <linux/hid.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/kfifo.h> | ||
23 | #include <linux/input/mt.h> | ||
24 | #include <asm/unaligned.h> | ||
25 | #include "hid-ids.h" | ||
26 | |||
27 | MODULE_LICENSE("GPL"); | ||
28 | MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); | ||
29 | MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>"); | ||
30 | |||
31 | #define REPORT_ID_HIDPP_SHORT 0x10 | ||
32 | #define REPORT_ID_HIDPP_LONG 0x11 | ||
33 | |||
34 | #define HIDPP_REPORT_SHORT_LENGTH 7 | ||
35 | #define HIDPP_REPORT_LONG_LENGTH 20 | ||
36 | |||
37 | #define HIDPP_QUIRK_CLASS_WTP BIT(0) | ||
38 | |||
39 | /* bits 1..20 are reserved for classes */ | ||
40 | #define HIDPP_QUIRK_DELAYED_INIT BIT(21) | ||
41 | #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) | ||
42 | #define HIDPP_QUIRK_MULTI_INPUT BIT(23) | ||
43 | |||
44 | /* | ||
45 | * There are two hidpp protocols in use, the first version hidpp10 is known | ||
46 | * as register access protocol or RAP, the second version hidpp20 is known as | ||
47 | * feature access protocol or FAP | ||
48 | * | ||
49 | * Most older devices (including the Unifying usb receiver) use the RAP protocol | ||
50 | * where as most newer devices use the FAP protocol. Both protocols are | ||
51 | * compatible with the underlying transport, which could be usb, Unifiying, or | ||
52 | * bluetooth. The message lengths are defined by the hid vendor specific report | ||
53 | * descriptor for the HIDPP_SHORT report type (total message lenth 7 bytes) and | ||
54 | * the HIDPP_LONG report type (total message length 20 bytes) | ||
55 | * | ||
56 | * The RAP protocol uses both report types, whereas the FAP only uses HIDPP_LONG | ||
57 | * messages. The Unifying receiver itself responds to RAP messages (device index | ||
58 | * is 0xFF for the receiver), and all messages (short or long) with a device | ||
59 | * index between 1 and 6 are passed untouched to the corresponding paired | ||
60 | * Unifying device. | ||
61 | * | ||
62 | * The paired device can be RAP or FAP, it will receive the message untouched | ||
63 | * from the Unifiying receiver. | ||
64 | */ | ||
65 | |||
66 | struct fap { | ||
67 | u8 feature_index; | ||
68 | u8 funcindex_clientid; | ||
69 | u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; | ||
70 | }; | ||
71 | |||
72 | struct rap { | ||
73 | u8 sub_id; | ||
74 | u8 reg_address; | ||
75 | u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; | ||
76 | }; | ||
77 | |||
78 | struct hidpp_report { | ||
79 | u8 report_id; | ||
80 | u8 device_index; | ||
81 | union { | ||
82 | struct fap fap; | ||
83 | struct rap rap; | ||
84 | u8 rawbytes[sizeof(struct fap)]; | ||
85 | }; | ||
86 | } __packed; | ||
87 | |||
88 | struct hidpp_device { | ||
89 | struct hid_device *hid_dev; | ||
90 | struct mutex send_mutex; | ||
91 | void *send_receive_buf; | ||
92 | wait_queue_head_t wait; | ||
93 | bool answer_available; | ||
94 | u8 protocol_major; | ||
95 | u8 protocol_minor; | ||
96 | |||
97 | void *private_data; | ||
98 | |||
99 | struct work_struct work; | ||
100 | struct kfifo delayed_work_fifo; | ||
101 | atomic_t connected; | ||
102 | struct input_dev *delayed_input; | ||
103 | |||
104 | unsigned long quirks; | ||
105 | }; | ||
106 | |||
107 | |||
108 | #define HIDPP_ERROR 0x8f | ||
109 | #define HIDPP_ERROR_SUCCESS 0x00 | ||
110 | #define HIDPP_ERROR_INVALID_SUBID 0x01 | ||
111 | #define HIDPP_ERROR_INVALID_ADRESS 0x02 | ||
112 | #define HIDPP_ERROR_INVALID_VALUE 0x03 | ||
113 | #define HIDPP_ERROR_CONNECT_FAIL 0x04 | ||
114 | #define HIDPP_ERROR_TOO_MANY_DEVICES 0x05 | ||
115 | #define HIDPP_ERROR_ALREADY_EXISTS 0x06 | ||
116 | #define HIDPP_ERROR_BUSY 0x07 | ||
117 | #define HIDPP_ERROR_UNKNOWN_DEVICE 0x08 | ||
118 | #define HIDPP_ERROR_RESOURCE_ERROR 0x09 | ||
119 | #define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a | ||
120 | #define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b | ||
121 | #define HIDPP_ERROR_WRONG_PIN_CODE 0x0c | ||
122 | |||
123 | static void hidpp_connect_event(struct hidpp_device *hidpp_dev); | ||
124 | |||
125 | static int __hidpp_send_report(struct hid_device *hdev, | ||
126 | struct hidpp_report *hidpp_report) | ||
127 | { | ||
128 | int fields_count, ret; | ||
129 | |||
130 | switch (hidpp_report->report_id) { | ||
131 | case REPORT_ID_HIDPP_SHORT: | ||
132 | fields_count = HIDPP_REPORT_SHORT_LENGTH; | ||
133 | break; | ||
134 | case REPORT_ID_HIDPP_LONG: | ||
135 | fields_count = HIDPP_REPORT_LONG_LENGTH; | ||
136 | break; | ||
137 | default: | ||
138 | return -ENODEV; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * set the device_index as the receiver, it will be overwritten by | ||
143 | * hid_hw_request if needed | ||
144 | */ | ||
145 | hidpp_report->device_index = 0xff; | ||
146 | |||
147 | ret = hid_hw_raw_request(hdev, hidpp_report->report_id, | ||
148 | (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, | ||
149 | HID_REQ_SET_REPORT); | ||
150 | |||
151 | return ret == fields_count ? 0 : -1; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * hidpp_send_message_sync() returns 0 in case of success, and something else | ||
156 | * in case of a failure. | ||
157 | * - If ' something else' is positive, that means that an error has been raised | ||
158 | * by the protocol itself. | ||
159 | * - If ' something else' is negative, that means that we had a classic error | ||
160 | * (-ENOMEM, -EPIPE, etc...) | ||
161 | */ | ||
162 | static int hidpp_send_message_sync(struct hidpp_device *hidpp, | ||
163 | struct hidpp_report *message, | ||
164 | struct hidpp_report *response) | ||
165 | { | ||
166 | int ret; | ||
167 | |||
168 | mutex_lock(&hidpp->send_mutex); | ||
169 | |||
170 | hidpp->send_receive_buf = response; | ||
171 | hidpp->answer_available = false; | ||
172 | |||
173 | /* | ||
174 | * So that we can later validate the answer when it arrives | ||
175 | * in hidpp_raw_event | ||
176 | */ | ||
177 | *response = *message; | ||
178 | |||
179 | ret = __hidpp_send_report(hidpp->hid_dev, message); | ||
180 | |||
181 | if (ret) { | ||
182 | dbg_hid("__hidpp_send_report returned err: %d\n", ret); | ||
183 | memset(response, 0, sizeof(struct hidpp_report)); | ||
184 | goto exit; | ||
185 | } | ||
186 | |||
187 | if (!wait_event_timeout(hidpp->wait, hidpp->answer_available, | ||
188 | 5*HZ)) { | ||
189 | dbg_hid("%s:timeout waiting for response\n", __func__); | ||
190 | memset(response, 0, sizeof(struct hidpp_report)); | ||
191 | ret = -ETIMEDOUT; | ||
192 | } | ||
193 | |||
194 | if (response->report_id == REPORT_ID_HIDPP_SHORT && | ||
195 | response->fap.feature_index == HIDPP_ERROR) { | ||
196 | ret = response->fap.params[1]; | ||
197 | dbg_hid("__hidpp_send_report got hidpp error %02X\n", ret); | ||
198 | goto exit; | ||
199 | } | ||
200 | |||
201 | exit: | ||
202 | mutex_unlock(&hidpp->send_mutex); | ||
203 | return ret; | ||
204 | |||
205 | } | ||
206 | |||
207 | static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, | ||
208 | u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count, | ||
209 | struct hidpp_report *response) | ||
210 | { | ||
211 | struct hidpp_report *message; | ||
212 | int ret; | ||
213 | |||
214 | if (param_count > sizeof(message->fap.params)) | ||
215 | return -EINVAL; | ||
216 | |||
217 | message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); | ||
218 | if (!message) | ||
219 | return -ENOMEM; | ||
220 | message->report_id = REPORT_ID_HIDPP_LONG; | ||
221 | message->fap.feature_index = feat_index; | ||
222 | message->fap.funcindex_clientid = funcindex_clientid; | ||
223 | memcpy(&message->fap.params, params, param_count); | ||
224 | |||
225 | ret = hidpp_send_message_sync(hidpp, message, response); | ||
226 | kfree(message); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, | ||
231 | u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count, | ||
232 | struct hidpp_report *response) | ||
233 | { | ||
234 | struct hidpp_report *message; | ||
235 | int ret; | ||
236 | |||
237 | if ((report_id != REPORT_ID_HIDPP_SHORT) && | ||
238 | (report_id != REPORT_ID_HIDPP_LONG)) | ||
239 | return -EINVAL; | ||
240 | |||
241 | if (param_count > sizeof(message->rap.params)) | ||
242 | return -EINVAL; | ||
243 | |||
244 | message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); | ||
245 | if (!message) | ||
246 | return -ENOMEM; | ||
247 | message->report_id = report_id; | ||
248 | message->rap.sub_id = sub_id; | ||
249 | message->rap.reg_address = reg_address; | ||
250 | memcpy(&message->rap.params, params, param_count); | ||
251 | |||
252 | ret = hidpp_send_message_sync(hidpp_dev, message, response); | ||
253 | kfree(message); | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static void delayed_work_cb(struct work_struct *work) | ||
258 | { | ||
259 | struct hidpp_device *hidpp = container_of(work, struct hidpp_device, | ||
260 | work); | ||
261 | hidpp_connect_event(hidpp); | ||
262 | } | ||
263 | |||
264 | static inline bool hidpp_match_answer(struct hidpp_report *question, | ||
265 | struct hidpp_report *answer) | ||
266 | { | ||
267 | return (answer->fap.feature_index == question->fap.feature_index) && | ||
268 | (answer->fap.funcindex_clientid == question->fap.funcindex_clientid); | ||
269 | } | ||
270 | |||
271 | static inline bool hidpp_match_error(struct hidpp_report *question, | ||
272 | struct hidpp_report *answer) | ||
273 | { | ||
274 | return (answer->fap.feature_index == HIDPP_ERROR) && | ||
275 | (answer->fap.funcindex_clientid == question->fap.feature_index) && | ||
276 | (answer->fap.params[0] == question->fap.funcindex_clientid); | ||
277 | } | ||
278 | |||
279 | static inline bool hidpp_report_is_connect_event(struct hidpp_report *report) | ||
280 | { | ||
281 | return (report->report_id == REPORT_ID_HIDPP_SHORT) && | ||
282 | (report->rap.sub_id == 0x41); | ||
283 | } | ||
284 | |||
285 | /* -------------------------------------------------------------------------- */ | ||
286 | /* HIDP++ 1.0 commands */ | ||
287 | /* -------------------------------------------------------------------------- */ | ||
288 | |||
289 | #define HIDPP_SET_REGISTER 0x80 | ||
290 | #define HIDPP_GET_REGISTER 0x81 | ||
291 | #define HIDPP_SET_LONG_REGISTER 0x82 | ||
292 | #define HIDPP_GET_LONG_REGISTER 0x83 | ||
293 | |||
294 | #define HIDPP_REG_PAIRING_INFORMATION 0xB5 | ||
295 | #define DEVICE_NAME 0x40 | ||
296 | |||
297 | static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) | ||
298 | { | ||
299 | struct hidpp_report response; | ||
300 | int ret; | ||
301 | /* hid-logitech-dj is in charge of setting the right device index */ | ||
302 | u8 params[1] = { DEVICE_NAME }; | ||
303 | char *name; | ||
304 | int len; | ||
305 | |||
306 | ret = hidpp_send_rap_command_sync(hidpp_dev, | ||
307 | REPORT_ID_HIDPP_SHORT, | ||
308 | HIDPP_GET_LONG_REGISTER, | ||
309 | HIDPP_REG_PAIRING_INFORMATION, | ||
310 | params, 1, &response); | ||
311 | if (ret) | ||
312 | return NULL; | ||
313 | |||
314 | len = response.rap.params[1]; | ||
315 | |||
316 | if (2 + len > sizeof(response.rap.params)) | ||
317 | return NULL; | ||
318 | |||
319 | name = kzalloc(len + 1, GFP_KERNEL); | ||
320 | if (!name) | ||
321 | return NULL; | ||
322 | |||
323 | memcpy(name, &response.rap.params[2], len); | ||
324 | return name; | ||
325 | } | ||
326 | |||
327 | /* -------------------------------------------------------------------------- */ | ||
328 | /* 0x0000: Root */ | ||
329 | /* -------------------------------------------------------------------------- */ | ||
330 | |||
331 | #define HIDPP_PAGE_ROOT 0x0000 | ||
332 | #define HIDPP_PAGE_ROOT_IDX 0x00 | ||
333 | |||
334 | #define CMD_ROOT_GET_FEATURE 0x01 | ||
335 | #define CMD_ROOT_GET_PROTOCOL_VERSION 0x11 | ||
336 | |||
337 | static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature, | ||
338 | u8 *feature_index, u8 *feature_type) | ||
339 | { | ||
340 | struct hidpp_report response; | ||
341 | int ret; | ||
342 | u8 params[2] = { feature >> 8, feature & 0x00FF }; | ||
343 | |||
344 | ret = hidpp_send_fap_command_sync(hidpp, | ||
345 | HIDPP_PAGE_ROOT_IDX, | ||
346 | CMD_ROOT_GET_FEATURE, | ||
347 | params, 2, &response); | ||
348 | if (ret) | ||
349 | return ret; | ||
350 | |||
351 | *feature_index = response.fap.params[0]; | ||
352 | *feature_type = response.fap.params[1]; | ||
353 | |||
354 | return ret; | ||
355 | } | ||
356 | |||
357 | static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp) | ||
358 | { | ||
359 | struct hidpp_report response; | ||
360 | int ret; | ||
361 | |||
362 | ret = hidpp_send_fap_command_sync(hidpp, | ||
363 | HIDPP_PAGE_ROOT_IDX, | ||
364 | CMD_ROOT_GET_PROTOCOL_VERSION, | ||
365 | NULL, 0, &response); | ||
366 | |||
367 | if (ret == HIDPP_ERROR_INVALID_SUBID) { | ||
368 | hidpp->protocol_major = 1; | ||
369 | hidpp->protocol_minor = 0; | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | /* the device might not be connected */ | ||
374 | if (ret == HIDPP_ERROR_RESOURCE_ERROR) | ||
375 | return -EIO; | ||
376 | |||
377 | if (ret > 0) { | ||
378 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
379 | __func__, ret); | ||
380 | return -EPROTO; | ||
381 | } | ||
382 | if (ret) | ||
383 | return ret; | ||
384 | |||
385 | hidpp->protocol_major = response.fap.params[0]; | ||
386 | hidpp->protocol_minor = response.fap.params[1]; | ||
387 | |||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | static bool hidpp_is_connected(struct hidpp_device *hidpp) | ||
392 | { | ||
393 | int ret; | ||
394 | |||
395 | ret = hidpp_root_get_protocol_version(hidpp); | ||
396 | if (!ret) | ||
397 | hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n", | ||
398 | hidpp->protocol_major, hidpp->protocol_minor); | ||
399 | return ret == 0; | ||
400 | } | ||
401 | |||
402 | /* -------------------------------------------------------------------------- */ | ||
403 | /* 0x0005: GetDeviceNameType */ | ||
404 | /* -------------------------------------------------------------------------- */ | ||
405 | |||
406 | #define HIDPP_PAGE_GET_DEVICE_NAME_TYPE 0x0005 | ||
407 | |||
408 | #define CMD_GET_DEVICE_NAME_TYPE_GET_COUNT 0x01 | ||
409 | #define CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11 | ||
410 | #define CMD_GET_DEVICE_NAME_TYPE_GET_TYPE 0x21 | ||
411 | |||
412 | static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp, | ||
413 | u8 feature_index, u8 *nameLength) | ||
414 | { | ||
415 | struct hidpp_report response; | ||
416 | int ret; | ||
417 | |||
418 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
419 | CMD_GET_DEVICE_NAME_TYPE_GET_COUNT, NULL, 0, &response); | ||
420 | |||
421 | if (ret > 0) { | ||
422 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
423 | __func__, ret); | ||
424 | return -EPROTO; | ||
425 | } | ||
426 | if (ret) | ||
427 | return ret; | ||
428 | |||
429 | *nameLength = response.fap.params[0]; | ||
430 | |||
431 | return ret; | ||
432 | } | ||
433 | |||
434 | static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, | ||
435 | u8 feature_index, u8 char_index, char *device_name, int len_buf) | ||
436 | { | ||
437 | struct hidpp_report response; | ||
438 | int ret, i; | ||
439 | int count; | ||
440 | |||
441 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
442 | CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME, &char_index, 1, | ||
443 | &response); | ||
444 | |||
445 | if (ret > 0) { | ||
446 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
447 | __func__, ret); | ||
448 | return -EPROTO; | ||
449 | } | ||
450 | if (ret) | ||
451 | return ret; | ||
452 | |||
453 | if (response.report_id == REPORT_ID_HIDPP_LONG) | ||
454 | count = HIDPP_REPORT_LONG_LENGTH - 4; | ||
455 | else | ||
456 | count = HIDPP_REPORT_SHORT_LENGTH - 4; | ||
457 | |||
458 | if (len_buf < count) | ||
459 | count = len_buf; | ||
460 | |||
461 | for (i = 0; i < count; i++) | ||
462 | device_name[i] = response.fap.params[i]; | ||
463 | |||
464 | return count; | ||
465 | } | ||
466 | |||
467 | static char *hidpp_get_device_name(struct hidpp_device *hidpp) | ||
468 | { | ||
469 | u8 feature_type; | ||
470 | u8 feature_index; | ||
471 | u8 __name_length; | ||
472 | char *name; | ||
473 | unsigned index = 0; | ||
474 | int ret; | ||
475 | |||
476 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_GET_DEVICE_NAME_TYPE, | ||
477 | &feature_index, &feature_type); | ||
478 | if (ret) | ||
479 | return NULL; | ||
480 | |||
481 | ret = hidpp_devicenametype_get_count(hidpp, feature_index, | ||
482 | &__name_length); | ||
483 | if (ret) | ||
484 | return NULL; | ||
485 | |||
486 | name = kzalloc(__name_length + 1, GFP_KERNEL); | ||
487 | if (!name) | ||
488 | return NULL; | ||
489 | |||
490 | while (index < __name_length) { | ||
491 | ret = hidpp_devicenametype_get_device_name(hidpp, | ||
492 | feature_index, index, name + index, | ||
493 | __name_length - index); | ||
494 | if (ret <= 0) { | ||
495 | kfree(name); | ||
496 | return NULL; | ||
497 | } | ||
498 | index += ret; | ||
499 | } | ||
500 | |||
501 | return name; | ||
502 | } | ||
503 | |||
504 | /* -------------------------------------------------------------------------- */ | ||
505 | /* 0x6100: TouchPadRawXY */ | ||
506 | /* -------------------------------------------------------------------------- */ | ||
507 | |||
508 | #define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100 | ||
509 | |||
510 | #define CMD_TOUCHPAD_GET_RAW_INFO 0x01 | ||
511 | #define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x21 | ||
512 | |||
513 | #define EVENT_TOUCHPAD_RAW_XY 0x00 | ||
514 | |||
515 | #define TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT 0x01 | ||
516 | #define TOUCHPAD_RAW_XY_ORIGIN_UPPER_LEFT 0x03 | ||
517 | |||
518 | struct hidpp_touchpad_raw_info { | ||
519 | u16 x_size; | ||
520 | u16 y_size; | ||
521 | u8 z_range; | ||
522 | u8 area_range; | ||
523 | u8 timestamp_unit; | ||
524 | u8 maxcontacts; | ||
525 | u8 origin; | ||
526 | u16 res; | ||
527 | }; | ||
528 | |||
529 | struct hidpp_touchpad_raw_xy_finger { | ||
530 | u8 contact_type; | ||
531 | u8 contact_status; | ||
532 | u16 x; | ||
533 | u16 y; | ||
534 | u8 z; | ||
535 | u8 area; | ||
536 | u8 finger_id; | ||
537 | }; | ||
538 | |||
539 | struct hidpp_touchpad_raw_xy { | ||
540 | u16 timestamp; | ||
541 | struct hidpp_touchpad_raw_xy_finger fingers[2]; | ||
542 | u8 spurious_flag; | ||
543 | u8 end_of_frame; | ||
544 | u8 finger_count; | ||
545 | u8 button; | ||
546 | }; | ||
547 | |||
548 | static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp, | ||
549 | u8 feature_index, struct hidpp_touchpad_raw_info *raw_info) | ||
550 | { | ||
551 | struct hidpp_report response; | ||
552 | int ret; | ||
553 | u8 *params = (u8 *)response.fap.params; | ||
554 | |||
555 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
556 | CMD_TOUCHPAD_GET_RAW_INFO, NULL, 0, &response); | ||
557 | |||
558 | if (ret > 0) { | ||
559 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
560 | __func__, ret); | ||
561 | return -EPROTO; | ||
562 | } | ||
563 | if (ret) | ||
564 | return ret; | ||
565 | |||
566 | raw_info->x_size = get_unaligned_be16(¶ms[0]); | ||
567 | raw_info->y_size = get_unaligned_be16(¶ms[2]); | ||
568 | raw_info->z_range = params[4]; | ||
569 | raw_info->area_range = params[5]; | ||
570 | raw_info->maxcontacts = params[7]; | ||
571 | raw_info->origin = params[8]; | ||
572 | /* res is given in unit per inch */ | ||
573 | raw_info->res = get_unaligned_be16(¶ms[13]) * 2 / 51; | ||
574 | |||
575 | return ret; | ||
576 | } | ||
577 | |||
578 | static int hidpp_touchpad_set_raw_report_state(struct hidpp_device *hidpp_dev, | ||
579 | u8 feature_index, bool send_raw_reports, | ||
580 | bool sensor_enhanced_settings) | ||
581 | { | ||
582 | struct hidpp_report response; | ||
583 | |||
584 | /* | ||
585 | * Params: | ||
586 | * bit 0 - enable raw | ||
587 | * bit 1 - 16bit Z, no area | ||
588 | * bit 2 - enhanced sensitivity | ||
589 | * bit 3 - width, height (4 bits each) instead of area | ||
590 | * bit 4 - send raw + gestures (degrades smoothness) | ||
591 | * remaining bits - reserved | ||
592 | */ | ||
593 | u8 params = send_raw_reports | (sensor_enhanced_settings << 2); | ||
594 | |||
595 | return hidpp_send_fap_command_sync(hidpp_dev, feature_index, | ||
596 | CMD_TOUCHPAD_SET_RAW_REPORT_STATE, ¶ms, 1, &response); | ||
597 | } | ||
598 | |||
599 | static void hidpp_touchpad_touch_event(u8 *data, | ||
600 | struct hidpp_touchpad_raw_xy_finger *finger) | ||
601 | { | ||
602 | u8 x_m = data[0] << 2; | ||
603 | u8 y_m = data[2] << 2; | ||
604 | |||
605 | finger->x = x_m << 6 | data[1]; | ||
606 | finger->y = y_m << 6 | data[3]; | ||
607 | |||
608 | finger->contact_type = data[0] >> 6; | ||
609 | finger->contact_status = data[2] >> 6; | ||
610 | |||
611 | finger->z = data[4]; | ||
612 | finger->area = data[5]; | ||
613 | finger->finger_id = data[6] >> 4; | ||
614 | } | ||
615 | |||
616 | static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev, | ||
617 | u8 *data, struct hidpp_touchpad_raw_xy *raw_xy) | ||
618 | { | ||
619 | memset(raw_xy, 0, sizeof(struct hidpp_touchpad_raw_xy)); | ||
620 | raw_xy->end_of_frame = data[8] & 0x01; | ||
621 | raw_xy->spurious_flag = (data[8] >> 1) & 0x01; | ||
622 | raw_xy->finger_count = data[15] & 0x0f; | ||
623 | raw_xy->button = (data[8] >> 2) & 0x01; | ||
624 | |||
625 | if (raw_xy->finger_count) { | ||
626 | hidpp_touchpad_touch_event(&data[2], &raw_xy->fingers[0]); | ||
627 | hidpp_touchpad_touch_event(&data[9], &raw_xy->fingers[1]); | ||
628 | } | ||
629 | } | ||
630 | |||
631 | /* ************************************************************************** */ | ||
632 | /* */ | ||
633 | /* Device Support */ | ||
634 | /* */ | ||
635 | /* ************************************************************************** */ | ||
636 | |||
637 | /* -------------------------------------------------------------------------- */ | ||
638 | /* Touchpad HID++ devices */ | ||
639 | /* -------------------------------------------------------------------------- */ | ||
640 | |||
641 | #define WTP_MANUAL_RESOLUTION 39 | ||
642 | |||
643 | struct wtp_data { | ||
644 | struct input_dev *input; | ||
645 | u16 x_size, y_size; | ||
646 | u8 finger_count; | ||
647 | u8 mt_feature_index; | ||
648 | u8 button_feature_index; | ||
649 | u8 maxcontacts; | ||
650 | bool flip_y; | ||
651 | unsigned int resolution; | ||
652 | }; | ||
653 | |||
654 | static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
655 | struct hid_field *field, struct hid_usage *usage, | ||
656 | unsigned long **bit, int *max) | ||
657 | { | ||
658 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
659 | |||
660 | if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && | ||
661 | (field->application == HID_GD_KEYBOARD)) | ||
662 | return 0; | ||
663 | |||
664 | return -1; | ||
665 | } | ||
666 | |||
667 | static void wtp_populate_input(struct hidpp_device *hidpp, | ||
668 | struct input_dev *input_dev, bool origin_is_hid_core) | ||
669 | { | ||
670 | struct wtp_data *wd = hidpp->private_data; | ||
671 | |||
672 | if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && origin_is_hid_core) | ||
673 | /* this is the generic hid-input call */ | ||
674 | return; | ||
675 | |||
676 | __set_bit(EV_ABS, input_dev->evbit); | ||
677 | __set_bit(EV_KEY, input_dev->evbit); | ||
678 | __clear_bit(EV_REL, input_dev->evbit); | ||
679 | __clear_bit(EV_LED, input_dev->evbit); | ||
680 | |||
681 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, wd->x_size, 0, 0); | ||
682 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, wd->resolution); | ||
683 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, wd->y_size, 0, 0); | ||
684 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, wd->resolution); | ||
685 | |||
686 | /* Max pressure is not given by the devices, pick one */ | ||
687 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 50, 0, 0); | ||
688 | |||
689 | input_set_capability(input_dev, EV_KEY, BTN_LEFT); | ||
690 | |||
691 | if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) | ||
692 | input_set_capability(input_dev, EV_KEY, BTN_RIGHT); | ||
693 | else | ||
694 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | ||
695 | |||
696 | input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER | | ||
697 | INPUT_MT_DROP_UNUSED); | ||
698 | |||
699 | wd->input = input_dev; | ||
700 | } | ||
701 | |||
702 | static void wtp_touch_event(struct wtp_data *wd, | ||
703 | struct hidpp_touchpad_raw_xy_finger *touch_report) | ||
704 | { | ||
705 | int slot; | ||
706 | |||
707 | if (!touch_report->finger_id || touch_report->contact_type) | ||
708 | /* no actual data */ | ||
709 | return; | ||
710 | |||
711 | slot = input_mt_get_slot_by_key(wd->input, touch_report->finger_id); | ||
712 | |||
713 | input_mt_slot(wd->input, slot); | ||
714 | input_mt_report_slot_state(wd->input, MT_TOOL_FINGER, | ||
715 | touch_report->contact_status); | ||
716 | if (touch_report->contact_status) { | ||
717 | input_event(wd->input, EV_ABS, ABS_MT_POSITION_X, | ||
718 | touch_report->x); | ||
719 | input_event(wd->input, EV_ABS, ABS_MT_POSITION_Y, | ||
720 | wd->flip_y ? wd->y_size - touch_report->y : | ||
721 | touch_report->y); | ||
722 | input_event(wd->input, EV_ABS, ABS_MT_PRESSURE, | ||
723 | touch_report->area); | ||
724 | } | ||
725 | } | ||
726 | |||
727 | static void wtp_send_raw_xy_event(struct hidpp_device *hidpp, | ||
728 | struct hidpp_touchpad_raw_xy *raw) | ||
729 | { | ||
730 | struct wtp_data *wd = hidpp->private_data; | ||
731 | int i; | ||
732 | |||
733 | for (i = 0; i < 2; i++) | ||
734 | wtp_touch_event(wd, &(raw->fingers[i])); | ||
735 | |||
736 | if (raw->end_of_frame && | ||
737 | !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS)) | ||
738 | input_event(wd->input, EV_KEY, BTN_LEFT, raw->button); | ||
739 | |||
740 | if (raw->end_of_frame || raw->finger_count <= 2) { | ||
741 | input_mt_sync_frame(wd->input); | ||
742 | input_sync(wd->input); | ||
743 | } | ||
744 | } | ||
745 | |||
746 | static int wtp_mouse_raw_xy_event(struct hidpp_device *hidpp, u8 *data) | ||
747 | { | ||
748 | struct wtp_data *wd = hidpp->private_data; | ||
749 | u8 c1_area = ((data[7] & 0xf) * (data[7] & 0xf) + | ||
750 | (data[7] >> 4) * (data[7] >> 4)) / 2; | ||
751 | u8 c2_area = ((data[13] & 0xf) * (data[13] & 0xf) + | ||
752 | (data[13] >> 4) * (data[13] >> 4)) / 2; | ||
753 | struct hidpp_touchpad_raw_xy raw = { | ||
754 | .timestamp = data[1], | ||
755 | .fingers = { | ||
756 | { | ||
757 | .contact_type = 0, | ||
758 | .contact_status = !!data[7], | ||
759 | .x = get_unaligned_le16(&data[3]), | ||
760 | .y = get_unaligned_le16(&data[5]), | ||
761 | .z = c1_area, | ||
762 | .area = c1_area, | ||
763 | .finger_id = data[2], | ||
764 | }, { | ||
765 | .contact_type = 0, | ||
766 | .contact_status = !!data[13], | ||
767 | .x = get_unaligned_le16(&data[9]), | ||
768 | .y = get_unaligned_le16(&data[11]), | ||
769 | .z = c2_area, | ||
770 | .area = c2_area, | ||
771 | .finger_id = data[8], | ||
772 | } | ||
773 | }, | ||
774 | .finger_count = wd->maxcontacts, | ||
775 | .spurious_flag = 0, | ||
776 | .end_of_frame = (data[0] >> 7) == 0, | ||
777 | .button = data[0] & 0x01, | ||
778 | }; | ||
779 | |||
780 | wtp_send_raw_xy_event(hidpp, &raw); | ||
781 | |||
782 | return 1; | ||
783 | } | ||
784 | |||
785 | static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) | ||
786 | { | ||
787 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
788 | struct wtp_data *wd = hidpp->private_data; | ||
789 | struct hidpp_report *report = (struct hidpp_report *)data; | ||
790 | struct hidpp_touchpad_raw_xy raw; | ||
791 | |||
792 | if (!wd || !wd->input) | ||
793 | return 1; | ||
794 | |||
795 | switch (data[0]) { | ||
796 | case 0x02: | ||
797 | if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { | ||
798 | input_event(wd->input, EV_KEY, BTN_LEFT, | ||
799 | !!(data[1] & 0x01)); | ||
800 | input_event(wd->input, EV_KEY, BTN_RIGHT, | ||
801 | !!(data[1] & 0x02)); | ||
802 | input_sync(wd->input); | ||
803 | } else { | ||
804 | if (size < 21) | ||
805 | return 1; | ||
806 | return wtp_mouse_raw_xy_event(hidpp, &data[7]); | ||
807 | } | ||
808 | case REPORT_ID_HIDPP_LONG: | ||
809 | if ((report->fap.feature_index != wd->mt_feature_index) || | ||
810 | (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) | ||
811 | return 1; | ||
812 | hidpp_touchpad_raw_xy_event(hidpp, data + 4, &raw); | ||
813 | |||
814 | wtp_send_raw_xy_event(hidpp, &raw); | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | static int wtp_get_config(struct hidpp_device *hidpp) | ||
822 | { | ||
823 | struct wtp_data *wd = hidpp->private_data; | ||
824 | struct hidpp_touchpad_raw_info raw_info = {0}; | ||
825 | u8 feature_type; | ||
826 | int ret; | ||
827 | |||
828 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_TOUCHPAD_RAW_XY, | ||
829 | &wd->mt_feature_index, &feature_type); | ||
830 | if (ret) | ||
831 | /* means that the device is not powered up */ | ||
832 | return ret; | ||
833 | |||
834 | ret = hidpp_touchpad_get_raw_info(hidpp, wd->mt_feature_index, | ||
835 | &raw_info); | ||
836 | if (ret) | ||
837 | return ret; | ||
838 | |||
839 | wd->x_size = raw_info.x_size; | ||
840 | wd->y_size = raw_info.y_size; | ||
841 | wd->maxcontacts = raw_info.maxcontacts; | ||
842 | wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT; | ||
843 | wd->resolution = raw_info.res; | ||
844 | if (!wd->resolution) | ||
845 | wd->resolution = WTP_MANUAL_RESOLUTION; | ||
846 | |||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id) | ||
851 | { | ||
852 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
853 | struct wtp_data *wd; | ||
854 | |||
855 | wd = devm_kzalloc(&hdev->dev, sizeof(struct wtp_data), | ||
856 | GFP_KERNEL); | ||
857 | if (!wd) | ||
858 | return -ENOMEM; | ||
859 | |||
860 | hidpp->private_data = wd; | ||
861 | |||
862 | return 0; | ||
863 | }; | ||
864 | |||
865 | static void wtp_connect(struct hid_device *hdev, bool connected) | ||
866 | { | ||
867 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
868 | struct wtp_data *wd = hidpp->private_data; | ||
869 | int ret; | ||
870 | |||
871 | if (!connected) | ||
872 | return; | ||
873 | |||
874 | if (!wd->x_size) { | ||
875 | ret = wtp_get_config(hidpp); | ||
876 | if (ret) { | ||
877 | hid_err(hdev, "Can not get wtp config: %d\n", ret); | ||
878 | return; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index, | ||
883 | true, true); | ||
884 | } | ||
885 | |||
886 | /* -------------------------------------------------------------------------- */ | ||
887 | /* Generic HID++ devices */ | ||
888 | /* -------------------------------------------------------------------------- */ | ||
889 | |||
890 | static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
891 | struct hid_field *field, struct hid_usage *usage, | ||
892 | unsigned long **bit, int *max) | ||
893 | { | ||
894 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
895 | |||
896 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | ||
897 | return wtp_input_mapping(hdev, hi, field, usage, bit, max); | ||
898 | |||
899 | return 0; | ||
900 | } | ||
901 | |||
902 | static void hidpp_populate_input(struct hidpp_device *hidpp, | ||
903 | struct input_dev *input, bool origin_is_hid_core) | ||
904 | { | ||
905 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | ||
906 | wtp_populate_input(hidpp, input, origin_is_hid_core); | ||
907 | } | ||
908 | |||
909 | static void hidpp_input_configured(struct hid_device *hdev, | ||
910 | struct hid_input *hidinput) | ||
911 | { | ||
912 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
913 | struct input_dev *input = hidinput->input; | ||
914 | |||
915 | hidpp_populate_input(hidpp, input, true); | ||
916 | } | ||
917 | |||
918 | static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | ||
919 | int size) | ||
920 | { | ||
921 | struct hidpp_report *question = hidpp->send_receive_buf; | ||
922 | struct hidpp_report *answer = hidpp->send_receive_buf; | ||
923 | struct hidpp_report *report = (struct hidpp_report *)data; | ||
924 | |||
925 | /* | ||
926 | * If the mutex is locked then we have a pending answer from a | ||
927 | * previoulsly sent command | ||
928 | */ | ||
929 | if (unlikely(mutex_is_locked(&hidpp->send_mutex))) { | ||
930 | /* | ||
931 | * Check for a correct hidpp20 answer or the corresponding | ||
932 | * error | ||
933 | */ | ||
934 | if (hidpp_match_answer(question, report) || | ||
935 | hidpp_match_error(question, report)) { | ||
936 | *answer = *report; | ||
937 | hidpp->answer_available = true; | ||
938 | wake_up(&hidpp->wait); | ||
939 | /* | ||
940 | * This was an answer to a command that this driver sent | ||
941 | * We return 1 to hid-core to avoid forwarding the | ||
942 | * command upstream as it has been treated by the driver | ||
943 | */ | ||
944 | |||
945 | return 1; | ||
946 | } | ||
947 | } | ||
948 | |||
949 | if (unlikely(hidpp_report_is_connect_event(report))) { | ||
950 | atomic_set(&hidpp->connected, | ||
951 | !(report->rap.params[0] & (1 << 6))); | ||
952 | if ((hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) && | ||
953 | (schedule_work(&hidpp->work) == 0)) | ||
954 | dbg_hid("%s: connect event already queued\n", __func__); | ||
955 | return 1; | ||
956 | } | ||
957 | |||
958 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | ||
959 | return wtp_raw_event(hidpp->hid_dev, data, size); | ||
960 | |||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, | ||
965 | u8 *data, int size) | ||
966 | { | ||
967 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
968 | |||
969 | switch (data[0]) { | ||
970 | case REPORT_ID_HIDPP_LONG: | ||
971 | if (size != HIDPP_REPORT_LONG_LENGTH) { | ||
972 | hid_err(hdev, "received hid++ report of bad size (%d)", | ||
973 | size); | ||
974 | return 1; | ||
975 | } | ||
976 | return hidpp_raw_hidpp_event(hidpp, data, size); | ||
977 | case REPORT_ID_HIDPP_SHORT: | ||
978 | if (size != HIDPP_REPORT_SHORT_LENGTH) { | ||
979 | hid_err(hdev, "received hid++ report of bad size (%d)", | ||
980 | size); | ||
981 | return 1; | ||
982 | } | ||
983 | return hidpp_raw_hidpp_event(hidpp, data, size); | ||
984 | } | ||
985 | |||
986 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | ||
987 | return wtp_raw_event(hdev, data, size); | ||
988 | |||
989 | return 0; | ||
990 | } | ||
991 | |||
992 | static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) | ||
993 | { | ||
994 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
995 | char *name; | ||
996 | |||
997 | if (use_unifying) | ||
998 | /* | ||
999 | * the device is connected through an Unifying receiver, and | ||
1000 | * might not be already connected. | ||
1001 | * Ask the receiver for its name. | ||
1002 | */ | ||
1003 | name = hidpp_get_unifying_name(hidpp); | ||
1004 | else | ||
1005 | name = hidpp_get_device_name(hidpp); | ||
1006 | |||
1007 | if (!name) | ||
1008 | hid_err(hdev, "unable to retrieve the name of the device"); | ||
1009 | else | ||
1010 | snprintf(hdev->name, sizeof(hdev->name), "%s", name); | ||
1011 | |||
1012 | kfree(name); | ||
1013 | } | ||
1014 | |||
1015 | static int hidpp_input_open(struct input_dev *dev) | ||
1016 | { | ||
1017 | struct hid_device *hid = input_get_drvdata(dev); | ||
1018 | |||
1019 | return hid_hw_open(hid); | ||
1020 | } | ||
1021 | |||
1022 | static void hidpp_input_close(struct input_dev *dev) | ||
1023 | { | ||
1024 | struct hid_device *hid = input_get_drvdata(dev); | ||
1025 | |||
1026 | hid_hw_close(hid); | ||
1027 | } | ||
1028 | |||
1029 | static struct input_dev *hidpp_allocate_input(struct hid_device *hdev) | ||
1030 | { | ||
1031 | struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev); | ||
1032 | |||
1033 | if (!input_dev) | ||
1034 | return NULL; | ||
1035 | |||
1036 | input_set_drvdata(input_dev, hdev); | ||
1037 | input_dev->open = hidpp_input_open; | ||
1038 | input_dev->close = hidpp_input_close; | ||
1039 | |||
1040 | input_dev->name = hdev->name; | ||
1041 | input_dev->phys = hdev->phys; | ||
1042 | input_dev->uniq = hdev->uniq; | ||
1043 | input_dev->id.bustype = hdev->bus; | ||
1044 | input_dev->id.vendor = hdev->vendor; | ||
1045 | input_dev->id.product = hdev->product; | ||
1046 | input_dev->id.version = hdev->version; | ||
1047 | input_dev->dev.parent = &hdev->dev; | ||
1048 | |||
1049 | return input_dev; | ||
1050 | } | ||
1051 | |||
1052 | static void hidpp_connect_event(struct hidpp_device *hidpp) | ||
1053 | { | ||
1054 | struct hid_device *hdev = hidpp->hid_dev; | ||
1055 | int ret = 0; | ||
1056 | bool connected = atomic_read(&hidpp->connected); | ||
1057 | struct input_dev *input; | ||
1058 | char *name, *devm_name; | ||
1059 | |||
1060 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | ||
1061 | wtp_connect(hdev, connected); | ||
1062 | |||
1063 | if (!connected || hidpp->delayed_input) | ||
1064 | return; | ||
1065 | |||
1066 | if (!hidpp->protocol_major) { | ||
1067 | ret = !hidpp_is_connected(hidpp); | ||
1068 | if (ret) { | ||
1069 | hid_err(hdev, "Can not get the protocol version.\n"); | ||
1070 | return; | ||
1071 | } | ||
1072 | } | ||
1073 | |||
1074 | /* the device is already connected, we can ask for its name and | ||
1075 | * protocol */ | ||
1076 | hid_info(hdev, "HID++ %u.%u device connected.\n", | ||
1077 | hidpp->protocol_major, hidpp->protocol_minor); | ||
1078 | |||
1079 | input = hidpp_allocate_input(hdev); | ||
1080 | if (!input) { | ||
1081 | hid_err(hdev, "cannot allocate new input device: %d\n", ret); | ||
1082 | return; | ||
1083 | } | ||
1084 | |||
1085 | name = hidpp_get_device_name(hidpp); | ||
1086 | if (!name) { | ||
1087 | hid_err(hdev, "unable to retrieve the name of the device"); | ||
1088 | } else { | ||
1089 | devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name); | ||
1090 | if (devm_name) | ||
1091 | input->name = devm_name; | ||
1092 | kfree(name); | ||
1093 | } | ||
1094 | |||
1095 | hidpp_populate_input(hidpp, input, false); | ||
1096 | |||
1097 | ret = input_register_device(input); | ||
1098 | if (ret) | ||
1099 | input_free_device(input); | ||
1100 | |||
1101 | hidpp->delayed_input = input; | ||
1102 | } | ||
1103 | |||
1104 | static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
1105 | { | ||
1106 | struct hidpp_device *hidpp; | ||
1107 | int ret; | ||
1108 | bool connected; | ||
1109 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | ||
1110 | |||
1111 | hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device), | ||
1112 | GFP_KERNEL); | ||
1113 | if (!hidpp) | ||
1114 | return -ENOMEM; | ||
1115 | |||
1116 | hidpp->hid_dev = hdev; | ||
1117 | hid_set_drvdata(hdev, hidpp); | ||
1118 | |||
1119 | hidpp->quirks = id->driver_data; | ||
1120 | |||
1121 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { | ||
1122 | ret = wtp_allocate(hdev, id); | ||
1123 | if (ret) | ||
1124 | goto wtp_allocate_fail; | ||
1125 | } | ||
1126 | |||
1127 | INIT_WORK(&hidpp->work, delayed_work_cb); | ||
1128 | mutex_init(&hidpp->send_mutex); | ||
1129 | init_waitqueue_head(&hidpp->wait); | ||
1130 | |||
1131 | ret = hid_parse(hdev); | ||
1132 | if (ret) { | ||
1133 | hid_err(hdev, "%s:parse failed\n", __func__); | ||
1134 | goto hid_parse_fail; | ||
1135 | } | ||
1136 | |||
1137 | /* Allow incoming packets */ | ||
1138 | hid_device_io_start(hdev); | ||
1139 | |||
1140 | connected = hidpp_is_connected(hidpp); | ||
1141 | if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE) { | ||
1142 | if (!connected) { | ||
1143 | hid_err(hdev, "Device not connected"); | ||
1144 | hid_device_io_stop(hdev); | ||
1145 | goto hid_parse_fail; | ||
1146 | } | ||
1147 | |||
1148 | hid_info(hdev, "HID++ %u.%u device connected.\n", | ||
1149 | hidpp->protocol_major, hidpp->protocol_minor); | ||
1150 | } | ||
1151 | |||
1152 | hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE); | ||
1153 | atomic_set(&hidpp->connected, connected); | ||
1154 | |||
1155 | if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { | ||
1156 | ret = wtp_get_config(hidpp); | ||
1157 | if (ret) | ||
1158 | goto hid_parse_fail; | ||
1159 | } | ||
1160 | |||
1161 | /* Block incoming packets */ | ||
1162 | hid_device_io_stop(hdev); | ||
1163 | |||
1164 | if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) | ||
1165 | connect_mask &= ~HID_CONNECT_HIDINPUT; | ||
1166 | |||
1167 | /* Re-enable hidinput for multi-input devices */ | ||
1168 | if (hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) | ||
1169 | connect_mask |= HID_CONNECT_HIDINPUT; | ||
1170 | |||
1171 | ret = hid_hw_start(hdev, connect_mask); | ||
1172 | if (ret) { | ||
1173 | hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); | ||
1174 | goto hid_hw_start_fail; | ||
1175 | } | ||
1176 | |||
1177 | if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) { | ||
1178 | /* Allow incoming packets */ | ||
1179 | hid_device_io_start(hdev); | ||
1180 | |||
1181 | hidpp_connect_event(hidpp); | ||
1182 | } | ||
1183 | |||
1184 | return ret; | ||
1185 | |||
1186 | hid_hw_start_fail: | ||
1187 | hid_parse_fail: | ||
1188 | cancel_work_sync(&hidpp->work); | ||
1189 | mutex_destroy(&hidpp->send_mutex); | ||
1190 | wtp_allocate_fail: | ||
1191 | hid_set_drvdata(hdev, NULL); | ||
1192 | return ret; | ||
1193 | } | ||
1194 | |||
1195 | static void hidpp_remove(struct hid_device *hdev) | ||
1196 | { | ||
1197 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
1198 | |||
1199 | cancel_work_sync(&hidpp->work); | ||
1200 | mutex_destroy(&hidpp->send_mutex); | ||
1201 | hid_hw_stop(hdev); | ||
1202 | } | ||
1203 | |||
1204 | static const struct hid_device_id hidpp_devices[] = { | ||
1205 | { /* wireless touchpad */ | ||
1206 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, | ||
1207 | USB_VENDOR_ID_LOGITECH, 0x4011), | ||
1208 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | | ||
1209 | HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, | ||
1210 | { /* wireless touchpad T650 */ | ||
1211 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, | ||
1212 | USB_VENDOR_ID_LOGITECH, 0x4101), | ||
1213 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, | ||
1214 | { /* wireless touchpad T651 */ | ||
1215 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, | ||
1216 | USB_DEVICE_ID_LOGITECH_T651), | ||
1217 | .driver_data = HIDPP_QUIRK_CLASS_WTP }, | ||
1218 | { /* Keyboard TK820 */ | ||
1219 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, | ||
1220 | USB_VENDOR_ID_LOGITECH, 0x4102), | ||
1221 | .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_MULTI_INPUT | | ||
1222 | HIDPP_QUIRK_CLASS_WTP }, | ||
1223 | |||
1224 | { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, | ||
1225 | USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, | ||
1226 | {} | ||
1227 | }; | ||
1228 | |||
1229 | MODULE_DEVICE_TABLE(hid, hidpp_devices); | ||
1230 | |||
1231 | static struct hid_driver hidpp_driver = { | ||
1232 | .name = "logitech-hidpp-device", | ||
1233 | .id_table = hidpp_devices, | ||
1234 | .probe = hidpp_probe, | ||
1235 | .remove = hidpp_remove, | ||
1236 | .raw_event = hidpp_raw_event, | ||
1237 | .input_configured = hidpp_input_configured, | ||
1238 | .input_mapping = hidpp_input_mapping, | ||
1239 | }; | ||
1240 | |||
1241 | module_hid_driver(hidpp_driver); | ||
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 8ba17a946f2a..cacda43f6a6f 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
@@ -274,6 +274,8 @@ static const struct hid_device_id ms_devices[] = { | |||
274 | .driver_data = MS_NOGET }, | 274 | .driver_data = MS_NOGET }, |
275 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), | 275 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
276 | .driver_data = MS_DUPLICATE_USAGES }, | 276 | .driver_data = MS_DUPLICATE_USAGES }, |
277 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), | ||
278 | .driver_data = MS_HIDINPUT }, | ||
277 | 279 | ||
278 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), | 280 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), |
279 | .driver_data = MS_PRESENTER }, | 281 | .driver_data = MS_PRESENTER }, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 51e25b9407f2..f65e78b46999 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -67,6 +67,7 @@ MODULE_LICENSE("GPL"); | |||
67 | #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) | 67 | #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) |
68 | #define MT_QUIRK_HOVERING (1 << 11) | 68 | #define MT_QUIRK_HOVERING (1 << 11) |
69 | #define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) | 69 | #define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) |
70 | #define MT_QUIRK_FORCE_GET_FEATURE (1 << 13) | ||
70 | 71 | ||
71 | #define MT_INPUTMODE_TOUCHSCREEN 0x02 | 72 | #define MT_INPUTMODE_TOUCHSCREEN 0x02 |
72 | #define MT_INPUTMODE_TOUCHPAD 0x03 | 73 | #define MT_INPUTMODE_TOUCHPAD 0x03 |
@@ -150,6 +151,7 @@ static void mt_post_parse(struct mt_device *td); | |||
150 | #define MT_CLS_FLATFROG 0x0107 | 151 | #define MT_CLS_FLATFROG 0x0107 |
151 | #define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108 | 152 | #define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108 |
152 | #define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109 | 153 | #define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109 |
154 | #define MT_CLS_VTL 0x0110 | ||
153 | 155 | ||
154 | #define MT_DEFAULT_MAXCONTACT 10 | 156 | #define MT_DEFAULT_MAXCONTACT 10 |
155 | #define MT_MAX_MAXCONTACT 250 | 157 | #define MT_MAX_MAXCONTACT 250 |
@@ -255,6 +257,11 @@ static struct mt_class mt_classes[] = { | |||
255 | .sn_move = 2048, | 257 | .sn_move = 2048, |
256 | .maxcontacts = 40, | 258 | .maxcontacts = 40, |
257 | }, | 259 | }, |
260 | { .name = MT_CLS_VTL, | ||
261 | .quirks = MT_QUIRK_ALWAYS_VALID | | ||
262 | MT_QUIRK_CONTACT_CNT_ACCURATE | | ||
263 | MT_QUIRK_FORCE_GET_FEATURE, | ||
264 | }, | ||
258 | { } | 265 | { } |
259 | }; | 266 | }; |
260 | 267 | ||
@@ -809,6 +816,9 @@ static void mt_set_input_mode(struct hid_device *hdev) | |||
809 | struct mt_device *td = hid_get_drvdata(hdev); | 816 | struct mt_device *td = hid_get_drvdata(hdev); |
810 | struct hid_report *r; | 817 | struct hid_report *r; |
811 | struct hid_report_enum *re; | 818 | struct hid_report_enum *re; |
819 | struct mt_class *cls = &td->mtclass; | ||
820 | char *buf; | ||
821 | int report_len; | ||
812 | 822 | ||
813 | if (td->inputmode < 0) | 823 | if (td->inputmode < 0) |
814 | return; | 824 | return; |
@@ -816,6 +826,18 @@ static void mt_set_input_mode(struct hid_device *hdev) | |||
816 | re = &(hdev->report_enum[HID_FEATURE_REPORT]); | 826 | re = &(hdev->report_enum[HID_FEATURE_REPORT]); |
817 | r = re->report_id_hash[td->inputmode]; | 827 | r = re->report_id_hash[td->inputmode]; |
818 | if (r) { | 828 | if (r) { |
829 | if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) { | ||
830 | report_len = hid_report_len(r); | ||
831 | buf = hid_alloc_report_buf(r, GFP_KERNEL); | ||
832 | if (!buf) { | ||
833 | hid_err(hdev, "failed to allocate buffer for report\n"); | ||
834 | return; | ||
835 | } | ||
836 | hid_hw_raw_request(hdev, r->id, buf, report_len, | ||
837 | HID_FEATURE_REPORT, | ||
838 | HID_REQ_GET_REPORT); | ||
839 | kfree(buf); | ||
840 | } | ||
819 | r->field[0]->value[td->inputmode_index] = td->inputmode_value; | 841 | r->field[0]->value[td->inputmode_index] = td->inputmode_value; |
820 | hid_hw_request(hdev, r, HID_REQ_SET_REPORT); | 842 | hid_hw_request(hdev, r, HID_REQ_SET_REPORT); |
821 | } | 843 | } |
@@ -1281,6 +1303,11 @@ static const struct hid_device_id mt_devices[] = { | |||
1281 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, | 1303 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, |
1282 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, | 1304 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, |
1283 | 1305 | ||
1306 | /* VTL panels */ | ||
1307 | { .driver_data = MT_CLS_VTL, | ||
1308 | MT_USB_DEVICE(USB_VENDOR_ID_VTL, | ||
1309 | USB_DEVICE_ID_VTL_MULTITOUCH_FF3F) }, | ||
1310 | |||
1284 | /* Wistron panels */ | 1311 | /* Wistron panels */ |
1285 | { .driver_data = MT_CLS_NSMU, | 1312 | { .driver_data = MT_CLS_NSMU, |
1286 | MT_USB_DEVICE(USB_VENDOR_ID_WISTRON, | 1313 | MT_USB_DEVICE(USB_VENDOR_ID_WISTRON, |
diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c new file mode 100644 index 000000000000..2180e0789b76 --- /dev/null +++ b/drivers/hid/hid-plantronics.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Plantronics USB HID Driver | ||
3 | * | ||
4 | * Copyright (c) 2014 JD Cole <jd.cole@plantronics.com> | ||
5 | * Copyright (c) 2014 Terry Junge <terry.junge@plantronics.com> | ||
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 "hid-ids.h" | ||
16 | |||
17 | #include <linux/hid.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | static int plantronics_input_mapping(struct hid_device *hdev, | ||
21 | struct hid_input *hi, | ||
22 | struct hid_field *field, | ||
23 | struct hid_usage *usage, | ||
24 | unsigned long **bit, int *max) | ||
25 | { | ||
26 | if (field->application == HID_CP_CONSUMERCONTROL | ||
27 | && (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) { | ||
28 | hid_dbg(hdev, "usage: %08x (appl: %08x) - defaulted\n", | ||
29 | usage->hid, field->application); | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | hid_dbg(hdev, "usage: %08x (appl: %08x) - ignored\n", | ||
34 | usage->hid, field->application); | ||
35 | |||
36 | return -1; | ||
37 | } | ||
38 | |||
39 | static const struct hid_device_id plantronics_devices[] = { | ||
40 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, | ||
41 | { } | ||
42 | }; | ||
43 | MODULE_DEVICE_TABLE(hid, plantronics_devices); | ||
44 | |||
45 | static struct hid_driver plantronics_driver = { | ||
46 | .name = "plantronics", | ||
47 | .id_table = plantronics_devices, | ||
48 | .input_mapping = plantronics_input_mapping, | ||
49 | }; | ||
50 | module_hid_driver(plantronics_driver); | ||
51 | |||
52 | MODULE_AUTHOR("JD Cole <jd.cole@plantronics.com>"); | ||
53 | MODULE_AUTHOR("Terry Junge <terry.junge@plantronics.com>"); | ||
54 | MODULE_DESCRIPTION("Plantronics USB HID Driver"); | ||
55 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 3cccff73b9b9..b51200fe2f33 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
@@ -584,11 +584,15 @@ static int rmi_populate_f11(struct hid_device *hdev) | |||
584 | bool has_query10 = false; | 584 | bool has_query10 = false; |
585 | bool has_query11; | 585 | bool has_query11; |
586 | bool has_query12; | 586 | bool has_query12; |
587 | bool has_query27; | ||
588 | bool has_query28; | ||
589 | bool has_query36 = false; | ||
587 | bool has_physical_props; | 590 | bool has_physical_props; |
588 | bool has_gestures; | 591 | bool has_gestures; |
589 | bool has_rel; | 592 | bool has_rel; |
593 | bool has_data40 = false; | ||
590 | unsigned x_size, y_size; | 594 | unsigned x_size, y_size; |
591 | u16 query12_offset; | 595 | u16 query_offset; |
592 | 596 | ||
593 | if (!data->f11.query_base_addr) { | 597 | if (!data->f11.query_base_addr) { |
594 | hid_err(hdev, "No 2D sensor found, giving up.\n"); | 598 | hid_err(hdev, "No 2D sensor found, giving up.\n"); |
@@ -604,6 +608,8 @@ static int rmi_populate_f11(struct hid_device *hdev) | |||
604 | has_query9 = !!(buf[0] & BIT(3)); | 608 | has_query9 = !!(buf[0] & BIT(3)); |
605 | has_query11 = !!(buf[0] & BIT(4)); | 609 | has_query11 = !!(buf[0] & BIT(4)); |
606 | has_query12 = !!(buf[0] & BIT(5)); | 610 | has_query12 = !!(buf[0] & BIT(5)); |
611 | has_query27 = !!(buf[0] & BIT(6)); | ||
612 | has_query28 = !!(buf[0] & BIT(7)); | ||
607 | 613 | ||
608 | /* query 1 to get the max number of fingers */ | 614 | /* query 1 to get the max number of fingers */ |
609 | ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf); | 615 | ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf); |
@@ -626,43 +632,43 @@ static int rmi_populate_f11(struct hid_device *hdev) | |||
626 | has_rel = !!(buf[0] & BIT(3)); | 632 | has_rel = !!(buf[0] & BIT(3)); |
627 | has_gestures = !!(buf[0] & BIT(5)); | 633 | has_gestures = !!(buf[0] & BIT(5)); |
628 | 634 | ||
635 | /* | ||
636 | * At least 4 queries are guaranteed to be present in F11 | ||
637 | * +1 for query 5 which is present since absolute events are | ||
638 | * reported and +1 for query 12. | ||
639 | */ | ||
640 | query_offset = 6; | ||
641 | |||
642 | if (has_rel) | ||
643 | ++query_offset; /* query 6 is present */ | ||
644 | |||
629 | if (has_gestures) { | 645 | if (has_gestures) { |
630 | /* query 8 to find out if query 10 exists */ | 646 | /* query 8 to find out if query 10 exists */ |
631 | ret = rmi_read(hdev, data->f11.query_base_addr + 8, buf); | 647 | ret = rmi_read(hdev, |
648 | data->f11.query_base_addr + query_offset + 1, buf); | ||
632 | if (ret) { | 649 | if (ret) { |
633 | hid_err(hdev, "can not read gesture information: %d.\n", | 650 | hid_err(hdev, "can not read gesture information: %d.\n", |
634 | ret); | 651 | ret); |
635 | return ret; | 652 | return ret; |
636 | } | 653 | } |
637 | has_query10 = !!(buf[0] & BIT(2)); | 654 | has_query10 = !!(buf[0] & BIT(2)); |
638 | } | ||
639 | 655 | ||
640 | /* | 656 | query_offset += 2; /* query 7 and 8 are present */ |
641 | * At least 4 queries are guaranteed to be present in F11 | 657 | } |
642 | * +1 for query 5 which is present since absolute events are | ||
643 | * reported and +1 for query 12. | ||
644 | */ | ||
645 | query12_offset = 6; | ||
646 | |||
647 | if (has_rel) | ||
648 | ++query12_offset; /* query 6 is present */ | ||
649 | |||
650 | if (has_gestures) | ||
651 | query12_offset += 2; /* query 7 and 8 are present */ | ||
652 | 658 | ||
653 | if (has_query9) | 659 | if (has_query9) |
654 | ++query12_offset; | 660 | ++query_offset; |
655 | 661 | ||
656 | if (has_query10) | 662 | if (has_query10) |
657 | ++query12_offset; | 663 | ++query_offset; |
658 | 664 | ||
659 | if (has_query11) | 665 | if (has_query11) |
660 | ++query12_offset; | 666 | ++query_offset; |
661 | 667 | ||
662 | /* query 12 to know if the physical properties are reported */ | 668 | /* query 12 to know if the physical properties are reported */ |
663 | if (has_query12) { | 669 | if (has_query12) { |
664 | ret = rmi_read(hdev, data->f11.query_base_addr | 670 | ret = rmi_read(hdev, data->f11.query_base_addr |
665 | + query12_offset, buf); | 671 | + query_offset, buf); |
666 | if (ret) { | 672 | if (ret) { |
667 | hid_err(hdev, "can not get query 12: %d.\n", ret); | 673 | hid_err(hdev, "can not get query 12: %d.\n", ret); |
668 | return ret; | 674 | return ret; |
@@ -670,9 +676,10 @@ static int rmi_populate_f11(struct hid_device *hdev) | |||
670 | has_physical_props = !!(buf[0] & BIT(5)); | 676 | has_physical_props = !!(buf[0] & BIT(5)); |
671 | 677 | ||
672 | if (has_physical_props) { | 678 | if (has_physical_props) { |
679 | query_offset += 1; | ||
673 | ret = rmi_read_block(hdev, | 680 | ret = rmi_read_block(hdev, |
674 | data->f11.query_base_addr | 681 | data->f11.query_base_addr |
675 | + query12_offset + 1, buf, 4); | 682 | + query_offset, buf, 4); |
676 | if (ret) { | 683 | if (ret) { |
677 | hid_err(hdev, "can not read query 15-18: %d.\n", | 684 | hid_err(hdev, "can not read query 15-18: %d.\n", |
678 | ret); | 685 | ret); |
@@ -687,9 +694,45 @@ static int rmi_populate_f11(struct hid_device *hdev) | |||
687 | 694 | ||
688 | hid_info(hdev, "%s: size in mm: %d x %d\n", | 695 | hid_info(hdev, "%s: size in mm: %d x %d\n", |
689 | __func__, data->x_size_mm, data->y_size_mm); | 696 | __func__, data->x_size_mm, data->y_size_mm); |
697 | |||
698 | /* | ||
699 | * query 15 - 18 contain the size of the sensor | ||
700 | * and query 19 - 26 contain bezel dimensions | ||
701 | */ | ||
702 | query_offset += 12; | ||
703 | } | ||
704 | } | ||
705 | |||
706 | if (has_query27) | ||
707 | ++query_offset; | ||
708 | |||
709 | if (has_query28) { | ||
710 | ret = rmi_read(hdev, data->f11.query_base_addr | ||
711 | + query_offset, buf); | ||
712 | if (ret) { | ||
713 | hid_err(hdev, "can not get query 28: %d.\n", ret); | ||
714 | return ret; | ||
715 | } | ||
716 | |||
717 | has_query36 = !!(buf[0] & BIT(6)); | ||
718 | } | ||
719 | |||
720 | if (has_query36) { | ||
721 | query_offset += 2; | ||
722 | ret = rmi_read(hdev, data->f11.query_base_addr | ||
723 | + query_offset, buf); | ||
724 | if (ret) { | ||
725 | hid_err(hdev, "can not get query 36: %d.\n", ret); | ||
726 | return ret; | ||
690 | } | 727 | } |
728 | |||
729 | has_data40 = !!(buf[0] & BIT(5)); | ||
691 | } | 730 | } |
692 | 731 | ||
732 | |||
733 | if (has_data40) | ||
734 | data->f11.report_size += data->max_fingers * 2; | ||
735 | |||
693 | /* | 736 | /* |
694 | * retrieve the ctrl registers | 737 | * retrieve the ctrl registers |
695 | * the ctrl register has a size of 20 but a fw bug split it into 16 + 4, | 738 | * the ctrl register has a size of 20 but a fw bug split it into 16 + 4, |
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 6101816a7ddd..c29265055ac1 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c | |||
@@ -46,6 +46,7 @@ static void kone_profile_activated(struct kone_device *kone, uint new_profile) | |||
46 | static void kone_profile_report(struct kone_device *kone, uint new_profile) | 46 | static void kone_profile_report(struct kone_device *kone, uint new_profile) |
47 | { | 47 | { |
48 | struct kone_roccat_report roccat_report; | 48 | struct kone_roccat_report roccat_report; |
49 | |||
49 | roccat_report.event = kone_mouse_event_switch_profile; | 50 | roccat_report.event = kone_mouse_event_switch_profile; |
50 | roccat_report.value = new_profile; | 51 | roccat_report.value = new_profile; |
51 | roccat_report.key = 0; | 52 | roccat_report.key = 0; |
@@ -163,6 +164,7 @@ static int kone_set_settings(struct usb_device *usb_dev, | |||
163 | struct kone_settings const *settings) | 164 | struct kone_settings const *settings) |
164 | { | 165 | { |
165 | int retval; | 166 | int retval; |
167 | |||
166 | retval = kone_send(usb_dev, kone_command_settings, | 168 | retval = kone_send(usb_dev, kone_command_settings, |
167 | settings, sizeof(struct kone_settings)); | 169 | settings, sizeof(struct kone_settings)); |
168 | if (retval) | 170 | if (retval) |
@@ -387,7 +389,7 @@ static struct bin_attribute bin_attr_profile##number = { \ | |||
387 | .read = kone_sysfs_read_profilex, \ | 389 | .read = kone_sysfs_read_profilex, \ |
388 | .write = kone_sysfs_write_profilex, \ | 390 | .write = kone_sysfs_write_profilex, \ |
389 | .private = &profile_numbers[number-1], \ | 391 | .private = &profile_numbers[number-1], \ |
390 | }; | 392 | } |
391 | PROFILE_ATTR(1); | 393 | PROFILE_ATTR(1); |
392 | PROFILE_ATTR(2); | 394 | PROFILE_ATTR(2); |
393 | PROFILE_ATTR(3); | 395 | PROFILE_ATTR(3); |
@@ -456,6 +458,7 @@ static ssize_t kone_sysfs_show_tcu(struct device *dev, | |||
456 | static int kone_tcu_command(struct usb_device *usb_dev, int number) | 458 | static int kone_tcu_command(struct usb_device *usb_dev, int number) |
457 | { | 459 | { |
458 | unsigned char value; | 460 | unsigned char value; |
461 | |||
459 | value = number; | 462 | value = number; |
460 | return kone_send(usb_dev, kone_command_calibrate, &value, 1); | 463 | return kone_send(usb_dev, kone_command_calibrate, &value, 1); |
461 | } | 464 | } |
@@ -697,10 +700,8 @@ static int kone_init_specials(struct hid_device *hdev) | |||
697 | == USB_INTERFACE_PROTOCOL_MOUSE) { | 700 | == USB_INTERFACE_PROTOCOL_MOUSE) { |
698 | 701 | ||
699 | kone = kzalloc(sizeof(*kone), GFP_KERNEL); | 702 | kone = kzalloc(sizeof(*kone), GFP_KERNEL); |
700 | if (!kone) { | 703 | if (!kone) |
701 | hid_err(hdev, "can't alloc device descriptor\n"); | ||
702 | return -ENOMEM; | 704 | return -ENOMEM; |
703 | } | ||
704 | hid_set_drvdata(hdev, kone); | 705 | hid_set_drvdata(hdev, kone); |
705 | 706 | ||
706 | retval = kone_init_kone_device_struct(usb_dev, kone); | 707 | retval = kone_init_kone_device_struct(usb_dev, kone); |
diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c index 69cca1476a0c..5632c54eadf0 100644 --- a/drivers/hid/hid-saitek.c +++ b/drivers/hid/hid-saitek.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * (This module is based on "hid-ortek".) | 7 | * (This module is based on "hid-ortek".) |
8 | * Copyright (c) 2012 Andreas Hübner | 8 | * Copyright (c) 2012 Andreas Hübner |
9 | * | 9 | * |
10 | * R.A.T.7, M.M.O.7 (USB gaming mice): | 10 | * R.A.T.7, R.A.T.9, M.M.O.7 (USB gaming mice): |
11 | * Fixes the mode button which cycles through three constantly pressed | 11 | * Fixes the mode button which cycles through three constantly pressed |
12 | * buttons. All three press events are mapped to one button and the | 12 | * buttons. All three press events are mapped to one button and the |
13 | * missing release event is generated immediately. | 13 | * missing release event is generated immediately. |
@@ -179,6 +179,8 @@ static const struct hid_device_id saitek_devices[] = { | |||
179 | .driver_data = SAITEK_FIX_PS1000 }, | 179 | .driver_data = SAITEK_FIX_PS1000 }, |
180 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7), | 180 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7), |
181 | .driver_data = SAITEK_RELEASE_MODE_RAT7 }, | 181 | .driver_data = SAITEK_RELEASE_MODE_RAT7 }, |
182 | { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9), | ||
183 | .driver_data = SAITEK_RELEASE_MODE_RAT7 }, | ||
182 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7), | 184 | { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7), |
183 | .driver_data = SAITEK_RELEASE_MODE_MMO7 }, | 185 | .driver_data = SAITEK_RELEASE_MODE_MMO7 }, |
184 | { } | 186 | { } |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index bc4269e559f1..31e9d2561106 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -798,6 +798,12 @@ union sixaxis_output_report_01 { | |||
798 | __u8 buf[36]; | 798 | __u8 buf[36]; |
799 | }; | 799 | }; |
800 | 800 | ||
801 | #define DS4_REPORT_0x02_SIZE 37 | ||
802 | #define DS4_REPORT_0x05_SIZE 32 | ||
803 | #define DS4_REPORT_0x11_SIZE 78 | ||
804 | #define DS4_REPORT_0x81_SIZE 7 | ||
805 | #define SIXAXIS_REPORT_0xF2_SIZE 18 | ||
806 | |||
801 | static spinlock_t sony_dev_list_lock; | 807 | static spinlock_t sony_dev_list_lock; |
802 | static LIST_HEAD(sony_device_list); | 808 | static LIST_HEAD(sony_device_list); |
803 | static DEFINE_IDA(sony_device_id_allocator); | 809 | static DEFINE_IDA(sony_device_id_allocator); |
@@ -811,6 +817,7 @@ struct sony_sc { | |||
811 | struct work_struct state_worker; | 817 | struct work_struct state_worker; |
812 | struct power_supply battery; | 818 | struct power_supply battery; |
813 | int device_id; | 819 | int device_id; |
820 | __u8 *output_report_dmabuf; | ||
814 | 821 | ||
815 | #ifdef CONFIG_SONY_FF | 822 | #ifdef CONFIG_SONY_FF |
816 | __u8 left; | 823 | __u8 left; |
@@ -1142,9 +1149,20 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) | |||
1142 | 1149 | ||
1143 | static int sixaxis_set_operational_bt(struct hid_device *hdev) | 1150 | static int sixaxis_set_operational_bt(struct hid_device *hdev) |
1144 | { | 1151 | { |
1145 | unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; | 1152 | static const __u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; |
1146 | return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), | 1153 | __u8 *buf; |
1154 | int ret; | ||
1155 | |||
1156 | buf = kmemdup(report, sizeof(report), GFP_KERNEL); | ||
1157 | if (!buf) | ||
1158 | return -ENOMEM; | ||
1159 | |||
1160 | ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report), | ||
1147 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | 1161 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
1162 | |||
1163 | kfree(buf); | ||
1164 | |||
1165 | return ret; | ||
1148 | } | 1166 | } |
1149 | 1167 | ||
1150 | /* | 1168 | /* |
@@ -1153,10 +1171,19 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev) | |||
1153 | */ | 1171 | */ |
1154 | static int dualshock4_set_operational_bt(struct hid_device *hdev) | 1172 | static int dualshock4_set_operational_bt(struct hid_device *hdev) |
1155 | { | 1173 | { |
1156 | __u8 buf[37] = { 0 }; | 1174 | __u8 *buf; |
1175 | int ret; | ||
1176 | |||
1177 | buf = kmalloc(DS4_REPORT_0x02_SIZE, GFP_KERNEL); | ||
1178 | if (!buf) | ||
1179 | return -ENOMEM; | ||
1157 | 1180 | ||
1158 | return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf), | 1181 | ret = hid_hw_raw_request(hdev, 0x02, buf, DS4_REPORT_0x02_SIZE, |
1159 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); | 1182 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); |
1183 | |||
1184 | kfree(buf); | ||
1185 | |||
1186 | return ret; | ||
1160 | } | 1187 | } |
1161 | 1188 | ||
1162 | static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS]) | 1189 | static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS]) |
@@ -1471,9 +1498,7 @@ error_leds: | |||
1471 | 1498 | ||
1472 | static void sixaxis_state_worker(struct work_struct *work) | 1499 | static void sixaxis_state_worker(struct work_struct *work) |
1473 | { | 1500 | { |
1474 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); | 1501 | static const union sixaxis_output_report_01 default_report = { |
1475 | int n; | ||
1476 | union sixaxis_output_report_01 report = { | ||
1477 | .buf = { | 1502 | .buf = { |
1478 | 0x01, | 1503 | 0x01, |
1479 | 0x00, 0xff, 0x00, 0xff, 0x00, | 1504 | 0x00, 0xff, 0x00, 0xff, 0x00, |
@@ -1485,20 +1510,27 @@ static void sixaxis_state_worker(struct work_struct *work) | |||
1485 | 0x00, 0x00, 0x00, 0x00, 0x00 | 1510 | 0x00, 0x00, 0x00, 0x00, 0x00 |
1486 | } | 1511 | } |
1487 | }; | 1512 | }; |
1513 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); | ||
1514 | struct sixaxis_output_report *report = | ||
1515 | (struct sixaxis_output_report *)sc->output_report_dmabuf; | ||
1516 | int n; | ||
1517 | |||
1518 | /* Initialize the report with default values */ | ||
1519 | memcpy(report, &default_report, sizeof(struct sixaxis_output_report)); | ||
1488 | 1520 | ||
1489 | #ifdef CONFIG_SONY_FF | 1521 | #ifdef CONFIG_SONY_FF |
1490 | report.data.rumble.right_motor_on = sc->right ? 1 : 0; | 1522 | report->rumble.right_motor_on = sc->right ? 1 : 0; |
1491 | report.data.rumble.left_motor_force = sc->left; | 1523 | report->rumble.left_motor_force = sc->left; |
1492 | #endif | 1524 | #endif |
1493 | 1525 | ||
1494 | report.data.leds_bitmap |= sc->led_state[0] << 1; | 1526 | report->leds_bitmap |= sc->led_state[0] << 1; |
1495 | report.data.leds_bitmap |= sc->led_state[1] << 2; | 1527 | report->leds_bitmap |= sc->led_state[1] << 2; |
1496 | report.data.leds_bitmap |= sc->led_state[2] << 3; | 1528 | report->leds_bitmap |= sc->led_state[2] << 3; |
1497 | report.data.leds_bitmap |= sc->led_state[3] << 4; | 1529 | report->leds_bitmap |= sc->led_state[3] << 4; |
1498 | 1530 | ||
1499 | /* Set flag for all leds off, required for 3rd party INTEC controller */ | 1531 | /* Set flag for all leds off, required for 3rd party INTEC controller */ |
1500 | if ((report.data.leds_bitmap & 0x1E) == 0) | 1532 | if ((report->leds_bitmap & 0x1E) == 0) |
1501 | report.data.leds_bitmap |= 0x20; | 1533 | report->leds_bitmap |= 0x20; |
1502 | 1534 | ||
1503 | /* | 1535 | /* |
1504 | * The LEDs in the report are indexed in reverse order to their | 1536 | * The LEDs in the report are indexed in reverse order to their |
@@ -1511,28 +1543,30 @@ static void sixaxis_state_worker(struct work_struct *work) | |||
1511 | */ | 1543 | */ |
1512 | for (n = 0; n < 4; n++) { | 1544 | for (n = 0; n < 4; n++) { |
1513 | if (sc->led_delay_on[n] || sc->led_delay_off[n]) { | 1545 | if (sc->led_delay_on[n] || sc->led_delay_off[n]) { |
1514 | report.data.led[3 - n].duty_off = sc->led_delay_off[n]; | 1546 | report->led[3 - n].duty_off = sc->led_delay_off[n]; |
1515 | report.data.led[3 - n].duty_on = sc->led_delay_on[n]; | 1547 | report->led[3 - n].duty_on = sc->led_delay_on[n]; |
1516 | } | 1548 | } |
1517 | } | 1549 | } |
1518 | 1550 | ||
1519 | hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf, | 1551 | hid_hw_raw_request(sc->hdev, report->report_id, (__u8 *)report, |
1520 | sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); | 1552 | sizeof(struct sixaxis_output_report), |
1553 | HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); | ||
1521 | } | 1554 | } |
1522 | 1555 | ||
1523 | static void dualshock4_state_worker(struct work_struct *work) | 1556 | static void dualshock4_state_worker(struct work_struct *work) |
1524 | { | 1557 | { |
1525 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); | 1558 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); |
1526 | struct hid_device *hdev = sc->hdev; | 1559 | struct hid_device *hdev = sc->hdev; |
1560 | __u8 *buf = sc->output_report_dmabuf; | ||
1527 | int offset; | 1561 | int offset; |
1528 | 1562 | ||
1529 | __u8 buf[78] = { 0 }; | ||
1530 | |||
1531 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { | 1563 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { |
1564 | memset(buf, 0, DS4_REPORT_0x05_SIZE); | ||
1532 | buf[0] = 0x05; | 1565 | buf[0] = 0x05; |
1533 | buf[1] = 0xFF; | 1566 | buf[1] = 0xFF; |
1534 | offset = 4; | 1567 | offset = 4; |
1535 | } else { | 1568 | } else { |
1569 | memset(buf, 0, DS4_REPORT_0x11_SIZE); | ||
1536 | buf[0] = 0x11; | 1570 | buf[0] = 0x11; |
1537 | buf[1] = 0xB0; | 1571 | buf[1] = 0xB0; |
1538 | buf[3] = 0x0F; | 1572 | buf[3] = 0x0F; |
@@ -1560,12 +1594,33 @@ static void dualshock4_state_worker(struct work_struct *work) | |||
1560 | buf[offset++] = sc->led_delay_off[3]; | 1594 | buf[offset++] = sc->led_delay_off[3]; |
1561 | 1595 | ||
1562 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) | 1596 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) |
1563 | hid_hw_output_report(hdev, buf, 32); | 1597 | hid_hw_output_report(hdev, buf, DS4_REPORT_0x05_SIZE); |
1564 | else | 1598 | else |
1565 | hid_hw_raw_request(hdev, 0x11, buf, 78, | 1599 | hid_hw_raw_request(hdev, 0x11, buf, DS4_REPORT_0x11_SIZE, |
1566 | HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); | 1600 | HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
1567 | } | 1601 | } |
1568 | 1602 | ||
1603 | static int sony_allocate_output_report(struct sony_sc *sc) | ||
1604 | { | ||
1605 | if (sc->quirks & SIXAXIS_CONTROLLER) | ||
1606 | sc->output_report_dmabuf = | ||
1607 | kmalloc(sizeof(union sixaxis_output_report_01), | ||
1608 | GFP_KERNEL); | ||
1609 | else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) | ||
1610 | sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x11_SIZE, | ||
1611 | GFP_KERNEL); | ||
1612 | else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) | ||
1613 | sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x05_SIZE, | ||
1614 | GFP_KERNEL); | ||
1615 | else | ||
1616 | return 0; | ||
1617 | |||
1618 | if (!sc->output_report_dmabuf) | ||
1619 | return -ENOMEM; | ||
1620 | |||
1621 | return 0; | ||
1622 | } | ||
1623 | |||
1569 | #ifdef CONFIG_SONY_FF | 1624 | #ifdef CONFIG_SONY_FF |
1570 | static int sony_play_effect(struct input_dev *dev, void *data, | 1625 | static int sony_play_effect(struct input_dev *dev, void *data, |
1571 | struct ff_effect *effect) | 1626 | struct ff_effect *effect) |
@@ -1754,6 +1809,7 @@ static int sony_get_bt_devaddr(struct sony_sc *sc) | |||
1754 | 1809 | ||
1755 | static int sony_check_add(struct sony_sc *sc) | 1810 | static int sony_check_add(struct sony_sc *sc) |
1756 | { | 1811 | { |
1812 | __u8 *buf = NULL; | ||
1757 | int n, ret; | 1813 | int n, ret; |
1758 | 1814 | ||
1759 | if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || | 1815 | if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || |
@@ -1769,36 +1825,44 @@ static int sony_check_add(struct sony_sc *sc) | |||
1769 | return 0; | 1825 | return 0; |
1770 | } | 1826 | } |
1771 | } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { | 1827 | } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { |
1772 | __u8 buf[7]; | 1828 | buf = kmalloc(DS4_REPORT_0x81_SIZE, GFP_KERNEL); |
1829 | if (!buf) | ||
1830 | return -ENOMEM; | ||
1773 | 1831 | ||
1774 | /* | 1832 | /* |
1775 | * The MAC address of a DS4 controller connected via USB can be | 1833 | * The MAC address of a DS4 controller connected via USB can be |
1776 | * retrieved with feature report 0x81. The address begins at | 1834 | * retrieved with feature report 0x81. The address begins at |
1777 | * offset 1. | 1835 | * offset 1. |
1778 | */ | 1836 | */ |
1779 | ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf), | 1837 | ret = hid_hw_raw_request(sc->hdev, 0x81, buf, |
1780 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); | 1838 | DS4_REPORT_0x81_SIZE, HID_FEATURE_REPORT, |
1839 | HID_REQ_GET_REPORT); | ||
1781 | 1840 | ||
1782 | if (ret != 7) { | 1841 | if (ret != DS4_REPORT_0x81_SIZE) { |
1783 | hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n"); | 1842 | hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n"); |
1784 | return ret < 0 ? ret : -EINVAL; | 1843 | ret = ret < 0 ? ret : -EINVAL; |
1844 | goto out_free; | ||
1785 | } | 1845 | } |
1786 | 1846 | ||
1787 | memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); | 1847 | memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); |
1788 | } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { | 1848 | } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { |
1789 | __u8 buf[18]; | 1849 | buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL); |
1850 | if (!buf) | ||
1851 | return -ENOMEM; | ||
1790 | 1852 | ||
1791 | /* | 1853 | /* |
1792 | * The MAC address of a Sixaxis controller connected via USB can | 1854 | * The MAC address of a Sixaxis controller connected via USB can |
1793 | * be retrieved with feature report 0xf2. The address begins at | 1855 | * be retrieved with feature report 0xf2. The address begins at |
1794 | * offset 4. | 1856 | * offset 4. |
1795 | */ | 1857 | */ |
1796 | ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf), | 1858 | ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, |
1797 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); | 1859 | SIXAXIS_REPORT_0xF2_SIZE, HID_FEATURE_REPORT, |
1860 | HID_REQ_GET_REPORT); | ||
1798 | 1861 | ||
1799 | if (ret != 18) { | 1862 | if (ret != SIXAXIS_REPORT_0xF2_SIZE) { |
1800 | hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n"); | 1863 | hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n"); |
1801 | return ret < 0 ? ret : -EINVAL; | 1864 | ret = ret < 0 ? ret : -EINVAL; |
1865 | goto out_free; | ||
1802 | } | 1866 | } |
1803 | 1867 | ||
1804 | /* | 1868 | /* |
@@ -1811,7 +1875,13 @@ static int sony_check_add(struct sony_sc *sc) | |||
1811 | return 0; | 1875 | return 0; |
1812 | } | 1876 | } |
1813 | 1877 | ||
1814 | return sony_check_add_dev_list(sc); | 1878 | ret = sony_check_add_dev_list(sc); |
1879 | |||
1880 | out_free: | ||
1881 | |||
1882 | kfree(buf); | ||
1883 | |||
1884 | return ret; | ||
1815 | } | 1885 | } |
1816 | 1886 | ||
1817 | static int sony_set_device_id(struct sony_sc *sc) | 1887 | static int sony_set_device_id(struct sony_sc *sc) |
@@ -1895,6 +1965,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1895 | return ret; | 1965 | return ret; |
1896 | } | 1966 | } |
1897 | 1967 | ||
1968 | ret = sony_allocate_output_report(sc); | ||
1969 | if (ret < 0) { | ||
1970 | hid_err(hdev, "failed to allocate the output report buffer\n"); | ||
1971 | goto err_stop; | ||
1972 | } | ||
1973 | |||
1898 | ret = sony_set_device_id(sc); | 1974 | ret = sony_set_device_id(sc); |
1899 | if (ret < 0) { | 1975 | if (ret < 0) { |
1900 | hid_err(hdev, "failed to allocate the device id\n"); | 1976 | hid_err(hdev, "failed to allocate the device id\n"); |
@@ -1984,6 +2060,7 @@ err_stop: | |||
1984 | if (sc->quirks & SONY_BATTERY_SUPPORT) | 2060 | if (sc->quirks & SONY_BATTERY_SUPPORT) |
1985 | sony_battery_remove(sc); | 2061 | sony_battery_remove(sc); |
1986 | sony_cancel_work_sync(sc); | 2062 | sony_cancel_work_sync(sc); |
2063 | kfree(sc->output_report_dmabuf); | ||
1987 | sony_remove_dev_list(sc); | 2064 | sony_remove_dev_list(sc); |
1988 | sony_release_device_id(sc); | 2065 | sony_release_device_id(sc); |
1989 | hid_hw_stop(hdev); | 2066 | hid_hw_stop(hdev); |
@@ -2004,6 +2081,8 @@ static void sony_remove(struct hid_device *hdev) | |||
2004 | 2081 | ||
2005 | sony_cancel_work_sync(sc); | 2082 | sony_cancel_work_sync(sc); |
2006 | 2083 | ||
2084 | kfree(sc->output_report_dmabuf); | ||
2085 | |||
2007 | sony_remove_dev_list(sc); | 2086 | sony_remove_dev_list(sc); |
2008 | 2087 | ||
2009 | sony_release_device_id(sc); | 2088 | sony_release_device_id(sc); |
@@ -2034,6 +2113,9 @@ static const struct hid_device_id sony_devices[] = { | |||
2034 | /* Logitech Harmony Adapter for PS3 */ | 2113 | /* Logitech Harmony Adapter for PS3 */ |
2035 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), | 2114 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), |
2036 | .driver_data = PS3REMOTE }, | 2115 | .driver_data = PS3REMOTE }, |
2116 | /* SMK-Link PS3 BD Remote Control */ | ||
2117 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE), | ||
2118 | .driver_data = PS3REMOTE }, | ||
2037 | /* Sony Dualshock 4 controllers for PS4 */ | 2119 | /* Sony Dualshock 4 controllers for PS4 */ |
2038 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), | 2120 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), |
2039 | .driver_data = DUALSHOCK4_CONTROLLER_USB }, | 2121 | .driver_data = DUALSHOCK4_CONTROLLER_USB }, |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index f09e70cafaf1..d32037cbf9db 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -137,6 +137,7 @@ struct i2c_hid { | |||
137 | * descriptor. */ | 137 | * descriptor. */ |
138 | unsigned int bufsize; /* i2c buffer size */ | 138 | unsigned int bufsize; /* i2c buffer size */ |
139 | char *inbuf; /* Input buffer */ | 139 | char *inbuf; /* Input buffer */ |
140 | char *rawbuf; /* Raw Input buffer */ | ||
140 | char *cmdbuf; /* Command buffer */ | 141 | char *cmdbuf; /* Command buffer */ |
141 | char *argsbuf; /* Command arguments buffer */ | 142 | char *argsbuf; /* Command arguments buffer */ |
142 | 143 | ||
@@ -369,7 +370,7 @@ static int i2c_hid_hwreset(struct i2c_client *client) | |||
369 | static void i2c_hid_get_input(struct i2c_hid *ihid) | 370 | static void i2c_hid_get_input(struct i2c_hid *ihid) |
370 | { | 371 | { |
371 | int ret, ret_size; | 372 | int ret, ret_size; |
372 | int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); | 373 | int size = ihid->bufsize; |
373 | 374 | ||
374 | ret = i2c_master_recv(ihid->client, ihid->inbuf, size); | 375 | ret = i2c_master_recv(ihid->client, ihid->inbuf, size); |
375 | if (ret != size) { | 376 | if (ret != size) { |
@@ -437,7 +438,7 @@ static void i2c_hid_init_report(struct hid_report *report, u8 *buffer, | |||
437 | report->id, buffer, size)) | 438 | report->id, buffer, size)) |
438 | return; | 439 | return; |
439 | 440 | ||
440 | i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, ihid->inbuf); | 441 | i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, buffer); |
441 | 442 | ||
442 | ret_size = buffer[0] | (buffer[1] << 8); | 443 | ret_size = buffer[0] | (buffer[1] << 8); |
443 | 444 | ||
@@ -504,9 +505,11 @@ static void i2c_hid_find_max_report(struct hid_device *hid, unsigned int type, | |||
504 | static void i2c_hid_free_buffers(struct i2c_hid *ihid) | 505 | static void i2c_hid_free_buffers(struct i2c_hid *ihid) |
505 | { | 506 | { |
506 | kfree(ihid->inbuf); | 507 | kfree(ihid->inbuf); |
508 | kfree(ihid->rawbuf); | ||
507 | kfree(ihid->argsbuf); | 509 | kfree(ihid->argsbuf); |
508 | kfree(ihid->cmdbuf); | 510 | kfree(ihid->cmdbuf); |
509 | ihid->inbuf = NULL; | 511 | ihid->inbuf = NULL; |
512 | ihid->rawbuf = NULL; | ||
510 | ihid->cmdbuf = NULL; | 513 | ihid->cmdbuf = NULL; |
511 | ihid->argsbuf = NULL; | 514 | ihid->argsbuf = NULL; |
512 | ihid->bufsize = 0; | 515 | ihid->bufsize = 0; |
@@ -522,10 +525,11 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) | |||
522 | report_size; /* report */ | 525 | report_size; /* report */ |
523 | 526 | ||
524 | ihid->inbuf = kzalloc(report_size, GFP_KERNEL); | 527 | ihid->inbuf = kzalloc(report_size, GFP_KERNEL); |
528 | ihid->rawbuf = kzalloc(report_size, GFP_KERNEL); | ||
525 | ihid->argsbuf = kzalloc(args_len, GFP_KERNEL); | 529 | ihid->argsbuf = kzalloc(args_len, GFP_KERNEL); |
526 | ihid->cmdbuf = kzalloc(sizeof(union command) + args_len, GFP_KERNEL); | 530 | ihid->cmdbuf = kzalloc(sizeof(union command) + args_len, GFP_KERNEL); |
527 | 531 | ||
528 | if (!ihid->inbuf || !ihid->argsbuf || !ihid->cmdbuf) { | 532 | if (!ihid->inbuf || !ihid->rawbuf || !ihid->argsbuf || !ihid->cmdbuf) { |
529 | i2c_hid_free_buffers(ihid); | 533 | i2c_hid_free_buffers(ihid); |
530 | return -ENOMEM; | 534 | return -ENOMEM; |
531 | } | 535 | } |
@@ -552,12 +556,12 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, | |||
552 | 556 | ||
553 | ret = i2c_hid_get_report(client, | 557 | ret = i2c_hid_get_report(client, |
554 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x01, | 558 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x01, |
555 | report_number, ihid->inbuf, ask_count); | 559 | report_number, ihid->rawbuf, ask_count); |
556 | 560 | ||
557 | if (ret < 0) | 561 | if (ret < 0) |
558 | return ret; | 562 | return ret; |
559 | 563 | ||
560 | ret_count = ihid->inbuf[0] | (ihid->inbuf[1] << 8); | 564 | ret_count = ihid->rawbuf[0] | (ihid->rawbuf[1] << 8); |
561 | 565 | ||
562 | if (ret_count <= 2) | 566 | if (ret_count <= 2) |
563 | return 0; | 567 | return 0; |
@@ -566,7 +570,7 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, | |||
566 | 570 | ||
567 | /* The query buffer contains the size, dropping it in the reply */ | 571 | /* The query buffer contains the size, dropping it in the reply */ |
568 | count = min(count, ret_count - 2); | 572 | count = min(count, ret_count - 2); |
569 | memcpy(buf, ihid->inbuf + 2, count); | 573 | memcpy(buf, ihid->rawbuf + 2, count); |
570 | 574 | ||
571 | return count; | 575 | return count; |
572 | } | 576 | } |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index ca6849a0121e..bfbe1bedda7f 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -278,18 +278,20 @@ static void hid_irq_in(struct urb *urb) | |||
278 | usbhid->retry_delay = 0; | 278 | usbhid->retry_delay = 0; |
279 | if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open) | 279 | if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open) |
280 | break; | 280 | break; |
281 | hid_input_report(urb->context, HID_INPUT_REPORT, | 281 | if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { |
282 | urb->transfer_buffer, | 282 | hid_input_report(urb->context, HID_INPUT_REPORT, |
283 | urb->actual_length, 1); | 283 | urb->transfer_buffer, |
284 | /* | 284 | urb->actual_length, 1); |
285 | * autosuspend refused while keys are pressed | 285 | /* |
286 | * because most keyboards don't wake up when | 286 | * autosuspend refused while keys are pressed |
287 | * a key is released | 287 | * because most keyboards don't wake up when |
288 | */ | 288 | * a key is released |
289 | if (hid_check_keys_pressed(hid)) | 289 | */ |
290 | set_bit(HID_KEYS_PRESSED, &usbhid->iofl); | 290 | if (hid_check_keys_pressed(hid)) |
291 | else | 291 | set_bit(HID_KEYS_PRESSED, &usbhid->iofl); |
292 | clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); | 292 | else |
293 | clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); | ||
294 | } | ||
293 | break; | 295 | break; |
294 | case -EPIPE: /* stall */ | 296 | case -EPIPE: /* stall */ |
295 | usbhid_mark_busy(usbhid); | 297 | usbhid_mark_busy(usbhid); |
@@ -338,8 +340,7 @@ static int hid_submit_out(struct hid_device *hid) | |||
338 | report = usbhid->out[usbhid->outtail].report; | 340 | report = usbhid->out[usbhid->outtail].report; |
339 | raw_report = usbhid->out[usbhid->outtail].raw_report; | 341 | raw_report = usbhid->out[usbhid->outtail].raw_report; |
340 | 342 | ||
341 | usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + | 343 | usbhid->urbout->transfer_buffer_length = hid_report_len(report); |
342 | 1 + (report->id > 0); | ||
343 | usbhid->urbout->dev = hid_to_usb_dev(hid); | 344 | usbhid->urbout->dev = hid_to_usb_dev(hid); |
344 | if (raw_report) { | 345 | if (raw_report) { |
345 | memcpy(usbhid->outbuf, raw_report, | 346 | memcpy(usbhid->outbuf, raw_report, |
@@ -688,6 +689,7 @@ int usbhid_open(struct hid_device *hid) | |||
688 | goto done; | 689 | goto done; |
689 | } | 690 | } |
690 | usbhid->intf->needs_remote_wakeup = 1; | 691 | usbhid->intf->needs_remote_wakeup = 1; |
692 | set_bit(HID_RESUME_RUNNING, &usbhid->iofl); | ||
691 | res = hid_start_in(hid); | 693 | res = hid_start_in(hid); |
692 | if (res) { | 694 | if (res) { |
693 | if (res != -ENOSPC) { | 695 | if (res != -ENOSPC) { |
@@ -701,6 +703,15 @@ int usbhid_open(struct hid_device *hid) | |||
701 | } | 703 | } |
702 | } | 704 | } |
703 | usb_autopm_put_interface(usbhid->intf); | 705 | usb_autopm_put_interface(usbhid->intf); |
706 | |||
707 | /* | ||
708 | * In case events are generated while nobody was listening, | ||
709 | * some are released when the device is re-opened. | ||
710 | * Wait 50 msec for the queue to empty before allowing events | ||
711 | * to go through hid. | ||
712 | */ | ||
713 | msleep(50); | ||
714 | clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); | ||
704 | } | 715 | } |
705 | done: | 716 | done: |
706 | mutex_unlock(&hid_open_mut); | 717 | mutex_unlock(&hid_open_mut); |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 552671ee7c5d..dc89be90b35e 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -73,11 +73,13 @@ static const struct hid_blacklist { | |||
73 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL }, | 73 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL }, |
74 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL }, | 74 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL }, |
75 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL }, | 75 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL }, |
76 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c, HID_QUIRK_ALWAYS_POLL }, | ||
76 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL }, | 77 | { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL }, |
77 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 78 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
78 | { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, | 79 | { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, |
79 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, | 80 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
80 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, | 81 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, |
82 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, | ||
81 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, | 83 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, |
82 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, | 84 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, |
83 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, | 85 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index f633c24ce28b..807922b49aa4 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -52,6 +52,7 @@ struct usb_interface *usbhid_find_interface(int minor); | |||
52 | #define HID_STARTED 8 | 52 | #define HID_STARTED 8 |
53 | #define HID_KEYS_PRESSED 10 | 53 | #define HID_KEYS_PRESSED 10 |
54 | #define HID_NO_BANDWIDTH 11 | 54 | #define HID_NO_BANDWIDTH 11 |
55 | #define HID_RESUME_RUNNING 12 | ||
55 | 56 | ||
56 | /* | 57 | /* |
57 | * USB-specific HID struct, to be pointed to | 58 | * USB-specific HID struct, to be pointed to |
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 0cc53440543a..7db432809e9e 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h | |||
@@ -140,7 +140,7 @@ extern const struct hid_device_id wacom_ids[]; | |||
140 | 140 | ||
141 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | 141 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); |
142 | void wacom_setup_device_quirks(struct wacom_features *features); | 142 | void wacom_setup_device_quirks(struct wacom_features *features); |
143 | int wacom_setup_input_capabilities(struct input_dev *input_dev, | 143 | int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, |
144 | struct wacom_wac *wacom_wac); | 144 | struct wacom_wac *wacom_wac); |
145 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | 145 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, |
146 | struct wacom_wac *wacom_wac); | 146 | struct wacom_wac *wacom_wac); |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 8593047bb726..654202941d30 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include "wacom_wac.h" | 14 | #include "wacom_wac.h" |
15 | #include "wacom.h" | 15 | #include "wacom.h" |
16 | #include <linux/input/mt.h> | ||
16 | 17 | ||
17 | #define WAC_MSG_RETRIES 5 | 18 | #define WAC_MSG_RETRIES 5 |
18 | 19 | ||
@@ -70,22 +71,15 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
70 | static int wacom_open(struct input_dev *dev) | 71 | static int wacom_open(struct input_dev *dev) |
71 | { | 72 | { |
72 | struct wacom *wacom = input_get_drvdata(dev); | 73 | struct wacom *wacom = input_get_drvdata(dev); |
73 | int retval; | ||
74 | |||
75 | mutex_lock(&wacom->lock); | ||
76 | retval = hid_hw_open(wacom->hdev); | ||
77 | mutex_unlock(&wacom->lock); | ||
78 | 74 | ||
79 | return retval; | 75 | return hid_hw_open(wacom->hdev); |
80 | } | 76 | } |
81 | 77 | ||
82 | static void wacom_close(struct input_dev *dev) | 78 | static void wacom_close(struct input_dev *dev) |
83 | { | 79 | { |
84 | struct wacom *wacom = input_get_drvdata(dev); | 80 | struct wacom *wacom = input_get_drvdata(dev); |
85 | 81 | ||
86 | mutex_lock(&wacom->lock); | ||
87 | hid_hw_close(wacom->hdev); | 82 | hid_hw_close(wacom->hdev); |
88 | mutex_unlock(&wacom->lock); | ||
89 | } | 83 | } |
90 | 84 | ||
91 | /* | 85 | /* |
@@ -192,9 +186,15 @@ static void wacom_usage_mapping(struct hid_device *hdev, | |||
192 | if (!pen && !finger) | 186 | if (!pen && !finger) |
193 | return; | 187 | return; |
194 | 188 | ||
195 | if (finger && !features->touch_max) | 189 | /* |
196 | /* touch device at least supports one touch point */ | 190 | * Bamboo models do not support HID_DG_CONTACTMAX. |
197 | features->touch_max = 1; | 191 | * And, Bamboo Pen only descriptor contains touch. |
192 | */ | ||
193 | if (features->type != BAMBOO_PT) { | ||
194 | /* ISDv4 touch devices at least supports one touch point */ | ||
195 | if (finger && !features->touch_max) | ||
196 | features->touch_max = 1; | ||
197 | } | ||
198 | 198 | ||
199 | switch (usage->hid) { | 199 | switch (usage->hid) { |
200 | case HID_GD_X: | 200 | case HID_GD_X: |
@@ -230,6 +230,21 @@ static void wacom_usage_mapping(struct hid_device *hdev, | |||
230 | wacom_wac_usage_mapping(hdev, field, usage); | 230 | wacom_wac_usage_mapping(hdev, field, usage); |
231 | } | 231 | } |
232 | 232 | ||
233 | static void wacom_post_parse_hid(struct hid_device *hdev, | ||
234 | struct wacom_features *features) | ||
235 | { | ||
236 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
237 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
238 | |||
239 | if (features->type == HID_GENERIC) { | ||
240 | /* Any last-minute generic device setup */ | ||
241 | if (features->touch_max > 1) { | ||
242 | input_mt_init_slots(wacom_wac->input, wacom_wac->features.touch_max, | ||
243 | INPUT_MT_DIRECT); | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | |||
233 | static void wacom_parse_hid(struct hid_device *hdev, | 248 | static void wacom_parse_hid(struct hid_device *hdev, |
234 | struct wacom_features *features) | 249 | struct wacom_features *features) |
235 | { | 250 | { |
@@ -264,6 +279,8 @@ static void wacom_parse_hid(struct hid_device *hdev, | |||
264 | wacom_usage_mapping(hdev, hreport->field[i], | 279 | wacom_usage_mapping(hdev, hreport->field[i], |
265 | hreport->field[i]->usage + j); | 280 | hreport->field[i]->usage + j); |
266 | } | 281 | } |
282 | |||
283 | wacom_post_parse_hid(hdev, features); | ||
267 | } | 284 | } |
268 | 285 | ||
269 | static int wacom_hid_set_device_mode(struct hid_device *hdev) | 286 | static int wacom_hid_set_device_mode(struct hid_device *hdev) |
@@ -1129,7 +1146,7 @@ static void wacom_clean_inputs(struct wacom *wacom) | |||
1129 | input_free_device(wacom->wacom_wac.input); | 1146 | input_free_device(wacom->wacom_wac.input); |
1130 | } | 1147 | } |
1131 | if (wacom->wacom_wac.pad_input) { | 1148 | if (wacom->wacom_wac.pad_input) { |
1132 | if (wacom->wacom_wac.input_registered) | 1149 | if (wacom->wacom_wac.pad_registered) |
1133 | input_unregister_device(wacom->wacom_wac.pad_input); | 1150 | input_unregister_device(wacom->wacom_wac.pad_input); |
1134 | else | 1151 | else |
1135 | input_free_device(wacom->wacom_wac.pad_input); | 1152 | input_free_device(wacom->wacom_wac.pad_input); |
@@ -1151,13 +1168,13 @@ static int wacom_register_inputs(struct wacom *wacom) | |||
1151 | if (!input_dev || !pad_input_dev) | 1168 | if (!input_dev || !pad_input_dev) |
1152 | return -EINVAL; | 1169 | return -EINVAL; |
1153 | 1170 | ||
1154 | error = wacom_setup_input_capabilities(input_dev, wacom_wac); | 1171 | error = wacom_setup_pentouch_input_capabilities(input_dev, wacom_wac); |
1155 | if (error) | 1172 | if (!error) { |
1156 | return error; | 1173 | error = input_register_device(input_dev); |
1157 | 1174 | if (error) | |
1158 | error = input_register_device(input_dev); | 1175 | return error; |
1159 | if (error) | 1176 | wacom_wac->input_registered = true; |
1160 | return error; | 1177 | } |
1161 | 1178 | ||
1162 | error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); | 1179 | error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); |
1163 | if (error) { | 1180 | if (error) { |
@@ -1169,22 +1186,23 @@ static int wacom_register_inputs(struct wacom *wacom) | |||
1169 | error = input_register_device(pad_input_dev); | 1186 | error = input_register_device(pad_input_dev); |
1170 | if (error) | 1187 | if (error) |
1171 | goto fail_register_pad_input; | 1188 | goto fail_register_pad_input; |
1189 | wacom_wac->pad_registered = true; | ||
1172 | 1190 | ||
1173 | error = wacom_initialize_leds(wacom); | 1191 | error = wacom_initialize_leds(wacom); |
1174 | if (error) | 1192 | if (error) |
1175 | goto fail_leds; | 1193 | goto fail_leds; |
1176 | } | 1194 | } |
1177 | 1195 | ||
1178 | wacom_wac->input_registered = true; | ||
1179 | |||
1180 | return 0; | 1196 | return 0; |
1181 | 1197 | ||
1182 | fail_leds: | 1198 | fail_leds: |
1183 | input_unregister_device(pad_input_dev); | 1199 | input_unregister_device(pad_input_dev); |
1184 | pad_input_dev = NULL; | 1200 | pad_input_dev = NULL; |
1201 | wacom_wac->pad_registered = false; | ||
1185 | fail_register_pad_input: | 1202 | fail_register_pad_input: |
1186 | input_unregister_device(input_dev); | 1203 | input_unregister_device(input_dev); |
1187 | wacom_wac->input = NULL; | 1204 | wacom_wac->input = NULL; |
1205 | wacom_wac->input_registered = false; | ||
1188 | return error; | 1206 | return error; |
1189 | } | 1207 | } |
1190 | 1208 | ||
@@ -1321,12 +1339,6 @@ static void wacom_calculate_res(struct wacom_features *features) | |||
1321 | features->unitExpo); | 1339 | features->unitExpo); |
1322 | } | 1340 | } |
1323 | 1341 | ||
1324 | static int wacom_hid_report_len(struct hid_report *report) | ||
1325 | { | ||
1326 | /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ | ||
1327 | return ((report->size - 1) >> 3) + 1 + (report->id > 0); | ||
1328 | } | ||
1329 | |||
1330 | static size_t wacom_compute_pktlen(struct hid_device *hdev) | 1342 | static size_t wacom_compute_pktlen(struct hid_device *hdev) |
1331 | { | 1343 | { |
1332 | struct hid_report_enum *report_enum; | 1344 | struct hid_report_enum *report_enum; |
@@ -1336,7 +1348,7 @@ static size_t wacom_compute_pktlen(struct hid_device *hdev) | |||
1336 | report_enum = hdev->report_enum + HID_INPUT_REPORT; | 1348 | report_enum = hdev->report_enum + HID_INPUT_REPORT; |
1337 | 1349 | ||
1338 | list_for_each_entry(report, &report_enum->report_list, list) { | 1350 | list_for_each_entry(report, &report_enum->report_list, list) { |
1339 | size_t report_size = wacom_hid_report_len(report); | 1351 | size_t report_size = hid_report_len(report); |
1340 | if (report_size > size) | 1352 | if (report_size > size) |
1341 | size = report_size; | 1353 | size = report_size; |
1342 | } | 1354 | } |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 586b2405b0d4..ac7447c7b82e 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -25,6 +25,10 @@ | |||
25 | #define WACOM_INTUOS_RES 100 | 25 | #define WACOM_INTUOS_RES 100 |
26 | #define WACOM_INTUOS3_RES 200 | 26 | #define WACOM_INTUOS3_RES 200 |
27 | 27 | ||
28 | /* Newer Cintiq and DTU have an offset between tablet and screen areas */ | ||
29 | #define WACOM_DTU_OFFSET 200 | ||
30 | #define WACOM_CINTIQ_OFFSET 400 | ||
31 | |||
28 | /* | 32 | /* |
29 | * Scale factor relating reported contact size to logical contact area. | 33 | * Scale factor relating reported contact size to logical contact area. |
30 | * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo | 34 | * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo |
@@ -600,8 +604,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom) | |||
600 | } | 604 | } |
601 | input_report_abs(input, ABS_PRESSURE, t); | 605 | input_report_abs(input, ABS_PRESSURE, t); |
602 | input_report_abs(input, ABS_TILT_X, | 606 | input_report_abs(input, ABS_TILT_X, |
603 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 607 | (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); |
604 | input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); | 608 | input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); |
605 | input_report_key(input, BTN_STYLUS, data[1] & 2); | 609 | input_report_key(input, BTN_STYLUS, data[1] & 2); |
606 | input_report_key(input, BTN_STYLUS2, data[1] & 4); | 610 | input_report_key(input, BTN_STYLUS2, data[1] & 4); |
607 | input_report_key(input, BTN_TOUCH, t > 10); | 611 | input_report_key(input, BTN_TOUCH, t > 10); |
@@ -612,8 +616,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom) | |||
612 | input_report_abs(input, ABS_WHEEL, | 616 | input_report_abs(input, ABS_WHEEL, |
613 | (data[6] << 2) | ((data[7] >> 6) & 3)); | 617 | (data[6] << 2) | ((data[7] >> 6) & 3)); |
614 | input_report_abs(input, ABS_TILT_X, | 618 | input_report_abs(input, ABS_TILT_X, |
615 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 619 | (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); |
616 | input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); | 620 | input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); |
617 | } | 621 | } |
618 | } | 622 | } |
619 | 623 | ||
@@ -915,8 +919,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
915 | input_report_key(input, BTN_EXTRA, data[6] & 0x10); | 919 | input_report_key(input, BTN_EXTRA, data[6] & 0x10); |
916 | 920 | ||
917 | input_report_abs(input, ABS_TILT_X, | 921 | input_report_abs(input, ABS_TILT_X, |
918 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 922 | (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); |
919 | input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); | 923 | input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); |
920 | } else { | 924 | } else { |
921 | /* 2D mouse packet */ | 925 | /* 2D mouse packet */ |
922 | input_report_key(input, BTN_LEFT, data[8] & 0x04); | 926 | input_report_key(input, BTN_LEFT, data[8] & 0x04); |
@@ -1377,11 +1381,12 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, | |||
1377 | { | 1381 | { |
1378 | struct wacom *wacom = hid_get_drvdata(hdev); | 1382 | struct wacom *wacom = hid_get_drvdata(hdev); |
1379 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | 1383 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
1380 | struct input_dev *input = wacom_wac->input; | 1384 | struct wacom_features *features = &wacom_wac->features; |
1381 | unsigned touch_max = wacom_wac->features.touch_max; | 1385 | unsigned touch_max = wacom_wac->features.touch_max; |
1382 | 1386 | ||
1383 | switch (usage->hid) { | 1387 | switch (usage->hid) { |
1384 | case HID_GD_X: | 1388 | case HID_GD_X: |
1389 | features->last_slot_field = usage->hid; | ||
1385 | if (touch_max == 1) | 1390 | if (touch_max == 1) |
1386 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); | 1391 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); |
1387 | else | 1392 | else |
@@ -1389,6 +1394,7 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, | |||
1389 | ABS_MT_POSITION_X, 4); | 1394 | ABS_MT_POSITION_X, 4); |
1390 | break; | 1395 | break; |
1391 | case HID_GD_Y: | 1396 | case HID_GD_Y: |
1397 | features->last_slot_field = usage->hid; | ||
1392 | if (touch_max == 1) | 1398 | if (touch_max == 1) |
1393 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); | 1399 | wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); |
1394 | else | 1400 | else |
@@ -1396,19 +1402,48 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, | |||
1396 | ABS_MT_POSITION_Y, 4); | 1402 | ABS_MT_POSITION_Y, 4); |
1397 | break; | 1403 | break; |
1398 | case HID_DG_CONTACTID: | 1404 | case HID_DG_CONTACTID: |
1399 | input_mt_init_slots(input, wacom_wac->features.touch_max, | 1405 | features->last_slot_field = usage->hid; |
1400 | INPUT_MT_DIRECT); | ||
1401 | break; | 1406 | break; |
1402 | case HID_DG_INRANGE: | 1407 | case HID_DG_INRANGE: |
1408 | features->last_slot_field = usage->hid; | ||
1403 | break; | 1409 | break; |
1404 | case HID_DG_INVERT: | 1410 | case HID_DG_INVERT: |
1411 | features->last_slot_field = usage->hid; | ||
1405 | break; | 1412 | break; |
1406 | case HID_DG_TIPSWITCH: | 1413 | case HID_DG_TIPSWITCH: |
1414 | features->last_slot_field = usage->hid; | ||
1407 | wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); | 1415 | wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); |
1408 | break; | 1416 | break; |
1409 | } | 1417 | } |
1410 | } | 1418 | } |
1411 | 1419 | ||
1420 | static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, | ||
1421 | struct input_dev *input) | ||
1422 | { | ||
1423 | struct hid_data *hid_data = &wacom_wac->hid_data; | ||
1424 | bool mt = wacom_wac->features.touch_max > 1; | ||
1425 | bool prox = hid_data->tipswitch && | ||
1426 | !wacom_wac->shared->stylus_in_proximity; | ||
1427 | |||
1428 | if (mt) { | ||
1429 | int slot; | ||
1430 | |||
1431 | slot = input_mt_get_slot_by_key(input, hid_data->id); | ||
1432 | input_mt_slot(input, slot); | ||
1433 | input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); | ||
1434 | } | ||
1435 | else { | ||
1436 | input_report_key(input, BTN_TOUCH, prox); | ||
1437 | } | ||
1438 | |||
1439 | if (prox) { | ||
1440 | input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X, | ||
1441 | hid_data->x); | ||
1442 | input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y, | ||
1443 | hid_data->y); | ||
1444 | } | ||
1445 | } | ||
1446 | |||
1412 | static int wacom_wac_finger_event(struct hid_device *hdev, | 1447 | static int wacom_wac_finger_event(struct hid_device *hdev, |
1413 | struct hid_field *field, struct hid_usage *usage, __s32 value) | 1448 | struct hid_field *field, struct hid_usage *usage, __s32 value) |
1414 | { | 1449 | { |
@@ -1431,36 +1466,35 @@ static int wacom_wac_finger_event(struct hid_device *hdev, | |||
1431 | } | 1466 | } |
1432 | 1467 | ||
1433 | 1468 | ||
1469 | if (usage->usage_index + 1 == field->report_count) { | ||
1470 | if (usage->hid == wacom_wac->features.last_slot_field) | ||
1471 | wacom_wac_finger_slot(wacom_wac, wacom_wac->input); | ||
1472 | } | ||
1473 | |||
1434 | return 0; | 1474 | return 0; |
1435 | } | 1475 | } |
1436 | 1476 | ||
1437 | static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac, | 1477 | static int wacom_wac_finger_count_touches(struct hid_device *hdev) |
1438 | struct input_dev *input, bool touch) | ||
1439 | { | 1478 | { |
1440 | int slot; | 1479 | struct wacom *wacom = hid_get_drvdata(hdev); |
1441 | struct hid_data *hid_data = &wacom_wac->hid_data; | 1480 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
1481 | struct input_dev *input = wacom_wac->input; | ||
1482 | unsigned touch_max = wacom_wac->features.touch_max; | ||
1483 | int count = 0; | ||
1484 | int i; | ||
1442 | 1485 | ||
1443 | slot = input_mt_get_slot_by_key(input, hid_data->id); | 1486 | if (touch_max == 1) |
1487 | return wacom_wac->hid_data.tipswitch && | ||
1488 | !wacom_wac->shared->stylus_in_proximity; | ||
1444 | 1489 | ||
1445 | input_mt_slot(input, slot); | 1490 | for (i = 0; i < input->mt->num_slots; i++) { |
1446 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | 1491 | struct input_mt_slot *ps = &input->mt->slots[i]; |
1447 | if (touch) { | 1492 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); |
1448 | input_report_abs(input, ABS_MT_POSITION_X, hid_data->x); | 1493 | if (id >= 0) |
1449 | input_report_abs(input, ABS_MT_POSITION_Y, hid_data->y); | 1494 | count++; |
1450 | } | 1495 | } |
1451 | input_mt_sync_frame(input); | ||
1452 | } | ||
1453 | 1496 | ||
1454 | static void wacom_wac_finger_single_touch_report(struct wacom_wac *wacom_wac, | 1497 | return count; |
1455 | struct input_dev *input, bool touch) | ||
1456 | { | ||
1457 | struct hid_data *hid_data = &wacom_wac->hid_data; | ||
1458 | |||
1459 | if (touch) { | ||
1460 | input_report_abs(input, ABS_X, hid_data->x); | ||
1461 | input_report_abs(input, ABS_Y, hid_data->y); | ||
1462 | } | ||
1463 | input_report_key(input, BTN_TOUCH, touch); | ||
1464 | } | 1498 | } |
1465 | 1499 | ||
1466 | static void wacom_wac_finger_report(struct hid_device *hdev, | 1500 | static void wacom_wac_finger_report(struct hid_device *hdev, |
@@ -1469,24 +1503,23 @@ static void wacom_wac_finger_report(struct hid_device *hdev, | |||
1469 | struct wacom *wacom = hid_get_drvdata(hdev); | 1503 | struct wacom *wacom = hid_get_drvdata(hdev); |
1470 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | 1504 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
1471 | struct input_dev *input = wacom_wac->input; | 1505 | struct input_dev *input = wacom_wac->input; |
1472 | bool touch = wacom_wac->hid_data.tipswitch && | ||
1473 | !wacom_wac->shared->stylus_in_proximity; | ||
1474 | unsigned touch_max = wacom_wac->features.touch_max; | 1506 | unsigned touch_max = wacom_wac->features.touch_max; |
1475 | 1507 | ||
1476 | if (touch_max > 1) | 1508 | if (touch_max > 1) |
1477 | wacom_wac_finger_mt_report(wacom_wac, input, touch); | 1509 | input_mt_sync_frame(input); |
1478 | else | 1510 | |
1479 | wacom_wac_finger_single_touch_report(wacom_wac, input, touch); | ||
1480 | input_sync(input); | 1511 | input_sync(input); |
1481 | 1512 | ||
1482 | /* keep touch state for pen event */ | 1513 | /* keep touch state for pen event */ |
1483 | wacom_wac->shared->touch_down = touch; | 1514 | wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev); |
1484 | } | 1515 | } |
1485 | 1516 | ||
1486 | #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ | 1517 | #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ |
1487 | ((f)->physical == HID_DG_STYLUS)) | 1518 | ((f)->physical == HID_DG_STYLUS) || \ |
1519 | ((f)->application == HID_DG_PEN)) | ||
1488 | #define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \ | 1520 | #define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \ |
1489 | ((f)->physical == HID_DG_FINGER)) | 1521 | ((f)->physical == HID_DG_FINGER) || \ |
1522 | ((f)->application == HID_DG_TOUCHSCREEN)) | ||
1490 | 1523 | ||
1491 | void wacom_wac_usage_mapping(struct hid_device *hdev, | 1524 | void wacom_wac_usage_mapping(struct hid_device *hdev, |
1492 | struct hid_field *field, struct hid_usage *usage) | 1525 | struct hid_field *field, struct hid_usage *usage) |
@@ -1681,7 +1714,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) | |||
1681 | return 0; | 1714 | return 0; |
1682 | 1715 | ||
1683 | if (data[0] == WACOM_REPORT_USB) { | 1716 | if (data[0] == WACOM_REPORT_USB) { |
1684 | if (features->type == INTUOSHT && features->touch_max) { | 1717 | if (features->type == INTUOSHT && |
1718 | wacom->shared->touch_input && | ||
1719 | features->touch_max) { | ||
1685 | input_report_switch(wacom->shared->touch_input, | 1720 | input_report_switch(wacom->shared->touch_input, |
1686 | SW_MUTE_DEVICE, data[8] & 0x40); | 1721 | SW_MUTE_DEVICE, data[8] & 0x40); |
1687 | input_sync(wacom->shared->touch_input); | 1722 | input_sync(wacom->shared->touch_input); |
@@ -1774,7 +1809,8 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) | |||
1774 | int pid, battery, ps_connected; | 1809 | int pid, battery, ps_connected; |
1775 | 1810 | ||
1776 | if ((wacom->shared->type == INTUOSHT) && | 1811 | if ((wacom->shared->type == INTUOSHT) && |
1777 | wacom->shared->touch_max) { | 1812 | wacom->shared->touch_input && |
1813 | wacom->shared->touch_max) { | ||
1778 | input_report_switch(wacom->shared->touch_input, | 1814 | input_report_switch(wacom->shared->touch_input, |
1779 | SW_MUTE_DEVICE, data[5] & 0x40); | 1815 | SW_MUTE_DEVICE, data[5] & 0x40); |
1780 | input_sync(wacom->shared->touch_input); | 1816 | input_sync(wacom->shared->touch_input); |
@@ -1838,6 +1874,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1838 | break; | 1874 | break; |
1839 | 1875 | ||
1840 | case DTUS: | 1876 | case DTUS: |
1877 | case DTUSX: | ||
1841 | sync = wacom_dtus_irq(wacom_wac); | 1878 | sync = wacom_dtus_irq(wacom_wac); |
1842 | break; | 1879 | break; |
1843 | 1880 | ||
@@ -1926,8 +1963,10 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) | |||
1926 | input_set_abs_params(input_dev, ABS_DISTANCE, | 1963 | input_set_abs_params(input_dev, ABS_DISTANCE, |
1927 | 0, wacom_wac->features.distance_max, 0, 0); | 1964 | 0, wacom_wac->features.distance_max, 0, 0); |
1928 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); | 1965 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); |
1929 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); | 1966 | input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); |
1930 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); | 1967 | input_abs_set_res(input_dev, ABS_TILT_X, 57); |
1968 | input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, 0, 0); | ||
1969 | input_abs_set_res(input_dev, ABS_TILT_Y, 57); | ||
1931 | } | 1970 | } |
1932 | 1971 | ||
1933 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | 1972 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) |
@@ -1947,6 +1986,7 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | |||
1947 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); | 1986 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); |
1948 | 1987 | ||
1949 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); | 1988 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); |
1989 | input_abs_set_res(input_dev, ABS_RZ, 287); | ||
1950 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); | 1990 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); |
1951 | } | 1991 | } |
1952 | 1992 | ||
@@ -2029,7 +2069,7 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, | |||
2029 | } | 2069 | } |
2030 | } | 2070 | } |
2031 | 2071 | ||
2032 | int wacom_setup_input_capabilities(struct input_dev *input_dev, | 2072 | int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, |
2033 | struct wacom_wac *wacom_wac) | 2073 | struct wacom_wac *wacom_wac) |
2034 | { | 2074 | { |
2035 | struct wacom_features *features = &wacom_wac->features; | 2075 | struct wacom_features *features = &wacom_wac->features; |
@@ -2047,9 +2087,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2047 | 2087 | ||
2048 | switch (features->type) { | 2088 | switch (features->type) { |
2049 | case WACOM_MO: | 2089 | case WACOM_MO: |
2050 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | ||
2051 | /* fall through */ | ||
2052 | |||
2053 | case WACOM_G4: | 2090 | case WACOM_G4: |
2054 | /* fall through */ | 2091 | /* fall through */ |
2055 | 2092 | ||
@@ -2092,6 +2129,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2092 | 2129 | ||
2093 | case WACOM_24HD: | 2130 | case WACOM_24HD: |
2094 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2131 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
2132 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
2095 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); | 2133 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); |
2096 | /* fall through */ | 2134 | /* fall through */ |
2097 | 2135 | ||
@@ -2106,6 +2144,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2106 | case WACOM_BEE: | 2144 | case WACOM_BEE: |
2107 | case CINTIQ: | 2145 | case CINTIQ: |
2108 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2146 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
2147 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
2109 | 2148 | ||
2110 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | 2149 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); |
2111 | 2150 | ||
@@ -2114,6 +2153,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2114 | 2153 | ||
2115 | case WACOM_13HD: | 2154 | case WACOM_13HD: |
2116 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2155 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
2156 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
2117 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | 2157 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); |
2118 | wacom_setup_cintiq(wacom_wac); | 2158 | wacom_setup_cintiq(wacom_wac); |
2119 | break; | 2159 | break; |
@@ -2122,6 +2162,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2122 | case INTUOS3L: | 2162 | case INTUOS3L: |
2123 | case INTUOS3S: | 2163 | case INTUOS3S: |
2124 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2164 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
2165 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
2125 | /* fall through */ | 2166 | /* fall through */ |
2126 | 2167 | ||
2127 | case INTUOS: | 2168 | case INTUOS: |
@@ -2144,6 +2185,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2144 | 0, 0); | 2185 | 0, 0); |
2145 | 2186 | ||
2146 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2187 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
2188 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
2147 | 2189 | ||
2148 | wacom_setup_intuos(wacom_wac); | 2190 | wacom_setup_intuos(wacom_wac); |
2149 | } else if (features->device_type == BTN_TOOL_FINGER) { | 2191 | } else if (features->device_type == BTN_TOOL_FINGER) { |
@@ -2162,6 +2204,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2162 | case INTUOS4L: | 2204 | case INTUOS4L: |
2163 | case INTUOS4S: | 2205 | case INTUOS4S: |
2164 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2206 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
2207 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
2165 | wacom_setup_intuos(wacom_wac); | 2208 | wacom_setup_intuos(wacom_wac); |
2166 | 2209 | ||
2167 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 2210 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
@@ -2196,6 +2239,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2196 | /* fall through */ | 2239 | /* fall through */ |
2197 | 2240 | ||
2198 | case DTUS: | 2241 | case DTUS: |
2242 | case DTUSX: | ||
2199 | case PL: | 2243 | case PL: |
2200 | case DTU: | 2244 | case DTU: |
2201 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | 2245 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
@@ -2246,6 +2290,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2246 | __clear_bit(ABS_X, input_dev->absbit); | 2290 | __clear_bit(ABS_X, input_dev->absbit); |
2247 | __clear_bit(ABS_Y, input_dev->absbit); | 2291 | __clear_bit(ABS_Y, input_dev->absbit); |
2248 | __clear_bit(BTN_TOUCH, input_dev->keybit); | 2292 | __clear_bit(BTN_TOUCH, input_dev->keybit); |
2293 | |||
2294 | /* PAD is setup by wacom_setup_pad_input_capabilities later */ | ||
2295 | return 1; | ||
2249 | } | 2296 | } |
2250 | } else if (features->device_type == BTN_TOOL_PEN) { | 2297 | } else if (features->device_type == BTN_TOOL_PEN) { |
2251 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 2298 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
@@ -2261,6 +2308,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
2261 | 2308 | ||
2262 | case CINTIQ_HYBRID: | 2309 | case CINTIQ_HYBRID: |
2263 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2310 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
2311 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
2264 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | 2312 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); |
2265 | 2313 | ||
2266 | wacom_setup_cintiq(wacom_wac); | 2314 | wacom_setup_cintiq(wacom_wac); |
@@ -2303,9 +2351,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2303 | 2351 | ||
2304 | case WACOM_G4: | 2352 | case WACOM_G4: |
2305 | __set_bit(BTN_BACK, input_dev->keybit); | 2353 | __set_bit(BTN_BACK, input_dev->keybit); |
2306 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
2307 | __set_bit(BTN_FORWARD, input_dev->keybit); | 2354 | __set_bit(BTN_FORWARD, input_dev->keybit); |
2308 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
2309 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | 2355 | input_set_capability(input_dev, EV_REL, REL_WHEEL); |
2310 | break; | 2356 | break; |
2311 | 2357 | ||
@@ -2402,7 +2448,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2402 | case INTUOSPS: | 2448 | case INTUOSPS: |
2403 | /* touch interface does not have the pad device */ | 2449 | /* touch interface does not have the pad device */ |
2404 | if (features->device_type != BTN_TOOL_PEN) | 2450 | if (features->device_type != BTN_TOOL_PEN) |
2405 | return 1; | 2451 | return -ENODEV; |
2406 | 2452 | ||
2407 | for (i = 0; i < 7; i++) | 2453 | for (i = 0; i < 7; i++) |
2408 | __set_bit(BTN_0 + i, input_dev->keybit); | 2454 | __set_bit(BTN_0 + i, input_dev->keybit); |
@@ -2446,8 +2492,10 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2446 | case INTUOSHT: | 2492 | case INTUOSHT: |
2447 | case BAMBOO_PT: | 2493 | case BAMBOO_PT: |
2448 | /* pad device is on the touch interface */ | 2494 | /* pad device is on the touch interface */ |
2449 | if (features->device_type != BTN_TOOL_FINGER) | 2495 | if ((features->device_type != BTN_TOOL_FINGER) || |
2450 | return 1; | 2496 | /* Bamboo Pen only tablet does not have pad */ |
2497 | ((features->type == BAMBOO_PT) && !features->touch_max)) | ||
2498 | return -ENODEV; | ||
2451 | 2499 | ||
2452 | __clear_bit(ABS_MISC, input_dev->absbit); | 2500 | __clear_bit(ABS_MISC, input_dev->absbit); |
2453 | 2501 | ||
@@ -2460,7 +2508,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2460 | 2508 | ||
2461 | default: | 2509 | default: |
2462 | /* no pad supported */ | 2510 | /* no pad supported */ |
2463 | return 1; | 2511 | return -ENODEV; |
2464 | } | 2512 | } |
2465 | return 0; | 2513 | return 0; |
2466 | } | 2514 | } |
@@ -2664,11 +2712,13 @@ static const struct wacom_features wacom_features_0x317 = | |||
2664 | INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, | 2712 | INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, |
2665 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2713 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2666 | static const struct wacom_features wacom_features_0xF4 = | 2714 | static const struct wacom_features wacom_features_0xF4 = |
2667 | { "Wacom Cintiq 24HD", 104280, 65400, 2047, 63, | 2715 | { "Wacom Cintiq 24HD", 104080, 65200, 2047, 63, |
2668 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; | 2716 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2717 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | ||
2669 | static const struct wacom_features wacom_features_0xF8 = | 2718 | static const struct wacom_features wacom_features_0xF8 = |
2670 | { "Wacom Cintiq 24HD touch", 104280, 65400, 2047, 63, /* Pen */ | 2719 | { "Wacom Cintiq 24HD touch", 104080, 65200, 2047, 63, /* Pen */ |
2671 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, | 2720 | WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2721 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | ||
2672 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; | 2722 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; |
2673 | static const struct wacom_features wacom_features_0xF6 = | 2723 | static const struct wacom_features wacom_features_0xF6 = |
2674 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ | 2724 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ |
@@ -2684,8 +2734,9 @@ static const struct wacom_features wacom_features_0xC6 = | |||
2684 | { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63, | 2734 | { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63, |
2685 | WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2735 | WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
2686 | static const struct wacom_features wacom_features_0x304 = | 2736 | static const struct wacom_features wacom_features_0x304 = |
2687 | { "Wacom Cintiq 13HD", 59352, 33648, 1023, 63, | 2737 | { "Wacom Cintiq 13HD", 59152, 33448, 1023, 63, |
2688 | WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; | 2738 | WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2739 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | ||
2689 | static const struct wacom_features wacom_features_0xC7 = | 2740 | static const struct wacom_features wacom_features_0xC7 = |
2690 | { "Wacom DTU1931", 37832, 30305, 511, 0, | 2741 | { "Wacom DTU1931", 37832, 30305, 511, 0, |
2691 | PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2742 | PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -2697,28 +2748,38 @@ static const struct wacom_features wacom_features_0xF0 = | |||
2697 | { "Wacom DTU1631", 34623, 19553, 511, 0, | 2748 | { "Wacom DTU1631", 34623, 19553, 511, 0, |
2698 | DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2749 | DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2699 | static const struct wacom_features wacom_features_0xFB = | 2750 | static const struct wacom_features wacom_features_0xFB = |
2700 | { "Wacom DTU1031", 22096, 13960, 511, 0, | 2751 | { "Wacom DTU1031", 21896, 13760, 511, 0, |
2701 | DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2752 | DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
2753 | WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; | ||
2754 | static const struct wacom_features wacom_features_0x32F = | ||
2755 | { "Wacom DTU1031X", 22472, 12728, 511, 0, | ||
2756 | DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | ||
2757 | WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; | ||
2702 | static const struct wacom_features wacom_features_0x57 = | 2758 | static const struct wacom_features wacom_features_0x57 = |
2703 | { "Wacom DTK2241", 95640, 54060, 2047, 63, | 2759 | { "Wacom DTK2241", 95640, 54060, 2047, 63, |
2704 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; | 2760 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2761 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | ||
2705 | static const struct wacom_features wacom_features_0x59 = /* Pen */ | 2762 | static const struct wacom_features wacom_features_0x59 = /* Pen */ |
2706 | { "Wacom DTH2242", 95640, 54060, 2047, 63, | 2763 | { "Wacom DTH2242", 95640, 54060, 2047, 63, |
2707 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, | 2764 | DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2765 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | ||
2708 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; | 2766 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; |
2709 | static const struct wacom_features wacom_features_0x5D = /* Touch */ | 2767 | static const struct wacom_features wacom_features_0x5D = /* Touch */ |
2710 | { "Wacom DTH2242", .type = WACOM_24HDT, | 2768 | { "Wacom DTH2242", .type = WACOM_24HDT, |
2711 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10, | 2769 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10, |
2712 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2770 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2713 | static const struct wacom_features wacom_features_0xCC = | 2771 | static const struct wacom_features wacom_features_0xCC = |
2714 | { "Wacom Cintiq 21UX2", 87000, 65400, 2047, 63, | 2772 | { "Wacom Cintiq 21UX2", 86800, 65200, 2047, 63, |
2715 | WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; | 2773 | WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2774 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | ||
2716 | static const struct wacom_features wacom_features_0xFA = | 2775 | static const struct wacom_features wacom_features_0xFA = |
2717 | { "Wacom Cintiq 22HD", 95640, 54060, 2047, 63, | 2776 | { "Wacom Cintiq 22HD", 95440, 53860, 2047, 63, |
2718 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; | 2777 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2778 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; | ||
2719 | static const struct wacom_features wacom_features_0x5B = | 2779 | static const struct wacom_features wacom_features_0x5B = |
2720 | { "Wacom Cintiq 22HDT", 95640, 54060, 2047, 63, | 2780 | { "Wacom Cintiq 22HDT", 95440, 53860, 2047, 63, |
2721 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, | 2781 | WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2782 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | ||
2722 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; | 2783 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; |
2723 | static const struct wacom_features wacom_features_0x5E = | 2784 | static const struct wacom_features wacom_features_0x5E = |
2724 | { "Wacom Cintiq 22HDT", .type = WACOM_24HDT, | 2785 | { "Wacom Cintiq 22HDT", .type = WACOM_24HDT, |
@@ -2863,21 +2924,27 @@ static const struct wacom_features wacom_features_0x6004 = | |||
2863 | { "ISD-V4", 12800, 8000, 255, 0, | 2924 | { "ISD-V4", 12800, 8000, 255, 0, |
2864 | TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2925 | TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2865 | static const struct wacom_features wacom_features_0x307 = | 2926 | static const struct wacom_features wacom_features_0x307 = |
2866 | { "Wacom ISDv5 307", 59352, 33648, 2047, 63, | 2927 | { "Wacom ISDv5 307", 59152, 33448, 2047, 63, |
2867 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, | 2928 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2929 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | ||
2868 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; | 2930 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; |
2869 | static const struct wacom_features wacom_features_0x309 = | 2931 | static const struct wacom_features wacom_features_0x309 = |
2870 | { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ | 2932 | { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ |
2871 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10, | 2933 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10, |
2872 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2934 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2873 | static const struct wacom_features wacom_features_0x30A = | 2935 | static const struct wacom_features wacom_features_0x30A = |
2874 | { "Wacom ISDv5 30A", 59352, 33648, 2047, 63, | 2936 | { "Wacom ISDv5 30A", 59152, 33448, 2047, 63, |
2875 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, | 2937 | CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2938 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | ||
2876 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C }; | 2939 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C }; |
2877 | static const struct wacom_features wacom_features_0x30C = | 2940 | static const struct wacom_features wacom_features_0x30C = |
2878 | { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */ | 2941 | { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */ |
2879 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, | 2942 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, |
2880 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2943 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
2944 | static const struct wacom_features wacom_features_0x323 = | ||
2945 | { "Wacom Intuos P M", 21600, 13500, 1023, 31, | ||
2946 | INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | ||
2947 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | ||
2881 | 2948 | ||
2882 | static const struct wacom_features wacom_features_HID_ANY_ID = | 2949 | static const struct wacom_features wacom_features_HID_ANY_ID = |
2883 | { "Wacom HID", .type = HID_GENERIC }; | 2950 | { "Wacom HID", .type = HID_GENERIC }; |
@@ -3022,10 +3089,13 @@ const struct hid_device_id wacom_ids[] = { | |||
3022 | { USB_DEVICE_WACOM(0x314) }, | 3089 | { USB_DEVICE_WACOM(0x314) }, |
3023 | { USB_DEVICE_WACOM(0x315) }, | 3090 | { USB_DEVICE_WACOM(0x315) }, |
3024 | { USB_DEVICE_WACOM(0x317) }, | 3091 | { USB_DEVICE_WACOM(0x317) }, |
3092 | { USB_DEVICE_WACOM(0x323) }, | ||
3093 | { USB_DEVICE_WACOM(0x32F) }, | ||
3025 | { USB_DEVICE_WACOM(0x4001) }, | 3094 | { USB_DEVICE_WACOM(0x4001) }, |
3026 | { USB_DEVICE_WACOM(0x4004) }, | 3095 | { USB_DEVICE_WACOM(0x4004) }, |
3027 | { USB_DEVICE_WACOM(0x5000) }, | 3096 | { USB_DEVICE_WACOM(0x5000) }, |
3028 | { USB_DEVICE_WACOM(0x5002) }, | 3097 | { USB_DEVICE_WACOM(0x5002) }, |
3098 | { USB_DEVICE_LENOVO(0x6004) }, | ||
3029 | 3099 | ||
3030 | { USB_DEVICE_WACOM(HID_ANY_ID) }, | 3100 | { USB_DEVICE_WACOM(HID_ANY_ID) }, |
3031 | { } | 3101 | { } |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 0f0b85ec1322..bfad815cda8a 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -80,6 +80,7 @@ enum { | |||
80 | PL, | 80 | PL, |
81 | DTU, | 81 | DTU, |
82 | DTUS, | 82 | DTUS, |
83 | DTUSX, | ||
83 | INTUOS, | 84 | INTUOS, |
84 | INTUOS3S, | 85 | INTUOS3S, |
85 | INTUOS3, | 86 | INTUOS3, |
@@ -144,6 +145,7 @@ struct wacom_features { | |||
144 | int pktlen; | 145 | int pktlen; |
145 | bool check_for_hid_type; | 146 | bool check_for_hid_type; |
146 | int hid_type; | 147 | int hid_type; |
148 | int last_slot_field; | ||
147 | }; | 149 | }; |
148 | 150 | ||
149 | struct wacom_shared { | 151 | struct wacom_shared { |
@@ -183,6 +185,7 @@ struct wacom_wac { | |||
183 | struct input_dev *input; | 185 | struct input_dev *input; |
184 | struct input_dev *pad_input; | 186 | struct input_dev *pad_input; |
185 | bool input_registered; | 187 | bool input_registered; |
188 | bool pad_registered; | ||
186 | int pid; | 189 | int pid; |
187 | int battery_capacity; | 190 | int battery_capacity; |
188 | int num_contacts_left; | 191 | int num_contacts_left; |