diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-18 00:32:20 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-18 00:32:20 -0400 |
| commit | d66435cc7da95964cb386674bd82ec12ca66320a (patch) | |
| tree | f095996c4129db736b566de9e42c9d329b8ed6e5 | |
| parent | 1a46712aa99594eabe1e9aeedf115dfff0db1dfd (diff) | |
| parent | e1c9b9ff2420c0d8c25924be312bc422bf9dc056 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- functionally equivalent cleanups for wacom driver, making the code
more readable, from Benjamin Tissoires
- a bunch of improvements and fixes for thingm driver from Heiner
Kallweit
- bugfixes to out-of-bound access for generic parsing functions (which
have been there since ever) extract() and implement(), from Dmitry
Torokhov
- a lot of added / improved device support in sony, wacom, microsoft,
multitouch and logitech driver, from various people
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (44 commits)
HID: microsoft: Add ID for MS Wireless Comfort Keyboard
hid: thingm: reorder calls in thingm_probe
HID: i2c-hid: fix OOB write in i2c_hid_set_or_send_report()
HID: multitouch: Release all touch slots on reset_resume
HID: usbhid: enable NO_INIT_REPORTS quirk for Semico USB Keykoard2
HID: penmount: report only one button for PenMount 6000 USB touchscreen controller
HID: i2c-hid: Fix suspend/resume when already runtime suspended
HID: i2c-hid: Add hid-over-i2c name to i2c id table
HID: multitouch: force retrieving of Win8 signature blob
HID: Support for CMedia CM6533 HID audio jack controls
HID: thingm: improve locking
HID: thingm: switch to managed version of led_classdev_register
HID: thingm: remove workqueue
HID: corsair: fix mapping of non-keyboard usages
HID: wacom: close the wireless receiver on remove()
HID: wacom: cleanup input devices
HID: wacom: reuse wacom_parse_and_register() in wireless_work
HID: wacom: move down wireless_work()
HID: wacom: break out parsing of device and registering of input
HID: wacom: break out wacom_intuos_get_tool_type
...
| -rw-r--r-- | drivers/hid/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/hid/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-cmedia.c | 168 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 104 | ||||
| -rw-r--r-- | drivers/hid/hid-corsair.c | 3 | ||||
| -rw-r--r-- | drivers/hid/hid-dr.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 12 | ||||
| -rw-r--r-- | drivers/hid/hid-lg.c | 10 | ||||
| -rw-r--r-- | drivers/hid/hid-logitech-hidpp.c | 701 | ||||
| -rw-r--r-- | drivers/hid/hid-microsoft.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 30 | ||||
| -rw-r--r-- | drivers/hid/hid-penmount.c | 8 | ||||
| -rw-r--r-- | drivers/hid/hid-rmi.c | 11 | ||||
| -rw-r--r-- | drivers/hid/hid-sony.c | 182 | ||||
| -rw-r--r-- | drivers/hid/hid-thingm.c | 135 | ||||
| -rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 60 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 3 | ||||
| -rw-r--r-- | drivers/hid/wacom_sys.c | 363 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.c | 249 |
19 files changed, 1422 insertions, 630 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 513a16cc6e18..411722570035 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -196,6 +196,12 @@ config HID_PRODIKEYS | |||
| 196 | multimedia keyboard, but will lack support for the musical keyboard | 196 | multimedia keyboard, but will lack support for the musical keyboard |
| 197 | and some additional multimedia keys. | 197 | and some additional multimedia keys. |
| 198 | 198 | ||
| 199 | config HID_CMEDIA | ||
| 200 | tristate "CMedia CM6533 HID audio jack controls" | ||
| 201 | depends on HID | ||
| 202 | ---help--- | ||
| 203 | Support for CMedia CM6533 HID audio jack controls. | ||
| 204 | |||
| 199 | config HID_CP2112 | 205 | config HID_CP2112 |
| 200 | tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support" | 206 | tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support" |
| 201 | depends on USB_HID && I2C && GPIOLIB | 207 | depends on USB_HID && I2C && GPIOLIB |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 00011fee08b9..be56ab6f75a8 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
| @@ -29,6 +29,7 @@ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | |||
| 29 | obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o | 29 | obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o |
| 30 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 30 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
| 31 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | 31 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o |
| 32 | obj-$(CONFIG_HID_CMEDIA) += hid-cmedia.o | ||
| 32 | obj-$(CONFIG_HID_CORSAIR) += hid-corsair.o | 33 | obj-$(CONFIG_HID_CORSAIR) += hid-corsair.o |
| 33 | obj-$(CONFIG_HID_CP2112) += hid-cp2112.o | 34 | obj-$(CONFIG_HID_CP2112) += hid-cp2112.o |
| 34 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | 35 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o |
diff --git a/drivers/hid/hid-cmedia.c b/drivers/hid/hid-cmedia.c new file mode 100644 index 000000000000..7230f8513681 --- /dev/null +++ b/drivers/hid/hid-cmedia.c | |||
| @@ -0,0 +1,168 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for CMedia CM6533 audio jack controls | ||
| 3 | * | ||
| 4 | * Copyright (C) 2015 Ben Chen <ben_chen@bizlinktech.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/hid.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include "hid-ids.h" | ||
| 20 | |||
| 21 | MODULE_AUTHOR("Ben Chen"); | ||
| 22 | MODULE_DESCRIPTION("CM6533 HID jack controls"); | ||
| 23 | MODULE_LICENSE("GPL"); | ||
| 24 | |||
| 25 | #define CM6533_JD_TYPE_COUNT 1 | ||
| 26 | #define CM6533_JD_RAWEV_LEN 16 | ||
| 27 | #define CM6533_JD_SFX_OFFSET 8 | ||
| 28 | |||
| 29 | /* | ||
| 30 | * | ||
| 31 | *CM6533 audio jack HID raw events: | ||
| 32 | * | ||
| 33 | *Plug in: | ||
| 34 | *01000600 002083xx 080008c0 10000000 | ||
| 35 | *about 3 seconds later... | ||
| 36 | *01000a00 002083xx 08000380 10000000 | ||
| 37 | *01000600 002083xx 08000380 10000000 | ||
| 38 | * | ||
| 39 | *Plug out: | ||
| 40 | *01000400 002083xx 080008c0 x0000000 | ||
| 41 | */ | ||
| 42 | |||
| 43 | static const u8 ji_sfx[] = { 0x08, 0x00, 0x08, 0xc0 }; | ||
| 44 | static const u8 ji_in[] = { 0x01, 0x00, 0x06, 0x00 }; | ||
| 45 | static const u8 ji_out[] = { 0x01, 0x00, 0x04, 0x00 }; | ||
| 46 | |||
| 47 | static int jack_switch_types[CM6533_JD_TYPE_COUNT] = { | ||
| 48 | SW_HEADPHONE_INSERT, | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct cmhid { | ||
| 52 | struct input_dev *input_dev; | ||
| 53 | struct hid_device *hid; | ||
| 54 | unsigned short switch_map[CM6533_JD_TYPE_COUNT]; | ||
| 55 | }; | ||
| 56 | |||
| 57 | static void hp_ev(struct hid_device *hid, struct cmhid *cm, int value) | ||
| 58 | { | ||
| 59 | input_report_switch(cm->input_dev, SW_HEADPHONE_INSERT, value); | ||
| 60 | input_sync(cm->input_dev); | ||
| 61 | } | ||
| 62 | |||
| 63 | static int cmhid_raw_event(struct hid_device *hid, struct hid_report *report, | ||
| 64 | u8 *data, int len) | ||
| 65 | { | ||
| 66 | struct cmhid *cm = hid_get_drvdata(hid); | ||
| 67 | |||
| 68 | if (len != CM6533_JD_RAWEV_LEN) | ||
| 69 | goto out; | ||
| 70 | if (memcmp(data+CM6533_JD_SFX_OFFSET, ji_sfx, sizeof(ji_sfx))) | ||
| 71 | goto out; | ||
| 72 | |||
| 73 | if (!memcmp(data, ji_out, sizeof(ji_out))) { | ||
| 74 | hp_ev(hid, cm, 0); | ||
| 75 | goto out; | ||
| 76 | } | ||
| 77 | if (!memcmp(data, ji_in, sizeof(ji_in))) { | ||
| 78 | hp_ev(hid, cm, 1); | ||
| 79 | goto out; | ||
| 80 | } | ||
| 81 | |||
| 82 | out: | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 86 | static int cmhid_input_configured(struct hid_device *hid, | ||
| 87 | struct hid_input *hidinput) | ||
| 88 | { | ||
| 89 | struct input_dev *input_dev = hidinput->input; | ||
| 90 | struct cmhid *cm = hid_get_drvdata(hid); | ||
| 91 | int i; | ||
| 92 | |||
| 93 | cm->input_dev = input_dev; | ||
| 94 | memcpy(cm->switch_map, jack_switch_types, sizeof(cm->switch_map)); | ||
| 95 | input_dev->evbit[0] = BIT(EV_SW); | ||
| 96 | for (i = 0; i < CM6533_JD_TYPE_COUNT; i++) | ||
| 97 | input_set_capability(cm->input_dev, | ||
| 98 | EV_SW, jack_switch_types[i]); | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | static int cmhid_input_mapping(struct hid_device *hid, | ||
| 103 | struct hid_input *hi, struct hid_field *field, | ||
| 104 | struct hid_usage *usage, unsigned long **bit, int *max) | ||
| 105 | { | ||
| 106 | return -1; | ||
| 107 | } | ||
| 108 | |||
| 109 | static int cmhid_probe(struct hid_device *hid, const struct hid_device_id *id) | ||
| 110 | { | ||
| 111 | int ret; | ||
| 112 | struct cmhid *cm; | ||
| 113 | |||
| 114 | cm = kzalloc(sizeof(struct cmhid), GFP_KERNEL); | ||
| 115 | if (!cm) { | ||
| 116 | ret = -ENOMEM; | ||
| 117 | goto allocfail; | ||
| 118 | } | ||
| 119 | |||
| 120 | cm->hid = hid; | ||
| 121 | |||
| 122 | hid->quirks |= HID_QUIRK_HIDINPUT_FORCE; | ||
| 123 | hid_set_drvdata(hid, cm); | ||
| 124 | |||
| 125 | ret = hid_parse(hid); | ||
| 126 | if (ret) { | ||
| 127 | hid_err(hid, "parse failed\n"); | ||
| 128 | goto fail; | ||
| 129 | } | ||
| 130 | |||
| 131 | ret = hid_hw_start(hid, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE); | ||
| 132 | if (ret) { | ||
| 133 | hid_err(hid, "hw start failed\n"); | ||
| 134 | goto fail; | ||
| 135 | } | ||
| 136 | |||
| 137 | return 0; | ||
| 138 | fail: | ||
| 139 | kfree(cm); | ||
| 140 | allocfail: | ||
| 141 | return ret; | ||
| 142 | } | ||
| 143 | |||
| 144 | static void cmhid_remove(struct hid_device *hid) | ||
| 145 | { | ||
| 146 | struct cmhid *cm = hid_get_drvdata(hid); | ||
| 147 | |||
| 148 | hid_hw_stop(hid); | ||
| 149 | kfree(cm); | ||
| 150 | } | ||
| 151 | |||
| 152 | static const struct hid_device_id cmhid_devices[] = { | ||
| 153 | { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) }, | ||
| 154 | { } | ||
| 155 | }; | ||
| 156 | MODULE_DEVICE_TABLE(hid, cmhid_devices); | ||
| 157 | |||
| 158 | static struct hid_driver cmhid_driver = { | ||
| 159 | .name = "cm6533_jd", | ||
| 160 | .id_table = cmhid_devices, | ||
| 161 | .raw_event = cmhid_raw_event, | ||
| 162 | .input_configured = cmhid_input_configured, | ||
| 163 | .probe = cmhid_probe, | ||
| 164 | .remove = cmhid_remove, | ||
| 165 | .input_mapping = cmhid_input_mapping, | ||
| 166 | }; | ||
| 167 | module_hid_driver(cmhid_driver); | ||
| 168 | |||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 7e89288b1537..bdb8cc89cacc 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1075,7 +1075,7 @@ static u32 s32ton(__s32 value, unsigned n) | |||
| 1075 | * Extract/implement a data field from/to a little endian report (bit array). | 1075 | * Extract/implement a data field from/to a little endian report (bit array). |
| 1076 | * | 1076 | * |
| 1077 | * Code sort-of follows HID spec: | 1077 | * Code sort-of follows HID spec: |
| 1078 | * http://www.usb.org/developers/devclass_docs/HID1_11.pdf | 1078 | * http://www.usb.org/developers/hidpage/HID1_11.pdf |
| 1079 | * | 1079 | * |
| 1080 | * While the USB HID spec allows unlimited length bit fields in "report | 1080 | * While the USB HID spec allows unlimited length bit fields in "report |
| 1081 | * descriptors", most devices never use more than 16 bits. | 1081 | * descriptors", most devices never use more than 16 bits. |
| @@ -1083,20 +1083,37 @@ static u32 s32ton(__s32 value, unsigned n) | |||
| 1083 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". | 1083 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". |
| 1084 | */ | 1084 | */ |
| 1085 | 1085 | ||
| 1086 | __u32 hid_field_extract(const struct hid_device *hid, __u8 *report, | 1086 | static u32 __extract(u8 *report, unsigned offset, int n) |
| 1087 | unsigned offset, unsigned n) | 1087 | { |
| 1088 | { | 1088 | unsigned int idx = offset / 8; |
| 1089 | u64 x; | 1089 | unsigned int bit_nr = 0; |
| 1090 | unsigned int bit_shift = offset % 8; | ||
| 1091 | int bits_to_copy = 8 - bit_shift; | ||
| 1092 | u32 value = 0; | ||
| 1093 | u32 mask = n < 32 ? (1U << n) - 1 : ~0U; | ||
| 1094 | |||
| 1095 | while (n > 0) { | ||
| 1096 | value |= ((u32)report[idx] >> bit_shift) << bit_nr; | ||
| 1097 | n -= bits_to_copy; | ||
| 1098 | bit_nr += bits_to_copy; | ||
| 1099 | bits_to_copy = 8; | ||
| 1100 | bit_shift = 0; | ||
| 1101 | idx++; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | return value & mask; | ||
| 1105 | } | ||
| 1090 | 1106 | ||
| 1091 | if (n > 32) | 1107 | u32 hid_field_extract(const struct hid_device *hid, u8 *report, |
| 1108 | unsigned offset, unsigned n) | ||
| 1109 | { | ||
| 1110 | if (n > 32) { | ||
| 1092 | hid_warn(hid, "hid_field_extract() called with n (%d) > 32! (%s)\n", | 1111 | hid_warn(hid, "hid_field_extract() called with n (%d) > 32! (%s)\n", |
| 1093 | n, current->comm); | 1112 | n, current->comm); |
| 1113 | n = 32; | ||
| 1114 | } | ||
| 1094 | 1115 | ||
| 1095 | report += offset >> 3; /* adjust byte index */ | 1116 | return __extract(report, offset, n); |
| 1096 | offset &= 7; /* now only need bit offset into one byte */ | ||
| 1097 | x = get_unaligned_le64(report); | ||
| 1098 | x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ | ||
| 1099 | return (u32) x; | ||
| 1100 | } | 1117 | } |
| 1101 | EXPORT_SYMBOL_GPL(hid_field_extract); | 1118 | EXPORT_SYMBOL_GPL(hid_field_extract); |
| 1102 | 1119 | ||
| @@ -1106,31 +1123,56 @@ EXPORT_SYMBOL_GPL(hid_field_extract); | |||
| 1106 | * The data mangled in the bit stream remains in little endian | 1123 | * The data mangled in the bit stream remains in little endian |
| 1107 | * order the whole time. It make more sense to talk about | 1124 | * order the whole time. It make more sense to talk about |
| 1108 | * endianness of register values by considering a register | 1125 | * endianness of register values by considering a register |
| 1109 | * a "cached" copy of the little endiad bit stream. | 1126 | * a "cached" copy of the little endian bit stream. |
| 1110 | */ | 1127 | */ |
| 1111 | static void implement(const struct hid_device *hid, __u8 *report, | 1128 | |
| 1112 | unsigned offset, unsigned n, __u32 value) | 1129 | static void __implement(u8 *report, unsigned offset, int n, u32 value) |
| 1130 | { | ||
| 1131 | unsigned int idx = offset / 8; | ||
| 1132 | unsigned int size = offset + n; | ||
| 1133 | unsigned int bit_shift = offset % 8; | ||
| 1134 | int bits_to_set = 8 - bit_shift; | ||
| 1135 | u8 bit_mask = 0xff << bit_shift; | ||
| 1136 | |||
| 1137 | while (n - bits_to_set >= 0) { | ||
| 1138 | report[idx] &= ~bit_mask; | ||
| 1139 | report[idx] |= value << bit_shift; | ||
| 1140 | value >>= bits_to_set; | ||
| 1141 | n -= bits_to_set; | ||
| 1142 | bits_to_set = 8; | ||
| 1143 | bit_mask = 0xff; | ||
| 1144 | bit_shift = 0; | ||
| 1145 | idx++; | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | /* last nibble */ | ||
| 1149 | if (n) { | ||
| 1150 | if (size % 8) | ||
| 1151 | bit_mask &= (1U << (size % 8)) - 1; | ||
| 1152 | report[idx] &= ~bit_mask; | ||
| 1153 | report[idx] |= (value << bit_shift) & bit_mask; | ||
| 1154 | } | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | static void implement(const struct hid_device *hid, u8 *report, | ||
| 1158 | unsigned offset, unsigned n, u32 value) | ||
| 1113 | { | 1159 | { |
| 1114 | u64 x; | 1160 | u64 m; |
| 1115 | u64 m = (1ULL << n) - 1; | ||
| 1116 | 1161 | ||
| 1117 | if (n > 32) | 1162 | if (n > 32) { |
| 1118 | hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n", | 1163 | hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n", |
| 1119 | __func__, n, current->comm); | 1164 | __func__, n, current->comm); |
| 1165 | n = 32; | ||
| 1166 | } | ||
| 1120 | 1167 | ||
| 1168 | m = (1ULL << n) - 1; | ||
| 1121 | if (value > m) | 1169 | if (value > m) |
| 1122 | hid_warn(hid, "%s() called with too large value %d! (%s)\n", | 1170 | hid_warn(hid, "%s() called with too large value %d! (%s)\n", |
| 1123 | __func__, value, current->comm); | 1171 | __func__, value, current->comm); |
| 1124 | WARN_ON(value > m); | 1172 | WARN_ON(value > m); |
| 1125 | value &= m; | 1173 | value &= m; |
| 1126 | 1174 | ||
| 1127 | report += offset >> 3; | 1175 | __implement(report, offset, n, value); |
| 1128 | offset &= 7; | ||
| 1129 | |||
| 1130 | x = get_unaligned_le64(report); | ||
| 1131 | x &= ~(m << offset); | ||
| 1132 | x |= ((u64)value) << offset; | ||
| 1133 | put_unaligned_le64(x, report); | ||
| 1134 | } | 1176 | } |
| 1135 | 1177 | ||
| 1136 | /* | 1178 | /* |
| @@ -1251,6 +1293,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, | |||
| 1251 | /* Ignore report if ErrorRollOver */ | 1293 | /* Ignore report if ErrorRollOver */ |
| 1252 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) && | 1294 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) && |
| 1253 | value[n] >= min && value[n] <= max && | 1295 | value[n] >= min && value[n] <= max && |
| 1296 | value[n] - min < field->maxusage && | ||
| 1254 | field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) | 1297 | field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) |
| 1255 | goto exit; | 1298 | goto exit; |
| 1256 | } | 1299 | } |
| @@ -1263,11 +1306,13 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, | |||
| 1263 | } | 1306 | } |
| 1264 | 1307 | ||
| 1265 | if (field->value[n] >= min && field->value[n] <= max | 1308 | if (field->value[n] >= min && field->value[n] <= max |
| 1309 | && field->value[n] - min < field->maxusage | ||
| 1266 | && field->usage[field->value[n] - min].hid | 1310 | && field->usage[field->value[n] - min].hid |
| 1267 | && search(value, field->value[n], count)) | 1311 | && search(value, field->value[n], count)) |
| 1268 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); | 1312 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); |
| 1269 | 1313 | ||
| 1270 | if (value[n] >= min && value[n] <= max | 1314 | if (value[n] >= min && value[n] <= max |
| 1315 | && value[n] - min < field->maxusage | ||
| 1271 | && field->usage[value[n] - min].hid | 1316 | && field->usage[value[n] - min].hid |
| 1272 | && search(field->value, value[n], count)) | 1317 | && search(field->value, value[n], count)) |
| 1273 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); | 1318 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); |
| @@ -1891,6 +1936,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1891 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, | 1936 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, |
| 1892 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, | 1937 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, |
| 1893 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, | 1938 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, |
| 1939 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DUAL_ACTION) }, | ||
| 1894 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, | 1940 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, |
| 1895 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, | 1941 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, |
| 1896 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, | 1942 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, |
| @@ -1919,6 +1965,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1919 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, | 1965 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, |
| 1920 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, | 1966 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, |
| 1921 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, | 1967 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, |
| 1968 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD) }, | ||
| 1922 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, | 1969 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, |
| 1923 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, | 1970 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, |
| 1924 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) }, | 1971 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) }, |
| @@ -2003,6 +2050,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 2003 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) }, | 2050 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) }, |
| 2004 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 2051 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
| 2005 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, | 2052 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, |
| 2053 | { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) }, | ||
| 2006 | { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, | 2054 | { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, |
| 2007 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 2055 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
| 2008 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, | 2056 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, |
| @@ -2051,6 +2099,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 2051 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, | 2099 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, |
| 2052 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, | 2100 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, |
| 2053 | { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) }, | 2101 | { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) }, |
| 2102 | { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) }, | ||
| 2054 | { } | 2103 | { } |
| 2055 | }; | 2104 | }; |
| 2056 | 2105 | ||
| @@ -2615,9 +2664,10 @@ int hid_add_device(struct hid_device *hdev) | |||
| 2615 | /* | 2664 | /* |
| 2616 | * Scan generic devices for group information | 2665 | * Scan generic devices for group information |
| 2617 | */ | 2666 | */ |
| 2618 | if (hid_ignore_special_drivers || | 2667 | if (hid_ignore_special_drivers) { |
| 2619 | (!hdev->group && | 2668 | hdev->group = HID_GROUP_GENERIC; |
| 2620 | !hid_match_id(hdev, hid_have_special_driver))) { | 2669 | } else if (!hdev->group && |
| 2670 | !hid_match_id(hdev, hid_have_special_driver)) { | ||
| 2621 | ret = hid_scan_report(hdev); | 2671 | ret = hid_scan_report(hdev); |
| 2622 | if (ret) | 2672 | if (ret) |
| 2623 | hid_warn(hdev, "bad device descriptor (%d)\n", ret); | 2673 | hid_warn(hdev, "bad device descriptor (%d)\n", ret); |
diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index 58551964ce86..717704e9ae07 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c | |||
| @@ -595,6 +595,9 @@ static int corsair_input_mapping(struct hid_device *dev, | |||
| 595 | { | 595 | { |
| 596 | int gkey; | 596 | int gkey; |
| 597 | 597 | ||
| 598 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_KEYBOARD) | ||
| 599 | return 0; | ||
| 600 | |||
| 598 | gkey = corsair_usage_to_gkey(usage->hid & HID_USAGE); | 601 | gkey = corsair_usage_to_gkey(usage->hid & HID_USAGE); |
| 599 | if (gkey != 0) { | 602 | if (gkey != 0) { |
| 600 | hid_map_usage_clear(input, usage, bit, max, EV_KEY, | 603 | hid_map_usage_clear(input, usage, bit, max, EV_KEY, |
diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index 1d78ba3b799e..8fd4bf77f264 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c | |||
| @@ -151,7 +151,7 @@ static inline int drff_init(struct hid_device *hid) | |||
| 151 | * descriptor. In any case, it's a wonder it works on Windows. | 151 | * descriptor. In any case, it's a wonder it works on Windows. |
| 152 | * | 152 | * |
| 153 | * Usage Page (Desktop), ; Generic desktop controls (01h) | 153 | * Usage Page (Desktop), ; Generic desktop controls (01h) |
| 154 | * Usage (Joystik), ; Joystik (04h, application collection) | 154 | * Usage (Joystick), ; Joystick (04h, application collection) |
| 155 | * Collection (Application), | 155 | * Collection (Application), |
| 156 | * Collection (Logical), | 156 | * Collection (Logical), |
| 157 | * Report Size (8), | 157 | * Report Size (8), |
| @@ -207,7 +207,7 @@ static inline int drff_init(struct hid_device *hid) | |||
| 207 | /* Fixed report descriptor for PID 0x011 joystick */ | 207 | /* Fixed report descriptor for PID 0x011 joystick */ |
| 208 | static __u8 pid0011_rdesc_fixed[] = { | 208 | static __u8 pid0011_rdesc_fixed[] = { |
| 209 | 0x05, 0x01, /* Usage Page (Desktop), */ | 209 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 210 | 0x09, 0x04, /* Usage (Joystik), */ | 210 | 0x09, 0x04, /* Usage (Joystick), */ |
| 211 | 0xA1, 0x01, /* Collection (Application), */ | 211 | 0xA1, 0x01, /* Collection (Application), */ |
| 212 | 0xA1, 0x02, /* Collection (Logical), */ | 212 | 0xA1, 0x02, /* Collection (Logical), */ |
| 213 | 0x14, /* Logical Minimum (0), */ | 213 | 0x14, /* Logical Minimum (0), */ |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b6ff6e78ac54..5c0e43ed5c53 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -61,6 +61,9 @@ | |||
| 61 | #define USB_VENDOR_ID_AIREN 0x1a2c | 61 | #define USB_VENDOR_ID_AIREN 0x1a2c |
| 62 | #define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002 | 62 | #define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002 |
| 63 | 63 | ||
| 64 | #define USB_VENDOR_ID_AKAI 0x2011 | ||
| 65 | #define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 | ||
| 66 | |||
| 64 | #define USB_VENDOR_ID_ALCOR 0x058f | 67 | #define USB_VENDOR_ID_ALCOR 0x058f |
| 65 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 | 68 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 |
| 66 | 69 | ||
| @@ -246,6 +249,7 @@ | |||
| 246 | 249 | ||
| 247 | #define USB_VENDOR_ID_CMEDIA 0x0d8c | 250 | #define USB_VENDOR_ID_CMEDIA 0x0d8c |
| 248 | #define USB_DEVICE_ID_CM109 0x000e | 251 | #define USB_DEVICE_ID_CM109 0x000e |
| 252 | #define USB_DEVICE_ID_CM6533 0x0022 | ||
| 249 | 253 | ||
| 250 | #define USB_VENDOR_ID_CODEMERCS 0x07c0 | 254 | #define USB_VENDOR_ID_CODEMERCS 0x07c0 |
| 251 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 | 255 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 |
| @@ -680,6 +684,7 @@ | |||
| 680 | #define USB_DEVICE_ID_MS_NE7K 0x071d | 684 | #define USB_DEVICE_ID_MS_NE7K 0x071d |
| 681 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 | 685 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 |
| 682 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c | 686 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c |
| 687 | #define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3 | ||
| 683 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 | 688 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 |
| 684 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 | 689 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 |
| 685 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | 690 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
| @@ -800,6 +805,7 @@ | |||
| 800 | #define USB_VENDOR_ID_QUANTA 0x0408 | 805 | #define USB_VENDOR_ID_QUANTA 0x0408 |
| 801 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000 | 806 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000 |
| 802 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 | 807 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 |
| 808 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003 0x3003 | ||
| 803 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 | 809 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 |
| 804 | 810 | ||
| 805 | #define USB_VENDOR_ID_RAZER 0x1532 | 811 | #define USB_VENDOR_ID_RAZER 0x1532 |
| @@ -839,6 +845,7 @@ | |||
| 839 | 845 | ||
| 840 | #define USB_VENDOR_ID_SEMICO 0x1a2c | 846 | #define USB_VENDOR_ID_SEMICO 0x1a2c |
| 841 | #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023 | 847 | #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023 |
| 848 | #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2 0x0027 | ||
| 842 | 849 | ||
| 843 | #define USB_VENDOR_ID_SENNHEISER 0x1395 | 850 | #define USB_VENDOR_ID_SENNHEISER 0x1395 |
| 844 | #define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c | 851 | #define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c |
| @@ -872,6 +879,9 @@ | |||
| 872 | #define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002 | 879 | #define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002 |
| 873 | #define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000 | 880 | #define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000 |
| 874 | 881 | ||
| 882 | #define USB_VENDOR_ID_SINO_LITE 0x1345 | ||
| 883 | #define USB_DEVICE_ID_SINO_LITE_CONTROLLER 0x3008 | ||
| 884 | |||
| 875 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 | 885 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 |
| 876 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 | 886 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 |
| 877 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046 | 887 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046 |
| @@ -1047,7 +1057,7 @@ | |||
| 1047 | #define USB_DEVICE_ID_RI_KA_WEBMAIL 0x1320 /* Webmail Notifier */ | 1057 | #define USB_DEVICE_ID_RI_KA_WEBMAIL 0x1320 /* Webmail Notifier */ |
| 1048 | 1058 | ||
| 1049 | #define USB_VENDOR_ID_MULTIPLE_1781 0x1781 | 1059 | #define USB_VENDOR_ID_MULTIPLE_1781 0x1781 |
| 1050 | #define USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD 0x0a8d | 1060 | #define USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD 0x0a9d |
| 1051 | 1061 | ||
| 1052 | #define USB_VENDOR_ID_DRACAL_RAPHNET 0x289b | 1062 | #define USB_VENDOR_ID_DRACAL_RAPHNET 0x289b |
| 1053 | #define USB_DEVICE_ID_RAPHNET_2NES2SNES 0x0002 | 1063 | #define USB_DEVICE_ID_RAPHNET_2NES2SNES 0x0002 |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index c690fae02cf8..feb2be71f77c 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
| @@ -61,7 +61,7 @@ | |||
| 61 | */ | 61 | */ |
| 62 | static __u8 df_rdesc_fixed[] = { | 62 | static __u8 df_rdesc_fixed[] = { |
| 63 | 0x05, 0x01, /* Usage Page (Desktop), */ | 63 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 64 | 0x09, 0x04, /* Usage (Joystik), */ | 64 | 0x09, 0x04, /* Usage (Joystick), */ |
| 65 | 0xA1, 0x01, /* Collection (Application), */ | 65 | 0xA1, 0x01, /* Collection (Application), */ |
| 66 | 0xA1, 0x02, /* Collection (Logical), */ | 66 | 0xA1, 0x02, /* Collection (Logical), */ |
| 67 | 0x95, 0x01, /* Report Count (1), */ | 67 | 0x95, 0x01, /* Report Count (1), */ |
| @@ -127,7 +127,7 @@ static __u8 df_rdesc_fixed[] = { | |||
| 127 | 127 | ||
| 128 | static __u8 dfp_rdesc_fixed[] = { | 128 | static __u8 dfp_rdesc_fixed[] = { |
| 129 | 0x05, 0x01, /* Usage Page (Desktop), */ | 129 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 130 | 0x09, 0x04, /* Usage (Joystik), */ | 130 | 0x09, 0x04, /* Usage (Joystick), */ |
| 131 | 0xA1, 0x01, /* Collection (Application), */ | 131 | 0xA1, 0x01, /* Collection (Application), */ |
| 132 | 0xA1, 0x02, /* Collection (Logical), */ | 132 | 0xA1, 0x02, /* Collection (Logical), */ |
| 133 | 0x95, 0x01, /* Report Count (1), */ | 133 | 0x95, 0x01, /* Report Count (1), */ |
| @@ -175,7 +175,7 @@ static __u8 dfp_rdesc_fixed[] = { | |||
| 175 | 175 | ||
| 176 | static __u8 fv_rdesc_fixed[] = { | 176 | static __u8 fv_rdesc_fixed[] = { |
| 177 | 0x05, 0x01, /* Usage Page (Desktop), */ | 177 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 178 | 0x09, 0x04, /* Usage (Joystik), */ | 178 | 0x09, 0x04, /* Usage (Joystick), */ |
| 179 | 0xA1, 0x01, /* Collection (Application), */ | 179 | 0xA1, 0x01, /* Collection (Application), */ |
| 180 | 0xA1, 0x02, /* Collection (Logical), */ | 180 | 0xA1, 0x02, /* Collection (Logical), */ |
| 181 | 0x95, 0x01, /* Report Count (1), */ | 181 | 0x95, 0x01, /* Report Count (1), */ |
| @@ -242,7 +242,7 @@ static __u8 fv_rdesc_fixed[] = { | |||
| 242 | 242 | ||
| 243 | static __u8 momo_rdesc_fixed[] = { | 243 | static __u8 momo_rdesc_fixed[] = { |
| 244 | 0x05, 0x01, /* Usage Page (Desktop), */ | 244 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 245 | 0x09, 0x04, /* Usage (Joystik), */ | 245 | 0x09, 0x04, /* Usage (Joystick), */ |
| 246 | 0xA1, 0x01, /* Collection (Application), */ | 246 | 0xA1, 0x01, /* Collection (Application), */ |
| 247 | 0xA1, 0x02, /* Collection (Logical), */ | 247 | 0xA1, 0x02, /* Collection (Logical), */ |
| 248 | 0x95, 0x01, /* Report Count (1), */ | 248 | 0x95, 0x01, /* Report Count (1), */ |
| @@ -288,7 +288,7 @@ static __u8 momo_rdesc_fixed[] = { | |||
| 288 | 288 | ||
| 289 | static __u8 momo2_rdesc_fixed[] = { | 289 | static __u8 momo2_rdesc_fixed[] = { |
| 290 | 0x05, 0x01, /* Usage Page (Desktop), */ | 290 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 291 | 0x09, 0x04, /* Usage (Joystik), */ | 291 | 0x09, 0x04, /* Usage (Joystick), */ |
| 292 | 0xA1, 0x01, /* Collection (Application), */ | 292 | 0xA1, 0x01, /* Collection (Application), */ |
| 293 | 0xA1, 0x02, /* Collection (Logical), */ | 293 | 0xA1, 0x02, /* Collection (Logical), */ |
| 294 | 0x95, 0x01, /* Report Count (1), */ | 294 | 0x95, 0x01, /* Report Count (1), */ |
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index bd2ab476c65e..2e2515a4c070 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c | |||
| @@ -15,13 +15,19 @@ | |||
| 15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 16 | 16 | ||
| 17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
| 18 | #include <linux/input.h> | ||
| 19 | #include <linux/usb.h> | ||
| 18 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
| 19 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 20 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 21 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 22 | #include <linux/kfifo.h> | 24 | #include <linux/kfifo.h> |
| 23 | #include <linux/input/mt.h> | 25 | #include <linux/input/mt.h> |
| 26 | #include <linux/workqueue.h> | ||
| 27 | #include <linux/atomic.h> | ||
| 28 | #include <linux/fixp-arith.h> | ||
| 24 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
| 30 | #include "usbhid/usbhid.h" | ||
| 25 | #include "hid-ids.h" | 31 | #include "hid-ids.h" |
| 26 | 32 | ||
| 27 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
| @@ -773,6 +779,589 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev, | |||
| 773 | } | 779 | } |
| 774 | } | 780 | } |
| 775 | 781 | ||
| 782 | /* -------------------------------------------------------------------------- */ | ||
| 783 | /* 0x8123: Force feedback support */ | ||
| 784 | /* -------------------------------------------------------------------------- */ | ||
| 785 | |||
| 786 | #define HIDPP_FF_GET_INFO 0x01 | ||
| 787 | #define HIDPP_FF_RESET_ALL 0x11 | ||
| 788 | #define HIDPP_FF_DOWNLOAD_EFFECT 0x21 | ||
| 789 | #define HIDPP_FF_SET_EFFECT_STATE 0x31 | ||
| 790 | #define HIDPP_FF_DESTROY_EFFECT 0x41 | ||
| 791 | #define HIDPP_FF_GET_APERTURE 0x51 | ||
| 792 | #define HIDPP_FF_SET_APERTURE 0x61 | ||
| 793 | #define HIDPP_FF_GET_GLOBAL_GAINS 0x71 | ||
| 794 | #define HIDPP_FF_SET_GLOBAL_GAINS 0x81 | ||
| 795 | |||
| 796 | #define HIDPP_FF_EFFECT_STATE_GET 0x00 | ||
| 797 | #define HIDPP_FF_EFFECT_STATE_STOP 0x01 | ||
| 798 | #define HIDPP_FF_EFFECT_STATE_PLAY 0x02 | ||
| 799 | #define HIDPP_FF_EFFECT_STATE_PAUSE 0x03 | ||
| 800 | |||
| 801 | #define HIDPP_FF_EFFECT_CONSTANT 0x00 | ||
| 802 | #define HIDPP_FF_EFFECT_PERIODIC_SINE 0x01 | ||
| 803 | #define HIDPP_FF_EFFECT_PERIODIC_SQUARE 0x02 | ||
| 804 | #define HIDPP_FF_EFFECT_PERIODIC_TRIANGLE 0x03 | ||
| 805 | #define HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHUP 0x04 | ||
| 806 | #define HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHDOWN 0x05 | ||
| 807 | #define HIDPP_FF_EFFECT_SPRING 0x06 | ||
| 808 | #define HIDPP_FF_EFFECT_DAMPER 0x07 | ||
| 809 | #define HIDPP_FF_EFFECT_FRICTION 0x08 | ||
| 810 | #define HIDPP_FF_EFFECT_INERTIA 0x09 | ||
| 811 | #define HIDPP_FF_EFFECT_RAMP 0x0A | ||
| 812 | |||
| 813 | #define HIDPP_FF_EFFECT_AUTOSTART 0x80 | ||
| 814 | |||
| 815 | #define HIDPP_FF_EFFECTID_NONE -1 | ||
| 816 | #define HIDPP_FF_EFFECTID_AUTOCENTER -2 | ||
| 817 | |||
| 818 | #define HIDPP_FF_MAX_PARAMS 20 | ||
| 819 | #define HIDPP_FF_RESERVED_SLOTS 1 | ||
| 820 | |||
| 821 | struct hidpp_ff_private_data { | ||
| 822 | struct hidpp_device *hidpp; | ||
| 823 | u8 feature_index; | ||
| 824 | u8 version; | ||
| 825 | u16 gain; | ||
| 826 | s16 range; | ||
| 827 | u8 slot_autocenter; | ||
| 828 | u8 num_effects; | ||
| 829 | int *effect_ids; | ||
| 830 | struct workqueue_struct *wq; | ||
| 831 | atomic_t workqueue_size; | ||
| 832 | }; | ||
| 833 | |||
| 834 | struct hidpp_ff_work_data { | ||
| 835 | struct work_struct work; | ||
| 836 | struct hidpp_ff_private_data *data; | ||
| 837 | int effect_id; | ||
| 838 | u8 command; | ||
| 839 | u8 params[HIDPP_FF_MAX_PARAMS]; | ||
| 840 | u8 size; | ||
| 841 | }; | ||
| 842 | |||
| 843 | static const signed short hiddpp_ff_effects[] = { | ||
| 844 | FF_CONSTANT, | ||
| 845 | FF_PERIODIC, | ||
| 846 | FF_SINE, | ||
| 847 | FF_SQUARE, | ||
| 848 | FF_SAW_UP, | ||
| 849 | FF_SAW_DOWN, | ||
| 850 | FF_TRIANGLE, | ||
| 851 | FF_SPRING, | ||
| 852 | FF_DAMPER, | ||
| 853 | FF_AUTOCENTER, | ||
| 854 | FF_GAIN, | ||
| 855 | -1 | ||
| 856 | }; | ||
| 857 | |||
| 858 | static const signed short hiddpp_ff_effects_v2[] = { | ||
| 859 | FF_RAMP, | ||
| 860 | FF_FRICTION, | ||
| 861 | FF_INERTIA, | ||
| 862 | -1 | ||
| 863 | }; | ||
| 864 | |||
| 865 | static const u8 HIDPP_FF_CONDITION_CMDS[] = { | ||
| 866 | HIDPP_FF_EFFECT_SPRING, | ||
| 867 | HIDPP_FF_EFFECT_FRICTION, | ||
| 868 | HIDPP_FF_EFFECT_DAMPER, | ||
| 869 | HIDPP_FF_EFFECT_INERTIA | ||
| 870 | }; | ||
| 871 | |||
| 872 | static const char *HIDPP_FF_CONDITION_NAMES[] = { | ||
| 873 | "spring", | ||
| 874 | "friction", | ||
| 875 | "damper", | ||
| 876 | "inertia" | ||
| 877 | }; | ||
| 878 | |||
| 879 | |||
| 880 | static u8 hidpp_ff_find_effect(struct hidpp_ff_private_data *data, int effect_id) | ||
| 881 | { | ||
| 882 | int i; | ||
| 883 | |||
| 884 | for (i = 0; i < data->num_effects; i++) | ||
| 885 | if (data->effect_ids[i] == effect_id) | ||
| 886 | return i+1; | ||
| 887 | |||
| 888 | return 0; | ||
| 889 | } | ||
| 890 | |||
| 891 | static void hidpp_ff_work_handler(struct work_struct *w) | ||
| 892 | { | ||
| 893 | struct hidpp_ff_work_data *wd = container_of(w, struct hidpp_ff_work_data, work); | ||
| 894 | struct hidpp_ff_private_data *data = wd->data; | ||
| 895 | struct hidpp_report response; | ||
| 896 | u8 slot; | ||
| 897 | int ret; | ||
| 898 | |||
| 899 | /* add slot number if needed */ | ||
| 900 | switch (wd->effect_id) { | ||
| 901 | case HIDPP_FF_EFFECTID_AUTOCENTER: | ||
| 902 | wd->params[0] = data->slot_autocenter; | ||
| 903 | break; | ||
| 904 | case HIDPP_FF_EFFECTID_NONE: | ||
| 905 | /* leave slot as zero */ | ||
| 906 | break; | ||
| 907 | default: | ||
| 908 | /* find current slot for effect */ | ||
| 909 | wd->params[0] = hidpp_ff_find_effect(data, wd->effect_id); | ||
| 910 | break; | ||
| 911 | } | ||
| 912 | |||
| 913 | /* send command and wait for reply */ | ||
| 914 | ret = hidpp_send_fap_command_sync(data->hidpp, data->feature_index, | ||
| 915 | wd->command, wd->params, wd->size, &response); | ||
| 916 | |||
| 917 | if (ret) { | ||
| 918 | hid_err(data->hidpp->hid_dev, "Failed to send command to device!\n"); | ||
| 919 | goto out; | ||
| 920 | } | ||
| 921 | |||
| 922 | /* parse return data */ | ||
| 923 | switch (wd->command) { | ||
| 924 | case HIDPP_FF_DOWNLOAD_EFFECT: | ||
| 925 | slot = response.fap.params[0]; | ||
| 926 | if (slot > 0 && slot <= data->num_effects) { | ||
| 927 | if (wd->effect_id >= 0) | ||
| 928 | /* regular effect uploaded */ | ||
| 929 | data->effect_ids[slot-1] = wd->effect_id; | ||
| 930 | else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER) | ||
| 931 | /* autocenter spring uploaded */ | ||
| 932 | data->slot_autocenter = slot; | ||
| 933 | } | ||
| 934 | break; | ||
| 935 | case HIDPP_FF_DESTROY_EFFECT: | ||
| 936 | if (wd->effect_id >= 0) | ||
| 937 | /* regular effect destroyed */ | ||
| 938 | data->effect_ids[wd->params[0]-1] = -1; | ||
| 939 | else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER) | ||
| 940 | /* autocenter spring destoyed */ | ||
| 941 | data->slot_autocenter = 0; | ||
| 942 | break; | ||
| 943 | case HIDPP_FF_SET_GLOBAL_GAINS: | ||
| 944 | data->gain = (wd->params[0] << 8) + wd->params[1]; | ||
| 945 | break; | ||
| 946 | case HIDPP_FF_SET_APERTURE: | ||
| 947 | data->range = (wd->params[0] << 8) + wd->params[1]; | ||
| 948 | break; | ||
| 949 | default: | ||
| 950 | /* no action needed */ | ||
| 951 | break; | ||
| 952 | } | ||
| 953 | |||
| 954 | out: | ||
| 955 | atomic_dec(&data->workqueue_size); | ||
| 956 | kfree(wd); | ||
| 957 | } | ||
| 958 | |||
| 959 | static int hidpp_ff_queue_work(struct hidpp_ff_private_data *data, int effect_id, u8 command, u8 *params, u8 size) | ||
| 960 | { | ||
| 961 | struct hidpp_ff_work_data *wd = kzalloc(sizeof(*wd), GFP_KERNEL); | ||
| 962 | int s; | ||
| 963 | |||
| 964 | if (!wd) | ||
| 965 | return -ENOMEM; | ||
| 966 | |||
| 967 | INIT_WORK(&wd->work, hidpp_ff_work_handler); | ||
| 968 | |||
| 969 | wd->data = data; | ||
| 970 | wd->effect_id = effect_id; | ||
| 971 | wd->command = command; | ||
| 972 | wd->size = size; | ||
| 973 | memcpy(wd->params, params, size); | ||
| 974 | |||
| 975 | atomic_inc(&data->workqueue_size); | ||
| 976 | queue_work(data->wq, &wd->work); | ||
| 977 | |||
| 978 | /* warn about excessive queue size */ | ||
| 979 | s = atomic_read(&data->workqueue_size); | ||
| 980 | if (s >= 20 && s % 20 == 0) | ||
| 981 | hid_warn(data->hidpp->hid_dev, "Force feedback command queue contains %d commands, causing substantial delays!", s); | ||
| 982 | |||
| 983 | return 0; | ||
| 984 | } | ||
| 985 | |||
| 986 | static int hidpp_ff_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old) | ||
| 987 | { | ||
| 988 | struct hidpp_ff_private_data *data = dev->ff->private; | ||
| 989 | u8 params[20]; | ||
| 990 | u8 size; | ||
| 991 | int force; | ||
| 992 | |||
| 993 | /* set common parameters */ | ||
| 994 | params[2] = effect->replay.length >> 8; | ||
| 995 | params[3] = effect->replay.length & 255; | ||
| 996 | params[4] = effect->replay.delay >> 8; | ||
| 997 | params[5] = effect->replay.delay & 255; | ||
| 998 | |||
| 999 | switch (effect->type) { | ||
| 1000 | case FF_CONSTANT: | ||
| 1001 | force = (effect->u.constant.level * fixp_sin16((effect->direction * 360) >> 16)) >> 15; | ||
| 1002 | params[1] = HIDPP_FF_EFFECT_CONSTANT; | ||
| 1003 | params[6] = force >> 8; | ||
| 1004 | params[7] = force & 255; | ||
| 1005 | params[8] = effect->u.constant.envelope.attack_level >> 7; | ||
| 1006 | params[9] = effect->u.constant.envelope.attack_length >> 8; | ||
| 1007 | params[10] = effect->u.constant.envelope.attack_length & 255; | ||
| 1008 | params[11] = effect->u.constant.envelope.fade_level >> 7; | ||
| 1009 | params[12] = effect->u.constant.envelope.fade_length >> 8; | ||
| 1010 | params[13] = effect->u.constant.envelope.fade_length & 255; | ||
| 1011 | size = 14; | ||
| 1012 | dbg_hid("Uploading constant force level=%d in dir %d = %d\n", | ||
| 1013 | effect->u.constant.level, | ||
| 1014 | effect->direction, force); | ||
| 1015 | dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n", | ||
| 1016 | effect->u.constant.envelope.attack_level, | ||
| 1017 | effect->u.constant.envelope.attack_length, | ||
| 1018 | effect->u.constant.envelope.fade_level, | ||
| 1019 | effect->u.constant.envelope.fade_length); | ||
| 1020 | break; | ||
| 1021 | case FF_PERIODIC: | ||
| 1022 | { | ||
| 1023 | switch (effect->u.periodic.waveform) { | ||
| 1024 | case FF_SINE: | ||
| 1025 | params[1] = HIDPP_FF_EFFECT_PERIODIC_SINE; | ||
| 1026 | break; | ||
| 1027 | case FF_SQUARE: | ||
| 1028 | params[1] = HIDPP_FF_EFFECT_PERIODIC_SQUARE; | ||
| 1029 | break; | ||
| 1030 | case FF_SAW_UP: | ||
| 1031 | params[1] = HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHUP; | ||
| 1032 | break; | ||
| 1033 | case FF_SAW_DOWN: | ||
| 1034 | params[1] = HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHDOWN; | ||
| 1035 | break; | ||
| 1036 | case FF_TRIANGLE: | ||
| 1037 | params[1] = HIDPP_FF_EFFECT_PERIODIC_TRIANGLE; | ||
| 1038 | break; | ||
| 1039 | default: | ||
| 1040 | hid_err(data->hidpp->hid_dev, "Unexpected periodic waveform type %i!\n", effect->u.periodic.waveform); | ||
| 1041 | return -EINVAL; | ||
| 1042 | } | ||
| 1043 | force = (effect->u.periodic.magnitude * fixp_sin16((effect->direction * 360) >> 16)) >> 15; | ||
| 1044 | params[6] = effect->u.periodic.magnitude >> 8; | ||
| 1045 | params[7] = effect->u.periodic.magnitude & 255; | ||
| 1046 | params[8] = effect->u.periodic.offset >> 8; | ||
| 1047 | params[9] = effect->u.periodic.offset & 255; | ||
| 1048 | params[10] = effect->u.periodic.period >> 8; | ||
| 1049 | params[11] = effect->u.periodic.period & 255; | ||
| 1050 | params[12] = effect->u.periodic.phase >> 8; | ||
| 1051 | params[13] = effect->u.periodic.phase & 255; | ||
| 1052 | params[14] = effect->u.periodic.envelope.attack_level >> 7; | ||
| 1053 | params[15] = effect->u.periodic.envelope.attack_length >> 8; | ||
| 1054 | params[16] = effect->u.periodic.envelope.attack_length & 255; | ||
| 1055 | params[17] = effect->u.periodic.envelope.fade_level >> 7; | ||
| 1056 | params[18] = effect->u.periodic.envelope.fade_length >> 8; | ||
| 1057 | params[19] = effect->u.periodic.envelope.fade_length & 255; | ||
| 1058 | size = 20; | ||
| 1059 | dbg_hid("Uploading periodic force mag=%d/dir=%d, offset=%d, period=%d ms, phase=%d\n", | ||
| 1060 | effect->u.periodic.magnitude, effect->direction, | ||
| 1061 | effect->u.periodic.offset, | ||
| 1062 | effect->u.periodic.period, | ||
| 1063 | effect->u.periodic.phase); | ||
| 1064 | dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n", | ||
| 1065 | effect->u.periodic.envelope.attack_level, | ||
| 1066 | effect->u.periodic.envelope.attack_length, | ||
| 1067 | effect->u.periodic.envelope.fade_level, | ||
| 1068 | effect->u.periodic.envelope.fade_length); | ||
| 1069 | break; | ||
| 1070 | } | ||
| 1071 | case FF_RAMP: | ||
| 1072 | params[1] = HIDPP_FF_EFFECT_RAMP; | ||
| 1073 | force = (effect->u.ramp.start_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15; | ||
| 1074 | params[6] = force >> 8; | ||
| 1075 | params[7] = force & 255; | ||
| 1076 | force = (effect->u.ramp.end_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15; | ||
| 1077 | params[8] = force >> 8; | ||
| 1078 | params[9] = force & 255; | ||
| 1079 | params[10] = effect->u.ramp.envelope.attack_level >> 7; | ||
| 1080 | params[11] = effect->u.ramp.envelope.attack_length >> 8; | ||
| 1081 | params[12] = effect->u.ramp.envelope.attack_length & 255; | ||
| 1082 | params[13] = effect->u.ramp.envelope.fade_level >> 7; | ||
| 1083 | params[14] = effect->u.ramp.envelope.fade_length >> 8; | ||
| 1084 | params[15] = effect->u.ramp.envelope.fade_length & 255; | ||
| 1085 | size = 16; | ||
| 1086 | dbg_hid("Uploading ramp force level=%d -> %d in dir %d = %d\n", | ||
| 1087 | effect->u.ramp.start_level, | ||
| 1088 | effect->u.ramp.end_level, | ||
| 1089 | effect->direction, force); | ||
| 1090 | dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n", | ||
| 1091 | effect->u.ramp.envelope.attack_level, | ||
| 1092 | effect->u.ramp.envelope.attack_length, | ||
| 1093 | effect->u.ramp.envelope.fade_level, | ||
| 1094 | effect->u.ramp.envelope.fade_length); | ||
| 1095 | break; | ||
| 1096 | case FF_FRICTION: | ||
| 1097 | case FF_INERTIA: | ||
| 1098 | case FF_SPRING: | ||
| 1099 | case FF_DAMPER: | ||
| 1100 | params[1] = HIDPP_FF_CONDITION_CMDS[effect->type - FF_SPRING]; | ||
| 1101 | params[6] = effect->u.condition[0].left_saturation >> 9; | ||
| 1102 | params[7] = (effect->u.condition[0].left_saturation >> 1) & 255; | ||
| 1103 | params[8] = effect->u.condition[0].left_coeff >> 8; | ||
| 1104 | params[9] = effect->u.condition[0].left_coeff & 255; | ||
| 1105 | params[10] = effect->u.condition[0].deadband >> 9; | ||
| 1106 | params[11] = (effect->u.condition[0].deadband >> 1) & 255; | ||
| 1107 | params[12] = effect->u.condition[0].center >> 8; | ||
| 1108 | params[13] = effect->u.condition[0].center & 255; | ||
| 1109 | params[14] = effect->u.condition[0].right_coeff >> 8; | ||
| 1110 | params[15] = effect->u.condition[0].right_coeff & 255; | ||
| 1111 | params[16] = effect->u.condition[0].right_saturation >> 9; | ||
| 1112 | params[17] = (effect->u.condition[0].right_saturation >> 1) & 255; | ||
| 1113 | size = 18; | ||
| 1114 | dbg_hid("Uploading %s force left coeff=%d, left sat=%d, right coeff=%d, right sat=%d\n", | ||
| 1115 | HIDPP_FF_CONDITION_NAMES[effect->type - FF_SPRING], | ||
| 1116 | effect->u.condition[0].left_coeff, | ||
| 1117 | effect->u.condition[0].left_saturation, | ||
| 1118 | effect->u.condition[0].right_coeff, | ||
| 1119 | effect->u.condition[0].right_saturation); | ||
| 1120 | dbg_hid(" deadband=%d, center=%d\n", | ||
| 1121 | effect->u.condition[0].deadband, | ||
| 1122 | effect->u.condition[0].center); | ||
| 1123 | break; | ||
| 1124 | default: | ||
| 1125 | hid_err(data->hidpp->hid_dev, "Unexpected force type %i!\n", effect->type); | ||
| 1126 | return -EINVAL; | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | return hidpp_ff_queue_work(data, effect->id, HIDPP_FF_DOWNLOAD_EFFECT, params, size); | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | static int hidpp_ff_playback(struct input_dev *dev, int effect_id, int value) | ||
| 1133 | { | ||
| 1134 | struct hidpp_ff_private_data *data = dev->ff->private; | ||
| 1135 | u8 params[2]; | ||
| 1136 | |||
| 1137 | params[1] = value ? HIDPP_FF_EFFECT_STATE_PLAY : HIDPP_FF_EFFECT_STATE_STOP; | ||
| 1138 | |||
| 1139 | dbg_hid("St%sing playback of effect %d.\n", value?"art":"opp", effect_id); | ||
| 1140 | |||
| 1141 | return hidpp_ff_queue_work(data, effect_id, HIDPP_FF_SET_EFFECT_STATE, params, ARRAY_SIZE(params)); | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | static int hidpp_ff_erase_effect(struct input_dev *dev, int effect_id) | ||
| 1145 | { | ||
| 1146 | struct hidpp_ff_private_data *data = dev->ff->private; | ||
| 1147 | u8 slot = 0; | ||
| 1148 | |||
| 1149 | dbg_hid("Erasing effect %d.\n", effect_id); | ||
| 1150 | |||
| 1151 | return hidpp_ff_queue_work(data, effect_id, HIDPP_FF_DESTROY_EFFECT, &slot, 1); | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude) | ||
| 1155 | { | ||
| 1156 | struct hidpp_ff_private_data *data = dev->ff->private; | ||
| 1157 | u8 params[18]; | ||
| 1158 | |||
| 1159 | dbg_hid("Setting autocenter to %d.\n", magnitude); | ||
| 1160 | |||
| 1161 | /* start a standard spring effect */ | ||
| 1162 | params[1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART; | ||
| 1163 | /* zero delay and duration */ | ||
| 1164 | params[2] = params[3] = params[4] = params[5] = 0; | ||
| 1165 | /* set coeff to 25% of saturation */ | ||
| 1166 | params[8] = params[14] = magnitude >> 11; | ||
| 1167 | params[9] = params[15] = (magnitude >> 3) & 255; | ||
| 1168 | params[6] = params[16] = magnitude >> 9; | ||
| 1169 | params[7] = params[17] = (magnitude >> 1) & 255; | ||
| 1170 | /* zero deadband and center */ | ||
| 1171 | params[10] = params[11] = params[12] = params[13] = 0; | ||
| 1172 | |||
| 1173 | hidpp_ff_queue_work(data, HIDPP_FF_EFFECTID_AUTOCENTER, HIDPP_FF_DOWNLOAD_EFFECT, params, ARRAY_SIZE(params)); | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | static void hidpp_ff_set_gain(struct input_dev *dev, u16 gain) | ||
| 1177 | { | ||
| 1178 | struct hidpp_ff_private_data *data = dev->ff->private; | ||
| 1179 | u8 params[4]; | ||
| 1180 | |||
| 1181 | dbg_hid("Setting gain to %d.\n", gain); | ||
| 1182 | |||
| 1183 | params[0] = gain >> 8; | ||
| 1184 | params[1] = gain & 255; | ||
| 1185 | params[2] = 0; /* no boost */ | ||
| 1186 | params[3] = 0; | ||
| 1187 | |||
| 1188 | hidpp_ff_queue_work(data, HIDPP_FF_EFFECTID_NONE, HIDPP_FF_SET_GLOBAL_GAINS, params, ARRAY_SIZE(params)); | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | static ssize_t hidpp_ff_range_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 1192 | { | ||
| 1193 | struct hid_device *hid = to_hid_device(dev); | ||
| 1194 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
| 1195 | struct input_dev *idev = hidinput->input; | ||
| 1196 | struct hidpp_ff_private_data *data = idev->ff->private; | ||
| 1197 | |||
| 1198 | return scnprintf(buf, PAGE_SIZE, "%u\n", data->range); | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | static ssize_t hidpp_ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | ||
| 1202 | { | ||
| 1203 | struct hid_device *hid = to_hid_device(dev); | ||
| 1204 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
| 1205 | struct input_dev *idev = hidinput->input; | ||
| 1206 | struct hidpp_ff_private_data *data = idev->ff->private; | ||
| 1207 | u8 params[2]; | ||
| 1208 | int range = simple_strtoul(buf, NULL, 10); | ||
| 1209 | |||
| 1210 | range = clamp(range, 180, 900); | ||
| 1211 | |||
| 1212 | params[0] = range >> 8; | ||
| 1213 | params[1] = range & 0x00FF; | ||
| 1214 | |||
| 1215 | hidpp_ff_queue_work(data, -1, HIDPP_FF_SET_APERTURE, params, ARRAY_SIZE(params)); | ||
| 1216 | |||
| 1217 | return count; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, hidpp_ff_range_show, hidpp_ff_range_store); | ||
| 1221 | |||
| 1222 | static void hidpp_ff_destroy(struct ff_device *ff) | ||
| 1223 | { | ||
| 1224 | struct hidpp_ff_private_data *data = ff->private; | ||
| 1225 | |||
| 1226 | kfree(data->effect_ids); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) | ||
| 1230 | { | ||
| 1231 | struct hid_device *hid = hidpp->hid_dev; | ||
| 1232 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
| 1233 | struct input_dev *dev = hidinput->input; | ||
| 1234 | const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); | ||
| 1235 | const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); | ||
| 1236 | struct ff_device *ff; | ||
| 1237 | struct hidpp_report response; | ||
| 1238 | struct hidpp_ff_private_data *data; | ||
| 1239 | int error, j, num_slots; | ||
| 1240 | u8 version; | ||
| 1241 | |||
| 1242 | if (!dev) { | ||
| 1243 | hid_err(hid, "Struct input_dev not set!\n"); | ||
| 1244 | return -EINVAL; | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | /* Get firmware release */ | ||
| 1248 | version = bcdDevice & 255; | ||
| 1249 | |||
| 1250 | /* Set supported force feedback capabilities */ | ||
| 1251 | for (j = 0; hiddpp_ff_effects[j] >= 0; j++) | ||
| 1252 | set_bit(hiddpp_ff_effects[j], dev->ffbit); | ||
| 1253 | if (version > 1) | ||
| 1254 | for (j = 0; hiddpp_ff_effects_v2[j] >= 0; j++) | ||
| 1255 | set_bit(hiddpp_ff_effects_v2[j], dev->ffbit); | ||
| 1256 | |||
| 1257 | /* Read number of slots available in device */ | ||
| 1258 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1259 | HIDPP_FF_GET_INFO, NULL, 0, &response); | ||
| 1260 | if (error) { | ||
| 1261 | if (error < 0) | ||
| 1262 | return error; | ||
| 1263 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
| 1264 | __func__, error); | ||
| 1265 | return -EPROTO; | ||
| 1266 | } | ||
| 1267 | |||
| 1268 | num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS; | ||
| 1269 | |||
| 1270 | error = input_ff_create(dev, num_slots); | ||
| 1271 | |||
| 1272 | if (error) { | ||
| 1273 | hid_err(dev, "Failed to create FF device!\n"); | ||
| 1274 | return error; | ||
| 1275 | } | ||
| 1276 | |||
| 1277 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
| 1278 | if (!data) | ||
| 1279 | return -ENOMEM; | ||
| 1280 | data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL); | ||
| 1281 | if (!data->effect_ids) { | ||
| 1282 | kfree(data); | ||
| 1283 | return -ENOMEM; | ||
| 1284 | } | ||
| 1285 | data->hidpp = hidpp; | ||
| 1286 | data->feature_index = feature_index; | ||
| 1287 | data->version = version; | ||
| 1288 | data->slot_autocenter = 0; | ||
| 1289 | data->num_effects = num_slots; | ||
| 1290 | for (j = 0; j < num_slots; j++) | ||
| 1291 | data->effect_ids[j] = -1; | ||
| 1292 | |||
| 1293 | ff = dev->ff; | ||
| 1294 | ff->private = data; | ||
| 1295 | |||
| 1296 | ff->upload = hidpp_ff_upload_effect; | ||
| 1297 | ff->erase = hidpp_ff_erase_effect; | ||
| 1298 | ff->playback = hidpp_ff_playback; | ||
| 1299 | ff->set_gain = hidpp_ff_set_gain; | ||
| 1300 | ff->set_autocenter = hidpp_ff_set_autocenter; | ||
| 1301 | ff->destroy = hidpp_ff_destroy; | ||
| 1302 | |||
| 1303 | |||
| 1304 | /* reset all forces */ | ||
| 1305 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1306 | HIDPP_FF_RESET_ALL, NULL, 0, &response); | ||
| 1307 | |||
| 1308 | /* Read current Range */ | ||
| 1309 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1310 | HIDPP_FF_GET_APERTURE, NULL, 0, &response); | ||
| 1311 | if (error) | ||
| 1312 | hid_warn(hidpp->hid_dev, "Failed to read range from device!\n"); | ||
| 1313 | data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]); | ||
| 1314 | |||
| 1315 | /* Create sysfs interface */ | ||
| 1316 | error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); | ||
| 1317 | if (error) | ||
| 1318 | hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error); | ||
| 1319 | |||
| 1320 | /* Read the current gain values */ | ||
| 1321 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1322 | HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response); | ||
| 1323 | if (error) | ||
| 1324 | hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n"); | ||
| 1325 | data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]); | ||
| 1326 | /* ignore boost value at response.fap.params[2] */ | ||
| 1327 | |||
| 1328 | /* init the hardware command queue */ | ||
| 1329 | data->wq = create_singlethread_workqueue("hidpp-ff-sendqueue"); | ||
| 1330 | atomic_set(&data->workqueue_size, 0); | ||
| 1331 | |||
| 1332 | /* initialize with zero autocenter to get wheel in usable state */ | ||
| 1333 | hidpp_ff_set_autocenter(dev, 0); | ||
| 1334 | |||
| 1335 | hid_info(hid, "Force feeback support loaded (firmware release %d).\n", version); | ||
| 1336 | |||
| 1337 | return 0; | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | static int hidpp_ff_deinit(struct hid_device *hid) | ||
| 1341 | { | ||
| 1342 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
| 1343 | struct input_dev *dev = hidinput->input; | ||
| 1344 | struct hidpp_ff_private_data *data; | ||
| 1345 | |||
| 1346 | if (!dev) { | ||
| 1347 | hid_err(hid, "Struct input_dev not found!\n"); | ||
| 1348 | return -EINVAL; | ||
| 1349 | } | ||
| 1350 | |||
| 1351 | hid_info(hid, "Unloading HID++ force feedback.\n"); | ||
| 1352 | data = dev->ff->private; | ||
| 1353 | if (!data) { | ||
| 1354 | hid_err(hid, "Private data not found!\n"); | ||
| 1355 | return -EINVAL; | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | destroy_workqueue(data->wq); | ||
| 1359 | device_remove_file(&hid->dev, &dev_attr_range); | ||
| 1360 | |||
| 1361 | return 0; | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | |||
| 776 | /* ************************************************************************** */ | 1365 | /* ************************************************************************** */ |
| 777 | /* */ | 1366 | /* */ |
| 778 | /* Device Support */ | 1367 | /* Device Support */ |
| @@ -1301,121 +1890,22 @@ static int k400_connect(struct hid_device *hdev, bool connected) | |||
| 1301 | 1890 | ||
| 1302 | #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 | 1891 | #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 |
| 1303 | 1892 | ||
| 1304 | /* Using session ID = 1 */ | ||
| 1305 | #define CMD_G920_FORCE_GET_APERTURE 0x51 | ||
| 1306 | #define CMD_G920_FORCE_SET_APERTURE 0x61 | ||
| 1307 | |||
| 1308 | struct g920_private_data { | ||
| 1309 | u8 force_feature; | ||
| 1310 | u16 range; | ||
| 1311 | }; | ||
| 1312 | |||
| 1313 | static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr, | ||
| 1314 | char *buf) | ||
| 1315 | { | ||
| 1316 | struct hid_device *hid = to_hid_device(dev); | ||
| 1317 | struct hidpp_device *hidpp = hid_get_drvdata(hid); | ||
| 1318 | struct g920_private_data *pdata; | ||
| 1319 | |||
| 1320 | pdata = hidpp->private_data; | ||
| 1321 | if (!pdata) { | ||
| 1322 | hid_err(hid, "Private driver data not found!\n"); | ||
| 1323 | return -EINVAL; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->range); | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | static ssize_t g920_range_store(struct device *dev, struct device_attribute *attr, | ||
| 1330 | const char *buf, size_t count) | ||
| 1331 | { | ||
| 1332 | struct hid_device *hid = to_hid_device(dev); | ||
| 1333 | struct hidpp_device *hidpp = hid_get_drvdata(hid); | ||
| 1334 | struct g920_private_data *pdata; | ||
| 1335 | struct hidpp_report response; | ||
| 1336 | u8 params[2]; | ||
| 1337 | int ret; | ||
| 1338 | u16 range = simple_strtoul(buf, NULL, 10); | ||
| 1339 | |||
| 1340 | pdata = hidpp->private_data; | ||
| 1341 | if (!pdata) { | ||
| 1342 | hid_err(hid, "Private driver data not found!\n"); | ||
| 1343 | return -EINVAL; | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | if (range < 180) | ||
| 1347 | range = 180; | ||
| 1348 | else if (range > 900) | ||
| 1349 | range = 900; | ||
| 1350 | |||
| 1351 | params[0] = range >> 8; | ||
| 1352 | params[1] = range & 0x00FF; | ||
| 1353 | |||
| 1354 | ret = hidpp_send_fap_command_sync(hidpp, pdata->force_feature, | ||
| 1355 | CMD_G920_FORCE_SET_APERTURE, params, 2, &response); | ||
| 1356 | if (ret) | ||
| 1357 | return ret; | ||
| 1358 | |||
| 1359 | pdata->range = range; | ||
| 1360 | return count; | ||
| 1361 | } | ||
| 1362 | |||
| 1363 | static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, g920_range_show, g920_range_store); | ||
| 1364 | |||
| 1365 | static int g920_allocate(struct hid_device *hdev) | ||
| 1366 | { | ||
| 1367 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
| 1368 | struct g920_private_data *pdata; | ||
| 1369 | |||
| 1370 | pdata = devm_kzalloc(&hdev->dev, sizeof(struct g920_private_data), | ||
| 1371 | GFP_KERNEL); | ||
| 1372 | if (!pdata) | ||
| 1373 | return -ENOMEM; | ||
| 1374 | |||
| 1375 | hidpp->private_data = pdata; | ||
| 1376 | |||
| 1377 | return 0; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | static int g920_get_config(struct hidpp_device *hidpp) | 1893 | static int g920_get_config(struct hidpp_device *hidpp) |
| 1381 | { | 1894 | { |
| 1382 | struct g920_private_data *pdata = hidpp->private_data; | ||
| 1383 | struct hidpp_report response; | ||
| 1384 | u8 feature_type; | 1895 | u8 feature_type; |
| 1385 | u8 feature_index; | 1896 | u8 feature_index; |
| 1386 | int ret; | 1897 | int ret; |
| 1387 | 1898 | ||
| 1388 | pdata = hidpp->private_data; | ||
| 1389 | if (!pdata) { | ||
| 1390 | hid_err(hidpp->hid_dev, "Private driver data not found!\n"); | ||
| 1391 | return -EINVAL; | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | /* Find feature and store for later use */ | 1899 | /* Find feature and store for later use */ |
| 1395 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, | 1900 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, |
| 1396 | &feature_index, &feature_type); | 1901 | &feature_index, &feature_type); |
| 1397 | if (ret) | 1902 | if (ret) |
| 1398 | return ret; | 1903 | return ret; |
| 1399 | 1904 | ||
| 1400 | pdata->force_feature = feature_index; | 1905 | ret = hidpp_ff_init(hidpp, feature_index); |
| 1401 | |||
| 1402 | /* Read current Range */ | ||
| 1403 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1404 | CMD_G920_FORCE_GET_APERTURE, NULL, 0, &response); | ||
| 1405 | if (ret > 0) { | ||
| 1406 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
| 1407 | __func__, ret); | ||
| 1408 | return -EPROTO; | ||
| 1409 | } | ||
| 1410 | if (ret) | ||
| 1411 | return ret; | ||
| 1412 | |||
| 1413 | pdata->range = get_unaligned_be16(&response.fap.params[0]); | ||
| 1414 | |||
| 1415 | /* Create sysfs interface */ | ||
| 1416 | ret = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); | ||
| 1417 | if (ret) | 1906 | if (ret) |
| 1418 | hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d\n", ret); | 1907 | hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n", |
| 1908 | ret); | ||
| 1419 | 1909 | ||
| 1420 | return 0; | 1910 | return 0; |
| 1421 | } | 1911 | } |
| @@ -1739,10 +2229,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1739 | ret = k400_allocate(hdev); | 2229 | ret = k400_allocate(hdev); |
| 1740 | if (ret) | 2230 | if (ret) |
| 1741 | goto allocate_fail; | 2231 | goto allocate_fail; |
| 1742 | } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { | ||
| 1743 | ret = g920_allocate(hdev); | ||
| 1744 | if (ret) | ||
| 1745 | goto allocate_fail; | ||
| 1746 | } | 2232 | } |
| 1747 | 2233 | ||
| 1748 | INIT_WORK(&hidpp->work, delayed_work_cb); | 2234 | INIT_WORK(&hidpp->work, delayed_work_cb); |
| @@ -1825,7 +2311,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1825 | hid_hw_open_failed: | 2311 | hid_hw_open_failed: |
| 1826 | hid_device_io_stop(hdev); | 2312 | hid_device_io_stop(hdev); |
| 1827 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { | 2313 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { |
| 1828 | device_remove_file(&hdev->dev, &dev_attr_range); | ||
| 1829 | hid_hw_close(hdev); | 2314 | hid_hw_close(hdev); |
| 1830 | hid_hw_stop(hdev); | 2315 | hid_hw_stop(hdev); |
| 1831 | } | 2316 | } |
| @@ -1843,7 +2328,7 @@ static void hidpp_remove(struct hid_device *hdev) | |||
| 1843 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | 2328 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); |
| 1844 | 2329 | ||
| 1845 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { | 2330 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { |
| 1846 | device_remove_file(&hdev->dev, &dev_attr_range); | 2331 | hidpp_ff_deinit(hdev); |
| 1847 | hid_hw_close(hdev); | 2332 | hid_hw_close(hdev); |
| 1848 | } | 2333 | } |
| 1849 | hid_hw_stop(hdev); | 2334 | hid_hw_stop(hdev); |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 77a2cf3e4afe..75cd3bc59c54 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
| @@ -286,6 +286,8 @@ static const struct hid_device_id ms_devices[] = { | |||
| 286 | .driver_data = MS_HIDINPUT }, | 286 | .driver_data = MS_HIDINPUT }, |
| 287 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), | 287 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), |
| 288 | .driver_data = MS_HIDINPUT }, | 288 | .driver_data = MS_HIDINPUT }, |
| 289 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD), | ||
| 290 | .driver_data = MS_ERGONOMY}, | ||
| 289 | 291 | ||
| 290 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), | 292 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), |
| 291 | .driver_data = MS_PRESENTER }, | 293 | .driver_data = MS_PRESENTER }, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 296d4991560e..25d3c4330bf6 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -396,6 +396,11 @@ static void mt_feature_mapping(struct hid_device *hdev, | |||
| 396 | td->is_buttonpad = true; | 396 | td->is_buttonpad = true; |
| 397 | 397 | ||
| 398 | break; | 398 | break; |
| 399 | case 0xff0000c5: | ||
| 400 | /* Retrieve the Win8 blob once to enable some devices */ | ||
| 401 | if (usage->usage_index == 0) | ||
| 402 | mt_get_feature(hdev, field->report); | ||
| 403 | break; | ||
| 399 | } | 404 | } |
| 400 | } | 405 | } |
| 401 | 406 | ||
| @@ -1133,6 +1138,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1133 | return ret; | 1138 | return ret; |
| 1134 | 1139 | ||
| 1135 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); | 1140 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); |
| 1141 | if (ret) | ||
| 1142 | dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s\n", | ||
| 1143 | hdev->name); | ||
| 1136 | 1144 | ||
| 1137 | mt_set_maxcontacts(hdev); | 1145 | mt_set_maxcontacts(hdev); |
| 1138 | mt_set_input_mode(hdev); | 1146 | mt_set_input_mode(hdev); |
| @@ -1145,8 +1153,30 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 1145 | } | 1153 | } |
| 1146 | 1154 | ||
| 1147 | #ifdef CONFIG_PM | 1155 | #ifdef CONFIG_PM |
| 1156 | static void mt_release_contacts(struct hid_device *hid) | ||
| 1157 | { | ||
| 1158 | struct hid_input *hidinput; | ||
| 1159 | |||
| 1160 | list_for_each_entry(hidinput, &hid->inputs, list) { | ||
| 1161 | struct input_dev *input_dev = hidinput->input; | ||
| 1162 | struct input_mt *mt = input_dev->mt; | ||
| 1163 | int i; | ||
| 1164 | |||
| 1165 | if (mt) { | ||
| 1166 | for (i = 0; i < mt->num_slots; i++) { | ||
| 1167 | input_mt_slot(input_dev, i); | ||
| 1168 | input_mt_report_slot_state(input_dev, | ||
| 1169 | MT_TOOL_FINGER, | ||
| 1170 | false); | ||
| 1171 | } | ||
| 1172 | input_sync(input_dev); | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | } | ||
| 1176 | |||
| 1148 | static int mt_reset_resume(struct hid_device *hdev) | 1177 | static int mt_reset_resume(struct hid_device *hdev) |
| 1149 | { | 1178 | { |
| 1179 | mt_release_contacts(hdev); | ||
| 1150 | mt_set_maxcontacts(hdev); | 1180 | mt_set_maxcontacts(hdev); |
| 1151 | mt_set_input_mode(hdev); | 1181 | mt_set_input_mode(hdev); |
| 1152 | return 0; | 1182 | return 0; |
diff --git a/drivers/hid/hid-penmount.c b/drivers/hid/hid-penmount.c index c11dce85cd18..d90383f788e2 100644 --- a/drivers/hid/hid-penmount.c +++ b/drivers/hid/hid-penmount.c | |||
| @@ -23,8 +23,12 @@ static int penmount_input_mapping(struct hid_device *hdev, | |||
| 23 | struct hid_usage *usage, unsigned long **bit, int *max) | 23 | struct hid_usage *usage, unsigned long **bit, int *max) |
| 24 | { | 24 | { |
| 25 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { | 25 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { |
| 26 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 26 | if (((usage->hid - 1) & HID_USAGE) == 0) { |
| 27 | return 1; | 27 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
| 28 | return 1; | ||
| 29 | } else { | ||
| 30 | return -1; | ||
| 31 | } | ||
| 28 | } | 32 | } |
| 29 | 33 | ||
| 30 | return 0; | 34 | return 0; |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 67cd059a8f46..9cd2ca34a6be 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
| @@ -594,6 +594,9 @@ static int rmi_suspend(struct hid_device *hdev, pm_message_t message) | |||
| 594 | int ret; | 594 | int ret; |
| 595 | u8 buf[RMI_F11_CTRL_REG_COUNT]; | 595 | u8 buf[RMI_F11_CTRL_REG_COUNT]; |
| 596 | 596 | ||
| 597 | if (!(data->device_flags & RMI_DEVICE)) | ||
| 598 | return 0; | ||
| 599 | |||
| 597 | ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, | 600 | ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, |
| 598 | RMI_F11_CTRL_REG_COUNT); | 601 | RMI_F11_CTRL_REG_COUNT); |
| 599 | if (ret) | 602 | if (ret) |
| @@ -613,6 +616,9 @@ static int rmi_post_reset(struct hid_device *hdev) | |||
| 613 | struct rmi_data *data = hid_get_drvdata(hdev); | 616 | struct rmi_data *data = hid_get_drvdata(hdev); |
| 614 | int ret; | 617 | int ret; |
| 615 | 618 | ||
| 619 | if (!(data->device_flags & RMI_DEVICE)) | ||
| 620 | return 0; | ||
| 621 | |||
| 616 | ret = rmi_reset_attn_mode(hdev); | 622 | ret = rmi_reset_attn_mode(hdev); |
| 617 | if (ret) { | 623 | if (ret) { |
| 618 | hid_err(hdev, "can not set rmi mode\n"); | 624 | hid_err(hdev, "can not set rmi mode\n"); |
| @@ -640,6 +646,11 @@ static int rmi_post_reset(struct hid_device *hdev) | |||
| 640 | 646 | ||
| 641 | static int rmi_post_resume(struct hid_device *hdev) | 647 | static int rmi_post_resume(struct hid_device *hdev) |
| 642 | { | 648 | { |
| 649 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
| 650 | |||
| 651 | if (!(data->device_flags & RMI_DEVICE)) | ||
| 652 | return 0; | ||
| 653 | |||
| 643 | return rmi_reset_attn_mode(hdev); | 654 | return rmi_reset_attn_mode(hdev); |
| 644 | } | 655 | } |
| 645 | #endif /* CONFIG_PM */ | 656 | #endif /* CONFIG_PM */ |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 9b8db0e0ef1c..310436a54a3f 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #define MOTION_CONTROLLER_BT BIT(8) | 50 | #define MOTION_CONTROLLER_BT BIT(8) |
| 51 | #define NAVIGATION_CONTROLLER_USB BIT(9) | 51 | #define NAVIGATION_CONTROLLER_USB BIT(9) |
| 52 | #define NAVIGATION_CONTROLLER_BT BIT(10) | 52 | #define NAVIGATION_CONTROLLER_BT BIT(10) |
| 53 | #define SINO_LITE_CONTROLLER BIT(11) | ||
| 53 | 54 | ||
| 54 | #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) | 55 | #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) |
| 55 | #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) | 56 | #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) |
| @@ -74,7 +75,7 @@ | |||
| 74 | * axis values. Additionally, the controller only has 20 actual, physical axes | 75 | * axis values. Additionally, the controller only has 20 actual, physical axes |
| 75 | * so there are several unused axes in between the used ones. | 76 | * so there are several unused axes in between the used ones. |
| 76 | */ | 77 | */ |
| 77 | static __u8 sixaxis_rdesc[] = { | 78 | static u8 sixaxis_rdesc[] = { |
| 78 | 0x05, 0x01, /* Usage Page (Desktop), */ | 79 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 79 | 0x09, 0x04, /* Usage (Joystick), */ | 80 | 0x09, 0x04, /* Usage (Joystick), */ |
| 80 | 0xA1, 0x01, /* Collection (Application), */ | 81 | 0xA1, 0x01, /* Collection (Application), */ |
| @@ -152,7 +153,7 @@ static __u8 sixaxis_rdesc[] = { | |||
| 152 | }; | 153 | }; |
| 153 | 154 | ||
| 154 | /* PS/3 Motion controller */ | 155 | /* PS/3 Motion controller */ |
| 155 | static __u8 motion_rdesc[] = { | 156 | static u8 motion_rdesc[] = { |
| 156 | 0x05, 0x01, /* Usage Page (Desktop), */ | 157 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 157 | 0x09, 0x04, /* Usage (Joystick), */ | 158 | 0x09, 0x04, /* Usage (Joystick), */ |
| 158 | 0xA1, 0x01, /* Collection (Application), */ | 159 | 0xA1, 0x01, /* Collection (Application), */ |
| @@ -249,9 +250,9 @@ static __u8 motion_rdesc[] = { | |||
| 249 | }; | 250 | }; |
| 250 | 251 | ||
| 251 | /* PS/3 Navigation controller */ | 252 | /* PS/3 Navigation controller */ |
| 252 | static __u8 navigation_rdesc[] = { | 253 | static u8 navigation_rdesc[] = { |
| 253 | 0x05, 0x01, /* Usage Page (Desktop), */ | 254 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 254 | 0x09, 0x04, /* Usage (Joystik), */ | 255 | 0x09, 0x04, /* Usage (Joystick), */ |
| 255 | 0xA1, 0x01, /* Collection (Application), */ | 256 | 0xA1, 0x01, /* Collection (Application), */ |
| 256 | 0xA1, 0x02, /* Collection (Logical), */ | 257 | 0xA1, 0x02, /* Collection (Logical), */ |
| 257 | 0x85, 0x01, /* Report ID (1), */ | 258 | 0x85, 0x01, /* Report ID (1), */ |
| @@ -809,7 +810,7 @@ static u8 dualshock4_bt_rdesc[] = { | |||
| 809 | 0xC0 /* End Collection */ | 810 | 0xC0 /* End Collection */ |
| 810 | }; | 811 | }; |
| 811 | 812 | ||
| 812 | static __u8 ps3remote_rdesc[] = { | 813 | static u8 ps3remote_rdesc[] = { |
| 813 | 0x05, 0x01, /* GUsagePage Generic Desktop */ | 814 | 0x05, 0x01, /* GUsagePage Generic Desktop */ |
| 814 | 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ | 815 | 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ |
| 815 | 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ | 816 | 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ |
| @@ -817,14 +818,18 @@ static __u8 ps3remote_rdesc[] = { | |||
| 817 | /* Use collection 1 for joypad buttons */ | 818 | /* Use collection 1 for joypad buttons */ |
| 818 | 0xA1, 0x02, /* MCollection Logical (interrelated data) */ | 819 | 0xA1, 0x02, /* MCollection Logical (interrelated data) */ |
| 819 | 820 | ||
| 820 | /* Ignore the 1st byte, maybe it is used for a controller | 821 | /* |
| 821 | * number but it's not needed for correct operation */ | 822 | * Ignore the 1st byte, maybe it is used for a controller |
| 823 | * number but it's not needed for correct operation | ||
| 824 | */ | ||
| 822 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | 825 | 0x75, 0x08, /* GReportSize 0x08 [8] */ |
| 823 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | 826 | 0x95, 0x01, /* GReportCount 0x01 [1] */ |
| 824 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ | 827 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ |
| 825 | 828 | ||
| 826 | /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these | 829 | /* |
| 827 | * buttons multiple keypresses are allowed */ | 830 | * Bytes from 2nd to 4th are a bitmap for joypad buttons, for these |
| 831 | * buttons multiple keypresses are allowed | ||
| 832 | */ | ||
| 828 | 0x05, 0x09, /* GUsagePage Button */ | 833 | 0x05, 0x09, /* GUsagePage Button */ |
| 829 | 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ | 834 | 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ |
| 830 | 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ | 835 | 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ |
| @@ -849,8 +854,10 @@ static __u8 ps3remote_rdesc[] = { | |||
| 849 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | 854 | 0x95, 0x01, /* GReportCount 0x01 [1] */ |
| 850 | 0x80, /* MInput */ | 855 | 0x80, /* MInput */ |
| 851 | 856 | ||
| 852 | /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at | 857 | /* |
| 853 | * 0xff and 11th is for press indication */ | 858 | * Ignore bytes from 6th to 11th, 6th to 10th are always constant at |
| 859 | * 0xff and 11th is for press indication | ||
| 860 | */ | ||
| 854 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | 861 | 0x75, 0x08, /* GReportSize 0x08 [8] */ |
| 855 | 0x95, 0x06, /* GReportCount 0x06 [6] */ | 862 | 0x95, 0x06, /* GReportCount 0x06 [6] */ |
| 856 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ | 863 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ |
| @@ -929,7 +936,7 @@ static const unsigned int buzz_keymap[] = { | |||
| 929 | /* | 936 | /* |
| 930 | * The controller has 4 remote buzzers, each with one LED and 5 | 937 | * The controller has 4 remote buzzers, each with one LED and 5 |
| 931 | * buttons. | 938 | * buttons. |
| 932 | * | 939 | * |
| 933 | * We use the mapping chosen by the controller, which is: | 940 | * We use the mapping chosen by the controller, which is: |
| 934 | * | 941 | * |
| 935 | * Key Offset | 942 | * Key Offset |
| @@ -943,15 +950,15 @@ static const unsigned int buzz_keymap[] = { | |||
| 943 | * So, for example, the orange button on the third buzzer is mapped to | 950 | * So, for example, the orange button on the third buzzer is mapped to |
| 944 | * BTN_TRIGGER_HAPPY14 | 951 | * BTN_TRIGGER_HAPPY14 |
| 945 | */ | 952 | */ |
| 946 | [ 1] = BTN_TRIGGER_HAPPY1, | 953 | [1] = BTN_TRIGGER_HAPPY1, |
| 947 | [ 2] = BTN_TRIGGER_HAPPY2, | 954 | [2] = BTN_TRIGGER_HAPPY2, |
| 948 | [ 3] = BTN_TRIGGER_HAPPY3, | 955 | [3] = BTN_TRIGGER_HAPPY3, |
| 949 | [ 4] = BTN_TRIGGER_HAPPY4, | 956 | [4] = BTN_TRIGGER_HAPPY4, |
| 950 | [ 5] = BTN_TRIGGER_HAPPY5, | 957 | [5] = BTN_TRIGGER_HAPPY5, |
| 951 | [ 6] = BTN_TRIGGER_HAPPY6, | 958 | [6] = BTN_TRIGGER_HAPPY6, |
| 952 | [ 7] = BTN_TRIGGER_HAPPY7, | 959 | [7] = BTN_TRIGGER_HAPPY7, |
| 953 | [ 8] = BTN_TRIGGER_HAPPY8, | 960 | [8] = BTN_TRIGGER_HAPPY8, |
| 954 | [ 9] = BTN_TRIGGER_HAPPY9, | 961 | [9] = BTN_TRIGGER_HAPPY9, |
| 955 | [10] = BTN_TRIGGER_HAPPY10, | 962 | [10] = BTN_TRIGGER_HAPPY10, |
| 956 | [11] = BTN_TRIGGER_HAPPY11, | 963 | [11] = BTN_TRIGGER_HAPPY11, |
| 957 | [12] = BTN_TRIGGER_HAPPY12, | 964 | [12] = BTN_TRIGGER_HAPPY12, |
| @@ -973,33 +980,33 @@ static enum power_supply_property sony_battery_props[] = { | |||
| 973 | }; | 980 | }; |
| 974 | 981 | ||
| 975 | struct sixaxis_led { | 982 | struct sixaxis_led { |
| 976 | __u8 time_enabled; /* the total time the led is active (0xff means forever) */ | 983 | u8 time_enabled; /* the total time the led is active (0xff means forever) */ |
| 977 | __u8 duty_length; /* how long a cycle is in deciseconds (0 means "really fast") */ | 984 | u8 duty_length; /* how long a cycle is in deciseconds (0 means "really fast") */ |
| 978 | __u8 enabled; | 985 | u8 enabled; |
| 979 | __u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */ | 986 | u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */ |
| 980 | __u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */ | 987 | u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */ |
| 981 | } __packed; | 988 | } __packed; |
| 982 | 989 | ||
| 983 | struct sixaxis_rumble { | 990 | struct sixaxis_rumble { |
| 984 | __u8 padding; | 991 | u8 padding; |
| 985 | __u8 right_duration; /* Right motor duration (0xff means forever) */ | 992 | u8 right_duration; /* Right motor duration (0xff means forever) */ |
| 986 | __u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */ | 993 | u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */ |
| 987 | __u8 left_duration; /* Left motor duration (0xff means forever) */ | 994 | u8 left_duration; /* Left motor duration (0xff means forever) */ |
| 988 | __u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */ | 995 | u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */ |
| 989 | } __packed; | 996 | } __packed; |
| 990 | 997 | ||
| 991 | struct sixaxis_output_report { | 998 | struct sixaxis_output_report { |
| 992 | __u8 report_id; | 999 | u8 report_id; |
| 993 | struct sixaxis_rumble rumble; | 1000 | struct sixaxis_rumble rumble; |
| 994 | __u8 padding[4]; | 1001 | u8 padding[4]; |
| 995 | __u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */ | 1002 | u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */ |
| 996 | struct sixaxis_led led[4]; /* LEDx at (4 - x) */ | 1003 | struct sixaxis_led led[4]; /* LEDx at (4 - x) */ |
| 997 | struct sixaxis_led _reserved; /* LED5, not actually soldered */ | 1004 | struct sixaxis_led _reserved; /* LED5, not actually soldered */ |
| 998 | } __packed; | 1005 | } __packed; |
| 999 | 1006 | ||
| 1000 | union sixaxis_output_report_01 { | 1007 | union sixaxis_output_report_01 { |
| 1001 | struct sixaxis_output_report data; | 1008 | struct sixaxis_output_report data; |
| 1002 | __u8 buf[36]; | 1009 | u8 buf[36]; |
| 1003 | }; | 1010 | }; |
| 1004 | 1011 | ||
| 1005 | struct motion_output_report_02 { | 1012 | struct motion_output_report_02 { |
| @@ -1028,30 +1035,30 @@ struct sony_sc { | |||
| 1028 | struct led_classdev *leds[MAX_LEDS]; | 1035 | struct led_classdev *leds[MAX_LEDS]; |
| 1029 | unsigned long quirks; | 1036 | unsigned long quirks; |
| 1030 | struct work_struct state_worker; | 1037 | struct work_struct state_worker; |
| 1031 | void(*send_output_report)(struct sony_sc*); | 1038 | void (*send_output_report)(struct sony_sc *); |
| 1032 | struct power_supply *battery; | 1039 | struct power_supply *battery; |
| 1033 | struct power_supply_desc battery_desc; | 1040 | struct power_supply_desc battery_desc; |
| 1034 | int device_id; | 1041 | int device_id; |
| 1035 | __u8 *output_report_dmabuf; | 1042 | u8 *output_report_dmabuf; |
| 1036 | 1043 | ||
| 1037 | #ifdef CONFIG_SONY_FF | 1044 | #ifdef CONFIG_SONY_FF |
| 1038 | __u8 left; | 1045 | u8 left; |
| 1039 | __u8 right; | 1046 | u8 right; |
| 1040 | #endif | 1047 | #endif |
| 1041 | 1048 | ||
| 1042 | __u8 mac_address[6]; | 1049 | u8 mac_address[6]; |
| 1043 | __u8 worker_initialized; | 1050 | u8 worker_initialized; |
| 1044 | __u8 cable_state; | 1051 | u8 cable_state; |
| 1045 | __u8 battery_charging; | 1052 | u8 battery_charging; |
| 1046 | __u8 battery_capacity; | 1053 | u8 battery_capacity; |
| 1047 | __u8 led_state[MAX_LEDS]; | 1054 | u8 led_state[MAX_LEDS]; |
| 1048 | __u8 resume_led_state[MAX_LEDS]; | 1055 | u8 resume_led_state[MAX_LEDS]; |
| 1049 | __u8 led_delay_on[MAX_LEDS]; | 1056 | u8 led_delay_on[MAX_LEDS]; |
| 1050 | __u8 led_delay_off[MAX_LEDS]; | 1057 | u8 led_delay_off[MAX_LEDS]; |
| 1051 | __u8 led_count; | 1058 | u8 led_count; |
| 1052 | }; | 1059 | }; |
| 1053 | 1060 | ||
| 1054 | static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc, | 1061 | static u8 *sixaxis_fixup(struct hid_device *hdev, u8 *rdesc, |
| 1055 | unsigned int *rsize) | 1062 | unsigned int *rsize) |
| 1056 | { | 1063 | { |
| 1057 | *rsize = sizeof(sixaxis_rdesc); | 1064 | *rsize = sizeof(sixaxis_rdesc); |
| @@ -1072,7 +1079,7 @@ static u8 *navigation_fixup(struct hid_device *hdev, u8 *rdesc, | |||
| 1072 | return navigation_rdesc; | 1079 | return navigation_rdesc; |
| 1073 | } | 1080 | } |
| 1074 | 1081 | ||
| 1075 | static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, | 1082 | static u8 *ps3remote_fixup(struct hid_device *hdev, u8 *rdesc, |
| 1076 | unsigned int *rsize) | 1083 | unsigned int *rsize) |
| 1077 | { | 1084 | { |
| 1078 | *rsize = sizeof(ps3remote_rdesc); | 1085 | *rsize = sizeof(ps3remote_rdesc); |
| @@ -1113,11 +1120,14 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 1113 | return 1; | 1120 | return 1; |
| 1114 | } | 1121 | } |
| 1115 | 1122 | ||
| 1116 | static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 1123 | static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc, |
| 1117 | unsigned int *rsize) | 1124 | unsigned int *rsize) |
| 1118 | { | 1125 | { |
| 1119 | struct sony_sc *sc = hid_get_drvdata(hdev); | 1126 | struct sony_sc *sc = hid_get_drvdata(hdev); |
| 1120 | 1127 | ||
| 1128 | if (sc->quirks & SINO_LITE_CONTROLLER) | ||
| 1129 | return rdesc; | ||
| 1130 | |||
| 1121 | /* | 1131 | /* |
| 1122 | * Some Sony RF receivers wrongly declare the mouse pointer as a | 1132 | * Some Sony RF receivers wrongly declare the mouse pointer as a |
| 1123 | * a constant non-data variable. | 1133 | * a constant non-data variable. |
| @@ -1164,12 +1174,12 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 1164 | return rdesc; | 1174 | return rdesc; |
| 1165 | } | 1175 | } |
| 1166 | 1176 | ||
| 1167 | static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) | 1177 | static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size) |
| 1168 | { | 1178 | { |
| 1169 | static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; | 1179 | static const u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; |
| 1170 | unsigned long flags; | 1180 | unsigned long flags; |
| 1171 | int offset; | 1181 | int offset; |
| 1172 | __u8 cable_state, battery_capacity, battery_charging; | 1182 | u8 cable_state, battery_capacity, battery_charging; |
| 1173 | 1183 | ||
| 1174 | /* | 1184 | /* |
| 1175 | * The sixaxis is charging if the battery value is 0xee | 1185 | * The sixaxis is charging if the battery value is 0xee |
| @@ -1184,7 +1194,7 @@ static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) | |||
| 1184 | battery_charging = !(rd[offset] & 0x01); | 1194 | battery_charging = !(rd[offset] & 0x01); |
| 1185 | cable_state = 1; | 1195 | cable_state = 1; |
| 1186 | } else { | 1196 | } else { |
| 1187 | __u8 index = rd[offset] <= 5 ? rd[offset] : 5; | 1197 | u8 index = rd[offset] <= 5 ? rd[offset] : 5; |
| 1188 | battery_capacity = sixaxis_battery_capacity[index]; | 1198 | battery_capacity = sixaxis_battery_capacity[index]; |
| 1189 | battery_charging = 0; | 1199 | battery_charging = 0; |
| 1190 | cable_state = 0; | 1200 | cable_state = 0; |
| @@ -1197,14 +1207,14 @@ static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) | |||
| 1197 | spin_unlock_irqrestore(&sc->lock, flags); | 1207 | spin_unlock_irqrestore(&sc->lock, flags); |
| 1198 | } | 1208 | } |
| 1199 | 1209 | ||
| 1200 | static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) | 1210 | static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) |
| 1201 | { | 1211 | { |
| 1202 | struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, | 1212 | struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, |
| 1203 | struct hid_input, list); | 1213 | struct hid_input, list); |
| 1204 | struct input_dev *input_dev = hidinput->input; | 1214 | struct input_dev *input_dev = hidinput->input; |
| 1205 | unsigned long flags; | 1215 | unsigned long flags; |
| 1206 | int n, offset; | 1216 | int n, offset; |
| 1207 | __u8 cable_state, battery_capacity, battery_charging; | 1217 | u8 cable_state, battery_capacity, battery_charging; |
| 1208 | 1218 | ||
| 1209 | /* | 1219 | /* |
| 1210 | * Battery and touchpad data starts at byte 30 in the USB report and | 1220 | * Battery and touchpad data starts at byte 30 in the USB report and |
| @@ -1254,7 +1264,7 @@ static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) | |||
| 1254 | * follows the data for the first. | 1264 | * follows the data for the first. |
| 1255 | */ | 1265 | */ |
| 1256 | for (n = 0; n < 2; n++) { | 1266 | for (n = 0; n < 2; n++) { |
| 1257 | __u16 x, y; | 1267 | u16 x, y; |
| 1258 | 1268 | ||
| 1259 | x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); | 1269 | x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); |
| 1260 | y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); | 1270 | y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); |
| @@ -1270,7 +1280,7 @@ static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) | |||
| 1270 | } | 1280 | } |
| 1271 | 1281 | ||
| 1272 | static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, | 1282 | static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, |
| 1273 | __u8 *rd, int size) | 1283 | u8 *rd, int size) |
| 1274 | { | 1284 | { |
| 1275 | struct sony_sc *sc = hid_get_drvdata(hdev); | 1285 | struct sony_sc *sc = hid_get_drvdata(hdev); |
| 1276 | 1286 | ||
| @@ -1394,7 +1404,7 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) | |||
| 1394 | { | 1404 | { |
| 1395 | const int buf_size = | 1405 | const int buf_size = |
| 1396 | max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); | 1406 | max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); |
| 1397 | __u8 *buf; | 1407 | u8 *buf; |
| 1398 | int ret; | 1408 | int ret; |
| 1399 | 1409 | ||
| 1400 | buf = kmalloc(buf_size, GFP_KERNEL); | 1410 | buf = kmalloc(buf_size, GFP_KERNEL); |
| @@ -1420,8 +1430,10 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) | |||
| 1420 | } | 1430 | } |
| 1421 | 1431 | ||
| 1422 | ret = hid_hw_output_report(hdev, buf, 1); | 1432 | ret = hid_hw_output_report(hdev, buf, 1); |
| 1423 | if (ret < 0) | 1433 | if (ret < 0) { |
| 1424 | hid_err(hdev, "can't set operational mode: step 3\n"); | 1434 | hid_info(hdev, "can't set operational mode: step 3, ignoring\n"); |
| 1435 | ret = 0; | ||
| 1436 | } | ||
| 1425 | 1437 | ||
| 1426 | out: | 1438 | out: |
| 1427 | kfree(buf); | 1439 | kfree(buf); |
| @@ -1431,8 +1443,8 @@ out: | |||
| 1431 | 1443 | ||
| 1432 | static int sixaxis_set_operational_bt(struct hid_device *hdev) | 1444 | static int sixaxis_set_operational_bt(struct hid_device *hdev) |
| 1433 | { | 1445 | { |
| 1434 | static const __u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; | 1446 | static const u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; |
| 1435 | __u8 *buf; | 1447 | u8 *buf; |
| 1436 | int ret; | 1448 | int ret; |
| 1437 | 1449 | ||
| 1438 | buf = kmemdup(report, sizeof(report), GFP_KERNEL); | 1450 | buf = kmemdup(report, sizeof(report), GFP_KERNEL); |
| @@ -1453,7 +1465,7 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev) | |||
| 1453 | */ | 1465 | */ |
| 1454 | static int dualshock4_set_operational_bt(struct hid_device *hdev) | 1466 | static int dualshock4_set_operational_bt(struct hid_device *hdev) |
| 1455 | { | 1467 | { |
| 1456 | __u8 *buf; | 1468 | u8 *buf; |
| 1457 | int ret; | 1469 | int ret; |
| 1458 | 1470 | ||
| 1459 | buf = kmalloc(DS4_REPORT_0x02_SIZE, GFP_KERNEL); | 1471 | buf = kmalloc(DS4_REPORT_0x02_SIZE, GFP_KERNEL); |
| @@ -1470,7 +1482,7 @@ static int dualshock4_set_operational_bt(struct hid_device *hdev) | |||
| 1470 | 1482 | ||
| 1471 | static void sixaxis_set_leds_from_id(struct sony_sc *sc) | 1483 | static void sixaxis_set_leds_from_id(struct sony_sc *sc) |
| 1472 | { | 1484 | { |
| 1473 | static const __u8 sixaxis_leds[10][4] = { | 1485 | static const u8 sixaxis_leds[10][4] = { |
| 1474 | { 0x01, 0x00, 0x00, 0x00 }, | 1486 | { 0x01, 0x00, 0x00, 0x00 }, |
| 1475 | { 0x00, 0x01, 0x00, 0x00 }, | 1487 | { 0x00, 0x01, 0x00, 0x00 }, |
| 1476 | { 0x00, 0x00, 0x01, 0x00 }, | 1488 | { 0x00, 0x00, 0x01, 0x00 }, |
| @@ -1497,7 +1509,7 @@ static void sixaxis_set_leds_from_id(struct sony_sc *sc) | |||
| 1497 | static void dualshock4_set_leds_from_id(struct sony_sc *sc) | 1509 | static void dualshock4_set_leds_from_id(struct sony_sc *sc) |
| 1498 | { | 1510 | { |
| 1499 | /* The first 4 color/index entries match what the PS4 assigns */ | 1511 | /* The first 4 color/index entries match what the PS4 assigns */ |
| 1500 | static const __u8 color_code[7][3] = { | 1512 | static const u8 color_code[7][3] = { |
| 1501 | /* Blue */ { 0x00, 0x00, 0x01 }, | 1513 | /* Blue */ { 0x00, 0x00, 0x01 }, |
| 1502 | /* Red */ { 0x01, 0x00, 0x00 }, | 1514 | /* Red */ { 0x01, 0x00, 0x00 }, |
| 1503 | /* Green */ { 0x00, 0x01, 0x00 }, | 1515 | /* Green */ { 0x00, 0x01, 0x00 }, |
| @@ -1525,7 +1537,7 @@ static void buzz_set_leds(struct sony_sc *sc) | |||
| 1525 | &hdev->report_enum[HID_OUTPUT_REPORT].report_list; | 1537 | &hdev->report_enum[HID_OUTPUT_REPORT].report_list; |
| 1526 | struct hid_report *report = list_entry(report_list->next, | 1538 | struct hid_report *report = list_entry(report_list->next, |
| 1527 | struct hid_report, list); | 1539 | struct hid_report, list); |
| 1528 | __s32 *value = report->field[0]->value; | 1540 | s32 *value = report->field[0]->value; |
| 1529 | 1541 | ||
| 1530 | BUILD_BUG_ON(MAX_LEDS < 4); | 1542 | BUILD_BUG_ON(MAX_LEDS < 4); |
| 1531 | 1543 | ||
| @@ -1619,7 +1631,7 @@ static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on, | |||
| 1619 | struct hid_device *hdev = to_hid_device(dev); | 1631 | struct hid_device *hdev = to_hid_device(dev); |
| 1620 | struct sony_sc *drv_data = hid_get_drvdata(hdev); | 1632 | struct sony_sc *drv_data = hid_get_drvdata(hdev); |
| 1621 | int n; | 1633 | int n; |
| 1622 | __u8 new_on, new_off; | 1634 | u8 new_on, new_off; |
| 1623 | 1635 | ||
| 1624 | if (!drv_data) { | 1636 | if (!drv_data) { |
| 1625 | hid_err(hdev, "No device data\n"); | 1637 | hid_err(hdev, "No device data\n"); |
| @@ -1690,8 +1702,8 @@ static int sony_leds_init(struct sony_sc *sc) | |||
| 1690 | const char *name_fmt; | 1702 | const char *name_fmt; |
| 1691 | static const char * const ds4_name_str[] = { "red", "green", "blue", | 1703 | static const char * const ds4_name_str[] = { "red", "green", "blue", |
| 1692 | "global" }; | 1704 | "global" }; |
| 1693 | __u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 }; | 1705 | u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 }; |
| 1694 | __u8 use_hw_blink[MAX_LEDS] = { 0 }; | 1706 | u8 use_hw_blink[MAX_LEDS] = { 0 }; |
| 1695 | 1707 | ||
| 1696 | BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); | 1708 | BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); |
| 1697 | 1709 | ||
| @@ -1719,7 +1731,7 @@ static int sony_leds_init(struct sony_sc *sc) | |||
| 1719 | name_len = 0; | 1731 | name_len = 0; |
| 1720 | name_fmt = "%s:%s"; | 1732 | name_fmt = "%s:%s"; |
| 1721 | } else if (sc->quirks & NAVIGATION_CONTROLLER) { | 1733 | } else if (sc->quirks & NAVIGATION_CONTROLLER) { |
| 1722 | static const __u8 navigation_leds[4] = {0x01, 0x00, 0x00, 0x00}; | 1734 | static const u8 navigation_leds[4] = {0x01, 0x00, 0x00, 0x00}; |
| 1723 | 1735 | ||
| 1724 | memcpy(sc->led_state, navigation_leds, sizeof(navigation_leds)); | 1736 | memcpy(sc->led_state, navigation_leds, sizeof(navigation_leds)); |
| 1725 | sc->led_count = 1; | 1737 | sc->led_count = 1; |
| @@ -1796,7 +1808,7 @@ static void sixaxis_send_output_report(struct sony_sc *sc) | |||
| 1796 | static const union sixaxis_output_report_01 default_report = { | 1808 | static const union sixaxis_output_report_01 default_report = { |
| 1797 | .buf = { | 1809 | .buf = { |
| 1798 | 0x01, | 1810 | 0x01, |
| 1799 | 0x00, 0xff, 0x00, 0xff, 0x00, | 1811 | 0x01, 0xff, 0x00, 0xff, 0x00, |
| 1800 | 0x00, 0x00, 0x00, 0x00, 0x00, | 1812 | 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1801 | 0xff, 0x27, 0x10, 0x00, 0x32, | 1813 | 0xff, 0x27, 0x10, 0x00, 0x32, |
| 1802 | 0xff, 0x27, 0x10, 0x00, 0x32, | 1814 | 0xff, 0x27, 0x10, 0x00, 0x32, |
| @@ -1842,7 +1854,7 @@ static void sixaxis_send_output_report(struct sony_sc *sc) | |||
| 1842 | } | 1854 | } |
| 1843 | } | 1855 | } |
| 1844 | 1856 | ||
| 1845 | hid_hw_raw_request(sc->hdev, report->report_id, (__u8 *)report, | 1857 | hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report, |
| 1846 | sizeof(struct sixaxis_output_report), | 1858 | sizeof(struct sixaxis_output_report), |
| 1847 | HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); | 1859 | HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
| 1848 | } | 1860 | } |
| @@ -1850,7 +1862,7 @@ static void sixaxis_send_output_report(struct sony_sc *sc) | |||
| 1850 | static void dualshock4_send_output_report(struct sony_sc *sc) | 1862 | static void dualshock4_send_output_report(struct sony_sc *sc) |
| 1851 | { | 1863 | { |
| 1852 | struct hid_device *hdev = sc->hdev; | 1864 | struct hid_device *hdev = sc->hdev; |
| 1853 | __u8 *buf = sc->output_report_dmabuf; | 1865 | u8 *buf = sc->output_report_dmabuf; |
| 1854 | int offset; | 1866 | int offset; |
| 1855 | 1867 | ||
| 1856 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { | 1868 | if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { |
| @@ -1910,7 +1922,7 @@ static void motion_send_output_report(struct sony_sc *sc) | |||
| 1910 | report->rumble = max(sc->right, sc->left); | 1922 | report->rumble = max(sc->right, sc->left); |
| 1911 | #endif | 1923 | #endif |
| 1912 | 1924 | ||
| 1913 | hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE); | 1925 | hid_hw_output_report(hdev, (u8 *)report, MOTION_REPORT_0x02_SIZE); |
| 1914 | } | 1926 | } |
| 1915 | 1927 | ||
| 1916 | static inline void sony_send_output_report(struct sony_sc *sc) | 1928 | static inline void sony_send_output_report(struct sony_sc *sc) |
| @@ -1922,6 +1934,7 @@ static inline void sony_send_output_report(struct sony_sc *sc) | |||
| 1922 | static void sony_state_worker(struct work_struct *work) | 1934 | static void sony_state_worker(struct work_struct *work) |
| 1923 | { | 1935 | { |
| 1924 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); | 1936 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); |
| 1937 | |||
| 1925 | sc->send_output_report(sc); | 1938 | sc->send_output_report(sc); |
| 1926 | } | 1939 | } |
| 1927 | 1940 | ||
| @@ -2142,7 +2155,7 @@ static int sony_get_bt_devaddr(struct sony_sc *sc) | |||
| 2142 | 2155 | ||
| 2143 | static int sony_check_add(struct sony_sc *sc) | 2156 | static int sony_check_add(struct sony_sc *sc) |
| 2144 | { | 2157 | { |
| 2145 | __u8 *buf = NULL; | 2158 | u8 *buf = NULL; |
| 2146 | int n, ret; | 2159 | int n, ret; |
| 2147 | 2160 | ||
| 2148 | if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || | 2161 | if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || |
| @@ -2253,7 +2266,7 @@ static void sony_release_device_id(struct sony_sc *sc) | |||
| 2253 | } | 2266 | } |
| 2254 | 2267 | ||
| 2255 | static inline void sony_init_output_report(struct sony_sc *sc, | 2268 | static inline void sony_init_output_report(struct sony_sc *sc, |
| 2256 | void(*send_output_report)(struct sony_sc*)) | 2269 | void (*send_output_report)(struct sony_sc *)) |
| 2257 | { | 2270 | { |
| 2258 | sc->send_output_report = send_output_report; | 2271 | sc->send_output_report = send_output_report; |
| 2259 | 2272 | ||
| @@ -2441,7 +2454,7 @@ static int sony_suspend(struct hid_device *hdev, pm_message_t message) | |||
| 2441 | /* | 2454 | /* |
| 2442 | * On suspend save the current LED state, | 2455 | * On suspend save the current LED state, |
| 2443 | * stop running force-feedback and blank the LEDS. | 2456 | * stop running force-feedback and blank the LEDS. |
| 2444 | */ | 2457 | */ |
| 2445 | if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) { | 2458 | if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) { |
| 2446 | struct sony_sc *sc = hid_get_drvdata(hdev); | 2459 | struct sony_sc *sc = hid_get_drvdata(hdev); |
| 2447 | 2460 | ||
| @@ -2501,8 +2514,10 @@ static const struct hid_device_id sony_devices[] = { | |||
| 2501 | .driver_data = VAIO_RDESC_CONSTANT }, | 2514 | .driver_data = VAIO_RDESC_CONSTANT }, |
| 2502 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), | 2515 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), |
| 2503 | .driver_data = VAIO_RDESC_CONSTANT }, | 2516 | .driver_data = VAIO_RDESC_CONSTANT }, |
| 2504 | /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as | 2517 | /* |
| 2505 | * Logitech joystick from the device descriptor. */ | 2518 | * Wired Buzz Controller. Reported as Sony Hub from its USB ID and as |
| 2519 | * Logitech joystick from the device descriptor. | ||
| 2520 | */ | ||
| 2506 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), | 2521 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), |
| 2507 | .driver_data = BUZZ_CONTROLLER }, | 2522 | .driver_data = BUZZ_CONTROLLER }, |
| 2508 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), | 2523 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), |
| @@ -2521,6 +2536,9 @@ static const struct hid_device_id sony_devices[] = { | |||
| 2521 | .driver_data = DUALSHOCK4_CONTROLLER_USB }, | 2536 | .driver_data = DUALSHOCK4_CONTROLLER_USB }, |
| 2522 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), | 2537 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), |
| 2523 | .driver_data = DUALSHOCK4_CONTROLLER_BT }, | 2538 | .driver_data = DUALSHOCK4_CONTROLLER_BT }, |
| 2539 | /* Nyko Core Controller for PS3 */ | ||
| 2540 | { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER), | ||
| 2541 | .driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER }, | ||
| 2524 | { } | 2542 | { } |
| 2525 | }; | 2543 | }; |
| 2526 | MODULE_DEVICE_TABLE(hid, sony_devices); | 2544 | MODULE_DEVICE_TABLE(hid, sony_devices); |
diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index b95d3978c272..847a497cd472 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <linux/leds.h> | 14 | #include <linux/leds.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
| 17 | #include <linux/workqueue.h> | ||
| 18 | 17 | ||
| 19 | #include "hid-ids.h" | 18 | #include "hid-ids.h" |
| 20 | 19 | ||
| @@ -56,7 +55,6 @@ struct thingm_rgb { | |||
| 56 | struct thingm_led red; | 55 | struct thingm_led red; |
| 57 | struct thingm_led green; | 56 | struct thingm_led green; |
| 58 | struct thingm_led blue; | 57 | struct thingm_led blue; |
| 59 | struct work_struct work; | ||
| 60 | u8 num; | 58 | u8 num; |
| 61 | }; | 59 | }; |
| 62 | 60 | ||
| @@ -79,9 +77,13 @@ static int thingm_send(struct thingm_device *tdev, u8 buf[REPORT_SIZE]) | |||
| 79 | buf[0], buf[1], buf[2], buf[3], buf[4], | 77 | buf[0], buf[1], buf[2], buf[3], buf[4], |
| 80 | buf[5], buf[6], buf[7], buf[8]); | 78 | buf[5], buf[6], buf[7], buf[8]); |
| 81 | 79 | ||
| 80 | mutex_lock(&tdev->lock); | ||
| 81 | |||
| 82 | ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, | 82 | ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, |
| 83 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | 83 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
| 84 | 84 | ||
| 85 | mutex_unlock(&tdev->lock); | ||
| 86 | |||
| 85 | return ret < 0 ? ret : 0; | 87 | return ret < 0 ? ret : 0; |
| 86 | } | 88 | } |
| 87 | 89 | ||
| @@ -89,16 +91,31 @@ static int thingm_recv(struct thingm_device *tdev, u8 buf[REPORT_SIZE]) | |||
| 89 | { | 91 | { |
| 90 | int ret; | 92 | int ret; |
| 91 | 93 | ||
| 94 | /* | ||
| 95 | * A read consists of two operations: sending the read command | ||
| 96 | * and the actual read from the device. Use the mutex to protect | ||
| 97 | * the full sequence of both operations. | ||
| 98 | */ | ||
| 99 | mutex_lock(&tdev->lock); | ||
| 100 | |||
| 101 | ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, | ||
| 102 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | ||
| 103 | if (ret < 0) | ||
| 104 | goto err; | ||
| 105 | |||
| 92 | ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, | 106 | ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, |
| 93 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); | 107 | HID_FEATURE_REPORT, HID_REQ_GET_REPORT); |
| 94 | if (ret < 0) | 108 | if (ret < 0) |
| 95 | return ret; | 109 | goto err; |
| 110 | |||
| 111 | ret = 0; | ||
| 96 | 112 | ||
| 97 | hid_dbg(tdev->hdev, "<- %d %c %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", | 113 | hid_dbg(tdev->hdev, "<- %d %c %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", |
| 98 | buf[0], buf[1], buf[2], buf[3], buf[4], | 114 | buf[0], buf[1], buf[2], buf[3], buf[4], |
| 99 | buf[5], buf[6], buf[7], buf[8]); | 115 | buf[5], buf[6], buf[7], buf[8]); |
| 100 | 116 | err: | |
| 101 | return 0; | 117 | mutex_unlock(&tdev->lock); |
| 118 | return ret; | ||
| 102 | } | 119 | } |
| 103 | 120 | ||
| 104 | static int thingm_version(struct thingm_device *tdev) | 121 | static int thingm_version(struct thingm_device *tdev) |
| @@ -106,10 +123,6 @@ static int thingm_version(struct thingm_device *tdev) | |||
| 106 | u8 buf[REPORT_SIZE] = { REPORT_ID, 'v', 0, 0, 0, 0, 0, 0, 0 }; | 123 | u8 buf[REPORT_SIZE] = { REPORT_ID, 'v', 0, 0, 0, 0, 0, 0, 0 }; |
| 107 | int err; | 124 | int err; |
| 108 | 125 | ||
| 109 | err = thingm_send(tdev, buf); | ||
| 110 | if (err) | ||
| 111 | return err; | ||
| 112 | |||
| 113 | err = thingm_recv(tdev, buf); | 126 | err = thingm_recv(tdev, buf); |
| 114 | if (err) | 127 | if (err) |
| 115 | return err; | 128 | return err; |
| @@ -131,25 +144,17 @@ static int thingm_write_color(struct thingm_rgb *rgb) | |||
| 131 | return thingm_send(rgb->tdev, buf); | 144 | return thingm_send(rgb->tdev, buf); |
| 132 | } | 145 | } |
| 133 | 146 | ||
| 134 | static void thingm_work(struct work_struct *work) | 147 | static int thingm_led_set(struct led_classdev *ldev, |
| 135 | { | 148 | enum led_brightness brightness) |
| 136 | struct thingm_rgb *rgb = container_of(work, struct thingm_rgb, work); | ||
| 137 | |||
| 138 | mutex_lock(&rgb->tdev->lock); | ||
| 139 | |||
| 140 | if (thingm_write_color(rgb)) | ||
| 141 | hid_err(rgb->tdev->hdev, "failed to write color\n"); | ||
| 142 | |||
| 143 | mutex_unlock(&rgb->tdev->lock); | ||
| 144 | } | ||
| 145 | |||
| 146 | static void thingm_led_set(struct led_classdev *ldev, | ||
| 147 | enum led_brightness brightness) | ||
| 148 | { | 149 | { |
| 149 | struct thingm_led *led = container_of(ldev, struct thingm_led, ldev); | 150 | struct thingm_led *led = container_of(ldev, struct thingm_led, ldev); |
| 151 | int ret; | ||
| 152 | |||
| 153 | ret = thingm_write_color(led->rgb); | ||
| 154 | if (ret) | ||
| 155 | hid_err(led->rgb->tdev->hdev, "failed to write color\n"); | ||
| 150 | 156 | ||
| 151 | /* the ledclass has already stored the brightness value */ | 157 | return ret; |
| 152 | schedule_work(&led->rgb->work); | ||
| 153 | } | 158 | } |
| 154 | 159 | ||
| 155 | static int thingm_init_rgb(struct thingm_rgb *rgb) | 160 | static int thingm_init_rgb(struct thingm_rgb *rgb) |
| @@ -162,10 +167,11 @@ static int thingm_init_rgb(struct thingm_rgb *rgb) | |||
| 162 | "thingm%d:red:led%d", minor, rgb->num); | 167 | "thingm%d:red:led%d", minor, rgb->num); |
| 163 | rgb->red.ldev.name = rgb->red.name; | 168 | rgb->red.ldev.name = rgb->red.name; |
| 164 | rgb->red.ldev.max_brightness = 255; | 169 | rgb->red.ldev.max_brightness = 255; |
| 165 | rgb->red.ldev.brightness_set = thingm_led_set; | 170 | rgb->red.ldev.brightness_set_blocking = thingm_led_set; |
| 166 | rgb->red.rgb = rgb; | 171 | rgb->red.rgb = rgb; |
| 167 | 172 | ||
| 168 | err = led_classdev_register(&rgb->tdev->hdev->dev, &rgb->red.ldev); | 173 | err = devm_led_classdev_register(&rgb->tdev->hdev->dev, |
| 174 | &rgb->red.ldev); | ||
| 169 | if (err) | 175 | if (err) |
| 170 | return err; | 176 | return err; |
| 171 | 177 | ||
| @@ -174,46 +180,27 @@ static int thingm_init_rgb(struct thingm_rgb *rgb) | |||
| 174 | "thingm%d:green:led%d", minor, rgb->num); | 180 | "thingm%d:green:led%d", minor, rgb->num); |
| 175 | rgb->green.ldev.name = rgb->green.name; | 181 | rgb->green.ldev.name = rgb->green.name; |
| 176 | rgb->green.ldev.max_brightness = 255; | 182 | rgb->green.ldev.max_brightness = 255; |
| 177 | rgb->green.ldev.brightness_set = thingm_led_set; | 183 | rgb->green.ldev.brightness_set_blocking = thingm_led_set; |
| 178 | rgb->green.rgb = rgb; | 184 | rgb->green.rgb = rgb; |
| 179 | 185 | ||
| 180 | err = led_classdev_register(&rgb->tdev->hdev->dev, &rgb->green.ldev); | 186 | err = devm_led_classdev_register(&rgb->tdev->hdev->dev, |
| 187 | &rgb->green.ldev); | ||
| 181 | if (err) | 188 | if (err) |
| 182 | goto unregister_red; | 189 | return err; |
| 183 | 190 | ||
| 184 | /* Register the blue diode */ | 191 | /* Register the blue diode */ |
| 185 | snprintf(rgb->blue.name, sizeof(rgb->blue.name), | 192 | snprintf(rgb->blue.name, sizeof(rgb->blue.name), |
| 186 | "thingm%d:blue:led%d", minor, rgb->num); | 193 | "thingm%d:blue:led%d", minor, rgb->num); |
| 187 | rgb->blue.ldev.name = rgb->blue.name; | 194 | rgb->blue.ldev.name = rgb->blue.name; |
| 188 | rgb->blue.ldev.max_brightness = 255; | 195 | rgb->blue.ldev.max_brightness = 255; |
| 189 | rgb->blue.ldev.brightness_set = thingm_led_set; | 196 | rgb->blue.ldev.brightness_set_blocking = thingm_led_set; |
| 190 | rgb->blue.rgb = rgb; | 197 | rgb->blue.rgb = rgb; |
| 191 | 198 | ||
| 192 | err = led_classdev_register(&rgb->tdev->hdev->dev, &rgb->blue.ldev); | 199 | err = devm_led_classdev_register(&rgb->tdev->hdev->dev, |
| 193 | if (err) | 200 | &rgb->blue.ldev); |
| 194 | goto unregister_green; | ||
| 195 | |||
| 196 | INIT_WORK(&rgb->work, thingm_work); | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | |||
| 200 | unregister_green: | ||
| 201 | led_classdev_unregister(&rgb->green.ldev); | ||
| 202 | |||
| 203 | unregister_red: | ||
| 204 | led_classdev_unregister(&rgb->red.ldev); | ||
| 205 | |||
| 206 | return err; | 201 | return err; |
| 207 | } | 202 | } |
| 208 | 203 | ||
| 209 | static void thingm_remove_rgb(struct thingm_rgb *rgb) | ||
| 210 | { | ||
| 211 | led_classdev_unregister(&rgb->red.ldev); | ||
| 212 | led_classdev_unregister(&rgb->green.ldev); | ||
| 213 | led_classdev_unregister(&rgb->blue.ldev); | ||
| 214 | flush_work(&rgb->work); | ||
| 215 | } | ||
| 216 | |||
| 217 | static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) | 204 | static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 218 | { | 205 | { |
| 219 | struct thingm_device *tdev; | 206 | struct thingm_device *tdev; |
| @@ -229,17 +216,13 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 229 | 216 | ||
| 230 | err = hid_parse(hdev); | 217 | err = hid_parse(hdev); |
| 231 | if (err) | 218 | if (err) |
| 232 | goto error; | 219 | return err; |
| 233 | |||
| 234 | err = hid_hw_start(hdev, HID_CONNECT_HIDRAW); | ||
| 235 | if (err) | ||
| 236 | goto error; | ||
| 237 | 220 | ||
| 238 | mutex_init(&tdev->lock); | 221 | mutex_init(&tdev->lock); |
| 239 | 222 | ||
| 240 | err = thingm_version(tdev); | 223 | err = thingm_version(tdev); |
| 241 | if (err) | 224 | if (err) |
| 242 | goto stop; | 225 | return err; |
| 243 | 226 | ||
| 244 | hid_dbg(hdev, "firmware version: %c.%c\n", | 227 | hid_dbg(hdev, "firmware version: %c.%c\n", |
| 245 | tdev->version.major, tdev->version.minor); | 228 | tdev->version.major, tdev->version.minor); |
| @@ -250,17 +233,18 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 250 | 233 | ||
| 251 | if (!tdev->fwinfo) { | 234 | if (!tdev->fwinfo) { |
| 252 | hid_err(hdev, "unsupported firmware %c\n", tdev->version.major); | 235 | hid_err(hdev, "unsupported firmware %c\n", tdev->version.major); |
| 253 | err = -ENODEV; | 236 | return -ENODEV; |
| 254 | goto stop; | ||
| 255 | } | 237 | } |
| 256 | 238 | ||
| 257 | tdev->rgb = devm_kzalloc(&hdev->dev, | 239 | tdev->rgb = devm_kzalloc(&hdev->dev, |
| 258 | sizeof(struct thingm_rgb) * tdev->fwinfo->numrgb, | 240 | sizeof(struct thingm_rgb) * tdev->fwinfo->numrgb, |
| 259 | GFP_KERNEL); | 241 | GFP_KERNEL); |
| 260 | if (!tdev->rgb) { | 242 | if (!tdev->rgb) |
| 261 | err = -ENOMEM; | 243 | return -ENOMEM; |
| 262 | goto stop; | 244 | |
| 263 | } | 245 | err = hid_hw_start(hdev, HID_CONNECT_HIDRAW); |
| 246 | if (err) | ||
| 247 | return err; | ||
| 264 | 248 | ||
| 265 | for (i = 0; i < tdev->fwinfo->numrgb; ++i) { | 249 | for (i = 0; i < tdev->fwinfo->numrgb; ++i) { |
| 266 | struct thingm_rgb *rgb = tdev->rgb + i; | 250 | struct thingm_rgb *rgb = tdev->rgb + i; |
| @@ -269,28 +253,12 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 269 | rgb->num = tdev->fwinfo->first + i; | 253 | rgb->num = tdev->fwinfo->first + i; |
| 270 | err = thingm_init_rgb(rgb); | 254 | err = thingm_init_rgb(rgb); |
| 271 | if (err) { | 255 | if (err) { |
| 272 | while (--i >= 0) | 256 | hid_hw_stop(hdev); |
| 273 | thingm_remove_rgb(tdev->rgb + i); | 257 | return err; |
| 274 | goto stop; | ||
| 275 | } | 258 | } |
| 276 | } | 259 | } |
| 277 | 260 | ||
| 278 | return 0; | 261 | return 0; |
| 279 | stop: | ||
| 280 | hid_hw_stop(hdev); | ||
| 281 | error: | ||
| 282 | return err; | ||
| 283 | } | ||
| 284 | |||
| 285 | static void thingm_remove(struct hid_device *hdev) | ||
| 286 | { | ||
| 287 | struct thingm_device *tdev = hid_get_drvdata(hdev); | ||
| 288 | int i; | ||
| 289 | |||
| 290 | hid_hw_stop(hdev); | ||
| 291 | |||
| 292 | for (i = 0; i < tdev->fwinfo->numrgb; ++i) | ||
| 293 | thingm_remove_rgb(tdev->rgb + i); | ||
| 294 | } | 262 | } |
| 295 | 263 | ||
| 296 | static const struct hid_device_id thingm_table[] = { | 264 | static const struct hid_device_id thingm_table[] = { |
| @@ -302,7 +270,6 @@ MODULE_DEVICE_TABLE(hid, thingm_table); | |||
| 302 | static struct hid_driver thingm_driver = { | 270 | static struct hid_driver thingm_driver = { |
| 303 | .name = "thingm", | 271 | .name = "thingm", |
| 304 | .probe = thingm_probe, | 272 | .probe = thingm_probe, |
| 305 | .remove = thingm_remove, | ||
| 306 | .id_table = thingm_table, | 273 | .id_table = thingm_table, |
| 307 | }; | 274 | }; |
| 308 | 275 | ||
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index b9216938a718..2e021ba8ff05 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -283,17 +283,21 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, | |||
| 283 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); | 283 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); |
| 284 | u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister); | 284 | u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister); |
| 285 | u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength); | 285 | u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength); |
| 286 | u16 size; | ||
| 287 | int args_len; | ||
| 288 | int index = 0; | ||
| 289 | |||
| 290 | i2c_hid_dbg(ihid, "%s\n", __func__); | ||
| 291 | |||
| 292 | if (data_len > ihid->bufsize) | ||
| 293 | return -EINVAL; | ||
| 286 | 294 | ||
| 287 | /* hid_hw_* already checked that data_len < HID_MAX_BUFFER_SIZE */ | 295 | size = 2 /* size */ + |
| 288 | u16 size = 2 /* size */ + | ||
| 289 | (reportID ? 1 : 0) /* reportID */ + | 296 | (reportID ? 1 : 0) /* reportID */ + |
| 290 | data_len /* buf */; | 297 | data_len /* buf */; |
| 291 | int args_len = (reportID >= 0x0F ? 1 : 0) /* optional third byte */ + | 298 | args_len = (reportID >= 0x0F ? 1 : 0) /* optional third byte */ + |
| 292 | 2 /* dataRegister */ + | 299 | 2 /* dataRegister */ + |
| 293 | size /* args */; | 300 | size /* args */; |
| 294 | int index = 0; | ||
| 295 | |||
| 296 | i2c_hid_dbg(ihid, "%s\n", __func__); | ||
| 297 | 301 | ||
| 298 | if (!use_data && maxOutputLength == 0) | 302 | if (!use_data && maxOutputLength == 0) |
| 299 | return -ENOSYS; | 303 | return -ENOSYS; |
| @@ -1108,13 +1112,30 @@ static int i2c_hid_suspend(struct device *dev) | |||
| 1108 | struct i2c_client *client = to_i2c_client(dev); | 1112 | struct i2c_client *client = to_i2c_client(dev); |
| 1109 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 1113 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
| 1110 | struct hid_device *hid = ihid->hid; | 1114 | struct hid_device *hid = ihid->hid; |
| 1111 | int ret = 0; | 1115 | int ret; |
| 1112 | int wake_status; | 1116 | int wake_status; |
| 1113 | 1117 | ||
| 1114 | if (hid->driver && hid->driver->suspend) | 1118 | if (hid->driver && hid->driver->suspend) { |
| 1119 | /* | ||
| 1120 | * Wake up the device so that IO issues in | ||
| 1121 | * HID driver's suspend code can succeed. | ||
| 1122 | */ | ||
| 1123 | ret = pm_runtime_resume(dev); | ||
| 1124 | if (ret < 0) | ||
| 1125 | return ret; | ||
| 1126 | |||
| 1115 | ret = hid->driver->suspend(hid, PMSG_SUSPEND); | 1127 | ret = hid->driver->suspend(hid, PMSG_SUSPEND); |
| 1128 | if (ret < 0) | ||
| 1129 | return ret; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | if (!pm_runtime_suspended(dev)) { | ||
| 1133 | /* Save some power */ | ||
| 1134 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
| 1135 | |||
| 1136 | disable_irq(ihid->irq); | ||
| 1137 | } | ||
| 1116 | 1138 | ||
| 1117 | disable_irq(ihid->irq); | ||
| 1118 | if (device_may_wakeup(&client->dev)) { | 1139 | if (device_may_wakeup(&client->dev)) { |
| 1119 | wake_status = enable_irq_wake(ihid->irq); | 1140 | wake_status = enable_irq_wake(ihid->irq); |
| 1120 | if (!wake_status) | 1141 | if (!wake_status) |
| @@ -1124,10 +1145,7 @@ static int i2c_hid_suspend(struct device *dev) | |||
| 1124 | wake_status); | 1145 | wake_status); |
| 1125 | } | 1146 | } |
| 1126 | 1147 | ||
| 1127 | /* Save some power */ | 1148 | return 0; |
| 1128 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
| 1129 | |||
| 1130 | return ret; | ||
| 1131 | } | 1149 | } |
| 1132 | 1150 | ||
| 1133 | static int i2c_hid_resume(struct device *dev) | 1151 | static int i2c_hid_resume(struct device *dev) |
| @@ -1138,11 +1156,6 @@ static int i2c_hid_resume(struct device *dev) | |||
| 1138 | struct hid_device *hid = ihid->hid; | 1156 | struct hid_device *hid = ihid->hid; |
| 1139 | int wake_status; | 1157 | int wake_status; |
| 1140 | 1158 | ||
| 1141 | enable_irq(ihid->irq); | ||
| 1142 | ret = i2c_hid_hwreset(client); | ||
| 1143 | if (ret) | ||
| 1144 | return ret; | ||
| 1145 | |||
| 1146 | if (device_may_wakeup(&client->dev) && ihid->irq_wake_enabled) { | 1159 | if (device_may_wakeup(&client->dev) && ihid->irq_wake_enabled) { |
| 1147 | wake_status = disable_irq_wake(ihid->irq); | 1160 | wake_status = disable_irq_wake(ihid->irq); |
| 1148 | if (!wake_status) | 1161 | if (!wake_status) |
| @@ -1152,6 +1165,16 @@ static int i2c_hid_resume(struct device *dev) | |||
| 1152 | wake_status); | 1165 | wake_status); |
| 1153 | } | 1166 | } |
| 1154 | 1167 | ||
| 1168 | /* We'll resume to full power */ | ||
| 1169 | pm_runtime_disable(dev); | ||
| 1170 | pm_runtime_set_active(dev); | ||
| 1171 | pm_runtime_enable(dev); | ||
| 1172 | |||
| 1173 | enable_irq(ihid->irq); | ||
| 1174 | ret = i2c_hid_hwreset(client); | ||
| 1175 | if (ret) | ||
| 1176 | return ret; | ||
| 1177 | |||
| 1155 | if (hid->driver && hid->driver->reset_resume) { | 1178 | if (hid->driver && hid->driver->reset_resume) { |
| 1156 | ret = hid->driver->reset_resume(hid); | 1179 | ret = hid->driver->reset_resume(hid); |
| 1157 | return ret; | 1180 | return ret; |
| @@ -1191,6 +1214,7 @@ static const struct dev_pm_ops i2c_hid_pm = { | |||
| 1191 | 1214 | ||
| 1192 | static const struct i2c_device_id i2c_hid_id_table[] = { | 1215 | static const struct i2c_device_id i2c_hid_id_table[] = { |
| 1193 | { "hid", 0 }, | 1216 | { "hid", 0 }, |
| 1217 | { "hid-over-i2c", 0 }, | ||
| 1194 | { }, | 1218 | { }, |
| 1195 | }; | 1219 | }; |
| 1196 | MODULE_DEVICE_TABLE(i2c, i2c_hid_id_table); | 1220 | MODULE_DEVICE_TABLE(i2c, i2c_hid_id_table); |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 7dd0953cd70f..ed2f68edc8f1 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
| @@ -55,6 +55,7 @@ static const struct hid_blacklist { | |||
| 55 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, | 55 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, |
| 56 | 56 | ||
| 57 | { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, | 57 | { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, |
| 58 | { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, | ||
| 58 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
| 59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 60 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
| 60 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, | 61 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |
| @@ -106,6 +107,7 @@ static const struct hid_blacklist { | |||
| 106 | { USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22, HID_QUIRK_ALWAYS_POLL }, | 107 | { USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22, HID_QUIRK_ALWAYS_POLL }, |
| 107 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, | 108 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, |
| 108 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, | 109 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, |
| 110 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003, HID_QUIRK_NOGET }, | ||
| 109 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, | 111 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, |
| 110 | { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS }, | 112 | { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS }, |
| 111 | { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, | 113 | { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, |
| @@ -140,6 +142,7 @@ static const struct hid_blacklist { | |||
| 140 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912, HID_QUIRK_MULTI_INPUT }, | 142 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912, HID_QUIRK_MULTI_INPUT }, |
| 141 | { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, | 143 | { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, |
| 142 | { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, | 144 | { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, |
| 145 | { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2, HID_QUIRK_NO_INIT_REPORTS }, | ||
| 143 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1, HID_QUIRK_NO_INIT_REPORTS }, | 146 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1, HID_QUIRK_NO_INIT_REPORTS }, |
| 144 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2, HID_QUIRK_NO_INIT_REPORTS }, | 147 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2, HID_QUIRK_NO_INIT_REPORTS }, |
| 145 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS }, | 148 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 5cb21dd91094..68a560957871 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
| @@ -1357,6 +1357,9 @@ static void wacom_clean_inputs(struct wacom *wacom) | |||
| 1357 | wacom->wacom_wac.pen_input = NULL; | 1357 | wacom->wacom_wac.pen_input = NULL; |
| 1358 | wacom->wacom_wac.touch_input = NULL; | 1358 | wacom->wacom_wac.touch_input = NULL; |
| 1359 | wacom->wacom_wac.pad_input = NULL; | 1359 | wacom->wacom_wac.pad_input = NULL; |
| 1360 | wacom->wacom_wac.pen_registered = false; | ||
| 1361 | wacom->wacom_wac.touch_registered = false; | ||
| 1362 | wacom->wacom_wac.pad_registered = false; | ||
| 1360 | wacom_destroy_leds(wacom); | 1363 | wacom_destroy_leds(wacom); |
| 1361 | } | 1364 | } |
| 1362 | 1365 | ||
| @@ -1494,123 +1497,6 @@ static void wacom_calculate_res(struct wacom_features *features) | |||
| 1494 | features->unitExpo); | 1497 | features->unitExpo); |
| 1495 | } | 1498 | } |
| 1496 | 1499 | ||
| 1497 | static void wacom_wireless_work(struct work_struct *work) | ||
| 1498 | { | ||
| 1499 | struct wacom *wacom = container_of(work, struct wacom, work); | ||
| 1500 | struct usb_device *usbdev = wacom->usbdev; | ||
| 1501 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
| 1502 | struct hid_device *hdev1, *hdev2; | ||
| 1503 | struct wacom *wacom1, *wacom2; | ||
| 1504 | struct wacom_wac *wacom_wac1, *wacom_wac2; | ||
| 1505 | int error; | ||
| 1506 | |||
| 1507 | /* | ||
| 1508 | * Regardless if this is a disconnect or a new tablet, | ||
| 1509 | * remove any existing input and battery devices. | ||
| 1510 | */ | ||
| 1511 | |||
| 1512 | wacom_destroy_battery(wacom); | ||
| 1513 | |||
| 1514 | /* Stylus interface */ | ||
| 1515 | hdev1 = usb_get_intfdata(usbdev->config->interface[1]); | ||
| 1516 | wacom1 = hid_get_drvdata(hdev1); | ||
| 1517 | wacom_wac1 = &(wacom1->wacom_wac); | ||
| 1518 | wacom_clean_inputs(wacom1); | ||
| 1519 | |||
| 1520 | /* Touch interface */ | ||
| 1521 | hdev2 = usb_get_intfdata(usbdev->config->interface[2]); | ||
| 1522 | wacom2 = hid_get_drvdata(hdev2); | ||
| 1523 | wacom_wac2 = &(wacom2->wacom_wac); | ||
| 1524 | wacom_clean_inputs(wacom2); | ||
| 1525 | |||
| 1526 | if (wacom_wac->pid == 0) { | ||
| 1527 | hid_info(wacom->hdev, "wireless tablet disconnected\n"); | ||
| 1528 | wacom_wac1->shared->type = 0; | ||
| 1529 | } else { | ||
| 1530 | const struct hid_device_id *id = wacom_ids; | ||
| 1531 | |||
| 1532 | hid_info(wacom->hdev, "wireless tablet connected with PID %x\n", | ||
| 1533 | wacom_wac->pid); | ||
| 1534 | |||
| 1535 | while (id->bus) { | ||
| 1536 | if (id->vendor == USB_VENDOR_ID_WACOM && | ||
| 1537 | id->product == wacom_wac->pid) | ||
| 1538 | break; | ||
| 1539 | id++; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | if (!id->bus) { | ||
| 1543 | hid_info(wacom->hdev, "ignoring unknown PID.\n"); | ||
| 1544 | return; | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | /* Stylus interface */ | ||
| 1548 | wacom_wac1->features = | ||
| 1549 | *((struct wacom_features *)id->driver_data); | ||
| 1550 | wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PEN; | ||
| 1551 | wacom_set_default_phy(&wacom_wac1->features); | ||
| 1552 | wacom_calculate_res(&wacom_wac1->features); | ||
| 1553 | snprintf(wacom_wac1->pen_name, WACOM_NAME_MAX, "%s (WL) Pen", | ||
| 1554 | wacom_wac1->features.name); | ||
| 1555 | if (wacom_wac1->features.type < BAMBOO_PEN || | ||
| 1556 | wacom_wac1->features.type > BAMBOO_PT) { | ||
| 1557 | snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad", | ||
| 1558 | wacom_wac1->features.name); | ||
| 1559 | wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD; | ||
| 1560 | } | ||
| 1561 | wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max; | ||
| 1562 | wacom_wac1->shared->type = wacom_wac1->features.type; | ||
| 1563 | wacom_wac1->pid = wacom_wac->pid; | ||
| 1564 | error = wacom_allocate_inputs(wacom1) || | ||
| 1565 | wacom_register_inputs(wacom1); | ||
| 1566 | if (error) | ||
| 1567 | goto fail; | ||
| 1568 | |||
| 1569 | /* Touch interface */ | ||
| 1570 | if (wacom_wac1->features.touch_max || | ||
| 1571 | (wacom_wac1->features.type >= INTUOSHT && | ||
| 1572 | wacom_wac1->features.type <= BAMBOO_PT)) { | ||
| 1573 | wacom_wac2->features = | ||
| 1574 | *((struct wacom_features *)id->driver_data); | ||
| 1575 | wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; | ||
| 1576 | wacom_set_default_phy(&wacom_wac2->features); | ||
| 1577 | wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; | ||
| 1578 | wacom_calculate_res(&wacom_wac2->features); | ||
| 1579 | snprintf(wacom_wac2->touch_name, WACOM_NAME_MAX, | ||
| 1580 | "%s (WL) Finger",wacom_wac2->features.name); | ||
| 1581 | if (wacom_wac1->features.touch_max) | ||
| 1582 | wacom_wac2->features.device_type |= WACOM_DEVICETYPE_TOUCH; | ||
| 1583 | if (wacom_wac1->features.type >= INTUOSHT && | ||
| 1584 | wacom_wac1->features.type <= BAMBOO_PT) { | ||
| 1585 | snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX, | ||
| 1586 | "%s (WL) Pad",wacom_wac2->features.name); | ||
| 1587 | wacom_wac2->features.device_type |= WACOM_DEVICETYPE_PAD; | ||
| 1588 | } | ||
| 1589 | wacom_wac2->pid = wacom_wac->pid; | ||
| 1590 | error = wacom_allocate_inputs(wacom2) || | ||
| 1591 | wacom_register_inputs(wacom2); | ||
| 1592 | if (error) | ||
| 1593 | goto fail; | ||
| 1594 | |||
| 1595 | if ((wacom_wac1->features.type == INTUOSHT || | ||
| 1596 | wacom_wac1->features.type == INTUOSHT2) && | ||
| 1597 | wacom_wac1->features.touch_max) | ||
| 1598 | wacom_wac->shared->touch_input = wacom_wac2->touch_input; | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | error = wacom_initialize_battery(wacom); | ||
| 1602 | if (error) | ||
| 1603 | goto fail; | ||
| 1604 | } | ||
| 1605 | |||
| 1606 | return; | ||
| 1607 | |||
| 1608 | fail: | ||
| 1609 | wacom_clean_inputs(wacom1); | ||
| 1610 | wacom_clean_inputs(wacom2); | ||
| 1611 | return; | ||
| 1612 | } | ||
| 1613 | |||
| 1614 | void wacom_battery_work(struct work_struct *work) | 1500 | void wacom_battery_work(struct work_struct *work) |
| 1615 | { | 1501 | { |
| 1616 | struct wacom *wacom = container_of(work, struct wacom, work); | 1502 | struct wacom *wacom = container_of(work, struct wacom, work); |
| @@ -1642,7 +1528,7 @@ static size_t wacom_compute_pktlen(struct hid_device *hdev) | |||
| 1642 | return size; | 1528 | return size; |
| 1643 | } | 1529 | } |
| 1644 | 1530 | ||
| 1645 | static void wacom_update_name(struct wacom *wacom) | 1531 | static void wacom_update_name(struct wacom *wacom, const char *suffix) |
| 1646 | { | 1532 | { |
| 1647 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | 1533 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
| 1648 | struct wacom_features *features = &wacom_wac->features; | 1534 | struct wacom_features *features = &wacom_wac->features; |
| @@ -1678,68 +1564,28 @@ static void wacom_update_name(struct wacom *wacom) | |||
| 1678 | 1564 | ||
| 1679 | /* Append the device type to the name */ | 1565 | /* Append the device type to the name */ |
| 1680 | snprintf(wacom_wac->pen_name, sizeof(wacom_wac->pen_name), | 1566 | snprintf(wacom_wac->pen_name, sizeof(wacom_wac->pen_name), |
| 1681 | "%s Pen", name); | 1567 | "%s%s Pen", name, suffix); |
| 1682 | snprintf(wacom_wac->touch_name, sizeof(wacom_wac->touch_name), | 1568 | snprintf(wacom_wac->touch_name, sizeof(wacom_wac->touch_name), |
| 1683 | "%s Finger", name); | 1569 | "%s%s Finger", name, suffix); |
| 1684 | snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name), | 1570 | snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name), |
| 1685 | "%s Pad", name); | 1571 | "%s%s Pad", name, suffix); |
| 1686 | } | 1572 | } |
| 1687 | 1573 | ||
| 1688 | static int wacom_probe(struct hid_device *hdev, | 1574 | static int wacom_parse_and_register(struct wacom *wacom, bool wireless) |
| 1689 | const struct hid_device_id *id) | ||
| 1690 | { | 1575 | { |
| 1691 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 1576 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
| 1692 | struct usb_device *dev = interface_to_usbdev(intf); | 1577 | struct wacom_features *features = &wacom_wac->features; |
| 1693 | struct wacom *wacom; | 1578 | struct hid_device *hdev = wacom->hdev; |
| 1694 | struct wacom_wac *wacom_wac; | ||
| 1695 | struct wacom_features *features; | ||
| 1696 | int error; | 1579 | int error; |
| 1697 | unsigned int connect_mask = HID_CONNECT_HIDRAW; | 1580 | unsigned int connect_mask = HID_CONNECT_HIDRAW; |
| 1698 | 1581 | ||
| 1699 | if (!id->driver_data) | ||
| 1700 | return -EINVAL; | ||
| 1701 | |||
| 1702 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | ||
| 1703 | |||
| 1704 | /* hid-core sets this quirk for the boot interface */ | ||
| 1705 | hdev->quirks &= ~HID_QUIRK_NOGET; | ||
| 1706 | |||
| 1707 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | ||
| 1708 | if (!wacom) | ||
| 1709 | return -ENOMEM; | ||
| 1710 | |||
| 1711 | hid_set_drvdata(hdev, wacom); | ||
| 1712 | wacom->hdev = hdev; | ||
| 1713 | |||
| 1714 | /* ask for the report descriptor to be loaded by HID */ | ||
| 1715 | error = hid_parse(hdev); | ||
| 1716 | if (error) { | ||
| 1717 | hid_err(hdev, "parse failed\n"); | ||
| 1718 | goto fail_parse; | ||
| 1719 | } | ||
| 1720 | |||
| 1721 | wacom_wac = &wacom->wacom_wac; | ||
| 1722 | wacom_wac->features = *((struct wacom_features *)id->driver_data); | ||
| 1723 | features = &wacom_wac->features; | ||
| 1724 | features->pktlen = wacom_compute_pktlen(hdev); | 1582 | features->pktlen = wacom_compute_pktlen(hdev); |
| 1725 | if (features->pktlen > WACOM_PKGLEN_MAX) { | 1583 | if (features->pktlen > WACOM_PKGLEN_MAX) |
| 1726 | error = -EINVAL; | 1584 | return -EINVAL; |
| 1727 | goto fail_pktlen; | ||
| 1728 | } | ||
| 1729 | |||
| 1730 | if (features->check_for_hid_type && features->hid_type != hdev->type) { | ||
| 1731 | error = -ENODEV; | ||
| 1732 | goto fail_type; | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | wacom->usbdev = dev; | ||
| 1736 | wacom->intf = intf; | ||
| 1737 | mutex_init(&wacom->lock); | ||
| 1738 | INIT_WORK(&wacom->work, wacom_wireless_work); | ||
| 1739 | 1585 | ||
| 1740 | error = wacom_allocate_inputs(wacom); | 1586 | error = wacom_allocate_inputs(wacom); |
| 1741 | if (error) | 1587 | if (error) |
| 1742 | goto fail_allocate_inputs; | 1588 | return error; |
| 1743 | 1589 | ||
| 1744 | /* | 1590 | /* |
| 1745 | * Bamboo Pad has a generic hid handling for the Pen, and we switch it | 1591 | * Bamboo Pad has a generic hid handling for the Pen, and we switch it |
| @@ -1752,7 +1598,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
| 1752 | } else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) && | 1598 | } else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) && |
| 1753 | (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) { | 1599 | (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) { |
| 1754 | error = -ENODEV; | 1600 | error = -ENODEV; |
| 1755 | goto fail_shared_data; | 1601 | goto fail_allocate_inputs; |
| 1756 | } | 1602 | } |
| 1757 | } | 1603 | } |
| 1758 | 1604 | ||
| @@ -1772,14 +1618,14 @@ static int wacom_probe(struct hid_device *hdev, | |||
| 1772 | error ? "Ignoring" : "Assuming pen"); | 1618 | error ? "Ignoring" : "Assuming pen"); |
| 1773 | 1619 | ||
| 1774 | if (error) | 1620 | if (error) |
| 1775 | goto fail_shared_data; | 1621 | goto fail_parsed; |
| 1776 | 1622 | ||
| 1777 | features->device_type |= WACOM_DEVICETYPE_PEN; | 1623 | features->device_type |= WACOM_DEVICETYPE_PEN; |
| 1778 | } | 1624 | } |
| 1779 | 1625 | ||
| 1780 | wacom_calculate_res(features); | 1626 | wacom_calculate_res(features); |
| 1781 | 1627 | ||
| 1782 | wacom_update_name(wacom); | 1628 | wacom_update_name(wacom, wireless ? " (WL)" : ""); |
| 1783 | 1629 | ||
| 1784 | error = wacom_add_shared_data(hdev); | 1630 | error = wacom_add_shared_data(hdev); |
| 1785 | if (error) | 1631 | if (error) |
| @@ -1796,14 +1642,6 @@ static int wacom_probe(struct hid_device *hdev, | |||
| 1796 | if (error) | 1642 | if (error) |
| 1797 | goto fail_register_inputs; | 1643 | goto fail_register_inputs; |
| 1798 | 1644 | ||
| 1799 | if (hdev->bus == BUS_BLUETOOTH) { | ||
| 1800 | error = device_create_file(&hdev->dev, &dev_attr_speed); | ||
| 1801 | if (error) | ||
| 1802 | hid_warn(hdev, | ||
| 1803 | "can't create sysfs speed attribute err: %d\n", | ||
| 1804 | error); | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | if (features->type == HID_GENERIC) | 1645 | if (features->type == HID_GENERIC) |
| 1808 | connect_mask |= HID_CONNECT_DRIVER; | 1646 | connect_mask |= HID_CONNECT_DRIVER; |
| 1809 | 1647 | ||
| @@ -1814,8 +1652,10 @@ static int wacom_probe(struct hid_device *hdev, | |||
| 1814 | goto fail_hw_start; | 1652 | goto fail_hw_start; |
| 1815 | } | 1653 | } |
| 1816 | 1654 | ||
| 1817 | /* Note that if query fails it is not a hard failure */ | 1655 | if (!wireless) { |
| 1818 | wacom_query_tablet_data(hdev, features); | 1656 | /* Note that if query fails it is not a hard failure */ |
| 1657 | wacom_query_tablet_data(hdev, features); | ||
| 1658 | } | ||
| 1819 | 1659 | ||
| 1820 | /* touch only Bamboo doesn't support pen */ | 1660 | /* touch only Bamboo doesn't support pen */ |
| 1821 | if ((features->type == BAMBOO_TOUCH) && | 1661 | if ((features->type == BAMBOO_TOUCH) && |
| @@ -1844,18 +1684,166 @@ static int wacom_probe(struct hid_device *hdev, | |||
| 1844 | return 0; | 1684 | return 0; |
| 1845 | 1685 | ||
| 1846 | fail_hw_start: | 1686 | fail_hw_start: |
| 1847 | if (hdev->bus == BUS_BLUETOOTH) | 1687 | hid_hw_stop(hdev); |
| 1848 | device_remove_file(&hdev->dev, &dev_attr_speed); | ||
| 1849 | fail_register_inputs: | 1688 | fail_register_inputs: |
| 1850 | wacom_clean_inputs(wacom); | 1689 | wacom_clean_inputs(wacom); |
| 1851 | wacom_destroy_battery(wacom); | 1690 | wacom_destroy_battery(wacom); |
| 1852 | fail_battery: | 1691 | fail_battery: |
| 1853 | wacom_remove_shared_data(wacom); | 1692 | wacom_remove_shared_data(wacom); |
| 1854 | fail_shared_data: | 1693 | fail_shared_data: |
| 1855 | wacom_clean_inputs(wacom); | 1694 | fail_parsed: |
| 1856 | fail_allocate_inputs: | 1695 | fail_allocate_inputs: |
| 1696 | wacom_clean_inputs(wacom); | ||
| 1697 | return error; | ||
| 1698 | } | ||
| 1699 | |||
| 1700 | static void wacom_wireless_work(struct work_struct *work) | ||
| 1701 | { | ||
| 1702 | struct wacom *wacom = container_of(work, struct wacom, work); | ||
| 1703 | struct usb_device *usbdev = wacom->usbdev; | ||
| 1704 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
| 1705 | struct hid_device *hdev1, *hdev2; | ||
| 1706 | struct wacom *wacom1, *wacom2; | ||
| 1707 | struct wacom_wac *wacom_wac1, *wacom_wac2; | ||
| 1708 | int error; | ||
| 1709 | |||
| 1710 | /* | ||
| 1711 | * Regardless if this is a disconnect or a new tablet, | ||
| 1712 | * remove any existing input and battery devices. | ||
| 1713 | */ | ||
| 1714 | |||
| 1715 | wacom_destroy_battery(wacom); | ||
| 1716 | |||
| 1717 | /* Stylus interface */ | ||
| 1718 | hdev1 = usb_get_intfdata(usbdev->config->interface[1]); | ||
| 1719 | wacom1 = hid_get_drvdata(hdev1); | ||
| 1720 | wacom_wac1 = &(wacom1->wacom_wac); | ||
| 1721 | wacom_clean_inputs(wacom1); | ||
| 1722 | |||
| 1723 | /* Touch interface */ | ||
| 1724 | hdev2 = usb_get_intfdata(usbdev->config->interface[2]); | ||
| 1725 | wacom2 = hid_get_drvdata(hdev2); | ||
| 1726 | wacom_wac2 = &(wacom2->wacom_wac); | ||
| 1727 | wacom_clean_inputs(wacom2); | ||
| 1728 | |||
| 1729 | if (wacom_wac->pid == 0) { | ||
| 1730 | hid_info(wacom->hdev, "wireless tablet disconnected\n"); | ||
| 1731 | wacom_wac1->shared->type = 0; | ||
| 1732 | } else { | ||
| 1733 | const struct hid_device_id *id = wacom_ids; | ||
| 1734 | |||
| 1735 | hid_info(wacom->hdev, "wireless tablet connected with PID %x\n", | ||
| 1736 | wacom_wac->pid); | ||
| 1737 | |||
| 1738 | while (id->bus) { | ||
| 1739 | if (id->vendor == USB_VENDOR_ID_WACOM && | ||
| 1740 | id->product == wacom_wac->pid) | ||
| 1741 | break; | ||
| 1742 | id++; | ||
| 1743 | } | ||
| 1744 | |||
| 1745 | if (!id->bus) { | ||
| 1746 | hid_info(wacom->hdev, "ignoring unknown PID.\n"); | ||
| 1747 | return; | ||
| 1748 | } | ||
| 1749 | |||
| 1750 | /* Stylus interface */ | ||
| 1751 | wacom_wac1->features = | ||
| 1752 | *((struct wacom_features *)id->driver_data); | ||
| 1753 | |||
| 1754 | wacom_wac1->pid = wacom_wac->pid; | ||
| 1755 | hid_hw_stop(hdev1); | ||
| 1756 | error = wacom_parse_and_register(wacom1, true); | ||
| 1757 | if (error) | ||
| 1758 | goto fail; | ||
| 1759 | |||
| 1760 | /* Touch interface */ | ||
| 1761 | if (wacom_wac1->features.touch_max || | ||
| 1762 | (wacom_wac1->features.type >= INTUOSHT && | ||
| 1763 | wacom_wac1->features.type <= BAMBOO_PT)) { | ||
| 1764 | wacom_wac2->features = | ||
| 1765 | *((struct wacom_features *)id->driver_data); | ||
| 1766 | wacom_wac2->pid = wacom_wac->pid; | ||
| 1767 | hid_hw_stop(hdev2); | ||
| 1768 | error = wacom_parse_and_register(wacom2, true); | ||
| 1769 | if (error) | ||
| 1770 | goto fail; | ||
| 1771 | } | ||
| 1772 | |||
| 1773 | error = wacom_initialize_battery(wacom); | ||
| 1774 | if (error) | ||
| 1775 | goto fail; | ||
| 1776 | } | ||
| 1777 | |||
| 1778 | return; | ||
| 1779 | |||
| 1780 | fail: | ||
| 1781 | wacom_clean_inputs(wacom1); | ||
| 1782 | wacom_clean_inputs(wacom2); | ||
| 1783 | return; | ||
| 1784 | } | ||
| 1785 | |||
| 1786 | static int wacom_probe(struct hid_device *hdev, | ||
| 1787 | const struct hid_device_id *id) | ||
| 1788 | { | ||
| 1789 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 1790 | struct usb_device *dev = interface_to_usbdev(intf); | ||
| 1791 | struct wacom *wacom; | ||
| 1792 | struct wacom_wac *wacom_wac; | ||
| 1793 | struct wacom_features *features; | ||
| 1794 | int error; | ||
| 1795 | |||
| 1796 | if (!id->driver_data) | ||
| 1797 | return -EINVAL; | ||
| 1798 | |||
| 1799 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | ||
| 1800 | |||
| 1801 | /* hid-core sets this quirk for the boot interface */ | ||
| 1802 | hdev->quirks &= ~HID_QUIRK_NOGET; | ||
| 1803 | |||
| 1804 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | ||
| 1805 | if (!wacom) | ||
| 1806 | return -ENOMEM; | ||
| 1807 | |||
| 1808 | hid_set_drvdata(hdev, wacom); | ||
| 1809 | wacom->hdev = hdev; | ||
| 1810 | |||
| 1811 | wacom_wac = &wacom->wacom_wac; | ||
| 1812 | wacom_wac->features = *((struct wacom_features *)id->driver_data); | ||
| 1813 | features = &wacom_wac->features; | ||
| 1814 | |||
| 1815 | if (features->check_for_hid_type && features->hid_type != hdev->type) { | ||
| 1816 | error = -ENODEV; | ||
| 1817 | goto fail_type; | ||
| 1818 | } | ||
| 1819 | |||
| 1820 | wacom->usbdev = dev; | ||
| 1821 | wacom->intf = intf; | ||
| 1822 | mutex_init(&wacom->lock); | ||
| 1823 | INIT_WORK(&wacom->work, wacom_wireless_work); | ||
| 1824 | |||
| 1825 | /* ask for the report descriptor to be loaded by HID */ | ||
| 1826 | error = hid_parse(hdev); | ||
| 1827 | if (error) { | ||
| 1828 | hid_err(hdev, "parse failed\n"); | ||
| 1829 | goto fail_parse; | ||
| 1830 | } | ||
| 1831 | |||
| 1832 | error = wacom_parse_and_register(wacom, false); | ||
| 1833 | if (error) | ||
| 1834 | goto fail_parse; | ||
| 1835 | |||
| 1836 | if (hdev->bus == BUS_BLUETOOTH) { | ||
| 1837 | error = device_create_file(&hdev->dev, &dev_attr_speed); | ||
| 1838 | if (error) | ||
| 1839 | hid_warn(hdev, | ||
| 1840 | "can't create sysfs speed attribute err: %d\n", | ||
| 1841 | error); | ||
| 1842 | } | ||
| 1843 | |||
| 1844 | return 0; | ||
| 1845 | |||
| 1857 | fail_type: | 1846 | fail_type: |
| 1858 | fail_pktlen: | ||
| 1859 | fail_parse: | 1847 | fail_parse: |
| 1860 | kfree(wacom); | 1848 | kfree(wacom); |
| 1861 | hid_set_drvdata(hdev, NULL); | 1849 | hid_set_drvdata(hdev, NULL); |
| @@ -1865,6 +1853,11 @@ fail_parse: | |||
| 1865 | static void wacom_remove(struct hid_device *hdev) | 1853 | static void wacom_remove(struct hid_device *hdev) |
| 1866 | { | 1854 | { |
| 1867 | struct wacom *wacom = hid_get_drvdata(hdev); | 1855 | struct wacom *wacom = hid_get_drvdata(hdev); |
| 1856 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
| 1857 | struct wacom_features *features = &wacom_wac->features; | ||
| 1858 | |||
| 1859 | if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) | ||
| 1860 | hid_hw_close(hdev); | ||
| 1868 | 1861 | ||
| 1869 | hid_hw_stop(hdev); | 1862 | hid_hw_stop(hdev); |
| 1870 | 1863 | ||
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 99ef77fcfb80..bd198bbd4df0 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -575,16 +575,102 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) | |||
| 575 | return 1; | 575 | return 1; |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | static int wacom_intuos_get_tool_type(int tool_id) | ||
| 579 | { | ||
| 580 | int tool_type; | ||
| 581 | |||
| 582 | switch (tool_id) { | ||
| 583 | case 0x812: /* Inking pen */ | ||
| 584 | case 0x801: /* Intuos3 Inking pen */ | ||
| 585 | case 0x120802: /* Intuos4/5 Inking Pen */ | ||
| 586 | case 0x012: | ||
| 587 | tool_type = BTN_TOOL_PENCIL; | ||
| 588 | break; | ||
| 589 | |||
| 590 | case 0x822: /* Pen */ | ||
| 591 | case 0x842: | ||
| 592 | case 0x852: | ||
| 593 | case 0x823: /* Intuos3 Grip Pen */ | ||
| 594 | case 0x813: /* Intuos3 Classic Pen */ | ||
| 595 | case 0x885: /* Intuos3 Marker Pen */ | ||
| 596 | case 0x802: /* Intuos4/5 13HD/24HD General Pen */ | ||
| 597 | case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ | ||
| 598 | case 0x8e2: /* IntuosHT2 pen */ | ||
| 599 | case 0x022: | ||
| 600 | case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */ | ||
| 601 | case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ | ||
| 602 | case 0x160802: /* Cintiq 13HD Pro Pen */ | ||
| 603 | case 0x180802: /* DTH2242 Pen */ | ||
| 604 | case 0x100802: /* Intuos4/5 13HD/24HD General Pen */ | ||
| 605 | tool_type = BTN_TOOL_PEN; | ||
| 606 | break; | ||
| 607 | |||
| 608 | case 0x832: /* Stroke pen */ | ||
| 609 | case 0x032: | ||
| 610 | tool_type = BTN_TOOL_BRUSH; | ||
| 611 | break; | ||
| 612 | |||
| 613 | case 0x007: /* Mouse 4D and 2D */ | ||
| 614 | case 0x09c: | ||
| 615 | case 0x094: | ||
| 616 | case 0x017: /* Intuos3 2D Mouse */ | ||
| 617 | case 0x806: /* Intuos4 Mouse */ | ||
| 618 | tool_type = BTN_TOOL_MOUSE; | ||
| 619 | break; | ||
| 620 | |||
| 621 | case 0x096: /* Lens cursor */ | ||
| 622 | case 0x097: /* Intuos3 Lens cursor */ | ||
| 623 | case 0x006: /* Intuos4 Lens cursor */ | ||
| 624 | tool_type = BTN_TOOL_LENS; | ||
| 625 | break; | ||
| 626 | |||
| 627 | case 0x82a: /* Eraser */ | ||
| 628 | case 0x85a: | ||
| 629 | case 0x91a: | ||
| 630 | case 0xd1a: | ||
| 631 | case 0x0fa: | ||
| 632 | case 0x82b: /* Intuos3 Grip Pen Eraser */ | ||
| 633 | case 0x81b: /* Intuos3 Classic Pen Eraser */ | ||
| 634 | case 0x91b: /* Intuos3 Airbrush Eraser */ | ||
| 635 | case 0x80c: /* Intuos4/5 13HD/24HD Marker Pen Eraser */ | ||
| 636 | case 0x80a: /* Intuos4/5 13HD/24HD General Pen Eraser */ | ||
| 637 | case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ | ||
| 638 | case 0x14080a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */ | ||
| 639 | case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ | ||
| 640 | case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ | ||
| 641 | case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ | ||
| 642 | case 0x18080a: /* DTH2242 Eraser */ | ||
| 643 | case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */ | ||
| 644 | tool_type = BTN_TOOL_RUBBER; | ||
| 645 | break; | ||
| 646 | |||
| 647 | case 0xd12: | ||
| 648 | case 0x912: | ||
| 649 | case 0x112: | ||
| 650 | case 0x913: /* Intuos3 Airbrush */ | ||
| 651 | case 0x902: /* Intuos4/5 13HD/24HD Airbrush */ | ||
| 652 | case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */ | ||
| 653 | tool_type = BTN_TOOL_AIRBRUSH; | ||
| 654 | break; | ||
| 655 | |||
| 656 | default: /* Unknown tool */ | ||
| 657 | tool_type = BTN_TOOL_PEN; | ||
| 658 | break; | ||
| 659 | } | ||
| 660 | return tool_type; | ||
| 661 | } | ||
| 662 | |||
| 578 | static int wacom_intuos_inout(struct wacom_wac *wacom) | 663 | static int wacom_intuos_inout(struct wacom_wac *wacom) |
| 579 | { | 664 | { |
| 580 | struct wacom_features *features = &wacom->features; | 665 | struct wacom_features *features = &wacom->features; |
| 581 | unsigned char *data = wacom->data; | 666 | unsigned char *data = wacom->data; |
| 582 | struct input_dev *input = wacom->pen_input; | 667 | struct input_dev *input = wacom->pen_input; |
| 583 | int idx = 0; | 668 | int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; |
| 584 | 669 | ||
| 585 | /* tool number */ | 670 | if (!(((data[1] & 0xfc) == 0xc0) || /* in prox */ |
| 586 | if (features->type == INTUOS) | 671 | ((data[1] & 0xfe) == 0x20) || /* in range */ |
| 587 | idx = data[1] & 0x01; | 672 | ((data[1] & 0xfe) == 0x80))) /* out prox */ |
| 673 | return 0; | ||
| 588 | 674 | ||
| 589 | /* Enter report */ | 675 | /* Enter report */ |
| 590 | if ((data[1] & 0xfc) == 0xc0) { | 676 | if ((data[1] & 0xfc) == 0xc0) { |
| @@ -596,116 +682,24 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 596 | wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) | | 682 | wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) | |
| 597 | ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12); | 683 | ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12); |
| 598 | 684 | ||
| 599 | switch (wacom->id[idx]) { | 685 | wacom->tool[idx] = wacom_intuos_get_tool_type(wacom->id[idx]); |
| 600 | case 0x812: /* Inking pen */ | 686 | |
| 601 | case 0x801: /* Intuos3 Inking pen */ | ||
| 602 | case 0x120802: /* Intuos4/5 Inking Pen */ | ||
| 603 | case 0x012: | ||
| 604 | wacom->tool[idx] = BTN_TOOL_PENCIL; | ||
| 605 | break; | ||
| 606 | |||
| 607 | case 0x822: /* Pen */ | ||
| 608 | case 0x842: | ||
| 609 | case 0x852: | ||
| 610 | case 0x823: /* Intuos3 Grip Pen */ | ||
| 611 | case 0x813: /* Intuos3 Classic Pen */ | ||
| 612 | case 0x885: /* Intuos3 Marker Pen */ | ||
| 613 | case 0x802: /* Intuos4/5 13HD/24HD General Pen */ | ||
| 614 | case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ | ||
| 615 | case 0x022: | ||
| 616 | case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */ | ||
| 617 | case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ | ||
| 618 | case 0x160802: /* Cintiq 13HD Pro Pen */ | ||
| 619 | case 0x180802: /* DTH2242 Pen */ | ||
| 620 | case 0x100802: /* Intuos4/5 13HD/24HD General Pen */ | ||
| 621 | wacom->tool[idx] = BTN_TOOL_PEN; | ||
| 622 | break; | ||
| 623 | |||
| 624 | case 0x832: /* Stroke pen */ | ||
| 625 | case 0x032: | ||
| 626 | wacom->tool[idx] = BTN_TOOL_BRUSH; | ||
| 627 | break; | ||
| 628 | |||
| 629 | case 0x007: /* Mouse 4D and 2D */ | ||
| 630 | case 0x09c: | ||
| 631 | case 0x094: | ||
| 632 | case 0x017: /* Intuos3 2D Mouse */ | ||
| 633 | case 0x806: /* Intuos4 Mouse */ | ||
| 634 | wacom->tool[idx] = BTN_TOOL_MOUSE; | ||
| 635 | break; | ||
| 636 | |||
| 637 | case 0x096: /* Lens cursor */ | ||
| 638 | case 0x097: /* Intuos3 Lens cursor */ | ||
| 639 | case 0x006: /* Intuos4 Lens cursor */ | ||
| 640 | wacom->tool[idx] = BTN_TOOL_LENS; | ||
| 641 | break; | ||
| 642 | |||
| 643 | case 0x82a: /* Eraser */ | ||
| 644 | case 0x85a: | ||
| 645 | case 0x91a: | ||
| 646 | case 0xd1a: | ||
| 647 | case 0x0fa: | ||
| 648 | case 0x82b: /* Intuos3 Grip Pen Eraser */ | ||
| 649 | case 0x81b: /* Intuos3 Classic Pen Eraser */ | ||
| 650 | case 0x91b: /* Intuos3 Airbrush Eraser */ | ||
| 651 | case 0x80c: /* Intuos4/5 13HD/24HD Marker Pen Eraser */ | ||
| 652 | case 0x80a: /* Intuos4/5 13HD/24HD General Pen Eraser */ | ||
| 653 | case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ | ||
| 654 | case 0x14080a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */ | ||
| 655 | case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ | ||
| 656 | case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ | ||
| 657 | case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ | ||
| 658 | case 0x18080a: /* DTH2242 Eraser */ | ||
| 659 | case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */ | ||
| 660 | wacom->tool[idx] = BTN_TOOL_RUBBER; | ||
| 661 | break; | ||
| 662 | |||
| 663 | case 0xd12: | ||
| 664 | case 0x912: | ||
| 665 | case 0x112: | ||
| 666 | case 0x913: /* Intuos3 Airbrush */ | ||
| 667 | case 0x902: /* Intuos4/5 13HD/24HD Airbrush */ | ||
| 668 | case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */ | ||
| 669 | wacom->tool[idx] = BTN_TOOL_AIRBRUSH; | ||
| 670 | break; | ||
| 671 | |||
| 672 | default: /* Unknown tool */ | ||
| 673 | wacom->tool[idx] = BTN_TOOL_PEN; | ||
| 674 | break; | ||
| 675 | } | ||
| 676 | return 1; | 687 | return 1; |
| 677 | } | 688 | } |
| 678 | 689 | ||
| 679 | /* | 690 | /* in Range */ |
| 680 | * don't report events for invalid data | 691 | if ((data[1] & 0xfe) == 0x20) { |
| 681 | */ | 692 | if (features->type != INTUOSHT2) |
| 682 | /* older I4 styli don't work with new Cintiqs */ | 693 | wacom->shared->stylus_in_proximity = true; |
| 683 | if ((!((wacom->id[idx] >> 20) & 0x01) && | ||
| 684 | (features->type == WACOM_21UX2)) || | ||
| 685 | /* Only large Intuos support Lense Cursor */ | ||
| 686 | (wacom->tool[idx] == BTN_TOOL_LENS && | ||
| 687 | (features->type == INTUOS3 || | ||
| 688 | features->type == INTUOS3S || | ||
| 689 | features->type == INTUOS4 || | ||
| 690 | features->type == INTUOS4S || | ||
| 691 | features->type == INTUOS5 || | ||
| 692 | features->type == INTUOS5S || | ||
| 693 | features->type == INTUOSPM || | ||
| 694 | features->type == INTUOSPS)) || | ||
| 695 | /* Cintiq doesn't send data when RDY bit isn't set */ | ||
| 696 | (features->type == CINTIQ && !(data[1] & 0x40))) | ||
| 697 | return 1; | ||
| 698 | 694 | ||
| 699 | wacom->shared->stylus_in_proximity = true; | 695 | /* in Range while exiting */ |
| 700 | if (wacom->shared->touch_down) | 696 | if (wacom->reporting_data) { |
| 697 | input_report_key(input, BTN_TOUCH, 0); | ||
| 698 | input_report_abs(input, ABS_PRESSURE, 0); | ||
| 699 | input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); | ||
| 700 | return 2; | ||
| 701 | } | ||
| 701 | return 1; | 702 | return 1; |
| 702 | |||
| 703 | /* in Range while exiting */ | ||
| 704 | if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) { | ||
| 705 | input_report_key(input, BTN_TOUCH, 0); | ||
| 706 | input_report_abs(input, ABS_PRESSURE, 0); | ||
| 707 | input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); | ||
| 708 | return 2; | ||
| 709 | } | 703 | } |
| 710 | 704 | ||
| 711 | /* Exit report */ | 705 | /* Exit report */ |
| @@ -750,13 +744,6 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 750 | return 2; | 744 | return 2; |
| 751 | } | 745 | } |
| 752 | 746 | ||
| 753 | /* don't report other events if we don't know the ID */ | ||
| 754 | if (!wacom->id[idx]) { | ||
| 755 | /* but reschedule a read of the current tool */ | ||
| 756 | wacom_intuos_schedule_prox_event(wacom); | ||
| 757 | return 1; | ||
| 758 | } | ||
| 759 | |||
| 760 | return 0; | 747 | return 0; |
| 761 | } | 748 | } |
| 762 | 749 | ||
| @@ -897,6 +884,36 @@ static int wacom_intuos_general(struct wacom_wac *wacom) | |||
| 897 | data[0] != WACOM_REPORT_INTUOS_PEN) | 884 | data[0] != WACOM_REPORT_INTUOS_PEN) |
| 898 | return 0; | 885 | return 0; |
| 899 | 886 | ||
| 887 | if (wacom->shared->touch_down) | ||
| 888 | return 1; | ||
| 889 | |||
| 890 | /* don't report events if we don't know the tool ID */ | ||
| 891 | if (!wacom->id[idx]) { | ||
| 892 | /* but reschedule a read of the current tool */ | ||
| 893 | wacom_intuos_schedule_prox_event(wacom); | ||
| 894 | return 1; | ||
| 895 | } | ||
| 896 | |||
| 897 | /* | ||
| 898 | * don't report events for invalid data | ||
| 899 | */ | ||
| 900 | /* older I4 styli don't work with new Cintiqs */ | ||
| 901 | if ((!((wacom->id[idx] >> 20) & 0x01) && | ||
| 902 | (features->type == WACOM_21UX2)) || | ||
| 903 | /* Only large Intuos support Lense Cursor */ | ||
| 904 | (wacom->tool[idx] == BTN_TOOL_LENS && | ||
| 905 | (features->type == INTUOS3 || | ||
| 906 | features->type == INTUOS3S || | ||
| 907 | features->type == INTUOS4 || | ||
| 908 | features->type == INTUOS4S || | ||
| 909 | features->type == INTUOS5 || | ||
| 910 | features->type == INTUOS5S || | ||
| 911 | features->type == INTUOSPM || | ||
| 912 | features->type == INTUOSPS)) || | ||
| 913 | /* Cintiq doesn't send data when RDY bit isn't set */ | ||
| 914 | (features->type == CINTIQ && !(data[1] & 0x40))) | ||
| 915 | return 1; | ||
| 916 | |||
| 900 | x = (be16_to_cpup((__be16 *)&data[2]) << 1) | ((data[9] >> 1) & 1); | 917 | x = (be16_to_cpup((__be16 *)&data[2]) << 1) | ((data[9] >> 1) & 1); |
| 901 | y = (be16_to_cpup((__be16 *)&data[4]) << 1) | (data[9] & 1); | 918 | y = (be16_to_cpup((__be16 *)&data[4]) << 1) | (data[9] & 1); |
| 902 | distance = data[9] >> 2; | 919 | distance = data[9] >> 2; |
