aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r--drivers/hid/hid-input.c125
1 files changed, 104 insertions, 21 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7f817897b178..8edbd30cf795 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -60,6 +60,19 @@ static const unsigned char hid_keyboard[256] = {
60 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk 60 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
61}; 61};
62 62
63/* extended mapping for certain Logitech hardware (Logitech cordless desktop LX500) */
64#define LOGITECH_EXPANDED_KEYMAP_SIZE 80
65static int logitech_expanded_keymap[LOGITECH_EXPANDED_KEYMAP_SIZE] = {
66 0,216, 0,213,175,156, 0, 0, 0, 0,
67 144, 0, 0, 0, 0, 0, 0, 0, 0,212,
68 174,167,152,161,112, 0, 0, 0,154, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0,183,184,185,186,187,
73 188,189,190,191,192,193,194, 0, 0, 0
74};
75
63static const struct { 76static const struct {
64 __s32 x; 77 __s32 x;
65 __s32 y; 78 __s32 y;
@@ -308,9 +321,7 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
308 321
309 clear_bit(old_keycode, dev->keybit); 322 clear_bit(old_keycode, dev->keybit);
310 set_bit(usage->code, dev->keybit); 323 set_bit(usage->code, dev->keybit);
311#ifdef CONFIG_HID_DEBUG 324 dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
312 printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
313#endif
314 /* Set the keybit for the old keycode if the old keycode is used 325 /* Set the keybit for the old keycode if the old keycode is used
315 * by another key */ 326 * by another key */
316 if (hidinput_find_key (hid, 0, old_keycode)) 327 if (hidinput_find_key (hid, 0, old_keycode))
@@ -333,11 +344,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
333 344
334 field->hidinput = hidinput; 345 field->hidinput = hidinput;
335 346
336#ifdef CONFIG_HID_DEBUG 347 dbg_hid("Mapping: ");
337 printk(KERN_DEBUG "Mapping: ");
338 hid_resolv_usage(usage->hid); 348 hid_resolv_usage(usage->hid);
339 printk(" ---> "); 349 dbg_hid_line(" ---> ");
340#endif
341 350
342 if (field->flags & HID_MAIN_ITEM_CONSTANT) 351 if (field->flags & HID_MAIN_ITEM_CONSTANT)
343 goto ignore; 352 goto ignore;
@@ -378,6 +387,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
378 } 387 }
379 } 388 }
380 389
390 /* Special handling for Logitech Cordless Desktop */
391 if (field->application != HID_GD_MOUSE) {
392 if (device->quirks & HID_QUIRK_LOGITECH_EXPANDED_KEYMAP) {
393 int hid = usage->hid & HID_USAGE;
394 if (hid < LOGITECH_EXPANDED_KEYMAP_SIZE && logitech_expanded_keymap[hid] != 0)
395 code = logitech_expanded_keymap[hid];
396 }
397 } else {
398 if (device->quirks & HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL) {
399 int hid = usage->hid & HID_USAGE;
400 if (hid == 7 || hid == 8)
401 goto ignore;
402 }
403 }
404
381 map_key(code); 405 map_key(code);
382 break; 406 break;
383 407
@@ -566,6 +590,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
566 case 0x0e5: map_key_clear(KEY_BASSBOOST); break; 590 case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
567 case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; 591 case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
568 case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; 592 case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
593
594 /* reserved in HUT 1.12. Reported on Petalynx remote */
595 case 0x0f6: map_key_clear(KEY_NEXT); break;
596 case 0x0fa: map_key_clear(KEY_BACK); break;
597
569 case 0x183: map_key_clear(KEY_CONFIG); break; 598 case 0x183: map_key_clear(KEY_CONFIG); break;
570 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; 599 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
571 case 0x185: map_key_clear(KEY_EDITOR); break; 600 case 0x185: map_key_clear(KEY_EDITOR); break;
@@ -598,7 +627,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
598 case 0x21b: map_key_clear(KEY_COPY); break; 627 case 0x21b: map_key_clear(KEY_COPY); break;
599 case 0x21c: map_key_clear(KEY_CUT); break; 628 case 0x21c: map_key_clear(KEY_CUT); break;
600 case 0x21d: map_key_clear(KEY_PASTE); break; 629 case 0x21d: map_key_clear(KEY_PASTE); break;
601 case 0x221: map_key_clear(KEY_FIND); break; 630 case 0x21f: map_key_clear(KEY_FIND); break;
631 case 0x221: map_key_clear(KEY_SEARCH); break;
632 case 0x222: map_key_clear(KEY_GOTO); break;
602 case 0x223: map_key_clear(KEY_HOMEPAGE); break; 633 case 0x223: map_key_clear(KEY_HOMEPAGE); break;
603 case 0x224: map_key_clear(KEY_BACK); break; 634 case 0x224: map_key_clear(KEY_BACK); break;
604 case 0x225: map_key_clear(KEY_FORWARD); break; 635 case 0x225: map_key_clear(KEY_FORWARD); break;
@@ -688,7 +719,28 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
688 break; 719 break;
689 720
690 case HID_UP_MSVENDOR: 721 case HID_UP_MSVENDOR:
691 goto ignore; 722
723 /* special case - Chicony Chicony KU-0418 tactical pad */
724 if (device->vendor == 0x04f2 && device->product == 0x0418) {
725 set_bit(EV_REP, input->evbit);
726 switch(usage->hid & HID_USAGE) {
727 case 0xff01: map_key_clear(BTN_1); break;
728 case 0xff02: map_key_clear(BTN_2); break;
729 case 0xff03: map_key_clear(BTN_3); break;
730 case 0xff04: map_key_clear(BTN_4); break;
731 case 0xff05: map_key_clear(BTN_5); break;
732 case 0xff06: map_key_clear(BTN_6); break;
733 case 0xff07: map_key_clear(BTN_7); break;
734 case 0xff08: map_key_clear(BTN_8); break;
735 case 0xff09: map_key_clear(BTN_9); break;
736 case 0xff0a: map_key_clear(BTN_A); break;
737 case 0xff0b: map_key_clear(BTN_B); break;
738 default: goto ignore;
739 }
740 } else {
741 goto ignore;
742 }
743 break;
692 744
693 case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ 745 case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
694 746
@@ -704,10 +756,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
704 } 756 }
705 break; 757 break;
706 758
707 case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */ 759 case HID_UP_LOGIVENDOR:
708
709 set_bit(EV_REP, input->evbit); 760 set_bit(EV_REP, input->evbit);
710 switch(usage->hid & HID_USAGE) { 761 switch(usage->hid & HID_USAGE) {
762 /* Reported on Logitech Ultra X Media Remote */
711 case 0x004: map_key_clear(KEY_AGAIN); break; 763 case 0x004: map_key_clear(KEY_AGAIN); break;
712 case 0x00d: map_key_clear(KEY_HOME); break; 764 case 0x00d: map_key_clear(KEY_HOME); break;
713 case 0x024: map_key_clear(KEY_SHUFFLE); break; 765 case 0x024: map_key_clear(KEY_SHUFFLE); break;
@@ -725,6 +777,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
725 case 0x04d: map_key_clear(KEY_SUBTITLE); break; 777 case 0x04d: map_key_clear(KEY_SUBTITLE); break;
726 case 0x051: map_key_clear(KEY_RED); break; 778 case 0x051: map_key_clear(KEY_RED); break;
727 case 0x052: map_key_clear(KEY_CLOSE); break; 779 case 0x052: map_key_clear(KEY_CLOSE); break;
780
781 /* Reported on Petalynx Maxter remote */
782 case 0x05a: map_key_clear(KEY_TEXT); break;
783 case 0x05b: map_key_clear(KEY_RED); break;
784 case 0x05c: map_key_clear(KEY_GREEN); break;
785 case 0x05d: map_key_clear(KEY_YELLOW); break;
786 case 0x05e: map_key_clear(KEY_BLUE); break;
787
728 default: goto ignore; 788 default: goto ignore;
729 } 789 }
730 break; 790 break;
@@ -818,16 +878,24 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
818 field->dpad = usage->code; 878 field->dpad = usage->code;
819 } 879 }
820 880
881 /* for those devices which produce Consumer volume usage as relative,
882 * we emulate pressing volumeup/volumedown appropriate number of times
883 * in hidinput_hid_event()
884 */
885 if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
886 (usage->code == ABS_VOLUME)) {
887 set_bit(KEY_VOLUMEUP, input->keybit);
888 set_bit(KEY_VOLUMEDOWN, input->keybit);
889 }
890
821 hid_resolv_event(usage->type, usage->code); 891 hid_resolv_event(usage->type, usage->code);
822#ifdef CONFIG_HID_DEBUG 892
823 printk("\n"); 893 dbg_hid_line("\n");
824#endif 894
825 return; 895 return;
826 896
827ignore: 897ignore:
828#ifdef CONFIG_HID_DEBUG 898 dbg_hid_line("IGNORED\n");
829 printk("IGNORED\n");
830#endif
831 return; 899 return;
832} 900}
833 901
@@ -896,18 +964,33 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
896 } 964 }
897 965
898 if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */ 966 if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
899 dbg("Maximum Effects - %d",value); 967 dbg_hid("Maximum Effects - %d\n",value);
900 return; 968 return;
901 } 969 }
902 970
903 if (usage->hid == (HID_UP_PID | 0x7fUL)) { 971 if (usage->hid == (HID_UP_PID | 0x7fUL)) {
904 dbg("PID Pool Report\n"); 972 dbg_hid("PID Pool Report\n");
905 return; 973 return;
906 } 974 }
907 975
908 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ 976 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
909 return; 977 return;
910 978
979 if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
980 (usage->code == ABS_VOLUME)) {
981 int count = abs(value);
982 int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN;
983 int i;
984
985 for (i = 0; i < count; i++) {
986 input_event(input, EV_KEY, direction, 1);
987 input_sync(input);
988 input_event(input, EV_KEY, direction, 0);
989 input_sync(input);
990 }
991 return;
992 }
993
911 input_event(input, usage->type, usage->code, value); 994 input_event(input, usage->type, usage->code, value);
912 995
913 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) 996 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
@@ -976,7 +1059,7 @@ int hidinput_connect(struct hid_device *hid)
976 if (IS_INPUT_APPLICATION(hid->collection[i].usage)) 1059 if (IS_INPUT_APPLICATION(hid->collection[i].usage))
977 break; 1060 break;
978 1061
979 if (i == hid->maxcollection) 1062 if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0)
980 return -1; 1063 return -1;
981 1064
982 if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) 1065 if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
@@ -994,7 +1077,7 @@ int hidinput_connect(struct hid_device *hid)
994 if (!hidinput || !input_dev) { 1077 if (!hidinput || !input_dev) {
995 kfree(hidinput); 1078 kfree(hidinput);
996 input_free_device(input_dev); 1079 input_free_device(input_dev);
997 err("Out of memory during hid input probe"); 1080 err_hid("Out of memory during hid input probe");
998 return -1; 1081 return -1;
999 } 1082 }
1000 1083