Loading drivers/hid/Kconfig +13 −0 Original line number Diff line number Diff line Loading @@ -67,4 +67,17 @@ config HIDRAW source "drivers/hid/usbhid/Kconfig" menu "Special HID drivers" depends on HID config HID_LOGITECH tristate "Logitech" default m depends on USB_HID ---help--- Support for some Logitech devices which breaks less or more HID specification. endmenu endif # HID_SUPPORT drivers/hid/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,8 @@ obj-$(CONFIG_HID) += hid.o hid-$(CONFIG_HID_DEBUG) += hid-debug.o hid-$(CONFIG_HIDRAW) += hidraw.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o obj-$(CONFIG_USB_HID) += usbhid/ obj-$(CONFIG_USB_MOUSE) += usbhid/ obj-$(CONFIG_USB_KBD) += usbhid/ Loading drivers/hid/hid-core.c +16 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <linux/hid-debug.h> #include <linux/hidraw.h> #include "hid-ids.h" /* * Version Information */ Loading Loading @@ -1128,6 +1130,20 @@ static const struct hid_device_id *hid_match_id(struct hid_device *hdev, } static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, { } }; Loading drivers/hid/hid-input-quirks.c +0 −96 Original line number Diff line number Diff line Loading @@ -54,39 +54,6 @@ static int quirk_cherry_cymotion(struct hid_usage *usage, return 1; } static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) return 0; set_bit(EV_REP, hidinput->input->evbit); switch(usage->hid & HID_USAGE) { /* Reported on Logitech Ultra X Media Remote */ case 0x004: map_key_clear(KEY_AGAIN); break; case 0x00d: map_key_clear(KEY_HOME); break; case 0x024: map_key_clear(KEY_SHUFFLE); break; case 0x025: map_key_clear(KEY_TV); break; case 0x026: map_key_clear(KEY_MENU); break; case 0x031: map_key_clear(KEY_AUDIO); break; case 0x032: map_key_clear(KEY_TEXT); break; case 0x033: map_key_clear(KEY_LAST); break; case 0x047: map_key_clear(KEY_MP3); break; case 0x048: map_key_clear(KEY_DVD); break; case 0x049: map_key_clear(KEY_MEDIA); break; case 0x04a: map_key_clear(KEY_VIDEO); break; case 0x04b: map_key_clear(KEY_ANGLE); break; case 0x04c: map_key_clear(KEY_LANGUAGE); break; case 0x04d: map_key_clear(KEY_SUBTITLE); break; case 0x051: map_key_clear(KEY_RED); break; case 0x052: map_key_clear(KEY_CLOSE); break; default: return 0; } return 1; } static int quirk_gyration_remote(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { Loading Loading @@ -207,58 +174,6 @@ static int quirk_petalynx_remote(struct hid_usage *usage, return 1; } static int quirk_logitech_wireless(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) return 0; switch (usage->hid & HID_USAGE) { case 0x1001: map_key_clear(KEY_MESSENGER); break; case 0x1003: map_key_clear(KEY_SOUND); break; case 0x1004: map_key_clear(KEY_VIDEO); break; case 0x1005: map_key_clear(KEY_AUDIO); break; case 0x100a: map_key_clear(KEY_DOCUMENTS); break; case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; case 0x1012: map_key_clear(KEY_NEXTSONG); break; case 0x1013: map_key_clear(KEY_CAMERA); break; case 0x1014: map_key_clear(KEY_MESSENGER); break; case 0x1015: map_key_clear(KEY_RECORD); break; case 0x1016: map_key_clear(KEY_PLAYER); break; case 0x1017: map_key_clear(KEY_EJECTCD); break; case 0x1018: map_key_clear(KEY_MEDIA); break; case 0x1019: map_key_clear(KEY_PROG1); break; case 0x101a: map_key_clear(KEY_PROG2); break; case 0x101b: map_key_clear(KEY_PROG3); break; case 0x101f: map_key_clear(KEY_ZOOMIN); break; case 0x1020: map_key_clear(KEY_ZOOMOUT); break; case 0x1021: map_key_clear(KEY_ZOOMRESET); break; case 0x1023: map_key_clear(KEY_CLOSE); break; case 0x1027: map_key_clear(KEY_MENU); break; /* this one is marked as 'Rotate' */ case 0x1028: map_key_clear(KEY_ANGLE); break; case 0x1029: map_key_clear(KEY_SHUFFLE); break; case 0x102a: map_key_clear(KEY_BACK); break; case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; case 0x1041: map_key_clear(KEY_BATTERY); break; case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; case 0x1043: map_key_clear(KEY_SPREADSHEET); break; case 0x1044: map_key_clear(KEY_PRESENTATION); break; case 0x1045: map_key_clear(KEY_UNDO); break; case 0x1046: map_key_clear(KEY_REDO); break; case 0x1047: map_key_clear(KEY_PRINT); break; case 0x1048: map_key_clear(KEY_SAVE); break; case 0x1049: map_key_clear(KEY_PROG1); break; case 0x104a: map_key_clear(KEY_PROG2); break; case 0x104b: map_key_clear(KEY_PROG3); break; case 0x104c: map_key_clear(KEY_PROG4); break; default: return 0; } return 1; } static int quirk_cherry_genius_29e(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { Loading Loading @@ -329,12 +244,6 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage, #define VENDOR_ID_GYRATION 0x0c16 #define DEVICE_ID_GYRATION_REMOTE 0x0002 #define VENDOR_ID_LOGITECH 0x046d #define DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define DEVICE_ID_S510_RECEIVER 0xc50c #define DEVICE_ID_S510_RECEIVER_2 0xc517 #define DEVICE_ID_MX3000_RECEIVER 0xc513 #define VENDOR_ID_MICROSOFT 0x045e #define DEVICE_ID_MS4K 0x00db #define DEVICE_ID_MS6K 0x00f9 Loading Loading @@ -366,11 +275,6 @@ static const struct hid_input_blacklist { { VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote }, { 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 }, { VENDOR_ID_LOGITECH, DEVICE_ID_MX3000_RECEIVER, quirk_logitech_wireless }, { VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb }, { VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb }, { VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k }, Loading drivers/hid/hid-input.c +0 −38 Original line number Diff line number Diff line Loading @@ -58,19 +58,6 @@ static const unsigned char hid_keyboard[256] = { 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk }; /* extended mapping for certain Logitech hardware (Logitech cordless desktop LX500) */ #define LOGITECH_EXPANDED_KEYMAP_SIZE 80 static int logitech_expanded_keymap[LOGITECH_EXPANDED_KEYMAP_SIZE] = { 0,216, 0,213,175,156, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0,212, 174,167,152,161,112, 0, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,183,184,185,186,187, 188,189,190,191,192,193,194, 0, 0, 0 }; static const struct { __s32 x; __s32 y; Loading Loading @@ -437,21 +424,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } } /* Special handling for Logitech Cordless Desktop */ if (field->application != HID_GD_MOUSE) { if (device->quirks & HID_QUIRK_LOGITECH_EXPANDED_KEYMAP) { int hid = usage->hid & HID_USAGE; if (hid < LOGITECH_EXPANDED_KEYMAP_SIZE && logitech_expanded_keymap[hid] != 0) code = logitech_expanded_keymap[hid]; } } else { if (device->quirks & HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL) { int hid = usage->hid & HID_USAGE; if (hid == 7 || hid == 8) goto ignore; } } map_key(code); break; Loading Loading @@ -788,18 +760,8 @@ 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); if (device->quirks & HID_QUIRK_DUPLICATE_USAGES && (usage->type == EV_KEY || usage->type == EV_REL || usage->type == EV_ABS)) clear_bit(usage->code, bit); while (usage->code <= max && test_and_set_bit(usage->code, bit)) usage->code = find_next_zero_bit(bit, max + 1, usage->code); Loading Loading
drivers/hid/Kconfig +13 −0 Original line number Diff line number Diff line Loading @@ -67,4 +67,17 @@ config HIDRAW source "drivers/hid/usbhid/Kconfig" menu "Special HID drivers" depends on HID config HID_LOGITECH tristate "Logitech" default m depends on USB_HID ---help--- Support for some Logitech devices which breaks less or more HID specification. endmenu endif # HID_SUPPORT
drivers/hid/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,8 @@ obj-$(CONFIG_HID) += hid.o hid-$(CONFIG_HID_DEBUG) += hid-debug.o hid-$(CONFIG_HIDRAW) += hidraw.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o obj-$(CONFIG_USB_HID) += usbhid/ obj-$(CONFIG_USB_MOUSE) += usbhid/ obj-$(CONFIG_USB_KBD) += usbhid/ Loading
drivers/hid/hid-core.c +16 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <linux/hid-debug.h> #include <linux/hidraw.h> #include "hid-ids.h" /* * Version Information */ Loading Loading @@ -1128,6 +1130,20 @@ static const struct hid_device_id *hid_match_id(struct hid_device *hdev, } static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, { } }; Loading
drivers/hid/hid-input-quirks.c +0 −96 Original line number Diff line number Diff line Loading @@ -54,39 +54,6 @@ static int quirk_cherry_cymotion(struct hid_usage *usage, return 1; } static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) return 0; set_bit(EV_REP, hidinput->input->evbit); switch(usage->hid & HID_USAGE) { /* Reported on Logitech Ultra X Media Remote */ case 0x004: map_key_clear(KEY_AGAIN); break; case 0x00d: map_key_clear(KEY_HOME); break; case 0x024: map_key_clear(KEY_SHUFFLE); break; case 0x025: map_key_clear(KEY_TV); break; case 0x026: map_key_clear(KEY_MENU); break; case 0x031: map_key_clear(KEY_AUDIO); break; case 0x032: map_key_clear(KEY_TEXT); break; case 0x033: map_key_clear(KEY_LAST); break; case 0x047: map_key_clear(KEY_MP3); break; case 0x048: map_key_clear(KEY_DVD); break; case 0x049: map_key_clear(KEY_MEDIA); break; case 0x04a: map_key_clear(KEY_VIDEO); break; case 0x04b: map_key_clear(KEY_ANGLE); break; case 0x04c: map_key_clear(KEY_LANGUAGE); break; case 0x04d: map_key_clear(KEY_SUBTITLE); break; case 0x051: map_key_clear(KEY_RED); break; case 0x052: map_key_clear(KEY_CLOSE); break; default: return 0; } return 1; } static int quirk_gyration_remote(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { Loading Loading @@ -207,58 +174,6 @@ static int quirk_petalynx_remote(struct hid_usage *usage, return 1; } static int quirk_logitech_wireless(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) return 0; switch (usage->hid & HID_USAGE) { case 0x1001: map_key_clear(KEY_MESSENGER); break; case 0x1003: map_key_clear(KEY_SOUND); break; case 0x1004: map_key_clear(KEY_VIDEO); break; case 0x1005: map_key_clear(KEY_AUDIO); break; case 0x100a: map_key_clear(KEY_DOCUMENTS); break; case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; case 0x1012: map_key_clear(KEY_NEXTSONG); break; case 0x1013: map_key_clear(KEY_CAMERA); break; case 0x1014: map_key_clear(KEY_MESSENGER); break; case 0x1015: map_key_clear(KEY_RECORD); break; case 0x1016: map_key_clear(KEY_PLAYER); break; case 0x1017: map_key_clear(KEY_EJECTCD); break; case 0x1018: map_key_clear(KEY_MEDIA); break; case 0x1019: map_key_clear(KEY_PROG1); break; case 0x101a: map_key_clear(KEY_PROG2); break; case 0x101b: map_key_clear(KEY_PROG3); break; case 0x101f: map_key_clear(KEY_ZOOMIN); break; case 0x1020: map_key_clear(KEY_ZOOMOUT); break; case 0x1021: map_key_clear(KEY_ZOOMRESET); break; case 0x1023: map_key_clear(KEY_CLOSE); break; case 0x1027: map_key_clear(KEY_MENU); break; /* this one is marked as 'Rotate' */ case 0x1028: map_key_clear(KEY_ANGLE); break; case 0x1029: map_key_clear(KEY_SHUFFLE); break; case 0x102a: map_key_clear(KEY_BACK); break; case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; case 0x1041: map_key_clear(KEY_BATTERY); break; case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; case 0x1043: map_key_clear(KEY_SPREADSHEET); break; case 0x1044: map_key_clear(KEY_PRESENTATION); break; case 0x1045: map_key_clear(KEY_UNDO); break; case 0x1046: map_key_clear(KEY_REDO); break; case 0x1047: map_key_clear(KEY_PRINT); break; case 0x1048: map_key_clear(KEY_SAVE); break; case 0x1049: map_key_clear(KEY_PROG1); break; case 0x104a: map_key_clear(KEY_PROG2); break; case 0x104b: map_key_clear(KEY_PROG3); break; case 0x104c: map_key_clear(KEY_PROG4); break; default: return 0; } return 1; } static int quirk_cherry_genius_29e(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { Loading Loading @@ -329,12 +244,6 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage, #define VENDOR_ID_GYRATION 0x0c16 #define DEVICE_ID_GYRATION_REMOTE 0x0002 #define VENDOR_ID_LOGITECH 0x046d #define DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define DEVICE_ID_S510_RECEIVER 0xc50c #define DEVICE_ID_S510_RECEIVER_2 0xc517 #define DEVICE_ID_MX3000_RECEIVER 0xc513 #define VENDOR_ID_MICROSOFT 0x045e #define DEVICE_ID_MS4K 0x00db #define DEVICE_ID_MS6K 0x00f9 Loading Loading @@ -366,11 +275,6 @@ static const struct hid_input_blacklist { { VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote }, { 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 }, { VENDOR_ID_LOGITECH, DEVICE_ID_MX3000_RECEIVER, quirk_logitech_wireless }, { VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb }, { VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb }, { VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k }, Loading
drivers/hid/hid-input.c +0 −38 Original line number Diff line number Diff line Loading @@ -58,19 +58,6 @@ static const unsigned char hid_keyboard[256] = { 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk }; /* extended mapping for certain Logitech hardware (Logitech cordless desktop LX500) */ #define LOGITECH_EXPANDED_KEYMAP_SIZE 80 static int logitech_expanded_keymap[LOGITECH_EXPANDED_KEYMAP_SIZE] = { 0,216, 0,213,175,156, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0,212, 174,167,152,161,112, 0, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,183,184,185,186,187, 188,189,190,191,192,193,194, 0, 0, 0 }; static const struct { __s32 x; __s32 y; Loading Loading @@ -437,21 +424,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } } /* Special handling for Logitech Cordless Desktop */ if (field->application != HID_GD_MOUSE) { if (device->quirks & HID_QUIRK_LOGITECH_EXPANDED_KEYMAP) { int hid = usage->hid & HID_USAGE; if (hid < LOGITECH_EXPANDED_KEYMAP_SIZE && logitech_expanded_keymap[hid] != 0) code = logitech_expanded_keymap[hid]; } } else { if (device->quirks & HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL) { int hid = usage->hid & HID_USAGE; if (hid == 7 || hid == 8) goto ignore; } } map_key(code); break; Loading Loading @@ -788,18 +760,8 @@ 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); if (device->quirks & HID_QUIRK_DUPLICATE_USAGES && (usage->type == EV_KEY || usage->type == EV_REL || usage->type == EV_ABS)) clear_bit(usage->code, bit); while (usage->code <= max && test_and_set_bit(usage->code, bit)) usage->code = find_next_zero_bit(bit, max + 1, usage->code); Loading