From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f171.google.com (mail-oi1-f171.google.com [209.85.167.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77D972AE76 for ; Sat, 1 Aug 2026 07:56:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785571012; cv=none; b=fRNhg/vEQto0G28ZY0jo4j225g1QKG9hLh5mOKmqqqsZICkedhPe3rVp9zzhSSh6DIK34T7rykQvLX6GRpEYW7OQ1InjnGmoiQhymFf5s9IQF/b0HFzPoSswWtFT2uHVtZqj3KIABzU9+SF9jNAG1wDdltOpXw2UrDeAsPR16C8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785571012; c=relaxed/simple; bh=Kt7aw5v1be9+lcNnaGvyQA2wTGV+AOKl2Wj6IFLXFi8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lcu1BGypRo2KcmBig4VYbaRKuakky3mUH4h0PIWxoigcdWnRXuEEMe0Qu4ZnzTGD9RZvbizIaJC8rcDVk79rH+OsVovBrDnMTH95rFNMJ4sZ9rqdZ5EteQV47CXp5pbfkkphZKjFAqS82V/uqIiZw4S4BlSbroDYqopDks8nmdI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MrLbi6TG; arc=none smtp.client-ip=209.85.167.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MrLbi6TG" Received: by mail-oi1-f171.google.com with SMTP id 5614622812f47-497d3e4460aso2380887b6e.1 for ; Sat, 01 Aug 2026 00:56:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785571010; x=1786175810; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=/N0Tzrpz6sDPQRaRp7HmPznbO3iM+ppqHQmfBVtWeo4=; b=MrLbi6TGFdhkdvF6yhzNRk40/kovsOyADgy1CAUjx2JUQQqw4EwjByZGoSWmBU3QCn xXnH1KJ14Sp+KCkZtsz4CbLqPE6d24I1kSgM1YoqY/bem0U3hraxANkboChkl25glT07 z/z87MVwrTwRLcB99DRNqTZv6w9S0BDSzBqu/Zc/nACUAFZL0n1oI+yQsPpYGmCK5D2T ma2KJG3ON6fnzCX76TcQLtihtoBQa6gcgwvkG1X4DGYgbPUHAcXYacEAH1ZT1mz7u9lI hqrQtdkNH8gQCEZIiJhVvy0QaJGs+dz7sen64m1vl2rHMdXLr/drZycsMdtV2C7F3dIc 3/dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785571010; x=1786175810; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=/N0Tzrpz6sDPQRaRp7HmPznbO3iM+ppqHQmfBVtWeo4=; b=GB6jCWMWcZt/2h+MqCy8VgSFzdSzmtMFvl7nfYU3d7HC7BMMmE3Tf0q2e8tTsymlz1 rph97gc7YXjE5/iOay0j1TGrqzXvtCl71x59l2uq45uLNE5oRstjip0zhsxedPu9TFgg ep/KmDCu9OTzdBq2wg+qUgn0yxnxhChfCXT4Ih40nICoBgAb9/9QA8LMTFIAsoJ01TR6 s/G6rwI3Azwl1AnAeckpJLeMUl0d+PxTp/Xy38Mx4E8SbMHDsAa2W6KUeQeSzkTA0l79 R+s/jhlBVK/WIqSS5Aojd7l1qC/sxOX31tSK247NNv+hYjgE7loB5Oi8PakBfMMiCYkH vczA== X-Forwarded-Encrypted: i=1; AHgh+RoFPuuFM9IIsxvtaJwsJjJm4w0KvXoJDH0r+HvJl4Rvszy4BfUUk4uAZaG8eh0WD+zgwi7Y0HtDeP5KcsY=@vger.kernel.org X-Gm-Message-State: AOJu0Ywl3p991Nqwr3U8Cp/1e5oDZMcwKAFy0h6H78EiMIgaTBTlLe82 /cEOLkpKBAD6PQurYccU/jIBAe3eils08YdrpF41PwsFOYQPokJYkQ4a X-Gm-Gg: AR+sD121y50dpdR6SMcvbIxwkSqbfn9tf9sKb6452tF9pi2iWwEjk3OUvF5p9rj/QtV +qkMCb3bnZiXYT6cEu6nXCNnV/DAri4rIoCbZllLSdSiwjVEwWjLpi3Lug2WFMflbAXv7TgQe81 M29jwKR7n+8B8xuVuFMHbVy/mYAvgt0LoXghWGs7gZa5fDEinTKpJeUZklALWnJFDyPLRBJ1Jah SfEJIXsJ1wwjK95PaNIK3KMGvXRJVnfIUlV96LB+Qj4Hgc+WOApKI4aSEzQu9Y47P//SmrulR4v I61haN80sb3csZ45QbpepXX+kEwpgQ+vOhI/Vr0f3+XjN43YAHYoneqB2BNGTsE3S9h+aTZzdTT tihz1S/o0qrwNleFaxKIzYuMGMXfUWcqdiFqV3izck0lYFv6WIfv2pIqiq9ORtAZxpcXYWOJrau RWIEul742b4oZHnnA0Ooc1wHl2B9WKCKWyESZ8ojMF2T7+0Ekta2ZA+036mgr15/n66q5LBxY1c L0oxQ== X-Received: by 2002:a05:6808:1583:b0:492:3ad9:15d9 with SMTP id 5614622812f47-4af5e91f205mr2306521b6e.6.1785571010260; Sat, 01 Aug 2026 00:56:50 -0700 (PDT) Received: from u-ThinkPad-X1-Extreme-Gen-4i ([192.3.12.183]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4af58ce3e8esm2466717b6e.3.2026.08.01.00.56.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Aug 2026 00:56:48 -0700 (PDT) From: Aaron Ma To: Dmitry Torokhov , linux-input@vger.kernel.org (open list:INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN)...), linux-kernel@vger.kernel.org Cc: Sanjay Govind , Aaron Ma , Kees Cook , Zoltan Illes , Qbeliw Tanaka , Elliot Tester , Dmitriy Zharov Subject: [PATCH v2 2/2] Input: xpad - add wired Beitong BTP-KP20D support Date: Sat, 1 Aug 2026 15:56:23 +0800 Message-ID: <20260801075623.2769601-2-mapengyu@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260801075623.2769601-1-mapengyu@gmail.com> References: <20260801075623.2769601-1-mapengyu@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The wired BTP-KP20D resets itself when its interrupt-IN pipe is idle for a few seconds, causing periodic re-enumeration whenever no userspace client holds the input device open. Add a FLAG_KEEPALIVE quirk that keeps the input URB running from probe to disconnect, mirroring the XTYPE_XBOX360W URB lifecycle. The device also needs the MS OS descriptor query to stay in Xbox 360 mode. Stop any active output URB on probe failure before freeing its URB and DMA buffer. LED setup may submit the output URB before input initialization completes. Signed-off-by: Aaron Ma --- Changes in v2: - Stop the output URB before freeing it on probe failure. drivers/input/joystick/xpad.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 1616047e65f5e..9adc419066353 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -73,6 +73,7 @@ #define FLAG_DELAY_INIT BIT(0) #define FLAG_MS_OS_DESC BIT(1) +#define FLAG_KEEPALIVE BIT(2) static bool dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); @@ -335,6 +336,7 @@ static const struct xpad_device { { 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 }, + { 0x20bc, 0x5158, "Beitong BTP-KP20D Controller", 0, XTYPE_XBOX360, FLAG_MS_OS_DESC | FLAG_KEEPALIVE }, { 0x20bc, 0x5159, "Beitong BTP-KP20D Controller", 0, XTYPE_XBOX360, FLAG_MS_OS_DESC }, { 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 }, @@ -780,6 +782,7 @@ struct usb_xpad { time64_t mode_btn_down_ts; bool delay_init; /* init packets should be delayed */ bool delayed_init_done; + bool keepalive; /* int URB must run from probe to disconnect */ }; static int xpad_init_input(struct usb_xpad *xpad); @@ -1971,7 +1974,7 @@ static int xpad_init_input(struct usb_xpad *xpad) input_set_drvdata(input_dev, xpad); - if (xpad->xtype != XTYPE_XBOX360W) { + if (xpad->xtype != XTYPE_XBOX360W && !xpad->keepalive) { input_dev->open = xpad_open; input_dev->close = xpad_close; } @@ -2105,6 +2108,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_KEEPALIVE) + xpad->keepalive = true; xpad->packet_type = PKT_XB; INIT_WORK(&xpad->work, xpad_presence_work); @@ -2227,10 +2232,24 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id error = xpad_init_input(xpad); if (error) goto err_deinit_output; + + if (xpad->keepalive) { + /* + * The device resets itself when the interrupt-IN pipe + * is idle for a few seconds, so keep the URB running + * from probe until disconnect. + */ + error = xpad_start_input(xpad); + if (error) + goto err_deinit_input; + } } return 0; +err_deinit_input: + xpad_deinit_input(xpad); err_deinit_output: + xpad_stop_output(xpad); xpad_deinit_output(xpad); err_free_in_urb: usb_free_urb(xpad->irq_in); @@ -2247,6 +2266,8 @@ static void xpad_disconnect(struct usb_interface *intf) if (xpad->xtype == XTYPE_XBOX360W) xpad360w_stop_input(xpad); + else if (xpad->keepalive) + xpad_stop_input(xpad); xpad_deinit_input(xpad); @@ -2288,6 +2309,8 @@ static int xpad_suspend(struct usb_interface *intf, pm_message_t message) */ if (auto_poweroff && xpad->pad_present) xpad360w_poweroff_controller(xpad); + } else if (xpad->keepalive) { + xpad_stop_input(xpad); } else { guard(mutex)(&input->mutex); @@ -2309,6 +2332,9 @@ static int xpad_resume(struct usb_interface *intf) if (xpad->xtype == XTYPE_XBOX360W) return xpad360w_start_input(xpad); + if (xpad->keepalive) + return xpad_start_input(xpad); + guard(mutex)(&input->mutex); if (input_device_enabled(input)) -- 2.53.0