diff options
| -rw-r--r-- | drivers/hid/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/hid/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-dummy.c | 3 | ||||
| -rw-r--r-- | drivers/hid/hid-samsung.c | 101 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 33 | ||||
| -rw-r--r-- | include/linux/hid.h | 6 | 
7 files changed, 113 insertions, 39 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 4dcb92ac887..52b617bf2b9 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -175,6 +175,13 @@ config HID_PETALYNX  	---help---  	Support for Petalynx Maxter remote. +config HID_SAMSUNG +	tristate "Samsung" +	default m +	depends on USB_HID +	---help--- +	Support for Samsung IR remote. +  config HID_SUNPLUS  	tristate "Sunplus"  	default m diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 50a06f71b48..735c371ca02 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_HID_LOGITECH)	+= hid-logitech.o  obj-$(CONFIG_HID_MICROSOFT)	+= hid-microsoft.o  obj-$(CONFIG_HID_MONTEREY)	+= hid-monterey.o  obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o +obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o  obj-$(CONFIG_HID_SUNPLUS)	+= hid-sunplus.o  obj-$(CONFIG_USB_HID)		+= usbhid/ diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 53f30560b93..1b43af072ce 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1194,6 +1194,7 @@ static const struct hid_device_id hid_blacklist[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c index 1c9e7c2814a..cd21dcc4181 100644 --- a/drivers/hid/hid-dummy.c +++ b/drivers/hid/hid-dummy.c @@ -40,6 +40,9 @@ static int __init hid_dummy_init(void)  #ifdef CONFIG_HID_PETALYNX_MODULE  	HID_COMPAT_CALL_DRIVER(petalynx);  #endif +#ifdef CONFIG_HID_SAMSUNG_MODULE +	HID_COMPAT_CALL_DRIVER(samsung); +#endif  #ifdef CONFIG_HID_SUNPLUS_MODULE  	HID_COMPAT_CALL_DRIVER(sunplus);  #endif diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c new file mode 100644 index 00000000000..8771bfae02f --- /dev/null +++ b/drivers/hid/hid-samsung.c @@ -0,0 +1,101 @@ +/* + *  HID driver for some samsung "special" devices + * + *  Copyright (c) 1999 Andreas Gal + *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> + *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc + *  Copyright (c) 2006-2007 Jiri Kosina + *  Copyright (c) 2007 Paul Walmsley + *  Copyright (c) 2008 Jiri Slaby + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <linux/device.h> +#include <linux/hid.h> +#include <linux/module.h> + +#include "hid-ids.h" + +/* + * Samsung IrDA remote controller (reports as Cypress USB Mouse). + * + * Vendor specific report #4 has a size of 48 bit, + * and therefore is not accepted when inspecting the descriptors. + * As a workaround we reinterpret the report as: + *   Variable type, count 6, size 8 bit, log. maximum 255 + * The burden to reconstruct the data is moved into user space. + */ +static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, +		unsigned int rsize) +{ +	if (rsize >= 182 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && +			rdesc[177] == 0x75 && rdesc[178] == 0x30 && +			rdesc[179] == 0x95 && rdesc[180] == 0x01 && +			rdesc[182] == 0x40) { +		dev_info(&hdev->dev, "fixing up Samsung IrDA report " +				"descriptor\n"); +		rdesc[176] = 0xff; +		rdesc[178] = 0x08; +		rdesc[180] = 0x06; +		rdesc[182] = 0x42; +	} +} + +static int samsung_probe(struct hid_device *hdev, +		const struct hid_device_id *id) +{ +	int ret; + +	hdev->quirks |= HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT; + +	ret = hid_parse(hdev); +	if (ret) { +		dev_err(&hdev->dev, "parse failed\n"); +		goto err_free; +	} + +	ret = hid_hw_start(hdev); +	if (ret) { +		dev_err(&hdev->dev, "hw start failed\n"); +		goto err_free; +	} + +	return 0; +err_free: +	return ret; +} + +static const struct hid_device_id samsung_devices[] = { +	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, +	{ } +}; +MODULE_DEVICE_TABLE(hid, samsung_devices); + +static struct hid_driver samsung_driver = { +	.name = "samsung", +	.id_table = samsung_devices, +	.report_fixup = samsung_report_fixup, +	.probe = samsung_probe, +}; + +static int samsung_init(void) +{ +	return hid_register_driver(&samsung_driver); +} + +static void samsung_exit(void) +{ +	hid_unregister_driver(&samsung_driver); +} + +module_init(samsung_init); +module_exit(samsung_exit); +MODULE_LICENSE("GPL"); + +HID_COMPAT_LOAD_DRIVER(samsung); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index cc1927b1b88..d57a37997f9 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -43,8 +43,6 @@ static const struct hid_blacklist {  	{ USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, -	{ USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, -  	{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },  	{ USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, @@ -75,8 +73,6 @@ static const struct hid_rdesc_blacklist {  	__u16 idProduct;  	__u32 quirks;  } hid_rdesc_blacklist[] = { -	{ USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, -  	{ 0, 0 }  }; @@ -308,37 +304,8 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)  EXPORT_SYMBOL_GPL(usbhid_lookup_quirk); -/* - * Samsung IrDA remote controller (reports as Cypress USB Mouse). - * - * Vendor specific report #4 has a size of 48 bit, - * and therefore is not accepted when inspecting the descriptors. - * As a workaround we reinterpret the report as: - *   Variable type, count 6, size 8 bit, log. maximum 255 - * The burden to reconstruct the data is moved into user space. - */ -static void usbhid_fixup_samsung_irda_descriptor(unsigned char *rdesc, -						  int rsize) -{ -	if (rsize >= 182 && rdesc[175] == 0x25 -			 && rdesc[176] == 0x40 -			 && rdesc[177] == 0x75 -			 && rdesc[178] == 0x30 -			 && rdesc[179] == 0x95 -			 && rdesc[180] == 0x01 -			 && rdesc[182] == 0x40) { -		printk(KERN_INFO "Fixing up Samsung IrDA report descriptor\n"); -		rdesc[176] = 0xff; -		rdesc[178] = 0x08; -		rdesc[180] = 0x06; -		rdesc[182] = 0x42; -	} -} -  static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)  { -	if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) -		usbhid_fixup_samsung_irda_descriptor(rdesc, rsize);  }  /** diff --git a/include/linux/hid.h b/include/linux/hid.h index 3a639bff4ab..5b47feecc10 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -269,12 +269,6 @@ struct hid_item {  #define HID_QUIRK_FULLSPEED_INTERVAL		0x10000000  /* - * Separate quirks for runtime report descriptor fixup - */ - -#define HID_QUIRK_RDESC_SAMSUNG_REMOTE		0x00000040 - -/*   * This is the global environment of the parser. This information is   * persistent for main-items. The global environment can be saved and   * restored with PUSH/POP statements.  | 
