Commit 8a1e377e authored by Linus Torvalds's avatar Linus Torvalds

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
parents b6ffb11e 4973ca9a
...@@ -234,58 +234,6 @@ static __u8 pid0011_rdesc_fixed[] = { ...@@ -234,58 +234,6 @@ static __u8 pid0011_rdesc_fixed[] = {
0xC0 /* End Collection */ 0xC0 /* End Collection */
}; };
static __u8 pid0006_rdesc_fixed[] = {
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x04, /* Usage (Joystick) */
0xA1, 0x01, /* Collection (Application) */
0xA1, 0x02, /* Collection (Logical) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x05, /* Report Count (5) */
0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xFF, 0x00, /* Logical Maximum (255) */
0x35, 0x00, /* Physical Minimum (0) */
0x46, 0xFF, 0x00, /* Physical Maximum (255) */
0x09, 0x30, /* Usage (X) */
0x09, 0x33, /* Usage (Ry) */
0x09, 0x32, /* Usage (Z) */
0x09, 0x31, /* Usage (Y) */
0x09, 0x34, /* Usage (Ry) */
0x81, 0x02, /* Input (Variable) */
0x75, 0x04, /* Report Size (4) */
0x95, 0x01, /* Report Count (1) */
0x25, 0x07, /* Logical Maximum (7) */
0x46, 0x3B, 0x01, /* Physical Maximum (315) */
0x65, 0x14, /* Unit (Centimeter) */
0x09, 0x39, /* Usage (Hat switch) */
0x81, 0x42, /* Input (Variable) */
0x65, 0x00, /* Unit (None) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x0C, /* Report Count (12) */
0x25, 0x01, /* Logical Maximum (1) */
0x45, 0x01, /* Physical Maximum (1) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 0x01, /* Usage Minimum (0x01) */
0x29, 0x0C, /* Usage Maximum (0x0C) */
0x81, 0x02, /* Input (Variable) */
0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x08, /* Report Count (8) */
0x25, 0x01, /* Logical Maximum (1) */
0x45, 0x01, /* Physical Maximum (1) */
0x09, 0x01, /* Usage (0x01) */
0x81, 0x02, /* Input (Variable) */
0xC0, /* End Collection */
0xA1, 0x02, /* Collection (Logical) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x07, /* Report Count (7) */
0x46, 0xFF, 0x00, /* Physical Maximum (255) */
0x26, 0xFF, 0x00, /* Logical Maximum (255) */
0x09, 0x02, /* Usage (0x02) */
0x91, 0x02, /* Output (Variable) */
0xC0, /* End Collection */
0xC0 /* End Collection */
};
static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc, static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize) unsigned int *rsize)
{ {
...@@ -296,16 +244,34 @@ static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc, ...@@ -296,16 +244,34 @@ static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
*rsize = sizeof(pid0011_rdesc_fixed); *rsize = sizeof(pid0011_rdesc_fixed);
} }
break; break;
case 0x0006:
if (*rsize == sizeof(pid0006_rdesc_fixed)) {
rdesc = pid0006_rdesc_fixed;
*rsize = sizeof(pid0006_rdesc_fixed);
}
break;
} }
return rdesc; return rdesc;
} }
#define map_abs(c) hid_map_usage(hi, usage, bit, max, EV_ABS, (c))
#define map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c))
static int dr_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
switch (usage->hid) {
/*
* revert to the old hid-input behavior where axes
* can be randomly assigned when hid->usage is reused.
*/
case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
if (field->flags & HID_MAIN_ITEM_RELATIVE)
map_rel(usage->hid & 0xf);
else
map_abs(usage->hid & 0xf);
return 1;
}
return 0;
}
static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
{ {
int ret; int ret;
...@@ -352,6 +318,7 @@ static struct hid_driver dr_driver = { ...@@ -352,6 +318,7 @@ static struct hid_driver dr_driver = {
.id_table = dr_devices, .id_table = dr_devices,
.report_fixup = dr_report_fixup, .report_fixup = dr_report_fixup,
.probe = dr_probe, .probe = dr_probe,
.input_mapping = dr_input_mapping,
}; };
module_hid_driver(dr_driver); module_hid_driver(dr_driver);
......
...@@ -64,6 +64,9 @@ ...@@ -64,6 +64,9 @@
#define USB_VENDOR_ID_AKAI 0x2011 #define USB_VENDOR_ID_AKAI 0x2011
#define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 #define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715
#define USB_VENDOR_ID_AKAI_09E8 0x09E8
#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031
#define USB_VENDOR_ID_ALCOR 0x058f #define USB_VENDOR_ID_ALCOR 0x058f
#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
......
...@@ -100,6 +100,7 @@ struct hidled_device { ...@@ -100,6 +100,7 @@ struct hidled_device {
const struct hidled_config *config; const struct hidled_config *config;
struct hid_device *hdev; struct hid_device *hdev;
struct hidled_rgb *rgb; struct hidled_rgb *rgb;
u8 *buf;
struct mutex lock; struct mutex lock;
}; };
...@@ -118,13 +119,19 @@ static int hidled_send(struct hidled_device *ldev, __u8 *buf) ...@@ -118,13 +119,19 @@ static int hidled_send(struct hidled_device *ldev, __u8 *buf)
mutex_lock(&ldev->lock); mutex_lock(&ldev->lock);
/*
* buffer provided to hid_hw_raw_request must not be on the stack
* and must not be part of a data structure
*/
memcpy(ldev->buf, buf, ldev->config->report_size);
if (ldev->config->report_type == RAW_REQUEST) if (ldev->config->report_type == RAW_REQUEST)
ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf,
ldev->config->report_size, ldev->config->report_size,
HID_FEATURE_REPORT, HID_FEATURE_REPORT,
HID_REQ_SET_REPORT); HID_REQ_SET_REPORT);
else if (ldev->config->report_type == OUTPUT_REPORT) else if (ldev->config->report_type == OUTPUT_REPORT)
ret = hid_hw_output_report(ldev->hdev, buf, ret = hid_hw_output_report(ldev->hdev, ldev->buf,
ldev->config->report_size); ldev->config->report_size);
else else
ret = -EINVAL; ret = -EINVAL;
...@@ -147,17 +154,21 @@ static int hidled_recv(struct hidled_device *ldev, __u8 *buf) ...@@ -147,17 +154,21 @@ static int hidled_recv(struct hidled_device *ldev, __u8 *buf)
mutex_lock(&ldev->lock); mutex_lock(&ldev->lock);
ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, memcpy(ldev->buf, buf, ldev->config->report_size);
ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf,
ldev->config->report_size, ldev->config->report_size,
HID_FEATURE_REPORT, HID_FEATURE_REPORT,
HID_REQ_SET_REPORT); HID_REQ_SET_REPORT);
if (ret < 0) if (ret < 0)
goto err; goto err;
ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf,
ldev->config->report_size, ldev->config->report_size,
HID_FEATURE_REPORT, HID_FEATURE_REPORT,
HID_REQ_GET_REPORT); HID_REQ_GET_REPORT);
memcpy(buf, ldev->buf, ldev->config->report_size);
err: err:
mutex_unlock(&ldev->lock); mutex_unlock(&ldev->lock);
...@@ -447,6 +458,10 @@ static int hidled_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -447,6 +458,10 @@ static int hidled_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (!ldev) if (!ldev)
return -ENOMEM; return -ENOMEM;
ldev->buf = devm_kmalloc(&hdev->dev, MAX_REPORT_SIZE, GFP_KERNEL);
if (!ldev->buf)
return -ENOMEM;
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -56,6 +56,7 @@ static const struct hid_blacklist { ...@@ -56,6 +56,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment