Thread (5 messages) 5 messages, 2 authors, 11d ago
DORMANTno replies

[PATCH v3] Input: xpad - add support for Azeron devices

From: Roberts Kursitis <hidden>
Date: 2026-06-19 14:23:02
Also in: lkml
Subsystem: input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers: Dmitry Torokhov, Linus Torvalds

Add USB Vendor and Product IDs for the Azeron devices (Cyro, Cyborg,
Classic/Compact, Cyro Lefty, Cyborg II and Keyzen). These devices share
a firmware XInput implementation and expose the standard Xbox 360
interface signature.

Note that 0x16d0 is a shared vendor block (MCS Electronics / pid.codes
allocations), but binding here is safe as the XPAD_XBOX360_VENDOR macro
only binds interfaces presenting the strict Xbox 360 signature.

These devices reject Xbox 360 LED and rumble magic packets with a
stall (-EPIPE). Add FLAG_NO_LED and FLAG_NO_RUMBLE device flags,
set on all Azeron entries, so xpad_led_probe() and xpad_init_ff()
skip LED and force-feedback initialization for them.

Signed-off-by: Roberts Kursitis <redacted>
---
v2 -> v3:
 - Move 0x16d0 entries after 0x1689 to keep both tables sorted by
   vendor ID
 - Move quirks from the mapping field to the flags field; mapping is
   u8 and the new bits overflowed it
 - Add FLAG_NO_RUMBLE; these devices stall on rumble packets too

 drivers/input/joystick/xpad.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index feb8f368f..405fcd5e9 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -72,6 +72,9 @@
 #define PKT_XBE2_FW_5_11    4
 
 #define FLAG_DELAY_INIT BIT(0)
+#define FLAG_NO_LED	BIT(1)
+#define FLAG_NO_RUMBLE	BIT(2)
+#define FLAG_NO_LED_RUMBLE	(FLAG_NO_LED | FLAG_NO_RUMBLE)
 
 static bool dpad_to_buttons;
 module_param(dpad_to_buttons, bool, S_IRUGO);
@@ -292,6 +295,12 @@ static const struct xpad_device {
 	{ 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 },
 	{ 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 },
 	{ 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+	{ 0x16d0, 0x1103, "Azeron Cyro", 0, XTYPE_XBOX360, FLAG_NO_LED_RUMBLE },
+	{ 0x16d0, 0x113c, "Azeron Cyborg", 0, XTYPE_XBOX360, FLAG_NO_LED_RUMBLE },
+	{ 0x16d0, 0x1192, "Azeron Classic/Compact", 0, XTYPE_XBOX360, FLAG_NO_LED_RUMBLE },
+	{ 0x16d0, 0x1212, "Azeron Cyro Lefty", 0, XTYPE_XBOX360, FLAG_NO_LED_RUMBLE },
+	{ 0x16d0, 0x12f7, "Azeron Cyborg II", 0, XTYPE_XBOX360, FLAG_NO_LED_RUMBLE },
+	{ 0x16d0, 0x13ea, "Azeron Keyzen", 0, XTYPE_XBOX360, FLAG_NO_LED_RUMBLE },
 	{ 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 },
 	{ 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 },
 	{ 0x1a86, 0xe310, "Legion Go S", 0, XTYPE_XBOX360 },
@@ -533,6 +542,7 @@ static const struct usb_device_id xpad_table[] = {
 	XPAD_XBOX360_VENDOR(0x15e4),		/* Numark Xbox 360 controllers */
 	XPAD_XBOX360_VENDOR(0x162e),		/* Joytech Xbox 360 controllers */
 	XPAD_XBOX360_VENDOR(0x1689),		/* Razer Onza */
+	XPAD_XBOX360_VENDOR(0x16d0),		/* Azeron controllers */
 	XPAD_XBOX360_VENDOR(0x17ef),		/* Lenovo */
 	XPAD_XBOX360_VENDOR(0x1949),		/* Amazon controllers */
 	XPAD_XBOX360_VENDOR(0x1a86),		/* Nanjing Qinheng Microelectronics (WCH) */
@@ -776,6 +786,8 @@ struct usb_xpad {
 	const char *name;		/* name of the device */
 	struct work_struct work;	/* init/remove device from callback */
 	time64_t mode_btn_down_ts;
+	bool no_led;			/* device stalls on LED packets */
+	bool no_rumble;			/* device stalls on rumble packets */
 	bool delay_init;		/* init packets should be delayed */
 	bool delayed_init_done;
 };
@@ -1615,6 +1627,9 @@ static int xpad_init_ff(struct usb_xpad *xpad)
 	if (xpad->xtype == XTYPE_UNKNOWN)
 		return 0;
 
+	if (xpad->no_rumble)
+		return 0;
+
 	input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
 
 	return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
@@ -1719,6 +1734,9 @@ static int xpad_led_probe(struct usb_xpad *xpad)
 	struct led_classdev *led_cdev;
 	int error;
 
+	if (xpad->no_led)
+		return 0;
+
 	if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W)
 		return 0;
 
@@ -2082,6 +2100,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 	xpad->name = xpad_device[i].name;
 	if (xpad_device[i].flags & FLAG_DELAY_INIT)
 		xpad->delay_init = true;
+	if (xpad_device[i].flags & FLAG_NO_LED)
+		xpad->no_led = true;
+	if (xpad_device[i].flags & FLAG_NO_RUMBLE)
+		xpad->no_rumble = true;
 
 	xpad->packet_type = PKT_XB;
 	INIT_WORK(&xpad->work, xpad_presence_work);
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help