This document explains why Logitech devices connected via Bluetooth have limited functionality on Linux compared to USB connections.
Verified: Tested 2026-01-21 with MX Master 3S via Bluetooth on Linux 6.18.5. All limitations confirmed.
Bluetooth-connected Logitech devices cannot be configured by logiops-rs. The Linux kernel's logitech-hidpp-device driver intercepts HID++ protocol responses, preventing userspace applications from communicating with the device.
Solution: Connect your device via USB (directly or using the Unifying/Bolt receiver) for full configuration support.
Other tools affected: Solaar, libratbag/Piper have the same limitation—they use the same hidraw interface and experience identical timeouts.
Logitech's HID++ protocol is a bidirectional communication layer on top of standard HID. It allows:
- Querying device capabilities (DPI ranges, battery level, feature support)
- Configuring device settings (DPI, scroll wheel behavior, button mappings)
- Receiving notifications (battery warnings, button presses for remapping)
Communication follows a request-response pattern over HID reports.
The Linux kernel includes a driver (hid-logitech-hidpp) that provides native support for Logitech HID++ devices. This driver:
- Automatically binds to all Logitech Bluetooth HID devices
- Consumes HID++ responses at the kernel transport layer
- Exposes limited data via sysfs (battery level only)
When logiops-rs sends an HID++ request to a Bluetooth device:
logiops-rs → HID++ request → kernel → device
device → HID++ response → kernel driver (consumed) ✗ logiops-rs never receives it
The response never reaches userspace, causing communication timeouts.
Verified behavior (MX Master 3S via Bluetooth):
INFO logiops_core::device: initializing HID++ device path=/dev/hidraw13
WARN logiops::registry: failed to initialize device error=read timeout after 1000ms
USB HID transport has a different architecture that allows responses to reach both the kernel driver AND userspace:
logiops-rs → HID++ request → kernel → device
device → HID++ response → kernel → driver AND /dev/hidraw* → logiops-rs ✓
This includes:
- Direct USB connection (cable)
- Unifying receiver (USB dongle, pairs up to 6 devices)
- Bolt receiver (USB dongle, newer protocol)
| Feature | logiops-rs | Kernel sysfs | Notes |
|---|---|---|---|
| Basic mouse/keyboard input | N/A | N/A | Standard HID, works normally |
| Battery level | ✗ | ✓ Read-only | /sys/class/power_supply/hidpp_battery_* |
| Device name | ✗ | ✓ Read-only | Via model_name in sysfs |
| DPI adjustment | ✗ | ✗ | HID++ blocked |
| SmartShift configuration | ✗ | ✗ | HID++ blocked |
| Button remapping | ✗ | ✗ | HID++ blocked |
| Gesture configuration | ✗ | ✗ | HID++ blocked |
| Profile switching | ✗ | ✗ | HID++ blocked |
| Feature | Status | Implementation |
|---|---|---|
| Basic mouse/keyboard input | ✓ Works | Standard HID |
| Battery level | ✓ Works | Unified Battery (0x1000) or Battery Status (0x1001) |
| Device name | ✓ Works | DeviceName (0x0005) |
| DPI adjustment | ✓ Works | Adjustable DPI (0x2201) |
| SmartShift configuration | ✓ Works | SmartShift (0x2110) |
| Button remapping | ✗ Planned | Reprogrammable Controls (0x1b04) - Phase 3 |
| Gesture configuration | ✗ Planned | Phase 3 |
| Profile switching | ✗ Planned | Phase 5 |
Currently logiops-rs can (on USB only):
- Read: Device info, feature list, DPI, SmartShift config, battery status
- Write: DPI value, SmartShift threshold/torque/mode
- Auto-apply: Configuration from TOML file on device connect
-
Use the included USB receiver - Most Logitech devices ship with a Unifying or Bolt receiver. Use it for full configuration support.
-
Use USB cable if available - Some devices (like MX Master series) support direct USB connection.
-
Accept Bluetooth limitations - If you must use Bluetooth, understand you'll be stuck with factory default settings.
# List Logitech HID devices with their driver and bus type
for h in /sys/class/hidraw/hidraw*; do
uevent=$(cat "$h/device/uevent" 2>/dev/null)
if echo "$uevent" | grep -q "046D"; then
name=$(echo "$uevent" | grep HID_NAME | cut -d= -f2)
driver=$(echo "$uevent" | grep DRIVER | cut -d= -f2)
bus=$(echo "$uevent" | grep MODALIAS | grep -oP 'b\K[0-9a-f]{4}')
echo "$(basename $h): $name"
echo " Driver: $driver"
echo " Bus: $bus (0003=USB, 0005=Bluetooth)"
fi
doneExample output:
hidraw13: Logitech MX Master 3S
Driver: logitech-hidpp-device
Bus: 0005 (0003=USB, 0005=Bluetooth) ← Bluetooth, won't work with logiops-rs
Even though configuration doesn't work, you can read battery level:
# Find Logitech battery devices
ls /sys/class/power_supply/ | grep hidpp
# Read battery percentage
cat /sys/class/power_supply/hidpp_battery_*/capacity
# Read charging status
cat /sys/class/power_supply/hidpp_battery_*/statusYou might think unbinding the kernel driver would allow userspace access:
# Find your device ID
ls /sys/bus/hid/drivers/logitech-hidpp-device/
# Shows: 0005:046D:B034.0023
# Unbind the driver
echo "0005:046D:B034.0023" | sudo tee /sys/bus/hid/drivers/logitech-hidpp-device/unbindResult: The /dev/hidraw* device disappears entirely. The HID driver creates the hidraw node, so without any driver bound, there's no device to communicate with.
Attempting to rebind to hid-generic also fails because it won't accept devices that match the more specific logitech-hidpp-device driver.
You can prevent the kernel driver from loading entirely:
# /etc/modprobe.d/logitech-hidpp-blacklist.conf
blacklist hid_logitech_hidppThen reboot or rmmod hid_logitech_hidpp.
Warning: This affects ALL Logitech HID++ devices (USB and Bluetooth) and disables:
- System battery indicator for all Logitech devices
- Kernel-level power management
- High-resolution scrolling provided by the kernel
Not recommended unless you only use USB devices and want logiops-rs to handle everything.
If you need specific settings on Bluetooth:
- Configure on Windows/macOS using Logitech Options+
- Settings are stored in device onboard memory
- Bluetooth connection will use those stored settings
The kernel developers attempted to improve Bluetooth HID++ support in Linux 6.1 by enabling it for all Logitech Bluetooth devices by default. This was reverted because:
- Device compatibility issues: Some devices that don't fully support HID++ would be left with a "dead mouse" when the driver gave up
- Match function limitations: The
->match()function wasn't designed for use outsidehid-generic - Corner cases: The driver has unhandled edge cases where it gives up on devices it shouldn't
The fix was postponed to Linux 6.2/6.3 but the fundamental architecture remains: the kernel driver owns the HID++ response stream for Bluetooth devices.
This is an architectural decision, not a bug. The kernel prioritizes system-level battery monitoring and power management over userspace configuration tools.
Potential improvements for logiops-rs:
-
Hybrid mode: Detect Bluetooth devices and read battery from sysfs while warning about configuration limitations
-
Connection type detection: Automatically identify USB vs Bluetooth and adjust behavior
-
Graceful degradation: Show device info even when configuration isn't possible
-
Notification to user: Clear warning when a Bluetooth device is detected
These features are planned for future phases but will have the same Bluetooth limitation:
| Feature | Phase | HID++ Feature ID |
|---|---|---|
| Button remapping | 3 | Reprogrammable Controls (0x1b04) |
| Gesture configuration | 3 | TBD |
| HiRes scrolling | 3 | HiRes Wheel (0x2121) |
| Profile switching | 5 | Onboard Profiles (0x8100) |