[PATCH 2/2] HID: logitech-hidpp: enable reprogrammable buttons on Signature M650

From: Elliot Douglas

Date: Sat Jun 13 2026 - 13:51:59 EST


The Bluetooth Signature M650 exposes its side buttons through the normal
mouse report, but the observed events are short click-like events emitted
around release rather than physical press/release state.

The device appears to use the held side-button state for its built-in
gesture and side-button + wheel horizontal-scroll mode. As a result,
holding a side button long enough can prevent the normal mouse report from
emitting a usable button event at all.

HID++ REPROG_CONTROLS_V4 diversion for control IDs 0x0053 and 0x0056
provides real press and release timing for those same controls. Logitech
documents the Signature M650 side buttons as Back/Forward buttons, so
report the diverted controls as BTN_BACK and BTN_FORWARD.

Link: https://support.logi.com/hc/en-nz/articles/4414473810583-Getting-Started-Signature-M650

Signed-off-by: Elliot Douglas <edouglas7358@xxxxxxxxx>
---
drivers/hid/hid-logitech-hidpp.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 24c9cfaa4f37..80108778ee80 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -3621,6 +3621,9 @@ static int hidpp10_extra_mouse_buttons_raw_event(struct hidpp_device *hidpp,

#define HIDPP_REPROG_CONTROLS_EVENT_DIVERTED 0x00

+#define HIDPP_REPROG_CONTROL_M650_BACK 0x0053
+#define HIDPP_REPROG_CONTROL_M650_FORWARD 0x0056
+
struct hidpp_reprog_control_mapping {
u16 control;
u16 code;
@@ -3631,9 +3634,24 @@ struct hidpp_reprog_controls_profile {
unsigned int mapping_count;
};

+static const struct hidpp_reprog_control_mapping m650_reprog_control_mappings[] = {
+ { HIDPP_REPROG_CONTROL_M650_BACK, BTN_BACK },
+ { HIDPP_REPROG_CONTROL_M650_FORWARD, BTN_FORWARD },
+};
+
+static const struct hidpp_reprog_controls_profile m650_reprog_controls_profile = {
+ .mappings = m650_reprog_control_mappings,
+ .mapping_count = ARRAY_SIZE(m650_reprog_control_mappings),
+};
+
static const struct hidpp_reprog_controls_profile *
hidpp20_reprog_controls_get_profile(struct hidpp_device *hidpp)
{
+ switch (hidpp->hid_dev->product) {
+ case 0xb02a:
+ return &m650_reprog_controls_profile;
+ }
+
return NULL;
}

@@ -4921,7 +4939,8 @@ static const struct hid_device_id hidpp_devices[] = {
{ /* MX Vertical mouse over Bluetooth */
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb020) },
{ /* Signature M650 over Bluetooth */
- HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb02a) },
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb02a),
+ .driver_data = HIDPP_QUIRK_HIDPP_REPROG_CONTROLS_BTNS },
{ /* MX Master 3 mouse over Bluetooth */
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023) },
{ /* MX Anywhere 3 mouse over Bluetooth */
--
2.54.0