aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-input.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2007-07-09 08:23:37 -0400
committerJiri Kosina <jkosina@suse.cz>2007-07-09 08:23:37 -0400
commitfeb485d4010e450183bd422d90c0d0f6be98f932 (patch)
tree6c6b14d67b81fe98d6bee658c0caaffefae6b789 /drivers/hid/hid-input.c
parent58037eb961f859607b161c50d9d4ecb374de1e8f (diff)
parent2c1d8aea2ca76df1b1de2aed23e3ceda2a044ed1 (diff)
Merge branches 'debug-module-param' and 'upstream' into for-linus
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r--drivers/hid/hid-input.c99
1 files changed, 94 insertions, 5 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 38595d3935ce..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;
@@ -374,6 +387,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
374 } 387 }
375 } 388 }
376 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
377 map_key(code); 405 map_key(code);
378 break; 406 break;
379 407
@@ -562,6 +590,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
562 case 0x0e5: map_key_clear(KEY_BASSBOOST); break; 590 case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
563 case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; 591 case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
564 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
565 case 0x183: map_key_clear(KEY_CONFIG); break; 598 case 0x183: map_key_clear(KEY_CONFIG); break;
566 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; 599 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
567 case 0x185: map_key_clear(KEY_EDITOR); break; 600 case 0x185: map_key_clear(KEY_EDITOR); break;
@@ -594,7 +627,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
594 case 0x21b: map_key_clear(KEY_COPY); break; 627 case 0x21b: map_key_clear(KEY_COPY); break;
595 case 0x21c: map_key_clear(KEY_CUT); break; 628 case 0x21c: map_key_clear(KEY_CUT); break;
596 case 0x21d: map_key_clear(KEY_PASTE); break; 629 case 0x21d: map_key_clear(KEY_PASTE); break;
597 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;
598 case 0x223: map_key_clear(KEY_HOMEPAGE); break; 633 case 0x223: map_key_clear(KEY_HOMEPAGE); break;
599 case 0x224: map_key_clear(KEY_BACK); break; 634 case 0x224: map_key_clear(KEY_BACK); break;
600 case 0x225: map_key_clear(KEY_FORWARD); break; 635 case 0x225: map_key_clear(KEY_FORWARD); break;
@@ -684,7 +719,28 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
684 break; 719 break;
685 720
686 case HID_UP_MSVENDOR: 721 case HID_UP_MSVENDOR:
687 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;
688 744
689 case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ 745 case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
690 746
@@ -700,10 +756,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
700 } 756 }
701 break; 757 break;
702 758
703 case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */ 759 case HID_UP_LOGIVENDOR:
704
705 set_bit(EV_REP, input->evbit); 760 set_bit(EV_REP, input->evbit);
706 switch(usage->hid & HID_USAGE) { 761 switch(usage->hid & HID_USAGE) {
762 /* Reported on Logitech Ultra X Media Remote */
707 case 0x004: map_key_clear(KEY_AGAIN); break; 763 case 0x004: map_key_clear(KEY_AGAIN); break;
708 case 0x00d: map_key_clear(KEY_HOME); break; 764 case 0x00d: map_key_clear(KEY_HOME); break;
709 case 0x024: map_key_clear(KEY_SHUFFLE); break; 765 case 0x024: map_key_clear(KEY_SHUFFLE); break;
@@ -721,6 +777,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
721 case 0x04d: map_key_clear(KEY_SUBTITLE); break; 777 case 0x04d: map_key_clear(KEY_SUBTITLE); break;
722 case 0x051: map_key_clear(KEY_RED); break; 778 case 0x051: map_key_clear(KEY_RED); break;
723 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
724 default: goto ignore; 788 default: goto ignore;
725 } 789 }
726 break; 790 break;
@@ -814,6 +878,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
814 field->dpad = usage->code; 878 field->dpad = usage->code;
815 } 879 }
816 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
817 hid_resolv_event(usage->type, usage->code); 891 hid_resolv_event(usage->type, usage->code);
818 892
819 dbg_hid_line("\n"); 893 dbg_hid_line("\n");
@@ -902,6 +976,21 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
902 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 */
903 return; 977 return;
904 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
905 input_event(input, usage->type, usage->code, value); 994 input_event(input, usage->type, usage->code, value);
906 995
907 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) 996 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
@@ -970,7 +1059,7 @@ int hidinput_connect(struct hid_device *hid)
970 if (IS_INPUT_APPLICATION(hid->collection[i].usage)) 1059 if (IS_INPUT_APPLICATION(hid->collection[i].usage))
971 break; 1060 break;
972 1061
973 if (i == hid->maxcollection) 1062 if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0)
974 return -1; 1063 return -1;
975 1064
976 if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) 1065 if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)