Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1573783 > unrolled thread

[PATCH 0/5] Correctly support some quirky Xbox One pads

Started byCameron Gutman <aicommander@gmail.com>
First post2017-02-05 01:40 +0100
Last post2017-02-05 01:40 +0100
Articles 12 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/5] Correctly support some quirky Xbox One pads Cameron Gutman <aicommander@gmail.com> - 2017-02-05 01:40 +0100
    [PATCH 2/5] Input: xpad - add init packet for Hori and Titanfall 2 pads Cameron Gutman <aicommander@gmail.com> - 2017-02-05 01:40 +0100
    [PATCH 5/5] Input: xpad - fix stuck mode button on Xbox One S pad Cameron Gutman <aicommander@gmail.com> - 2017-02-05 01:40 +0100
      Re: [PATCH 5/5] Input: xpad - fix stuck mode button on Xbox One S pad Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2017-02-06 23:10 +0100
    [PATCH 4/5] Input: xpad - restore LED state after device resume Cameron Gutman <aicommander@gmail.com> - 2017-02-05 01:40 +0100
      Re: [PATCH 4/5] Input: xpad - restore LED state after device resume kbuild test robot <lkp@intel.com> - 2017-02-05 02:20 +0100
        Re: [PATCH 4/5] Input: xpad - restore LED state after device resume Cameron Gutman <aicommander@gmail.com> - 2017-02-05 02:50 +0100
      Re: [PATCH 4/5] Input: xpad - restore LED state after device resume Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2017-02-06 23:10 +0100
        Re: [PATCH 4/5] Input: xpad - restore LED state after device resume Cameron Gutman <aicommander@gmail.com> - 2017-02-07 00:00 +0100
    [PATCH 3/5] Input: xpad - send rumble on Xbox One init to fix PowerA pads Cameron Gutman <aicommander@gmail.com> - 2017-02-05 01:40 +0100
      Re: [PATCH 3/5] Input: xpad - send rumble on Xbox One init to fix  PowerA pads Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2017-02-06 23:20 +0100
    [PATCH 1/5] Input: xpad - use a packet array to start Xbox One pads Cameron Gutman <aicommander@gmail.com> - 2017-02-05 01:40 +0100

#1573783 — [PATCH 0/5] Correctly support some quirky Xbox One pads

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-05 01:40 +0100
Subject[PATCH 0/5] Correctly support some quirky Xbox One pads
Message-ID<t7j21-8qv-3@gated-at.bofh.it>
There are a bunch of quirky Xbox One pads that depend on weird
initialization things that the Microsoft pads don't. In this series,
I've incorporated quirk handling from Valve's Steam Link driver[0]
and the 360Controller project[1] for macOS.

Patches 1 - 3 are split that way in case 2 or 3 introduce regressions
that need to be bisected. The new packet in patch 2 has been in Pavel's
xpad repository[2] for a little over a month without complaints, and
patch 3 just sends a rumble packet on init, so I don't expect regressions.

Patch 2 was tested by a GitHub user with a Hori pad[3]. I've tested patch 3
on a previously non-working PowerA pad that I got my hands on.

I folded Patch 4 into this series as it was previously submitted alone.
It is unchanged from its original submission.

Patch 5 was a patch I had previously dropped from a previous series, but it
turns out to still be needed for Xbox One S pads on the latest firmware. It
has also been in Pavel's repository for months without complaints.

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

Cameron Gutman (5):
  Input: xpad - use a packet array to start Xbox One pads
  Input: xpad - add init packet for Hori and Titanfall 2 pads
  Input: xpad - send rumble on Xbox One init to fix PowerA pads
  Input: xpad - restore LED state after device resume
  Input: xpad - fix stuck mode button on Xbox One S pad

 drivers/input/joystick/xpad.c | 102 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 88 insertions(+), 14 deletions(-)

-- 
2.9.3

[toc] | [next] | [standalone]


#1573784 — [PATCH 2/5] Input: xpad - add init packet for Hori and Titanfall 2 pads

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-05 01:40 +0100
Subject[PATCH 2/5] Input: xpad - add init packet for Hori and Titanfall 2 pads
Message-ID<t7j21-8qv-11@gated-at.bofh.it>
In reply to#1573783
Without sending this packet, the Titanfall 2 pad (0x0e6f:0x0165)
continuously attempts to handshake with the PC and never sends
any input reports.

The Hori gamepad (0x0f0d:0x0067) analog sticks don't work if
this isn't sent, though other buttons do work without it.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
 drivers/input/joystick/xpad.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 6f07b5b..3f19f32b 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -346,6 +346,14 @@ struct xpad_output_packet {
 /* Sequence numbers will be added before the packets are sent */
 static const struct xpad_output_packet xone_init_pkt[] = {
 	/*
+	 * 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.
+	 */
+	{{0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
+	  0x00, 0x00, 0x00, 0x80, 0x00}, 13, true},
+
+	/*
 	 * This packet is required for all Xbox One pads with 2015
 	 * or later firmware installed (or present from the factory).
 	 */
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1573785 — [PATCH 5/5] Input: xpad - fix stuck mode button on Xbox One S pad

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-05 01:40 +0100
Subject[PATCH 5/5] Input: xpad - fix stuck mode button on Xbox One S pad
Message-ID<t7j21-8qv-7@gated-at.bofh.it>
In reply to#1573783
The Xbox One S requires an ack to its mode button report
otherwise it continuously retransmits the report. This
makes the mode button appear to be stuck down after it
is pressed for the first time.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
 drivers/input/joystick/xpad.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 1179266..eb01c54 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -414,6 +414,7 @@ struct usb_xpad {
 
 static int xpad_init_input(struct usb_xpad *xpad);
 static void xpad_deinit_input(struct usb_xpad *xpad);
+static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
 
 /*
  *	xpad_process_packet
@@ -647,6 +648,14 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
 
 	/* the xbox button has its own special report */
 	if (data[0] == 0X07) {
+		/*
+		 * The Xbox One S controller requires these reports to be
+		 * acked otherwise it continues sending them forever and
+		 * won't report further mode button events.
+		 */
+		if (data[1] == 0x30)
+			xpadone_ack_mode_report(xpad, data[2]);
+
 		input_report_key(dev, BTN_MODE, data[4] & 0x01);
 		input_sync(dev);
 		return;
@@ -983,6 +992,30 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
 	return retval;
 }
 
+static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
+{
+	unsigned long flags;
+	struct xpad_output_packet *packet =
+			&xpad->out_packets[XPAD_OUT_CMD_IDX];
+	static const u8 mode_report_ack[] = {
+		0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
+		0x00, 0x00, 0x00, 0x00, 0x00
+	};
+
+	spin_lock_irqsave(&xpad->odata_lock, flags);
+
+	packet->len = sizeof(mode_report_ack);
+	memcpy(packet->data, mode_report_ack, packet->len);
+	packet->data[2] = seq_num;
+	packet->pending = true;
+
+	/* Reset the sequence so we send out the ack now */
+	xpad->last_out_packet = -1;
+	xpad_try_sending_next_out_packet(xpad);
+
+	spin_unlock_irqrestore(&xpad->odata_lock, flags);
+}
+
 #ifdef CONFIG_JOYSTICK_XPAD_FF
 static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
 {
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1575197 — Re: [PATCH 5/5] Input: xpad - fix stuck mode button on Xbox One S pad

FromDmitry Torokhov <dmitry.torokhov@gmail.com>
Date2017-02-06 23:10 +0100
SubjectRe: [PATCH 5/5] Input: xpad - fix stuck mode button on Xbox One S pad
Message-ID<t7ZDY-2rk-31@gated-at.bofh.it>
In reply to#1573785
On Sat, Feb 04, 2017 at 04:30:02PM -0800, Cameron Gutman wrote:
> The Xbox One S requires an ack to its mode button report
> otherwise it continuously retransmits the report. This
> makes the mode button appear to be stuck down after it
> is pressed for the first time.
> 
> Signed-off-by: Cameron Gutman <aicommander@gmail.com>

Applied, thank you.

> ---
>  drivers/input/joystick/xpad.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index 1179266..eb01c54 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -414,6 +414,7 @@ struct usb_xpad {
>  
>  static int xpad_init_input(struct usb_xpad *xpad);
>  static void xpad_deinit_input(struct usb_xpad *xpad);
> +static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
>  
>  /*
>   *	xpad_process_packet
> @@ -647,6 +648,14 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
>  
>  	/* the xbox button has its own special report */
>  	if (data[0] == 0X07) {
> +		/*
> +		 * The Xbox One S controller requires these reports to be
> +		 * acked otherwise it continues sending them forever and
> +		 * won't report further mode button events.
> +		 */
> +		if (data[1] == 0x30)
> +			xpadone_ack_mode_report(xpad, data[2]);
> +
>  		input_report_key(dev, BTN_MODE, data[4] & 0x01);
>  		input_sync(dev);
>  		return;
> @@ -983,6 +992,30 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
>  	return retval;
>  }
>  
> +static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
> +{
> +	unsigned long flags;
> +	struct xpad_output_packet *packet =
> +			&xpad->out_packets[XPAD_OUT_CMD_IDX];
> +	static const u8 mode_report_ack[] = {
> +		0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
> +		0x00, 0x00, 0x00, 0x00, 0x00
> +	};
> +
> +	spin_lock_irqsave(&xpad->odata_lock, flags);
> +
> +	packet->len = sizeof(mode_report_ack);
> +	memcpy(packet->data, mode_report_ack, packet->len);
> +	packet->data[2] = seq_num;
> +	packet->pending = true;
> +
> +	/* Reset the sequence so we send out the ack now */
> +	xpad->last_out_packet = -1;
> +	xpad_try_sending_next_out_packet(xpad);
> +
> +	spin_unlock_irqrestore(&xpad->odata_lock, flags);
> +}
> +
>  #ifdef CONFIG_JOYSTICK_XPAD_FF
>  static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
>  {
> -- 
> 2.9.3
> 

-- 
Dmitry

[toc] | [prev] | [next] | [standalone]


#1573788 — [PATCH 4/5] Input: xpad - restore LED state after device resume

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-05 01:40 +0100
Subject[PATCH 4/5] Input: xpad - restore LED state after device resume
Message-ID<t7j21-8qv-15@gated-at.bofh.it>
In reply to#1573783
The state of pad LEDs can be inconsistent when the system is
woken up after sleep. Rather than leaving the controllers blinking,
let's resend the last LED command to Xbox 360 pads on resume.

Since Xbox One pads stop flashing only when reinitialized, we'll
send them the initialization packet so they calm down too.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
 drivers/input/joystick/xpad.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 13f298d..1179266 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1683,11 +1683,23 @@ static int xpad_resume(struct usb_interface *intf)
 		retval = xpad360w_start_input(xpad);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input->users) {
 			retval = xpad_start_input(xpad);
+		} else if (xpad->xtype == XTYPE_XBOXONE) {
+			/*
+			 * Even if there are no users, we'll send Xbox One pads
+			 * the startup sequence so they don't sit there and
+			 * blink until somebody opens the input device again.
+			 */
+			retval = xpad_start_xbox_one(xpad);
+		}
 		mutex_unlock(&input->mutex);
 	}
 
+	/* LED state is lost across resume, so resend the last command */
+	if (xpad->led)
+		xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
+
 	return retval;
 }
 
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1573794 — Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

Fromkbuild test robot <lkp@intel.com>
Date2017-02-05 02:20 +0100
SubjectRe: [PATCH 4/5] Input: xpad - restore LED state after device resume
Message-ID<t7jEJ-tr-3@gated-at.bofh.it>
In reply to#1573788

[Multipart message — attachments visible in raw view] — view raw

Hi Cameron,

[auto build test ERROR on input/next]
[also build test ERROR on v4.10-rc6 next-20170203]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Cameron-Gutman/Correctly-support-some-quirky-Xbox-One-pads/20170205-083659
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
config: x86_64-randconfig-x016-201706 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/input/joystick/xpad.c: In function 'xpad_resume':
>> drivers/input/joystick/xpad.c:1700:10: error: 'struct usb_xpad' has no member named 'led'
     if (xpad->led)
             ^~
>> drivers/input/joystick/xpad.c:1701:3: error: implicit declaration of function 'xpad_send_led_command' [-Werror=implicit-function-declaration]
      xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
      ^~~~~~~~~~~~~~~~~~~~~
   drivers/input/joystick/xpad.c:1701:35: error: 'struct usb_xpad' has no member named 'led'
      xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
                                      ^~
   cc1: some warnings being treated as errors

vim +1700 drivers/input/joystick/xpad.c

  1694				retval = xpad_start_xbox_one(xpad);
  1695			}
  1696			mutex_unlock(&input->mutex);
  1697		}
  1698	
  1699		/* LED state is lost across resume, so resend the last command */
> 1700		if (xpad->led)
> 1701			xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
  1702	
  1703		return retval;
  1704	}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[toc] | [prev] | [next] | [standalone]


#1573796 — Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-05 02:50 +0100
SubjectRe: [PATCH 4/5] Input: xpad - restore LED state after device resume
Message-ID<t7k7L-DR-3@gated-at.bofh.it>
In reply to#1573794
On 02/04/2017 05:17 PM, kbuild test robot wrote:
> Hi Cameron,
> 
> [auto build test ERROR on input/next]
> [also build test ERROR on v4.10-rc6 next-20170203]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Cameron-Gutman/Correctly-support-some-quirky-Xbox-One-pads/20170205-083659
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
> config: x86_64-randconfig-x016-201706 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/input/joystick/xpad.c: In function 'xpad_resume':
>>> drivers/input/joystick/xpad.c:1700:10: error: 'struct usb_xpad' has no member named 'led'
>      if (xpad->led)
>              ^~
>>> drivers/input/joystick/xpad.c:1701:3: error: implicit declaration of function 'xpad_send_led_command' [-Werror=implicit-function-declaration]
>       xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
>       ^~~~~~~~~~~~~~~~~~~~~
>    drivers/input/joystick/xpad.c:1701:35: error: 'struct usb_xpad' has no member named 'led'
>       xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
>                                       ^~
>    cc1: some warnings being treated as errors

Whoops, missed a CONFIG_JOYSTICK_XPAD_LEDS guard around that.

I'll send a v2 in the next day or two, incorporating this fix plus any review
comments made in the meantime.

> 
> vim +1700 drivers/input/joystick/xpad.c
> 
>   1694				retval = xpad_start_xbox_one(xpad);
>   1695			}
>   1696			mutex_unlock(&input->mutex);
>   1697		}
>   1698	
>   1699		/* LED state is lost across resume, so resend the last command */
>> 1700		if (xpad->led)
>> 1701			xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
>   1702	
>   1703		return retval;
>   1704	}
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> 

Regards,
Cameron

[toc] | [prev] | [next] | [standalone]


#1575194 — Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

FromDmitry Torokhov <dmitry.torokhov@gmail.com>
Date2017-02-06 23:10 +0100
SubjectRe: [PATCH 4/5] Input: xpad - restore LED state after device resume
Message-ID<t7ZDY-2rk-29@gated-at.bofh.it>
In reply to#1573788
On Sat, Feb 04, 2017 at 04:30:01PM -0800, Cameron Gutman wrote:
> The state of pad LEDs can be inconsistent when the system is
> woken up after sleep. Rather than leaving the controllers blinking,
> let's resend the last LED command to Xbox 360 pads on resume.
> 
> Since Xbox One pads stop flashing only when reinitialized, we'll
> send them the initialization packet so they calm down too.
> 
> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
> ---
>  drivers/input/joystick/xpad.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index 13f298d..1179266 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -1683,11 +1683,23 @@ static int xpad_resume(struct usb_interface *intf)
>  		retval = xpad360w_start_input(xpad);
>  	} else {
>  		mutex_lock(&input->mutex);
> -		if (input->users)
> +		if (input->users) {
>  			retval = xpad_start_input(xpad);
> +		} else if (xpad->xtype == XTYPE_XBOXONE) {
> +			/*
> +			 * Even if there are no users, we'll send Xbox One pads
> +			 * the startup sequence so they don't sit there and
> +			 * blink until somebody opens the input device again.
> +			 */
> +			retval = xpad_start_xbox_one(xpad);
> +		}
>  		mutex_unlock(&input->mutex);
>  	}
>  
> +	/* LED state is lost across resume, so resend the last command */
> +	if (xpad->led)
> +		xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);

I can see that we might need to send the "start" command, but I am not
sure that explicitly calling xpad_send_led_command() is needed: LED core
should restore LED state upon resume, and this should happen after its
parent (i.e. xbox device) is resumed.

Thanks.

-- 
Dmitry

[toc] | [prev] | [next] | [standalone]


#1575230 — Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-07 00:00 +0100
SubjectRe: [PATCH 4/5] Input: xpad - restore LED state after device resume
Message-ID<t80qr-2JH-29@gated-at.bofh.it>
In reply to#1575194
On 02/06/2017 02:05 PM, Dmitry Torokhov wrote:
> On Sat, Feb 04, 2017 at 04:30:01PM -0800, Cameron Gutman wrote:
>> The state of pad LEDs can be inconsistent when the system is
>> woken up after sleep. Rather than leaving the controllers blinking,
>> let's resend the last LED command to Xbox 360 pads on resume.
>>
>> Since Xbox One pads stop flashing only when reinitialized, we'll
>> send them the initialization packet so they calm down too.
>>
>> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
>> ---
>>  drivers/input/joystick/xpad.c | 14 +++++++++++++-
>>  1 file changed, 13 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
>> index 13f298d..1179266 100644
>> --- a/drivers/input/joystick/xpad.c
>> +++ b/drivers/input/joystick/xpad.c
>> @@ -1683,11 +1683,23 @@ static int xpad_resume(struct usb_interface *intf)
>>  		retval = xpad360w_start_input(xpad);
>>  	} else {
>>  		mutex_lock(&input->mutex);
>> -		if (input->users)
>> +		if (input->users) {
>>  			retval = xpad_start_input(xpad);
>> +		} else if (xpad->xtype == XTYPE_XBOXONE) {
>> +			/*
>> +			 * Even if there are no users, we'll send Xbox One pads
>> +			 * the startup sequence so they don't sit there and
>> +			 * blink until somebody opens the input device again.
>> +			 */
>> +			retval = xpad_start_xbox_one(xpad);
>> +		}
>>  		mutex_unlock(&input->mutex);
>>  	}
>>  
>> +	/* LED state is lost across resume, so resend the last command */
>> +	if (xpad->led)
>> +		xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
> 
> I can see that we might need to send the "start" command, but I am not
> sure that explicitly calling xpad_send_led_command() is needed: LED core
> should restore LED state upon resume, and this should happen after its
> parent (i.e. xbox device) is resumed.
> 
> Thanks.
> 

Ah, so it seems we're missing the LED_CORE_SUSPENDRESUME flag on our LED
device required for that to happen automatically. I'll just use that
instead of manually setting brightness on resume.

[toc] | [prev] | [next] | [standalone]


#1573789 — [PATCH 3/5] Input: xpad - send rumble on Xbox One init to fix PowerA pads

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-05 01:40 +0100
Subject[PATCH 3/5] Input: xpad - send rumble on Xbox One init to fix PowerA pads
Message-ID<t7j21-8qv-17@gated-at.bofh.it>
In reply to#1573783
Some PowerA pads require a rumble packet to start sending
input reports.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
 drivers/input/joystick/xpad.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 3f19f32b..13f298d 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -358,6 +358,13 @@ static const struct xpad_output_packet xone_init_pkt[] = {
 	 * or later firmware installed (or present from the factory).
 	 */
 	{{0x05, 0x20, 0x00, 0x01, 0x00}, 5, true},
+
+	/*
+	 * A rumble packet is required for some PowerA pads to start
+	 * sending input reports. One of those pads is (0x24c6:0x543a).
+	 */
+	{{0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
+	  0x00, 0x00, 0x00, 0x00, 0x00}, 13, true},
 };
 
 #define XPAD_OUT_CMD_IDX	0
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1575205 — Re: [PATCH 3/5] Input: xpad - send rumble on Xbox One init to fix PowerA pads

FromDmitry Torokhov <dmitry.torokhov@gmail.com>
Date2017-02-06 23:20 +0100
SubjectRe: [PATCH 3/5] Input: xpad - send rumble on Xbox One init to fix PowerA pads
Message-ID<t7ZNE-2v6-27@gated-at.bofh.it>
In reply to#1573789
On Sat, Feb 04, 2017 at 04:30:00PM -0800, Cameron Gutman wrote:
> Some PowerA pads require a rumble packet to start sending
> input reports.
> 
> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
> ---
>  drivers/input/joystick/xpad.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index 3f19f32b..13f298d 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -358,6 +358,13 @@ static const struct xpad_output_packet xone_init_pkt[] = {
>  	 * or later firmware installed (or present from the factory).
>  	 */
>  	{{0x05, 0x20, 0x00, 0x01, 0x00}, 5, true},
> +
> +	/*
> +	 * A rumble packet is required for some PowerA pads to start
> +	 * sending input reports. One of those pads is (0x24c6:0x543a).
> +	 */
> +	{{0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
> +	  0x00, 0x00, 0x00, 0x00, 0x00}, 13, true},

I am uncomfortable with us just blasting random commands to random
controllers. Can we make it device-dependent. I.e:

struct xboxone_init_packet = {
	u16 idVendor;
	u16 idProduct;
	const u8 *data;
	size_t len;
};

static const u8 xboxone_powera_init[] = {
	0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00
};

#define XBOXONE_INIT_PKT(_vid, _pid, _data)		\
	{						\
		.idVendor	= (_vid),		\
		.idProduct	= (_pid),		\
		.data		= (_data),		\
		.len		= ARRAY_SIZE(data),	\
	}
...

static const struct xboxone_init_packet xboxone_init_packets[] = {
	...
	XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_powera_init),
	...

With 0/0 VID/PID being "catch all" entry.

BTW, why do we set "pending" on these ones? I do not think it is needed.

Thanks.

-- 
Dmitry

[toc] | [prev] | [next] | [standalone]


#1573790 — [PATCH 1/5] Input: xpad - use a packet array to start Xbox One pads

FromCameron Gutman <aicommander@gmail.com>
Date2017-02-05 01:40 +0100
Subject[PATCH 1/5] Input: xpad - use a packet array to start Xbox One pads
Message-ID<t7j21-8qv-5@gated-at.bofh.it>
In reply to#1573783
This is preparatory work for supporting some 3rd party
pads that need more initialization packets than just
one. No initialization behavior change expected.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
 drivers/input/joystick/xpad.c | 40 +++++++++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 247fd3a..6f07b5b 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -343,6 +343,15 @@ struct xpad_output_packet {
 	bool pending;
 };
 
+/* Sequence numbers will be added before the packets are sent */
+static const struct xpad_output_packet xone_init_pkt[] = {
+	/*
+	 * This packet is required for all Xbox One pads with 2015
+	 * or later firmware installed (or present from the factory).
+	 */
+	{{0x05, 0x20, 0x00, 0x01, 0x00}, 5, true},
+};
+
 #define XPAD_OUT_CMD_IDX	0
 #define XPAD_OUT_FF_IDX		1
 #define XPAD_OUT_LED_IDX	(1 + IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF))
@@ -373,6 +382,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;
@@ -742,8 +752,19 @@ static void xpad_irq_in(struct urb *urb)
 static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
 {
 	struct xpad_output_packet *pkt, *packet = NULL;
+	const struct xpad_output_packet *init_packet;
 	int i;
 
+	if (xpad->xtype == XTYPE_XBOXONE && xpad->init_seq < ARRAY_SIZE(xone_init_pkt)) {
+		init_packet = &xone_init_pkt[xpad->init_seq++];
+		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;
+	}
+
 	for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
 		if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
 			xpad->last_out_packet = 0;
@@ -929,24 +950,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

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web