Seitenanfang

Ubuntu 14.04 Trusty: Mapping USB keyboards

I bought a Cherry G84-4700PUCDE-2 keypad about three years ago to have some "special multimedia keys" on the left side of my keyboard. It used to work after some trying until I upgraded to Ubuntu 14.04. The "trusty" release removed support for /lib/udev/findkeys and /lib/udev/keymap and replaced both by something called "hwdb". Converting turned out to be hard, because there are many wrong hints out there spread over the internet.

HP-Keyboard-2-icon.pngMy Cherry keypad is basically an external number pad build for laptops which usually don't have a number pad but only numbers on the top of the keyboard. I don't need more numbers, but like to switch to my browser, development editor and other common tools with a single keypress. You could configure any command on those keys - if you managed to find them.

You don't imagine how many different "scancodes" each single key has. I found about ten different codes for the same key depending on which program is being used for detecting them. Finally my old scancodes workey, but it took me hours to find the correct format. But let's start at the beginning...

Get the device

The first step is easy: Use the command lsusb to get the USB vendor and device ID for the keyboard which should be reassigned:

$ lsusb
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 096: ID 046a:0014 Cherry GmbH
Bus 001 Device 094: ID 046a:0011 Cherry GmbH G83 (RS 6000) Keyboard
Bus 001 Device 005: ID 17ef:100a Lenovo ThinkPad Mini Dock Plus Series 3
Bus 001 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver

I'm using two Cherry devices: A G83 keyboard and the number pad which is located on bus 1 as device 96. Cherry's vendor id is 046a and the product id is 0014. Run lsusb once, disconnect the device, run lsusb again and compare the lists for the missing device if you're unsure which is the right one.

Create a HWDB config file

Custom HWDB config files must be placed in /etc/udev/hwdb.d and must have a .hwdb suffix. I named mine /etc/udev/hwdb.d/cherry_ML4700.hwdb (remember to create it as root, for example using sudo gedit /etc/udev/hwdb.d/cherry_ML4700.hwdb ). The file starts with the keyboard USB id (notice that all letters in the USB id must be UPPERCASE) followed by one or more key definition lines, for example:

keyboard:usb:v046Ap0014*
KEYBOARD_KEY_0x70062=mute
KEYBOARD_KEY_0x70059=calc
KEYBOARD_KEY_0x70029=prog1

The first line defines a USB keyboard match containing the vendor id, the product id and a suffix asterisk (*). The following lines must start with a leading space and contain key mappings. The first mapping redefines key 0x70062 to switch the sound output on and off. All valid key names (right to the equal sign) are listed here.

Convert a keymap file

My old keymap file used to be /etc/udev/keymaps/cherry_g84-4700 and it could be easily converted to the new mapping syntax using a simple Perl oneliner:

$ perl -ple 's/^0x(\w+)\s(\S+)/ KEYBOARD_KEY_0x$1=$2/;' </etc/udev/keymaps/cherry_g84-4700

This mini-script outputs the new format to be used in the HWDB config file.

Find the scancode of a key

I found only one tool which got the correct scancodes: getscancodes. Download it from here, unpack and make it:

$ tar -xzf getscancodes-1.0.tar.gz
$ cd getscancodes
$ make
gcc -O2 -Wall -c -o getscancodes.o getscancodes.c
gcc -o getscancodes getscancodes.o
$ ./getscancodes
Usage: ./getscancodes /dev/input/eventX
Where X = input device number

This will create the getscancodes tool - which doesn't care about USB ids. Each input device has a virtual file in /dev/input called event followed by a number. Run getscancodes on all of your /dev/input/event* files until you find your device. Press any key to get a scancode or Ctrl+C to exit.

$ sudo ./getscancodes /dev/input/event11
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x46a product 0x14 version 0x111
Input device name: "HID 046a:0014"
458850 (0x70062)
^C

The last line shows the Ctrl+C for exiting getscancodes, the line before shows a keypress of my number pad. The first number doesn't matter, but the second one 0x70062 is the one you're looking for.

Testing a HWDB change

Either reboot your computer to make your new configuration file active or run the udevadm command to update the internal database from your file and reload it into the running system:

$ sudo udevadm -d hwdb --update;sudo udevadm -d control --reload

Now unplug your USB keyboard, wait two or three seconds (or more) and plug it in again. Press the reconfigured key and you should get the action defined in the config file (I used mute for testing, because it's a visible action in Ubuntu).

Debugging

It took me three or four hours to get here. If something doesn't work - try slow steps. Reconfigure a single key first and use some easily visible action (like mute or a single letter). The definition keyboard:usb:v*p* matches all USB keyboards, you could use it to check if the keyboard is detected propaly (but be careful, it will redefine the key on all USB keyboard which might even include a builtin laptop keyboard. Redefining the C key might not be a good idea - you won't be able to type Ctrl+C any longer!)

 

Noch keine Kommentare. Schreib was dazu

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>