summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SOURCES/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch258
-rw-r--r--SOURCES/set-ps4-bt-poll-rate-1000hz.patch27
-rw-r--r--SOURCES/xbox-controller-update.patch72
-rw-r--r--SPECS/kernel.spec31
4 files changed, 387 insertions, 1 deletions
diff --git a/SOURCES/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch b/SOURCES/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch
new file mode 100644
index 0000000..ecd0304
--- /dev/null
+++ b/SOURCES/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch
@@ -0,0 +1,258 @@
+From 498e88ae626be4f523063c8a7027b4b02eca31d2 Mon Sep 17 00:00:00 2001
+From: GloriousEggroll <gloriouseggroll@gmail.com>
+Date: Tue, 17 Jan 2023 12:08:46 -0700
+Subject: [PATCH] Allow to set custom USB pollrate for specific devices like
+ so: usbcore.interrupt_interval_override=045e:00db:16,1bcf:0005:1
+
+---
+ .../admin-guide/kernel-parameters.txt | 8 +
+ drivers/usb/core/config.c | 170 +++++++++++++++++-
+ drivers/usb/core/usb.c | 1 +
+ drivers/usb/core/usb.h | 1 +
+ 4 files changed, 179 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index dbd26fde4..c9b8b80af 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -6552,6 +6552,14 @@
+ delay after resetting its port);
+ Example: quirks=0781:5580:bk,0a5c:5834:gij
+
++ usbcore.interrupt_interval_override=
++ [USB] A list of USB devices for which a different polling
++ interval than the default shall be used on all interrupt-type
++ endpoints. The format is VendorID:ProductID:interval, with
++ the vendor and product ids specified hexadecimally, and the
++ interval decimally in milliseconds.
++ Example: interrupt_interval_override=045e:00db:16,1bcf:0005:2
++
+ usbhid.mousepoll=
+ [USBHID] The interval which mice are to be polled at.
+
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
+index 48bc8a481..84bd550ad 100644
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -19,6 +19,149 @@
+ #define USB_MAXCONFIG 8 /* Arbitrary limit */
+
+
++/* A struct associated with the interrupt_interval_override module parameter, representing
++ an user's choice to force a specific interrupt interval upon all interrupt endpoints of
++ a certain device. */
++struct interrupt_interval_override {
++ /* The vendor ID of the device of which the interrupt interval shall be overridden */
++ u16 vendor;
++ /* The product ID of the device of which the interrupt interval shall be overridden */
++ u16 product;
++ /* The new interval measured in milliseconds that shall be given to all endpoints of type interrupt on said device */
++ unsigned int interval;
++};
++
++static DEFINE_MUTEX(interrupt_interval_override_mutex);
++static char interrupt_interval_override_param[128];
++static struct interrupt_interval_override *interrupt_interval_override_list = NULL;
++static size_t interrupt_interval_override_count = 0;
++
++static int interrupt_interval_override_param_set(const char *value, const struct kernel_param *kp)
++{
++ const char *p;
++ unsigned short vendor, product;
++ unsigned int interval;
++ struct interrupt_interval_override* list;
++ struct interrupt_interval_override param;
++ size_t count, max_count, i, len;
++ int err, res;
++
++ mutex_lock(&interrupt_interval_override_mutex);
++
++ if (!value || !*value) {
++ /* Unset the current variable. */
++ kfree(interrupt_interval_override_list);
++ interrupt_interval_override_list = NULL;
++ interrupt_interval_override_count = 0;
++ param_set_copystring(value, kp); /* Does not fail: the empty string is short enough to fit. */
++ mutex_unlock(&interrupt_interval_override_mutex);
++ return 0;
++ }
++
++ /* Compute an upper bound on the amount of entries we need. */
++ for (max_count = 1, i = 0; value[i]; i++) {
++ if (value[i] == ',')
++ max_count++;
++ }
++
++ /* Ensure we can allocate enough memory before overwriting the global variables. */
++ list = kcalloc(max_count,
++ sizeof(struct interrupt_interval_override),
++ GFP_KERNEL);
++
++ if (!list) {
++ mutex_unlock(&interrupt_interval_override_mutex);
++ return -ENOMEM;
++ }
++
++ err = param_set_copystring(value, kp);
++ if (err) {
++ kfree(list);
++ mutex_unlock(&interrupt_interval_override_mutex);
++ return err;
++ }
++
++ /* Parse the parameter. Example of a valid parameter: 045e:00db:16,1bcf:0005:2 */
++ for (count = 0, p = (const char*)value; p && *p;) {
++ res = sscanf(p, "%hx:%hx:%d%zn", &vendor, &product, &interval, &len);
++
++ /* Check whether all variables (vendor, product, interval, len) were assigned.
++ %zn does not increase the assignment count, so we need to check for value 3 instead of 4.
++ %zn does not consume input either, so setting len shouldn't fail if interval has been properly set. */
++ if (res != 3) {
++ pr_warn("Error while parsing USB interrupt interval override parameter %s.\n", value);
++ break;
++ }
++
++ param.vendor = (u16)vendor;
++ param.product = (u16)product;
++ param.interval = interval;
++ list[count++] = param;
++
++ p += len;
++ if (*p == ',' && *(p+1) != '\0') {
++ p++;
++ continue;
++ } else if(*p == '\0' || (*p == '\n' && *(p+1) == '\0')) {
++ break;
++ } else {
++ pr_warn("Error while parsing USB interrupt interval override parameter %s.\n", value);
++ break;
++ }
++ }
++
++ /* Overwrite the global variables with the local ones. */
++ kfree(interrupt_interval_override_list);
++ interrupt_interval_override_list = list;
++ interrupt_interval_override_count = count;
++ mutex_unlock(&interrupt_interval_override_mutex);
++ return 0;
++}
++
++static const struct kernel_param_ops interrupt_interval_override_param_ops = {
++ .set = interrupt_interval_override_param_set,
++ .get = param_get_string,
++};
++
++static struct kparam_string interrupt_interval_override_param_string = {
++ .maxlen = sizeof(interrupt_interval_override_param),
++ .string = interrupt_interval_override_param,
++};
++
++device_param_cb(interrupt_interval_override,
++ &interrupt_interval_override_param_ops,
++ &interrupt_interval_override_param_string,
++ 0644);
++MODULE_PARM_DESC(interrupt_interval_override,
++ "Override the polling interval of all interrupt-type endpoints of a specific USB"
++ " device by specifying interrupt_interval_override=vendorID:productID:interval.");
++
++/* Given an USB device, this checks whether the user has specified they want to override the interrupt
++ polling interval on all interrupt-type endpoints of said device.
++
++ This function returns the user-desired amount of milliseconds between interrupts on said endpoint.
++ If this function returns zero, the device-requested interrupt interval should be used. */
++static unsigned int usb_check_interrupt_interval_override(struct usb_device* udev)
++{
++ size_t i;
++ unsigned int res;
++ u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
++ u16 product = le16_to_cpu(udev->descriptor.idProduct);
++
++ mutex_lock(&interrupt_interval_override_mutex);
++ for (i = 0; i < interrupt_interval_override_count; i++) {
++ if (interrupt_interval_override_list[i].vendor == vendor
++ && interrupt_interval_override_list[i].product == product) {
++
++ res = interrupt_interval_override_list[i].interval;
++ mutex_unlock(&interrupt_interval_override_mutex);
++ return res;
++ }
++ }
++ mutex_unlock(&interrupt_interval_override_mutex);
++ return 0;
++}
++
+ static inline const char *plural(int n)
+ {
+ return (n == 1 ? "" : "s");
+@@ -261,7 +404,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
+ struct usb_endpoint_descriptor *d;
+ struct usb_host_endpoint *endpoint;
+ int n, i, j, retval;
+- unsigned int maxp;
++ unsigned int maxp, ival;
+ const unsigned short *maxpacket_maxes;
+
+ d = (struct usb_endpoint_descriptor *) buffer;
+@@ -386,6 +529,23 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
+ endpoint->desc.bInterval = n;
+ }
+
++ /* Override the interrupt polling interval if a module parameter tells us to do so. */
++ if (usb_endpoint_xfer_int(d)) {
++ ival = usb_check_interrupt_interval_override(udev);
++ if (ival > 0) {
++ switch (udev->speed) {
++ case USB_SPEED_SUPER_PLUS:
++ case USB_SPEED_SUPER:
++ case USB_SPEED_HIGH:
++ endpoint->desc.bInterval = fls(ival) + 3;
++ break;
++ default: /* USB_SPEED_FULL or _LOW */
++ endpoint->desc.bInterval = ival;
++ break;
++ }
++ }
++ }
++
+ /* Some buggy low-speed devices have Bulk endpoints, which is
+ * explicitly forbidden by the USB spec. In an attempt to make
+ * them usable, we will try treating them as Interrupt endpoints.
+@@ -1092,3 +1252,11 @@ int usb_get_bos_descriptor(struct usb_device *dev)
+ usb_release_bos_descriptor(dev);
+ return ret;
+ }
++
++void usb_release_interrupt_interval_override_list(void)
++{
++ mutex_lock(&interrupt_interval_override_mutex);
++ kfree(interrupt_interval_override_list);
++ interrupt_interval_override_list = NULL;
++ mutex_unlock(&interrupt_interval_override_mutex);
++}
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 11b15d7b3..ec52c6322 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -1066,6 +1066,7 @@ static void __exit usb_exit(void)
+ return;
+
+ usb_release_quirk_list();
++ usb_release_interrupt_interval_override_list();
+ usb_deregister_device_driver(&usb_generic_driver);
+ usb_major_cleanup();
+ usb_deregister(&usbfs_driver);
+diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
+index 82538daac..b6faa897c 100644
+--- a/drivers/usb/core/usb.h
++++ b/drivers/usb/core/usb.h
+@@ -37,6 +37,7 @@ extern void usb_authorize_interface(struct usb_interface *);
+ extern void usb_detect_quirks(struct usb_device *udev);
+ extern void usb_detect_interface_quirks(struct usb_device *udev);
+ extern void usb_release_quirk_list(void);
++extern void usb_release_interrupt_interval_override_list(void);
+ extern bool usb_endpoint_is_ignored(struct usb_device *udev,
+ struct usb_host_interface *intf,
+ struct usb_endpoint_descriptor *epd);
+--
+2.39.0
+
diff --git a/SOURCES/set-ps4-bt-poll-rate-1000hz.patch b/SOURCES/set-ps4-bt-poll-rate-1000hz.patch
new file mode 100644
index 0000000..8431cf7
--- /dev/null
+++ b/SOURCES/set-ps4-bt-poll-rate-1000hz.patch
@@ -0,0 +1,27 @@
+From 0f2c07ab93dca496a1f34399ad2ff8a954690a72 Mon Sep 17 00:00:00 2001
+From: GloriousEggroll <gloriouseggroll@gmail.com>
+Date: Mon, 29 May 2023 17:15:14 -0600
+Subject: [PATCH] set ds controller bluetooth pollrate to 1 ms
+
+---
+ drivers/hid/hid-playstation.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
+index 8ac8f7b8e..1130663c3 100644
+--- a/drivers/hid/hid-playstation.c
++++ b/drivers/hid/hid-playstation.c
+@@ -330,8 +330,8 @@ struct dualsense_output_report {
+ * 0x3F - disabled
+ */
+ #define DS4_OUTPUT_HWCTL_BT_POLL_MASK 0x3F
+-/* Default to 4ms poll interval, which is same as USB (not adjustable). */
+-#define DS4_BT_DEFAULT_POLL_INTERVAL_MS 4
++/* Default to 1ms poll interval (1000Hz, lower latency). */
++#define DS4_BT_DEFAULT_POLL_INTERVAL_MS 1
+ #define DS4_OUTPUT_HWCTL_CRC32 0x40
+ #define DS4_OUTPUT_HWCTL_HID 0x80
+
+--
+2.40.1
+
diff --git a/SOURCES/xbox-controller-update.patch b/SOURCES/xbox-controller-update.patch
new file mode 100644
index 0000000..b1720d2
--- /dev/null
+++ b/SOURCES/xbox-controller-update.patch
@@ -0,0 +1,72 @@
+From: Siarhei Vishniakou <svv@google.com>
+To: Jiri Kosina <jikos@kernel.org>,
+ Benjamin Tissoires <benjamin.tissoires@redhat.com>,
+ linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
+Cc: Siarhei Vishniakou <svv@google.com>
+Subject: [PATCH] Add rumble support to latest xbox controllers
+Date: Thu, 20 Oct 2022 09:14:01 -0700 [thread overview]
+Message-ID: <20221020161401.941927-1-svv@google.com> (raw)
+
+Currently, rumble is only supported via bluetooth on a single xbox
+controller, called 'model 1708'. On the back of the device, it's named
+'wireless controller for xbox one'. However, in 2021, Microsoft released
+a firmware update for this controller. As part of this update, the HID
+descriptor of the device changed. The product ID was also changed from
+0x02fd to 0x0b20. On this controller, rumble was supported via
+hid-microsoft, which matched against the old product id (0x02fd). As a
+result, the firmware update broke rumble support on this controller.
+
+The hid-microsoft driver actually supports rumble on the new firmware,
+as well. So simply adding new product id is sufficient to bring back
+this support.
+
+After discussing further with the xbox team, it was pointed out that
+other xbox controllers, such as xbox elite, should also be possible to
+support in a similar way. However, I could only verify this on 2
+controllers so far.
+
+In this patch, add rumble support for the following 2 controllers:
+1. 'wireless controller for xbox one', model 1708, after applying the
+ most recent firmware update as of 2022-10-20.
+2. 'xbox wireless controller', model 1914. This is also sometimes
+ referred to as 'xbox series S|X'.
+
+I verified rumble support on both bluetooth and usb.
+
+Signed-off-by: Siarhei Vishniakou <svv@google.com>
+---
+ drivers/hid/hid-ids.h | 2 ++
+ drivers/hid/hid-microsoft.c | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 2235d7878..c110f0beb 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -919,6 +919,8 @@
+ #define USB_DEVICE_ID_MS_POWER_COVER 0x07da
+ #define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de
+ #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd
++#define USB_DEVICE_ID_MS_XBOX_ONE_S_2021_FIRMWARE 0x0b20
++#define USB_DEVICE_ID_MS_XBOX_WIRELESS_CONTROLLER 0x0b13
+ #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb
+ #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0
+ #define USB_DEVICE_ID_MS_MOUSE_0783 0x0783
+diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
+index 071fd093a..2973e91fc 100644
+--- a/drivers/hid/hid-microsoft.c
++++ b/drivers/hid/hid-microsoft.c
+@@ -448,6 +448,10 @@ static const struct hid_device_id ms_devices[] = {
+ .driver_data = MS_SURFACE_DIAL },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER),
+ .driver_data = MS_QUIRK_FF },
++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_2021_FIRMWARE),
++ .driver_data = MS_QUIRK_FF },
++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_WIRELESS_CONTROLLER),
++ .driver_data = MS_QUIRK_FF },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS),
+ .driver_data = MS_QUIRK_FF },
+ { }
+--
+2.39.2
+
diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec
index 4ea5048..f1f2086 100644
--- a/SPECS/kernel.spec
+++ b/SPECS/kernel.spec
@@ -180,7 +180,7 @@ Summary: The Linux kernel
# This is needed to do merge window version magic
%define patchlevel 4
# This allows pkg_release to have configurable %%{?dist} tag
-%define specrelease 201%{?buildid}%{?dist}
+%define specrelease 202%{?buildid}%{?dist}
# This defines the kabi tarball version
%define kabiversion 6.4.4
@@ -1050,6 +1050,19 @@ Patch411: 0001-Revert-b0cb56fc6e3096c9da04c30d9b501da84dae2b4f.patch
Patch412: 0002-Revert-1ca399f127e0a372537625b1d462ed586f5d9139.patch
Patch413: 0003-Revert-da2d907e051d591717d00e28e67ab341b961fd05.patch
+# Allow to set custom USB pollrate for specific devices like so:
+# usbcore.interrupt_interval_override=045e:00db:16,1bcf:0005:1
+# useful for setting polling rate of wired PS4/PS5 controller to 1000Hz
+# https://github.com/KarsMulder/Linux-Pollrate-Patch
+# https://gitlab.com/GloriousEggroll/nobara-images/-/issues/64
+Patch506: 0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch
+
+# Also set the PS controller bluetooth polling rate to 1000Hz
+Patch507: set-ps4-bt-poll-rate-1000hz.patch
+
+# xbox controller update
+Patch510: xbox-controller-update.patch
+
%endif
# empty final patch to facilitate testing of kernel patches
@@ -1812,6 +1825,19 @@ ApplyOptionalPatch 0001-Revert-b0cb56fc6e3096c9da04c30d9b501da84dae2b4f.patch
ApplyOptionalPatch 0002-Revert-1ca399f127e0a372537625b1d462ed586f5d9139.patch
ApplyOptionalPatch 0003-Revert-da2d907e051d591717d00e28e67ab341b961fd05.patch
+# Allow to set custom USB pollrate for specific devices like so:
+# usbcore.interrupt_interval_override=045e:00db:16,1bcf:0005:1
+# useful for setting polling rate of wired PS4/PS5 controller to 1000Hz
+# https://github.com/KarsMulder/Linux-Pollrate-Patch
+# https://gitlab.com/GloriousEggroll/nobara-images/-/issues/64
+ApplyOptionalPatch 0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch
+
+# Also set the PScontroller bluetooth polling rate to 1000Hz
+ApplyOptionalPatch set-ps4-bt-poll-rate-1000hz.patch
+
+# xbox controller update
+ApplyOptionalPatch xbox-controller-update.patch
+
%endif
ApplyOptionalPatch linux-kernel-test.patch
@@ -3790,6 +3816,9 @@ fi\
#
#
%changelog
+* Sun Jul 23 2023 Jan Drögehoff <sentrycraft123@gmail.com> - 6.4.4-202.fsync
+- Adopt nobara kernel patches
+
* Sat Jul 22 2023 Jan Drögehoff <sentrycraft123@gmail.com> - 6.4.4-201.fsync
- kernel-fsync v6.4.4