Input: HID - add a quirk for the Logitech USB Receiver
authorAnssi Hannula <anssi.hannula@gmail.com>
Sun, 5 Nov 2006 03:49:53 +0000 (22:49 -0500)
committerDmitry Torokhov <dtor@insightbb.com>
Sun, 5 Nov 2006 03:49:53 +0000 (22:49 -0500)
Logitech USB Receiver (046d:c101) has two interfaces. The first one
contains fields from HID_UP_KEYBOARD and HID_UP_LED, and the other one
contains fields from HID_UP_CONSUMER and HID_UP_LOGIVENDOR. This device
is used with multiple wireless Logitech products, including UltraX Media
Remote.

All fields on both interfaces are either keys or leds. All fields in the
first interface are marked as Absolute, while the fields in the second
interface are marked as Relative. Marking the keys as relative causes
hidinput_hid_event() to send release events right after key press
events.

The device has EV_REP set, so the userspace expects the device to send
repeat events if a key is held down. However, as hidinput_hid_event()
sends release events immediately, repeat events are not sent at all. In
fact, the userspace has no way of knowing if a key is being held down.

Fix this by adding a quirk for 046d:c101 which changes relative keys to
absolute ones.

Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/usb/input/hid-core.c
drivers/usb/input/hid-input.c
drivers/usb/input/hid.h

index 6daf85c6eeee216f18a6c01f1df24e1a922601b2..6095d9cedb7ee770dd88815b74158a6e59e25afe 100644 (file)
@@ -1643,6 +1643,9 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_VENDOR_ID_AIRCABLE         0x16CA
 #define USB_DEVICE_ID_AIRCABLE1                0x1502
 
+#define USB_VENDOR_ID_LOGITECH         0x046d
+#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER    0xc101
+
 /*
  * Alphabetically sorted blacklist by quirk type.
  */
@@ -1811,7 +1814,9 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
 
        { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
-       
+
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
+
        { 0, 0 }
 };
 
index 9a808a3b4d3750e1a6e4a93a3c9cac1b98c1a667..c8ce65c70a42b876959c6df2284c1c9efaaf14a1 100644 (file)
@@ -564,6 +564,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
                goto ignore;
 
+       if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) &&
+           usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE))
+               field->flags &= ~HID_MAIN_ITEM_RELATIVE;
+
        set_bit(usage->type, input->evbit);
 
        while (usage->code <= max && test_and_set_bit(usage->code, bit))
index 9b50effef75817af9c00b3d459bf481c1c5e1d9d..8aa9ec08e8ab6ffa7315c00ea1d3a4e2ea0a6c9a 100644 (file)
@@ -260,6 +260,7 @@ struct hid_item {
 #define HID_QUIRK_POWERBOOK_HAS_FN             0x00001000
 #define HID_QUIRK_POWERBOOK_FN_ON              0x00002000
 #define HID_QUIRK_INVERT_HWHEEL                        0x00004000
+#define HID_QUIRK_BAD_RELATIVE_KEYS            0x00008000
 
 /*
  * This is the global environment of the parser. This information is