hid-microsoft: support for XBox Elite 2 paddles.

This commit is contained in:
Sorgelig
2026-04-08 20:13:41 +08:00
parent d5beb5aa60
commit c784a6856d

View File

@@ -9,9 +9,6 @@
* Copyright (c) 2008 Jiri Slaby
*/
/*
*/
#include <linux/device.h>
#include <linux/input.h>
#include <linux/hid.h>
@@ -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 },
{ }