[PATCH] usb: Key codes for Microsoft Natural Ergonomic 4000 USB keyboard

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: John Zaitseff <[email protected]>

The following patch to Linux kernel 2.6.16-rc5 enables the extra
keys found on the Microsoft Natural Ergonomic 4000 USB keyboard.  I
had to add a number of keycodes to include/linux/input.h; feel free
to reallocate IDs assigned to these new keys.

Main changes:

* Enabled the use of the extra "(" and ")" in the top right-hand
  part of the keyboard, above the keypad

* Map the zoom slider to KEY_ZOOMPLUS and KEY_ZOOMMINUS (they are
  actually keypresses)

* Map the F1-F12 keys to appropriate keys when the F Lock is off
  (this is quite easy as the keyboard already generates different
  USB key events)

* Map the five buttons above My Favorites to KEY_FN_F1 to KEY_FN_F5

I am not sure that I have done the last of these changes correctly:
the keyboard returns a usage->hid of (HID_UP_MSVENDOR | 0xff05)
whenever any of the five keys are pressed or let go (as well as at
certain other times, when the value is 0):

  value = 0x00  --->  none of the five keys are pressed
  value = 0x01  --->  key 1 is pressed
  value = 0x02  --->  key 2 is pressed
  value = 0x04  --->  key 3 is pressed
  value = 0x08  --->  key 4 is pressed
  value = 0x10  --->  key 5 is pressed

Note that although this looks like a bitfield, multiple keys CANNOT
in effect be pressed simultaneously: only one of these six values is
ever returned (as tested).

Please apply if at all possible!  Please CC me on any discussion, as
I am not subscribed to the mailing lists.

Signed-off-by: John Zaitseff <[email protected]>
---

 drivers/usb/input/hid-debug.h |    7 +++---
 drivers/usb/input/hid-input.c |   45 +++++++++++++++++++++++++++++++++++++++---
 drivers/usb/input/usbkbd.c    |    2 -
 include/linux/input.h         |    3 ++
 4 files changed, 50 insertions(+), 7 deletions(-)


diff -ruNp linux-2.6.16-rc5/drivers/usb/input/hid-debug.h linux-2.6.16-rc5.patched/drivers/usb/input/hid-debug.h
--- linux-2.6.16-rc5/drivers/usb/input/hid-debug.h	2006-02-27 16:09:35.000000000 +1100
+++ linux-2.6.16-rc5.patched/drivers/usb/input/hid-debug.h	2006-03-02 10:48:49.000000000 +1100
@@ -675,9 +675,10 @@ static char *keys[KEY_MAX + 1] = {
 	[KEY_SLOW] = "Slow",			[KEY_SHUFFLE] = "Shuffle",
 	[KEY_BREAK] = "Break",			[KEY_PREVIOUS] = "Previous",
 	[KEY_DIGITS] = "Digits",		[KEY_TEEN] = "TEEN",
-	[KEY_TWEN] = "TWEN",			[KEY_DEL_EOL] = "DeleteEOL",
-	[KEY_DEL_EOS] = "DeleteEOS",		[KEY_INS_LINE] = "InsertLine",
-	[KEY_DEL_LINE] = "DeleteLine",
+	[KEY_TWEN] = "TWEN",			[KEY_ZOOMPLUS] = "ZoomPlus",
+	[KEY_ZOOMMINUS] = "ZoomMinus",		[KEY_SPELL] = "Spell",
+	[KEY_DEL_EOL] = "DeleteEOL",		[KEY_DEL_EOS] = "DeleteEOS",
+	[KEY_INS_LINE] = "InsertLine",		[KEY_DEL_LINE] = "DeleteLine",
 	[KEY_SEND] = "Send",			[KEY_REPLY] = "Reply",
 	[KEY_FORWARDMAIL] = "ForwardMail",	[KEY_SAVE] = "Save",
 	[KEY_DOCUMENTS] = "Documents",
diff -ruNp linux-2.6.16-rc5/drivers/usb/input/hid-input.c linux-2.6.16-rc5.patched/drivers/usb/input/hid-input.c
--- linux-2.6.16-rc5/drivers/usb/input/hid-input.c	2006-02-27 16:09:35.000000000 +1100
+++ linux-2.6.16-rc5.patched/drivers/usb/input/hid-input.c	2006-03-02 13:47:00.000000000 +1100
@@ -51,7 +51,7 @@ static const unsigned char hid_keyboard[
 	115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
 	122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
 	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
-	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
+	unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
 	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
 	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
 	 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
@@ -426,12 +426,16 @@ static void hidinput_configure_usage(str
 				case 0x0e5: map_key_clear(KEY_BASSBOOST);	break;
 				case 0x0e9: map_key_clear(KEY_VOLUMEUP);	break;
 				case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
+				case 0x182: map_key_clear(KEY_FAVORITES);	break;
 				case 0x183: map_key_clear(KEY_CONFIG);		break;
 				case 0x18a: map_key_clear(KEY_MAIL);		break;
 				case 0x192: map_key_clear(KEY_CALC);		break;
 				case 0x194: map_key_clear(KEY_FILE);		break;
 				case 0x1a7: map_key_clear(KEY_DOCUMENTS);	break;
+				case 0x1ab: map_key_clear(KEY_SPELL);		break;
 				case 0x201: map_key_clear(KEY_NEW);		break;
+				case 0x202: map_key_clear(KEY_OPEN);		break;
+				case 0x203: map_key_clear(KEY_CLOSE);		break;
 				case 0x207: map_key_clear(KEY_SAVE);		break;
 				case 0x208: map_key_clear(KEY_PRINT);		break;
 				case 0x209: map_key_clear(KEY_PROPS);		break;
@@ -446,6 +450,8 @@ static void hidinput_configure_usage(str
 				case 0x226: map_key_clear(KEY_STOP);		break;
 				case 0x227: map_key_clear(KEY_REFRESH);		break;
 				case 0x22a: map_key_clear(KEY_BOOKMARKS);	break;
+				case 0x22d: map_key_clear(KEY_ZOOMPLUS);	break;
+				case 0x22e: map_key_clear(KEY_ZOOMMINUS);	break;
 				case 0x233: map_key_clear(KEY_SCROLLUP);	break;
 				case 0x234: map_key_clear(KEY_SCROLLDOWN);	break;
 				case 0x238: map_rel(REL_HWHEEL);		break;
@@ -483,8 +489,23 @@ static void hidinput_configure_usage(str
 			}
 			break;
 
-		case HID_UP_MSVENDOR:
-			goto ignore;
+		case HID_UP_MSVENDOR: /* Reported on MS Natural Ergonomic 4000 USB keyboard */
+
+			set_bit(EV_REP, input->evbit);
+			switch(usage->hid & HID_USAGE) {
+				case 0xff05:
+					/* The Favourites 1-5 keys */
+					map_key_clear(KEY_FN);
+					clear_bit(KEY_FN_F1, input->keybit);
+					clear_bit(KEY_FN_F2, input->keybit);
+					clear_bit(KEY_FN_F3, input->keybit);
+					clear_bit(KEY_FN_F4, input->keybit);
+					clear_bit(KEY_FN_F5, input->keybit);
+					break;
+
+				default:    goto ignore;
+			}
+			break;
 
 		case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
 
@@ -655,6 +676,24 @@ void hidinput_hid_event(struct hid_devic
 	if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value))
 		return;
 
+	if (usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
+		unsigned int code = 0;
+
+		switch (value) {
+			case 0x01: code = KEY_FN_F1;	break;
+			case 0x02: code = KEY_FN_F2;	break;
+			case 0x04: code = KEY_FN_F3;	break;
+			case 0x08: code = KEY_FN_F4;	break;
+			case 0x10: code = KEY_FN_F5;	break;
+			default:			break;
+		}
+		if (code) {
+			input_event(input, usage->type, code, 1);
+			input_event(input, usage->type, code, 0);
+			return;
+		}
+	}
+
 	if (usage->hat_min < usage->hat_max || usage->hat_dir) {
 		int hat_dir = usage->hat_dir;
 		if (!hat_dir)
diff -ruNp linux-2.6.16-rc5/drivers/usb/input/usbkbd.c linux-2.6.16-rc5.patched/drivers/usb/input/usbkbd.c
--- linux-2.6.16-rc5/drivers/usb/input/usbkbd.c	2006-02-27 16:09:35.000000000 +1100
+++ linux-2.6.16-rc5.patched/drivers/usb/input/usbkbd.c	2006-03-02 10:44:28.000000000 +1100
@@ -58,7 +58,7 @@ static unsigned char usb_kbd_keycode[256
 	115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,
 	122,123, 90, 91, 85,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	  0,  0,  0,  0,  0,  0,179,180,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
diff -ruNp linux-2.6.16-rc5/include/linux/input.h linux-2.6.16-rc5.patched/include/linux/input.h
--- linux-2.6.16-rc5/include/linux/input.h	2006-02-27 16:09:35.000000000 +1100
+++ linux-2.6.16-rc5.patched/include/linux/input.h	2006-03-02 10:15:35.000000000 +1100
@@ -484,6 +484,9 @@ struct input_absinfo {
 #define KEY_DIGITS		0x19d
 #define KEY_TEEN		0x19e
 #define KEY_TWEN		0x19f
+#define KEY_ZOOMPLUS		0x1a0
+#define KEY_ZOOMMINUS		0x1a1
+#define KEY_SPELL		0x1a2
 
 #define KEY_DEL_EOL		0x1c0
 #define KEY_DEL_EOS		0x1c1


-- 
John Zaitseff                    ,--_|\    The ZAP Group
Phone:  +61 2 9643 7737         /      \   Sydney, Australia
E-mail: [email protected]   \_,--._*   http://www.zap.org.au/
Finger: [email protected]               v
GnuPG   fingerprint:  8FD2 8962 7768 2546 FE07  DE7C 61A8 4486 C9A6 69B0
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux