diff options
Diffstat (limited to 'SOURCES')
-rw-r--r-- | SOURCES/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch | 258 | ||||
-rw-r--r-- | SOURCES/set-ps4-bt-poll-rate-1000hz.patch | 27 | ||||
-rw-r--r-- | SOURCES/xbox-controller-update.patch | 72 |
3 files changed, 357 insertions, 0 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 + |