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.c92
1 files changed, 83 insertions, 9 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 8edbd30cf795..0c3e12c1794c 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -53,7 +53,7 @@ static const unsigned char hid_keyboard[256] = {
53 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, 53 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
54 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, 54 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
55 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, 55 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
56 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, 56 unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
57 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, 57 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
58 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, 58 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
59 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, 59 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
@@ -86,6 +86,10 @@ 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
89#ifdef CONFIG_USB_HIDINPUT_POWERBOOK 93#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
90 94
91struct hidinput_key_translation { 95struct hidinput_key_translation {
@@ -295,7 +299,7 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode,
295{ 299{
296 struct hid_device *hid = dev->private; 300 struct hid_device *hid = dev->private;
297 struct hid_usage *usage; 301 struct hid_usage *usage;
298 302
299 usage = hidinput_find_key(hid, scancode, 0); 303 usage = hidinput_find_key(hid, scancode, 0);
300 if (usage) { 304 if (usage) {
301 *keycode = usage->code; 305 *keycode = usage->code;
@@ -310,15 +314,15 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
310 struct hid_device *hid = dev->private; 314 struct hid_device *hid = dev->private;
311 struct hid_usage *usage; 315 struct hid_usage *usage;
312 int old_keycode; 316 int old_keycode;
313 317
314 if (keycode < 0 || keycode > KEY_MAX) 318 if (keycode < 0 || keycode > KEY_MAX)
315 return -EINVAL; 319 return -EINVAL;
316 320
317 usage = hidinput_find_key(hid, scancode, 0); 321 usage = hidinput_find_key(hid, scancode, 0);
318 if (usage) { 322 if (usage) {
319 old_keycode = usage->code; 323 old_keycode = usage->code;
320 usage->code = keycode; 324 usage->code = keycode;
321 325
322 clear_bit(old_keycode, dev->keybit); 326 clear_bit(old_keycode, dev->keybit);
323 set_bit(usage->code, dev->keybit); 327 set_bit(usage->code, dev->keybit);
324 dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); 328 dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
@@ -326,10 +330,10 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
326 * by another key */ 330 * by another key */
327 if (hidinput_find_key (hid, 0, old_keycode)) 331 if (hidinput_find_key (hid, 0, old_keycode))
328 set_bit(old_keycode, dev->keybit); 332 set_bit(old_keycode, dev->keybit);
329 333
330 return 0; 334 return 0;
331 } 335 }
332 336
333 return -EINVAL; 337 return -EINVAL;
334} 338}
335 339
@@ -351,6 +355,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
351 if (field->flags & HID_MAIN_ITEM_CONSTANT) 355 if (field->flags & HID_MAIN_ITEM_CONSTANT)
352 goto ignore; 356 goto ignore;
353 357
358 /* only LED usages are supported in output fields */
359 if (field->report_type == HID_OUTPUT_REPORT &&
360 (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
361 dbg_hid_line(" [non-LED output field] ");
362 goto ignore;
363 }
364
354 switch (usage->hid & HID_USAGE_PAGE) { 365 switch (usage->hid & HID_USAGE_PAGE) {
355 366
356 case HID_UP_UNDEFINED: 367 case HID_UP_UNDEFINED:
@@ -595,6 +606,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
595 case 0x0f6: map_key_clear(KEY_NEXT); break; 606 case 0x0f6: map_key_clear(KEY_NEXT); break;
596 case 0x0fa: map_key_clear(KEY_BACK); break; 607 case 0x0fa: map_key_clear(KEY_BACK); break;
597 608
609 case 0x182: map_key_clear(KEY_BOOKMARKS); break;
598 case 0x183: map_key_clear(KEY_CONFIG); break; 610 case 0x183: map_key_clear(KEY_CONFIG); break;
599 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; 611 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
600 case 0x185: map_key_clear(KEY_EDITOR); break; 612 case 0x185: map_key_clear(KEY_EDITOR); break;
@@ -611,9 +623,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
611 case 0x192: map_key_clear(KEY_CALC); break; 623 case 0x192: map_key_clear(KEY_CALC); break;
612 case 0x194: map_key_clear(KEY_FILE); break; 624 case 0x194: map_key_clear(KEY_FILE); break;
613 case 0x196: map_key_clear(KEY_WWW); break; 625 case 0x196: map_key_clear(KEY_WWW); break;
626 case 0x19c: map_key_clear(KEY_LOGOFF); break;
614 case 0x19e: map_key_clear(KEY_COFFEE); break; 627 case 0x19e: map_key_clear(KEY_COFFEE); break;
615 case 0x1a6: map_key_clear(KEY_HELP); break; 628 case 0x1a6: map_key_clear(KEY_HELP); break;
616 case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; 629 case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
630 case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
631 case 0x1b6: map_key_clear(KEY_MEDIA); break;
632 case 0x1b7: map_key_clear(KEY_SOUND); break;
617 case 0x1bc: map_key_clear(KEY_MESSENGER); break; 633 case 0x1bc: map_key_clear(KEY_MESSENGER); break;
618 case 0x1bd: map_key_clear(KEY_INFO); break; 634 case 0x1bd: map_key_clear(KEY_INFO); break;
619 case 0x201: map_key_clear(KEY_NEW); break; 635 case 0x201: map_key_clear(KEY_NEW); break;
@@ -720,8 +736,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
720 736
721 case HID_UP_MSVENDOR: 737 case HID_UP_MSVENDOR:
722 738
723 /* special case - Chicony Chicony KU-0418 tactical pad */ 739 /* Unfortunately, there are multiple devices which
724 if (device->vendor == 0x04f2 && device->product == 0x0418) { 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)) {
725 set_bit(EV_REP, input->evbit); 748 set_bit(EV_REP, input->evbit);
726 switch(usage->hid & HID_USAGE) { 749 switch(usage->hid & HID_USAGE) {
727 case 0xff01: map_key_clear(BTN_1); break; 750 case 0xff01: map_key_clear(BTN_1); break;
@@ -737,6 +760,26 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
737 case 0xff0b: map_key_clear(BTN_B); break; 760 case 0xff0b: map_key_clear(BTN_B); break;
738 default: goto ignore; 761 default: goto ignore;
739 } 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 }
740 } else { 783 } else {
741 goto ignore; 784 goto ignore;
742 } 785 }
@@ -888,6 +931,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
888 set_bit(KEY_VOLUMEDOWN, input->keybit); 931 set_bit(KEY_VOLUMEDOWN, input->keybit);
889 } 932 }
890 933
934 if (usage->type == EV_KEY) {
935 set_bit(EV_MSC, input->evbit);
936 set_bit(MSC_SCAN, input->mscbit);
937 }
938
891 hid_resolv_event(usage->type, usage->code); 939 hid_resolv_event(usage->type, usage->code);
892 940
893 dbg_hid_line("\n"); 941 dbg_hid_line("\n");
@@ -991,6 +1039,29 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
991 return; 1039 return;
992 } 1040 }
993 1041
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 */
1062 if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
1063 input_event(input, EV_MSC, MSC_SCAN, usage->hid);
1064
994 input_event(input, usage->type, usage->code, value); 1065 input_event(input, usage->type, usage->code, value);
995 1066
996 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) 1067 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
@@ -1051,6 +1122,9 @@ int hidinput_connect(struct hid_device *hid)
1051 int i, j, k; 1122 int i, j, k;
1052 int max_report_type = HID_OUTPUT_REPORT; 1123 int max_report_type = HID_OUTPUT_REPORT;
1053 1124
1125 if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT)
1126 return -1;
1127
1054 INIT_LIST_HEAD(&hid->inputs); 1128 INIT_LIST_HEAD(&hid->inputs);
1055 1129
1056 for (i = 0; i < hid->maxcollection; i++) 1130 for (i = 0; i < hid->maxcollection; i++)