* [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