[PATCH v3 2/2] Input: xpad - introduce a static table to ignore devices

From: Denis Benato

Date: Tue Aug 11 2026 - 09:05:46 EST


Certain devices can work both as HID and as an xpad device: binding both
would duplicate inputs causing userspace to receive double inputs; at the
same time if a HID device is available it is to be preferred as it can
support additional features such as integrated IMU and additional buttons
and more, depending on the specific driver, therefore allow only the
best driver available to bind the device.

Suggested-by: Derek J. Clark <derekjohn.clark@xxxxxxxxx>
Signed-off-by: Denis Benato <denis.benato@xxxxxxxxx>
---
drivers/input/joystick/xpad.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index feb8f368f834..545119a4fb36 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -406,6 +406,18 @@ static const struct xpad_device {
{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
};

+#define XPAD_SUBSTITUTE(_vid, _pid, _enabled) \
+ { .vid = (_vid), .pid = (_pid), .enabled = (_enabled) }
+
+static const struct xpad_excluded_device {
+ u16 vid;
+ u16 pid;
+ bool enabled;
+} xpad_excluded_devices[] = {
+ XPAD_SUBSTITUTE(0x37d7, 0x2401, IS_ENABLED(CONFIG_HID_FLYDIGI)),
+ { }
+};
+
/* buttons shared with xbox and xbox360 */
static const signed short xpad_common_btn[] = {
BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */
@@ -2044,11 +2056,23 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_xpad *xpad;
struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
+ const struct xpad_excluded_device *excluded;
int i, error;

if (intf->cur_altsetting->desc.bNumEndpoints != 2)
return -ENODEV;

+ for (excluded = xpad_excluded_devices;
+ excluded->vid || excluded->pid;
+ excluded++) {
+ if (!excluded->enabled)
+ continue;
+
+ if (le16_to_cpu(udev->descriptor.idVendor) == excluded->vid &&
+ le16_to_cpu(udev->descriptor.idProduct) == excluded->pid)
+ return -ENODEV;
+ }
+
for (i = 0; xpad_device[i].idVendor; i++) {
if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
(le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
--
2.47.3