0
\$\begingroup\$

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?

asked Jun 23, 2023 at 1:27
\$\endgroup\$
1
  • \$\begingroup\$ # Remaining 28 keys omitted ... please post the full output \$\endgroup\$ Commented Jun 23, 2023 at 1:31

1 Answer 1

1
\$\begingroup\$

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.

answered Jun 30, 2023 at 17:29
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.