Hi Chris, On Sun, Nov 1, 2020 at 8:35 PM Chris Ye <lzye@xxxxxxxxxx> wrote: > > Generic Desktop DPAD usage is mapped by hid-input, that only the first > DPAD usage maps to usage type EV_ABS and code of an axis. If HID > descriptor has DPAD UP/DOWN/LEFT/RIGHT HID usages and each of usage size > is 1 bit, then only the first one will generate input event, the rest of > the HID usages will be assigned to hat direction only. > The hid input event should check the HID report value and generate > HID event for its hat direction. > > Test: Connect HID device with Generic Desktop DPAD usage and press the > DPAD to generate input events. Thanks for the patch, but I would rather have a proper tests added to https://gitlab.freedesktop.org/libevdev/hid-tools We already have gamepads tests, and it would be very nice to have this patch reflected as a test as well. This would also allow me to better understand the problem. I am not sure I follow the whole logic of this patch without seeing the 2 variants of report descriptors. Cheers, Benjamin > > Signed-off-by: Chris Ye <lzye@xxxxxxxxxx> > --- > drivers/hid/hid-input.c | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c > index 9770db624bfa..6c1007de3409 100644 > --- a/drivers/hid/hid-input.c > +++ b/drivers/hid/hid-input.c > @@ -1269,7 +1269,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct > struct input_dev *input; > unsigned *quirks = &hid->quirks; > > - if (!usage->type) > + if (!usage->type && !field->dpad) > return; > > if (usage->type == EV_PWR) { > @@ -1286,9 +1286,17 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct > int hat_dir = usage->hat_dir; > if (!hat_dir) > hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; > - if (hat_dir < 0 || hat_dir > 8) hat_dir = 0; > - input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x); > - input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); > + if (hat_dir < 0 || hat_dir > 8 || value == 0) > + hat_dir = 0; > + if (field->dpad) { > + input_event(input, EV_ABS, field->dpad, hid_hat_to_axis[hat_dir].x); > + input_event(input, EV_ABS, field->dpad + 1, hid_hat_to_axis[hat_dir].y); > + } else { > + input_event(input, usage->type, usage->code, > + hid_hat_to_axis[hat_dir].x); > + input_event(input, usage->type, usage->code + 1, > + hid_hat_to_axis[hat_dir].y); > + } > return; > } > > -- > 2.29.1.341.ge80a0c044ae-goog >