aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-19 12:56:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-19 12:56:57 -0400
commit8a1e377e55f2dca5c689926313beeaa8ac2adb22 (patch)
treea0123dcf7c2268e48f6c23900df74eca0ae477e8
parentb6ffb11e4e5b6d1ae61c26c90255877fa4749eca (diff)
parent4973ca9a01e2354b159acedec1b9b8eb8de02ab7 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID fixes from Jiri Kosina: - hid-dr regression fix for certain dragonrise gamepads (device ID 0079:0006), from Ioan-Adrian Ratiu - dma-on-stack fix for hid-led driver, from Heiner Kallweit - quirk for Akai MIDImix device * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: HID: add quirk for Akai MIDImix. Revert "HID: dragonrise: fix HID Descriptor for 0x0006 PID" HID: hid-dr: add input mapping for axis selection HID: hid-led: fix issue with transfer buffer not being dma capable
-rw-r--r--drivers/hid/hid-dr.c83
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-led.c23
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
4 files changed, 48 insertions, 62 deletions
diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c
index 8fd4bf77f264..818ea7d93533 100644
--- a/drivers/hid/hid-dr.c
+++ b/drivers/hid/hid-dr.c
@@ -234,58 +234,6 @@ static __u8 pid0011_rdesc_fixed[] = {
234 0xC0 /* End Collection */ 234 0xC0 /* End Collection */
235}; 235};
236 236
237static __u8 pid0006_rdesc_fixed[] = {
238 0x05, 0x01, /* Usage Page (Generic Desktop) */
239 0x09, 0x04, /* Usage (Joystick) */
240 0xA1, 0x01, /* Collection (Application) */
241 0xA1, 0x02, /* Collection (Logical) */
242 0x75, 0x08, /* Report Size (8) */
243 0x95, 0x05, /* Report Count (5) */
244 0x15, 0x00, /* Logical Minimum (0) */
245 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
246 0x35, 0x00, /* Physical Minimum (0) */
247 0x46, 0xFF, 0x00, /* Physical Maximum (255) */
248 0x09, 0x30, /* Usage (X) */
249 0x09, 0x33, /* Usage (Ry) */
250 0x09, 0x32, /* Usage (Z) */
251 0x09, 0x31, /* Usage (Y) */
252 0x09, 0x34, /* Usage (Ry) */
253 0x81, 0x02, /* Input (Variable) */
254 0x75, 0x04, /* Report Size (4) */
255 0x95, 0x01, /* Report Count (1) */
256 0x25, 0x07, /* Logical Maximum (7) */
257 0x46, 0x3B, 0x01, /* Physical Maximum (315) */
258 0x65, 0x14, /* Unit (Centimeter) */
259 0x09, 0x39, /* Usage (Hat switch) */
260 0x81, 0x42, /* Input (Variable) */
261 0x65, 0x00, /* Unit (None) */
262 0x75, 0x01, /* Report Size (1) */
263 0x95, 0x0C, /* Report Count (12) */
264 0x25, 0x01, /* Logical Maximum (1) */
265 0x45, 0x01, /* Physical Maximum (1) */
266 0x05, 0x09, /* Usage Page (Button) */
267 0x19, 0x01, /* Usage Minimum (0x01) */
268 0x29, 0x0C, /* Usage Maximum (0x0C) */
269 0x81, 0x02, /* Input (Variable) */
270 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined) */
271 0x75, 0x01, /* Report Size (1) */
272 0x95, 0x08, /* Report Count (8) */
273 0x25, 0x01, /* Logical Maximum (1) */
274 0x45, 0x01, /* Physical Maximum (1) */
275 0x09, 0x01, /* Usage (0x01) */
276 0x81, 0x02, /* Input (Variable) */
277 0xC0, /* End Collection */
278 0xA1, 0x02, /* Collection (Logical) */
279 0x75, 0x08, /* Report Size (8) */
280 0x95, 0x07, /* Report Count (7) */
281 0x46, 0xFF, 0x00, /* Physical Maximum (255) */
282 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
283 0x09, 0x02, /* Usage (0x02) */
284 0x91, 0x02, /* Output (Variable) */
285 0xC0, /* End Collection */
286 0xC0 /* End Collection */
287};
288
289static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc, 237static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
290 unsigned int *rsize) 238 unsigned int *rsize)
291{ 239{
@@ -296,16 +244,34 @@ static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
296 *rsize = sizeof(pid0011_rdesc_fixed); 244 *rsize = sizeof(pid0011_rdesc_fixed);
297 } 245 }
298 break; 246 break;
299 case 0x0006:
300 if (*rsize == sizeof(pid0006_rdesc_fixed)) {
301 rdesc = pid0006_rdesc_fixed;
302 *rsize = sizeof(pid0006_rdesc_fixed);
303 }
304 break;
305 } 247 }
306 return rdesc; 248 return rdesc;
307} 249}
308 250
251#define map_abs(c) hid_map_usage(hi, usage, bit, max, EV_ABS, (c))
252#define map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c))
253
254static int dr_input_mapping(struct hid_device *hdev, struct hid_input *hi,
255 struct hid_field *field, struct hid_usage *usage,
256 unsigned long **bit, int *max)
257{
258 switch (usage->hid) {
259 /*
260 * revert to the old hid-input behavior where axes
261 * can be randomly assigned when hid->usage is reused.
262 */
263 case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
264 case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
265 if (field->flags & HID_MAIN_ITEM_RELATIVE)
266 map_rel(usage->hid & 0xf);
267 else
268 map_abs(usage->hid & 0xf);
269 return 1;
270 }
271
272 return 0;
273}
274
309static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) 275static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
310{ 276{
311 int ret; 277 int ret;
@@ -352,6 +318,7 @@ static struct hid_driver dr_driver = {
352 .id_table = dr_devices, 318 .id_table = dr_devices,
353 .report_fixup = dr_report_fixup, 319 .report_fixup = dr_report_fixup,
354 .probe = dr_probe, 320 .probe = dr_probe,
321 .input_mapping = dr_input_mapping,
355}; 322};
356module_hid_driver(dr_driver); 323module_hid_driver(dr_driver);
357 324
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index cd59c79eebdd..6cfb5cacc253 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -64,6 +64,9 @@
64#define USB_VENDOR_ID_AKAI 0x2011 64#define USB_VENDOR_ID_AKAI 0x2011
65#define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 65#define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715
66 66
67#define USB_VENDOR_ID_AKAI_09E8 0x09E8
68#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031
69
67#define USB_VENDOR_ID_ALCOR 0x058f 70#define USB_VENDOR_ID_ALCOR 0x058f
68#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 71#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
69 72
diff --git a/drivers/hid/hid-led.c b/drivers/hid/hid-led.c
index d8d55f37b4f5..d3e1ab162f7c 100644
--- a/drivers/hid/hid-led.c
+++ b/drivers/hid/hid-led.c
@@ -100,6 +100,7 @@ struct hidled_device {
100 const struct hidled_config *config; 100 const struct hidled_config *config;
101 struct hid_device *hdev; 101 struct hid_device *hdev;
102 struct hidled_rgb *rgb; 102 struct hidled_rgb *rgb;
103 u8 *buf;
103 struct mutex lock; 104 struct mutex lock;
104}; 105};
105 106
@@ -118,13 +119,19 @@ static int hidled_send(struct hidled_device *ldev, __u8 *buf)
118 119
119 mutex_lock(&ldev->lock); 120 mutex_lock(&ldev->lock);
120 121
122 /*
123 * buffer provided to hid_hw_raw_request must not be on the stack
124 * and must not be part of a data structure
125 */
126 memcpy(ldev->buf, buf, ldev->config->report_size);
127
121 if (ldev->config->report_type == RAW_REQUEST) 128 if (ldev->config->report_type == RAW_REQUEST)
122 ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, 129 ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf,
123 ldev->config->report_size, 130 ldev->config->report_size,
124 HID_FEATURE_REPORT, 131 HID_FEATURE_REPORT,
125 HID_REQ_SET_REPORT); 132 HID_REQ_SET_REPORT);
126 else if (ldev->config->report_type == OUTPUT_REPORT) 133 else if (ldev->config->report_type == OUTPUT_REPORT)
127 ret = hid_hw_output_report(ldev->hdev, buf, 134 ret = hid_hw_output_report(ldev->hdev, ldev->buf,
128 ldev->config->report_size); 135 ldev->config->report_size);
129 else 136 else
130 ret = -EINVAL; 137 ret = -EINVAL;
@@ -147,17 +154,21 @@ static int hidled_recv(struct hidled_device *ldev, __u8 *buf)
147 154
148 mutex_lock(&ldev->lock); 155 mutex_lock(&ldev->lock);
149 156
150 ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, 157 memcpy(ldev->buf, buf, ldev->config->report_size);
158
159 ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf,
151 ldev->config->report_size, 160 ldev->config->report_size,
152 HID_FEATURE_REPORT, 161 HID_FEATURE_REPORT,
153 HID_REQ_SET_REPORT); 162 HID_REQ_SET_REPORT);
154 if (ret < 0) 163 if (ret < 0)
155 goto err; 164 goto err;
156 165
157 ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, 166 ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf,
158 ldev->config->report_size, 167 ldev->config->report_size,
159 HID_FEATURE_REPORT, 168 HID_FEATURE_REPORT,
160 HID_REQ_GET_REPORT); 169 HID_REQ_GET_REPORT);
170
171 memcpy(buf, ldev->buf, ldev->config->report_size);
161err: 172err:
162 mutex_unlock(&ldev->lock); 173 mutex_unlock(&ldev->lock);
163 174
@@ -447,6 +458,10 @@ static int hidled_probe(struct hid_device *hdev, const struct hid_device_id *id)
447 if (!ldev) 458 if (!ldev)
448 return -ENOMEM; 459 return -ENOMEM;
449 460
461 ldev->buf = devm_kmalloc(&hdev->dev, MAX_REPORT_SIZE, GFP_KERNEL);
462 if (!ldev->buf)
463 return -ENOMEM;
464
450 ret = hid_parse(hdev); 465 ret = hid_parse(hdev);
451 if (ret) 466 if (ret)
452 return ret; 467 return ret;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 0a0eca5da47d..354d49ea36dd 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -56,6 +56,7 @@ static const struct hid_blacklist {
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_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS },
59 { USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS },
59 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, 60 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
60 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, 61 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
61 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, 62 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },