diff mbox series

[3/4] Input: xpad - Poweroff XBOX360W on mode button long press

Message ID 20220818130021.487410-4-rojtberg@gmail.com (mailing list archive)
State Superseded
Headers show
Series Input: xpad - sync with github fork | expand

Commit Message

Pavel Rojtberg Aug. 18, 2022, 1 p.m. UTC
From: Santosh De Massari <s.demassari@gmail.com>

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

Do not use BIT() macro for consistency within the file.

Signed-off-by: Santosh De Massari <s.demassari@gmail.com>
Signed-off-by: Pavel Rojtberg <rojtberg@gmail.com>
---
 drivers/input/joystick/xpad.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Comments

Greg KH Aug. 18, 2022, 1:11 p.m. UTC | #1
On Thu, Aug 18, 2022 at 03:00:20PM +0200, Pavel Rojtberg wrote:
> From: Santosh De Massari <s.demassari@gmail.com>
> 
> Newer gamepads turn themselves off when the mode button is held down.
> For XBOX360W gamepads we must do this in the driver.
> 
> Do not use BIT() macro for consistency within the file.

You can fix the file up to properly use the BIT() macro :)

thanks,

greg k-h
Pavel Rojtberg Aug. 18, 2022, 1:53 p.m. UTC | #2
Am 18.08.22 um 15:11 schrieb Greg KH:
> On Thu, Aug 18, 2022 at 03:00:20PM +0200, Pavel Rojtberg wrote:
>> From: Santosh De Massari <s.demassari@gmail.com>
>>
>> Newer gamepads turn themselves off when the mode button is held down.
>> For XBOX360W gamepads we must do this in the driver.
>>
>> Do not use BIT() macro for consistency within the file.
> 
> You can fix the file up to properly use the BIT() macro :)
> 
> thanks,
> 
> greg k-h

That change should be a separate patch anyway, no?
Can we postpone this to the next patch series?

Greetings, Pavel
Greg KH Aug. 18, 2022, 2:07 p.m. UTC | #3
On Thu, Aug 18, 2022 at 03:53:01PM +0200, Pavel Rojtberg wrote:
> Am 18.08.22 um 15:11 schrieb Greg KH:
> > On Thu, Aug 18, 2022 at 03:00:20PM +0200, Pavel Rojtberg wrote:
> >> From: Santosh De Massari <s.demassari@gmail.com>
> >>
> >> Newer gamepads turn themselves off when the mode button is held down.
> >> For XBOX360W gamepads we must do this in the driver.
> >>
> >> Do not use BIT() macro for consistency within the file.
> > 
> > You can fix the file up to properly use the BIT() macro :)
> > 
> > thanks,
> > 
> > greg k-h
> 
> That change should be a separate patch anyway, no?

Yes.

> Can we postpone this to the next patch series?

Sure, it's just not good to keep postponing it to allow you to keep
having to justify not using it in new changes.

thanks,

greg k-h
diff mbox series

Patch

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 4e01056..f964219 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -89,6 +89,11 @@ 
 #define XTYPE_XBOXONE     3
 #define XTYPE_UNKNOWN     4
 
+/* Send power-off packet to xpad360w after holding the mode button for this many
+ * seconds
+ */
+#define XPAD360W_POWEROFF_TIMEOUT 5
+
 static bool dpad_to_buttons;
 module_param(dpad_to_buttons, bool, S_IRUGO);
 MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
@@ -630,11 +635,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;
 };
 
 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
@@ -786,6 +793,23 @@  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 &&
+		    ((ktime_get_seconds() - xpad->mode_btn_down_ts) >=
+		     XPAD360W_POWEROFF_TIMEOUT)) {
+			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)