From 6371fe54b500f1f31033e0035a061fa320171930 Mon Sep 17 00:00:00 2001 From: Bojan Prtvar Date: Thu, 4 Aug 2011 22:43:46 +0200 Subject: HID: zydacron: kfree() NULL pointer cleanup Checking for NULL pointers before kfree() is redundant. Signed-off-by: Bojan Prtvar Signed-off-by: Jiri Kosina --- drivers/hid/hid-zydacron.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c index e903715..1ad85f2 100644 --- a/drivers/hid/hid-zydacron.c +++ b/drivers/hid/hid-zydacron.c @@ -201,9 +201,7 @@ static void zc_remove(struct hid_device *hdev) struct zc_device *zc = hid_get_drvdata(hdev); hid_hw_stop(hdev); - - if (NULL != zc) - kfree(zc); + kfree(zc); } static const struct hid_device_id zc_devices[] = { -- cgit v1.1 From 00b15628b0aa73199f74bd6c988b8d2b55f51190 Mon Sep 17 00:00:00 2001 From: Bojan Prtvar Date: Thu, 4 Aug 2011 23:46:48 +0200 Subject: HID: prodikeys: kfree() NULL pointer cleanup No need for freeing pm in case when it's not allocated. Reported-by: Julia Lawall Signed-off-by: Bojan Prtvar Signed-off-by: Jiri Kosina --- drivers/hid/hid-prodikeys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 158b389..f779009 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -816,7 +816,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) if (pm == NULL) { hid_err(hdev, "can't alloc descriptor\n"); ret = -ENOMEM; - goto err_free; + goto err_free_pk; } pm->pk = pk; @@ -849,10 +849,10 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) err_stop: hid_hw_stop(hdev); err_free: - if (pm != NULL) - kfree(pm); - + kfree(pm); +err_free_pk: kfree(pk); + return ret; } -- cgit v1.1 From 4ea5454203d991ec85264f64f89ca8855fce69b0 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 10 Aug 2011 14:02:07 +0200 Subject: HID: Fix race condition between driver core and ll-driver HID low level drivers register new devices with the HID core which then adds the devices to the HID bus. The HID bus normally immediately probes an appropriate driver which then handles HID input for this device. The ll driver now uses the hid_input_report() function to report input events for a specific device. However, if the HID bus unloads the driver at the same time (for instance via a call to /sys/bus/hid/devices//unbind) then the hdev->driver pointer may be used by hid_input_report() and hid_device_remove() at the same time which may cause hdev->driver to point to invalid memory. This fix adds a semaphore to every hid device which protects hdev->driver from asynchronous access. This semaphore is locked during driver *_probe and *_remove and also inside hid_input_report(). The *_probe and *_remove functions may sleep so the semaphore is good here, however, hid_input_report() is in atomic context and hence only uses down_trylock(). If it cannot acquire the lock it simply drops the input package. The low-level drivers report input events synchronously so hid_input_report() should never be entered twice at the same time on the same device. Hence, the lock should always be available. But if the driver is currently probed/removed then the lock is not available and dropping the package should be safe because this is what would have happened if the package arrived some milliseconds earlier/later. This also fixes another race condition while probing drivers: First the *_probe function of the driver is called and only if that succeeds, the related input device of hidinput is registered. If the low level driver reports input events after the *_probe function returned but before the input device is registered, then a NULL pointer dereference will occur. (Equivalently on driver remove function). This is not possible anymore, since the semaphore lock drops all incoming packages until the driver/device is fully initialized. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1a5cf0c..f9cff93 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -1087,14 +1088,23 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i unsigned int i; int ret; - if (!hid || !hid->driver) + if (!hid) return -ENODEV; + + if (down_trylock(&hid->driver_lock)) + return -EBUSY; + + if (!hid->driver) { + ret = -ENODEV; + goto unlock; + } report_enum = hid->report_enum + type; hdrv = hid->driver; if (!size) { dbg_hid("empty report\n"); - return -1; + ret = -1; + goto unlock; } buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); @@ -1118,17 +1128,23 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i nomem: report = hid_get_report(report_enum, data); - if (!report) - return -1; + if (!report) { + ret = -1; + goto unlock; + } if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { ret = hdrv->raw_event(hid, report, data, size); - if (ret != 0) - return ret < 0 ? ret : 0; + if (ret != 0) { + ret = ret < 0 ? ret : 0; + goto unlock; + } } hid_report_raw_event(hid, type, data, size, interrupt); +unlock: + up(&hid->driver_lock); return 0; } EXPORT_SYMBOL_GPL(hid_input_report); @@ -1617,6 +1633,9 @@ static int hid_device_probe(struct device *dev) const struct hid_device_id *id; int ret = 0; + if (down_interruptible(&hdev->driver_lock)) + return -EINTR; + if (!hdev->driver) { id = hid_match_device(hdev, hdrv); if (id == NULL) @@ -1633,14 +1652,20 @@ static int hid_device_probe(struct device *dev) if (ret) hdev->driver = NULL; } + + up(&hdev->driver_lock); return ret; } static int hid_device_remove(struct device *dev) { struct hid_device *hdev = container_of(dev, struct hid_device, dev); - struct hid_driver *hdrv = hdev->driver; + struct hid_driver *hdrv; + + if (down_interruptible(&hdev->driver_lock)) + return -EINTR; + hdrv = hdev->driver; if (hdrv) { if (hdrv->remove) hdrv->remove(hdev); @@ -1649,6 +1674,7 @@ static int hid_device_remove(struct device *dev) hdev->driver = NULL; } + up(&hdev->driver_lock); return 0; } @@ -1996,6 +2022,7 @@ struct hid_device *hid_allocate_device(void) init_waitqueue_head(&hdev->debug_wait); INIT_LIST_HEAD(&hdev->debug_list); + sema_init(&hdev->driver_lock, 1); return hdev; err: -- cgit v1.1 From 45dc1ac73d28b3adb5819818785e758b1f369b74 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 10 Aug 2011 14:02:59 +0200 Subject: HID: propagate return value correctly in hid_input_report() Fix a return value propagation that was omitted in David Herrmann's locking fix around hid_input_report(). Reported-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f9cff93..bf1f740 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1086,7 +1086,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i struct hid_report *report; char *buf; unsigned int i; - int ret; + int ret = 0; if (!hid) return -ENODEV; @@ -1145,7 +1145,7 @@ nomem: unlock: up(&hid->driver_lock); - return 0; + return ret; } EXPORT_SYMBOL_GPL(hid_input_report); -- cgit v1.1 From 5d922baa631058c7e37ae33e81c4d3e6437f8d1d Mon Sep 17 00:00:00 2001 From: "Joshua V. Dillon" Date: Fri, 5 Aug 2011 12:05:22 -0700 Subject: HID: add support for MacBookAir4,2 keyboard. Added USB device IDs for MacBookAir4,2 keyboard. Device constants were copied from the MacBookAir3,2 constants. The 4,2 device specification is reportedly unchanged from the 3,2 predecessor and seems to work well. Signed-off-by: Joshua V Dillon Signed-off-by: Chase Douglas Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 9 +++++++++ drivers/hid/hid-ids.h | 3 +++ 2 files changed, 12 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index b85744f..8bfd87b 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -183,6 +183,9 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) table = macbookair_fn_keys; + else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) + table = macbookair_fn_keys; else if (hid->product < 0x21d || hid->product >= 0x300) table = powerbook_fn_keys; else @@ -487,6 +490,12 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI), + .driver_data = APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO), + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index db63ccf..3c83f8d 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -109,6 +109,9 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 +#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c +#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d +#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b -- cgit v1.1 From f6f554f09c5b831efdaf67c449e18ca06ee648fe Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 10 Aug 2011 14:12:52 +0200 Subject: HID: add MacBookAir4,2 to hid_have_special_driver[] Otherwise the generic driver wouldn't unbind from it and wouldn't let hid-apple to automatically take over. Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bf1f740..6813873 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1356,6 +1356,9 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, -- cgit v1.1 From ad395ccadb6b2f0a4f9e004c9e6f2a8c22091ed0 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sun, 14 Aug 2011 20:42:05 +0100 Subject: IHD: Support force feedback on MP-8866 Support force feedback on the Dual USB Force Feedback Joypad (MP-8866). Signed-off-by: Sean Young Acked-by: Jussi Kivilinna Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-sjoy.c | 68 ++++++++++++++++++++++------------------- drivers/hid/usbhid/hid-quirks.c | 1 - 3 files changed, 38 insertions(+), 32 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6813873..d34eb34 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1517,6 +1517,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c index 16f7caf..810425f 100644 --- a/drivers/hid/hid-sjoy.c +++ b/drivers/hid/hid-sjoy.c @@ -65,8 +65,7 @@ static int sjoyff_init(struct hid_device *hid) { struct sjoyff_device *sjoyff; struct hid_report *report; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); + struct hid_input *hidinput; struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct list_head *report_ptr = report_list; @@ -78,43 +77,45 @@ static int sjoyff_init(struct hid_device *hid) return -ENODEV; } - report_ptr = report_ptr->next; + list_for_each_entry(hidinput, &hid->inputs, list) { + report_ptr = report_ptr->next; - if (report_ptr == report_list) { - hid_err(hid, "required output report is missing\n"); - return -ENODEV; - } + if (report_ptr == report_list) { + hid_err(hid, "required output report is missing\n"); + return -ENODEV; + } - report = list_entry(report_ptr, struct hid_report, list); - if (report->maxfield < 1) { - hid_err(hid, "no fields in the report\n"); - return -ENODEV; - } + report = list_entry(report_ptr, struct hid_report, list); + if (report->maxfield < 1) { + hid_err(hid, "no fields in the report\n"); + return -ENODEV; + } - if (report->field[0]->report_count < 3) { - hid_err(hid, "not enough values in the field\n"); - return -ENODEV; - } + if (report->field[0]->report_count < 3) { + hid_err(hid, "not enough values in the field\n"); + return -ENODEV; + } - sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL); - if (!sjoyff) - return -ENOMEM; + sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL); + if (!sjoyff) + return -ENOMEM; - dev = hidinput->input; + dev = hidinput->input; - set_bit(FF_RUMBLE, dev->ffbit); + set_bit(FF_RUMBLE, dev->ffbit); - error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play); - if (error) { - kfree(sjoyff); - return error; - } + error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play); + if (error) { + kfree(sjoyff); + return error; + } - sjoyff->report = report; - sjoyff->report->field[0]->value[0] = 0x01; - sjoyff->report->field[0]->value[1] = 0x00; - sjoyff->report->field[0]->value[2] = 0x00; - usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); + sjoyff->report = report; + sjoyff->report->field[0]->value[0] = 0x01; + sjoyff->report->field[0]->value[1] = 0x00; + sjoyff->report->field[0]->value[2] = 0x00; + usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); + } hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); @@ -131,6 +132,8 @@ static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; + hdev->quirks |= id->driver_data; + ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); @@ -152,6 +155,9 @@ err: static const struct hid_device_id sjoy_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD), + .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET | + HID_QUIRK_SKIP_OUTPUT_REPORTS }, { } }; MODULE_DEVICE_TABLE(hid, sjoy_devices); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 621959d..df618a3 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -79,7 +79,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, -- cgit v1.1 From 54d3339ac127bbf1efd3ae5a1f520a6c302c952a Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Mon, 15 Aug 2011 16:39:02 -0700 Subject: HID: hid-debug: Show application usage for each collection. Signed-off-by: jeffbrown@android.com Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-debug.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index bae4874..9a243ca 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -450,6 +450,11 @@ void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) { seq_printf(f, "Logical("); hid_resolv_usage(field->logical, f); seq_printf(f, ")\n"); } + if (field->application) { + tab(n, f); + seq_printf(f, "Application("); + hid_resolv_usage(field->application, f); seq_printf(f, ")\n"); + } tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage); for (j = 0; j < field->maxusage; j++) { tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n"); -- cgit v1.1 From ba623a774f5b529f89b3d63e0837df52e16ffb3b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 24 Aug 2011 14:27:46 +0300 Subject: HID: unlock on error path in hid_device_probe() We recently introduced locking into this function, but we missed an error path which needs an unlock. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d34eb34..d98332b 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1642,8 +1642,10 @@ static int hid_device_probe(struct device *dev) if (!hdev->driver) { id = hid_match_device(hdev, hdrv); - if (id == NULL) - return -ENODEV; + if (id == NULL) { + ret = -ENODEV; + goto unlock; + } hdev->driver = hdrv; if (hdrv->probe) { @@ -1656,7 +1658,7 @@ static int hid_device_probe(struct device *dev) if (ret) hdev->driver = NULL; } - +unlock: up(&hdev->driver_lock); return ret; } -- cgit v1.1 From 1a8962317f494ad858971fc08ba035eff658a5c9 Mon Sep 17 00:00:00 2001 From: Amit Nagal Date: Wed, 7 Sep 2011 13:48:47 +0200 Subject: HID: hidraw: free list for all error in hidraw_open In function hidraw_open struct hidraw_list *list should be freed for all error conditions. Signed-off-by: Amit Nagal Signed-off-by: Jiri Kosina --- drivers/hid/hidraw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index c79578b..c841a8e 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -259,7 +259,6 @@ static int hidraw_open(struct inode *inode, struct file *file) mutex_lock(&minors_lock); if (!hidraw_table[minor]) { - kfree(list); err = -ENODEV; goto out_unlock; } @@ -285,6 +284,8 @@ static int hidraw_open(struct inode *inode, struct file *file) out_unlock: mutex_unlock(&minors_lock); out: + if (err < 0) + kfree(list); return err; } -- cgit v1.1 From d762cc290b9f17e346f4297fd5984b70ce71ef66 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Sat, 1 Oct 2011 15:54:53 +0900 Subject: HID: Add support MacbookAir 4,1 keyboard Added USB device IDs and keyboard map for MacBookAir 4,1 keyboard. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 31 +++++++++++++++++++++++++++++++ drivers/hid/hid-core.c | 3 +++ drivers/hid/hid-ids.h | 3 +++ 3 files changed, 37 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 8bfd87b..b33bab9 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -82,6 +82,28 @@ static const struct apple_key_translation macbookair_fn_keys[] = { { } }; +static const struct apple_key_translation macbookair4_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_ENTER, KEY_INSERT }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, + { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, + { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, + { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, + { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, + { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, + { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, + { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, + { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, + { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, + { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, + { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, + { KEY_UP, KEY_PAGEUP }, + { KEY_DOWN, KEY_PAGEDOWN }, + { KEY_LEFT, KEY_HOME }, + { KEY_RIGHT, KEY_END }, + { } +}; + static const struct apple_key_translation apple_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, @@ -186,6 +208,9 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI && hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) table = macbookair_fn_keys; + else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) + table = macbookair4_fn_keys; else if (hid->product < 0x21d || hid->product >= 0x300) table = powerbook_fn_keys; else @@ -496,6 +521,12 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI), + .driver_data = APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO), + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d98332b..5b4b76e 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1359,6 +1359,9 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3c83f8d..aa74193 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -109,6 +109,9 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 +#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 +#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a +#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e -- cgit v1.1 From 4b086910ad1b889ddf3ef5598caec03178cf2bb4 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 4 Oct 2011 14:01:12 +0200 Subject: HID: MacbookAir4,1 and MacbookAir4,2 need entry in hid_mouse_ignore_list[] The respective mouse devices are already supported by bcm5974. Now that Nobuhiro Iwamatsu added support for keyboard to hid-apple driver, we need to ignore the mouse interfaces of these so that they can still be properly claimed by bcm5974 driver. Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5b4b76e..d5dae95 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1924,6 +1924,12 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } -- cgit v1.1 From da617c7cb915545dda4280df888dd6f8d5697420 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 5 Oct 2011 16:54:45 +0200 Subject: HID: consolidate MacbookAir 4,1 mappings MacbookAir 4,1 doesn't require extra mapping table, as the mappings are identical to apple_fn_keys[]. Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index b33bab9..4674556 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -82,28 +82,6 @@ static const struct apple_key_translation macbookair_fn_keys[] = { { } }; -static const struct apple_key_translation macbookair4_fn_keys[] = { - { KEY_BACKSPACE, KEY_DELETE }, - { KEY_ENTER, KEY_INSERT }, - { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, - { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, - { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, - { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, - { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, - { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, - { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, - { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, - { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, - { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, - { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, - { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, - { KEY_UP, KEY_PAGEUP }, - { KEY_DOWN, KEY_PAGEDOWN }, - { KEY_LEFT, KEY_HOME }, - { KEY_RIGHT, KEY_END }, - { } -}; - static const struct apple_key_translation apple_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, @@ -208,9 +186,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI && hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) table = macbookair_fn_keys; - else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI && - hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) - table = macbookair4_fn_keys; else if (hid->product < 0x21d || hid->product >= 0x300) table = powerbook_fn_keys; else -- cgit v1.1 From f6a04605f303852963f3f357d19b967aa83c172f Mon Sep 17 00:00:00 2001 From: Terry Lambert Date: Fri, 14 Oct 2011 17:18:54 -0700 Subject: HID: support primax keyboards violating USB HID spec Primax keyboards with the issue this driver addresses report modifier keys as in band key events instead of as out of band modifier bits, resulting in the modifier keys generating key up events immediately before the keys they are intended to modify. This driver rewrites the raw report data from such keyboards into USB HID 1.11 compliant report data. It only matches the USB vendor and product IDs for the keyboard it has been tested on. Since there are several keyboards, notably a number of laptops and folding USB keyboards known to have similar unresolved problem reports, the list is expected to grow. Signed-off-by: Terry Lambert Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 8 ++++ drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 ++ drivers/hid/hid-primax.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 drivers/hid/hid-primax.c (limited to 'drivers/hid') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 306b15f..121eed5 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -441,6 +441,14 @@ config HID_PICOLCD_LEDS ---help--- Provide access to PicoLCD's GPO pins via leds class. +config HID_PRIMAX + tristate "Primax non-fully HID-compliant devices" if EXPERT + depends on USB_HID + default !EXPERT + ---help--- + Support for Primax devices that are not fully compliant with the + HID standard. + config HID_QUANTA tristate "Quanta Optical Touch panels" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 0a0a38e..735b8cc 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_HID_QUANTA) += hid-quanta.o obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o +obj-$(CONFIG_HID_PRIMAX) += hid-primax.o obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d5dae95..df693e7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1480,6 +1480,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index aa74193..fa7579b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -692,4 +692,7 @@ #define USB_VENDOR_ID_ZYDACRON 0x13EC #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 +#define USB_VENDOR_ID_PRIMAX 0x0461 +#define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 + #endif diff --git a/drivers/hid/hid-primax.c b/drivers/hid/hid-primax.c new file mode 100644 index 0000000..4d3c60d --- /dev/null +++ b/drivers/hid/hid-primax.c @@ -0,0 +1,117 @@ +/* + * HID driver for primax and similar keyboards with in-band modifiers + * + * Copyright 2011 Google Inc. All Rights Reserved + * + * Author: + * Terry Lambert + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include "hid-ids.h" + +static int px_raw_event(struct hid_device *hid, struct hid_report *report, + u8 *data, int size) +{ + int idx = size; + + switch (report->id) { + case 0: /* keyboard input */ + /* + * Convert in-band modifier key values into out of band + * modifier bits and pull the key strokes from the report. + * Thus a report data set which looked like: + * + * [00][00][E0][30][00][00][00][00] + * (no modifier bits + "Left Shift" key + "1" key) + * + * Would be converted to: + * + * [01][00][00][30][00][00][00][00] + * (Left Shift modifier bit + "1" key) + * + * As long as it's in the size range, the upper level + * drivers don't particularly care if there are in-band + * 0-valued keys, so they don't stop parsing. + */ + while (--idx > 1) { + if (data[idx] < 0xE0 || data[idx] > 0xE7) + continue; + data[0] |= (1 << (data[idx] - 0xE0)); + data[idx] = 0; + } + hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, 0); + return 1; + + default: /* unknown report */ + /* Unknown report type; pass upstream */ + hid_info(hid, "unknown report type %d\n", report->id); + break; + } + + return 0; +} + +static int px_probe(struct hid_device *hid, const struct hid_device_id *id) +{ + int ret; + + ret = hid_parse(hid); + if (ret) { + hid_err(hid, "parse failed\n"); + goto fail; + } + + ret = hid_hw_start(hid, HID_CONNECT_DEFAULT); + if (ret) + hid_err(hid, "hw start failed\n"); + +fail: + return ret; +} + +static void px_remove(struct hid_device *hid) +{ + hid_hw_stop(hid); +} + +static const struct hid_device_id px_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, + { } +}; +MODULE_DEVICE_TABLE(hid, px_devices); + +static struct hid_driver px_driver = { + .name = "primax", + .id_table = px_devices, + .raw_event = px_raw_event, + .probe = px_probe, + .remove = px_remove, +}; + +static int __init px_init(void) +{ + return hid_register_driver(&px_driver); +} + +static void __exit px_exit(void) +{ + hid_unregister_driver(&px_driver); +} + +module_init(px_init); +module_exit(px_exit); +MODULE_AUTHOR("Terry Lambert "); +MODULE_LICENSE("GPL"); -- cgit v1.1 From dfe9a31211c0a3a0252af6c87935d7ac718aadf9 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 17 Oct 2011 17:04:58 +0200 Subject: HID: primax: remove spurious dependency Remove Kconfig dependency for hid-primax driver on CONFIG_EXPERT. Please see changelog of 73d5e8f77e8 ("HID: fix up 'EMBEDDED' mess in Kconfig") for reasoning behind this. Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 121eed5..dab7b0d 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -442,9 +442,8 @@ config HID_PICOLCD_LEDS Provide access to PicoLCD's GPO pins via leds class. config HID_PRIMAX - tristate "Primax non-fully HID-compliant devices" if EXPERT + tristate "Primax non-fully HID-compliant devices" depends on USB_HID - default !EXPERT ---help--- Support for Primax devices that are not fully compliant with the HID standard. -- cgit v1.1 From 1bcc20675a1ac1ba47eaa201e02a89b0508e17b2 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 20 Oct 2011 21:26:21 +0100 Subject: HID: Add device IDs for more SJOY adapters Support the following models: Super Joy Box 3 Pro, Super Dual Box Pro and Super Joy Box 5 Pro. These models have support for pressure sensitive buttons and they can force the controller to either digital or analog mode, both of which are not supported yet. Signed-off-by: Sean Young Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 6 +++++- drivers/hid/hid-core.c | 3 +++ drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-sjoy.c | 7 +++++++ drivers/hid/usbhid/hid-quirks.c | 1 - 5 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index dab7b0d..4d07288 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -546,7 +546,11 @@ config HID_SMARTJOYPLUS tristate "SmartJoy PLUS PS2/USB adapter support" depends on USB_HID ---help--- - Support for SmartJoy PLUS PS2/USB adapter. + Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box, + Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro. + + Note that DDR (Dance Dance Revolution) mode is not supported, nor + is pressure sensitive buttons on the pro models. config SMARTJOYPLUS_FF bool "SmartJoy PLUS PS2/USB adapter force feedback support" diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index df693e7..e345370 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1522,6 +1522,9 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index fa7579b..fba6ceb 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -677,6 +677,9 @@ #define USB_VENDOR_ID_WISEGROUP_LTD 0x6666 #define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 +#define USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO 0x8801 +#define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802 +#define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804 #define USB_VENDOR_ID_X_TENSIONS 0x1ae7 #define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001 diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c index 810425f..670da91 100644 --- a/drivers/hid/hid-sjoy.c +++ b/drivers/hid/hid-sjoy.c @@ -154,6 +154,13 @@ err: } static const struct hid_device_id sjoy_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO), + .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET | + HID_QUIRK_SKIP_OUTPUT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO), + .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET | + HID_QUIRK_SKIP_OUTPUT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD), .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET | diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index df618a3..fe3e67d 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -81,7 +81,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, -- cgit v1.1