All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Erik Håkansson" <erikhakan@gmail.com>
To: Jiri Kosina <jikos@kernel.org>, Benjamin Tissoires <bentiss@kernel.org>
Cc: "Filipe Laíns" <lains@riseup.net>,
	"Bastien Nocera" <hadess@hadess.net>,
	"Rafael Passos" <rafael@rcpassos.me>,
	"Grégoire Stein" <greyxor@protonmail.com>,
	"Alexey Zagorodnikov" <xglooom@gmail.com>,
	"Oleksandr Natalenko" <oleksandr@natalenko.name>,
	"Roman Stingler" <roman.stingler@gmail.com>,
	"Lovekesh Solanki" <lovekeshsolanki00@gmail.com>,
	"Kateřina Medvědová" <k8ie@mcld.eu>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Erik Håkansson" <erikhakan@gmail.com>
Subject: [PATCH 1/2] HID: logitech-hidpp: fix hi-res scroll for Bolt-connected MX Master
Date: Tue, 22 Sep 2026 19:40:27 +0200	[thread overview]
Message-ID: <20260922-feature-bolt-fix-v1-1-63b0fa8da0d3@gmail.com> (raw)
In-Reply-To: <20260922-feature-bolt-fix-v1-0-63b0fa8da0d3@gmail.com>

From: Rafael Passos <rafael@rcpassos.me>

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>
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Tested-by: Alexey Zagorodnikov <xglooom@gmail.com>
---
 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 4e00ac91493f..166980be57b7 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -3891,6 +3891,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                                              */
 /* -------------------------------------------------------------------------- */
@@ -3901,7 +3914,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) {
@@ -3989,6 +4004,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;
 }
 
@@ -4379,19 +4407,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;
@@ -4553,7 +4568,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 */

-- 
2.55.0


  reply	other threads:[~2026-09-22 17:40 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-22 17:40 [PATCH 0/2] HID: logitech-hidpp: fix Bolt hi-res wheel handling Erik Håkansson
2026-09-22 17:40 ` Erik Håkansson [this message]
2026-09-22 17:51   ` [PATCH 1/2] HID: logitech-hidpp: fix hi-res scroll for Bolt-connected MX Master sashiko-bot
2026-09-22 17:40 ` [PATCH 2/2] HID: logitech-hidpp: fix Bolt wheel mode handling Erik Håkansson
2026-09-22 17:53   ` sashiko-bot
2026-09-23  6:39 ` [PATCH 0/2] HID: logitech-hidpp: fix Bolt hi-res wheel handling Oleksandr Natalenko
2026-09-23  7:54   ` Benjamin Tissoires
2026-09-23 16:09     ` erikhakan
2026-09-24  6:51       ` Oleksandr Natalenko
2026-09-24 21:41         ` Erik Håkansson
2026-09-24 21:48           ` erikhakan
2026-09-24 21:57           ` Oleksandr Natalenko
2026-09-26 11:13             ` Erik Håkansson
2026-09-26 11:39               ` Oleksandr Natalenko
2026-09-26 12:12                 ` Erik Håkansson
2026-09-26 12:24                   ` Oleksandr Natalenko
2026-09-26 16:47                     ` Erik Håkansson

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=20260922-feature-bolt-fix-v1-1-63b0fa8da0d3@gmail.com \
    --to=erikhakan@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=greyxor@protonmail.com \
    --cc=hadess@hadess.net \
    --cc=jikos@kernel.org \
    --cc=k8ie@mcld.eu \
    --cc=lains@riseup.net \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lovekeshsolanki00@gmail.com \
    --cc=oleksandr@natalenko.name \
    --cc=rafael@rcpassos.me \
    --cc=roman.stingler@gmail.com \
    --cc=xglooom@gmail.com \
    /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.