From: Oleksandr Natalenko <oleksandr@natalenko.name>
To: linux-input@vger.kernel.org
Cc: lains@riseup.net, hadess@hadess.net, jikos@kernel.org,
bentiss@kernel.org, erikhakan@gmail.com,
Shuah Khan <skhan@linuxfoundation.org>,
Brigham Campbell <me@brighamcampbell.com>,
Jori Koolstra <jkoolstra@xs4all.nl>,
Rafael Passos <rafael@rcpassos.me>
Subject: Re: [PATCH] HID: logitech-hidpp: fix hi-res scroll for Bolt-connected MX Master
Date: Mon, 14 Sep 2026 12:31:01 +0200 [thread overview]
Message-ID: <awkjflaaQZW7nPVUOsxJ5A@natalenko.name> (raw)
In-Reply-To: <20260904034843.1340846-1-rafael@rcpassos.me>
[-- Attachment #1: Type: text/plain, Size: 5147 bytes --]
Hello.
On pátek 4. září 2026 5:48:29, středoevropský letní čas Rafael Passos wrote:
> The new added support for Logitech HID++ caused this mouse to
> scroll too far for each tic when using the USB dongle (Bolt).
> Previously, this mouse was handled as hid_generic over the Bold
> connection, and logitech-hidpp when over Bluetooth.
>
> Cause:
> Over the Bolt receiver, the mouse reports are forwarded over the generic
> interface 1, instead of the new HID++ child device. The generic hid does
> now know about the hi-res scrolling used by the HID++.
> In my tests, I discovered this mouse has a multiplier factor of 15. This
> multiplier is only handled by the logitech-hidpp driver. When piped to
> hid_generic, the "hi-res" value was piped to a "low-res" field, making
> the scroll unbearable.
>
> The fix routes the wheel using the HID++, so the ticks are scaled by the
> multiplier and correctly reported as a hi-res event.
>
> I also had to move the hidpp_is_bolt_child function up, to use it in the
> hidpp_connect_event function, where the gate for
> hidpp_initialize_hires_scroll function lives.
>
> Tested with:
> - Logitech MX Master 3S (mouse) via Bolt receiver and Bluetooth.
>
> Fixes: 022eb347ff3a ("HID: logitech: add Bolt receiver support for Logitech HID++ devices")
> Signed-off-by: Rafael Passos <rafael@rcpassos.me>
For v7.3-rc3 + Bolt receiver + MX Master 4 mouse:
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Thank you.
> ---
>
> Hi,
> I decided to send this patch as soon as I made it work, to try to make
> it into this fix cycle.
>
> I do not have other devices to test this with.
> It would *be great* to have other users testing this.
>
> Lastly, I decided to make all the changes in a single patch.
> But I can break it up if asked.
>
> Thanks,
> Rafael
>
>
> drivers/hid/hid-logitech-hidpp.c | 47 ++++++++++++++++++++++----------
> 1 file changed, 32 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
> index 1504de32b1c84..960543bfd5ea1 100644
> --- a/drivers/hid/hid-logitech-hidpp.c
> +++ b/drivers/hid/hid-logitech-hidpp.c
> @@ -3900,6 +3900,19 @@ static int hidpp10_consumer_keys_raw_event(struct hidpp_device *hidpp,
> return 1;
> }
>
> +static bool hidpp_is_bolt_child(struct hid_device *hdev)
> +{
> + struct device *parent = hdev->dev.parent;
> + struct hid_device *receiver_hdev;
> +
> + if (!parent)
> + return false;
> +
> + receiver_hdev = to_hid_device(parent);
> + return receiver_hdev->vendor == USB_VENDOR_ID_LOGITECH &&
> + receiver_hdev->product == USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER;
> +}
> +
> /* -------------------------------------------------------------------------- */
> /* High-resolution scroll wheels */
> /* -------------------------------------------------------------------------- */
> @@ -3910,7 +3923,9 @@ 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);
> + bool use_hidpp = hidpp_is_bolt_child(hidpp->hid_dev);
> +
> + ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, use_hidpp);
> if (ret == 0)
> ret = hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
> } else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL) {
> @@ -3998,6 +4013,19 @@ static int hidpp20_hires_wheel_raw_event(struct hidpp_device *hidpp,
> return 1;
> }
>
> + /* wheel movement event: 16-bit signed delta in HID++ ticks */
> + if ((data[3] & 0xf0) == 0x00 && size >= 7 && hidpp->input &&
> + hidpp->vertical_wheel_counter.wheel_multiplier) {
> + s16 delta = get_unaligned_be16(&data[5]);
> +
> + if (delta) {
> + hidpp_scroll_counter_handle_scroll(hidpp->input,
> + &hidpp->vertical_wheel_counter, delta);
> + input_sync(hidpp->input);
> + }
> + return 1;
> + }
> +
> return 0;
> }
>
> @@ -4405,19 +4433,6 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
> return ret;
> }
>
> -static bool hidpp_is_bolt_child(struct hid_device *hdev)
> -{
> - struct device *parent = hdev->dev.parent;
> - struct hid_device *receiver_hdev;
> -
> - if (!parent)
> - return false;
> -
> - receiver_hdev = to_hid_device(parent);
> - return receiver_hdev->vendor == USB_VENDOR_ID_LOGITECH &&
> - receiver_hdev->product == USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER;
> -}
> -
> static int hidpp_bolt_init(struct hidpp_device *hidpp)
> {
> struct hid_device *hdev = hidpp->hid_dev;
> @@ -4579,7 +4594,9 @@ static void hidpp_connect_event(struct work_struct *work)
> }
>
> hidpp_initialize_battery(hidpp);
> - if (!hid_is_usb(hidpp->hid_dev))
> +
> + if (!hid_is_usb(hidpp->hid_dev) ||
> + hidpp_is_bolt_child(hidpp->hid_dev))
> hidpp_initialize_hires_scroll(hidpp);
>
> /* forward current battery state */
>
--
Oleksandr Natalenko, MSE
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2026-09-14 10:41 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-04 3:48 [PATCH] HID: logitech-hidpp: fix hi-res scroll for Bolt-connected MX Master Rafael Passos
2026-09-04 4:02 ` sashiko-bot
2026-09-04 7:44 ` Alexey Zagorodnikov
2026-09-04 16:34 ` Erik Håkansson
2026-09-04 17:03 ` Benjamin Tissoires
2026-09-04 18:20 ` Alexey Zagorodnikov
2026-09-04 18:17 ` Alexey Zagorodnikov
2026-09-04 20:21 ` Rafael Passos
2026-09-07 17:46 ` erikhakan
2026-09-14 10:31 ` Oleksandr Natalenko [this message]
2026-09-14 10:51 ` Oleksandr Natalenko
2026-09-22 15:28 ` erikhakan
2026-09-22 16:28 ` Rafael Passos
2026-09-22 16:32 ` Rafael Passos
2026-09-22 20:33 ` Oleksandr Natalenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=awkjflaaQZW7nPVUOsxJ5A@natalenko.name \
--to=oleksandr@natalenko.name \
--cc=bentiss@kernel.org \
--cc=erikhakan@gmail.com \
--cc=hadess@hadess.net \
--cc=jikos@kernel.org \
--cc=jkoolstra@xs4all.nl \
--cc=lains@riseup.net \
--cc=linux-input@vger.kernel.org \
--cc=me@brighamcampbell.com \
--cc=rafael@rcpassos.me \
--cc=skhan@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.