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. 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