aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2007-08-09 07:24:11 -0400
committerJiri Kosina <jkosina@suse.cz>2007-10-14 07:40:00 -0400
commit1fe8736da695c2b14961438c73d5600538bd92d9 (patch)
treeb3c920eacd9a017a63abf74973a6be331ab4271f
parent4dc21a8005216ee3784df545f028775242c6f499 (diff)
HID: add support for Microsoft Natural Ergonomic Keyboard 4000
This keyboard emits a few usages that are not handled properly by hid-input. The usages from MSVENDOR page are colliding with Chicony Tactical Pad device, so we have to distinguish in runtime. Ugly ... Also, the buttons 1-5 have to be handled in a non-standard way, as they are emitted by the keyboard in a bitfield-like fashion, but the field is not presented as bit-field by the keyboard. The keys can't be pressed simultaneously, so the handling we have is correct. This patch also extends hid_keyboard[] with KPLeftParenthesis and KPRightParenthesis as defined by Keyboard page in HUT 1.12. The corresponding usages are also emitted by this keyboard. Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-debug.c2
-rw-r--r--drivers/hid/hid-input.c52
2 files changed, 50 insertions, 4 deletions
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index a13757b78980..27e4cf003834 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -697,7 +697,7 @@ static char *keys[KEY_MAX + 1] = {
697 [KEY_DEL_LINE] = "DeleteLine", 697 [KEY_DEL_LINE] = "DeleteLine",
698 [KEY_SEND] = "Send", [KEY_REPLY] = "Reply", 698 [KEY_SEND] = "Send", [KEY_REPLY] = "Reply",
699 [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save", 699 [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save",
700 [KEY_DOCUMENTS] = "Documents", 700 [KEY_DOCUMENTS] = "Documents", [KEY_SPELLCHECK] = "SpellCheck",
701 [KEY_FN] = "Fn", [KEY_FN_ESC] = "Fn+ESC", 701 [KEY_FN] = "Fn", [KEY_FN_ESC] = "Fn+ESC",
702 [KEY_FN_1] = "Fn+1", [KEY_FN_2] = "Fn+2", 702 [KEY_FN_1] = "Fn+1", [KEY_FN_2] = "Fn+2",
703 [KEY_FN_B] = "Fn+B", [KEY_FN_D] = "Fn+D", 703 [KEY_FN_B] = "Fn+B", [KEY_FN_D] = "Fn+D",
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 8edbd30cf795..00f326012a31 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_NEK4K(x) (x->vendor == 0x045e && x->product == 0x00db)
92
89#ifdef CONFIG_USB_HIDINPUT_POWERBOOK 93#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
90 94
91struct hidinput_key_translation { 95struct hidinput_key_translation {
@@ -614,6 +618,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
614 case 0x19e: map_key_clear(KEY_COFFEE); break; 618 case 0x19e: map_key_clear(KEY_COFFEE); break;
615 case 0x1a6: map_key_clear(KEY_HELP); break; 619 case 0x1a6: map_key_clear(KEY_HELP); break;
616 case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; 620 case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
621 case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
617 case 0x1bc: map_key_clear(KEY_MESSENGER); break; 622 case 0x1bc: map_key_clear(KEY_MESSENGER); break;
618 case 0x1bd: map_key_clear(KEY_INFO); break; 623 case 0x1bd: map_key_clear(KEY_INFO); break;
619 case 0x201: map_key_clear(KEY_NEW); break; 624 case 0x201: map_key_clear(KEY_NEW); break;
@@ -720,8 +725,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
720 725
721 case HID_UP_MSVENDOR: 726 case HID_UP_MSVENDOR:
722 727
723 /* special case - Chicony Chicony KU-0418 tactical pad */ 728 /* Unfortunately, there are multiple devices which
724 if (device->vendor == 0x04f2 && device->product == 0x0418) { 729 * emit usages from MSVENDOR page that require different
730 * handling. If this list grows too much in the future,
731 * more general handling will have to be introduced here
732 * (i.e. another blacklist).
733 */
734
735 /* Chicony Chicony KU-0418 tactical pad */
736 if (IS_CHICONY_TACTICAL_PAD(device)) {
725 set_bit(EV_REP, input->evbit); 737 set_bit(EV_REP, input->evbit);
726 switch(usage->hid & HID_USAGE) { 738 switch(usage->hid & HID_USAGE) {
727 case 0xff01: map_key_clear(BTN_1); break; 739 case 0xff01: map_key_clear(BTN_1); break;
@@ -737,6 +749,20 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
737 case 0xff0b: map_key_clear(BTN_B); break; 749 case 0xff0b: map_key_clear(BTN_B); break;
738 default: goto ignore; 750 default: goto ignore;
739 } 751 }
752
753 /* Microsoft Natural Ergonomic Keyboard 4000 */
754 } else if (IS_MS_NEK4K(device)) {
755 switch(usage->hid & HID_USAGE) {
756 case 0xff05:
757 set_bit(EV_REP, input->evbit);
758 map_key_clear(BTN_0);
759 set_bit(BTN_1, input->keybit);
760 set_bit(BTN_2, input->keybit);
761 set_bit(BTN_3, input->keybit);
762 set_bit(BTN_4, input->keybit);
763 set_bit(BTN_5, input->keybit);
764 default: goto ignore;
765 }
740 } else { 766 } else {
741 goto ignore; 767 goto ignore;
742 } 768 }
@@ -991,6 +1017,26 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
991 return; 1017 return;
992 } 1018 }
993 1019
1020 /* Handling MS NEK4K special buttons */
1021 if (IS_MS_NEK4K(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
1022 int key = 0;
1023 static int last_key = 0;
1024 switch (value) {
1025 case 0x01: key = BTN_1; break;
1026 case 0x02: key = BTN_2; break;
1027 case 0x04: key = BTN_3; break;
1028 case 0x08: key = BTN_4; break;
1029 case 0x10: key = BTN_5; break;
1030 default: break;
1031 }
1032 if (key) {
1033 input_event(input, usage->type, key, 1);
1034 last_key = key;
1035 } else {
1036 input_event(input, usage->type, last_key, 0);
1037 }
1038 }
1039
994 input_event(input, usage->type, usage->code, value); 1040 input_event(input, usage->type, usage->code, value);
995 1041
996 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) 1042 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))