linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Support additional Xbox One pads
@ 2017-04-08 21:28 Cameron Gutman
  2017-04-08 21:28 ` [PATCH v2 1/2] Input: xpad - support some quirky " Cameron Gutman
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Cameron Gutman @ 2017-04-08 21:28 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input, linux-kernel

This series adds support for several new or quirky Xbox One pads.
With the existing code, these pads either don't send any input
data at all, only have partial functionality, or just aren't yet
recognized by the driver even though they would work just fine.

Patch 1 of this series may be considered a v2 for patches 1-3 of my
previous series:

  https://lkml.org/lkml/2017/2/4/189

I'm now only sending the quirk packets to the specific gamepads that
need them, per Dmitry's feedback on the last series.

Patch 2 is a trivial new device ID addition that I've tagged for
stable. This one is not purely cosmetic because we won't currently
bind to any Xbox One pads with Razer's VID without it. The Razer
Wildcat doesn't depend on any quirk handling or newer xpad changes
for full functionality, so it should work just fine when backported
to stable kernels.

v2 changes:
I've given the commit message for patch 1 some much needed TLC, as
the old one was poorly worded and did not contain many details about
the change.

Cameron Gutman (2):
  Input: xpad - support some quirky Xbox One pads
  Input: xpad - add support for Razer Wildcat gamepad

 drivers/input/joystick/xpad.c | 116 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 103 insertions(+), 13 deletions(-)

-- 
2.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] Input: xpad - support some quirky Xbox One pads
  2017-04-08 21:28 [PATCH v2 0/2] Support additional Xbox One pads Cameron Gutman
@ 2017-04-08 21:28 ` Cameron Gutman
  2017-04-08 21:28 ` [PATCH v2 2/2] Input: xpad - add support for Razer Wildcat gamepad Cameron Gutman
  2017-04-11  3:47 ` [PATCH v2 0/2] Support additional Xbox One pads Dmitry Torokhov
  2 siblings, 0 replies; 4+ messages in thread
From: Cameron Gutman @ 2017-04-08 21:28 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input, linux-kernel

There are several quirky Xbox One pads that depend on initialization
packets that the Microsoft pads don't require. To deal with these,
I've added a mechanism for issuing device-specific initialization
packets using a VID/PID-based quirks list.

For the initial set of init quirks, I have added quirk handling from
Valve's Steam Link xpad driver[0] and the 360Controller project[1] for
macOS to enable some new pads to work properly.

This should enable full functionality on the following quirky pads:
0x0e6f:0x0165 - Titanfall 2 gamepad (previously fully non-functional)
0x0f0d:0x0067 - Hori Horipad (analog sticks previously non-functional)
0x24c6:0x541a - PowerA Xbox One pad (previously fully non-functional)
0x24c6:0x542a - PowerA Xbox One pad (previously fully non-functional)
0x24c6:0x543a - PowerA Xbox One pad (previously fully non-functional)

[0]: https://github.com/ValveSoftware/steamlink-sdk/blob/master/kernel/drivers/input/joystick/xpad.c
[1]: https://github.com/360Controller/360Controller

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
v2:
- Fixed up the commit message which had some lines incorrectly copied
  from the previous submission.
- Added more details as the previous commit message was a bit sparse.

---
 drivers/input/joystick/xpad.c | 114 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 101 insertions(+), 13 deletions(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 155fcb3..efb798a 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -337,6 +337,64 @@ static struct usb_device_id xpad_table[] = {
 
 MODULE_DEVICE_TABLE(usb, xpad_table);
 
+struct xboxone_init_packet {
+	u16 idVendor;
+	u16 idProduct;
+	const u8 *data;
+	u8 len;
+};
+
+#define XBOXONE_INIT_PKT(_vid, _pid, _data)		\
+	{						\
+		.idVendor	= (_vid),		\
+		.idProduct	= (_pid),		\
+		.data		= (_data),		\
+		.len		= ARRAY_SIZE(_data),	\
+	}
+
+
+/*
+ * This packet is required for all Xbox One pads with 2015
+ * or later firmware installed (or present from the factory).
+ */
+static const u8 xboxone_fw2015_init[] = {
+	0x05, 0x20, 0x00, 0x01, 0x00
+};
+
+ /*
+  * This packet is required for the Titanfall 2 Xbox One pads
+  * (0x0e6f:0x0165) to finish initialization and for Hori pads
+  * (0x0f0d:0x0067) to make the analog sticks work.
+  */
+static const u8 xboxone_hori_init[] = {
+	0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
+	0x00, 0x00, 0x00, 0x80, 0x00
+};
+
+/*
+ * A rumble packet is required for some PowerA pads to start
+ * sending input reports. One of those pads is (0x24c6:0x543a).
+ */
+static const u8 xboxone_zerorumble_init[] = {
+	0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/*
+ * This specifies the selection of init packets that a gamepad
+ * will be sent on init *and* the order in which they will be
+ * sent. The correct sequence number will be added when the
+ * packet is going to be sent.
+ */
+static const struct xboxone_init_packet xboxone_init_packets[] = {
+	XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
+	XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
+	XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
+	XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_zerorumble_init),
+	XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_zerorumble_init),
+	XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_zerorumble_init),
+};
+
 struct xpad_output_packet {
 	u8 data[XPAD_PKT_LEN];
 	u8 len;
@@ -373,6 +431,7 @@ struct usb_xpad {
 
 	struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
 	int last_out_packet;
+	int init_seq;
 
 #if defined(CONFIG_JOYSTICK_XPAD_LEDS)
 	struct xpad_led *led;
@@ -748,11 +807,47 @@ static void xpad_irq_in(struct urb *urb)
 }
 
 /* Callers must hold xpad->odata_lock spinlock */
+static bool xpad_prepare_next_init_packet(struct usb_xpad *xpad)
+{
+	const struct xboxone_init_packet *init_packet;
+
+	if (xpad->xtype != XTYPE_XBOXONE)
+		return false;
+
+	/* Perform initialization sequence for Xbox One pads that require it */
+	while (xpad->init_seq < ARRAY_SIZE(xboxone_init_packets)) {
+		init_packet = &xboxone_init_packets[xpad->init_seq++];
+
+		if (init_packet->idVendor != 0 &&
+		    init_packet->idVendor != xpad->dev->id.vendor)
+			continue;
+
+		if (init_packet->idProduct != 0 &&
+		    init_packet->idProduct != xpad->dev->id.product)
+			continue;
+
+		/* This packet applies to our device, so prepare to send it */
+		memcpy(xpad->odata, init_packet->data, init_packet->len);
+		xpad->irq_out->transfer_buffer_length = init_packet->len;
+
+		/* Update packet with current sequence number */
+		xpad->odata[2] = xpad->odata_serial++;
+		return true;
+	}
+
+	return false;
+}
+
+/* Callers must hold xpad->odata_lock spinlock */
 static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
 {
 	struct xpad_output_packet *pkt, *packet = NULL;
 	int i;
 
+	/* We may have init packets to send before we can send user commands */
+	if (xpad_prepare_next_init_packet(xpad))
+		return true;
+
 	for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
 		if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
 			xpad->last_out_packet = 0;
@@ -938,24 +1033,17 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
 
 static int xpad_start_xbox_one(struct usb_xpad *xpad)
 {
-	struct xpad_output_packet *packet =
-			&xpad->out_packets[XPAD_OUT_CMD_IDX];
 	unsigned long flags;
 	int retval;
 
 	spin_lock_irqsave(&xpad->odata_lock, flags);
 
-	/* Xbox one controller needs to be initialized. */
-	packet->data[0] = 0x05;
-	packet->data[1] = 0x20;
-	packet->data[2] = xpad->odata_serial++; /* packet serial */
-	packet->data[3] = 0x01; /* rumble bit enable?  */
-	packet->data[4] = 0x00;
-	packet->len = 5;
-	packet->pending = true;
-
-	/* Reset the sequence so we send out start packet first */
-	xpad->last_out_packet = -1;
+	/*
+	 * Begin the init sequence by attempting to send a packet.
+	 * We will cycle through the init packet sequence before
+	 * sending any packets from the output ring.
+	 */
+	xpad->init_seq = 0;
 	retval = xpad_try_sending_next_out_packet(xpad);
 
 	spin_unlock_irqrestore(&xpad->odata_lock, flags);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] Input: xpad - add support for Razer Wildcat gamepad
  2017-04-08 21:28 [PATCH v2 0/2] Support additional Xbox One pads Cameron Gutman
  2017-04-08 21:28 ` [PATCH v2 1/2] Input: xpad - support some quirky " Cameron Gutman
@ 2017-04-08 21:28 ` Cameron Gutman
  2017-04-11  3:47 ` [PATCH v2 0/2] Support additional Xbox One pads Dmitry Torokhov
  2 siblings, 0 replies; 4+ messages in thread
From: Cameron Gutman @ 2017-04-08 21:28 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input, linux-kernel

Cc: stable@vger.kernel.org
Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
v2:
- No changes

 drivers/input/joystick/xpad.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index efb798a..5c3d249 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -202,6 +202,7 @@ static const struct xpad_device {
 	{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
 	{ 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+	{ 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
 	{ 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 },
@@ -326,6 +327,7 @@ static struct usb_device_id xpad_table[] = {
 	XPAD_XBOX360_VENDOR(0x1430),		/* RedOctane X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x146b),		/* BigBen Interactive Controllers */
 	XPAD_XBOX360_VENDOR(0x1532),		/* Razer Sabertooth */
+	XPAD_XBOXONE_VENDOR(0x1532),		/* Razer Wildcat */
 	XPAD_XBOX360_VENDOR(0x15e4),		/* Numark X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x162e),		/* Joytech X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x1689),		/* Razer Onza */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 0/2] Support additional Xbox One pads
  2017-04-08 21:28 [PATCH v2 0/2] Support additional Xbox One pads Cameron Gutman
  2017-04-08 21:28 ` [PATCH v2 1/2] Input: xpad - support some quirky " Cameron Gutman
  2017-04-08 21:28 ` [PATCH v2 2/2] Input: xpad - add support for Razer Wildcat gamepad Cameron Gutman
@ 2017-04-11  3:47 ` Dmitry Torokhov
  2 siblings, 0 replies; 4+ messages in thread
From: Dmitry Torokhov @ 2017-04-11  3:47 UTC (permalink / raw)
  To: Cameron Gutman; +Cc: rojtberg, linux-input, linux-kernel

On Sat, Apr 08, 2017 at 02:28:04PM -0700, Cameron Gutman wrote:
> This series adds support for several new or quirky Xbox One pads.
> With the existing code, these pads either don't send any input
> data at all, only have partial functionality, or just aren't yet
> recognized by the driver even though they would work just fine.
> 
> Patch 1 of this series may be considered a v2 for patches 1-3 of my
> previous series:
> 
>   https://lkml.org/lkml/2017/2/4/189
> 
> I'm now only sending the quirk packets to the specific gamepads that
> need them, per Dmitry's feedback on the last series.
> 
> Patch 2 is a trivial new device ID addition that I've tagged for
> stable. This one is not purely cosmetic because we won't currently
> bind to any Xbox One pads with Razer's VID without it. The Razer
> Wildcat doesn't depend on any quirk handling or newer xpad changes
> for full functionality, so it should work just fine when backported
> to stable kernels.
> 
> v2 changes:
> I've given the commit message for patch 1 some much needed TLC, as
> the old one was poorly worded and did not contain many details about
> the change.
> 
> Cameron Gutman (2):
>   Input: xpad - support some quirky Xbox One pads
>   Input: xpad - add support for Razer Wildcat gamepad
> 
>  drivers/input/joystick/xpad.c | 116 +++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 103 insertions(+), 13 deletions(-)

Applied, thank you.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-04-11  3:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-08 21:28 [PATCH v2 0/2] Support additional Xbox One pads Cameron Gutman
2017-04-08 21:28 ` [PATCH v2 1/2] Input: xpad - support some quirky " Cameron Gutman
2017-04-08 21:28 ` [PATCH v2 2/2] Input: xpad - add support for Razer Wildcat gamepad Cameron Gutman
2017-04-11  3:47 ` [PATCH v2 0/2] Support additional Xbox One pads Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).