linuxinputjoystickgamepadevdev

What is the difference between /dev/input/eventX and /dev/input/jsX?


When I connect a gamepad on my Linux kernel v5.14 there are two new devices that show up:

/dev/input/event23
/dev/input/js1

If I cat <file> | xxd both device files provide gamepad event information. But event23 is much more verbose than js1.

Also, evtest gives error Invalid Argument on js1 but works fine on event23. The same happens when I use libevdev both device files.

It looks like with every event, js1 dumps the contents of an input_event struct (defined in linux/input.h)

What is the difference between the device files? Why do they have different information and what more information does event23 provide over js1?


Solution

  • /dev/input/js* devices are created by the joydev legacy joystick driver. It only supports joysticks and joystick-like devices.

    https://www.kernel.org/doc/html/latest/input/joydev/joystick.html

    /dev/input/event* devices are created by the evdev input event interface. It supports all types of input devices, not just joysticks.

    https://linux.die.net/man/4/evdev

    The joydev interface exposes a subset of the information exposed through evdev, specifically it will only expose an input if it looks like a joystick button or axis. New applications should prefer to use evdev, but joydev is usually still available.

    The "looks like a joystick button or axis" heuristic can sometimes be a problem for joydev. When a HID gamepad is connected, evdev and joydev use information in the device's HID report descriptor to detect the number of button and axis inputs. joydev only considers buttons from the HID Button usage page, but newer gamepads sometimes define special buttons with different usages. This is especially common for Android gamepads, which have non-Button usages for the Home and Back buttons. These buttons don't get picked up by joydev.

    Another big difference: joydev is purely for input. evdev supports gamepad rumble and force feedback effects.