[PATCH] USB HID: Support Samsung IR remote (0419:0001)
Robert Schedel <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
From: Robert Schedel <[email protected]> Samsung USB remotes (0419:0001) are rejected by kernel 2.6.23, because the report descriptor from the remote contains a 48 bit HID report field. HID 1.11 states: Fields may span at most 4 bytes. This patch, based on 2.6.23, fixes this by modifying the internal report descriptor in hid-quirks.c. Additional user space support (e.g. LIRC) is required to fetch the information from the hiddev interface. Signed-off-by: Robert Schedel <[email protected]> --- drivers/hid/usbhid/hid-quirks.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/hid.h | 1 + 2 files changed, 39 insertions(+) On vanilla kernel 2.6.23 the USB remote bundled with Satelco EasyWatch DVBs (idVendor/Product 0419:0001 "Samsung IrDA", device name "Cypress USB Mouse") does not work correctly. On plugin the kernel rejects the device immediately, see trace below: drivers/hid/usbhid/hid-core.c: HID probe called for ifnum 0 drivers/hid/usbhid/hid-core.c: report descriptor (size 184, read 184) = 05 01 09 06 a1 01 85 01 05 07 19 e0 29 e7 15 00 25 01 95 08 75 01 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 05 75 08 15 00 25 65 05 07 19 00 29 65 81 00 c0 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 03 15 00 25 01 95 03 75 01 81 02 95 01 75 05 81 01 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 c0 c0 05 01 09 80 a1 01 85 03 05 01 19 81 29 88 15 00 25 01 95 08 75 01 81 02 c0 06 cc ff 09 88 a1 01 85 04 09 01 09 02 09 03 09 04 09 05 09 06 09 07 09 08 09 09 09 0a 15 00 25 40 75 30 95 01 81 40 c0 drivers/hid/hid-core.c: invalid report_size 48 drivers/hid/hid-core.c: item 0 1 1 7 parsing failed drivers/hid/usbhid/hid-core.c: parsing report descriptor failed I have also attached the decoded "lsusb" output for this device. As it shows, the proprietary usage page (used for indicating most keys) indicates a single 48 bit array field. In my understanding of HID 1.11, section "Report Constraints", fields may not span more than 4 bytes, so it sounds like a device quirk rather than a kernel deficiency. The patch introduces a workaround to the quirk by fixing up the report descriptor in hid-quirks.c. Some side notes: - As the device also has output applications (which are unused by the remote though), an hiddev interface is already created. So the flag "HID_QUIRK_HIDDEV" is not set in the patch. - Note, the new "hidraw" from 2.6.24 also will not solve the issue because the device is rejected either before hidraw has a chance to access the device. - A LIRC patch to fetch all keys from the hiddev interface has been posted to the LIRC developer list. - I am aware that the merge window for 2.6.24 is closed, so please consider whether this can be included in later kernels or provide feedback meanwhile. Regards, Robert Schedel diff -uprN linux-2.6.23-orig/drivers/hid/usbhid/hid-quirks.c linux-2.6.23/drivers/hid/usbhid/hid-quirks.c --- linux-2.6.23-orig/drivers/hid/usbhid/hid-quirks.c 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6.23/drivers/hid/usbhid/hid-quirks.c 2007-12-22 08:57:46.000000000 +0100 @@ -310,6 +310,9 @@ #define USB_VENDOR_ID_SAITEK 0x06a3 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 +#define USB_VENDOR_ID_SAMSUNG 0x0419 +#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 + #define USB_VENDOR_ID_SONY 0x054c #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 @@ -616,6 +619,8 @@ static const struct hid_rdesc_blacklist { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, + { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, @@ -888,6 +893,36 @@ static void usbhid_fixup_logitech_descri } } +/* + * Samsung IrDA remote controller (reports as Cypress USB Mouse). + * + * Unfortunately, the vendor specific report #4 has a size of 48 bit, + * and therefore is not accepted when inspecting the descriptors on plugin. + * According to the USB HID 1.11, section "Report Constraints", a field + * should span at most 4 bytes (=current Linux USB HID implementation). + * As a workaround we reinterpret the report like this: + * OLD: Array type, count 1, size 48 bit, log. maximum 64 + * NEW: Variable type, count 6, size 8 bit, log. maximum 255 + * The burden to reconstruct the data is moved into user space (hiddev). + */ +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; /* logical max value 255 */ + rdesc[178] = 0x08; /* 8 bit */ + rdesc[180] = 0x06; /* 6 usage elements */ + rdesc[182] = 0x42; /* variable */ + } +} + /* Petalynx Maxter Remote has maximum for consumer page set too low */ static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) { @@ -941,6 +976,9 @@ static void __usbhid_fixup_report_descri if (quirks & HID_QUIRK_RDESC_PETALYNX) usbhid_fixup_petalynx_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) + usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); } /** diff -uprN linux-2.6.23-orig/include/linux/hid.h linux-2.6.23/include/linux/hid.h --- linux-2.6.23-orig/include/linux/hid.h 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6.23/include/linux/hid.h 2007-12-22 08:53:30.000000000 +0100 @@ -285,6 +285,7 @@ struct hid_item { #define HID_QUIRK_RDESC_LOGITECH 0x00000002 #define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 #define HID_QUIRK_RDESC_PETALYNX 0x00000008 +#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000010 /* * This is the global environment of the parser. This information is __________________________________ Ihr erstes Baby? Holen Sie sich Tipps von anderen Eltern. www.yahoo.de/clever ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ [email protected] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
satelco-remote-lsusb.txt
(text/plain, 10.3 KB)
Bus 005 Device 002: ID 0419:0001 Samsung Info. Systems America, Inc. IrDA Remote Controller
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0419 Samsung Info. Systems America, Inc.
idProduct 0x0001 IrDA Remote Controller
bcdDevice 0.00
iManufacturer 1 Cypress Sem
iProduct 2 Cypress USB Mouse
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 4 HID Mouse
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 5 EndPoint1 Interrupt Pipe
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 184
Report Descriptor: (length is 184)
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x06 ] 6
Keyboard
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x01 ] 1
Item(Global): Usage Page, data= [ 0x07 ] 7
Keyboard
Item(Local ): Usage Minimum, data= [ 0xe0 ] 224
Control Left
Item(Local ): Usage Maximum, data= [ 0xe7 ] 231
GUI Right
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x08 ] 8
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Main ): Input, data= [ 0x01 ] 1
Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x05 ] 5
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Global): Usage Page, data= [ 0x08 ] 8
LEDs
Item(Local ): Usage Minimum, data= [ 0x01 ] 1
NumLock
Item(Local ): Usage Maximum, data= [ 0x05 ] 5
Kana
Item(Main ): Output, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x03 ] 3
Item(Main ): Output, data= [ 0x01 ] 1
Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x05 ] 5
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x65 ] 101
Item(Global): Usage Page, data= [ 0x07 ] 7
Keyboard
Item(Local ): Usage Minimum, data= [ 0x00 ] 0
No Event
Item(Local ): Usage Maximum, data= [ 0x65 ] 101
Keyboard Application (Windows Key for Win95 or Compose)
Item(Main ): Input, data= [ 0x00 ] 0
Data Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x02 ] 2
Mouse
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x02 ] 2
Item(Local ): Usage, data= [ 0x01 ] 1
Pointer
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
Item(Global): Usage Page, data= [ 0x09 ] 9
Buttons
Item(Local ): Usage Minimum, data= [ 0x01 ] 1
Button 1 (Primary)
Item(Local ): Usage Maximum, data= [ 0x03 ] 3
Button 3 (Tertiary)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x03 ] 3
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x05 ] 5
Item(Main ): Input, data= [ 0x01 ] 1
Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x30 ] 48
Direction-X
Item(Local ): Usage, data= [ 0x31 ] 49
Direction-Y
Item(Local ): Usage, data= [ 0x38 ] 56
Wheel
Item(Global): Logical Minimum, data= [ 0x81 ] 129
Item(Global): Logical Maximum, data= [ 0x7f ] 127
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x03 ] 3
Item(Main ): Input, data= [ 0x06 ] 6
Data Variable Relative No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Item(Main ): End Collection, data=none
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x80 ] 128
System Control
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x03 ] 3
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage Minimum, data= [ 0x81 ] 129
System Power Down
Item(Local ): Usage Maximum, data= [ 0x88 ] 136
System Menu Exit
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x08 ] 8
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Item(Global): Usage Page, data= [ 0xcc 0xff ] 65484
(null)
Item(Local ): Usage, data= [ 0x88 ] 136
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x04 ] 4
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Local ): Usage, data= [ 0x02 ] 2
(null)
Item(Local ): Usage, data= [ 0x03 ] 3
(null)
Item(Local ): Usage, data= [ 0x04 ] 4
(null)
Item(Local ): Usage, data= [ 0x05 ] 5
(null)
Item(Local ): Usage, data= [ 0x06 ] 6
(null)
Item(Local ): Usage, data= [ 0x07 ] 7
(null)
Item(Local ): Usage, data= [ 0x08 ] 8
(null)
Item(Local ): Usage, data= [ 0x09 ] 9
(null)
Item(Local ): Usage, data= [ 0x0a ] 10
(null)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x40 ] 64
Item(Global): Report Size, data= [ 0x30 ] 48
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x40 ] 64
Data Array Absolute No_Wrap Linear
Preferred_State Null_State Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)