* [PATCH] Input: xpad - add support for Beitong KP series controllers
@ 2026-07-26 8:01 VegetablCat
2026-07-26 8:10 ` sashiko-bot
0 siblings, 1 reply; 4+ messages in thread
From: VegetablCat @ 2026-07-26 8:01 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, linux-kernel, vegetablecat
From: vegetablecat <vegetablecat@foxmail.com>
Beitong KP series controllers (0x20bc:*) enumerate as standard
Xbox 360 devices but require a Microsoft OS Extended Compat ID
descriptor read (XUSB10) to lock into XInput mode. Without this
request the controller re-enumerates as a Nintendo Switch device
(057e:2069) after approximately 1.9 seconds and stops reporting
valid input.
Add FLAG_READ_XUSB10 and device table entries for KP20A/D,
KP40A/B/D/F, KP50B/C/D/E, and KP70A. Devices with this flag
trigger a usb_control_msg_recv() during probe to read the XUSB10
descriptor, which is the sole condition required to keep the
controllers in XInput mode.
The flag follows the same pattern as FLAG_DELAY_INIT used for
the ByoWave Proteus Controller.
Additionally, add a minimal HID receiver driver for the KP40D
receiver dongle (0x20dd:0x515c) that binds to its HID interface
to prevent hid-generic from interfering. This requires replacing
module_usb_driver() with manual module_init/module_exit to
register both the USB and HID drivers.
Tested on 20bc:5126 (KP20A) and 20bc:515b (KP40D).
Signed-off-by: vegetablecat <vegetablecat@foxmail.com>
---
drivers/input/joystick/xpad.c | 111 +++++++++++++++++++++++++++++++++-
1 file changed, 110 insertions(+), 1 deletion(-)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index feb8f36..d33ca18 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -28,6 +28,7 @@
*/
#include <linux/bits.h>
+#include <linux/hid.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/rcupdate.h>
@@ -72,6 +73,7 @@
#define PKT_XBE2_FW_5_11 4
#define FLAG_DELAY_INIT BIT(0)
+#define FLAG_READ_XUSB10 BIT(1)
static bool dpad_to_buttons;
module_param(dpad_to_buttons, bool, S_IRUGO);
@@ -332,6 +334,32 @@ static const struct xpad_device {
{ 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
{ 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 },
+ { 0x20bc, 0x5125, "BETOP BTP-KP20A/BTP-KP40A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5126, "BETOP BTP-KP20A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5127, "BETOP BTP-KP20A/BTP-KP40A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5128, "BETOP BTP-KP20A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x512f, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5130, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5133, "BETOP BTP-KP50B Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5145, "BETOP BTP-KP40A/BTP-KP40B Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5146, "BETOP BTP-KP40A/BTP-KP40B Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5149, "BETOP BTP-KP50C Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5150, "BETOP BTP-KP50D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5151, "BETOP BTP-KP50D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5152, "BETOP BTP-KP50E Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5153, "BETOP BTP-KP50E Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5154, "BETOP BTP-KP40D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5155, "BETOP BTP-KP40D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5158, "BETOP BTP-KP20D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5159, "BETOP BTP-KP20D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515b, "BETOP BTP-KP40D Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515c, "BETOP BTP-KP40D Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515d, "BETOP BTP-KP40F Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515e, "BETOP BTP-KP40F Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515f, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5160, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5169, "BETOP BTP-KP40F Controller (Black)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x516a, "BETOP BTP-KP40F Controller (Black)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
{ 0x20bc, 0x5134, "BETOP BTP-KP50B Xinput Dongle", 0, XTYPE_XBOX360 },
{ 0x20bc, 0x514a, "BETOP BTP-KP50C Xinput Dongle", 0, XTYPE_XBOX360 },
{ 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
@@ -778,6 +806,7 @@ struct usb_xpad {
time64_t mode_btn_down_ts;
bool delay_init; /* init packets should be delayed */
bool delayed_init_done;
+ bool read_xusb10; /* read XUSB10 descriptor during probe */
};
static int xpad_init_input(struct usb_xpad *xpad);
@@ -2044,6 +2073,7 @@ 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;
+ u8 ms_feature_descriptor[40];
int i, error;
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
@@ -2082,6 +2112,8 @@ 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_READ_XUSB10)
+ xpad->read_xusb10 = true;
xpad->packet_type = PKT_XB;
INIT_WORK(&xpad->work, xpad_presence_work);
@@ -2148,6 +2180,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_set_intfdata(intf, xpad);
+ if (xpad->read_xusb10) {
+ error = usb_control_msg_recv(udev, 0, 0xee,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_DEVICE,
+ 0x0000, 0x0004,
+ ms_feature_descriptor,
+ sizeof(ms_feature_descriptor), 25,
+ GFP_KERNEL);
+ if (error)
+ dev_warn(&intf->dev,
+ "unable to read Microsoft feature descriptor: %d\n",
+ error);
+ }
/* Packet type detection */
if (le16_to_cpu(udev->descriptor.idVendor) == 0x045e) { /* Microsoft controllers */
@@ -2312,7 +2357,71 @@ static struct usb_driver xpad_driver = {
.id_table = xpad_table,
};
-module_usb_driver(xpad_driver);
+static int xpad_receiver_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ int error;
+
+ error = hid_parse(hdev);
+ if (error)
+ return error;
+
+ error = hid_hw_start(hdev, 0);
+ if (error)
+ return error;
+
+ error = hid_hw_open(hdev);
+ if (error) {
+ hid_hw_stop(hdev);
+ return error;
+ }
+
+ return 0;
+}
+
+static void xpad_receiver_remove(struct hid_device *hdev)
+{
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+}
+
+static const struct hid_device_id xpad_receiver_devices[] = {
+ { HID_USB_DEVICE(0x20dd, 0x515c) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, xpad_receiver_devices);
+
+static struct hid_driver xpad_receiver_driver = {
+ .name = "xpad-kp40d-receiver",
+ .id_table = xpad_receiver_devices,
+ .probe = xpad_receiver_probe,
+ .remove = xpad_receiver_remove,
+};
+
+static int __init xpad_init(void)
+{
+ int error;
+
+ error = hid_register_driver(&xpad_receiver_driver);
+ if (error)
+ return error;
+
+ error = usb_register(&xpad_driver);
+ if (error) {
+ hid_unregister_driver(&xpad_receiver_driver);
+ return error;
+ }
+
+ return 0;
+}
+
+static void __exit xpad_exit(void)
+{
+ usb_deregister(&xpad_driver);
+ hid_unregister_driver(&xpad_receiver_driver);
+}
+
+module_init(xpad_init);
+module_exit(xpad_exit);
MODULE_AUTHOR("Marko Friedemann <mfr@bmx-chemnitz.de>");
MODULE_DESCRIPTION("Xbox pad driver");
--
2.55.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] Input: xpad - add support for Beitong KP series controllers
2026-07-26 8:01 VegetablCat
@ 2026-07-26 8:10 ` sashiko-bot
0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-07-26 8:10 UTC (permalink / raw)
To: VegetablCat; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The HID device ID for the receiver dongle uses an incorrect vendor ID (`0x20dd`), which conflicts with the `0x20bc` vendor ID defined in the USB device table, preventing the driver from binding.
- [Low] Missing Kconfig dependency on `CONFIG_HID` for `CONFIG_JOYSTICK_XPAD` leads to build and linkage failures when HID is disabled or built as a module.
--
--- Patch [1]: [PATCH] Input: xpad - add support for Beitong KP series controllers ---
commit bcec2846a21020976ee3a5901681b58a510bad9a
Author: vegetablecat <vegetablecat@foxmail.com>
Subject: Input: xpad - add support for Beitong KP series controllers
This commit adds support for Beitong KP series controllers by reading the
XUSB10 descriptor to lock them into XInput mode. It also introduces a
minimal HID receiver driver for the KP40D receiver dongle to prevent
hid-generic from interfering.
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index feb8f368f834e..d33ca181dfe8b 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
[ ... ]
> @@ -332,6 +334,32 @@ static const struct xpad_device {
> { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
> { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
> { 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 },
[ ... ]
> + { 0x20bc, 0x515b, "BETOP BTP-KP40D Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
> + { 0x20bc, 0x515c, "BETOP BTP-KP40D Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
> + { 0x20bc, 0x515d, "BETOP BTP-KP40F Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
[ ... ]
> @@ -2312,7 +2357,71 @@ static struct usb_driver xpad_driver = {
[ ... ]
> +static const struct hid_device_id xpad_receiver_devices[] = {
> + { HID_USB_DEVICE(0x20dd, 0x515c) },
> + { }
> +};
[Severity: High]
Is the vendor ID 0x20dd in the HID device table correct?
The USB device table defines product 0x515c with vendor ID 0x20bc,
but the HID device ID table uses 0x20dd. Since a child HID device inherits
its vendor ID from the underlying USB device, will the HID driver fail to
bind to the dongle if it is looking for 0x20dd instead of 0x20bc?
> +MODULE_DEVICE_TABLE(hid, xpad_receiver_devices);
> +
> +static struct hid_driver xpad_receiver_driver = {
> + .name = "xpad-kp40d-receiver",
> + .id_table = xpad_receiver_devices,
> + .probe = xpad_receiver_probe,
> + .remove = xpad_receiver_remove,
> +};
> +
> +static int __init xpad_init(void)
> +{
> + int error;
> +
> + error = hid_register_driver(&xpad_receiver_driver);
[Severity: Low]
Does this driver now require a dependency on the HID subsystem in Kconfig?
Since xpad_init() now unconditionally calls hid_register_driver(), will
building the kernel with CONFIG_JOYSTICK_XPAD=y and CONFIG_HID=m (or
disabled) cause a linker failure due to undefined HID core symbols?
> + if (error)
> + return error;
> +
> + error = usb_register(&xpad_driver);
--
Sashiko AI review · https://sashiko.dev/#/patchset/tencent_2DEADF4D9ADC33A9420BECBEA70B1A7EFD08@qq.com?part=1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] Input: xpad - add support for Beitong KP series controllers
@ 2026-07-26 8:18 VegetablCat
2026-07-26 8:26 ` sashiko-bot
0 siblings, 1 reply; 4+ messages in thread
From: VegetablCat @ 2026-07-26 8:18 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, linux-kernel, vegetablecat
From: vegetablecat <vegetablecat@foxmail.com>
Beitong KP series controllers (0x20bc:*) enumerate as standard
Xbox 360 devices but require a Microsoft OS Extended Compat ID
descriptor read (XUSB10) to lock into XInput mode. Without this
request the controller re-enumerates as a Nintendo Switch device
(057e:2069) after approximately 1.9 seconds and stops reporting
valid input.
Add FLAG_READ_XUSB10 and device table entries for KP20A/D,
KP40A/B/D/F, KP50B/C/D/E, and KP70A. Devices with this flag
trigger a usb_control_msg_recv() during probe to read the XUSB10
descriptor, which is the sole condition required to keep the
controllers in XInput mode.
The flag follows the same pattern as FLAG_DELAY_INIT used for
the ByoWave Proteus Controller.
Additionally, add an optional HID receiver driver for the KP40D
receiver dongle (0x20dd:0x515c) that binds to its HID interface
to prevent hid-generic from interfering. The receiver dongle is
a separate USB device with its own vendor ID (0x20dd), distinct
from the controller (0x20bc). The HID code is guarded with
IS_ENABLED(CONFIG_HID) to avoid build failures when HID is
disabled or built as a module.
Based on earlier work by Zixing Liu <zixing.liu@canonical.com>.
Tested on 20bc:5126 (KP20A) and 20bc:515b (KP40D).
Signed-off-by: vegetablecat <vegetablecat@foxmail.com>
---
drivers/input/joystick/xpad.c | 119 +++++++++++++++++++++++++++++++++-
1 file changed, 118 insertions(+), 1 deletion(-)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index feb8f36..13b6168 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -28,6 +28,7 @@
*/
#include <linux/bits.h>
+#include <linux/hid.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/rcupdate.h>
@@ -72,6 +73,7 @@
#define PKT_XBE2_FW_5_11 4
#define FLAG_DELAY_INIT BIT(0)
+#define FLAG_READ_XUSB10 BIT(1)
static bool dpad_to_buttons;
module_param(dpad_to_buttons, bool, S_IRUGO);
@@ -332,6 +334,32 @@ static const struct xpad_device {
{ 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
{ 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 },
+ { 0x20bc, 0x5125, "BETOP BTP-KP20A/BTP-KP40A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5126, "BETOP BTP-KP20A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5127, "BETOP BTP-KP20A/BTP-KP40A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5128, "BETOP BTP-KP20A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x512f, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5130, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5133, "BETOP BTP-KP50B Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5145, "BETOP BTP-KP40A/BTP-KP40B Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5146, "BETOP BTP-KP40A/BTP-KP40B Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5149, "BETOP BTP-KP50C Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5150, "BETOP BTP-KP50D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5151, "BETOP BTP-KP50D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5152, "BETOP BTP-KP50E Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5153, "BETOP BTP-KP50E Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5154, "BETOP BTP-KP40D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5155, "BETOP BTP-KP40D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5158, "BETOP BTP-KP20D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5159, "BETOP BTP-KP20D Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515b, "BETOP BTP-KP40D Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515c, "BETOP BTP-KP40D Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515d, "BETOP BTP-KP40F Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515e, "BETOP BTP-KP40F Controller (White)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x515f, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5160, "BETOP BTP-KP70A Controller", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x5169, "BETOP BTP-KP40F Controller (Black)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
+ { 0x20bc, 0x516a, "BETOP BTP-KP40F Controller (Black)", 0, XTYPE_XBOX360, FLAG_READ_XUSB10 },
{ 0x20bc, 0x5134, "BETOP BTP-KP50B Xinput Dongle", 0, XTYPE_XBOX360 },
{ 0x20bc, 0x514a, "BETOP BTP-KP50C Xinput Dongle", 0, XTYPE_XBOX360 },
{ 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
@@ -778,6 +806,7 @@ struct usb_xpad {
time64_t mode_btn_down_ts;
bool delay_init; /* init packets should be delayed */
bool delayed_init_done;
+ bool read_xusb10; /* read XUSB10 descriptor during probe */
};
static int xpad_init_input(struct usb_xpad *xpad);
@@ -2044,6 +2073,7 @@ 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;
+ u8 ms_feature_descriptor[40];
int i, error;
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
@@ -2082,6 +2112,8 @@ 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_READ_XUSB10)
+ xpad->read_xusb10 = true;
xpad->packet_type = PKT_XB;
INIT_WORK(&xpad->work, xpad_presence_work);
@@ -2148,6 +2180,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_set_intfdata(intf, xpad);
+ if (xpad->read_xusb10) {
+ error = usb_control_msg_recv(udev, 0, 0xee,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_DEVICE,
+ 0x0000, 0x0004,
+ ms_feature_descriptor,
+ sizeof(ms_feature_descriptor), 25,
+ GFP_KERNEL);
+ if (error)
+ dev_warn(&intf->dev,
+ "unable to read Microsoft feature descriptor: %d\n",
+ error);
+ }
/* Packet type detection */
if (le16_to_cpu(udev->descriptor.idVendor) == 0x045e) { /* Microsoft controllers */
@@ -2312,7 +2357,79 @@ static struct usb_driver xpad_driver = {
.id_table = xpad_table,
};
-module_usb_driver(xpad_driver);
+#if IS_ENABLED(CONFIG_HID)
+static int xpad_receiver_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ int error;
+
+ error = hid_parse(hdev);
+ if (error)
+ return error;
+
+ error = hid_hw_start(hdev, 0);
+ if (error)
+ return error;
+
+ error = hid_hw_open(hdev);
+ if (error) {
+ hid_hw_stop(hdev);
+ return error;
+ }
+
+ return 0;
+}
+
+static void xpad_receiver_remove(struct hid_device *hdev)
+{
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+}
+
+static const struct hid_device_id xpad_receiver_devices[] = {
+ { HID_USB_DEVICE(0x20dd, 0x515c) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, xpad_receiver_devices);
+
+static struct hid_driver xpad_receiver_driver = {
+ .name = "xpad-kp40d-receiver",
+ .id_table = xpad_receiver_devices,
+ .probe = xpad_receiver_probe,
+ .remove = xpad_receiver_remove,
+};
+#endif
+
+static int __init xpad_init(void)
+{
+ int error;
+
+#if IS_ENABLED(CONFIG_HID)
+ error = hid_register_driver(&xpad_receiver_driver);
+ if (error)
+ return error;
+#endif
+
+ error = usb_register(&xpad_driver);
+ if (error) {
+#if IS_ENABLED(CONFIG_HID)
+ hid_unregister_driver(&xpad_receiver_driver);
+#endif
+ return error;
+ }
+
+ return 0;
+}
+
+static void __exit xpad_exit(void)
+{
+ usb_deregister(&xpad_driver);
+#if IS_ENABLED(CONFIG_HID)
+ hid_unregister_driver(&xpad_receiver_driver);
+#endif
+}
+
+module_init(xpad_init);
+module_exit(xpad_exit);
MODULE_AUTHOR("Marko Friedemann <mfr@bmx-chemnitz.de>");
MODULE_DESCRIPTION("Xbox pad driver");
--
2.55.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] Input: xpad - add support for Beitong KP series controllers
2026-07-26 8:18 [PATCH] Input: xpad - add support for Beitong KP series controllers VegetablCat
@ 2026-07-26 8:26 ` sashiko-bot
0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-07-26 8:26 UTC (permalink / raw)
To: VegetablCat; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Aggressive 25ms timeout for USB control message can cause device initialization failures.
- [Low] Build Error / Linker Failure when CONFIG_JOYSTICK_XPAD=y and CONFIG_HID=m.
--
--- Patch [1]: [PATCH] Input: xpad - add support for Beitong KP series controllers ---
commit abec748a4c53845b79c26002cb6f3fc8b88c0708
Author: vegetablecat <vegetablecat@foxmail.com>
Input: xpad - add support for Beitong KP series controllers
This patch adds support for Beitong KP series controllers by reading the
XUSB10 descriptor to lock them into XInput mode. It also includes an optional
HID receiver driver for the KP40D dongle to prevent hid-generic interference.
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
[ ... ]
> @@ -2148,6 +2180,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
> xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
>
> usb_set_intfdata(intf, xpad);
> + if (xpad->read_xusb10) {
> + error = usb_control_msg_recv(udev, 0, 0xee,
> + USB_TYPE_VENDOR | USB_DIR_IN |
> + USB_RECIP_DEVICE,
> + 0x0000, 0x0004,
> + ms_feature_descriptor,
> + sizeof(ms_feature_descriptor), 25,
[Severity: Medium]
Is this 25ms timeout for usb_control_msg_recv() too aggressive?
Standard USB timeouts (e.g., USB_CTRL_GET_TIMEOUT) are typically 5000ms. A
25ms timeout risks transient probe failures on busy systems or slower USB
hubs, which could cause the device to fail to stay in XInput mode.
> + GFP_KERNEL);
> + if (error)
> + dev_warn(&intf->dev,
> + "unable to read Microsoft feature descriptor: %d\n",
> + error);
> + }
[ ... ]
> +static int __init xpad_init(void)
> +{
> + int error;
> +
> +#if IS_ENABLED(CONFIG_HID)
> + error = hid_register_driver(&xpad_receiver_driver);
[Severity: Low]
Will this cause a build error when CONFIG_JOYSTICK_XPAD=y and CONFIG_HID=m?
IS_ENABLED(CONFIG_HID) evaluates to true even when HID is built as a loadable
module. Since xpad is built into the main kernel image in this configuration,
it cannot link against module symbols, leading to a vmlinux link error.
Should this be #if IS_REACHABLE(CONFIG_HID) or managed via a Kconfig
dependency instead?
> + if (error)
> + return error;
> +#endif
> +
> + error = usb_register(&xpad_driver);
--
Sashiko AI review · https://sashiko.dev/#/patchset/tencent_3FA5706BA66E2CCCFA362E90F805A8FF370A@qq.com?part=1
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-07-26 8:26 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-26 8:18 [PATCH] Input: xpad - add support for Beitong KP series controllers VegetablCat
2026-07-26 8:26 ` sashiko-bot
-- strict thread matches above, loose matches on Subject: below --
2026-07-26 8:01 VegetablCat
2026-07-26 8:10 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox