linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad
@ 2016-08-16  4:10 Cameron Gutman
  2016-08-16  4:10 ` [PATCH v2 1/4] Input: xpad - add device ID for " Cameron Gutman
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Cameron Gutman @ 2016-08-16  4:10 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input

This pad generally works well enough on the current xpad, but there are
a few usability issues that I'm fixing with this series.

The notable changes:

The protocol seems to have changed a bit with the new pad. For one, it
needs an ack for the mode report now, otherwise it just retransmits it
forever. This makes the mode button look stuck down to userspace after
the first time it is pressed.

It also seems to overflow some internal buffer, hang, then eventually
reset the pad if there is user input without the driver listening.
This causes a spurious disconnection that may cause userspace programs
to behave unexpectedly.

Changes in v2:
Fixed multi-line comment style in patch 2 and 3 to be consistent with
the existing code. I've also added a simple patch to address rumble
issues on all Xbox One pads, including Xbox One S.

Cameron Gutman (4):
  Input: xpad - add device ID for Xbox One S pad
  Input: xpad - fix One S pad disconnecting when not opened
  Input: xpad - fix stuck mode button on Xbox One S pad
  Input: xpad - fix Xbox One rumble stopping after 2.5 secs

 drivers/input/joystick/xpad.c | 60 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 54 insertions(+), 6 deletions(-)

-- 
2.7.4


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

* [PATCH v2 1/4] Input: xpad - add device ID for Xbox One S pad
  2016-08-16  4:10 [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
@ 2016-08-16  4:10 ` Cameron Gutman
  2016-08-16  4:10 ` [PATCH v2 2/4] Input: xpad - fix One S pad disconnecting when not opened Cameron Gutman
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Cameron Gutman @ 2016-08-16  4:10 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input

This is the new gamepad that ships with the Xbox One S which
includes Bluetooth functionality.

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

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 83af17a..19886db 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -134,6 +134,7 @@ static const struct xpad_device {
 	{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
 	{ 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
 	{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE },
+	{ 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE },
 	{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
 	{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
 	{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
-- 
2.7.4


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

* [PATCH v2 2/4] Input: xpad - fix One S pad disconnecting when not opened
  2016-08-16  4:10 [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
  2016-08-16  4:10 ` [PATCH v2 1/4] Input: xpad - add device ID for " Cameron Gutman
@ 2016-08-16  4:10 ` Cameron Gutman
  2016-08-16  4:10 ` [PATCH v2 3/4] Input: xpad - fix stuck mode button on Xbox One S pad Cameron Gutman
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Cameron Gutman @ 2016-08-16  4:10 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input

The Xbox One S controller will hang after ~2 seconds of input
if it isn't being read by the OS. After another ~5 seconds the
controller will reset itself and reconnect to the host.

To avoid this, we'll just read Xbox One controllers all the time,
like we do for Xbox 360 wireless adapters.

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

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 19886db..3577253 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1381,7 +1381,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->xtype != XTYPE_XBOXONE) {
 		input_dev->open = xpad_open;
 		input_dev->close = xpad_close;
 	}
@@ -1573,9 +1573,21 @@ 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;
+
+		/*
+		 * Newer Xbox One controllers will hang and disconnect if
+		 * not initialized and read from when receiving user input.
+		 */
+		if (xpad->xtype == XTYPE_XBOXONE) {
+			error = xpad_start_input(xpad);
+			if (error)
+				goto err_deinit_input;
+		}
 	}
 	return 0;
 
+err_deinit_input:
+	xpad_deinit_input(xpad);
 err_deinit_output:
 	xpad_deinit_output(xpad);
 err_free_in_urb:
@@ -1593,6 +1605,8 @@ static void xpad_disconnect(struct usb_interface *intf)
 
 	if (xpad->xtype == XTYPE_XBOX360W)
 		xpad360w_stop_input(xpad);
+	else if (xpad->xtype == XTYPE_XBOXONE)
+		xpad_stop_input(xpad);
 
 	xpad_deinit_input(xpad);
 
@@ -1636,7 +1650,7 @@ static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
 			xpad360w_poweroff_controller(xpad);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input->users || xpad->xtype == XTYPE_XBOXONE)
 			xpad_stop_input(xpad);
 		mutex_unlock(&input->mutex);
 	}
@@ -1656,7 +1670,7 @@ static int xpad_resume(struct usb_interface *intf)
 		retval = xpad360w_start_input(xpad);
 	} else {
 		mutex_lock(&input->mutex);
-		if (input->users)
+		if (input->users || xpad->xtype == XTYPE_XBOXONE)
 			retval = xpad_start_input(xpad);
 		mutex_unlock(&input->mutex);
 	}
-- 
2.7.4


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

* [PATCH v2 3/4] Input: xpad - fix stuck mode button on Xbox One S pad
  2016-08-16  4:10 [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
  2016-08-16  4:10 ` [PATCH v2 1/4] Input: xpad - add device ID for " Cameron Gutman
  2016-08-16  4:10 ` [PATCH v2 2/4] Input: xpad - fix One S pad disconnecting when not opened Cameron Gutman
@ 2016-08-16  4:10 ` Cameron Gutman
  2016-08-16  4:10 ` [PATCH v2 4/4] Input: xpad - fix Xbox One rumble stopping after 2.5 secs Cameron Gutman
  2016-10-04 19:29 ` [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
  4 siblings, 0 replies; 6+ messages in thread
From: Cameron Gutman @ 2016-08-16  4:10 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input

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 3577253..42723ba 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -389,6 +389,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
@@ -699,6 +700,14 @@ static void xpadone_process_packet(struct usb_xpad *xpad,
 		break;
 
 	case 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]);
+
 		/* the xbox button has its own special report */
 		input_report_key(dev, BTN_MODE, data[4] & 0x01);
 		input_sync(dev);
@@ -974,6 +983,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.7.4


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

* [PATCH v2 4/4] Input: xpad - fix Xbox One rumble stopping after 2.5 secs
  2016-08-16  4:10 [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
                   ` (2 preceding siblings ...)
  2016-08-16  4:10 ` [PATCH v2 3/4] Input: xpad - fix stuck mode button on Xbox One S pad Cameron Gutman
@ 2016-08-16  4:10 ` Cameron Gutman
  2016-10-04 19:29 ` [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
  4 siblings, 0 replies; 6+ messages in thread
From: Cameron Gutman @ 2016-08-16  4:10 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input

Unlike previous Xbox pads, the Xbox One pad doesn't have
"sticky" rumble packets. The duration is encoded into
the command and expiration is handled by the pad firmware.

ff-memless needs pseudo-sticky behavior for rumble effects
to behave properly for long duration effects. We already
specify the maximum rumble on duration in the command
packets, but it's still only good for about 2.5 seconds
of rumble. This is easily reproducable running fftest's
sine vibration test.

It turns out there's a repeat count encoded in the rumble
command. We can abuse that to get the pseudo-sticky behavior
needed for rumble to behave as expected for effects with long
duration.

By my math, this change should allow a single ff_effect to
rumble for 10 minutes straight, which should be more than
enough for most needs.

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

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 42723ba..8954643 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1078,9 +1078,9 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
 		packet->data[7] = 0x00;
 		packet->data[8] = strong / 512;	/* left actuator */
 		packet->data[9] = weak / 512;	/* right actuator */
-		packet->data[10] = 0xFF;
-		packet->data[11] = 0x00;
-		packet->data[12] = 0x00;
+		packet->data[10] = 0xFF; /* on period */
+		packet->data[11] = 0x00; /* off period */
+		packet->data[12] = 0xFF; /* repeat count */
 		packet->len = 13;
 		packet->pending = true;
 		break;
-- 
2.7.4


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

* Re: [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad
  2016-08-16  4:10 [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
                   ` (3 preceding siblings ...)
  2016-08-16  4:10 ` [PATCH v2 4/4] Input: xpad - fix Xbox One rumble stopping after 2.5 secs Cameron Gutman
@ 2016-10-04 19:29 ` Cameron Gutman
  4 siblings, 0 replies; 6+ messages in thread
From: Cameron Gutman @ 2016-10-04 19:29 UTC (permalink / raw)
  To: dmitry.torokhov, rojtberg; +Cc: linux-input

On 08/15/2016 09:10 PM, Cameron Gutman wrote:
> This pad generally works well enough on the current xpad, but there are
> a few usability issues that I'm fixing with this series.
> 
> The notable changes:
> 
> The protocol seems to have changed a bit with the new pad. For one, it
> needs an ack for the mode report now, otherwise it just retransmits it
> forever. This makes the mode button look stuck down to userspace after
> the first time it is pressed.
> 
> It also seems to overflow some internal buffer, hang, then eventually
> reset the pad if there is user input without the driver listening.
> This causes a spurious disconnection that may cause userspace programs
> to behave unexpectedly.
> 
> Changes in v2:
> Fixed multi-line comment style in patch 2 and 3 to be consistent with
> the existing code. I've also added a simple patch to address rumble
> issues on all Xbox One pads, including Xbox One S.
> 
> Cameron Gutman (4):
>   Input: xpad - add device ID for Xbox One S pad
>   Input: xpad - fix One S pad disconnecting when not opened
>   Input: xpad - fix stuck mode button on Xbox One S pad
>   Input: xpad - fix Xbox One rumble stopping after 2.5 secs
> 
>  drivers/input/joystick/xpad.c | 60 ++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 54 insertions(+), 6 deletions(-)
> 

Hi Dmitry,

I'm just following up on these patches. Do you want any changes or are they
fine as is?

Pavel has already applied the patches to his out-of-tree xpad driver [0].

[0] https://github.com/paroj/xpad

Thanks,
Cameron

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

end of thread, other threads:[~2016-10-04 19:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-16  4:10 [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
2016-08-16  4:10 ` [PATCH v2 1/4] Input: xpad - add device ID for " Cameron Gutman
2016-08-16  4:10 ` [PATCH v2 2/4] Input: xpad - fix One S pad disconnecting when not opened Cameron Gutman
2016-08-16  4:10 ` [PATCH v2 3/4] Input: xpad - fix stuck mode button on Xbox One S pad Cameron Gutman
2016-08-16  4:10 ` [PATCH v2 4/4] Input: xpad - fix Xbox One rumble stopping after 2.5 secs Cameron Gutman
2016-10-04 19:29 ` [PATCH v2 0/4] Input: xpad - improve support for new Xbox One S pad Cameron Gutman

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).