Skip to content

Commit 686e161

Browse files
author
Jiri Kosina
committed
Merge branch 'for-5.13/logitech' into for-linus
- Support for newer Quad/BT 2.0 Logitech receivers in HID proxy mode from Hans de Goede
2 parents 0b21c35 + 434f770 commit 686e161

File tree

4 files changed

+120
-48
lines changed

4 files changed

+120
-48
lines changed

drivers/hid/hid-ids.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@
809809
#define USB_DEVICE_ID_LOGITECH_27MHZ_MOUSE_RECEIVER 0xc51b
810810
#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER 0xc52b
811811
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER 0xc52f
812+
#define USB_DEVICE_ID_LOGITECH_G700_RECEIVER 0xc531
812813
#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 0xc532
813814
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
814815
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
@@ -817,8 +818,14 @@
817818
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
818819
#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
819820
#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
820-
#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
821-
#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
821+
#define USB_DEVICE_ID_MX5000_RECEIVER_MOUSE_DEV 0xc70a
822+
#define USB_DEVICE_ID_MX5000_RECEIVER_KBD_DEV 0xc70e
823+
#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV 0xc713
824+
#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV 0xc714
825+
#define USB_DEVICE_ID_MX5500_RECEIVER_KBD_DEV 0xc71b
826+
#define USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV 0xc71c
827+
#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV 0xc71e
828+
#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV 0xc71f
822829
#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03
823830
#define USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL 0xca04
824831

drivers/hid/hid-lg.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -568,22 +568,6 @@ static int lg_ultrax_remote_mapping(struct hid_input *hi,
568568
return 1;
569569
}
570570

571-
static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
572-
unsigned long **bit, int *max)
573-
{
574-
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
575-
return 0;
576-
577-
switch (usage->hid & HID_USAGE) {
578-
579-
case 0x00d: lg_map_key_clear(KEY_MEDIA); break;
580-
default:
581-
return 0;
582-
583-
}
584-
return 1;
585-
}
586-
587571
static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
588572
unsigned long **bit, int *max)
589573
{
@@ -668,10 +652,6 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi,
668652
lg_ultrax_remote_mapping(hi, usage, bit, max))
669653
return 1;
670654

671-
if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
672-
lg_dinovo_mapping(hi, usage, bit, max))
673-
return 1;
674-
675655
if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
676656
return 1;
677657

@@ -879,10 +859,6 @@ static const struct hid_device_id lg_devices[] = {
879859

880860
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP),
881861
.driver_data = LG_DUPLICATE_USAGES },
882-
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE),
883-
.driver_data = LG_DUPLICATE_USAGES },
884-
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI),
885-
.driver_data = LG_DUPLICATE_USAGES },
886862

887863
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD),
888864
.driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },

drivers/hid/hid-logitech-dj.c

Lines changed: 111 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#define STD_MOUSE BIT(2)
8585
#define MULTIMEDIA BIT(3)
8686
#define POWER_KEYS BIT(4)
87+
#define KBD_MOUSE BIT(5)
8788
#define MEDIA_CENTER BIT(8)
8889
#define KBD_LEDS BIT(14)
8990
/* Fake (bitnr > NUMBER_OF_HID_REPORTS) bit to track HID++ capability */
@@ -117,6 +118,7 @@ enum recvr_type {
117118
recvr_type_mouse_only,
118119
recvr_type_27mhz,
119120
recvr_type_bluetooth,
121+
recvr_type_dinovo,
120122
};
121123

122124
struct dj_report {
@@ -333,6 +335,47 @@ static const char mse_bluetooth_descriptor[] = {
333335
0xC0, /* END_COLLECTION */
334336
};
335337

338+
/* Mouse descriptor (5) for Bluetooth receiver, normal-res hwheel, 8 buttons */
339+
static const char mse5_bluetooth_descriptor[] = {
340+
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
341+
0x09, 0x02, /* Usage (Mouse) */
342+
0xa1, 0x01, /* Collection (Application) */
343+
0x85, 0x05, /* Report ID (5) */
344+
0x09, 0x01, /* Usage (Pointer) */
345+
0xa1, 0x00, /* Collection (Physical) */
346+
0x05, 0x09, /* Usage Page (Button) */
347+
0x19, 0x01, /* Usage Minimum (1) */
348+
0x29, 0x08, /* Usage Maximum (8) */
349+
0x15, 0x00, /* Logical Minimum (0) */
350+
0x25, 0x01, /* Logical Maximum (1) */
351+
0x95, 0x08, /* Report Count (8) */
352+
0x75, 0x01, /* Report Size (1) */
353+
0x81, 0x02, /* Input (Data,Var,Abs) */
354+
0x05, 0x01, /* Usage Page (Generic Desktop) */
355+
0x16, 0x01, 0xf8, /* Logical Minimum (-2047) */
356+
0x26, 0xff, 0x07, /* Logical Maximum (2047) */
357+
0x75, 0x0c, /* Report Size (12) */
358+
0x95, 0x02, /* Report Count (2) */
359+
0x09, 0x30, /* Usage (X) */
360+
0x09, 0x31, /* Usage (Y) */
361+
0x81, 0x06, /* Input (Data,Var,Rel) */
362+
0x15, 0x81, /* Logical Minimum (-127) */
363+
0x25, 0x7f, /* Logical Maximum (127) */
364+
0x75, 0x08, /* Report Size (8) */
365+
0x95, 0x01, /* Report Count (1) */
366+
0x09, 0x38, /* Usage (Wheel) */
367+
0x81, 0x06, /* Input (Data,Var,Rel) */
368+
0x05, 0x0c, /* Usage Page (Consumer Devices) */
369+
0x0a, 0x38, 0x02, /* Usage (AC Pan) */
370+
0x15, 0x81, /* Logical Minimum (-127) */
371+
0x25, 0x7f, /* Logical Maximum (127) */
372+
0x75, 0x08, /* Report Size (8) */
373+
0x95, 0x01, /* Report Count (1) */
374+
0x81, 0x06, /* Input (Data,Var,Rel) */
375+
0xc0, /* End Collection */
376+
0xc0, /* End Collection */
377+
};
378+
336379
/* Gaming Mouse descriptor (2) */
337380
static const char mse_high_res_descriptor[] = {
338381
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
@@ -480,6 +523,7 @@ static const char hidpp_descriptor[] = {
480523
#define MAX_RDESC_SIZE \
481524
(sizeof(kbd_descriptor) + \
482525
sizeof(mse_bluetooth_descriptor) + \
526+
sizeof(mse5_bluetooth_descriptor) + \
483527
sizeof(consumer_descriptor) + \
484528
sizeof(syscontrol_descriptor) + \
485529
sizeof(media_descriptor) + \
@@ -517,6 +561,11 @@ static void delayedwork_callback(struct work_struct *work);
517561
static LIST_HEAD(dj_hdev_list);
518562
static DEFINE_MUTEX(dj_hdev_list_lock);
519563

564+
static bool recvr_type_is_bluetooth(enum recvr_type type)
565+
{
566+
return type == recvr_type_bluetooth || type == recvr_type_dinovo;
567+
}
568+
520569
/*
521570
* dj/HID++ receivers are really a single logical entity, but for BIOS/Windows
522571
* compatibility they have multiple USB interfaces. On HID++ receivers we need
@@ -534,7 +583,7 @@ static struct dj_receiver_dev *dj_find_receiver_dev(struct hid_device *hdev,
534583
* The bluetooth receiver contains a built-in hub and has separate
535584
* USB-devices for the keyboard and mouse interfaces.
536585
*/
537-
sep = (type == recvr_type_bluetooth) ? '.' : '/';
586+
sep = recvr_type_is_bluetooth(type) ? '.' : '/';
538587

539588
/* Try to find an already-probed interface from the same device */
540589
list_for_each_entry(djrcv_dev, &dj_hdev_list, list) {
@@ -872,6 +921,14 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
872921
* touchpad to work we must also forward mouse input reports to the dj_hiddev
873922
* created for the keyboard (instead of forwarding them to a second paired
874923
* device with a device_type of REPORT_TYPE_MOUSE as we normally would).
924+
*
925+
* On Dinovo receivers the keyboard's touchpad and an optional paired actual
926+
* mouse send separate input reports, INPUT(2) aka STD_MOUSE for the mouse
927+
* and INPUT(5) aka KBD_MOUSE for the keyboard's touchpad.
928+
*
929+
* On MX5x00 receivers (which can also be paired with a Dinovo keyboard)
930+
* INPUT(2) is used for both an optional paired actual mouse and for the
931+
* keyboard's touchpad.
875932
*/
876933
static const u16 kbd_builtin_touchpad_ids[] = {
877934
0xb309, /* Dinovo Edge */
@@ -898,7 +955,10 @@ static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
898955
id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb;
899956
for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) {
900957
if (id == kbd_builtin_touchpad_ids[i]) {
901-
workitem->reports_supported |= STD_MOUSE;
958+
if (djrcv_dev->type == recvr_type_dinovo)
959+
workitem->reports_supported |= KBD_MOUSE;
960+
else
961+
workitem->reports_supported |= STD_MOUSE;
902962
break;
903963
}
904964
}
@@ -1367,14 +1427,21 @@ static int logi_dj_ll_parse(struct hid_device *hid)
13671427
else if (djdev->dj_receiver_dev->type == recvr_type_27mhz)
13681428
rdcat(rdesc, &rsize, mse_27mhz_descriptor,
13691429
sizeof(mse_27mhz_descriptor));
1370-
else if (djdev->dj_receiver_dev->type == recvr_type_bluetooth)
1430+
else if (recvr_type_is_bluetooth(djdev->dj_receiver_dev->type))
13711431
rdcat(rdesc, &rsize, mse_bluetooth_descriptor,
13721432
sizeof(mse_bluetooth_descriptor));
13731433
else
13741434
rdcat(rdesc, &rsize, mse_descriptor,
13751435
sizeof(mse_descriptor));
13761436
}
13771437

1438+
if (djdev->reports_supported & KBD_MOUSE) {
1439+
dbg_hid("%s: sending a kbd-mouse descriptor, reports_supported: %llx\n",
1440+
__func__, djdev->reports_supported);
1441+
rdcat(rdesc, &rsize, mse5_bluetooth_descriptor,
1442+
sizeof(mse5_bluetooth_descriptor));
1443+
}
1444+
13781445
if (djdev->reports_supported & MULTIMEDIA) {
13791446
dbg_hid("%s: sending a multimedia report descriptor: %llx\n",
13801447
__func__, djdev->reports_supported);
@@ -1692,6 +1759,7 @@ static int logi_dj_probe(struct hid_device *hdev,
16921759
case recvr_type_mouse_only: no_dj_interfaces = 2; break;
16931760
case recvr_type_27mhz: no_dj_interfaces = 2; break;
16941761
case recvr_type_bluetooth: no_dj_interfaces = 2; break;
1762+
case recvr_type_dinovo: no_dj_interfaces = 2; break;
16951763
}
16961764
if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
16971765
intf = to_usb_interface(hdev->dev.parent);
@@ -1857,23 +1925,27 @@ static void logi_dj_remove(struct hid_device *hdev)
18571925
}
18581926

18591927
static const struct hid_device_id logi_dj_receivers[] = {
1860-
{HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1928+
{ /* Logitech unifying receiver (0xc52b) */
1929+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18611930
USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER),
18621931
.driver_data = recvr_type_dj},
1863-
{HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1932+
{ /* Logitech unifying receiver (0xc532) */
1933+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18641934
USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2),
18651935
.driver_data = recvr_type_dj},
1866-
{ /* Logitech Nano mouse only receiver */
1936+
1937+
{ /* Logitech Nano mouse only receiver (0xc52f) */
18671938
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18681939
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER),
18691940
.driver_data = recvr_type_mouse_only},
1870-
{ /* Logitech Nano (non DJ) receiver */
1941+
{ /* Logitech Nano (non DJ) receiver (0xc534) */
18711942
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18721943
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),
18731944
.driver_data = recvr_type_hidpp},
1945+
18741946
{ /* Logitech G700(s) receiver (0xc531) */
18751947
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1876-
0xc531),
1948+
USB_DEVICE_ID_LOGITECH_G700_RECEIVER),
18771949
.driver_data = recvr_type_gaming_hidpp},
18781950
{ /* Logitech G602 receiver (0xc537) */
18791951
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
@@ -1883,17 +1955,18 @@ static const struct hid_device_id logi_dj_receivers[] = {
18831955
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18841956
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1),
18851957
.driver_data = recvr_type_gaming_hidpp},
1958+
{ /* Logitech powerplay receiver (0xc53a) */
1959+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1960+
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY),
1961+
.driver_data = recvr_type_gaming_hidpp},
18861962
{ /* Logitech lightspeed receiver (0xc53f) */
18871963
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18881964
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
18891965
.driver_data = recvr_type_gaming_hidpp},
1966+
18901967
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
18911968
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
18921969
.driver_data = recvr_type_27mhz},
1893-
{ /* Logitech powerplay receiver (0xc53a) */
1894-
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1895-
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY),
1896-
.driver_data = recvr_type_gaming_hidpp},
18971970
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc517) */
18981971
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18991972
USB_DEVICE_ID_S510_RECEIVER_2),
@@ -1902,22 +1975,40 @@ static const struct hid_device_id logi_dj_receivers[] = {
19021975
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
19031976
USB_DEVICE_ID_LOGITECH_27MHZ_MOUSE_RECEIVER),
19041977
.driver_data = recvr_type_27mhz},
1905-
{ /* Logitech MX5000 HID++ / bluetooth receiver keyboard intf. */
1978+
1979+
{ /* Logitech MX5000 HID++ / bluetooth receiver keyboard intf. (0xc70e) */
19061980
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1907-
0xc70e),
1981+
USB_DEVICE_ID_MX5000_RECEIVER_KBD_DEV),
19081982
.driver_data = recvr_type_bluetooth},
1909-
{ /* Logitech MX5000 HID++ / bluetooth receiver mouse intf. */
1983+
{ /* Logitech MX5000 HID++ / bluetooth receiver mouse intf. (0xc70a) */
19101984
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1911-
0xc70a),
1985+
USB_DEVICE_ID_MX5000_RECEIVER_MOUSE_DEV),
19121986
.driver_data = recvr_type_bluetooth},
1913-
{ /* Logitech MX5500 HID++ / bluetooth receiver keyboard intf. */
1987+
{ /* Logitech MX5500 HID++ / bluetooth receiver keyboard intf. (0xc71b) */
19141988
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1915-
0xc71b),
1989+
USB_DEVICE_ID_MX5500_RECEIVER_KBD_DEV),
19161990
.driver_data = recvr_type_bluetooth},
1917-
{ /* Logitech MX5500 HID++ / bluetooth receiver mouse intf. */
1991+
{ /* Logitech MX5500 HID++ / bluetooth receiver mouse intf. (0xc71c) */
19181992
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1919-
0xc71c),
1993+
USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV),
19201994
.driver_data = recvr_type_bluetooth},
1995+
1996+
{ /* Logitech Dinovo Edge HID++ / bluetooth receiver keyboard intf. (0xc713) */
1997+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1998+
USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV),
1999+
.driver_data = recvr_type_dinovo},
2000+
{ /* Logitech Dinovo Edge HID++ / bluetooth receiver mouse intf. (0xc714) */
2001+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
2002+
USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV),
2003+
.driver_data = recvr_type_dinovo},
2004+
{ /* Logitech DiNovo Mini HID++ / bluetooth receiver mouse intf. (0xc71e) */
2005+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
2006+
USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV),
2007+
.driver_data = recvr_type_dinovo},
2008+
{ /* Logitech DiNovo Mini HID++ / bluetooth receiver keyboard intf. (0xc71f) */
2009+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
2010+
USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV),
2011+
.driver_data = recvr_type_dinovo},
19212012
{}
19222013
};
19232014

drivers/hid/hid-quirks.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
445445
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
446446
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
447447
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
448-
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
449-
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
450448
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
451449
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
452450
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },

0 commit comments

Comments
 (0)