diff options
author | Jiri Kosina <jkosina@suse.cz> | 2007-11-23 07:16:02 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-01-28 08:51:20 -0500 |
commit | 87bc2aa9933afc032a93490e1642918121e7470b (patch) | |
tree | fc09fa3c536a9f9a4dcfc7a6c58ea4551f6c1811 | |
parent | 10bd065facb2594bd508597ef464d401b212f379 (diff) |
HID: separate hid-input event quirks from generic code
This patch separates also the hid-input quirks that have to be
applied at the time the event occurs, so that the generic code
handling HUT-compliant devices is not messed up by them too much.
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-input-quirks.c | 65 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 63 | ||||
-rw-r--r-- | include/linux/hid.h | 2 |
3 files changed, 71 insertions, 59 deletions
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c index e05e9ad5522e..7f2f80b00d74 100644 --- a/drivers/hid/hid-input-quirks.c +++ b/drivers/hid/hid-input-quirks.c | |||
@@ -322,5 +322,68 @@ int hidinput_mapping_quirks(struct hid_usage *usage, | |||
322 | } | 322 | } |
323 | return 0; | 323 | return 0; |
324 | } | 324 | } |
325 | EXPORT_SYMBOL_GPL(hidinput_mapping_quirks); | 325 | |
326 | #define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9)) | ||
327 | |||
328 | void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) | ||
329 | { | ||
330 | struct input_dev *input; | ||
331 | unsigned *quirks = &hid->quirks; | ||
332 | |||
333 | input = field->hidinput->input; | ||
334 | |||
335 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | ||
336 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | ||
337 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
338 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
343 | (usage->type == EV_REL) && | ||
344 | (usage->code == REL_WHEEL)) { | ||
345 | hid->delayed_value = value; | ||
346 | return; | ||
347 | } | ||
348 | |||
349 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
350 | (usage->hid == 0x000100b8)) { | ||
351 | input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); | ||
352 | return; | ||
353 | } | ||
354 | |||
355 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
356 | input_event(input, usage->type, usage->code, -value); | ||
357 | return; | ||
358 | } | ||
359 | |||
360 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
361 | input_event(input, usage->type, REL_HWHEEL, value); | ||
362 | return; | ||
363 | } | ||
364 | |||
365 | if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value)) | ||
366 | return; | ||
367 | |||
368 | /* Handling MS keyboards special buttons */ | ||
369 | if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | ||
370 | int key = 0; | ||
371 | static int last_key = 0; | ||
372 | switch (value) { | ||
373 | case 0x01: key = KEY_F14; break; | ||
374 | case 0x02: key = KEY_F15; break; | ||
375 | case 0x04: key = KEY_F16; break; | ||
376 | case 0x08: key = KEY_F17; break; | ||
377 | case 0x10: key = KEY_F18; break; | ||
378 | default: break; | ||
379 | } | ||
380 | if (key) { | ||
381 | input_event(input, usage->type, key, 1); | ||
382 | last_key = key; | ||
383 | } else { | ||
384 | input_event(input, usage->type, last_key, 0); | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | |||
326 | 389 | ||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 3d448037c82f..aeb018e31bfc 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -86,11 +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 | #define IS_MS_PRESENTER_8000(x) (x->vendor == 0x045e && x->product == 0x0713) | ||
93 | |||
94 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | 89 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK |
95 | 90 | ||
96 | struct hidinput_key_translation { | 91 | struct hidinput_key_translation { |
@@ -177,7 +172,7 @@ static struct hidinput_key_translation *find_translation(struct hidinput_key_tra | |||
177 | return NULL; | 172 | return NULL; |
178 | } | 173 | } |
179 | 174 | ||
180 | static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, | 175 | int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, |
181 | struct hid_usage *usage, __s32 value) | 176 | struct hid_usage *usage, __s32 value) |
182 | { | 177 | { |
183 | struct hidinput_key_translation *trans; | 178 | struct hidinput_key_translation *trans; |
@@ -269,7 +264,7 @@ static void hidinput_apple_setup(struct input_dev *input) | |||
269 | 264 | ||
270 | } | 265 | } |
271 | #else | 266 | #else |
272 | static inline int hidinput_apple_event(struct hid_device *hid, | 267 | inline int hidinput_apple_event(struct hid_device *hid, |
273 | struct input_dev *input, | 268 | struct input_dev *input, |
274 | struct hid_usage *usage, __s32 value) | 269 | struct hid_usage *usage, __s32 value) |
275 | { | 270 | { |
@@ -386,6 +381,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
386 | goto ignore; | 381 | goto ignore; |
387 | } | 382 | } |
388 | 383 | ||
384 | /* handle input mappings for quirky devices */ | ||
389 | ret = hidinput_mapping_quirks(usage, input, bit, &max); | 385 | ret = hidinput_mapping_quirks(usage, input, bit, &max); |
390 | if (ret) | 386 | if (ret) |
391 | goto mapped; | 387 | goto mapped; |
@@ -857,38 +853,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
857 | if (!usage->type) | 853 | if (!usage->type) |
858 | return; | 854 | return; |
859 | 855 | ||
860 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 856 | /* handle input events for quirky devices */ |
861 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | 857 | hidinput_event_quirks(hid, field, usage, value); |
862 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
863 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
864 | return; | ||
865 | } | ||
866 | |||
867 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
868 | (usage->type == EV_REL) && | ||
869 | (usage->code == REL_WHEEL)) { | ||
870 | hid->delayed_value = value; | ||
871 | return; | ||
872 | } | ||
873 | |||
874 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
875 | (usage->hid == 0x000100b8)) { | ||
876 | input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); | ||
877 | return; | ||
878 | } | ||
879 | |||
880 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
881 | input_event(input, usage->type, usage->code, -value); | ||
882 | return; | ||
883 | } | ||
884 | |||
885 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
886 | input_event(input, usage->type, REL_HWHEEL, value); | ||
887 | return; | ||
888 | } | ||
889 | |||
890 | if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value)) | ||
891 | return; | ||
892 | 858 | ||
893 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 859 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
894 | int hat_dir = usage->hat_dir; | 860 | int hat_dir = usage->hat_dir; |
@@ -949,25 +915,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
949 | return; | 915 | return; |
950 | } | 916 | } |
951 | 917 | ||
952 | /* Handling MS keyboards special buttons */ | ||
953 | if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | ||
954 | int key = 0; | ||
955 | static int last_key = 0; | ||
956 | switch (value) { | ||
957 | case 0x01: key = KEY_F14; break; | ||
958 | case 0x02: key = KEY_F15; break; | ||
959 | case 0x04: key = KEY_F16; break; | ||
960 | case 0x08: key = KEY_F17; break; | ||
961 | case 0x10: key = KEY_F18; break; | ||
962 | default: break; | ||
963 | } | ||
964 | if (key) { | ||
965 | input_event(input, usage->type, key, 1); | ||
966 | last_key = key; | ||
967 | } else { | ||
968 | input_event(input, usage->type, last_key, 0); | ||
969 | } | ||
970 | } | ||
971 | /* 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 */ |
972 | 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) |
973 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); | 920 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); |
diff --git a/include/linux/hid.h b/include/linux/hid.h index cd5d562b1b7c..dca5804836f3 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -525,6 +525,8 @@ int hid_set_field(struct hid_field *, unsigned, __s32); | |||
525 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); | 525 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); |
526 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); | 526 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); |
527 | int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long *, int *); | 527 | int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long *, int *); |
528 | void hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | ||
529 | int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); | ||
528 | void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); | 530 | void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); |
529 | void hid_output_report(struct hid_report *report, __u8 *data); | 531 | void hid_output_report(struct hid_report *report, __u8 *data); |
530 | void hid_free_device(struct hid_device *device); | 532 | void hid_free_device(struct hid_device *device); |