Re: [PATCH v2] Input: Fix the HID usage of DPAD input event generation.

From: Benjamin Tissoires
Date: Mon Nov 02 2020 - 03:16:44 EST


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
>