diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 884706fe0..e4d9d4cdb 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -9,9 +9,6 @@ * Copyright (c) 2008 Jiri Slaby */ -/* - */ - #include #include #include @@ -27,6 +24,17 @@ #define MS_DUPLICATE_USAGES BIT(5) #define MS_SURFACE_DIAL BIT(6) #define MS_QUIRK_FF BIT(7) +#define MS_QUIRK_ELITE2_PADDLES BIT(8) + +#define MS_XBE2_TRIGSCALE_USAGE (HID_UP_CONSUMER | 0x0099) +#define MS_XBE2_PADDLE_USAGE (HID_UP_CONSUMER | 0x0081) + +#ifndef BTN_GRIPL +#define BTN_GRIPL 0x224 +#define BTN_GRIPL2 0x225 +#define BTN_GRIPR 0x226 +#define BTN_GRIPR2 0x227 +#endif struct ms_data { unsigned long quirks; @@ -203,6 +211,21 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi, return ret; } + if (quirks & MS_QUIRK_ELITE2_PADDLES) { + /* Ignore the trigger scale switch entirely */ + if (usage->hid == MS_XBE2_TRIGSCALE_USAGE) + return -1; + + if (usage->hid == MS_XBE2_PADDLE_USAGE) { + set_bit(EV_KEY, hi->input->evbit); + set_bit(BTN_GRIPL, hi->input->keybit); + set_bit(BTN_GRIPL2, hi->input->keybit); + set_bit(BTN_GRIPR, hi->input->keybit); + set_bit(BTN_GRIPR2, hi->input->keybit); + return -1; + } + } + return 0; } @@ -226,12 +249,26 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field, unsigned long quirks = ms->quirks; struct input_dev *input; + if ((quirks & MS_QUIRK_ELITE2_PADDLES) && + usage->hid == MS_XBE2_PADDLE_USAGE) { + if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput) + return 0; + input = field->hidinput->input; + input_report_key(input, BTN_GRIPL, value & BIT(2)); + input_report_key(input, BTN_GRIPL2, value & BIT(3)); + input_report_key(input, BTN_GRIPR, value & BIT(0)); + input_report_key(input, BTN_GRIPR2, value & BIT(1)); + input_sync(input); + return 1; + } + + /* All other handlers require a valid usage->type */ if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || !usage->type) return 0; input = field->hidinput->input; - + /* Handling MS keyboards special buttons */ if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) { /* Special keypad keys */ @@ -296,8 +333,8 @@ static void ms_ff_worker(struct work_struct *work) */ r->duration_10ms = U8_MAX; r->loop_count = U8_MAX; - r->magnitude[MAGNITUDE_STRONG] = ms->strong; /* left actuator */ - r->magnitude[MAGNITUDE_WEAK] = ms->weak; /* right actuator */ + r->magnitude[MAGNITUDE_STRONG] = ms->strong; + r->magnitude[MAGNITUDE_WEAK] = ms->weak; ret = hid_hw_output_report(hdev, (__u8 *)r, sizeof(*r)); if (ret < 0) @@ -451,7 +488,7 @@ static const struct hid_device_id ms_devices[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_SERIES_CONTROLLER), .driver_data = MS_QUIRK_FF }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ELITE2_CONTROLLER), - .driver_data = MS_QUIRK_FF }, + .driver_data = MS_QUIRK_FF | MS_QUIRK_ELITE2_PADDLES }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS), .driver_data = MS_QUIRK_FF }, { }