From 2877e80471966246788f403ba90aaa564fe661ee Mon Sep 17 00:00:00 2001
From: Daniel Tobias <dan.g.tob@gmail.com>
Date: Tue, 10 May 2016 00:31:56 +1000
Subject: [PATCH 1/9] xpad: print received packets if DEBUG_VERBOSE

Signed-off-by: Daniel Tobias <dan.g.tob@gmail.com>
---
 xpad.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/xpad.c b/xpad.c
index e7baa98..e89f1c7 100644
--- a/xpad.c
+++ b/xpad.c
@@ -952,6 +952,13 @@ static void xpad_irq_in(struct urb *urb)
 		goto exit;
 	}
 
+#if defined(DEBUG_VERBOSE)
+	/* If you set rowsize to larger than 32 it defaults to 16?
+	 * Otherwise I would set it to XPAD_PKT_LEN                  V
+	 */
+	print_hex_dump(KERN_DEBUG, "xpad-dbg: ", DUMP_PREFIX_OFFSET, 32, 1, xpad->idata, XPAD_PKT_LEN, 0);
+#endif
+
 	switch (xpad->xtype) {
 	case XTYPE_XBOX360:
 		xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata);

From fdf054c114049da4e1b732d1596d49e41cd7f81f Mon Sep 17 00:00:00 2001
From: Pavel Rojtberg <rojtberg@gmail.com>
Date: Sun, 5 Jul 2015 15:41:30 +0200
Subject: [PATCH 2/9] add code to enable debug outputs

---
 xpad.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xpad.c b/xpad.c
index e89f1c7..fff414e 100644
--- a/xpad.c
+++ b/xpad.c
@@ -60,7 +60,7 @@
  *
  * Later changes can be tracked in SCM.
  */
-
+// #define DEBUG
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/rcupdate.h>

From 19120308f02e891620e84ca1be9aaee4bd81889e Mon Sep 17 00:00:00 2001
From: Pavel Rojtberg <rojtberg@gmail.com>
Date: Wed, 24 Jun 2015 12:47:17 +0200
Subject: [PATCH 3/9] add README.md

Signed-off-by: Daniel Tobias <dan.g.tob@gmail.com>
Signed-off-by: Jonathan <greenbigfrog@gmail.com>
Signed-off-by: Matt Sturgeon <matt@sturgeon.me.uk>
---
 README.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 README.md

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a1c87ac
--- /dev/null
+++ b/README.md
@@ -0,0 +1,84 @@
+# Updated Xpad Linux Kernel Driver
+Driver for the Xbox/ Xbox 360/ Xbox 360 Wireless/ Xbox One Controllers
+
+This driver includes the latest changes in the upstream linux kernel and additionally carries the following staging changes:
+
+* enable debug outputs to ease resolving issues
+* some minor code refactoring improving readability 
+
+
+**This driver does not support the XBox One Wireless Adapter (WiFi)**  
+To get that running, see: [medusalix/xow](https://github.com/medusalix/xow)
+
+# Installing
+```
+sudo git clone https://github.com/paroj/xpad.git /usr/src/xpad-0.4
+sudo dkms install -m xpad -v 0.4
+```
+# Updating
+```
+cd /usr/src/xpad-0.4
+sudo git fetch
+sudo git checkout origin/master
+sudo dkms remove -m xpad -v 0.4 --all
+sudo dkms install -m xpad -v 0.4
+```
+# Removing
+```
+sudo dkms remove -m xpad -v 0.4 --all
+sudo rm -rf /usr/src/xpad-0.4
+```
+# Usage
+This driver creates three devices for each attached gamepad
+
+1. /dev/input/js**N**
+    * example `jstest /dev/input/js0`
+2. /sys/class/leds/xpad**N**/brightness
+    * example `echo COMMAND > /sys/class/leds/xpad0/brightness` where COMMAND is one of
+        *  0: off
+        *  1: all blink, then previous setting
+        *  2: 1/top-left blink, then on
+        *  3: 2/top-right blink, then on
+        *  4: 3/bottom-left blink, then on
+        *  5: 4/bottom-right blink, then on
+        *  6: 1/top-left on
+        *  7: 2/top-right on
+        *  8: 3/bottom-left on
+        *  9: 4/bottom-right on
+        * 10: rotate
+        * 11: blink, based on previous setting
+        * 12: slow blink, based on previous setting
+        * 13: rotate with two lights
+        * 14: persistent slow all blink
+        * 15: blink once, then previous setting
+3. the generic event device
+    * example `fftest /dev/input/by-id/usb-*360*event*`
+
+# Debugging
+As a regular unpriveledged user
+
+Setup console to display kernel log.  
+`dmesg --level=debug --follow`
+
+Open a new console and access the device with jstest.  
+`jstest /dev/input/jsX`
+
+Interact with the device and observe that data packets recieved from device are printed to kernel log.
+```
+[ 3968.772128] xpad-dbg: 00000000: 20 00 b5 0e 00 00 00 00 00 00 0c 03 04 fd 6c 01 40 fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 3968.772135] xpad-dbg: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 3968.804137] xpad-dbg: 00000000: 20 00 b6 0e 00 00 00 00 00 00 0c 03 04 fd 6c 01 fc fd 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 3968.804145] xpad-dbg: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 3969.152120] xpad-dbg: 00000000: 20 00 b7 0e 00 00 00 00 00 00 0c 03 04 fd 6c 01 b8 fd 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 3969.152129] xpad-dbg: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+Save dmesg buffer and attach to bug report, don't forget to describe button sequences in bug report.  
+`dmesg --level=debug > dmesg.txt`
+
+Ctrl+C to close interactive console sessions when finished.
+
+# Sending Upstream
+
+1. `git format-patch --cover-letter upstream..master`
+2. `git send-email --to xxx *.patch`

From 6eb808cb8129a52c02bdb134a084c67e59cd78b7 Mon Sep 17 00:00:00 2001
From: Pavel Rojtberg <rojtberg@gmail.com>
Date: Sun, 27 Sep 2015 23:57:46 +0200
Subject: [PATCH 4/9] add stress_urb_out.sh

---
 stress_urb_out.sh | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100755 stress_urb_out.sh

diff --git a/stress_urb_out.sh b/stress_urb_out.sh
new file mode 100755
index 0000000..2e5c235
--- /dev/null
+++ b/stress_urb_out.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+# stress test irq_urb_out. provokes URB request dropping.
+# script by Laura Abbott
+# see: http://www.spinics.net/lists/linux-input/msg40477.html
+
+while true; do
+    for i in $(seq 0 5); do
+        echo $i > /sys/class/leds/xpad0/subsystem/xpad0/brightness
+    done
+done

From 3529e2d77d86f6748caa3e5fb6f62afcb8d914dd Mon Sep 17 00:00:00 2001
From: Cameron Gutman <aicommander@gmail.com>
Date: Sat, 23 Jul 2016 08:27:41 +0200
Subject: [PATCH 5/9] Input: xpad - fix wireless 360 controller breaking after
 suspend

Suspending and resuming the system can sometimes cause the out
URB to get hung after a reset_resume. This causes LED setting
and force feedback to break on resume. To avoid this, just drop
the reset_resume callback so the USB core rebinds xpad to the
wireless pads on resume if a reset happened.

A nice side effect of this change is the LED ring on wireless
controllers is now set correctly on system resume.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
Cc: stable@vger.kernel.org
---
 xpad.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/xpad.c b/xpad.c
index fff414e..f404218 100644
--- a/xpad.c
+++ b/xpad.c
@@ -1977,7 +1977,6 @@ static struct usb_driver xpad_driver = {
 	.disconnect	= xpad_disconnect,
 	.suspend	= xpad_suspend,
 	.resume		= xpad_resume,
-	.reset_resume	= xpad_resume,
 	.id_table	= xpad_table,
 };
 

From 9170fa372024e39b7ac9a801a1497db1b731bc61 Mon Sep 17 00:00:00 2001
From: Pavel Rojtberg <rojtberg@gmail.com>
Date: Sun, 8 Dec 2019 13:44:36 +0100
Subject: [PATCH 6/9] add PR template

---
 .github/pull_request_template.md | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 .github/pull_request_template.md

diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..47459e1
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,7 @@
+<!--
+If you are adding support for a new generic xpad controller it is sufficient
+to update the xpad_table[] array.
+The type will be auto-detected in xpad_probe().
+Updating the xpad_device[] array is only needed if the controller requires
+additional flags like DANCEPAD_MAP_CONFIG to work.
+ -->
\ No newline at end of file

From 389e2589cca1596257ff6a490556d2e0d82cecaa Mon Sep 17 00:00:00 2001
From: lawl <github@dumbinter.net>
Date: Mon, 30 Nov 2020 13:31:58 +0100
Subject: [PATCH 7/9] Input: xpad - Poweroff XBOX360W on mode button long press

Newer gamepads turn themselves off when the mode button is held down.
For XBOX360W gamepads we must do this this in the driver.
---
 xpad.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/xpad.c b/xpad.c
index f404218..9ca96bb 100644
--- a/xpad.c
+++ b/xpad.c
@@ -609,11 +609,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
@@ -765,6 +767,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) >= 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)

From 84eee44a5cd47eaca1c4539a8341237d8c059ae8 Mon Sep 17 00:00:00 2001
From: Pavel Rojtberg <rojtberg@gmail.com>
Date: Sun, 15 Aug 2021 02:07:31 +0200
Subject: [PATCH 8/9] add zerplus init packets on top

---
 xpad.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/xpad.c b/xpad.c
index 9ca96bb..8d3623f 100644
--- a/xpad.c
+++ b/xpad.c
@@ -490,6 +490,20 @@ static const u8 xboxone_s_init[] = {
 	0x05, 0x20, 0x00, 0x0f, 0x06
 };
 
+/*
+ * This packet is required for some zeroplus pads (0x045e:0x02ea)
+ */
+static const u8 xboxone_zeroplus_init1[] = {
+       0x04, 0x20, 0x01, 0x00
+};
+/*
+ * This packet is required for some zeroplus pads (0x045e:0x02ea)
+ */
+static const u8 xboxone_zeroplus_init2[] = {
+       0x01, 0x20, 0x01, 0x09, 0x00, 0x1e, 0x20, 0x10,
+       0x00, 0x00, 0x00, 0x00, 0x00
+};
+
 /*
  * This packet is required for the Titanfall 2 Xbox One pads
  * (0x0e6f:0x0165) to finish initialization and for Hori pads
@@ -549,6 +563,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
 	XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
 	XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
 	XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init),
+    XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_zeroplus_init1),
+    XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_zeroplus_init2),
 	XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init),
 	XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1),
 	XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2),

From de37b6f97af60229b8e0f421ee1c6414477c5f77 Mon Sep 17 00:00:00 2001
From: Ganer <34655998+GanerCodes@users.noreply.github.com>
Date: Mon, 6 Dec 2021 01:46:21 -0600
Subject: [PATCH 9/9] Update Makefile

---
 Makefile | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Makefile b/Makefile
index f930ed3..d722c53 100644
--- a/Makefile
+++ b/Makefile
@@ -5,3 +5,12 @@ all:
 	make -C /lib/modules/$(KVERSION)/build V=1 M=$(PWD) modules
 clean:
 	test ! -d /lib/modules/$(KVERSION) || make -C /lib/modules/$(KVERSION)/build V=1 M=$(PWD) clean
+
+## Allow Install on Gentoo to work [huge thanks to hurikhan77 for figuring this part out]:
+## Note: you need to make the xpad built in driver set to module in kernel config for this to work
+## Once installed, run modprobe xpad to start it and it should work
+KERNEL_SOURCE_DIR := /lib/modules/$(shell uname -r)/source
+LD := ld.bfd
+
+modules_install:
+	$(MAKE) -C $(KERNEL_SOURCE_DIR) INSTALL_MOD_DIR="kernel/drivers/input/joystick" LD=$(LD) M=$(shell pwd) $@