Review of patch for MS USB keyboard
"Khelben Blackstaff" <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello.
I recently bought a Microsoft Wireless Laser Keyboard 6000 v2.0 (in
set with a mouse).
It has the usual 104 keys and 25 extra keys.
(PlayPause, Previous, Next, Mute, VolUp/Down, 1-5, Favorites, Back, Forward,
Documents,HomePage, Camera, Mail, Sound, Phone, Zoom In/Out, Gadget
button, Calc,
Lock Screen)
When i connected the wireless receiver in the usb port, i ran showkey
to see if the extra keys
work. Most of them did work, but Camera, Sound,Phone, Gadget,1-5,Favorites, Lock
didn't work.
I tried to use evtest and getkeycodes to read the missing scancodes as
most howtos
mention for usb keyboards. They didn't work and after googling i
learned about the
keyboards using hid codes. To make a long story short, i found an old
patch for Natural
keyboard and a newer/better version included in mr. Morton's
2.6.23-rc6-mm1 patchset.
I modified it to include my keys too. Microsoft's "USB HID to PS/2
Translation Table"
is rather old and didn't have most of the keys so i enabled hid
debugging support
and found the hid codes from there.
I have made two patches one for 2.6.22 kernel and one for 2.6.23-rc6-mm1.
I will try to explain what i modified from the 2.6.23-rc6-mm1 patch.
1 hunk) I included my keyboard (subid f9) in the matching
2 hunk) Added HID code 0x182 which is the Favorites key.
At first i named it KEY_FAVORITES but found out that
keycodes > 255 don't work
in the X server so renamed it to KEY_BOOKMARKS
3 hunk) Added HID code 0x19c which is the lock key. I didn't find any
name for this
so i named it KEY_COMPUTER. Also i changed KEY_SPELLCHECK to
KEY_FIND because KEY_SPELLCHECK > 255 . I know KEY_FIND itsn't right
but just till X supports larger keycodes.
Added HID codes 0x1b6,0x1b7 which are the Camera(Media) and Sound
buttons
4 hunk) Changed Zoom In/Out to Scroll Up/Down again due to the 255 issue. (Also
Scroll is more useful than zoom i guess.
5 hunk) This is the original part from the mm patch with the following changes.
a) I noticed that the "phone" and "gadget" keys didn't
emit a hid code but some
weird sequence which was similar to the ff05 that the
1-5 buttons emit. The
significant of the seqence were fd06 for the gadget
button (i named it chat)
and the fd07 for the phone buttons. For the ff05
sequence there is another
part of code later which i didn't use so i hope this
is correct. They work fine
though.
b) I didn't understand what the set_bit(BTN_X) do. The
keys work even with it
commented, so i commented. I guess it is there for a
reason so maybe my
commenting is wrong.
6 hunk) Changed BTN_1-5 to F13-F17 again due to > 255 for the keys to work in X
I use my box with this patch for some time and it didn't crash or
anything bad happen.
Because i haven't any knowledge about event interface please check if
my patch is
correct and if it is ok in order to be included in the mainline kernel.
With it applied all the keys work perfectly.
/proc/bus/usb/devices:
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=1.5 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=045e ProdID=00f9 Rev= 0.02
S: Manufacturer=Microsft
S: Product=Microsoft Wireless Desktop Receiver 3.1
C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms
I:* If#= 1 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid
E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=10ms
/proc/bus/input/devices:
I: Bus=0003 Vendor=045e Product=00f9 Version=0111
N: Name="Microsft Microsoft Wireless Desktop Receiver 3.1"
P: Phys=usb-0000:00:1c.1-1/input0
S: Sysfs=/class/input/input2
U: Uniq=
H: Handlers=kbd event2
B: EV=120003
B: KEY=10000 7 ff800000 7ff febeffdf f3cfffff ffffffff fffffffe
B: LED=107
I: Bus=0003 Vendor=045e Product=00f9 Version=0111
N: Name="Microsft Microsoft Wireless Desktop Receiver 3.1"
P: Phys=usb-0000:00:1c.1-1/input1
S: Sysfs=/class/input/input3
U: Uniq=
H: Handlers=kbd mouse0 event3
B: EV=10000f
B: KEY=7ff3 2c3027 bf004440 0 c000000 1f0000 10f84 8937c407 ffe77bfa f971dfff fe
beffdf ffefffff ffffffff fffffffe
B: REL=fc3
B: ABS=ffffff01 701ff
One event for keyboard and one for extra keys and mouse.
I am sorry if i made you tired with my long post and thank you for your time.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
from_2.6.22.diff
(application/octet-stream, 4.7 KB)
--- hid-input.orig 2007-09-21 10:47:49.000000000 +0300
+++ hid-input.c 2007-09-21 10:59:24.000000000 +0300
@@ -73,6 +73,10 @@
#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
+/* hardware needing special handling due to colliding MSVENDOR page usages */
+#define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418)
+#define IS_MS_NEK4K(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
+
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
struct hidinput_key_translation {
@@ -566,6 +570,7 @@
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_BOOKMARKS); break;
case 0x183: map_key_clear(KEY_CONFIG); break;
case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
case 0x185: map_key_clear(KEY_EDITOR); break;
@@ -582,9 +587,13 @@
case 0x192: map_key_clear(KEY_CALC); break;
case 0x194: map_key_clear(KEY_FILE); break;
case 0x196: map_key_clear(KEY_WWW); break;
+ case 0x19c: map_key_clear(KEY_COMPUTER); break;
case 0x19e: map_key_clear(KEY_COFFEE); break;
case 0x1a6: map_key_clear(KEY_HELP); break;
case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
+ case 0x1ab: map_key_clear(KEY_FIND); break;
+ case 0x1b6: map_key_clear(KEY_MEDIA); break;
+ case 0x1b7: map_key_clear(KEY_SOUND); break;
case 0x1bc: map_key_clear(KEY_MESSENGER); break;
case 0x1bd: map_key_clear(KEY_INFO); break;
case 0x201: map_key_clear(KEY_NEW); break;
@@ -605,8 +614,8 @@
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_ZOOMIN); break;
- case 0x22e: map_key_clear(KEY_ZOOMOUT); break;
+ case 0x22d: map_key_clear(KEY_SCROLLUP); break;
+ case 0x22e: map_key_clear(KEY_SCROLLDOWN); break;
case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
case 0x233: map_key_clear(KEY_SCROLLUP); break;
case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
@@ -688,7 +697,55 @@
break;
case HID_UP_MSVENDOR:
- goto ignore;
+
+ /* Unfortunately, there are multiple devices which
+ * emit usages from MSVENDOR page that require different
+ * handling. If this list grows too much in the future,
+ * more general handling will have to be introduced here
+ * (i.e. another blacklist).
+ */
+
+ /* Chicony Chicony KU-0418 tactical pad */
+ if (IS_CHICONY_TACTICAL_PAD(device)) {
+ set_bit(EV_REP, input->evbit);
+ switch(usage->hid & HID_USAGE) {
+ case 0xff01: map_key_clear(BTN_1); break;
+ case 0xff02: map_key_clear(BTN_2); break;
+ case 0xff03: map_key_clear(BTN_3); break;
+ case 0xff04: map_key_clear(BTN_4); break;
+ case 0xff05: map_key_clear(BTN_5); break;
+ case 0xff06: map_key_clear(BTN_6); break;
+ case 0xff07: map_key_clear(BTN_7); break;
+ case 0xff08: map_key_clear(BTN_8); break;
+ case 0xff09: map_key_clear(BTN_9); break;
+ case 0xff0a: map_key_clear(BTN_A); break;
+ case 0xff0b: map_key_clear(BTN_B); break;
+ default: goto ignore;
+ }
+
+ /* Microsoft Natural Ergonomic Keyboard 4000 */
+ } else if (IS_MS_NEK4K(device)) {
+ switch(usage->hid & HID_USAGE) {
+ case 0xfd06:
+ map_key_clear(KEY_CHAT);
+ break;
+ case 0xfd07:
+ map_key_clear(KEY_PHONE);
+ break;
+ case 0xff05:
+ set_bit(EV_REP, input->evbit);
+ map_key_clear(BTN_0);
+ /*set_bit(BTN_1, input->keybit);
+ set_bit(BTN_2, input->keybit);
+ set_bit(BTN_3, input->keybit);
+ set_bit(BTN_4, input->keybit);
+ set_bit(BTN_5, input->keybit);*/
+ default: goto ignore;
+ }
+ } else {
+ goto ignore;
+ }
+ break;
case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
@@ -908,6 +965,26 @@
if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
return;
+ /* Handling MS NEK4K special buttons */
+ if (IS_MS_NEK4K(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
+ int key = 0;
+ static int last_key = 0;
+ switch (value) {
+ case 0x01: key = KEY_F13; break;
+ case 0x02: key = KEY_F14; break;
+ case 0x04: key = KEY_F15; break;
+ case 0x08: key = KEY_F16; break;
+ case 0x10: key = KEY_F17; break;
+ default: break;
+ }
+ if (key) {
+ input_event(input, usage->type, key, 1);
+ last_key = key;
+ } else {
+ input_event(input, usage->type, last_key, 0);
+ }
+ }
+
input_event(input, usage->type, usage->code, value);
if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
from_2.6.23-rc6-mm1.diff
(application/octet-stream, 3.2 KB)
--- hid-input.orig 2007-09-20 11:13:14.000000000 +0300
+++ hid-input.c 2007-09-21 10:46:01.000000000 +0300
@@ -88,7 +88,7 @@
/* hardware needing special handling due to colliding MSVENDOR page usages */
#define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418)
-#define IS_MS_NEK4K(x) (x->vendor == 0x045e && x->product == 0x00db)
+#define IS_MS_NEK4K(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
@@ -606,6 +606,7 @@
case 0x0f6: map_key_clear(KEY_NEXT); break;
case 0x0fa: map_key_clear(KEY_BACK); break;
+ case 0x182: map_key_clear(KEY_BOOKMARKS); break;
case 0x183: map_key_clear(KEY_CONFIG); break;
case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
case 0x185: map_key_clear(KEY_EDITOR); break;
@@ -622,10 +623,13 @@
case 0x192: map_key_clear(KEY_CALC); break;
case 0x194: map_key_clear(KEY_FILE); break;
case 0x196: map_key_clear(KEY_WWW); break;
+ case 0x19c: map_key_clear(KEY_COMPUTER); break;
case 0x19e: map_key_clear(KEY_COFFEE); break;
case 0x1a6: map_key_clear(KEY_HELP); break;
case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
- case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
+ case 0x1ab: map_key_clear(KEY_FIND); break;
+ case 0x1b6: map_key_clear(KEY_MEDIA); break;
+ case 0x1b7: map_key_clear(KEY_SOUND); break;
case 0x1bc: map_key_clear(KEY_MESSENGER); break;
case 0x1bd: map_key_clear(KEY_INFO); break;
case 0x201: map_key_clear(KEY_NEW); break;
@@ -648,8 +652,8 @@
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_ZOOMIN); break;
- case 0x22e: map_key_clear(KEY_ZOOMOUT); break;
+ case 0x22d: map_key_clear(KEY_SCROLLUP); break;
+ case 0x22e: map_key_clear(KEY_SCROLLDOWN); break;
case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
case 0x233: map_key_clear(KEY_SCROLLUP); break;
case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
@@ -760,14 +764,20 @@
/* Microsoft Natural Ergonomic Keyboard 4000 */
} else if (IS_MS_NEK4K(device)) {
switch(usage->hid & HID_USAGE) {
+ case 0xfd06:
+ map_key_clear(KEY_CHAT);
+ break;
+ case 0xfd07:
+ map_key_clear(KEY_PHONE);
+ break;
case 0xff05:
set_bit(EV_REP, input->evbit);
map_key_clear(BTN_0);
- set_bit(BTN_1, input->keybit);
+ /*set_bit(BTN_1, input->keybit);
set_bit(BTN_2, input->keybit);
set_bit(BTN_3, input->keybit);
set_bit(BTN_4, input->keybit);
- set_bit(BTN_5, input->keybit);
+ set_bit(BTN_5, input->keybit);*/
default: goto ignore;
}
} else {
@@ -1034,11 +1044,11 @@
int key = 0;
static int last_key = 0;
switch (value) {
- case 0x01: key = BTN_1; break;
- case 0x02: key = BTN_2; break;
- case 0x04: key = BTN_3; break;
- case 0x08: key = BTN_4; break;
- case 0x10: key = BTN_5; break;
+ case 0x01: key = KEY_F13; break;
+ case 0x02: key = KEY_F14; break;
+ case 0x04: key = KEY_F15; break;
+ case 0x08: key = KEY_F16; break;
+ case 0x10: key = KEY_F17; break;
default: break;
}
if (key) {