Ask Your Question

multimedia keys on Kinesis Freestyle 2 keyboard

asked 2013-10-01 10:57:55 -0500

jbastian gravatar image

I have a Kinesis Freestyle 2 keyboard which has 4 multimedia keys -- mute, volume-down, volume-up, and calculator -- for Fn-F8 through Fn-F11, but the keys do not work on Fedora 19.

I tried monitoring for keyboard events with xev, evtest, showkey, and acpi_listen, and I get nothing from any of the utilities.

I noticed, however, that evtest reported I have two inputs for the keyboard:

~]# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event6:      KINESIS FREESTYLE KB700 KB700 Kinesis Freestyle
/dev/input/event7:      KINESIS FREESTYLE KB700 KB700 Kinesis Freestyle

I know very little about USB internals, but apparently this is because the standard keys are USB HID Code Page 0x07, whereas the multimedia keys are HID Code Page 0x0C, so the single keyboard actually appears somewhat like two devices?

I then tried usbmon on the bus and I finally got some feedback when I hit the keys.

~]# grep -B3 KINESIS /sys/kernel/debug/usb/devices
T:  Bus=02 Lev=03 Prnt=03 Port=02 Cnt=02 Dev#=  6 Spd=1.5  MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=058f ProdID=9410 Rev= 1.22
S:  Manufacturer=KINESIS FREESTYLE KB700

~]# usbmon -i 2
2f822d80 0.990223 C Ii:2:006:1 0:8 8 =
    00000000 00000000                 
2f822d80 0.990288 S Ii:2:006:1 -:8 8 <
2f17e900 3.335277 C Ii:2:006:2 0:128 3 =
2f17e900 3.335290 S Ii:2:006:2 -:128 3 <
2f17e900 3.463266 C Ii:2:006:2 0:128 3 =
2f17e900 3.463279 S Ii:2:006:2 -:128 3 <
2f17e900 7.559341 C Ii:2:006:2 0:128 3 =
2f17e900 7.559355 S Ii:2:006:2 -:128 3 <
2f17e900 7.687337 C Ii:2:006:2 0:128 3 =

As a quick sanity check, I tried the keyboard on a Mac and the volume keys worked, so OS X knows what to do with the key events, but something in Linux is either blocking the events from being sent up to userspace, or the events are simply ignored.

Finally, I emailed Kinesis tech support and they replied:

The HID Usage ID for the multi-media keys in our Freestyle2 keyboard are:
Mute = E2
Volume Down = EA
Volume Up = E9
Calculator = 92

Kinesis even offered to burn a new firmware to my keyboard if I can tell them if the codes should be different for Linux, but I think this is something that can be solved in software. I just need the events sent up to userspace and then I can map them to the XF86AudioMute, XF86AudioLowerVolume, XF86AudioRaiseVolume, and XF86Calculator using setxkbmap or xmodmap.

What might be blocking/ignoring the key press events?

edit retag flag offensive close merge delete


I have same keyboard and have not gotten the volume keys to work in Linux. Have you found how to solve this problem later? If you have, can you answer your own question here?

joelmo gravatar imagejoelmo ( 2016-04-14 04:06:17 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2017-11-07 11:02:42 -0500

TL;DR: The output from the function keys is understood by the lower level input driver stack in the kernel, but gets lost before the layer where keyboard events are emitted to userspace. You can work around this with a userspace driver.

I also have a Kinesis Freestyle 2, and I used your question as the foundation for a couple days of debugging this issue. As you state, there is output on the USB bus itself when using usbmon, but evtest doesn't emit anything when you try to use the /dev/input/eventX file for the keyboard's function keys (the second one for the 0xC HID Code page).

However, if you trace the /dev/hidrawX file that is created when you plug the keyboard in, the special function keys actually emit output. Try:

sudo od --width=2 -x /dev/hidrawX

Use whichever hidraw file corresponds to your keyboard and then press a few keys. You should see 3 bytes of hex-encoded output each time.

As far as I can tell, the usbhid driver reads the keyboard correctly and is responsible for creating this functional hidraw device. However, there's another driver called hid-generic that takes the output of usbhid and interprets it as input from a Human Interface Device that is used to generate the /dev/input/eventX files. hid-generic seems to not understand the data coming from the function keys and therefore never emits keypress events for that input.

I don't think that I'm up to debugging hid-generic, so I wrote a userspace driver that can open the /dev/hidrawX file and uses uinput to create a virtual keyboard. When you press one of the function keys, the userspace driver extracts the HID Usage ID from the 3-byte packet that comes out of the hidrawX file and then maps that to the appropriate input key on the virtual keyboard. You can find the source code here.

I documented the debugging process for this in a sequence of blog posts here if you're interested in how I came to this solution.

edit flag offensive delete link more


This looks great! Well done.

ahmadj gravatar imageahmadj ( 2017-11-10 10:14:48 -0500 )edit

Question Tools


Asked: 2013-10-01 10:57:55 -0500

Seen: 1,712 times

Last updated: Oct 01 '13