aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-input-quirks.c65
-rw-r--r--drivers/hid/hid-input.c63
-rw-r--r--include/linux/hid.h2
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}
325EXPORT_SYMBOL_GPL(hidinput_mapping_quirks); 325
326#define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
327
328void 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
96struct hidinput_key_translation { 91struct 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
180static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, 175int 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
272static inline int hidinput_apple_event(struct hid_device *hid, 267inline 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);
525int hid_input_report(struct hid_device *, int type, u8 *, int, int); 525int hid_input_report(struct hid_device *, int type, u8 *, int, int);
526int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); 526int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
527int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long *, int *); 527int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long *, int *);
528void hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
529int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32);
528void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); 530void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
529void hid_output_report(struct hid_report *report, __u8 *data); 531void hid_output_report(struct hid_report *report, __u8 *data);
530void hid_free_device(struct hid_device *device); 532void hid_free_device(struct hid_device *device);