diff options
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r-- | drivers/hid/hid-input.c | 295 |
1 files changed, 76 insertions, 219 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 0b27da7d7497..5325d98b4328 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <linux/hid.h> | 34 | #include <linux/hid.h> |
35 | #include <linux/hid-debug.h> | 35 | #include <linux/hid-debug.h> |
36 | 36 | ||
37 | static int hid_pb_fnmode = 1; | 37 | static int hid_apple_fnmode = 1; |
38 | module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); | 38 | module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644); |
39 | MODULE_PARM_DESC(pb_fnmode, | 39 | MODULE_PARM_DESC(pb_fnmode, |
40 | "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); | 40 | "Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); |
41 | 41 | ||
42 | #define unk KEY_UNKNOWN | 42 | #define unk KEY_UNKNOWN |
43 | 43 | ||
@@ -86,10 +86,6 @@ static const struct { | |||
86 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) | 86 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) |
87 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) | 87 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) |
88 | 88 | ||
89 | /* hardware needing special handling due to colliding MSVENDOR page usages */ | ||
90 | #define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418) | ||
91 | #define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9)) | ||
92 | |||
93 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | 89 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK |
94 | 90 | ||
95 | struct hidinput_key_translation { | 91 | struct hidinput_key_translation { |
@@ -98,20 +94,36 @@ struct hidinput_key_translation { | |||
98 | u8 flags; | 94 | u8 flags; |
99 | }; | 95 | }; |
100 | 96 | ||
101 | #define POWERBOOK_FLAG_FKEY 0x01 | 97 | #define APPLE_FLAG_FKEY 0x01 |
98 | |||
99 | static struct hidinput_key_translation apple_fn_keys[] = { | ||
100 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | ||
101 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | ||
102 | { KEY_F3, KEY_CYCLEWINDOWS, APPLE_FLAG_FKEY }, /* Exposé */ | ||
103 | { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ | ||
104 | { KEY_F5, KEY_FN_F5 }, | ||
105 | { KEY_F6, KEY_FN_F6 }, | ||
106 | { KEY_F7, KEY_BACK, APPLE_FLAG_FKEY }, | ||
107 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, | ||
108 | { KEY_F9, KEY_FORWARD, APPLE_FLAG_FKEY }, | ||
109 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, | ||
110 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, | ||
111 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, | ||
112 | { } | ||
113 | }; | ||
102 | 114 | ||
103 | static struct hidinput_key_translation powerbook_fn_keys[] = { | 115 | static struct hidinput_key_translation powerbook_fn_keys[] = { |
104 | { KEY_BACKSPACE, KEY_DELETE }, | 116 | { KEY_BACKSPACE, KEY_DELETE }, |
105 | { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY }, | 117 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
106 | { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY }, | 118 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
107 | { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY }, | 119 | { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, |
108 | { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY }, | 120 | { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
109 | { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY }, | 121 | { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
110 | { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY }, | 122 | { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, |
111 | { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY }, | 123 | { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, |
112 | { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY }, | 124 | { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, |
113 | { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY }, | 125 | { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
114 | { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY }, | 126 | { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
115 | { KEY_UP, KEY_PAGEUP }, | 127 | { KEY_UP, KEY_PAGEUP }, |
116 | { KEY_DOWN, KEY_PAGEDOWN }, | 128 | { KEY_DOWN, KEY_PAGEDOWN }, |
117 | { KEY_LEFT, KEY_HOME }, | 129 | { KEY_LEFT, KEY_HOME }, |
@@ -142,7 +154,7 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = { | |||
142 | { } | 154 | { } |
143 | }; | 155 | }; |
144 | 156 | ||
145 | static struct hidinput_key_translation powerbook_iso_keyboard[] = { | 157 | static struct hidinput_key_translation apple_iso_keyboard[] = { |
146 | { KEY_GRAVE, KEY_102ND }, | 158 | { KEY_GRAVE, KEY_102ND }, |
147 | { KEY_102ND, KEY_GRAVE }, | 159 | { KEY_102ND, KEY_GRAVE }, |
148 | { } | 160 | { } |
@@ -160,39 +172,42 @@ static struct hidinput_key_translation *find_translation(struct hidinput_key_tra | |||
160 | return NULL; | 172 | return NULL; |
161 | } | 173 | } |
162 | 174 | ||
163 | static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | 175 | int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, |
164 | struct hid_usage *usage, __s32 value) | 176 | struct hid_usage *usage, __s32 value) |
165 | { | 177 | { |
166 | struct hidinput_key_translation *trans; | 178 | struct hidinput_key_translation *trans; |
167 | 179 | ||
168 | if (usage->code == KEY_FN) { | 180 | if (usage->code == KEY_FN) { |
169 | if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON; | 181 | if (value) hid->quirks |= HID_QUIRK_APPLE_FN_ON; |
170 | else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON; | 182 | else hid->quirks &= ~HID_QUIRK_APPLE_FN_ON; |
171 | 183 | ||
172 | input_event(input, usage->type, usage->code, value); | 184 | input_event(input, usage->type, usage->code, value); |
173 | 185 | ||
174 | return 1; | 186 | return 1; |
175 | } | 187 | } |
176 | 188 | ||
177 | if (hid_pb_fnmode) { | 189 | if (hid_apple_fnmode) { |
178 | int do_translate; | 190 | int do_translate; |
179 | 191 | ||
180 | trans = find_translation(powerbook_fn_keys, usage->code); | 192 | trans = find_translation((hid->product < 0x220 || |
193 | hid->product >= 0x300) ? | ||
194 | powerbook_fn_keys : apple_fn_keys, | ||
195 | usage->code); | ||
181 | if (trans) { | 196 | if (trans) { |
182 | if (test_bit(usage->code, hid->pb_pressed_fn)) | 197 | if (test_bit(usage->code, hid->apple_pressed_fn)) |
183 | do_translate = 1; | 198 | do_translate = 1; |
184 | else if (trans->flags & POWERBOOK_FLAG_FKEY) | 199 | else if (trans->flags & APPLE_FLAG_FKEY) |
185 | do_translate = | 200 | do_translate = |
186 | (hid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || | 201 | (hid_apple_fnmode == 2 && (hid->quirks & HID_QUIRK_APPLE_FN_ON)) || |
187 | (hid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); | 202 | (hid_apple_fnmode == 1 && !(hid->quirks & HID_QUIRK_APPLE_FN_ON)); |
188 | else | 203 | else |
189 | do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); | 204 | do_translate = (hid->quirks & HID_QUIRK_APPLE_FN_ON); |
190 | 205 | ||
191 | if (do_translate) { | 206 | if (do_translate) { |
192 | if (value) | 207 | if (value) |
193 | set_bit(usage->code, hid->pb_pressed_fn); | 208 | set_bit(usage->code, hid->apple_pressed_fn); |
194 | else | 209 | else |
195 | clear_bit(usage->code, hid->pb_pressed_fn); | 210 | clear_bit(usage->code, hid->apple_pressed_fn); |
196 | 211 | ||
197 | input_event(input, usage->type, trans->to, value); | 212 | input_event(input, usage->type, trans->to, value); |
198 | 213 | ||
@@ -217,8 +232,8 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | |||
217 | } | 232 | } |
218 | } | 233 | } |
219 | 234 | ||
220 | if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { | 235 | if (hid->quirks & HID_QUIRK_APPLE_ISO_KEYBOARD) { |
221 | trans = find_translation(powerbook_iso_keyboard, usage->code); | 236 | trans = find_translation(apple_iso_keyboard, usage->code); |
222 | if (trans) { | 237 | if (trans) { |
223 | input_event(input, usage->type, trans->to, value); | 238 | input_event(input, usage->type, trans->to, value); |
224 | return 1; | 239 | return 1; |
@@ -228,31 +243,35 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | |||
228 | return 0; | 243 | return 0; |
229 | } | 244 | } |
230 | 245 | ||
231 | static void hidinput_pb_setup(struct input_dev *input) | 246 | static void hidinput_apple_setup(struct input_dev *input) |
232 | { | 247 | { |
233 | struct hidinput_key_translation *trans; | 248 | struct hidinput_key_translation *trans; |
234 | 249 | ||
235 | set_bit(KEY_NUMLOCK, input->keybit); | 250 | set_bit(KEY_NUMLOCK, input->keybit); |
236 | 251 | ||
237 | /* Enable all needed keys */ | 252 | /* Enable all needed keys */ |
253 | for (trans = apple_fn_keys; trans->from; trans++) | ||
254 | set_bit(trans->to, input->keybit); | ||
255 | |||
238 | for (trans = powerbook_fn_keys; trans->from; trans++) | 256 | for (trans = powerbook_fn_keys; trans->from; trans++) |
239 | set_bit(trans->to, input->keybit); | 257 | set_bit(trans->to, input->keybit); |
240 | 258 | ||
241 | for (trans = powerbook_numlock_keys; trans->from; trans++) | 259 | for (trans = powerbook_numlock_keys; trans->from; trans++) |
242 | set_bit(trans->to, input->keybit); | 260 | set_bit(trans->to, input->keybit); |
243 | 261 | ||
244 | for (trans = powerbook_iso_keyboard; trans->from; trans++) | 262 | for (trans = apple_iso_keyboard; trans->from; trans++) |
245 | set_bit(trans->to, input->keybit); | 263 | set_bit(trans->to, input->keybit); |
246 | 264 | ||
247 | } | 265 | } |
248 | #else | 266 | #else |
249 | static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | 267 | inline int hidinput_apple_event(struct hid_device *hid, |
250 | struct hid_usage *usage, __s32 value) | 268 | struct input_dev *input, |
269 | struct hid_usage *usage, __s32 value) | ||
251 | { | 270 | { |
252 | return 0; | 271 | return 0; |
253 | } | 272 | } |
254 | 273 | ||
255 | static inline void hidinput_pb_setup(struct input_dev *input) | 274 | static inline void hidinput_apple_setup(struct input_dev *input) |
256 | { | 275 | { |
257 | } | 276 | } |
258 | #endif | 277 | #endif |
@@ -343,7 +362,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
343 | { | 362 | { |
344 | struct input_dev *input = hidinput->input; | 363 | struct input_dev *input = hidinput->input; |
345 | struct hid_device *device = input_get_drvdata(input); | 364 | struct hid_device *device = input_get_drvdata(input); |
346 | int max = 0, code; | 365 | int max = 0, code, ret; |
347 | unsigned long *bit = NULL; | 366 | unsigned long *bit = NULL; |
348 | 367 | ||
349 | field->hidinput = hidinput; | 368 | field->hidinput = hidinput; |
@@ -362,6 +381,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
362 | goto ignore; | 381 | goto ignore; |
363 | } | 382 | } |
364 | 383 | ||
384 | /* handle input mappings for quirky devices */ | ||
385 | ret = hidinput_mapping_quirks(usage, input, &bit, &max); | ||
386 | if (ret) | ||
387 | goto mapped; | ||
388 | |||
365 | switch (usage->hid & HID_USAGE_PAGE) { | 389 | switch (usage->hid & HID_USAGE_PAGE) { |
366 | 390 | ||
367 | case HID_UP_UNDEFINED: | 391 | case HID_UP_UNDEFINED: |
@@ -549,14 +573,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
549 | case 0x000: goto ignore; | 573 | case 0x000: goto ignore; |
550 | case 0x034: map_key_clear(KEY_SLEEP); break; | 574 | case 0x034: map_key_clear(KEY_SLEEP); break; |
551 | case 0x036: map_key_clear(BTN_MISC); break; | 575 | case 0x036: map_key_clear(BTN_MISC); break; |
552 | /* | ||
553 | * The next three are reported by Belkin wireless | ||
554 | * keyboard (1020:0006). These values are "reserved" | ||
555 | * in HUT 1.12. | ||
556 | */ | ||
557 | case 0x03a: map_key_clear(KEY_SOUND); break; | ||
558 | case 0x03b: map_key_clear(KEY_CAMERA); break; | ||
559 | case 0x03c: map_key_clear(KEY_DOCUMENTS); break; | ||
560 | 576 | ||
561 | case 0x040: map_key_clear(KEY_MENU); break; | 577 | case 0x040: map_key_clear(KEY_MENU); break; |
562 | case 0x045: map_key_clear(KEY_RADIO); break; | 578 | case 0x045: map_key_clear(KEY_RADIO); break; |
@@ -602,10 +618,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
602 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; | 618 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; |
603 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; | 619 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; |
604 | 620 | ||
605 | /* reserved in HUT 1.12. Reported on Petalynx remote */ | ||
606 | case 0x0f6: map_key_clear(KEY_NEXT); break; | ||
607 | case 0x0fa: map_key_clear(KEY_BACK); break; | ||
608 | |||
609 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; | 621 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; |
610 | case 0x183: map_key_clear(KEY_CONFIG); break; | 622 | case 0x183: map_key_clear(KEY_CONFIG); break; |
611 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; | 623 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; |
@@ -665,51 +677,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
665 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | 677 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; |
666 | case 0x28c: map_key_clear(KEY_SEND); break; | 678 | case 0x28c: map_key_clear(KEY_SEND); break; |
667 | 679 | ||
668 | /* Reported on a Cherry Cymotion keyboard */ | ||
669 | case 0x301: map_key_clear(KEY_PROG1); break; | ||
670 | case 0x302: map_key_clear(KEY_PROG2); break; | ||
671 | case 0x303: map_key_clear(KEY_PROG3); break; | ||
672 | |||
673 | /* Reported on certain Logitech wireless keyboards */ | ||
674 | case 0x1001: map_key_clear(KEY_MESSENGER); break; | ||
675 | case 0x1003: map_key_clear(KEY_SOUND); break; | ||
676 | case 0x1004: map_key_clear(KEY_VIDEO); break; | ||
677 | case 0x1005: map_key_clear(KEY_AUDIO); break; | ||
678 | case 0x100a: map_key_clear(KEY_DOCUMENTS); break; | ||
679 | case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; | ||
680 | case 0x1012: map_key_clear(KEY_NEXTSONG); break; | ||
681 | case 0x1013: map_key_clear(KEY_CAMERA); break; | ||
682 | case 0x1014: map_key_clear(KEY_MESSENGER); break; | ||
683 | case 0x1015: map_key_clear(KEY_RECORD); break; | ||
684 | case 0x1016: map_key_clear(KEY_PLAYER); break; | ||
685 | case 0x1017: map_key_clear(KEY_EJECTCD); break; | ||
686 | case 0x1018: map_key_clear(KEY_MEDIA); break; | ||
687 | case 0x1019: map_key_clear(KEY_PROG1); break; | ||
688 | case 0x101a: map_key_clear(KEY_PROG2); break; | ||
689 | case 0x101b: map_key_clear(KEY_PROG3); break; | ||
690 | case 0x101f: map_key_clear(KEY_ZOOMIN); break; | ||
691 | case 0x1020: map_key_clear(KEY_ZOOMOUT); break; | ||
692 | case 0x1021: map_key_clear(KEY_ZOOMRESET); break; | ||
693 | case 0x1023: map_key_clear(KEY_CLOSE); break; | ||
694 | case 0x1027: map_key_clear(KEY_MENU); break; | ||
695 | /* this one is marked as 'Rotate' */ | ||
696 | case 0x1028: map_key_clear(KEY_ANGLE); break; | ||
697 | case 0x1029: map_key_clear(KEY_SHUFFLE); break; | ||
698 | case 0x102a: map_key_clear(KEY_BACK); break; | ||
699 | case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; | ||
700 | case 0x1041: map_key_clear(KEY_BATTERY); break; | ||
701 | case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; | ||
702 | case 0x1043: map_key_clear(KEY_SPREADSHEET); break; | ||
703 | case 0x1044: map_key_clear(KEY_PRESENTATION); break; | ||
704 | case 0x1045: map_key_clear(KEY_UNDO); break; | ||
705 | case 0x1046: map_key_clear(KEY_REDO); break; | ||
706 | case 0x1047: map_key_clear(KEY_PRINT); break; | ||
707 | case 0x1048: map_key_clear(KEY_SAVE); break; | ||
708 | case 0x1049: map_key_clear(KEY_PROG1); break; | ||
709 | case 0x104a: map_key_clear(KEY_PROG2); break; | ||
710 | case 0x104b: map_key_clear(KEY_PROG3); break; | ||
711 | case 0x104c: map_key_clear(KEY_PROG4); break; | ||
712 | |||
713 | default: goto ignore; | 680 | default: goto ignore; |
714 | } | 681 | } |
715 | break; | 682 | break; |
@@ -736,63 +703,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
736 | 703 | ||
737 | case HID_UP_MSVENDOR: | 704 | case HID_UP_MSVENDOR: |
738 | 705 | ||
739 | /* Unfortunately, there are multiple devices which | 706 | goto ignore; |
740 | * emit usages from MSVENDOR page that require different | ||
741 | * handling. If this list grows too much in the future, | ||
742 | * more general handling will have to be introduced here | ||
743 | * (i.e. another blacklist). | ||
744 | */ | ||
745 | |||
746 | /* Chicony Chicony KU-0418 tactical pad */ | ||
747 | if (IS_CHICONY_TACTICAL_PAD(device)) { | ||
748 | set_bit(EV_REP, input->evbit); | ||
749 | switch(usage->hid & HID_USAGE) { | ||
750 | case 0xff01: map_key_clear(BTN_1); break; | ||
751 | case 0xff02: map_key_clear(BTN_2); break; | ||
752 | case 0xff03: map_key_clear(BTN_3); break; | ||
753 | case 0xff04: map_key_clear(BTN_4); break; | ||
754 | case 0xff05: map_key_clear(BTN_5); break; | ||
755 | case 0xff06: map_key_clear(BTN_6); break; | ||
756 | case 0xff07: map_key_clear(BTN_7); break; | ||
757 | case 0xff08: map_key_clear(BTN_8); break; | ||
758 | case 0xff09: map_key_clear(BTN_9); break; | ||
759 | case 0xff0a: map_key_clear(BTN_A); break; | ||
760 | case 0xff0b: map_key_clear(BTN_B); break; | ||
761 | default: goto ignore; | ||
762 | } | ||
763 | |||
764 | /* Microsoft Natural Ergonomic Keyboard 4000 */ | ||
765 | } else if (IS_MS_KB(device)) { | ||
766 | switch(usage->hid & HID_USAGE) { | ||
767 | case 0xfd06: | ||
768 | map_key_clear(KEY_CHAT); | ||
769 | break; | ||
770 | case 0xfd07: | ||
771 | map_key_clear(KEY_PHONE); | ||
772 | break; | ||
773 | case 0xff05: | ||
774 | set_bit(EV_REP, input->evbit); | ||
775 | map_key_clear(KEY_F13); | ||
776 | set_bit(KEY_F14, input->keybit); | ||
777 | set_bit(KEY_F15, input->keybit); | ||
778 | set_bit(KEY_F16, input->keybit); | ||
779 | set_bit(KEY_F17, input->keybit); | ||
780 | set_bit(KEY_F18, input->keybit); | ||
781 | default: goto ignore; | ||
782 | } | ||
783 | } else { | ||
784 | goto ignore; | ||
785 | } | ||
786 | break; | ||
787 | 707 | ||
788 | case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ | 708 | case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ |
789 | 709 | ||
790 | set_bit(EV_REP, input->evbit); | 710 | set_bit(EV_REP, input->evbit); |
791 | switch(usage->hid & HID_USAGE) { | 711 | switch(usage->hid & HID_USAGE) { |
792 | case 0x003: | 712 | case 0x003: |
793 | /* The fn key on Apple PowerBooks */ | 713 | /* The fn key on Apple USB keyboards */ |
794 | map_key_clear(KEY_FN); | 714 | map_key_clear(KEY_FN); |
795 | hidinput_pb_setup(input); | 715 | hidinput_apple_setup(input); |
796 | break; | 716 | break; |
797 | 717 | ||
798 | default: goto ignore; | 718 | default: goto ignore; |
@@ -800,38 +720,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
800 | break; | 720 | break; |
801 | 721 | ||
802 | case HID_UP_LOGIVENDOR: | 722 | case HID_UP_LOGIVENDOR: |
803 | set_bit(EV_REP, input->evbit); | ||
804 | switch(usage->hid & HID_USAGE) { | ||
805 | /* Reported on Logitech Ultra X Media Remote */ | ||
806 | case 0x004: map_key_clear(KEY_AGAIN); break; | ||
807 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
808 | case 0x024: map_key_clear(KEY_SHUFFLE); break; | ||
809 | case 0x025: map_key_clear(KEY_TV); break; | ||
810 | case 0x026: map_key_clear(KEY_MENU); break; | ||
811 | case 0x031: map_key_clear(KEY_AUDIO); break; | ||
812 | case 0x032: map_key_clear(KEY_TEXT); break; | ||
813 | case 0x033: map_key_clear(KEY_LAST); break; | ||
814 | case 0x047: map_key_clear(KEY_MP3); break; | ||
815 | case 0x048: map_key_clear(KEY_DVD); break; | ||
816 | case 0x049: map_key_clear(KEY_MEDIA); break; | ||
817 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
818 | case 0x04b: map_key_clear(KEY_ANGLE); break; | ||
819 | case 0x04c: map_key_clear(KEY_LANGUAGE); break; | ||
820 | case 0x04d: map_key_clear(KEY_SUBTITLE); break; | ||
821 | case 0x051: map_key_clear(KEY_RED); break; | ||
822 | case 0x052: map_key_clear(KEY_CLOSE); break; | ||
823 | |||
824 | /* Reported on Petalynx Maxter remote */ | ||
825 | case 0x05a: map_key_clear(KEY_TEXT); break; | ||
826 | case 0x05b: map_key_clear(KEY_RED); break; | ||
827 | case 0x05c: map_key_clear(KEY_GREEN); break; | ||
828 | case 0x05d: map_key_clear(KEY_YELLOW); break; | ||
829 | case 0x05e: map_key_clear(KEY_BLUE); break; | ||
830 | |||
831 | default: goto ignore; | ||
832 | } | ||
833 | break; | ||
834 | 723 | ||
724 | goto ignore; | ||
725 | |||
835 | case HID_UP_PID: | 726 | case HID_UP_PID: |
836 | 727 | ||
837 | switch(usage->hid & HID_USAGE) { | 728 | switch(usage->hid & HID_USAGE) { |
@@ -858,6 +749,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
858 | break; | 749 | break; |
859 | } | 750 | } |
860 | 751 | ||
752 | mapped: | ||
861 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { | 753 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { |
862 | if (usage->hid == HID_GD_Z) | 754 | if (usage->hid == HID_GD_Z) |
863 | map_rel(REL_HWHEEL); | 755 | map_rel(REL_HWHEEL); |
@@ -867,9 +759,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
867 | map_key(BTN_1); | 759 | map_key(BTN_1); |
868 | } | 760 | } |
869 | 761 | ||
870 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && | 762 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 | |
871 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) | 763 | HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) && |
872 | set_bit(REL_HWHEEL, bit); | 764 | (usage->code == REL_WHEEL)) |
765 | set_bit(REL_HWHEEL, bit); | ||
873 | 766 | ||
874 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 767 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) |
875 | || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) | 768 | || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) |
@@ -960,25 +853,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
960 | if (!usage->type) | 853 | if (!usage->type) |
961 | return; | 854 | return; |
962 | 855 | ||
963 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 856 | /* handle input events for quirky devices */ |
964 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | 857 | hidinput_event_quirks(hid, field, usage, value); |
965 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
966 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
967 | return; | ||
968 | } | ||
969 | |||
970 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
971 | input_event(input, usage->type, usage->code, -value); | ||
972 | return; | ||
973 | } | ||
974 | |||
975 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
976 | input_event(input, usage->type, REL_HWHEEL, value); | ||
977 | return; | ||
978 | } | ||
979 | |||
980 | if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value)) | ||
981 | return; | ||
982 | 858 | ||
983 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 859 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
984 | int hat_dir = usage->hat_dir; | 860 | int hat_dir = usage->hat_dir; |
@@ -1039,25 +915,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
1039 | return; | 915 | return; |
1040 | } | 916 | } |
1041 | 917 | ||
1042 | /* Handling MS keyboards special buttons */ | ||
1043 | if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | ||
1044 | int key = 0; | ||
1045 | static int last_key = 0; | ||
1046 | switch (value) { | ||
1047 | case 0x01: key = KEY_F14; break; | ||
1048 | case 0x02: key = KEY_F15; break; | ||
1049 | case 0x04: key = KEY_F16; break; | ||
1050 | case 0x08: key = KEY_F17; break; | ||
1051 | case 0x10: key = KEY_F18; break; | ||
1052 | default: break; | ||
1053 | } | ||
1054 | if (key) { | ||
1055 | input_event(input, usage->type, key, 1); | ||
1056 | last_key = key; | ||
1057 | } else { | ||
1058 | input_event(input, usage->type, last_key, 0); | ||
1059 | } | ||
1060 | } | ||
1061 | /* report the usage code as scancode if the key status has changed */ | 918 | /* report the usage code as scancode if the key status has changed */ |
1062 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) | 919 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) |
1063 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); | 920 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); |