diff options
| -rw-r--r-- | drivers/hid/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/hid/Makefile | 50 | ||||
| -rw-r--r-- | drivers/hid/hid-betopff.c | 160 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 31 | ||||
| -rw-r--r-- | drivers/hid/hid-hyperv.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 9 | ||||
| -rw-r--r-- | drivers/hid/hid-input.c | 26 | ||||
| -rw-r--r-- | drivers/hid/hid-lenovo.c | 79 | ||||
| -rw-r--r-- | drivers/hid/hid-lg4ff.c | 11 | ||||
| -rw-r--r-- | drivers/hid/hid-logitech-hidpp.c | 81 | ||||
| -rw-r--r-- | drivers/hid/hid-microsoft.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-rmi.c | 118 | ||||
| -rw-r--r-- | drivers/hid/usbhid/Makefile | 12 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-pidff.c | 6 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 1 | ||||
| -rw-r--r-- | drivers/hid/wacom_sys.c | 9 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.c | 239 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.h | 17 | ||||
| -rw-r--r-- | include/linux/hid.h | 4 | ||||
| -rw-r--r-- | include/uapi/linux/input.h | 1 |
20 files changed, 641 insertions, 229 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index dfdc26970022..152b006833cd 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -147,6 +147,16 @@ config HID_BELKIN | |||
| 147 | ---help--- | 147 | ---help--- |
| 148 | Support for Belkin Flip KVM and Wireless keyboard. | 148 | Support for Belkin Flip KVM and Wireless keyboard. |
| 149 | 149 | ||
| 150 | config HID_BETOP_FF | ||
| 151 | tristate "Betop Production Inc. force feedback support" | ||
| 152 | depends on USB_HID | ||
| 153 | select INPUT_FF_MEMLESS | ||
| 154 | ---help--- | ||
| 155 | Say Y here if you want to enable force feedback support for devices by | ||
| 156 | BETOP Production Ltd. | ||
| 157 | Currently the following devices are known to be supported: | ||
| 158 | - BETOP 2185 PC & BFM MODE | ||
| 159 | |||
| 150 | config HID_CHERRY | 160 | config HID_CHERRY |
| 151 | tristate "Cherry Cymotion keyboard" if EXPERT | 161 | tristate "Cherry Cymotion keyboard" if EXPERT |
| 152 | depends on HID | 162 | depends on HID |
| @@ -389,7 +399,7 @@ config HID_LOGITECH_HIDPP | |||
| 389 | Say Y if you want support for Logitech devices relying on the HID++ | 399 | Say Y if you want support for Logitech devices relying on the HID++ |
| 390 | specification. Such devices are the various Logitech Touchpads (T650, | 400 | specification. Such devices are the various Logitech Touchpads (T650, |
| 391 | T651, TK820), some mice (Zone Touch mouse), or even keyboards (Solar | 401 | T651, TK820), some mice (Zone Touch mouse), or even keyboards (Solar |
| 392 | Keayboard). | 402 | Keyboard). |
| 393 | 403 | ||
| 394 | config LOGITECH_FF | 404 | config LOGITECH_FF |
| 395 | bool "Logitech force feedback support" | 405 | bool "Logitech force feedback support" |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index debd15b44b59..6f19958dfc38 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
| @@ -2,10 +2,7 @@ | |||
| 2 | # Makefile for the HID driver | 2 | # Makefile for the HID driver |
| 3 | # | 3 | # |
| 4 | hid-y := hid-core.o hid-input.o | 4 | hid-y := hid-core.o hid-input.o |
| 5 | 5 | hid-$(CONFIG_DEBUG_FS) += hid-debug.o | |
| 6 | ifdef CONFIG_DEBUG_FS | ||
| 7 | hid-objs += hid-debug.o | ||
| 8 | endif | ||
| 9 | 6 | ||
| 10 | obj-$(CONFIG_HID) += hid.o | 7 | obj-$(CONFIG_HID) += hid.o |
| 11 | obj-$(CONFIG_UHID) += uhid.o | 8 | obj-$(CONFIG_UHID) += uhid.o |
| @@ -15,23 +12,13 @@ obj-$(CONFIG_HID_GENERIC) += hid-generic.o | |||
| 15 | hid-$(CONFIG_HIDRAW) += hidraw.o | 12 | hid-$(CONFIG_HIDRAW) += hidraw.o |
| 16 | 13 | ||
| 17 | hid-logitech-y := hid-lg.o | 14 | hid-logitech-y := hid-lg.o |
| 18 | ifdef CONFIG_LOGITECH_FF | 15 | hid-logitech-$(CONFIG_LOGITECH_FF) += hid-lgff.o |
| 19 | hid-logitech-y += hid-lgff.o | 16 | hid-logitech-$(CONFIG_LOGIRUMBLEPAD2_FF) += hid-lg2ff.o |
| 20 | endif | 17 | hid-logitech-$(CONFIG_LOGIG940_FF) += hid-lg3ff.o |
| 21 | ifdef CONFIG_LOGIRUMBLEPAD2_FF | 18 | hid-logitech-$(CONFIG_LOGIWHEELS_FF) += hid-lg4ff.o |
| 22 | hid-logitech-y += hid-lg2ff.o | ||
| 23 | endif | ||
| 24 | ifdef CONFIG_LOGIG940_FF | ||
| 25 | hid-logitech-y += hid-lg3ff.o | ||
| 26 | endif | ||
| 27 | ifdef CONFIG_LOGIWHEELS_FF | ||
| 28 | hid-logitech-y += hid-lg4ff.o | ||
| 29 | endif | ||
| 30 | 19 | ||
| 31 | hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o | 20 | hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o |
| 32 | ifdef CONFIG_DEBUG_FS | 21 | hid-wiimote-$(CONFIG_DEBUG_FS) += hid-wiimote-debug.o |
| 33 | hid-wiimote-y += hid-wiimote-debug.o | ||
| 34 | endif | ||
| 35 | 22 | ||
| 36 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 23 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
| 37 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o | 24 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o |
| @@ -39,6 +26,7 @@ obj-$(CONFIG_HID_APPLE) += hid-apple.o | |||
| 39 | obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o | 26 | obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o |
| 40 | obj-$(CONFIG_HID_AUREAL) += hid-aureal.o | 27 | obj-$(CONFIG_HID_AUREAL) += hid-aureal.o |
| 41 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | 28 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o |
| 29 | obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o | ||
| 42 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 30 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
| 43 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | 31 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o |
| 44 | obj-$(CONFIG_HID_CP2112) += hid-cp2112.o | 32 | obj-$(CONFIG_HID_CP2112) += hid-cp2112.o |
| @@ -76,24 +64,12 @@ obj-$(CONFIG_HID_PENMOUNT) += hid-penmount.o | |||
| 76 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o | 64 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o |
| 77 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o | 65 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o |
| 78 | hid-picolcd-y += hid-picolcd_core.o | 66 | hid-picolcd-y += hid-picolcd_core.o |
| 79 | ifdef CONFIG_HID_PICOLCD_FB | 67 | hid-picolcd-$(CONFIG_HID_PICOLCD_FB) += hid-picolcd_fb.o |
| 80 | hid-picolcd-y += hid-picolcd_fb.o | 68 | hid-picolcd-$(CONFIG_HID_PICOLCD_BACKLIGHT) += hid-picolcd_backlight.o |
| 81 | endif | 69 | hid-picolcd-$(CONFIG_HID_PICOLCD_LCD) += hid-picolcd_lcd.o |
| 82 | ifdef CONFIG_HID_PICOLCD_BACKLIGHT | 70 | hid-picolcd-$(CONFIG_HID_PICOLCD_LEDS) += hid-picolcd_leds.o |
| 83 | hid-picolcd-y += hid-picolcd_backlight.o | 71 | hid-picolcd-$(CONFIG_HID_PICOLCD_CIR) += hid-picolcd_cir.o |
| 84 | endif | 72 | hid-picolcd-$(CONFIG_DEBUG_FS) += hid-picolcd_debugfs.o |
| 85 | ifdef CONFIG_HID_PICOLCD_LCD | ||
| 86 | hid-picolcd-y += hid-picolcd_lcd.o | ||
| 87 | endif | ||
| 88 | ifdef CONFIG_HID_PICOLCD_LEDS | ||
| 89 | hid-picolcd-y += hid-picolcd_leds.o | ||
| 90 | endif | ||
| 91 | ifdef CONFIG_HID_PICOLCD_CIR | ||
| 92 | hid-picolcd-y += hid-picolcd_cir.o | ||
| 93 | endif | ||
| 94 | ifdef CONFIG_DEBUG_FS | ||
| 95 | hid-picolcd-y += hid-picolcd_debugfs.o | ||
| 96 | endif | ||
| 97 | 73 | ||
| 98 | obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o | 74 | obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o |
| 99 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o | 75 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o |
diff --git a/drivers/hid/hid-betopff.c b/drivers/hid/hid-betopff.c new file mode 100644 index 000000000000..69cfc8dc6af1 --- /dev/null +++ b/drivers/hid/hid-betopff.c | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | /* | ||
| 2 | * Force feedback support for Betop based devices | ||
| 3 | * | ||
| 4 | * The devices are distributed under various names and the same USB device ID | ||
| 5 | * can be used in both adapters and actual game controllers. | ||
| 6 | * | ||
| 7 | * 0x11c2:0x2208 "BTP2185 BFM mode Joystick" | ||
| 8 | * - tested with BTP2185 BFM Mode. | ||
| 9 | * | ||
| 10 | * 0x11C0:0x5506 "BTP2185 PC mode Joystick" | ||
| 11 | * - tested with BTP2185 PC Mode. | ||
| 12 | * | ||
| 13 | * 0x8380:0x1850 "BTP2185 V2 PC mode USB Gamepad" | ||
| 14 | * - tested with BTP2185 PC Mode with another version. | ||
| 15 | * | ||
| 16 | * 0x20bc:0x5500 "BTP2185 V2 BFM mode Joystick" | ||
| 17 | * - tested with BTP2171s. | ||
| 18 | * Copyright (c) 2014 Huang Bo <huangbobupt@163.com> | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * This program is free software; you can redistribute it and/or modify it | ||
| 23 | * under the terms of the GNU General Public License as published by the Free | ||
| 24 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 25 | * any later version. | ||
| 26 | */ | ||
| 27 | |||
| 28 | |||
| 29 | #include <linux/input.h> | ||
| 30 | #include <linux/slab.h> | ||
| 31 | #include <linux/module.h> | ||
| 32 | #include <linux/hid.h> | ||
| 33 | |||
| 34 | #include "hid-ids.h" | ||
| 35 | |||
| 36 | struct betopff_device { | ||
| 37 | struct hid_report *report; | ||
| 38 | }; | ||
| 39 | |||
| 40 | static int hid_betopff_play(struct input_dev *dev, void *data, | ||
| 41 | struct ff_effect *effect) | ||
| 42 | { | ||
| 43 | struct hid_device *hid = input_get_drvdata(dev); | ||
| 44 | struct betopff_device *betopff = data; | ||
| 45 | __u16 left, right; | ||
| 46 | |||
| 47 | left = effect->u.rumble.strong_magnitude; | ||
| 48 | right = effect->u.rumble.weak_magnitude; | ||
| 49 | |||
| 50 | betopff->report->field[2]->value[0] = left / 256; | ||
| 51 | betopff->report->field[3]->value[0] = right / 256; | ||
| 52 | |||
| 53 | hid_hw_request(hid, betopff->report, HID_REQ_SET_REPORT); | ||
| 54 | |||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | static int betopff_init(struct hid_device *hid) | ||
| 59 | { | ||
| 60 | struct betopff_device *betopff; | ||
| 61 | struct hid_report *report; | ||
| 62 | struct hid_input *hidinput = | ||
| 63 | list_first_entry(&hid->inputs, struct hid_input, list); | ||
| 64 | struct list_head *report_list = | ||
| 65 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
| 66 | struct input_dev *dev = hidinput->input; | ||
| 67 | int field_count = 0; | ||
| 68 | int error; | ||
| 69 | int i, j; | ||
| 70 | |||
| 71 | if (list_empty(report_list)) { | ||
| 72 | hid_err(hid, "no output reports found\n"); | ||
| 73 | return -ENODEV; | ||
| 74 | } | ||
| 75 | |||
| 76 | report = list_first_entry(report_list, struct hid_report, list); | ||
| 77 | /* | ||
| 78 | * Actually there are 4 fields for 4 Bytes as below: | ||
| 79 | * ----------------------------------------- | ||
| 80 | * Byte0 Byte1 Byte2 Byte3 | ||
| 81 | * 0x00 0x00 left_motor right_motor | ||
| 82 | * ----------------------------------------- | ||
| 83 | * Do init them with default value. | ||
| 84 | */ | ||
| 85 | for (i = 0; i < report->maxfield; i++) { | ||
| 86 | for (j = 0; j < report->field[i]->report_count; j++) { | ||
| 87 | report->field[i]->value[j] = 0x00; | ||
| 88 | field_count++; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | if (field_count < 4) { | ||
| 93 | hid_err(hid, "not enough fields in the report: %d\n", | ||
| 94 | field_count); | ||
| 95 | return -ENODEV; | ||
| 96 | } | ||
| 97 | |||
| 98 | betopff = kzalloc(sizeof(*betopff), GFP_KERNEL); | ||
| 99 | if (!betopff) | ||
| 100 | return -ENOMEM; | ||
| 101 | |||
| 102 | set_bit(FF_RUMBLE, dev->ffbit); | ||
| 103 | |||
| 104 | error = input_ff_create_memless(dev, betopff, hid_betopff_play); | ||
| 105 | if (error) { | ||
| 106 | kfree(betopff); | ||
| 107 | return error; | ||
| 108 | } | ||
| 109 | |||
| 110 | betopff->report = report; | ||
| 111 | hid_hw_request(hid, betopff->report, HID_REQ_SET_REPORT); | ||
| 112 | |||
| 113 | hid_info(hid, "Force feedback for betop devices by huangbo <huangbobupt@163.com>\n"); | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int betop_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
| 119 | { | ||
| 120 | int ret; | ||
| 121 | |||
| 122 | if (id->driver_data) | ||
| 123 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | ||
| 124 | |||
| 125 | ret = hid_parse(hdev); | ||
| 126 | if (ret) { | ||
| 127 | hid_err(hdev, "parse failed\n"); | ||
| 128 | goto err; | ||
| 129 | } | ||
| 130 | |||
| 131 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | ||
| 132 | if (ret) { | ||
| 133 | hid_err(hdev, "hw start failed\n"); | ||
| 134 | goto err; | ||
| 135 | } | ||
| 136 | |||
| 137 | betopff_init(hdev); | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | err: | ||
| 141 | return ret; | ||
| 142 | } | ||
| 143 | |||
| 144 | static const struct hid_device_id betop_devices[] = { | ||
| 145 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, | ||
| 146 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) }, | ||
| 147 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) }, | ||
| 148 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) }, | ||
| 149 | { } | ||
| 150 | }; | ||
| 151 | MODULE_DEVICE_TABLE(hid, betop_devices); | ||
| 152 | |||
| 153 | static struct hid_driver betop_driver = { | ||
| 154 | .name = "betop", | ||
| 155 | .id_table = betop_devices, | ||
| 156 | .probe = betop_probe, | ||
| 157 | }; | ||
| 158 | module_hid_driver(betop_driver); | ||
| 159 | |||
| 160 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 77afffc6bab8..db4fb6e1cc5b 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -698,15 +698,25 @@ static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage) | |||
| 698 | static void hid_scan_collection(struct hid_parser *parser, unsigned type) | 698 | static void hid_scan_collection(struct hid_parser *parser, unsigned type) |
| 699 | { | 699 | { |
| 700 | struct hid_device *hid = parser->device; | 700 | struct hid_device *hid = parser->device; |
| 701 | int i; | ||
| 701 | 702 | ||
| 702 | if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && | 703 | if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && |
| 703 | type == HID_COLLECTION_PHYSICAL) | 704 | type == HID_COLLECTION_PHYSICAL) |
| 704 | hid->group = HID_GROUP_SENSOR_HUB; | 705 | hid->group = HID_GROUP_SENSOR_HUB; |
| 705 | 706 | ||
| 706 | if (hid->vendor == USB_VENDOR_ID_MICROSOFT && | 707 | if (hid->vendor == USB_VENDOR_ID_MICROSOFT && |
| 707 | hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 && | 708 | (hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 || |
| 709 | hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3_JP) && | ||
| 708 | hid->group == HID_GROUP_MULTITOUCH) | 710 | hid->group == HID_GROUP_MULTITOUCH) |
| 709 | hid->group = HID_GROUP_GENERIC; | 711 | hid->group = HID_GROUP_GENERIC; |
| 712 | |||
| 713 | if ((parser->global.usage_page << 16) == HID_UP_GENDESK) | ||
| 714 | for (i = 0; i < parser->local.usage_index; i++) | ||
| 715 | if (parser->local.usage[i] == HID_GD_POINTER) | ||
| 716 | parser->scan_flags |= HID_SCAN_FLAG_GD_POINTER; | ||
| 717 | |||
| 718 | if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR) | ||
| 719 | parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC; | ||
| 710 | } | 720 | } |
| 711 | 721 | ||
| 712 | static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) | 722 | static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) |
| @@ -792,11 +802,14 @@ static int hid_scan_report(struct hid_device *hid) | |||
| 792 | hid->group = HID_GROUP_WACOM; | 802 | hid->group = HID_GROUP_WACOM; |
| 793 | break; | 803 | break; |
| 794 | case USB_VENDOR_ID_SYNAPTICS: | 804 | case USB_VENDOR_ID_SYNAPTICS: |
| 795 | if ((hid->group == HID_GROUP_GENERIC) && | 805 | if (hid->group == HID_GROUP_GENERIC) |
| 796 | (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE)) | 806 | if ((parser->scan_flags & HID_SCAN_FLAG_VENDOR_SPECIFIC) |
| 797 | /* hid-rmi should only bind to the mouse interface of | 807 | && (parser->scan_flags & HID_SCAN_FLAG_GD_POINTER)) |
| 798 | * composite USB devices */ | 808 | /* |
| 799 | hid->group = HID_GROUP_RMI; | 809 | * hid-rmi should take care of them, |
| 810 | * not hid-generic | ||
| 811 | */ | ||
| 812 | hid->group = HID_GROUP_RMI; | ||
| 800 | break; | 813 | break; |
| 801 | } | 814 | } |
| 802 | 815 | ||
| @@ -1757,6 +1770,10 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1757 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1770 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| 1758 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, | 1771 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, |
| 1759 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1772 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
| 1773 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, | ||
| 1774 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) }, | ||
| 1775 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) }, | ||
| 1776 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) }, | ||
| 1760 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 1777 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
| 1761 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | 1778 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, |
| 1762 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1779 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
| @@ -1861,6 +1878,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1861 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, | 1878 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, |
| 1862 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, | 1879 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, |
| 1863 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, | 1880 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, |
| 1881 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP) }, | ||
| 1864 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1882 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
| 1865 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, | 1883 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, |
| 1866 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, | 1884 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, |
| @@ -1971,6 +1989,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1971 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, | 1989 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, |
| 1972 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, | 1990 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, |
| 1973 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, | 1991 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, |
| 1992 | { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) }, | ||
| 1974 | { } | 1993 | { } |
| 1975 | }; | 1994 | }; |
| 1976 | 1995 | ||
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 31fad641b744..6039f071fab1 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c | |||
| @@ -381,7 +381,7 @@ static void mousevsc_on_channel_callback(void *context) | |||
| 381 | static int mousevsc_connect_to_vsp(struct hv_device *device) | 381 | static int mousevsc_connect_to_vsp(struct hv_device *device) |
| 382 | { | 382 | { |
| 383 | int ret = 0; | 383 | int ret = 0; |
| 384 | int t; | 384 | unsigned long t; |
| 385 | struct mousevsc_dev *input_dev = hv_get_drvdata(device); | 385 | struct mousevsc_dev *input_dev = hv_get_drvdata(device); |
| 386 | struct mousevsc_prt_msg *request; | 386 | struct mousevsc_prt_msg *request; |
| 387 | struct mousevsc_prt_msg *response; | 387 | struct mousevsc_prt_msg *response; |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 8df47449126c..46edb4d3ed28 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -189,6 +189,11 @@ | |||
| 189 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 | 189 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 |
| 190 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 | 190 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 |
| 191 | 191 | ||
| 192 | #define USB_VENDOR_ID_BETOP_2185BFM 0x11c2 | ||
| 193 | #define USB_VENDOR_ID_BETOP_2185PC 0x11c0 | ||
| 194 | #define USB_VENDOR_ID_BETOP_2185V2PC 0x8380 | ||
| 195 | #define USB_VENDOR_ID_BETOP_2185V2BFM 0x20bc | ||
| 196 | |||
| 192 | #define USB_VENDOR_ID_BTC 0x046e | 197 | #define USB_VENDOR_ID_BTC 0x046e |
| 193 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 | 198 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 |
| 194 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 | 199 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 |
| @@ -655,6 +660,7 @@ | |||
| 655 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 | 660 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 |
| 656 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | 661 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
| 657 | #define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07dc | 662 | #define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07dc |
| 663 | #define USB_DEVICE_ID_MS_TYPE_COVER_3_JP 0x07dd | ||
| 658 | 664 | ||
| 659 | #define USB_VENDOR_ID_MOJO 0x8282 | 665 | #define USB_VENDOR_ID_MOJO 0x8282 |
| 660 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 | 666 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 |
| @@ -769,6 +775,9 @@ | |||
| 769 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 | 775 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 |
| 770 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 | 776 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 |
| 771 | 777 | ||
| 778 | #define USB_VENDOR_ID_RAZER 0x1532 | ||
| 779 | #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D | ||
| 780 | |||
| 772 | #define USB_VENDOR_ID_REALTEK 0x0bda | 781 | #define USB_VENDOR_ID_REALTEK 0x0bda |
| 773 | #define USB_DEVICE_ID_REALTEK_READER 0x0152 | 782 | #define USB_DEVICE_ID_REALTEK_READER 0x0152 |
| 774 | 783 | ||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 9505605b6e22..052869d0ab78 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -306,10 +306,13 @@ static enum power_supply_property hidinput_battery_props[] = { | |||
| 306 | 306 | ||
| 307 | static const struct hid_device_id hid_battery_quirks[] = { | 307 | static const struct hid_device_id hid_battery_quirks[] = { |
| 308 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 308 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
| 309 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), | 309 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), |
| 310 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | 310 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
| 311 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
| 312 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), | ||
| 313 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
| 311 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 314 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
| 312 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | 315 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
| 313 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | 316 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
| 314 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 317 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
| 315 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), | 318 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), |
| @@ -1104,6 +1107,23 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
| 1104 | return; | 1107 | return; |
| 1105 | } | 1108 | } |
| 1106 | 1109 | ||
| 1110 | /* | ||
| 1111 | * Ignore reports for absolute data if the data didn't change. This is | ||
| 1112 | * not only an optimization but also fixes 'dead' key reports. Some | ||
| 1113 | * RollOver implementations for localized keys (like BACKSLASH/PIPE; HID | ||
| 1114 | * 0x31 and 0x32) report multiple keys, even though a localized keyboard | ||
| 1115 | * can only have one of them physically available. The 'dead' keys | ||
| 1116 | * report constant 0. As all map to the same keycode, they'd confuse | ||
| 1117 | * the input layer. If we filter the 'dead' keys on the HID level, we | ||
| 1118 | * skip the keycode translation and only forward real events. | ||
| 1119 | */ | ||
| 1120 | if (!(field->flags & (HID_MAIN_ITEM_RELATIVE | | ||
| 1121 | HID_MAIN_ITEM_BUFFERED_BYTE)) && | ||
| 1122 | (field->flags & HID_MAIN_ITEM_VARIABLE) && | ||
| 1123 | usage->usage_index < field->maxusage && | ||
| 1124 | value == field->value[usage->usage_index]) | ||
| 1125 | return; | ||
| 1126 | |||
| 1107 | /* report the usage code as scancode if the key status has changed */ | 1127 | /* report the usage code as scancode if the key status has changed */ |
| 1108 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) | 1128 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) |
| 1109 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); | 1129 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); |
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 4c55f4d95798..c4c3f0952521 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c | |||
| @@ -38,6 +38,7 @@ struct lenovo_drvdata_tpkbd { | |||
| 38 | 38 | ||
| 39 | struct lenovo_drvdata_cptkbd { | 39 | struct lenovo_drvdata_cptkbd { |
| 40 | bool fn_lock; | 40 | bool fn_lock; |
| 41 | int sensitivity; | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) | 44 | #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) |
| @@ -91,6 +92,38 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, | |||
| 91 | case 0x00fa: /* Fn-Esc: Fn-lock toggle */ | 92 | case 0x00fa: /* Fn-Esc: Fn-lock toggle */ |
| 92 | map_key_clear(KEY_FN_ESC); | 93 | map_key_clear(KEY_FN_ESC); |
| 93 | return 1; | 94 | return 1; |
| 95 | case 0x00fb: /* Middle mouse button (in native mode) */ | ||
| 96 | map_key_clear(BTN_MIDDLE); | ||
| 97 | return 1; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | /* Compatibility middle/wheel mappings should be ignored */ | ||
| 102 | if (usage->hid == HID_GD_WHEEL) | ||
| 103 | return -1; | ||
| 104 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON && | ||
| 105 | (usage->hid & HID_USAGE) == 0x003) | ||
| 106 | return -1; | ||
| 107 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER && | ||
| 108 | (usage->hid & HID_USAGE) == 0x238) | ||
| 109 | return -1; | ||
| 110 | |||
| 111 | /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */ | ||
| 112 | if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 || | ||
| 113 | (usage->hid & HID_USAGE_PAGE) == 0xffa10000) { | ||
| 114 | field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE; | ||
| 115 | field->logical_minimum = -127; | ||
| 116 | field->logical_maximum = 127; | ||
| 117 | |||
| 118 | switch (usage->hid & HID_USAGE) { | ||
| 119 | case 0x0000: | ||
| 120 | hid_map_usage(hi, usage, bit, max, EV_REL, 0x06); | ||
| 121 | return 1; | ||
| 122 | case 0x0001: | ||
| 123 | hid_map_usage(hi, usage, bit, max, EV_REL, 0x08); | ||
| 124 | return 1; | ||
| 125 | default: | ||
| 126 | return -1; | ||
| 94 | } | 127 | } |
| 95 | } | 128 | } |
| 96 | 129 | ||
| @@ -145,6 +178,7 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev) | |||
| 145 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | 178 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); |
| 146 | 179 | ||
| 147 | ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); | 180 | ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); |
| 181 | ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity); | ||
| 148 | if (ret) | 182 | if (ret) |
| 149 | hid_err(hdev, "Fn-lock setting failed: %d\n", ret); | 183 | hid_err(hdev, "Fn-lock setting failed: %d\n", ret); |
| 150 | } | 184 | } |
| @@ -179,13 +213,50 @@ static ssize_t attr_fn_lock_store_cptkbd(struct device *dev, | |||
| 179 | return count; | 213 | return count; |
| 180 | } | 214 | } |
| 181 | 215 | ||
| 216 | static ssize_t attr_sensitivity_show_cptkbd(struct device *dev, | ||
| 217 | struct device_attribute *attr, | ||
| 218 | char *buf) | ||
| 219 | { | ||
| 220 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 221 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | ||
| 222 | |||
| 223 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
| 224 | cptkbd_data->sensitivity); | ||
| 225 | } | ||
| 226 | |||
| 227 | static ssize_t attr_sensitivity_store_cptkbd(struct device *dev, | ||
| 228 | struct device_attribute *attr, | ||
| 229 | const char *buf, | ||
| 230 | size_t count) | ||
| 231 | { | ||
| 232 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 233 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | ||
| 234 | int value; | ||
| 235 | |||
| 236 | if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) | ||
| 237 | return -EINVAL; | ||
| 238 | |||
| 239 | cptkbd_data->sensitivity = value; | ||
| 240 | lenovo_features_set_cptkbd(hdev); | ||
| 241 | |||
| 242 | return count; | ||
| 243 | } | ||
| 244 | |||
| 245 | |||
| 182 | static struct device_attribute dev_attr_fn_lock_cptkbd = | 246 | static struct device_attribute dev_attr_fn_lock_cptkbd = |
| 183 | __ATTR(fn_lock, S_IWUSR | S_IRUGO, | 247 | __ATTR(fn_lock, S_IWUSR | S_IRUGO, |
| 184 | attr_fn_lock_show_cptkbd, | 248 | attr_fn_lock_show_cptkbd, |
| 185 | attr_fn_lock_store_cptkbd); | 249 | attr_fn_lock_store_cptkbd); |
| 186 | 250 | ||
| 251 | static struct device_attribute dev_attr_sensitivity_cptkbd = | ||
| 252 | __ATTR(sensitivity, S_IWUSR | S_IRUGO, | ||
| 253 | attr_sensitivity_show_cptkbd, | ||
| 254 | attr_sensitivity_store_cptkbd); | ||
| 255 | |||
| 256 | |||
| 187 | static struct attribute *lenovo_attributes_cptkbd[] = { | 257 | static struct attribute *lenovo_attributes_cptkbd[] = { |
| 188 | &dev_attr_fn_lock_cptkbd.attr, | 258 | &dev_attr_fn_lock_cptkbd.attr, |
| 259 | &dev_attr_sensitivity_cptkbd.attr, | ||
| 189 | NULL | 260 | NULL |
| 190 | }; | 261 | }; |
| 191 | 262 | ||
| @@ -594,8 +665,14 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev) | |||
| 594 | if (ret) | 665 | if (ret) |
| 595 | hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); | 666 | hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); |
| 596 | 667 | ||
| 597 | /* Turn Fn-Lock on by default */ | 668 | /* Switch middle button to native mode */ |
| 669 | ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); | ||
| 670 | if (ret) | ||
| 671 | hid_warn(hdev, "Failed to switch middle button: %d\n", ret); | ||
| 672 | |||
| 673 | /* Set keyboard settings to known state */ | ||
| 598 | cptkbd_data->fn_lock = true; | 674 | cptkbd_data->fn_lock = true; |
| 675 | cptkbd_data->sensitivity = 0x05; | ||
| 599 | lenovo_features_set_cptkbd(hdev); | 676 | lenovo_features_set_cptkbd(hdev); |
| 600 | 677 | ||
| 601 | ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); | 678 | ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 7835717bc020..db0dd9b17e53 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
| @@ -49,10 +49,6 @@ | |||
| 49 | 49 | ||
| 50 | static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); | 50 | static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); |
| 51 | static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range); | 51 | static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range); |
| 52 | static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf); | ||
| 53 | static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); | ||
| 54 | |||
| 55 | static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IROTH, lg4ff_range_show, lg4ff_range_store); | ||
| 56 | 52 | ||
| 57 | struct lg4ff_device_entry { | 53 | struct lg4ff_device_entry { |
| 58 | __u32 product_id; | 54 | __u32 product_id; |
| @@ -416,7 +412,8 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n | |||
| 416 | } | 412 | } |
| 417 | 413 | ||
| 418 | /* Read current range and display it in terminal */ | 414 | /* Read current range and display it in terminal */ |
| 419 | static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf) | 415 | static ssize_t range_show(struct device *dev, struct device_attribute *attr, |
| 416 | char *buf) | ||
| 420 | { | 417 | { |
| 421 | struct hid_device *hid = to_hid_device(dev); | 418 | struct hid_device *hid = to_hid_device(dev); |
| 422 | struct lg4ff_device_entry *entry; | 419 | struct lg4ff_device_entry *entry; |
| @@ -441,7 +438,8 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att | |||
| 441 | 438 | ||
| 442 | /* Set range to user specified value, call appropriate function | 439 | /* Set range to user specified value, call appropriate function |
| 443 | * according to the type of the wheel */ | 440 | * according to the type of the wheel */ |
| 444 | static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 441 | static ssize_t range_store(struct device *dev, struct device_attribute *attr, |
| 442 | const char *buf, size_t count) | ||
| 445 | { | 443 | { |
| 446 | struct hid_device *hid = to_hid_device(dev); | 444 | struct hid_device *hid = to_hid_device(dev); |
| 447 | struct lg4ff_device_entry *entry; | 445 | struct lg4ff_device_entry *entry; |
| @@ -472,6 +470,7 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at | |||
| 472 | 470 | ||
| 473 | return count; | 471 | return count; |
| 474 | } | 472 | } |
| 473 | static DEVICE_ATTR_RW(range); | ||
| 475 | 474 | ||
| 476 | #ifdef CONFIG_LEDS_CLASS | 475 | #ifdef CONFIG_LEDS_CLASS |
| 477 | static void lg4ff_set_leds(struct hid_device *hid, __u8 leds) | 476 | static void lg4ff_set_leds(struct hid_device *hid, __u8 leds) |
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index a93cefe0e522..e77658cd037c 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c | |||
| @@ -89,6 +89,7 @@ struct hidpp_device { | |||
| 89 | struct hid_device *hid_dev; | 89 | struct hid_device *hid_dev; |
| 90 | struct mutex send_mutex; | 90 | struct mutex send_mutex; |
| 91 | void *send_receive_buf; | 91 | void *send_receive_buf; |
| 92 | char *name; /* will never be NULL and should not be freed */ | ||
| 92 | wait_queue_head_t wait; | 93 | wait_queue_head_t wait; |
| 93 | bool answer_available; | 94 | bool answer_available; |
| 94 | u8 protocol_major; | 95 | u8 protocol_major; |
| @@ -105,6 +106,7 @@ struct hidpp_device { | |||
| 105 | }; | 106 | }; |
| 106 | 107 | ||
| 107 | 108 | ||
| 109 | /* HID++ 1.0 error codes */ | ||
| 108 | #define HIDPP_ERROR 0x8f | 110 | #define HIDPP_ERROR 0x8f |
| 109 | #define HIDPP_ERROR_SUCCESS 0x00 | 111 | #define HIDPP_ERROR_SUCCESS 0x00 |
| 110 | #define HIDPP_ERROR_INVALID_SUBID 0x01 | 112 | #define HIDPP_ERROR_INVALID_SUBID 0x01 |
| @@ -119,6 +121,8 @@ struct hidpp_device { | |||
| 119 | #define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a | 121 | #define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a |
| 120 | #define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b | 122 | #define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b |
| 121 | #define HIDPP_ERROR_WRONG_PIN_CODE 0x0c | 123 | #define HIDPP_ERROR_WRONG_PIN_CODE 0x0c |
| 124 | /* HID++ 2.0 error codes */ | ||
| 125 | #define HIDPP20_ERROR 0xff | ||
| 122 | 126 | ||
| 123 | static void hidpp_connect_event(struct hidpp_device *hidpp_dev); | 127 | static void hidpp_connect_event(struct hidpp_device *hidpp_dev); |
| 124 | 128 | ||
| @@ -192,9 +196,16 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, | |||
| 192 | } | 196 | } |
| 193 | 197 | ||
| 194 | if (response->report_id == REPORT_ID_HIDPP_SHORT && | 198 | if (response->report_id == REPORT_ID_HIDPP_SHORT && |
| 195 | response->fap.feature_index == HIDPP_ERROR) { | 199 | response->rap.sub_id == HIDPP_ERROR) { |
| 200 | ret = response->rap.params[1]; | ||
| 201 | dbg_hid("%s:got hidpp error %02X\n", __func__, ret); | ||
| 202 | goto exit; | ||
| 203 | } | ||
| 204 | |||
| 205 | if (response->report_id == REPORT_ID_HIDPP_LONG && | ||
| 206 | response->fap.feature_index == HIDPP20_ERROR) { | ||
| 196 | ret = response->fap.params[1]; | 207 | ret = response->fap.params[1]; |
| 197 | dbg_hid("__hidpp_send_report got hidpp error %02X\n", ret); | 208 | dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret); |
| 198 | goto exit; | 209 | goto exit; |
| 199 | } | 210 | } |
| 200 | 211 | ||
| @@ -271,7 +282,8 @@ static inline bool hidpp_match_answer(struct hidpp_report *question, | |||
| 271 | static inline bool hidpp_match_error(struct hidpp_report *question, | 282 | static inline bool hidpp_match_error(struct hidpp_report *question, |
| 272 | struct hidpp_report *answer) | 283 | struct hidpp_report *answer) |
| 273 | { | 284 | { |
| 274 | return (answer->fap.feature_index == HIDPP_ERROR) && | 285 | return ((answer->rap.sub_id == HIDPP_ERROR) || |
| 286 | (answer->fap.feature_index == HIDPP20_ERROR)) && | ||
| 275 | (answer->fap.funcindex_clientid == question->fap.feature_index) && | 287 | (answer->fap.funcindex_clientid == question->fap.feature_index) && |
| 276 | (answer->fap.params[0] == question->fap.funcindex_clientid); | 288 | (answer->fap.params[0] == question->fap.funcindex_clientid); |
| 277 | } | 289 | } |
| @@ -903,24 +915,24 @@ static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 903 | return 0; | 915 | return 0; |
| 904 | }; | 916 | }; |
| 905 | 917 | ||
| 906 | static void wtp_connect(struct hid_device *hdev, bool connected) | 918 | static int wtp_connect(struct hid_device *hdev, bool connected) |
| 907 | { | 919 | { |
| 908 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | 920 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); |
| 909 | struct wtp_data *wd = hidpp->private_data; | 921 | struct wtp_data *wd = hidpp->private_data; |
| 910 | int ret; | 922 | int ret; |
| 911 | 923 | ||
| 912 | if (!connected) | 924 | if (!connected) |
| 913 | return; | 925 | return 0; |
| 914 | 926 | ||
| 915 | if (!wd->x_size) { | 927 | if (!wd->x_size) { |
| 916 | ret = wtp_get_config(hidpp); | 928 | ret = wtp_get_config(hidpp); |
| 917 | if (ret) { | 929 | if (ret) { |
| 918 | hid_err(hdev, "Can not get wtp config: %d\n", ret); | 930 | hid_err(hdev, "Can not get wtp config: %d\n", ret); |
| 919 | return; | 931 | return ret; |
| 920 | } | 932 | } |
| 921 | } | 933 | } |
| 922 | 934 | ||
| 923 | hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index, | 935 | return hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index, |
| 924 | true, true); | 936 | true, true); |
| 925 | } | 937 | } |
| 926 | 938 | ||
| @@ -965,7 +977,7 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | |||
| 965 | 977 | ||
| 966 | /* | 978 | /* |
| 967 | * If the mutex is locked then we have a pending answer from a | 979 | * If the mutex is locked then we have a pending answer from a |
| 968 | * previoulsly sent command | 980 | * previously sent command. |
| 969 | */ | 981 | */ |
| 970 | if (unlikely(mutex_is_locked(&hidpp->send_mutex))) { | 982 | if (unlikely(mutex_is_locked(&hidpp->send_mutex))) { |
| 971 | /* | 983 | /* |
| @@ -996,9 +1008,6 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | |||
| 996 | return 1; | 1008 | return 1; |
| 997 | } | 1009 | } |
| 998 | 1010 | ||
| 999 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | ||
| 1000 | return wtp_raw_event(hidpp->hid_dev, data, size); | ||
| 1001 | |||
| 1002 | return 0; | 1011 | return 0; |
| 1003 | } | 1012 | } |
| 1004 | 1013 | ||
| @@ -1006,7 +1015,9 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 1006 | u8 *data, int size) | 1015 | u8 *data, int size) |
| 1007 | { | 1016 | { |
| 1008 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | 1017 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); |
| 1018 | int ret = 0; | ||
| 1009 | 1019 | ||
| 1020 | /* Generic HID++ processing. */ | ||
| 1010 | switch (data[0]) { | 1021 | switch (data[0]) { |
| 1011 | case REPORT_ID_HIDPP_LONG: | 1022 | case REPORT_ID_HIDPP_LONG: |
| 1012 | if (size != HIDPP_REPORT_LONG_LENGTH) { | 1023 | if (size != HIDPP_REPORT_LONG_LENGTH) { |
| @@ -1014,16 +1025,23 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 1014 | size); | 1025 | size); |
| 1015 | return 1; | 1026 | return 1; |
| 1016 | } | 1027 | } |
| 1017 | return hidpp_raw_hidpp_event(hidpp, data, size); | 1028 | ret = hidpp_raw_hidpp_event(hidpp, data, size); |
| 1029 | break; | ||
| 1018 | case REPORT_ID_HIDPP_SHORT: | 1030 | case REPORT_ID_HIDPP_SHORT: |
| 1019 | if (size != HIDPP_REPORT_SHORT_LENGTH) { | 1031 | if (size != HIDPP_REPORT_SHORT_LENGTH) { |
| 1020 | hid_err(hdev, "received hid++ report of bad size (%d)", | 1032 | hid_err(hdev, "received hid++ report of bad size (%d)", |
| 1021 | size); | 1033 | size); |
| 1022 | return 1; | 1034 | return 1; |
| 1023 | } | 1035 | } |
| 1024 | return hidpp_raw_hidpp_event(hidpp, data, size); | 1036 | ret = hidpp_raw_hidpp_event(hidpp, data, size); |
| 1037 | break; | ||
| 1025 | } | 1038 | } |
| 1026 | 1039 | ||
| 1040 | /* If no report is available for further processing, skip calling | ||
| 1041 | * raw_event of subclasses. */ | ||
| 1042 | if (ret != 0) | ||
| 1043 | return ret; | ||
| 1044 | |||
| 1027 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | 1045 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) |
| 1028 | return wtp_raw_event(hdev, data, size); | 1046 | return wtp_raw_event(hdev, data, size); |
| 1029 | 1047 | ||
| @@ -1070,6 +1088,7 @@ static void hidpp_input_close(struct input_dev *dev) | |||
| 1070 | static struct input_dev *hidpp_allocate_input(struct hid_device *hdev) | 1088 | static struct input_dev *hidpp_allocate_input(struct hid_device *hdev) |
| 1071 | { | 1089 | { |
| 1072 | struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev); | 1090 | struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev); |
| 1091 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
| 1073 | 1092 | ||
| 1074 | if (!input_dev) | 1093 | if (!input_dev) |
| 1075 | return NULL; | 1094 | return NULL; |
| @@ -1078,7 +1097,7 @@ static struct input_dev *hidpp_allocate_input(struct hid_device *hdev) | |||
| 1078 | input_dev->open = hidpp_input_open; | 1097 | input_dev->open = hidpp_input_open; |
| 1079 | input_dev->close = hidpp_input_close; | 1098 | input_dev->close = hidpp_input_close; |
| 1080 | 1099 | ||
| 1081 | input_dev->name = hdev->name; | 1100 | input_dev->name = hidpp->name; |
| 1082 | input_dev->phys = hdev->phys; | 1101 | input_dev->phys = hdev->phys; |
| 1083 | input_dev->uniq = hdev->uniq; | 1102 | input_dev->uniq = hdev->uniq; |
| 1084 | input_dev->id.bustype = hdev->bus; | 1103 | input_dev->id.bustype = hdev->bus; |
| @@ -1098,8 +1117,11 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
| 1098 | struct input_dev *input; | 1117 | struct input_dev *input; |
| 1099 | char *name, *devm_name; | 1118 | char *name, *devm_name; |
| 1100 | 1119 | ||
| 1101 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) | 1120 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { |
| 1102 | wtp_connect(hdev, connected); | 1121 | ret = wtp_connect(hdev, connected); |
| 1122 | if (ret) | ||
| 1123 | return; | ||
| 1124 | } | ||
| 1103 | 1125 | ||
| 1104 | if (!connected || hidpp->delayed_input) | 1126 | if (!connected || hidpp->delayed_input) |
| 1105 | return; | 1127 | return; |
| @@ -1117,22 +1139,28 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
| 1117 | hid_info(hdev, "HID++ %u.%u device connected.\n", | 1139 | hid_info(hdev, "HID++ %u.%u device connected.\n", |
| 1118 | hidpp->protocol_major, hidpp->protocol_minor); | 1140 | hidpp->protocol_major, hidpp->protocol_minor); |
| 1119 | 1141 | ||
| 1142 | if (!hidpp->name || hidpp->name == hdev->name) { | ||
| 1143 | name = hidpp_get_device_name(hidpp); | ||
| 1144 | if (!name) { | ||
| 1145 | hid_err(hdev, | ||
| 1146 | "unable to retrieve the name of the device"); | ||
| 1147 | return; | ||
| 1148 | } | ||
| 1149 | |||
| 1150 | devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name); | ||
| 1151 | kfree(name); | ||
| 1152 | if (!devm_name) | ||
| 1153 | return; | ||
| 1154 | |||
| 1155 | hidpp->name = devm_name; | ||
| 1156 | } | ||
| 1157 | |||
| 1120 | input = hidpp_allocate_input(hdev); | 1158 | input = hidpp_allocate_input(hdev); |
| 1121 | if (!input) { | 1159 | if (!input) { |
| 1122 | hid_err(hdev, "cannot allocate new input device: %d\n", ret); | 1160 | hid_err(hdev, "cannot allocate new input device: %d\n", ret); |
| 1123 | return; | 1161 | return; |
| 1124 | } | 1162 | } |
| 1125 | 1163 | ||
| 1126 | name = hidpp_get_device_name(hidpp); | ||
| 1127 | if (!name) { | ||
| 1128 | hid_err(hdev, "unable to retrieve the name of the device"); | ||
| 1129 | } else { | ||
| 1130 | devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name); | ||
| 1131 | if (devm_name) | ||
| 1132 | input->name = devm_name; | ||
| 1133 | kfree(name); | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | hidpp_populate_input(hidpp, input, false); | 1164 | hidpp_populate_input(hidpp, input, false); |
| 1137 | 1165 | ||
| 1138 | ret = input_register_device(input); | 1166 | ret = input_register_device(input); |
| @@ -1155,6 +1183,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1155 | return -ENOMEM; | 1183 | return -ENOMEM; |
| 1156 | 1184 | ||
| 1157 | hidpp->hid_dev = hdev; | 1185 | hidpp->hid_dev = hdev; |
| 1186 | hidpp->name = hdev->name; | ||
| 1158 | hid_set_drvdata(hdev, hidpp); | 1187 | hid_set_drvdata(hdev, hidpp); |
| 1159 | 1188 | ||
| 1160 | hidpp->quirks = id->driver_data; | 1189 | hidpp->quirks = id->driver_data; |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index cacda43f6a6f..fbaea6eb882e 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
| @@ -276,6 +276,8 @@ static const struct hid_device_id ms_devices[] = { | |||
| 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), | 277 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), |
| 278 | .driver_data = MS_HIDINPUT }, | 278 | .driver_data = MS_HIDINPUT }, |
| 279 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP), | ||
| 280 | .driver_data = MS_HIDINPUT }, | ||
| 279 | 281 | ||
| 280 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), | 282 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), |
| 281 | .driver_data = MS_PRESENTER }, | 283 | .driver_data = MS_PRESENTER }, |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index b51200fe2f33..49d4fe4f5987 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
| @@ -33,6 +33,10 @@ | |||
| 33 | #define RMI_READ_DATA_PENDING BIT(1) | 33 | #define RMI_READ_DATA_PENDING BIT(1) |
| 34 | #define RMI_STARTED BIT(2) | 34 | #define RMI_STARTED BIT(2) |
| 35 | 35 | ||
| 36 | /* device flags */ | ||
| 37 | #define RMI_DEVICE BIT(0) | ||
| 38 | #define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1) | ||
| 39 | |||
| 36 | enum rmi_mode_type { | 40 | enum rmi_mode_type { |
| 37 | RMI_MODE_OFF = 0, | 41 | RMI_MODE_OFF = 0, |
| 38 | RMI_MODE_ATTN_REPORTS = 1, | 42 | RMI_MODE_ATTN_REPORTS = 1, |
| @@ -118,6 +122,8 @@ struct rmi_data { | |||
| 118 | 122 | ||
| 119 | struct work_struct reset_work; | 123 | struct work_struct reset_work; |
| 120 | struct hid_device *hdev; | 124 | struct hid_device *hdev; |
| 125 | |||
| 126 | unsigned long device_flags; | ||
| 121 | }; | 127 | }; |
| 122 | 128 | ||
| 123 | #define RMI_PAGE(addr) (((addr) >> 8) & 0xff) | 129 | #define RMI_PAGE(addr) (((addr) >> 8) & 0xff) |
| @@ -452,9 +458,32 @@ static int rmi_raw_event(struct hid_device *hdev, | |||
| 452 | return rmi_read_data_event(hdev, data, size); | 458 | return rmi_read_data_event(hdev, data, size); |
| 453 | case RMI_ATTN_REPORT_ID: | 459 | case RMI_ATTN_REPORT_ID: |
| 454 | return rmi_input_event(hdev, data, size); | 460 | return rmi_input_event(hdev, data, size); |
| 455 | case RMI_MOUSE_REPORT_ID: | 461 | default: |
| 462 | return 1; | ||
| 463 | } | ||
| 464 | |||
| 465 | return 0; | ||
| 466 | } | ||
| 467 | |||
| 468 | static int rmi_event(struct hid_device *hdev, struct hid_field *field, | ||
| 469 | struct hid_usage *usage, __s32 value) | ||
| 470 | { | ||
| 471 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
| 472 | |||
| 473 | if ((data->device_flags & RMI_DEVICE) && | ||
| 474 | (field->application == HID_GD_POINTER || | ||
| 475 | field->application == HID_GD_MOUSE)) { | ||
| 476 | if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) { | ||
| 477 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) | ||
| 478 | return 0; | ||
| 479 | |||
| 480 | if ((usage->hid == HID_GD_X || usage->hid == HID_GD_Y) | ||
| 481 | && !value) | ||
| 482 | return 1; | ||
| 483 | } | ||
| 484 | |||
| 456 | rmi_schedule_reset(hdev); | 485 | rmi_schedule_reset(hdev); |
| 457 | break; | 486 | return 1; |
| 458 | } | 487 | } |
| 459 | 488 | ||
| 460 | return 0; | 489 | return 0; |
| @@ -856,6 +885,9 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi) | |||
| 856 | if (ret) | 885 | if (ret) |
| 857 | return; | 886 | return; |
| 858 | 887 | ||
| 888 | if (!(data->device_flags & RMI_DEVICE)) | ||
| 889 | return; | ||
| 890 | |||
| 859 | /* Allow incoming hid reports */ | 891 | /* Allow incoming hid reports */ |
| 860 | hid_device_io_start(hdev); | 892 | hid_device_io_start(hdev); |
| 861 | 893 | ||
| @@ -914,8 +946,38 @@ static int rmi_input_mapping(struct hid_device *hdev, | |||
| 914 | struct hid_input *hi, struct hid_field *field, | 946 | struct hid_input *hi, struct hid_field *field, |
| 915 | struct hid_usage *usage, unsigned long **bit, int *max) | 947 | struct hid_usage *usage, unsigned long **bit, int *max) |
| 916 | { | 948 | { |
| 917 | /* we want to make HID ignore the advertised HID collection */ | 949 | struct rmi_data *data = hid_get_drvdata(hdev); |
| 918 | return -1; | 950 | |
| 951 | /* | ||
| 952 | * we want to make HID ignore the advertised HID collection | ||
| 953 | * for RMI deivces | ||
| 954 | */ | ||
| 955 | if (data->device_flags & RMI_DEVICE) { | ||
| 956 | if ((data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) && | ||
| 957 | ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)) | ||
| 958 | return 0; | ||
| 959 | |||
| 960 | return -1; | ||
| 961 | } | ||
| 962 | |||
| 963 | return 0; | ||
| 964 | } | ||
| 965 | |||
| 966 | static int rmi_check_valid_report_id(struct hid_device *hdev, unsigned type, | ||
| 967 | unsigned id, struct hid_report **report) | ||
| 968 | { | ||
| 969 | int i; | ||
| 970 | |||
| 971 | *report = hdev->report_enum[type].report_id_hash[id]; | ||
| 972 | if (*report) { | ||
| 973 | for (i = 0; i < (*report)->maxfield; i++) { | ||
| 974 | unsigned app = (*report)->field[i]->application; | ||
| 975 | if ((app & HID_USAGE_PAGE) >= HID_UP_MSVENDOR) | ||
| 976 | return 1; | ||
| 977 | } | ||
| 978 | } | ||
| 979 | |||
| 980 | return 0; | ||
| 919 | } | 981 | } |
| 920 | 982 | ||
| 921 | static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | 983 | static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| @@ -925,6 +987,7 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 925 | size_t alloc_size; | 987 | size_t alloc_size; |
| 926 | struct hid_report *input_report; | 988 | struct hid_report *input_report; |
| 927 | struct hid_report *output_report; | 989 | struct hid_report *output_report; |
| 990 | struct hid_report *feature_report; | ||
| 928 | 991 | ||
| 929 | data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL); | 992 | data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL); |
| 930 | if (!data) | 993 | if (!data) |
| @@ -943,27 +1006,37 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 943 | return ret; | 1006 | return ret; |
| 944 | } | 1007 | } |
| 945 | 1008 | ||
| 946 | input_report = hdev->report_enum[HID_INPUT_REPORT] | 1009 | if (id->driver_data) |
| 947 | .report_id_hash[RMI_ATTN_REPORT_ID]; | 1010 | data->device_flags = id->driver_data; |
| 948 | if (!input_report) { | 1011 | |
| 949 | hid_err(hdev, "device does not have expected input report\n"); | 1012 | /* |
| 950 | ret = -ENODEV; | 1013 | * Check for the RMI specific report ids. If they are misisng |
| 951 | return ret; | 1014 | * simply return and let the events be processed by hid-input |
| 1015 | */ | ||
| 1016 | if (!rmi_check_valid_report_id(hdev, HID_FEATURE_REPORT, | ||
| 1017 | RMI_SET_RMI_MODE_REPORT_ID, &feature_report)) { | ||
| 1018 | hid_dbg(hdev, "device does not have set mode feature report\n"); | ||
| 1019 | goto start; | ||
| 952 | } | 1020 | } |
| 953 | 1021 | ||
| 954 | data->input_report_size = (input_report->size >> 3) + 1 /* report id */; | 1022 | if (!rmi_check_valid_report_id(hdev, HID_INPUT_REPORT, |
| 1023 | RMI_ATTN_REPORT_ID, &input_report)) { | ||
| 1024 | hid_dbg(hdev, "device does not have attention input report\n"); | ||
| 1025 | goto start; | ||
| 1026 | } | ||
| 955 | 1027 | ||
| 956 | output_report = hdev->report_enum[HID_OUTPUT_REPORT] | 1028 | data->input_report_size = hid_report_len(input_report); |
| 957 | .report_id_hash[RMI_WRITE_REPORT_ID]; | 1029 | |
| 958 | if (!output_report) { | 1030 | if (!rmi_check_valid_report_id(hdev, HID_OUTPUT_REPORT, |
| 959 | hid_err(hdev, "device does not have expected output report\n"); | 1031 | RMI_WRITE_REPORT_ID, &output_report)) { |
| 960 | ret = -ENODEV; | 1032 | hid_dbg(hdev, |
| 961 | return ret; | 1033 | "device does not have rmi write output report\n"); |
| 1034 | goto start; | ||
| 962 | } | 1035 | } |
| 963 | 1036 | ||
| 964 | data->output_report_size = (output_report->size >> 3) | 1037 | data->output_report_size = hid_report_len(output_report); |
| 965 | + 1 /* report id */; | ||
| 966 | 1038 | ||
| 1039 | data->device_flags |= RMI_DEVICE; | ||
| 967 | alloc_size = data->output_report_size + data->input_report_size; | 1040 | alloc_size = data->output_report_size + data->input_report_size; |
| 968 | 1041 | ||
| 969 | data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL); | 1042 | data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL); |
| @@ -978,13 +1051,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 978 | 1051 | ||
| 979 | mutex_init(&data->page_mutex); | 1052 | mutex_init(&data->page_mutex); |
| 980 | 1053 | ||
| 1054 | start: | ||
| 981 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 1055 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
| 982 | if (ret) { | 1056 | if (ret) { |
| 983 | hid_err(hdev, "hw start failed\n"); | 1057 | hid_err(hdev, "hw start failed\n"); |
| 984 | return ret; | 1058 | return ret; |
| 985 | } | 1059 | } |
| 986 | 1060 | ||
| 987 | if (!test_bit(RMI_STARTED, &data->flags)) | 1061 | if ((data->device_flags & RMI_DEVICE) && |
| 1062 | !test_bit(RMI_STARTED, &data->flags)) | ||
| 988 | /* | 1063 | /* |
| 989 | * The device maybe in the bootloader if rmi_input_configured | 1064 | * The device maybe in the bootloader if rmi_input_configured |
| 990 | * failed to find F11 in the PDT. Print an error, but don't | 1065 | * failed to find F11 in the PDT. Print an error, but don't |
| @@ -1007,6 +1082,8 @@ static void rmi_remove(struct hid_device *hdev) | |||
| 1007 | } | 1082 | } |
| 1008 | 1083 | ||
| 1009 | static const struct hid_device_id rmi_id[] = { | 1084 | static const struct hid_device_id rmi_id[] = { |
| 1085 | { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14), | ||
| 1086 | .driver_data = RMI_DEVICE_HAS_PHYS_BUTTONS }, | ||
| 1010 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) }, | 1087 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) }, |
| 1011 | { } | 1088 | { } |
| 1012 | }; | 1089 | }; |
| @@ -1017,6 +1094,7 @@ static struct hid_driver rmi_driver = { | |||
| 1017 | .id_table = rmi_id, | 1094 | .id_table = rmi_id, |
| 1018 | .probe = rmi_probe, | 1095 | .probe = rmi_probe, |
| 1019 | .remove = rmi_remove, | 1096 | .remove = rmi_remove, |
| 1097 | .event = rmi_event, | ||
| 1020 | .raw_event = rmi_raw_event, | 1098 | .raw_event = rmi_raw_event, |
| 1021 | .input_mapping = rmi_input_mapping, | 1099 | .input_mapping = rmi_input_mapping, |
| 1022 | .input_configured = rmi_input_configured, | 1100 | .input_configured = rmi_input_configured, |
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile index db3cf31c6fa1..890f2914a8ff 100644 --- a/drivers/hid/usbhid/Makefile +++ b/drivers/hid/usbhid/Makefile | |||
| @@ -2,17 +2,9 @@ | |||
| 2 | # Makefile for the USB input drivers | 2 | # Makefile for the USB input drivers |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | # Multipart objects. | ||
| 6 | usbhid-y := hid-core.o hid-quirks.o | 5 | usbhid-y := hid-core.o hid-quirks.o |
| 7 | 6 | usbhid-$(CONFIG_USB_HIDDEV) += hiddev.o | |
| 8 | # Optional parts of multipart objects. | 7 | usbhid-$(CONFIG_HID_PID) += hid-pidff.o |
| 9 | |||
| 10 | ifeq ($(CONFIG_USB_HIDDEV),y) | ||
| 11 | usbhid-y += hiddev.o | ||
| 12 | endif | ||
| 13 | ifeq ($(CONFIG_HID_PID),y) | ||
| 14 | usbhid-y += hid-pidff.o | ||
| 15 | endif | ||
| 16 | 8 | ||
| 17 | obj-$(CONFIG_USB_HID) += usbhid.o | 9 | obj-$(CONFIG_USB_HID) += usbhid.o |
| 18 | obj-$(CONFIG_USB_KBD) += usbkbd.o | 10 | obj-$(CONFIG_USB_KBD) += usbkbd.o |
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index 10b616702780..0b531c6a76a5 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c | |||
| @@ -1252,6 +1252,8 @@ int hid_pidff_init(struct hid_device *hid) | |||
| 1252 | 1252 | ||
| 1253 | pidff->hid = hid; | 1253 | pidff->hid = hid; |
| 1254 | 1254 | ||
| 1255 | hid_device_io_start(hid); | ||
| 1256 | |||
| 1255 | pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff); | 1257 | pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff); |
| 1256 | pidff_find_reports(hid, HID_FEATURE_REPORT, pidff); | 1258 | pidff_find_reports(hid, HID_FEATURE_REPORT, pidff); |
| 1257 | 1259 | ||
| @@ -1315,9 +1317,13 @@ int hid_pidff_init(struct hid_device *hid) | |||
| 1315 | 1317 | ||
| 1316 | hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); | 1318 | hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); |
| 1317 | 1319 | ||
| 1320 | hid_device_io_stop(hid); | ||
| 1321 | |||
| 1318 | return 0; | 1322 | return 0; |
| 1319 | 1323 | ||
| 1320 | fail: | 1324 | fail: |
| 1325 | hid_device_io_stop(hid); | ||
| 1326 | |||
| 1321 | kfree(pidff); | 1327 | kfree(pidff); |
| 1322 | return error; | 1328 | return error; |
| 1323 | } | 1329 | } |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index b27b3d33ebab..9be99a67bfe2 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
| @@ -80,6 +80,7 @@ static const struct hid_blacklist { | |||
| 80 | { 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 }, |
| 81 | { 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 }, | 82 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, |
| 83 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS }, | ||
| 83 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, | 84 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, |
| 84 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, | 85 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, |
| 85 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, | 86 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 654202941d30..f0568a7e6de9 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
| @@ -173,10 +173,8 @@ static void wacom_usage_mapping(struct hid_device *hdev, | |||
| 173 | { | 173 | { |
| 174 | struct wacom *wacom = hid_get_drvdata(hdev); | 174 | struct wacom *wacom = hid_get_drvdata(hdev); |
| 175 | struct wacom_features *features = &wacom->wacom_wac.features; | 175 | struct wacom_features *features = &wacom->wacom_wac.features; |
| 176 | bool finger = (field->logical == HID_DG_FINGER) || | 176 | bool finger = WACOM_FINGER_FIELD(field); |
| 177 | (field->physical == HID_DG_FINGER); | 177 | bool pen = WACOM_PEN_FIELD(field); |
| 178 | bool pen = (field->logical == HID_DG_STYLUS) || | ||
| 179 | (field->physical == HID_DG_STYLUS); | ||
| 180 | 178 | ||
| 181 | /* | 179 | /* |
| 182 | * Requiring Stylus Usage will ignore boot mouse | 180 | * Requiring Stylus Usage will ignore boot mouse |
| @@ -405,6 +403,9 @@ static int wacom_query_tablet_data(struct hid_device *hdev, | |||
| 405 | else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { | 403 | else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { |
| 406 | return wacom_set_device_mode(hdev, 18, 3, 2); | 404 | return wacom_set_device_mode(hdev, 18, 3, 2); |
| 407 | } | 405 | } |
| 406 | else if (features->type == WACOM_27QHDT) { | ||
| 407 | return wacom_set_device_mode(hdev, 131, 3, 2); | ||
| 408 | } | ||
| 408 | } else if (features->device_type == BTN_TOOL_PEN) { | 409 | } else if (features->device_type == BTN_TOOL_PEN) { |
| 409 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { | 410 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { |
| 410 | return wacom_set_device_mode(hdev, 2, 2, 2); | 411 | return wacom_set_device_mode(hdev, 2, 2, 2); |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ac7447c7b82e..1a6507999a65 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
| 16 | #include "wacom.h" | 16 | #include "wacom.h" |
| 17 | #include <linux/input/mt.h> | 17 | #include <linux/input/mt.h> |
| 18 | #include <linux/hid.h> | ||
| 19 | 18 | ||
| 20 | /* resolution for penabled devices */ | 19 | /* resolution for penabled devices */ |
| 21 | #define WACOM_PL_RES 20 | 20 | #define WACOM_PL_RES 20 |
| @@ -444,9 +443,6 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 444 | 443 | ||
| 445 | /* Enter report */ | 444 | /* Enter report */ |
| 446 | if ((data[1] & 0xfc) == 0xc0) { | 445 | if ((data[1] & 0xfc) == 0xc0) { |
| 447 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) | ||
| 448 | wacom->shared->stylus_in_proximity = true; | ||
| 449 | |||
| 450 | /* serial number of the tool */ | 446 | /* serial number of the tool */ |
| 451 | wacom->serial[idx] = ((data[3] & 0x0f) << 28) + | 447 | wacom->serial[idx] = ((data[3] & 0x0f) << 28) + |
| 452 | (data[4] << 20) + (data[5] << 12) + | 448 | (data[4] << 20) + (data[5] << 12) + |
| @@ -535,24 +531,46 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 535 | return 1; | 531 | return 1; |
| 536 | } | 532 | } |
| 537 | 533 | ||
| 534 | /* | ||
| 535 | * don't report events for invalid data | ||
| 536 | */ | ||
| 538 | /* older I4 styli don't work with new Cintiqs */ | 537 | /* older I4 styli don't work with new Cintiqs */ |
| 539 | if (!((wacom->id[idx] >> 20) & 0x01) && | 538 | if ((!((wacom->id[idx] >> 20) & 0x01) && |
| 540 | (features->type == WACOM_21UX2)) | 539 | (features->type == WACOM_21UX2)) || |
| 540 | /* Only large Intuos support Lense Cursor */ | ||
| 541 | (wacom->tool[idx] == BTN_TOOL_LENS && | ||
| 542 | (features->type == INTUOS3 || | ||
| 543 | features->type == INTUOS3S || | ||
| 544 | features->type == INTUOS4 || | ||
| 545 | features->type == INTUOS4S || | ||
| 546 | features->type == INTUOS5 || | ||
| 547 | features->type == INTUOS5S || | ||
| 548 | features->type == INTUOSPM || | ||
| 549 | features->type == INTUOSPS)) || | ||
| 550 | /* Cintiq doesn't send data when RDY bit isn't set */ | ||
| 551 | (features->type == CINTIQ && !(data[1] & 0x40))) | ||
| 541 | return 1; | 552 | return 1; |
| 542 | 553 | ||
| 543 | /* Range Report */ | 554 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) |
| 544 | if ((data[1] & 0xfe) == 0x20) { | 555 | wacom->shared->stylus_in_proximity = true; |
| 556 | |||
| 557 | /* in Range while exiting */ | ||
| 558 | if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) { | ||
| 545 | input_report_key(input, BTN_TOUCH, 0); | 559 | input_report_key(input, BTN_TOUCH, 0); |
| 546 | input_report_abs(input, ABS_PRESSURE, 0); | 560 | input_report_abs(input, ABS_PRESSURE, 0); |
| 547 | input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); | 561 | input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); |
| 548 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) | 562 | return 2; |
| 549 | wacom->shared->stylus_in_proximity = true; | ||
| 550 | } | 563 | } |
| 551 | 564 | ||
| 552 | /* Exit report */ | 565 | /* Exit report */ |
| 553 | if ((data[1] & 0xfe) == 0x80) { | 566 | if ((data[1] & 0xfe) == 0x80) { |
| 554 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) | 567 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) |
| 555 | wacom->shared->stylus_in_proximity = false; | 568 | wacom->shared->stylus_in_proximity = false; |
| 569 | wacom->reporting_data = false; | ||
| 570 | |||
| 571 | /* don't report exit if we don't know the ID */ | ||
| 572 | if (!wacom->id[idx]) | ||
| 573 | return 1; | ||
| 556 | 574 | ||
| 557 | /* | 575 | /* |
| 558 | * Reset all states otherwise we lose the initial states | 576 | * Reset all states otherwise we lose the initial states |
| @@ -586,6 +604,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 586 | wacom->id[idx] = 0; | 604 | wacom->id[idx] = 0; |
| 587 | return 2; | 605 | return 2; |
| 588 | } | 606 | } |
| 607 | |||
| 608 | /* don't report other events if we don't know the ID */ | ||
| 609 | if (!wacom->id[idx]) | ||
| 610 | return 1; | ||
| 611 | |||
| 589 | return 0; | 612 | return 0; |
| 590 | } | 613 | } |
| 591 | 614 | ||
| @@ -633,6 +656,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 633 | data[0] != WACOM_REPORT_INTUOSREAD && | 656 | data[0] != WACOM_REPORT_INTUOSREAD && |
| 634 | data[0] != WACOM_REPORT_INTUOSWRITE && | 657 | data[0] != WACOM_REPORT_INTUOSWRITE && |
| 635 | data[0] != WACOM_REPORT_INTUOSPAD && | 658 | data[0] != WACOM_REPORT_INTUOSPAD && |
| 659 | data[0] != WACOM_REPORT_CINTIQ && | ||
| 660 | data[0] != WACOM_REPORT_CINTIQPAD && | ||
| 636 | data[0] != WACOM_REPORT_INTUOS5PAD) { | 661 | data[0] != WACOM_REPORT_INTUOS5PAD) { |
| 637 | dev_dbg(input->dev.parent, | 662 | dev_dbg(input->dev.parent, |
| 638 | "%s: received unknown report #%d\n", __func__, data[0]); | 663 | "%s: received unknown report #%d\n", __func__, data[0]); |
| @@ -644,7 +669,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 644 | idx = data[1] & 0x01; | 669 | idx = data[1] & 0x01; |
| 645 | 670 | ||
| 646 | /* pad packets. Works as a second tool and is always in prox */ | 671 | /* pad packets. Works as a second tool and is always in prox */ |
| 647 | if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD) { | 672 | if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || |
| 673 | data[0] == WACOM_REPORT_CINTIQPAD) { | ||
| 648 | input = wacom->pad_input; | 674 | input = wacom->pad_input; |
| 649 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { | 675 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
| 650 | input_report_key(input, BTN_0, (data[2] & 0x01)); | 676 | input_report_key(input, BTN_0, (data[2] & 0x01)); |
| @@ -744,6 +770,14 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 744 | } else { | 770 | } else { |
| 745 | input_report_abs(input, ABS_MISC, 0); | 771 | input_report_abs(input, ABS_MISC, 0); |
| 746 | } | 772 | } |
| 773 | } else if (features->type == WACOM_27QHD) { | ||
| 774 | input_report_key(input, KEY_PROG1, data[2] & 0x01); | ||
| 775 | input_report_key(input, KEY_PROG2, data[2] & 0x02); | ||
| 776 | input_report_key(input, KEY_PROG3, data[2] & 0x04); | ||
| 777 | |||
| 778 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); | ||
| 779 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); | ||
| 780 | input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); | ||
| 747 | } else if (features->type == CINTIQ_HYBRID) { | 781 | } else if (features->type == CINTIQ_HYBRID) { |
| 748 | /* | 782 | /* |
| 749 | * Do not send hardware buttons under Android. They | 783 | * Do not send hardware buttons under Android. They |
| @@ -760,6 +794,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 760 | input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ | 794 | input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ |
| 761 | input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ | 795 | input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ |
| 762 | input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ | 796 | input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ |
| 797 | |||
| 798 | if (data[4] | (data[3] & 0x01)) { | ||
| 799 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
| 800 | } else { | ||
| 801 | input_report_abs(input, ABS_MISC, 0); | ||
| 802 | } | ||
| 763 | } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { | 803 | } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { |
| 764 | int i; | 804 | int i; |
| 765 | 805 | ||
| @@ -843,28 +883,6 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 843 | if (result) | 883 | if (result) |
| 844 | return result - 1; | 884 | return result - 1; |
| 845 | 885 | ||
| 846 | /* don't proceed if we don't know the ID */ | ||
| 847 | if (!wacom->id[idx]) | ||
| 848 | return 0; | ||
| 849 | |||
| 850 | /* Only large Intuos support Lense Cursor */ | ||
| 851 | if (wacom->tool[idx] == BTN_TOOL_LENS && | ||
| 852 | (features->type == INTUOS3 || | ||
| 853 | features->type == INTUOS3S || | ||
| 854 | features->type == INTUOS4 || | ||
| 855 | features->type == INTUOS4S || | ||
| 856 | features->type == INTUOS5 || | ||
| 857 | features->type == INTUOS5S || | ||
| 858 | features->type == INTUOSPM || | ||
| 859 | features->type == INTUOSPS)) { | ||
| 860 | |||
| 861 | return 0; | ||
| 862 | } | ||
| 863 | |||
| 864 | /* Cintiq doesn't send data when RDY bit isn't set */ | ||
| 865 | if (features->type == CINTIQ && !(data[1] & 0x40)) | ||
| 866 | return 0; | ||
| 867 | |||
| 868 | if (features->type >= INTUOS3S) { | 886 | if (features->type >= INTUOS3S) { |
| 869 | input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); | 887 | input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); |
| 870 | input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); | 888 | input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); |
| @@ -951,6 +969,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 951 | input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */ | 969 | input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */ |
| 952 | input_report_key(input, wacom->tool[idx], 1); | 970 | input_report_key(input, wacom->tool[idx], 1); |
| 953 | input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 971 | input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
| 972 | wacom->reporting_data = true; | ||
| 954 | return 1; | 973 | return 1; |
| 955 | } | 974 | } |
| 956 | 975 | ||
| @@ -1019,8 +1038,20 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1019 | struct input_dev *input = wacom->input; | 1038 | struct input_dev *input = wacom->input; |
| 1020 | unsigned char *data = wacom->data; | 1039 | unsigned char *data = wacom->data; |
| 1021 | int i; | 1040 | int i; |
| 1022 | int current_num_contacts = data[61]; | 1041 | int current_num_contacts = 0; |
| 1023 | int contacts_to_send = 0; | 1042 | int contacts_to_send = 0; |
| 1043 | int num_contacts_left = 4; /* maximum contacts per packet */ | ||
| 1044 | int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET; | ||
| 1045 | int y_offset = 2; | ||
| 1046 | |||
| 1047 | if (wacom->features.type == WACOM_27QHDT) { | ||
| 1048 | current_num_contacts = data[63]; | ||
| 1049 | num_contacts_left = 10; | ||
| 1050 | byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET; | ||
| 1051 | y_offset = 0; | ||
| 1052 | } else { | ||
| 1053 | current_num_contacts = data[61]; | ||
| 1054 | } | ||
| 1024 | 1055 | ||
| 1025 | /* | 1056 | /* |
| 1026 | * First packet resets the counter since only the first | 1057 | * First packet resets the counter since only the first |
| @@ -1029,12 +1060,11 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1029 | if (current_num_contacts) | 1060 | if (current_num_contacts) |
| 1030 | wacom->num_contacts_left = current_num_contacts; | 1061 | wacom->num_contacts_left = current_num_contacts; |
| 1031 | 1062 | ||
| 1032 | /* There are at most 4 contacts per packet */ | 1063 | contacts_to_send = min(num_contacts_left, wacom->num_contacts_left); |
| 1033 | contacts_to_send = min(4, wacom->num_contacts_left); | ||
| 1034 | 1064 | ||
| 1035 | for (i = 0; i < contacts_to_send; i++) { | 1065 | for (i = 0; i < contacts_to_send; i++) { |
| 1036 | int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; | 1066 | int offset = (byte_per_packet * i) + 1; |
| 1037 | bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; | 1067 | bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; |
| 1038 | int slot = input_mt_get_slot_by_key(input, data[offset + 1]); | 1068 | int slot = input_mt_get_slot_by_key(input, data[offset + 1]); |
| 1039 | 1069 | ||
| 1040 | if (slot < 0) | 1070 | if (slot < 0) |
| @@ -1044,18 +1074,23 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1044 | 1074 | ||
| 1045 | if (touch) { | 1075 | if (touch) { |
| 1046 | int t_x = get_unaligned_le16(&data[offset + 2]); | 1076 | int t_x = get_unaligned_le16(&data[offset + 2]); |
| 1047 | int c_x = get_unaligned_le16(&data[offset + 4]); | 1077 | int t_y = get_unaligned_le16(&data[offset + 4 + y_offset]); |
| 1048 | int t_y = get_unaligned_le16(&data[offset + 6]); | ||
| 1049 | int c_y = get_unaligned_le16(&data[offset + 8]); | ||
| 1050 | int w = get_unaligned_le16(&data[offset + 10]); | ||
| 1051 | int h = get_unaligned_le16(&data[offset + 12]); | ||
| 1052 | 1078 | ||
| 1053 | input_report_abs(input, ABS_MT_POSITION_X, t_x); | 1079 | input_report_abs(input, ABS_MT_POSITION_X, t_x); |
| 1054 | input_report_abs(input, ABS_MT_POSITION_Y, t_y); | 1080 | input_report_abs(input, ABS_MT_POSITION_Y, t_y); |
| 1055 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); | 1081 | |
| 1056 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y)); | 1082 | if (wacom->features.type != WACOM_27QHDT) { |
| 1057 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); | 1083 | int c_x = get_unaligned_le16(&data[offset + 4]); |
| 1058 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); | 1084 | int c_y = get_unaligned_le16(&data[offset + 8]); |
| 1085 | int w = get_unaligned_le16(&data[offset + 10]); | ||
| 1086 | int h = get_unaligned_le16(&data[offset + 12]); | ||
| 1087 | |||
| 1088 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); | ||
| 1089 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, | ||
| 1090 | min(w, h) + int_dist(t_x, t_y, c_x, c_y)); | ||
| 1091 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); | ||
| 1092 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); | ||
| 1093 | } | ||
| 1059 | } | 1094 | } |
| 1060 | } | 1095 | } |
| 1061 | input_mt_report_pointer_emulation(input, true); | 1096 | input_mt_report_pointer_emulation(input, true); |
| @@ -1064,6 +1099,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
| 1064 | if (wacom->num_contacts_left <= 0) | 1099 | if (wacom->num_contacts_left <= 0) |
| 1065 | wacom->num_contacts_left = 0; | 1100 | wacom->num_contacts_left = 0; |
| 1066 | 1101 | ||
| 1102 | wacom->shared->touch_down = (wacom->num_contacts_left > 0); | ||
| 1067 | return 1; | 1103 | return 1; |
| 1068 | } | 1104 | } |
| 1069 | 1105 | ||
| @@ -1092,7 +1128,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
| 1092 | 1128 | ||
| 1093 | for (i = 0; i < contacts_to_send; i++) { | 1129 | for (i = 0; i < contacts_to_send; i++) { |
| 1094 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; | 1130 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; |
| 1095 | bool touch = data[offset] & 0x1; | 1131 | bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; |
| 1096 | int id = get_unaligned_le16(&data[offset + 1]); | 1132 | int id = get_unaligned_le16(&data[offset + 1]); |
| 1097 | int slot = input_mt_get_slot_by_key(input, id); | 1133 | int slot = input_mt_get_slot_by_key(input, id); |
| 1098 | 1134 | ||
| @@ -1114,6 +1150,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
| 1114 | if (wacom->num_contacts_left < 0) | 1150 | if (wacom->num_contacts_left < 0) |
| 1115 | wacom->num_contacts_left = 0; | 1151 | wacom->num_contacts_left = 0; |
| 1116 | 1152 | ||
| 1153 | wacom->shared->touch_down = (wacom->num_contacts_left > 0); | ||
| 1117 | return 1; | 1154 | return 1; |
| 1118 | } | 1155 | } |
| 1119 | 1156 | ||
| @@ -1514,13 +1551,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev, | |||
| 1514 | wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev); | 1551 | wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev); |
| 1515 | } | 1552 | } |
| 1516 | 1553 | ||
| 1517 | #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ | ||
| 1518 | ((f)->physical == HID_DG_STYLUS) || \ | ||
| 1519 | ((f)->application == HID_DG_PEN)) | ||
| 1520 | #define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \ | ||
| 1521 | ((f)->physical == HID_DG_FINGER) || \ | ||
| 1522 | ((f)->application == HID_DG_TOUCHSCREEN)) | ||
| 1523 | |||
| 1524 | void wacom_wac_usage_mapping(struct hid_device *hdev, | 1554 | void wacom_wac_usage_mapping(struct hid_device *hdev, |
| 1525 | struct hid_field *field, struct hid_usage *usage) | 1555 | struct hid_field *field, struct hid_usage *usage) |
| 1526 | { | 1556 | { |
| @@ -1891,6 +1921,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
| 1891 | case WACOM_21UX2: | 1921 | case WACOM_21UX2: |
| 1892 | case WACOM_22HD: | 1922 | case WACOM_22HD: |
| 1893 | case WACOM_24HD: | 1923 | case WACOM_24HD: |
| 1924 | case WACOM_27QHD: | ||
| 1894 | case DTK: | 1925 | case DTK: |
| 1895 | case CINTIQ_HYBRID: | 1926 | case CINTIQ_HYBRID: |
| 1896 | sync = wacom_intuos_irq(wacom_wac); | 1927 | sync = wacom_intuos_irq(wacom_wac); |
| @@ -1901,6 +1932,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
| 1901 | break; | 1932 | break; |
| 1902 | 1933 | ||
| 1903 | case WACOM_24HDT: | 1934 | case WACOM_24HDT: |
| 1935 | case WACOM_27QHDT: | ||
| 1904 | sync = wacom_24hdt_irq(wacom_wac); | 1936 | sync = wacom_24hdt_irq(wacom_wac); |
| 1905 | break; | 1937 | break; |
| 1906 | 1938 | ||
| @@ -2086,32 +2118,17 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2086 | wacom_abs_set_axis(input_dev, wacom_wac); | 2118 | wacom_abs_set_axis(input_dev, wacom_wac); |
| 2087 | 2119 | ||
| 2088 | switch (features->type) { | 2120 | switch (features->type) { |
| 2089 | case WACOM_MO: | ||
| 2090 | case WACOM_G4: | ||
| 2091 | /* fall through */ | ||
| 2092 | |||
| 2093 | case GRAPHIRE: | ||
| 2094 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
| 2095 | |||
| 2096 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
| 2097 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
| 2098 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
| 2099 | |||
| 2100 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | ||
| 2101 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | ||
| 2102 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
| 2103 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
| 2104 | __set_bit(BTN_STYLUS2, input_dev->keybit); | ||
| 2105 | |||
| 2106 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
| 2107 | break; | ||
| 2108 | |||
| 2109 | case GRAPHIRE_BT: | 2121 | case GRAPHIRE_BT: |
| 2110 | __clear_bit(ABS_MISC, input_dev->absbit); | 2122 | __clear_bit(ABS_MISC, input_dev->absbit); |
| 2123 | |||
| 2124 | case WACOM_MO: | ||
| 2125 | case WACOM_G4: | ||
| 2111 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, | 2126 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, |
| 2112 | features->distance_max, | 2127 | features->distance_max, |
| 2113 | 0, 0); | 2128 | 0, 0); |
| 2129 | /* fall through */ | ||
| 2114 | 2130 | ||
| 2131 | case GRAPHIRE: | ||
| 2115 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | 2132 | input_set_capability(input_dev, EV_REL, REL_WHEEL); |
| 2116 | 2133 | ||
| 2117 | __set_bit(BTN_LEFT, input_dev->keybit); | 2134 | __set_bit(BTN_LEFT, input_dev->keybit); |
| @@ -2127,31 +2144,15 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2127 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 2144 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
| 2128 | break; | 2145 | break; |
| 2129 | 2146 | ||
| 2147 | case WACOM_27QHD: | ||
| 2130 | case WACOM_24HD: | 2148 | case WACOM_24HD: |
| 2131 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
| 2132 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
| 2133 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); | ||
| 2134 | /* fall through */ | ||
| 2135 | |||
| 2136 | case DTK: | 2149 | case DTK: |
| 2137 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | ||
| 2138 | |||
| 2139 | wacom_setup_cintiq(wacom_wac); | ||
| 2140 | break; | ||
| 2141 | |||
| 2142 | case WACOM_22HD: | 2150 | case WACOM_22HD: |
| 2143 | case WACOM_21UX2: | 2151 | case WACOM_21UX2: |
| 2144 | case WACOM_BEE: | 2152 | case WACOM_BEE: |
| 2145 | case CINTIQ: | 2153 | case CINTIQ: |
| 2146 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
| 2147 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
| 2148 | |||
| 2149 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | ||
| 2150 | |||
| 2151 | wacom_setup_cintiq(wacom_wac); | ||
| 2152 | break; | ||
| 2153 | |||
| 2154 | case WACOM_13HD: | 2154 | case WACOM_13HD: |
| 2155 | case CINTIQ_HYBRID: | ||
| 2155 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2156 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| 2156 | input_abs_set_res(input_dev, ABS_Z, 287); | 2157 | input_abs_set_res(input_dev, ABS_Z, 287); |
| 2157 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | 2158 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); |
| @@ -2161,6 +2162,10 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2161 | case INTUOS3: | 2162 | case INTUOS3: |
| 2162 | case INTUOS3L: | 2163 | case INTUOS3L: |
| 2163 | case INTUOS3S: | 2164 | case INTUOS3S: |
| 2165 | case INTUOS4: | ||
| 2166 | case INTUOS4WL: | ||
| 2167 | case INTUOS4L: | ||
| 2168 | case INTUOS4S: | ||
| 2164 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 2169 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| 2165 | input_abs_set_res(input_dev, ABS_Z, 287); | 2170 | input_abs_set_res(input_dev, ABS_Z, 287); |
| 2166 | /* fall through */ | 2171 | /* fall through */ |
| @@ -2199,17 +2204,6 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2199 | } | 2204 | } |
| 2200 | break; | 2205 | break; |
| 2201 | 2206 | ||
| 2202 | case INTUOS4: | ||
| 2203 | case INTUOS4WL: | ||
| 2204 | case INTUOS4L: | ||
| 2205 | case INTUOS4S: | ||
| 2206 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
| 2207 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
| 2208 | wacom_setup_intuos(wacom_wac); | ||
| 2209 | |||
| 2210 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
| 2211 | break; | ||
| 2212 | |||
| 2213 | case WACOM_24HDT: | 2207 | case WACOM_24HDT: |
| 2214 | if (features->device_type == BTN_TOOL_FINGER) { | 2208 | if (features->device_type == BTN_TOOL_FINGER) { |
| 2215 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); | 2209 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); |
| @@ -2219,6 +2213,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2219 | } | 2213 | } |
| 2220 | /* fall through */ | 2214 | /* fall through */ |
| 2221 | 2215 | ||
| 2216 | case WACOM_27QHDT: | ||
| 2222 | case MTSCREEN: | 2217 | case MTSCREEN: |
| 2223 | case MTTPC: | 2218 | case MTTPC: |
| 2224 | case MTTPC_B: | 2219 | case MTTPC_B: |
| @@ -2305,14 +2300,6 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
| 2305 | 0, 0); | 2300 | 0, 0); |
| 2306 | } | 2301 | } |
| 2307 | break; | 2302 | break; |
| 2308 | |||
| 2309 | case CINTIQ_HYBRID: | ||
| 2310 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
| 2311 | input_abs_set_res(input_dev, ABS_Z, 287); | ||
| 2312 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | ||
| 2313 | |||
| 2314 | wacom_setup_cintiq(wacom_wac); | ||
| 2315 | break; | ||
| 2316 | } | 2303 | } |
| 2317 | return 0; | 2304 | return 0; |
| 2318 | } | 2305 | } |
| @@ -2374,6 +2361,19 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
| 2374 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); | 2361 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); |
| 2375 | break; | 2362 | break; |
| 2376 | 2363 | ||
| 2364 | case WACOM_27QHD: | ||
| 2365 | __set_bit(KEY_PROG1, input_dev->keybit); | ||
| 2366 | __set_bit(KEY_PROG2, input_dev->keybit); | ||
| 2367 | __set_bit(KEY_PROG3, input_dev->keybit); | ||
| 2368 | input_set_abs_params(input_dev, ABS_X, -2048, 2048, 0, 0); | ||
| 2369 | input_abs_set_res(input_dev, ABS_X, 1024); /* points/g */ | ||
| 2370 | input_set_abs_params(input_dev, ABS_Y, -2048, 2048, 0, 0); | ||
| 2371 | input_abs_set_res(input_dev, ABS_Y, 1024); | ||
| 2372 | input_set_abs_params(input_dev, ABS_Z, -2048, 2048, 0, 0); | ||
| 2373 | input_abs_set_res(input_dev, ABS_Z, 1024); | ||
| 2374 | __set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit); | ||
| 2375 | break; | ||
| 2376 | |||
| 2377 | case DTK: | 2377 | case DTK: |
| 2378 | for (i = 0; i < 6; i++) | 2378 | for (i = 0; i < 6; i++) |
| 2379 | __set_bit(BTN_0 + i, input_dev->keybit); | 2379 | __set_bit(BTN_0 + i, input_dev->keybit); |
| @@ -2724,6 +2724,18 @@ static const struct wacom_features wacom_features_0xF6 = | |||
| 2724 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ | 2724 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ |
| 2725 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, | 2725 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, |
| 2726 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 2726 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
| 2727 | static const struct wacom_features wacom_features_0x32A = | ||
| 2728 | { "Wacom Cintiq 27QHD", 119740, 67520, 2047, | ||
| 2729 | 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
| 2730 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
| 2731 | static const struct wacom_features wacom_features_0x32B = | ||
| 2732 | { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, | ||
| 2733 | WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
| 2734 | WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, | ||
| 2735 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C }; | ||
| 2736 | static const struct wacom_features wacom_features_0x32C = | ||
| 2737 | { "Wacom Cintiq 27QHD touch", .type = WACOM_27QHDT, | ||
| 2738 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 }; | ||
| 2727 | static const struct wacom_features wacom_features_0x3F = | 2739 | static const struct wacom_features wacom_features_0x3F = |
| 2728 | { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63, | 2740 | { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63, |
| 2729 | CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2741 | CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| @@ -3090,6 +3102,9 @@ const struct hid_device_id wacom_ids[] = { | |||
| 3090 | { USB_DEVICE_WACOM(0x315) }, | 3102 | { USB_DEVICE_WACOM(0x315) }, |
| 3091 | { USB_DEVICE_WACOM(0x317) }, | 3103 | { USB_DEVICE_WACOM(0x317) }, |
| 3092 | { USB_DEVICE_WACOM(0x323) }, | 3104 | { USB_DEVICE_WACOM(0x323) }, |
| 3105 | { USB_DEVICE_WACOM(0x32A) }, | ||
| 3106 | { USB_DEVICE_WACOM(0x32B) }, | ||
| 3107 | { USB_DEVICE_WACOM(0x32C) }, | ||
| 3093 | { USB_DEVICE_WACOM(0x32F) }, | 3108 | { USB_DEVICE_WACOM(0x32F) }, |
| 3094 | { USB_DEVICE_WACOM(0x4001) }, | 3109 | { USB_DEVICE_WACOM(0x4001) }, |
| 3095 | { USB_DEVICE_WACOM(0x4004) }, | 3110 | { USB_DEVICE_WACOM(0x4004) }, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index bfad815cda8a..021ee1c1980a 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
| @@ -10,9 +10,10 @@ | |||
| 10 | #define WACOM_WAC_H | 10 | #define WACOM_WAC_H |
| 11 | 11 | ||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | #include <linux/hid.h> | ||
| 13 | 14 | ||
| 14 | /* maximum packet length for USB devices */ | 15 | /* maximum packet length for USB devices */ |
| 15 | #define WACOM_PKGLEN_MAX 68 | 16 | #define WACOM_PKGLEN_MAX 192 |
| 16 | 17 | ||
| 17 | #define WACOM_NAME_MAX 64 | 18 | #define WACOM_NAME_MAX 64 |
| 18 | 19 | ||
| @@ -36,6 +37,7 @@ | |||
| 36 | /* wacom data size per MT contact */ | 37 | /* wacom data size per MT contact */ |
| 37 | #define WACOM_BYTES_PER_MT_PACKET 11 | 38 | #define WACOM_BYTES_PER_MT_PACKET 11 |
| 38 | #define WACOM_BYTES_PER_24HDT_PACKET 14 | 39 | #define WACOM_BYTES_PER_24HDT_PACKET 14 |
| 40 | #define WACOM_BYTES_PER_QHDTHID_PACKET 6 | ||
| 39 | 41 | ||
| 40 | /* device IDs */ | 42 | /* device IDs */ |
| 41 | #define STYLUS_DEVICE_ID 0x02 | 43 | #define STYLUS_DEVICE_ID 0x02 |
| @@ -57,6 +59,8 @@ | |||
| 57 | #define WACOM_REPORT_TPCMT 13 | 59 | #define WACOM_REPORT_TPCMT 13 |
| 58 | #define WACOM_REPORT_TPCMT2 3 | 60 | #define WACOM_REPORT_TPCMT2 3 |
| 59 | #define WACOM_REPORT_TPCHID 15 | 61 | #define WACOM_REPORT_TPCHID 15 |
| 62 | #define WACOM_REPORT_CINTIQ 16 | ||
| 63 | #define WACOM_REPORT_CINTIQPAD 17 | ||
| 60 | #define WACOM_REPORT_TPCST 16 | 64 | #define WACOM_REPORT_TPCST 16 |
| 61 | #define WACOM_REPORT_DTUS 17 | 65 | #define WACOM_REPORT_DTUS 17 |
| 62 | #define WACOM_REPORT_TPC1FGE 18 | 66 | #define WACOM_REPORT_TPC1FGE 18 |
| @@ -71,6 +75,14 @@ | |||
| 71 | #define WACOM_QUIRK_MONITOR 0x0008 | 75 | #define WACOM_QUIRK_MONITOR 0x0008 |
| 72 | #define WACOM_QUIRK_BATTERY 0x0010 | 76 | #define WACOM_QUIRK_BATTERY 0x0010 |
| 73 | 77 | ||
| 78 | #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ | ||
| 79 | ((f)->physical == HID_DG_STYLUS) || \ | ||
| 80 | ((f)->physical == HID_DG_PEN) || \ | ||
| 81 | ((f)->application == HID_DG_PEN)) | ||
| 82 | #define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \ | ||
| 83 | ((f)->physical == HID_DG_FINGER) || \ | ||
| 84 | ((f)->application == HID_DG_TOUCHSCREEN)) | ||
| 85 | |||
| 74 | enum { | 86 | enum { |
| 75 | PENPARTNER = 0, | 87 | PENPARTNER = 0, |
| 76 | GRAPHIRE, | 88 | GRAPHIRE, |
| @@ -100,6 +112,7 @@ enum { | |||
| 100 | WACOM_22HD, | 112 | WACOM_22HD, |
| 101 | DTK, | 113 | DTK, |
| 102 | WACOM_24HD, | 114 | WACOM_24HD, |
| 115 | WACOM_27QHD, | ||
| 103 | CINTIQ_HYBRID, | 116 | CINTIQ_HYBRID, |
| 104 | CINTIQ, | 117 | CINTIQ, |
| 105 | WACOM_BEE, | 118 | WACOM_BEE, |
| @@ -108,6 +121,7 @@ enum { | |||
| 108 | WIRELESS, | 121 | WIRELESS, |
| 109 | BAMBOO_PT, | 122 | BAMBOO_PT, |
| 110 | WACOM_24HDT, | 123 | WACOM_24HDT, |
| 124 | WACOM_27QHDT, | ||
| 111 | TABLETPC, /* add new TPC below */ | 125 | TABLETPC, /* add new TPC below */ |
| 112 | TABLETPCE, | 126 | TABLETPCE, |
| 113 | TABLETPC2FG, | 127 | TABLETPC2FG, |
| @@ -180,6 +194,7 @@ struct wacom_wac { | |||
| 180 | int tool[2]; | 194 | int tool[2]; |
| 181 | int id[2]; | 195 | int id[2]; |
| 182 | __u32 serial[2]; | 196 | __u32 serial[2]; |
| 197 | bool reporting_data; | ||
| 183 | struct wacom_features features; | 198 | struct wacom_features features; |
| 184 | struct wacom_shared *shared; | 199 | struct wacom_shared *shared; |
| 185 | struct input_dev *input; | 200 | struct input_dev *input; |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 06c4607744f6..efc7787a41a8 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -574,7 +574,9 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data) | |||
| 574 | #define HID_GLOBAL_STACK_SIZE 4 | 574 | #define HID_GLOBAL_STACK_SIZE 4 |
| 575 | #define HID_COLLECTION_STACK_SIZE 4 | 575 | #define HID_COLLECTION_STACK_SIZE 4 |
| 576 | 576 | ||
| 577 | #define HID_SCAN_FLAG_MT_WIN_8 0x00000001 | 577 | #define HID_SCAN_FLAG_MT_WIN_8 BIT(0) |
| 578 | #define HID_SCAN_FLAG_VENDOR_SPECIFIC BIT(1) | ||
| 579 | #define HID_SCAN_FLAG_GD_POINTER BIT(2) | ||
| 578 | 580 | ||
| 579 | struct hid_parser { | 581 | struct hid_parser { |
| 580 | struct hid_global global; | 582 | struct hid_global global; |
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index a1d7e931ab72..b0a813079852 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h | |||
| @@ -166,6 +166,7 @@ struct input_keymap_entry { | |||
| 166 | #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ | 166 | #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ |
| 167 | #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ | 167 | #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ |
| 168 | #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ | 168 | #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ |
| 169 | #define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ | ||
| 169 | 170 | ||
| 170 | #define INPUT_PROP_MAX 0x1f | 171 | #define INPUT_PROP_MAX 0x1f |
| 171 | #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) | 172 | #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) |
