I'm working on a device emulating a USB HID gamepad with 32 buttons. This is the basic Report Descriptor I created
Usage Page(Generic Desktop)
Usage(Gamepad)
Collection(Application)
Collection(Physical)
Usage Page(Button)
Usage Minimum(1)
Usage Maximum(32)
Logical Minimum(0)
Logical Maximum(1)
Report Count(32)
Report Size(1)
Input(Data, Variable, Absolute)
End Collection
End Collection
This descriptor generally seems to work fine — a Linux USB host sees a HID gamepad, and evtest
is detecting button press/release events as I generate them.
However, I'm a bit confused by some of the output from evtest
:
user@system:~$ sudo evtest /dev/input/event3
Input driver version is 1.0.1
Input device ID: ########################
Input device name: ########################
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 304 (BTN_SOUTH)
Event code 305 (BTN_EAST)
Event Code 306 (BTN_C)
Event Code 307 (BTN_NORTH)
# Remaining 28 keys omitted
evtest
believes that my first button corresponds to "Event code 304", but I'm not really sure where this mapping is coming from.
I've skimmed through the HID specification and Usage Tables, and I can't see how a HID gamepad can define a mapping between its physical buttons and key codes understood by the input HID driver in an OS. Is it possible to specify this in the report descriptor somehow?
1 Answer 1
hidinput_configure_usage is the function that maps the HID descriptor(s) to the gamepad button codes used in the Linux input subsystem. Specifically, there's this block in that function:
case HID_GD_GAMEPAD:
if (code <= 0xf)
code += BTN_GAMEPAD;
else
code += BTN_TRIGGER_HAPPY - 0x10;
break;
These constants (e.g. BTN_GAMEPAD
) are found in input-event-codes.h.
In the case of my USB HID gamepad, I specify buttons 1 through 32. The code
referenced above is decremented from the button number (making it zero-indexed), so the 32-button gamepad falls into two button ranges:
- 16 sequential input event codes starting at
BTN_GAMEPAD
- 16 sequential input event codes starting at
BTN_TRIGGER_HAPPY
I did not include the full evtest
output in my original question, but that lines up with what I observed.
To summarize, I cannot see any way for a HID descriptor to specify the mapping to Linux event codes. The HID kernel driver has a static mapping from HID gamepad button numbers to input event codes, so the solution is to specify buttons in the HID Report Descriptor that map to the intended event codes.
There may be software to remap these events at a higher level, but that is not something that can be implemented by a generic USB HID gamepad itself.
# Remaining 28 keys omitted
... please post the full output \$\endgroup\$