* [PATCH] HID: logitech-hidpp: do not overwrite the device's hi-res wheel mode
@ 2026-09-23 18:11 Roman Stingler
2026-09-25 9:50 ` johannes.goede
2026-09-25 9:50 ` johannes.goede
0 siblings, 2 replies; 3+ messages in thread
From: Roman Stingler @ 2026-09-23 18:11 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires
Cc: Roman Stingler, Lovekesh Solanki, Erik Hakansson, Filipe Lains,
Bastien Nocera, linux-input, linux-kernel, regressions
hi_res_scroll_enable() unconditionally puts HID++ 2.0 devices supporting
the HiRes Wheel feature (0x2121) into high-resolution mode on every
connect event.
On at least the MX Master 4 that mode is persistent state in the device.
With hid-logitech-hidpp unloaded, a mode set from userspace survives
switching the mouse off and on again. Writing it at connect therefore
destroys a setting the user configured, and does so on every probe --
cold boot, receiver replug or module reload -- so userspace cannot
reliably keep it either: it gets no indication that the mode it set has
been changed underneath it.
This became visible when Bolt receivers gained support in 7.3. Before
that these devices were driven by hid-generic, hid-logitech-hidpp never
bound to them, and nothing in the kernel wrote the setting.
0x2121 exposes getWheelMode alongside setWheelMode. Read the current
mode and scale vertical_wheel_counter.wheel_multiplier to match rather
than forcing high resolution: a device left in high-resolution mode
still gets its multiplier, and one the user configured for low
resolution is left alone.
Note this changes behaviour for devices sitting at a low-resolution
factory default -- the kernel will no longer switch those to
high-resolution scrolling.
Link: https://lore.kernel.org/all/20260920094508.39682-1-roman.stingler@gmail.com/
Signed-off-by: Roman Stingler <roman.stingler@gmail.com>
---
Lovekesh Solanki proposed an alternative in the report thread which
remembers the last mode seen from userspace. That fixes suspend/resume
but not the probe cases above, and he suggested sending this instead:
https://lore.kernel.org/all/arJs7GjCP3r4IaM-@eggarch/
Tested on 7.3-rc3 with an MX Master 4 (WPID B042) behind a Bolt
receiver, built as a module and loaded at boot:
stock this patch
suspend/resume no yes
module reload no yes
cold boot no yes
With the mouse left in high-resolution mode, a full module reload leaves
it in high resolution and the multiplier is fetched as before. I checked
that the mode is honoured; I did not instrument events per detent,
though that path is unchanged.
drivers/hid/hid-logitech-hidpp.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 493763a12518..338477bfcaeb 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2044,6 +2044,7 @@ static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp,
#define HIDPP_PAGE_HIRES_WHEEL 0x2121
#define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00
+#define CMD_HIRES_WHEEL_GET_WHEEL_MODE 0x10
#define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20
static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
@@ -2072,12 +2073,10 @@ static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
return ret;
}
-static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
- bool high_resolution, bool use_hidpp)
+static int hidpp_hrw_get_wheel_mode(struct hidpp_device *hidpp, u8 *mode)
{
u8 feature_index;
int ret;
- u8 params[1];
struct hidpp_report response;
ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
@@ -2085,13 +2084,14 @@ static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
if (ret)
return ret;
- params[0] = (invert ? BIT(2) : 0) |
- (high_resolution ? BIT(1) : 0) |
- (use_hidpp ? BIT(0) : 0);
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
+ CMD_HIRES_WHEEL_GET_WHEEL_MODE,
+ NULL, 0, &response);
+ if (ret)
+ return ret;
- return hidpp_send_fap_command_sync(hidpp, feature_index,
- CMD_HIRES_WHEEL_SET_WHEEL_MODE,
- params, sizeof(params), &response);
+ *mode = response.fap.params[0];
+ return 0;
}
/* -------------------------------------------------------------------------- */
@@ -3910,8 +3910,16 @@ static int hi_res_scroll_enable(struct hidpp_device *hidpp)
u8 multiplier = 1;
if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL) {
- ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
- if (ret == 0)
+ u8 mode;
+
+ /*
+ * The wheel mode is persistent state in the device, so read it
+ * rather than overwriting it, and scale to match. A device
+ * left in hi-res still gets the multiplier it needs; one the
+ * user configured for low resolution is left alone.
+ */
+ ret = hidpp_hrw_get_wheel_mode(hidpp, &mode);
+ if (ret == 0 && (mode & BIT(1)))
ret = hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
} else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL) {
ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
base-commit: fe2ec83746e501645709761605c2464a44fd2929
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] HID: logitech-hidpp: do not overwrite the device's hi-res wheel mode
2026-09-23 18:11 [PATCH] HID: logitech-hidpp: do not overwrite the device's hi-res wheel mode Roman Stingler
@ 2026-09-25 9:50 ` johannes.goede
2026-09-25 9:50 ` johannes.goede
1 sibling, 0 replies; 3+ messages in thread
From: johannes.goede @ 2026-09-25 9:50 UTC (permalink / raw)
To: Roman Stingler, Jiri Kosina, Benjamin Tissoires
Cc: Lovekesh Solanki, Erik Hakansson, Filipe Lains, Bastien Nocera,
linux-input, linux-kernel, regressions
Hi,
On 23-Sep-26 20:11, Roman Stingler wrote:
> hi_res_scroll_enable() unconditionally puts HID++ 2.0 devices supporting
> the HiRes Wheel feature (0x2121) into high-resolution mode on every
> connect event.
>
> On at least the MX Master 4 that mode is persistent state in the device.
> With hid-logitech-hidpp unloaded, a mode set from userspace survives
> switching the mouse off and on again. Writing it at connect therefore
> destroys a setting the user configured, and does so on every probe --
> cold boot, receiver replug or module reload -- so userspace cannot
> reliably keep it either: it gets no indication that the mode it set has
> been changed underneath it.
>
> This became visible when Bolt receivers gained support in 7.3. Before
> that these devices were driven by hid-generic, hid-logitech-hidpp never
> bound to them, and nothing in the kernel wrote the setting.
>
> 0x2121 exposes getWheelMode alongside setWheelMode. Read the current
> mode and scale vertical_wheel_counter.wheel_multiplier to match rather
> than forcing high resolution: a device left in high-resolution mode
> still gets its multiplier, and one the user configured for low
> resolution is left alone.
>
> Note this changes behaviour for devices sitting at a low-resolution
> factory default -- the kernel will no longer switch those to
> high-resolution scrolling.
>
> Link: https://lore.kernel.org/all/20260920094508.39682-1-roman.stingler@gmail.com/
> Signed-off-by: Roman Stingler <roman.stingler@gmail.com>
I assume the low-res mode factory default is because not all OS-es
can handle hires mode (I guess mostly much older Os-es cannot).
This regresses (new factory default mice) to no longer support
hi-res wheel mode at all under Linux, even the non Bolt ones even
though this is only a Bolt issue.
So in so far as this is a solution at all, it really should be
limited to Bolt devices only. Although I wonder what switching
Bolt devices to the hidpp driver wins us after this patch?
Do they still gain any meaningful functionality from the switch
to the hidpp driver?
Also I wonder if there is not a non-persistent equivalent of
setWheelMode? That would be ideal.
Do we know what Windows (with Logitech drivers) does here?
I cannot believe that Windows will not use hi-res wheel mode
when the Logitech drivers are installed.
Regards,
Hans
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] HID: logitech-hidpp: do not overwrite the device's hi-res wheel mode
2026-09-23 18:11 [PATCH] HID: logitech-hidpp: do not overwrite the device's hi-res wheel mode Roman Stingler
2026-09-25 9:50 ` johannes.goede
@ 2026-09-25 9:50 ` johannes.goede
1 sibling, 0 replies; 3+ messages in thread
From: johannes.goede @ 2026-09-25 9:50 UTC (permalink / raw)
To: Roman Stingler, Jiri Kosina, Benjamin Tissoires
Cc: Lovekesh Solanki, Erik Hakansson, Filipe Lains, Bastien Nocera,
linux-input, linux-kernel, regressions
Hi,
On 23-Sep-26 20:11, Roman Stingler wrote:
> hi_res_scroll_enable() unconditionally puts HID++ 2.0 devices supporting
> the HiRes Wheel feature (0x2121) into high-resolution mode on every
> connect event.
>
> On at least the MX Master 4 that mode is persistent state in the device.
> With hid-logitech-hidpp unloaded, a mode set from userspace survives
> switching the mouse off and on again. Writing it at connect therefore
> destroys a setting the user configured, and does so on every probe --
> cold boot, receiver replug or module reload -- so userspace cannot
> reliably keep it either: it gets no indication that the mode it set has
> been changed underneath it.
>
> This became visible when Bolt receivers gained support in 7.3. Before
> that these devices were driven by hid-generic, hid-logitech-hidpp never
> bound to them, and nothing in the kernel wrote the setting.
>
> 0x2121 exposes getWheelMode alongside setWheelMode. Read the current
> mode and scale vertical_wheel_counter.wheel_multiplier to match rather
> than forcing high resolution: a device left in high-resolution mode
> still gets its multiplier, and one the user configured for low
> resolution is left alone.
>
> Note this changes behaviour for devices sitting at a low-resolution
> factory default -- the kernel will no longer switch those to
> high-resolution scrolling.
>
> Link: https://lore.kernel.org/all/20260920094508.39682-1-roman.stingler@gmail.com/
> Signed-off-by: Roman Stingler <roman.stingler@gmail.com>
I assume the low-res mode factory default is because not all OS-es
can handle hires mode (I guess mostly much older Os-es cannot).
This regresses (new factory default mice) to no longer support
hi-res wheel mode at all under Linux, even the non Bolt ones even
though this is only a Bolt issue.
So in so far as this is a solution at all, it really should be
limited to Bolt devices only. Although I wonder what switching
Bolt devices to the hidpp driver wins us after this patch?
Do they still gain any meaningful functionality from the switch
to the hidpp driver?
AlsoI wonder if there is not a non-persistent equivalent of
setWheelMode, that would be ideal.
Do we know what Windows (with Logitech drivers) does here?
I cannot believe that Windows will not use hi-res wheel mode
in that case...
Regards,
Hans
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-25 9:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23 18:11 [PATCH] HID: logitech-hidpp: do not overwrite the device's hi-res wheel mode Roman Stingler
2026-09-25 9:50 ` johannes.goede
2026-09-25 9:50 ` johannes.goede
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®