* [PATCH 1/3] Input: xpad - add product ID for Xbox One S pad
2016-08-06 21:30 [PATCH 0/3] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
@ 2016-08-06 21:30 ` Cameron Gutman
2016-08-06 21:30 ` [PATCH 2/3] Input: xpad - fix One S pad disconnecting when not opened Cameron Gutman
2016-08-06 21:30 ` [PATCH 3/3] Input: xpad - fix stuck mode button on Xbox One S pad Cameron Gutman
2 siblings, 0 replies; 4+ messages in thread
From: Cameron Gutman @ 2016-08-06 21:30 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] 4+ messages in thread
* [PATCH 2/3] Input: xpad - fix One S pad disconnecting when not opened
2016-08-06 21:30 [PATCH 0/3] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
2016-08-06 21:30 ` [PATCH 1/3] Input: xpad - add product ID for " Cameron Gutman
@ 2016-08-06 21:30 ` Cameron Gutman
2016-08-06 21:30 ` [PATCH 3/3] Input: xpad - fix stuck mode button on Xbox One S pad Cameron Gutman
2 siblings, 0 replies; 4+ messages in thread
From: Cameron Gutman @ 2016-08-06 21:30 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 | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 19886db..6a3a775 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,20 @@ 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 +1604,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 +1649,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 +1669,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] 4+ messages in thread
* [PATCH 3/3] Input: xpad - fix stuck mode button on Xbox One S pad
2016-08-06 21:30 [PATCH 0/3] Input: xpad - improve support for new Xbox One S pad Cameron Gutman
2016-08-06 21:30 ` [PATCH 1/3] Input: xpad - add product ID for " Cameron Gutman
2016-08-06 21:30 ` [PATCH 2/3] Input: xpad - fix One S pad disconnecting when not opened Cameron Gutman
@ 2016-08-06 21:30 ` Cameron Gutman
2 siblings, 0 replies; 4+ messages in thread
From: Cameron Gutman @ 2016-08-06 21:30 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 | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 6a3a775..0dd5cf6 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,13 @@ 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 +982,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] 4+ messages in thread