UDEV Rules for Cheap Numeric Keypads

I’m thinking of numeric keypads as control panels for Raspberry Pi projects like a simpleminded streaming radio player, so:

Numeric keypads

Numeric keypads

Sorta like wedding pictures: you can expose for the groom-in-black or the bride-in-white, but not both at the same time.

The wireless keypad does not have a slot for the USB radio: put ’em in a bag to keep ’em together when not in use.

The general idea is to create a standard name (/dev/input/keypad) for either keypad when it gets plugged in, so the program need not figure out the device name from first principles. This being an embedded system, I can ensure only one keypad will be plugged in at any one time.

The wired keypad has an odd name that makes a certain perverse sense:

cat /proc/bus/input/devices
... snippage ...
I: Bus=0003 Vendor=13ba Product=0001 Version=0110
N: Name="HID 13ba:0001"
P: Phys=usb-20980000.usb-1.4/input0
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:13BA:0001.0007/input/input6
U: Uniq=
H: Handlers=sysrq kbd event0
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff800000 7ff febeffdf f3cfffff ffffffff fffffffe
B: MSC=10
B: LED=7

It’s a single-function device, so this rule in /etc/udev/rules.d/KeyPad.rules suffices:

ATTRS{name}=="HID 13ba:0001", SYMLINK+="input/keypad"

Using the Vendor and Device ID strings (13ba:0001) might make more sense.

The wireless keypad isn’t nearly that easy, because it reports for duty as both a keyboard and a mouse:

cat /proc/bus/input/devices
... snippage ...
I: Bus=0003 Vendor=062a Product=4101 Version=0110
N: Name="MOSART Semi. 2.4G Keyboard Mouse"
P: Phys=usb-20980000.usb-1.4/input0
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:062A:4101.0008/input/input7
U: Uniq=
H: Handlers=sysrq kbd event0
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7

I: Bus=0003 Vendor=062a Product=4101 Version=0110
N: Name="MOSART Semi. 2.4G Keyboard Mouse"
P: Phys=usb-20980000.usb-1.4/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.4/1-1.4:1.1/0003:062A:4101.0009/input/input8
U: Uniq=
H: Handlers=kbd mouse0 event2
B: PROP=0
B: EV=1f
B: KEY=3f 3007f 0 0 0 0 483ffff 17aff32d bf544446 0 0 1f0001 130f93 8b17c000 677bfa d941dfed 9ed680 4400 0 10000002
B: REL=1c3
B: ABS=1f01 0
B: MSC=10

That may be because the 0x06a2 Vendor ID was cloned (that’s pronounced “ripped-off”) from Creative Labs. My guess is they ripped the entire chipset, because the 0x4101 device ID came from a Creative Labs wireless keyboard + mouse:

lsusb
... snippage ...
Bus 001 Device 011: ID 062a:4101 Creative Labs
... snippage ...

Because it’s a dual-mode wireless device, we need more information to create the corresponding udev rule. The keyboard part appears (on this boot) as event0, which we find thusly:

ll /dev/input/by-id
total 0
lrwxrwxrwx 1 root root 9 Feb  5 17:39 usb-Burr-Brown_from_TI_USB_Audio_CODEC-event-if03 -> ../event1
lrwxrwxrwx 1 root root 9 Feb  5 17:39 usb-MOSART_Semi._2.4G_Keyboard_Mouse-event-kbd -> ../event0
lrwxrwxrwx 1 root root 9 Feb  5 17:39 usb-MOSART_Semi._2.4G_Keyboard_Mouse-if01-event-mouse -> ../event2
lrwxrwxrwx 1 root root 9 Feb  5 17:39 usb-MOSART_Semi._2.4G_Keyboard_Mouse-if01-mouse -> ../mouse0

Some spelunking suggests using the environment variables set up by the default udev rules, which we find thusly:

udevadm test /sys/class/input/event0
... vast snippage ...
.INPUT_CLASS=kbd
ACTION=add
DEVLINKS=/dev/input/by-id/usb-MOSART_Semi._2.4G_Keyboard_Mouse-event-kbd /dev/input/by-path/platform-20980000.usb-usb-0:1.4:1.0-event-kbd
DEVNAME=/dev/input/event0
DEVPATH=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:062A:4101.0012/input/input17/event0
ID_BUS=usb
ID_INPUT=1
ID_INPUT_KEY=1
ID_INPUT_KEYBOARD=1
ID_MODEL=2.4G_Keyboard_Mouse
ID_MODEL_ENC=2.4G\x20Keyboard\x20Mouse
ID_MODEL_ID=4101
ID_PATH=platform-20980000.usb-usb-0:1.4:1.0
ID_PATH_TAG=platform-20980000_usb-usb-0_1_4_1_0
ID_REVISION=0108
ID_SERIAL=MOSART_Semi._2.4G_Keyboard_Mouse
ID_TYPE=hid
ID_USB_DRIVER=usbhid
ID_USB_INTERFACES=:030101:030102:
ID_USB_INTERFACE_NUM=00
ID_VENDOR=MOSART_Semi.
ID_VENDOR_ENC=MOSART\x20Semi.
ID_VENDOR_ID=062a
MAJOR=13
MINOR=64
SUBSYSTEM=input
... more snippage ...

So when that vendor and device appear with ID_INPUT_KEYBOARD set, we can create a useful symlink using this rule in /etc/udev/rules.d/KeyPad.rules:

ATTRS{idVendor}=="062a", ATTRS{idProduct}=="4101", ENV{ID_INPUT_KEYBOARD}=="1", SYMLINK+="input/keypad"

Because only one keypad will be plugged in at any one time, the /etc/udev/rules.d/KeyPad.rules file can contain both rules:

ATTRS{name}=="HID 13ba:0001", SYMLINK+="input/keypad"
ATTRS{idVendor}=="062a", ATTRS{idProduct}=="4101", ENV{ID_INPUT_KEYBOARD}=="1", SYMLINK+="input/keypad"

Reload the rules and fire them off:

sudo udevadm control --reload
sudo udevadm trigger

And then It Just Works:

ll /dev/input/by-id
total 0
lrwxrwxrwx 1 root root 9 Feb  5 17:39 usb-Burr-Brown_from_TI_USB_Audio_CODEC-event-if03 -> ../event1
lrwxrwxrwx 1 root root 9 Feb  5 19:03 usb-MOSART_Semi._2.4G_Keyboard_Mouse-event-kbd -> ../event0
lrwxrwxrwx 1 root root 9 Feb  5 19:03 usb-MOSART_Semi._2.4G_Keyboard_Mouse-if01-event-mouse -> ../event2
lrwxrwxrwx 1 root root 9 Feb  5 19:03 usb-MOSART_Semi._2.4G_Keyboard_Mouse-if01-mouse -> ../mouse0ll /dev/input

ll /dev/input
total 0
drwxr-xr-x 2 root root     120 Feb  5 19:03 by-id
drwxr-xr-x 2 root root     120 Feb  5 19:03 by-path
crw-rw---- 1 root input 13, 64 Feb  5 19:03 event0
crw-rw---- 1 root input 13, 65 Feb  5 17:39 event1
crw-rw---- 1 root input 13, 66 Feb  5 19:03 event2
lrwxrwxrwx 1 root root       6 Feb  5 19:03 keypad -> event0
crw-rw---- 1 root input 13, 63 Feb  5 17:39 mice
crw-rw---- 1 root input 13, 32 Feb  5 19:03 mouse0

My configuration hand is strong

Note: Once again, I manually restored the source code after the WordPress “improved” editor shredded it by replacing all the double-quote and greater-than symbols inside the “protected” sourcecode blocks with their HTML-escaped equivalents. Some breakage may remain and, as always, WP can shred sourcecode blocks even if I don’t edit the post. They’ve (apparently) banned me from contacting Support, because of an intemperate rant based on years of having them ignore this (and other) problems. I didn’t expect any real help, so this isn’t much of a step backwards in terms of actual support …

Advertisements

  1. #1 by celem on 2016-02-22 - 09:01

    Thanks. I’ve done a little udev work to get devices recognized but not to this degree. Most educational.

    • #2 by Ed on 2016-02-22 - 14:44

      You can actually enumerate all the devices using the Python evdev machinery, so in principle you could discover & grab the keypad without any udev trickery. However, given the hocus-pocus required for the wireless keypad, I think bottling up that mess somewhere else makes more sense… even if it the udev machinery isn’t all that transparent.

  1. Raspberry Pi: USB Keypad Via evdev | The Smell of Molten Projects in the Morning
  2. Raspberry Pi Streaming Radio Player: Minimum Viable Product | The Smell of Molten Projects in the Morning
  3. Simple Rules for Cheap Numeric Keypads in udev #Linux « Adafruit Industries – Makers, hackers, artists, designers and engineers!
  4. Raspberry Pi Streaming Radio Player: Marginally Viable Product | The Smell of Molten Projects in the Morning
  5. UDEV Rules for Dell AC511 USB Soundbar | The Smell of Molten Projects in the Morning