aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCameron Gutman <aicommander@gmail.com>2017-04-10 23:43:04 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2017-04-10 23:45:14 -0400
commit81093c9848a781b85163d06de92ef8f84528cf6a (patch)
tree4a98d49a601cf21fa0334e02114f3ca34bac382e
parentc5cb37d0d62c58320f0a86777b738fb28272245b (diff)
Input: xpad - support some quirky Xbox One pads
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> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/joystick/xpad.c114
1 files changed, 101 insertions, 13 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 155fcb3b6230..8a41926dab0a 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -337,6 +337,64 @@ static struct usb_device_id xpad_table[] = {
337 337
338MODULE_DEVICE_TABLE(usb, xpad_table); 338MODULE_DEVICE_TABLE(usb, xpad_table);
339 339
340struct xboxone_init_packet {
341 u16 idVendor;
342 u16 idProduct;
343 const u8 *data;
344 u8 len;
345};
346
347#define XBOXONE_INIT_PKT(_vid, _pid, _data) \
348 { \
349 .idVendor = (_vid), \
350 .idProduct = (_pid), \
351 .data = (_data), \
352 .len = ARRAY_SIZE(_data), \
353 }
354
355
356/*
357 * This packet is required for all Xbox One pads with 2015
358 * or later firmware installed (or present from the factory).
359 */
360static const u8 xboxone_fw2015_init[] = {
361 0x05, 0x20, 0x00, 0x01, 0x00
362};
363
364/*
365 * This packet is required for the Titanfall 2 Xbox One pads
366 * (0x0e6f:0x0165) to finish initialization and for Hori pads
367 * (0x0f0d:0x0067) to make the analog sticks work.
368 */
369static const u8 xboxone_hori_init[] = {
370 0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
371 0x00, 0x00, 0x00, 0x80, 0x00
372};
373
374/*
375 * A rumble packet is required for some PowerA pads to start
376 * sending input reports. One of those pads is (0x24c6:0x543a).
377 */
378static const u8 xboxone_zerorumble_init[] = {
379 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00
381};
382
383/*
384 * This specifies the selection of init packets that a gamepad
385 * will be sent on init *and* the order in which they will be
386 * sent. The correct sequence number will be added when the
387 * packet is going to be sent.
388 */
389static const struct xboxone_init_packet xboxone_init_packets[] = {
390 XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
391 XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
392 XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
393 XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_zerorumble_init),
394 XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_zerorumble_init),
395 XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_zerorumble_init),
396};
397
340struct xpad_output_packet { 398struct xpad_output_packet {
341 u8 data[XPAD_PKT_LEN]; 399 u8 data[XPAD_PKT_LEN];
342 u8 len; 400 u8 len;
@@ -373,6 +431,7 @@ struct usb_xpad {
373 431
374 struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS]; 432 struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
375 int last_out_packet; 433 int last_out_packet;
434 int init_seq;
376 435
377#if defined(CONFIG_JOYSTICK_XPAD_LEDS) 436#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
378 struct xpad_led *led; 437 struct xpad_led *led;
@@ -748,11 +807,47 @@ exit:
748} 807}
749 808
750/* Callers must hold xpad->odata_lock spinlock */ 809/* Callers must hold xpad->odata_lock spinlock */
810static bool xpad_prepare_next_init_packet(struct usb_xpad *xpad)
811{
812 const struct xboxone_init_packet *init_packet;
813
814 if (xpad->xtype != XTYPE_XBOXONE)
815 return false;
816
817 /* Perform initialization sequence for Xbox One pads that require it */
818 while (xpad->init_seq < ARRAY_SIZE(xboxone_init_packets)) {
819 init_packet = &xboxone_init_packets[xpad->init_seq++];
820
821 if (init_packet->idVendor != 0 &&
822 init_packet->idVendor != xpad->dev->id.vendor)
823 continue;
824
825 if (init_packet->idProduct != 0 &&
826 init_packet->idProduct != xpad->dev->id.product)
827 continue;
828
829 /* This packet applies to our device, so prepare to send it */
830 memcpy(xpad->odata, init_packet->data, init_packet->len);
831 xpad->irq_out->transfer_buffer_length = init_packet->len;
832
833 /* Update packet with current sequence number */
834 xpad->odata[2] = xpad->odata_serial++;
835 return true;
836 }
837
838 return false;
839}
840
841/* Callers must hold xpad->odata_lock spinlock */
751static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad) 842static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
752{ 843{
753 struct xpad_output_packet *pkt, *packet = NULL; 844 struct xpad_output_packet *pkt, *packet = NULL;
754 int i; 845 int i;
755 846
847 /* We may have init packets to send before we can send user commands */
848 if (xpad_prepare_next_init_packet(xpad))
849 return true;
850
756 for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) { 851 for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
757 if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS) 852 if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
758 xpad->last_out_packet = 0; 853 xpad->last_out_packet = 0;
@@ -938,24 +1033,17 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
938 1033
939static int xpad_start_xbox_one(struct usb_xpad *xpad) 1034static int xpad_start_xbox_one(struct usb_xpad *xpad)
940{ 1035{
941 struct xpad_output_packet *packet =
942 &xpad->out_packets[XPAD_OUT_CMD_IDX];
943 unsigned long flags; 1036 unsigned long flags;
944 int retval; 1037 int retval;
945 1038
946 spin_lock_irqsave(&xpad->odata_lock, flags); 1039 spin_lock_irqsave(&xpad->odata_lock, flags);
947 1040
948 /* Xbox one controller needs to be initialized. */ 1041 /*
949 packet->data[0] = 0x05; 1042 * Begin the init sequence by attempting to send a packet.
950 packet->data[1] = 0x20; 1043 * We will cycle through the init packet sequence before
951 packet->data[2] = xpad->odata_serial++; /* packet serial */ 1044 * sending any packets from the output ring.
952 packet->data[3] = 0x01; /* rumble bit enable? */ 1045 */
953 packet->data[4] = 0x00; 1046 xpad->init_seq = 0;
954 packet->len = 5;
955 packet->pending = true;
956
957 /* Reset the sequence so we send out start packet first */
958 xpad->last_out_packet = -1;
959 retval = xpad_try_sending_next_out_packet(xpad); 1047 retval = xpad_try_sending_next_out_packet(xpad);
960 1048
961 spin_unlock_irqrestore(&xpad->odata_lock, flags); 1049 spin_unlock_irqrestore(&xpad->odata_lock, flags);