Skip to content

Commit 3ed224e

Browse files
jwrdegoedebentiss
authored andcommitted
HID: logitech-dj: Fix 064d:c52f receiver support
The c52f nano receiver is a mouse only receiver. This means that it needs some special handling compared to the c534 nano receiver: 1) It sends unnumbered mouse reports with a size of 8 bytes, so we need to extend the unnumbered mouse report handling to support reports upto 8 bytes large 2) It mouse reports have the same high-resolution format as those from the gaming mouse receivers 3) It can report consumer/multimedia buttons on its second interface, since this is a mouse-only receiver these must be forwarded to the mouse child device and not to the keyboard child-device (which will not exist) Link: https://bugzilla.kernel.org/show_bug.cgi?id=203619 Signed-off-by: Hans de Goede <[email protected]> Acked-by: Jiri Kosina <[email protected]> Signed-off-by: Benjamin Tissoires <[email protected]>
1 parent f9482da commit 3ed224e

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

drivers/hid/hid-logitech-dj.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ enum recvr_type {
128128
recvr_type_dj,
129129
recvr_type_hidpp,
130130
recvr_type_gaming_hidpp,
131+
recvr_type_mouse_only,
131132
recvr_type_27mhz,
132133
recvr_type_bluetooth,
133134
};
@@ -879,9 +880,12 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
879880
schedule_work(&djrcv_dev->work);
880881
}
881882

882-
static void logi_hidpp_dev_conn_notif_equad(struct hidpp_event *hidpp_report,
883+
static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
884+
struct hidpp_event *hidpp_report,
883885
struct dj_workitem *workitem)
884886
{
887+
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
888+
885889
workitem->type = WORKITEM_TYPE_PAIRED;
886890
workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
887891
HIDPP_DEVICE_TYPE_MASK;
@@ -895,6 +899,8 @@ static void logi_hidpp_dev_conn_notif_equad(struct hidpp_event *hidpp_report,
895899
break;
896900
case REPORT_TYPE_MOUSE:
897901
workitem->reports_supported |= STD_MOUSE | HIDPP;
902+
if (djrcv_dev->type == recvr_type_mouse_only)
903+
workitem->reports_supported |= MULTIMEDIA;
898904
break;
899905
}
900906
}
@@ -938,7 +944,7 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
938944
case 0x01:
939945
device_type = "Bluetooth";
940946
/* Bluetooth connect packet contents is the same as (e)QUAD */
941-
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
947+
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
942948
if (!(hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
943949
HIDPP_MANUFACTURER_MASK)) {
944950
hid_info(hdev, "Non Logitech device connected on slot %d\n",
@@ -952,18 +958,18 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
952958
break;
953959
case 0x03:
954960
device_type = "QUAD or eQUAD";
955-
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
961+
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
956962
break;
957963
case 0x04:
958964
device_type = "eQUAD step 4 DJ";
959-
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
965+
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
960966
break;
961967
case 0x05:
962968
device_type = "DFU Lite";
963969
break;
964970
case 0x06:
965971
device_type = "eQUAD step 4 Lite";
966-
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
972+
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
967973
break;
968974
case 0x07:
969975
device_type = "eQUAD step 4 Gaming";
@@ -973,11 +979,11 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
973979
break;
974980
case 0x0a:
975981
device_type = "eQUAD nano Lite";
976-
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
982+
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
977983
break;
978984
case 0x0c:
979985
device_type = "eQUAD Lightspeed";
980-
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
986+
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
981987
workitem.reports_supported |= STD_KEYBOARD;
982988
break;
983989
}
@@ -1328,7 +1334,8 @@ static int logi_dj_ll_parse(struct hid_device *hid)
13281334
if (djdev->reports_supported & STD_MOUSE) {
13291335
dbg_hid("%s: sending a mouse descriptor, reports_supported: %llx\n",
13301336
__func__, djdev->reports_supported);
1331-
if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp)
1337+
if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp ||
1338+
djdev->dj_receiver_dev->type == recvr_type_mouse_only)
13321339
rdcat(rdesc, &rsize, mse_high_res_descriptor,
13331340
sizeof(mse_high_res_descriptor));
13341341
else if (djdev->dj_receiver_dev->type == recvr_type_27mhz)
@@ -1571,15 +1578,19 @@ static int logi_dj_raw_event(struct hid_device *hdev,
15711578
data[0] = data[1];
15721579
data[1] = 0;
15731580
}
1574-
/* The 27 MHz mouse-only receiver sends unnumbered mouse data */
1581+
/*
1582+
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
1583+
* receiver uses 6 byte packets, the nano receiver 8 bytes.
1584+
*/
15751585
if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
1576-
size == 6) {
1577-
u8 mouse_report[7];
1586+
size <= 8) {
1587+
u8 mouse_report[9];
15781588

15791589
/* Prepend report id */
15801590
mouse_report[0] = REPORT_TYPE_MOUSE;
1581-
memcpy(mouse_report + 1, data, 6);
1582-
logi_dj_recv_forward_input_report(hdev, mouse_report, 7);
1591+
memcpy(mouse_report + 1, data, size);
1592+
logi_dj_recv_forward_input_report(hdev, mouse_report,
1593+
size + 1);
15831594
}
15841595

15851596
return false;
@@ -1650,6 +1661,7 @@ static int logi_dj_probe(struct hid_device *hdev,
16501661
case recvr_type_dj: no_dj_interfaces = 3; break;
16511662
case recvr_type_hidpp: no_dj_interfaces = 2; break;
16521663
case recvr_type_gaming_hidpp: no_dj_interfaces = 3; break;
1664+
case recvr_type_mouse_only: no_dj_interfaces = 2; break;
16531665
case recvr_type_27mhz: no_dj_interfaces = 2; break;
16541666
case recvr_type_bluetooth: no_dj_interfaces = 2; break;
16551667
}
@@ -1823,10 +1835,10 @@ static const struct hid_device_id logi_dj_receivers[] = {
18231835
{HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18241836
USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2),
18251837
.driver_data = recvr_type_dj},
1826-
{ /* Logitech Nano (non DJ) receiver */
1838+
{ /* Logitech Nano mouse only receiver */
18271839
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18281840
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER),
1829-
.driver_data = recvr_type_hidpp},
1841+
.driver_data = recvr_type_mouse_only},
18301842
{ /* Logitech Nano (non DJ) receiver */
18311843
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18321844
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),

0 commit comments

Comments
 (0)