All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Input: xpad - Poweroff XBOX360W on mode button long press
@ 2021-11-13 13:11 Benjamin Valentin
  2021-11-14  1:52 ` Cameron Gutman
  0 siblings, 1 reply; 6+ messages in thread
From: Benjamin Valentin @ 2021-11-13 13:11 UTC (permalink / raw)
  To: Dmitry Torokhov, linux-input; +Cc: Lee Jones, lawl

Newer gamepads turn themselves off when the mode button is held down.
For XBOX360W gamepads we must do this in the driver.

Power off the gamepad after 2s of holding down the button.

Signed-off-by: lawl <github@dumbinter.net>
Signed-off-by: Benjamin Valentin <benpicco@googlemail.com>
---
 drivers/input/joystick/xpad.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 18caaf436ed4..e36c4b0abd4b 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -619,11 +619,13 @@ struct usb_xpad {
 	int pad_nr;			/* the order x360 pads were attached */
 	const char *name;		/* name of the device */
 	struct work_struct work;	/* init/remove device from callback */
+	time64_t mode_btn_down_ts;	/* timestamp when mode button was pressed */
 };
 
 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);
+static void xpad360w_poweroff_controller(struct usb_xpad *xpad);
 
 /*
  *	xpad_process_packet
@@ -775,6 +777,24 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
 	}
 
 	input_sync(dev);
+
+	/* xbox360w controllers can't be turned off without driver assistance */
+	if (xpad->xtype == XTYPE_XBOX360W) {
+		if (xpad->mode_btn_down_ts > 0
+		    && xpad->pad_present
+		    /* send power off after 2s of holding the button */
+		    && (ktime_get_seconds() - xpad->mode_btn_down_ts) >= 2) {
+			xpad360w_poweroff_controller(xpad);
+			xpad->mode_btn_down_ts = 0;
+			return;
+		}
+
+		/* mode button down/up */
+		if (data[3] & 0x04)
+			xpad->mode_btn_down_ts = ktime_get_seconds();
+		else
+			xpad->mode_btn_down_ts = 0;
+	}
 }
 
 static void xpad_presence_work(struct work_struct *work)
-- 
2.32.0

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

* Re: [PATCH] Input: xpad - Poweroff XBOX360W on mode button long press
  2021-11-13 13:11 [PATCH] Input: xpad - Poweroff XBOX360W on mode button long press Benjamin Valentin
@ 2021-11-14  1:52 ` Cameron Gutman
  2021-11-14 19:23   ` [PATCH v2] " Benjamin Valentin
                     ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Cameron Gutman @ 2021-11-14  1:52 UTC (permalink / raw)
  To: Benjamin Valentin, Dmitry Torokhov, linux-input; +Cc: Lee Jones, lawl

On 11/13/21 07:11, Benjamin Valentin wrote:
> Newer gamepads turn themselves off when the mode button is held down.
> For XBOX360W gamepads we must do this in the driver.
> 
> Power off the gamepad after 2s of holding down the button.
> 

2 seconds is pretty short. It seems like there's a pretty good chance a
user might accidentally turn their gamepad off when trying to activate
something mapped to a long-press on the guide/mode button.

I timed a couple of my Xbox One gamepads and they both took 5-7 seconds
to power off when holding down the button. How about 5 seconds here?

> Signed-off-by: lawl <github@dumbinter.net>
> Signed-off-by: Benjamin Valentin <benpicco@googlemail.com>
> ---

Regards,
Cameron

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

* [PATCH v2] Input: xpad - Poweroff XBOX360W on mode button long press
  2021-11-14  1:52 ` Cameron Gutman
@ 2021-11-14 19:23   ` Benjamin Valentin
  2021-11-16 16:23   ` [PATCH 1/2] Input: xpad - name unknown gamepads according to device type Benjamin Valentin
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Benjamin Valentin @ 2021-11-14 19:23 UTC (permalink / raw)
  To: Cameron Gutman; +Cc: Dmitry Torokhov, linux-input, Lee Jones, lawl

Newer gamepads turn themselves off when the mode button is held down.
For XBOX360W gamepads we must do this in the driver.

Power off the gamepad after 5s of holding down the button.

Signed-off-by: lawl <github@dumbinter.net>
Signed-off-by: Benjamin Valentin <benpicco@googlemail.com>
---
Changed the timeout back to 5s

 drivers/input/joystick/xpad.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 18caaf436ed4..e36c4b0abd4b 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -619,11 +619,13 @@ struct usb_xpad {
 	int pad_nr;			/* the order x360 pads were attached */
 	const char *name;		/* name of the device */
 	struct work_struct work;	/* init/remove device from callback */
+	time64_t mode_btn_down_ts;	/* timestamp when mode button was pressed */
 };
 
 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);
+static void xpad360w_poweroff_controller(struct usb_xpad *xpad);
 
 /*
  *	xpad_process_packet
@@ -775,6 +777,24 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
 	}
 
 	input_sync(dev);
+
+	/* xbox360w controllers can't be turned off without driver assistance */
+	if (xpad->xtype == XTYPE_XBOX360W) {
+		if (xpad->mode_btn_down_ts > 0
+		    && xpad->pad_present
+		    /* send power off after 5s of holding the button */
+		    && (ktime_get_seconds() - xpad->mode_btn_down_ts) >= 5) {
+			xpad360w_poweroff_controller(xpad);
+			xpad->mode_btn_down_ts = 0;
+			return;
+		}
+
+		/* mode button down/up */
+		if (data[3] & 0x04)
+			xpad->mode_btn_down_ts = ktime_get_seconds();
+		else
+			xpad->mode_btn_down_ts = 0;
+	}
 }
 
 static void xpad_presence_work(struct work_struct *work)
-- 
2.32.0

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

* [PATCH 1/2] Input: xpad - name unknown gamepads according to device type
  2021-11-14  1:52 ` Cameron Gutman
  2021-11-14 19:23   ` [PATCH v2] " Benjamin Valentin
@ 2021-11-16 16:23   ` Benjamin Valentin
  2021-11-16 16:25   ` [PATCH 2/2] Input: xpad - drop checks for XTYPE_UNKNOWN Benjamin Valentin
  2022-01-05 11:53   ` [RESEND][PATCH v2] Input: xpad - Poweroff XBOX360W on mode button long press Benjamin Valentin
  3 siblings, 0 replies; 6+ messages in thread
From: Benjamin Valentin @ 2021-11-16 16:23 UTC (permalink / raw)
  To: Cameron Gutman; +Cc: Dmitry Torokhov, linux-input, Lee Jones

Calling any unknown device 'Generic X-Box pad' can lead to confusion
as a user might think the device type was not properly detected.

The different controller generations also have different button numbers
and mappings.

Instead use a device type specific name so it's immediately clear that
the device has been recognized.

This means we can now drop the "Generic X-Box pad" entry.
To allow the entire line to be 0, re-order the device types so that
'UNKNOWN' is 0 now too.

Signed-off-by: Benjamin Valentin <benpicco@googlemail.com>
---
 drivers/input/joystick/xpad.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 4c914f75a902..31a268f43b5b 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -83,11 +83,11 @@
 #define DANCEPAD_MAP_CONFIG	(MAP_DPAD_TO_BUTTONS |			\
 				MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
 
-#define XTYPE_XBOX        0
-#define XTYPE_XBOX360     1
-#define XTYPE_XBOX360W    2
-#define XTYPE_XBOXONE     3
-#define XTYPE_UNKNOWN     4
+#define XTYPE_UNKNOWN     0
+#define XTYPE_XBOX        1
+#define XTYPE_XBOX360     2
+#define XTYPE_XBOX360W    3
+#define XTYPE_XBOXONE     4
 
 static bool dpad_to_buttons;
 module_param(dpad_to_buttons, bool, S_IRUGO);
@@ -337,7 +337,7 @@ static const struct xpad_device {
 	{ 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
 	{ 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
 	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
-	{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
+	{ }
 };
 
 /* buttons shared with xbox and xbox360 */
@@ -1783,14 +1783,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 
 	if (xpad->xtype == XTYPE_UNKNOWN) {
 		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
-			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
+			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) {
 				xpad->xtype = XTYPE_XBOX360W;
-			else if (intf->cur_altsetting->desc.bInterfaceProtocol == 208)
+				xpad->name = "Xbox 360 wireless pad";
+			} else if (intf->cur_altsetting->desc.bInterfaceProtocol == 208) {
 				xpad->xtype = XTYPE_XBOXONE;
-			else
+				xpad->name = "Xbox One pad";
+			} else {
 				xpad->xtype = XTYPE_XBOX360;
+				xpad->name = "Xbox 360 pad";
+			}
 		} else {
 			xpad->xtype = XTYPE_XBOX;
+			xpad->name = "Xbox classic pad";
 		}
 
 		if (dpad_to_buttons)
-- 
2.32.0


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

* [PATCH 2/2] Input: xpad - drop checks for XTYPE_UNKNOWN
  2021-11-14  1:52 ` Cameron Gutman
  2021-11-14 19:23   ` [PATCH v2] " Benjamin Valentin
  2021-11-16 16:23   ` [PATCH 1/2] Input: xpad - name unknown gamepads according to device type Benjamin Valentin
@ 2021-11-16 16:25   ` Benjamin Valentin
  2022-01-05 11:53   ` [RESEND][PATCH v2] Input: xpad - Poweroff XBOX360W on mode button long press Benjamin Valentin
  3 siblings, 0 replies; 6+ messages in thread
From: Benjamin Valentin @ 2021-11-16 16:25 UTC (permalink / raw)
  To: Cameron Gutman; +Cc: Dmitry Torokhov, linux-input, Lee Jones

If xtype is XTYPE_UNKNOWN, it will *always* be replaced by the real
detected type in xpad_probe().

It is therefore not possible to encounter the xtype == XTYPE_UNKNOWN
condition anywhere at the run-time of the driver.

That means we can drop those checks.

Signed-off-by: Benjamin Valentin <benpicco@googlemail.com>
---
 drivers/input/joystick/xpad.c | 28 +++++++++-------------------
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 31a268f43b5b..66a12da58619 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -1110,13 +1110,10 @@ static void xpad_irq_out(struct urb *urb)
 }
 
 static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
-			struct usb_endpoint_descriptor *ep_irq_out)
+			    struct usb_endpoint_descriptor *ep_irq_out)
 {
 	int error;
 
-	if (xpad->xtype == XTYPE_UNKNOWN)
-		return 0;
-
 	init_usb_anchor(&xpad->irq_out_anchor);
 
 	xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
@@ -1148,23 +1145,19 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
 
 static void xpad_stop_output(struct usb_xpad *xpad)
 {
-	if (xpad->xtype != XTYPE_UNKNOWN) {
-		if (!usb_wait_anchor_empty_timeout(&xpad->irq_out_anchor,
-						   5000)) {
-			dev_warn(&xpad->intf->dev,
-				 "timed out waiting for output URB to complete, killing\n");
-			usb_kill_anchored_urbs(&xpad->irq_out_anchor);
-		}
+	if (!usb_wait_anchor_empty_timeout(&xpad->irq_out_anchor,
+					   5000)) {
+		dev_warn(&xpad->intf->dev,
+			 "timed out waiting for output URB to complete, killing\n");
+		usb_kill_anchored_urbs(&xpad->irq_out_anchor);
 	}
 }
 
 static void xpad_deinit_output(struct usb_xpad *xpad)
 {
-	if (xpad->xtype != XTYPE_UNKNOWN) {
-		usb_free_urb(xpad->irq_out);
-		usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
-				xpad->odata, xpad->odata_dma);
-	}
+	usb_free_urb(xpad->irq_out);
+	usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
+			xpad->odata, xpad->odata_dma);
 }
 
 static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
@@ -1339,9 +1332,6 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
 
 static int xpad_init_ff(struct usb_xpad *xpad)
 {
-	if (xpad->xtype == XTYPE_UNKNOWN)
-		return 0;
-
 	input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
 
 	return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
-- 
2.32.0


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

* [RESEND][PATCH v2] Input: xpad - Poweroff XBOX360W on mode button long press
  2021-11-14  1:52 ` Cameron Gutman
                     ` (2 preceding siblings ...)
  2021-11-16 16:25   ` [PATCH 2/2] Input: xpad - drop checks for XTYPE_UNKNOWN Benjamin Valentin
@ 2022-01-05 11:53   ` Benjamin Valentin
  3 siblings, 0 replies; 6+ messages in thread
From: Benjamin Valentin @ 2022-01-05 11:53 UTC (permalink / raw)
  To: Cameron Gutman; +Cc: Dmitry Torokhov, linux-input, Lee Jones, lawl

Newer gamepads turn themselves off when the mode button is held down.
For XBOX360W gamepads we must do this in the driver.

Power off the gamepad after 5s of holding down the button.

Signed-off-by: lawl <github@dumbinter.net>
Signed-off-by: Benjamin Valentin <benpicco@googlemail.com>
---
Changed the timeout back to 5s

 drivers/input/joystick/xpad.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 18caaf436ed4..e36c4b0abd4b 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -619,11 +619,13 @@ struct usb_xpad {
 	int pad_nr;			/* the order x360 pads were attached */
 	const char *name;		/* name of the device */
 	struct work_struct work;	/* init/remove device from callback */
+	time64_t mode_btn_down_ts;	/* timestamp when mode button was pressed */
 };
 
 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);
+static void xpad360w_poweroff_controller(struct usb_xpad *xpad);
 
 /*
  *	xpad_process_packet
@@ -775,6 +777,24 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
 	}
 
 	input_sync(dev);
+
+	/* xbox360w controllers can't be turned off without driver assistance */
+	if (xpad->xtype == XTYPE_XBOX360W) {
+		if (xpad->mode_btn_down_ts > 0
+		    && xpad->pad_present
+		    /* send power off after 5s of holding the button */
+		    && (ktime_get_seconds() - xpad->mode_btn_down_ts) >= 5) {
+			xpad360w_poweroff_controller(xpad);
+			xpad->mode_btn_down_ts = 0;
+			return;
+		}
+
+		/* mode button down/up */
+		if (data[3] & 0x04)
+			xpad->mode_btn_down_ts = ktime_get_seconds();
+		else
+			xpad->mode_btn_down_ts = 0;
+	}
 }
 
 static void xpad_presence_work(struct work_struct *work)
-- 
2.32.0

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

end of thread, other threads:[~2022-01-05 11:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-13 13:11 [PATCH] Input: xpad - Poweroff XBOX360W on mode button long press Benjamin Valentin
2021-11-14  1:52 ` Cameron Gutman
2021-11-14 19:23   ` [PATCH v2] " Benjamin Valentin
2021-11-16 16:23   ` [PATCH 1/2] Input: xpad - name unknown gamepads according to device type Benjamin Valentin
2021-11-16 16:25   ` [PATCH 2/2] Input: xpad - drop checks for XTYPE_UNKNOWN Benjamin Valentin
2022-01-05 11:53   ` [RESEND][PATCH v2] Input: xpad - Poweroff XBOX360W on mode button long press Benjamin Valentin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.