HID: hid-input quirk for BTC 8193
Jiri Kosina [Mon, 26 Nov 2007 12:18:00 +0000 (13:18 +0100)]
BTC 8193 keyboard handles its scrollwheel in very non-standard way.
It produces two non-standard usages for scrolling up and down, in
both cases with postive value equaling to 1. We handle this by temporary
mapping, which we then catch in quirk event handler, and remap to
negative HWHEEL even in order to introduce correct behavior.

Also the button requires special mapping, as it triggers standard-violating
usage code.

Reported in kernel.org bugzilla #9385

Reported-by: Kir Kolyshkin <kir@sacred.ru>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

drivers/hid/hid-input-quirks.c
drivers/hid/usbhid/hid-quirks.c
include/linux/hid.h

index 7f2f80b..e378b4a 100644 (file)
@@ -253,6 +253,27 @@ static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *in
        return 1;
 }
 
+static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
+                             unsigned long *bit, int *max)
+{
+       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+               return 0;
+
+       switch (usage->hid & HID_USAGE) {
+               case 0x230: map_key(BTN_MOUSE);                 break;
+               case 0x231: map_rel(REL_WHEEL);                 break;
+               /* 
+                * this keyboard has a scrollwheel implemented in
+                * totally broken way. We map this usage temporarily
+                * to HWHEEL and handle it in the event quirk handler
+                */
+               case 0x232: map_rel(REL_HWHEEL);                break;
+
+               default:
+                       return 0;
+       }
+       return 1;
+}
 
 #define VENDOR_ID_BELKIN                       0x1020
 #define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD     0x0006
@@ -263,6 +284,9 @@ static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *in
 #define VENDOR_ID_CHICONY                      0x04f2
 #define DEVICE_ID_CHICONY_TACTICAL_PAD         0x0418
 
+#define VENDOR_ID_EZKEY                                0x0518
+#define DEVICE_ID_BTC_8193                     0x0002
+
 #define VENDOR_ID_LOGITECH                     0x046d
 #define DEVICE_ID_LOGITECH_RECEIVER            0xc101
 #define DEVICE_ID_S510_RECEIVER                        0xc50c
@@ -291,6 +315,8 @@ static const struct hid_input_blacklist {
 
        { VENDOR_ID_CHICONY, DEVICE_ID_CHICONY_TACTICAL_PAD, quirk_chicony_tactical_pad },
 
+       { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 },
+
        { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote },
        { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless },
        { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless },
@@ -323,6 +349,7 @@ int hidinput_mapping_quirks(struct hid_usage *usage,
        return 0;
 }
 
+#define IS_BTC8193(x) (x->vendor == 0x0518 && x->product == 0x0002)
 #define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
 
 void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
@@ -384,6 +411,13 @@ void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, stru
                        input_event(input, usage->type, last_key, 0);
                }
        }
+
+       /* handle the temporary quirky mapping to HWHEEL */
+       if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT &&
+                       usage->type == EV_REL && usage->code == REL_HWHEEL) {
+               input_event(input, usage->type, REL_WHEEL, -value);
+               return;
+       }
 }
 
 
index d844757..aa470f8 100644 (file)
 #define USB_VENDOR_ID_ESSENTIAL_REALITY        0x0d7f
 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
 
+#define USB_VENDOR_ID_EZKEY            0x0518
+#define USB_DEVICE_ID_BTC_8193         0x0002
+
 #define USB_VENDOR_ID_GAMERON          0x0810
 #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
 
@@ -400,6 +403,8 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
        { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
 
+       { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT },
+
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE },
index dca5804..33ec333 100644 (file)
@@ -282,6 +282,7 @@ struct hid_item {
 #define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP     0x00800000
 #define HID_QUIRK_IGNORE_HIDINPUT              0x01000000
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_B8         0x02000000
+#define HID_QUIRK_HWHEEL_WHEEL_INVERT          0x04000000
 
 /*
  * Separate quirks for runtime report descriptor fixup