summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-04 08:24:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-04 08:24:32 -0700
commit3aae9383f42f687221c011d7ee87529398e826b3 (patch)
tree8a51a77273c2f101c43f55da9f6e7abba010f04c /drivers
parent7ca6d1cfec80ebe46cc063f3284c5896c344d9a1 (diff)
parent0d9363a764d9d601a05591f9695cea8b429e9be3 (diff)
Merge tag 'input-for-v7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/inputHEADmaster
Pull input fixes from Dmitry Torokhov: - new IDs for BETOP BTP-KP50B/C and Razer Wolverine V3 Pro added to xpad controller driver - another quirk for new TUXEDO InfinityBook added to i8042 - a small fixup for Synaptics RMI4 driver to properly unlock mutex when encountering an error in F54 - an update to bcm5974 touch controller driver to reliably switch into wellspring mode * tag 'input-for-v7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: xpad - add support for BETOP BTP-KP50B/C controller's wireless mode Input: xpad - add support for Razer Wolverine V3 Pro Input: synaptics-rmi4 - fix a locking bug in an error path Input: i8042 - add TUXEDO InfinityBook Max 16 Gen10 AMD to i8042 quirk table Input: bcm5974 - recover from failed mode switch
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/joystick/xpad.c5
-rw-r--r--drivers/input/mouse/bcm5974.c42
-rw-r--r--drivers/input/rmi4/rmi_f54.c4
-rw-r--r--drivers/input/serio/i8042-acpipnpio.h7
4 files changed, 55 insertions, 3 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index bf4accf3f581..d6fc3d6006bb 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -313,6 +313,8 @@ static const struct xpad_device {
{ 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
{ 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
{ 0x1532, 0x0a29, "Razer Wolverine V2", 0, XTYPE_XBOXONE },
+ { 0x1532, 0x0a57, "Razer Wolverine V3 Pro (Wired)", 0, XTYPE_XBOX360 },
+ { 0x1532, 0x0a59, "Razer Wolverine V3 Pro (2.4 GHz Dongle)", 0, XTYPE_XBOX360 },
{ 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 },
{ 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
{ 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 },
@@ -360,6 +362,8 @@ 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, 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 },
{ 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE },
{ 0x20d6, 0x2064, "PowerA Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
@@ -562,6 +566,7 @@ static const struct usb_device_id xpad_table[] = {
XPAD_XBOX360_VENDOR(0x1a86), /* Nanjing Qinheng Microelectronics (WCH) */
XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */
XPAD_XBOX360_VENDOR(0x1ee9), /* ZOTAC Technology Limited */
+ XPAD_XBOX360_VENDOR(0x20bc), /* BETOP wireless dongles */
XPAD_XBOX360_VENDOR(0x20d6), /* PowerA controllers */
XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA controllers */
XPAD_XBOX360_VENDOR(0x2345), /* Machenike Controllers */
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 8e3cea9db365..e772bac3b64c 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -286,6 +286,8 @@ struct bcm5974 {
const struct tp_finger *index[MAX_FINGERS]; /* finger index data */
struct input_mt_pos pos[MAX_FINGERS]; /* position array */
int slots[MAX_FINGERS]; /* slot assignments */
+ struct work_struct mode_reset_work;
+ unsigned long last_mode_reset;
};
/* trackpad finger block data, le16-aligned */
@@ -696,6 +698,32 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
return retval;
}
+/*
+ * Mode switches sent before the control response are ignored.
+ * Fixing this state requires switching to normal mode and waiting
+ * about 1ms before switching back to wellspring mode.
+ */
+static void bcm5974_mode_reset_work(struct work_struct *work)
+{
+ struct bcm5974 *dev = container_of(work, struct bcm5974, mode_reset_work);
+ int error;
+
+ guard(mutex)(&dev->pm_mutex);
+ dev->last_mode_reset = jiffies;
+
+ error = bcm5974_wellspring_mode(dev, false);
+ if (error) {
+ dev_err(&dev->intf->dev, "reset to normal mode failed\n");
+ return;
+ }
+
+ fsleep(1000);
+
+ error = bcm5974_wellspring_mode(dev, true);
+ if (error)
+ dev_err(&dev->intf->dev, "mode switch after reset failed\n");
+}
+
static void bcm5974_irq_button(struct urb *urb)
{
struct bcm5974 *dev = urb->context;
@@ -752,10 +780,20 @@ static void bcm5974_irq_trackpad(struct urb *urb)
if (dev->tp_urb->actual_length == 2)
goto exit;
- if (report_tp_state(dev, dev->tp_urb->actual_length))
+ if (report_tp_state(dev, dev->tp_urb->actual_length)) {
dprintk(1, "bcm5974: bad trackpad package, length: %d\n",
dev->tp_urb->actual_length);
+ /*
+ * Receiving a HID packet means we aren't in wellspring mode.
+ * If we haven't tried a reset in the last second, try now.
+ */
+ if (dev->tp_urb->actual_length == 8 &&
+ time_after(jiffies, dev->last_mode_reset + msecs_to_jiffies(1000))) {
+ schedule_work(&dev->mode_reset_work);
+ }
+ }
+
exit:
error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
if (error)
@@ -906,6 +944,7 @@ static int bcm5974_probe(struct usb_interface *iface,
dev->intf = iface;
dev->input = input_dev;
dev->cfg = *cfg;
+ INIT_WORK(&dev->mode_reset_work, bcm5974_mode_reset_work);
mutex_init(&dev->pm_mutex);
/* setup urbs */
@@ -998,6 +1037,7 @@ static void bcm5974_disconnect(struct usb_interface *iface)
{
struct bcm5974 *dev = usb_get_intfdata(iface);
+ disable_work_sync(&dev->mode_reset_work);
usb_set_intfdata(iface, NULL);
input_unregister_device(dev->input);
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
index ac4041a69fcd..61909e1a39e2 100644
--- a/drivers/input/rmi4/rmi_f54.c
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -538,6 +538,8 @@ static void rmi_f54_work(struct work_struct *work)
int error;
int i;
+ mutex_lock(&f54->data_mutex);
+
report_size = rmi_f54_get_report_size(f54);
if (report_size == 0) {
dev_err(&fn->dev, "Bad report size, report type=%d\n",
@@ -546,8 +548,6 @@ static void rmi_f54_work(struct work_struct *work)
goto error; /* retry won't help */
}
- mutex_lock(&f54->data_mutex);
-
/*
* Need to check if command has completed.
* If not try again later.
diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
index d2cf940b105a..8ebdf4fb9030 100644
--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -1189,6 +1189,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
},
{
.matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "X6KK45xU_X6SP45xU"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+ },
+ {
+ .matches = {
DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"),
},
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |