* This is used to handle HID-input mappings for devices violating
* HUT 1.12 specification.
*
- * Copyright (c) 2007 Jiri Kosina
+ * Copyright (c) 2007-2008 Jiri Kosina
*/
/*
#include <linux/input.h>
#include <linux/hid.h>
-#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; *max = ABS_MAX; } while (0)
-#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; *max = REL_MAX; } while (0)
-#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; *max = KEY_MAX; } while (0)
-#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; *max = LED_MAX; } while (0)
+#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; *bit = input->absbit; *max = ABS_MAX; } while (0)
+#define map_rel(c) do { usage->code = c; usage->type = EV_REL; *bit = input->relbit; *max = REL_MAX; } while (0)
+#define map_key(c) do { usage->code = c; usage->type = EV_KEY; *bit = input->keybit; *max = KEY_MAX; } while (0)
+#define map_led(c) do { usage->code = c; usage->type = EV_LED; *bit = input->ledbit; *max = LED_MAX; } while (0)
-#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
-#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
+#define map_abs_clear(c) do { map_abs(c); clear_bit(c, *bit); } while (0)
+#define map_key_clear(c) do { map_key(c); clear_bit(c, *bit); } while (0)
static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
return 0;
}
static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
return 0;
}
static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
return 0;
}
static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
return 0;
}
static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
return 0;
}
static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
return 0;
set_bit(EV_REP, input->evbit);
switch(usage->hid & HID_USAGE) {
- case 0xfd08: map_key_clear(KEY_RIGHT); break;
- case 0xfd09: map_key_clear(KEY_LEFT); break;
- case 0xfd0b: map_key_clear(KEY_PAUSE); break;
- case 0xfd0f: map_key_clear(KEY_F5); break;
+ case 0xfd08: map_key_clear(KEY_FORWARD); break;
+ case 0xfd09: map_key_clear(KEY_BACK); break;
+ case 0xfd0b: map_key_clear(KEY_PLAYPAUSE); break;
+ case 0xfd0e: map_key_clear(KEY_CLOSE); break;
+ case 0xfd0f: map_key_clear(KEY_PLAY); break;
default:
return 0;
}
}
static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) &&
((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER))
}
static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
return 0;
}
static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
return 0;
}
static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
return 0;
return 1;
}
+static int quirk_sunplus_wdesktop(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 0x2003: map_key_clear(KEY_ZOOMIN); break;
+ case 0x2103: map_key_clear(KEY_ZOOMOUT); break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
#define VENDOR_ID_BELKIN 0x1020
#define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006
#define VENDOR_ID_MICROSOFT 0x045e
#define DEVICE_ID_MS4K 0x00db
#define DEVICE_ID_MS6K 0x00f9
-#define DEVICE_ID_MS_PRESENTER_8K 0x0713
+#define DEVICE_IS_MS_PRESENTER_8K_BT 0x0701
+#define DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
#define VENDOR_ID_MONTEREY 0x0566
#define DEVICE_ID_GENIUS_KB29E 0x3004
#define VENDOR_ID_PETALYNX 0x18b1
#define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
+#define VENDOR_ID_SUNPLUS 0x04fc
+#define DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
+
static const struct hid_input_blacklist {
__u16 idVendor;
__u16 idProduct;
- int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long *, int *);
+ int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long **, int *);
} hid_input_blacklist[] = {
{ VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd },
{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb },
{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb },
- { VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K, quirk_microsoft_presenter_8k },
+ { VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k },
+ { VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K_USB, quirk_microsoft_presenter_8k },
{ VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e },
{ VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote },
-
- { 0, 0, 0 }
+
+ { VENDOR_ID_SUNPLUS, DEVICE_ID_SUNPLUS_WDESKTOP, quirk_sunplus_wdesktop },
+
+ { 0, 0, NULL }
};
int hidinput_mapping_quirks(struct hid_usage *usage,
struct input_dev *input,
- unsigned long *bit, int *max)
+ unsigned long **bit, int *max)
{
struct hid_device *device = input_get_drvdata(input);
int i = 0;
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)
+int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
{
struct input_dev *input;
|| ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
- return;
+ return 1;
}
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
(usage->type == EV_REL) &&
(usage->code == REL_WHEEL)) {
hid->delayed_value = value;
- return;
+ return 1;
}
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
(usage->hid == 0x000100b8)) {
input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value);
- return;
+ return 1;
}
if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
input_event(input, usage->type, usage->code, -value);
- return;
+ return 1;
}
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
input_event(input, usage->type, REL_HWHEEL, value);
- return;
+ return 1;
}
if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value))
- return;
+ return 1;
/* Handling MS keyboards special buttons */
- if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
+ if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS &&
+ usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
int key = 0;
static int last_key = 0;
switch (value) {
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;
+ return 1;
}
+ return 0;
}