Skip to content

Commit

Permalink
HID: logitech-dj: add support for the new lightspeed receiver iteration
Browse files Browse the repository at this point in the history
Tested with the G Pro X Superlight. libratbag sees the device, as
expected, and input events are passing trough.

libratbag/libratbag#1122

The receiver has a quirk where the moused interface doesn't have a
report ID, I am not sure why, perhaps they forgot. All other interfaces
have report IDs so I am left scratching my head.
Since this driver doesn't have a quirk system, I simply implemented it
as a different receiver type, which is true, it just wouldn't be the
prefered approach :P

Signed-off-by: Filipe Laíns <lains@riseup.net>
  • Loading branch information
FFY00 authored and cthbleachbit committed Jan 28, 2024
1 parent 78c3a2a commit 4ae6706
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
1 change: 1 addition & 0 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,7 @@
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc547
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
Expand Down
50 changes: 37 additions & 13 deletions drivers/hid/hid-logitech-dj.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ enum recvr_type {
recvr_type_dj,
recvr_type_hidpp,
recvr_type_gaming_hidpp,
recvr_type_gaming_hidpp_missing_mse_report_id, /* lightspeed receiver missing the mouse report ID */
recvr_type_mouse_only,
recvr_type_27mhz,
recvr_type_bluetooth,
Expand Down Expand Up @@ -1433,6 +1434,7 @@ static int logi_dj_ll_parse(struct hid_device *hid)
dbg_hid("%s: sending a mouse descriptor, reports_supported: %llx\n",
__func__, djdev->reports_supported);
if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp ||
djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp_missing_mse_report_id ||
djdev->dj_receiver_dev->type == recvr_type_mouse_only)
rdcat(rdesc, &rsize, mse_high_res_descriptor,
sizeof(mse_high_res_descriptor));
Expand Down Expand Up @@ -1693,19 +1695,35 @@ static int logi_dj_raw_event(struct hid_device *hdev,
data[0] = data[1];
data[1] = 0;
}
/*
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
* receiver uses 6 byte packets, the nano receiver 8 bytes.
*/
if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
size <= 8) {
u8 mouse_report[9];

/* Prepend report id */
mouse_report[0] = REPORT_TYPE_MOUSE;
memcpy(mouse_report + 1, data, size);
logi_dj_recv_forward_input_report(hdev, mouse_report,
size + 1);

if (djrcv_dev->unnumbered_application == HID_GD_MOUSE) {
/*
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
* receiver uses 6 byte packets, the nano receiver 8 bytes.
* the lightspeed receiver (Pro X Superlight) 13 bytes.
*/
if (size <= 13) {
u8 mouse_report[14];

/* Prepend report id */
mouse_report[0] = REPORT_TYPE_MOUSE;
memcpy(mouse_report + 1, data, size);
logi_dj_recv_forward_input_report(hdev, mouse_report,
size + 1);

/*
* A variant of the ligtpseed receivers is missing the mouse
* report ID.
*/
} else if (djrcv_dev->type == recvr_type_gaming_hidpp_missing_mse_report_id) {
u8 mouse_report[17];

/* Prepend report id */
mouse_report[0] = REPORT_TYPE_MOUSE;
memcpy(mouse_report + 1, data, size);
logi_dj_recv_forward_input_report(hdev, mouse_report,
size + 1);
}
}

return false;
Expand Down Expand Up @@ -1776,6 +1794,7 @@ static int logi_dj_probe(struct hid_device *hdev,
case recvr_type_dj: no_dj_interfaces = 3; break;
case recvr_type_hidpp: no_dj_interfaces = 2; break;
case recvr_type_gaming_hidpp: no_dj_interfaces = 3; break;
case recvr_type_gaming_hidpp_missing_mse_report_id: no_dj_interfaces = 3; break;
case recvr_type_mouse_only: no_dj_interfaces = 2; break;
case recvr_type_27mhz: no_dj_interfaces = 2; break;
case recvr_type_bluetooth: no_dj_interfaces = 2; break;
Expand Down Expand Up @@ -1984,6 +2003,11 @@ static const struct hid_device_id logi_dj_receivers[] = {
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
.driver_data = recvr_type_gaming_hidpp},

{ /* Logitech lightspeed receiver (0xc547) */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
.driver_data = recvr_type_gaming_hidpp_missing_mse_report_id},

{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
.driver_data = recvr_type_27mhz},
Expand Down

0 comments on commit 4ae6706

Please sign in to comment.