Message ID | 20201114212058.19590-4-hdegoede@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Jiri Kosina |
Headers | show |
Series | HID: logitech-dj: Dinovo keyboard fixes and improvements | expand |
Hi Hans, Not full review but... On Sat, Nov 14, 2020 at 10:21 PM Hans de Goede <hdegoede@redhat.com> wrote: > > The Dinovo Edge and Dinovo Mini keyboards with builtin touchpad come with > a different version of the quad/bt2.0 combo receivers shipped with the > MX5000 and MX5500 keyboards. These receivers are compatible with one > another, e.g. the Dinovo Edge keyboard can be paired with the MX5000 > receiver. > > Like the MX5x00 receivers in HID proxy mode these receivers present > themselves as a hub with multiple USB-HID devices, one for the keyboard > and one for the mouse. > > Where they differ is that the mouse USB-device has 2 input reports for > reporting mice events. It has the exact same INPUT(2) report as the > MX5x00 receivers, but it also has a second INPUT(5) mouse report which > is different; and when the Dinovo receivers are paired with the Dinovo > keyboards the second INPUT(5) mouse report is actually used for events > on the builtin touchpad. > > Add support for handling the Dinovo quad/bluetooth-2.0 combo receivers > in HID proxy mode to logitech-dj, like we already do for the similar > MX5000 and MX5500 receivers. > > This adds battery monitoring functionality (through logitech-hidpp) and > fixes the Phone (Fn + F1) and "[A]" - "[D]" (Fn + F9 - F12) hotkeys not > working on the Dinovo Edge. > > Note these receivers present themselves as a hub with 2 separate USB > devices for the keyboard and mouse; and the logitech-dj code needs to > bind to both devices (just as with the MX5x00 receivers). > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > drivers/hid/hid-ids.h | 6 ++- > drivers/hid/hid-lg.c | 24 --------- > drivers/hid/hid-logitech-dj.c | 91 +++++++++++++++++++++++++++++++++-- > drivers/hid/hid-quirks.c | 2 - > 4 files changed, 92 insertions(+), 31 deletions(-) > > diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h > index 108081ab5ae3..e17f252ba60f 100644 > --- a/drivers/hid/hid-ids.h > +++ b/drivers/hid/hid-ids.h > @@ -797,12 +797,14 @@ > #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 > #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 > #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 > -#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 > -#define USB_DEVICE_ID_DINOVO_MINI 0xc71f > #define USB_DEVICE_ID_MX5000_RECEIVER_MOUSE_DEV 0xc70a > #define USB_DEVICE_ID_MX5000_RECEIVER_KBD_DEV 0xc70e > +#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV 0xc713 > +#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV 0xc714 > #define USB_DEVICE_ID_MX5500_RECEIVER_KBD_DEV 0xc71b > #define USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV 0xc71c > +#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV 0xc71e > +#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV 0xc71f > #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 > #define USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL 0xca04 > > diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c > index 0dc7cdfc56f7..d40af911df63 100644 > --- a/drivers/hid/hid-lg.c > +++ b/drivers/hid/hid-lg.c > @@ -568,22 +568,6 @@ static int lg_ultrax_remote_mapping(struct hid_input *hi, > return 1; > } > > -static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage, > - unsigned long **bit, int *max) > -{ > - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) > - return 0; > - > - switch (usage->hid & HID_USAGE) { > - > - case 0x00d: lg_map_key_clear(KEY_MEDIA); break; > - default: > - return 0; > - > - } > - return 1; > -} > - I am not sure these changes on hid-logitech-hidpp.c are something you wanted to put in. Looks like the patch reverts the Dinovo Mini in 1/3. Cheers, Benjamin > static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, > unsigned long **bit, int *max) > { > @@ -668,10 +652,6 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, > lg_ultrax_remote_mapping(hi, usage, bit, max)) > return 1; > > - if (hdev->product == USB_DEVICE_ID_DINOVO_MINI && > - lg_dinovo_mapping(hi, usage, bit, max)) > - return 1; > - > if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) > return 1; > > @@ -879,10 +859,6 @@ static const struct hid_device_id lg_devices[] = { > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), > .driver_data = LG_DUPLICATE_USAGES }, > - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), > - .driver_data = LG_DUPLICATE_USAGES }, > - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), > - .driver_data = LG_DUPLICATE_USAGES }, > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), > .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, > diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c > index eaaedbb84a8d..e9e294b66e59 100644 > --- a/drivers/hid/hid-logitech-dj.c > +++ b/drivers/hid/hid-logitech-dj.c > @@ -84,6 +84,7 @@ > #define STD_MOUSE BIT(2) > #define MULTIMEDIA BIT(3) > #define POWER_KEYS BIT(4) > +#define KBD_MOUSE BIT(5) > #define MEDIA_CENTER BIT(8) > #define KBD_LEDS BIT(14) > /* Fake (bitnr > NUMBER_OF_HID_REPORTS) bit to track HID++ capability */ > @@ -118,6 +119,7 @@ enum recvr_type { > recvr_type_mouse_only, > recvr_type_27mhz, > recvr_type_bluetooth, > + recvr_type_dinovo, > }; > > struct dj_report { > @@ -334,6 +336,47 @@ static const char mse_bluetooth_descriptor[] = { > 0xC0, /* END_COLLECTION */ > }; > > +/* Mouse descriptor (5) for Bluetooth receiver, normal-res hwheel, 8 buttons */ > +static const char mse5_bluetooth_descriptor[] = { > + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ > + 0x09, 0x02, /* Usage (Mouse) */ > + 0xa1, 0x01, /* Collection (Application) */ > + 0x85, 0x05, /* Report ID (5) */ > + 0x09, 0x01, /* Usage (Pointer) */ > + 0xa1, 0x00, /* Collection (Physical) */ > + 0x05, 0x09, /* Usage Page (Button) */ > + 0x19, 0x01, /* Usage Minimum (1) */ > + 0x29, 0x08, /* Usage Maximum (8) */ > + 0x15, 0x00, /* Logical Minimum (0) */ > + 0x25, 0x01, /* Logical Maximum (1) */ > + 0x95, 0x08, /* Report Count (8) */ > + 0x75, 0x01, /* Report Size (1) */ > + 0x81, 0x02, /* Input (Data,Var,Abs) */ > + 0x05, 0x01, /* Usage Page (Generic Desktop) */ > + 0x16, 0x01, 0xf8, /* Logical Minimum (-2047) */ > + 0x26, 0xff, 0x07, /* Logical Maximum (2047) */ > + 0x75, 0x0c, /* Report Size (12) */ > + 0x95, 0x02, /* Report Count (2) */ > + 0x09, 0x30, /* Usage (X) */ > + 0x09, 0x31, /* Usage (Y) */ > + 0x81, 0x06, /* Input (Data,Var,Rel) */ > + 0x15, 0x81, /* Logical Minimum (-127) */ > + 0x25, 0x7f, /* Logical Maximum (127) */ > + 0x75, 0x08, /* Report Size (8) */ > + 0x95, 0x01, /* Report Count (1) */ > + 0x09, 0x38, /* Usage (Wheel) */ > + 0x81, 0x06, /* Input (Data,Var,Rel) */ > + 0x05, 0x0c, /* Usage Page (Consumer Devices) */ > + 0x0a, 0x38, 0x02, /* Usage (AC Pan) */ > + 0x15, 0x81, /* Logical Minimum (-127) */ > + 0x25, 0x7f, /* Logical Maximum (127) */ > + 0x75, 0x08, /* Report Size (8) */ > + 0x95, 0x01, /* Report Count (1) */ > + 0x81, 0x06, /* Input (Data,Var,Rel) */ > + 0xc0, /* End Collection */ > + 0xc0, /* End Collection */ > +}; > + > /* Gaming Mouse descriptor (2) */ > static const char mse_high_res_descriptor[] = { > 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ > @@ -481,6 +524,7 @@ static const char hidpp_descriptor[] = { > #define MAX_RDESC_SIZE \ > (sizeof(kbd_descriptor) + \ > sizeof(mse_bluetooth_descriptor) + \ > + sizeof(mse5_bluetooth_descriptor) + \ > sizeof(consumer_descriptor) + \ > sizeof(syscontrol_descriptor) + \ > sizeof(media_descriptor) + \ > @@ -518,6 +562,11 @@ static void delayedwork_callback(struct work_struct *work); > static LIST_HEAD(dj_hdev_list); > static DEFINE_MUTEX(dj_hdev_list_lock); > > +static bool recvr_type_is_bluetooth(enum recvr_type type) > +{ > + return type == recvr_type_bluetooth || type == recvr_type_dinovo; > +} > + > /* > * dj/HID++ receivers are really a single logical entity, but for BIOS/Windows > * compatibility they have multiple USB interfaces. On HID++ receivers we need > @@ -535,7 +584,7 @@ static struct dj_receiver_dev *dj_find_receiver_dev(struct hid_device *hdev, > * The bluetooth receiver contains a built-in hub and has separate > * USB-devices for the keyboard and mouse interfaces. > */ > - sep = (type == recvr_type_bluetooth) ? '.' : '/'; > + sep = recvr_type_is_bluetooth(type) ? '.' : '/'; > > /* Try to find an already-probed interface from the same device */ > list_for_each_entry(djrcv_dev, &dj_hdev_list, list) { > @@ -873,6 +922,14 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev, > * touchpad to work we must also forward mouse input reports to the dj_hiddev > * created for the keyboard (instead of forwarding them to a second paired > * device with a device_type of REPORT_TYPE_MOUSE as we normally would). > + * > + * On Dinovo receivers the keyboard's touchpad and an optional paired actual > + * mouse send separate input reports, INPUT(2) aka STD_MOUSE for the mouse > + * and INPUT(5) aka KBD_MOUSE for the keyboard's touchpad. > + * > + * On MX5x00 receivers (which can also be paired with a Dinovo keyboard) > + * INPUT(2) is used for both an optional paired actual mouse and for the > + * keyboard's touchpad. > */ > static const u16 kbd_builtin_touchpad_ids[] = { > 0xb309, /* Dinovo Edge */ > @@ -899,7 +956,10 @@ static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, > id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb; > for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) { > if (id == kbd_builtin_touchpad_ids[i]) { > - workitem->reports_supported |= STD_MOUSE; > + if (djrcv_dev->type == recvr_type_dinovo) > + workitem->reports_supported |= KBD_MOUSE; > + else > + workitem->reports_supported |= STD_MOUSE; > break; > } > } > @@ -1367,7 +1427,7 @@ static int logi_dj_ll_parse(struct hid_device *hid) > else if (djdev->dj_receiver_dev->type == recvr_type_27mhz) > rdcat(rdesc, &rsize, mse_27mhz_descriptor, > sizeof(mse_27mhz_descriptor)); > - else if (djdev->dj_receiver_dev->type == recvr_type_bluetooth) > + else if (recvr_type_is_bluetooth(djdev->dj_receiver_dev->type)) > rdcat(rdesc, &rsize, mse_bluetooth_descriptor, > sizeof(mse_bluetooth_descriptor)); > else > @@ -1375,6 +1435,13 @@ static int logi_dj_ll_parse(struct hid_device *hid) > sizeof(mse_descriptor)); > } > > + if (djdev->reports_supported & KBD_MOUSE) { > + dbg_hid("%s: sending a kbd-mouse descriptor, reports_supported: %llx\n", > + __func__, djdev->reports_supported); > + rdcat(rdesc, &rsize, mse5_bluetooth_descriptor, > + sizeof(mse5_bluetooth_descriptor)); > + } > + > if (djdev->reports_supported & MULTIMEDIA) { > dbg_hid("%s: sending a multimedia report descriptor: %llx\n", > __func__, djdev->reports_supported); > @@ -1692,6 +1759,7 @@ static int logi_dj_probe(struct hid_device *hdev, > 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; > + case recvr_type_dinovo: no_dj_interfaces = 2; break; > } > if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) { > intf = to_usb_interface(hdev->dev.parent); > @@ -1920,6 +1988,23 @@ static const struct hid_device_id logi_dj_receivers[] = { > HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV), > .driver_data = recvr_type_bluetooth}, > + > + { /* Logitech Dinovo Edge HID++ / bluetooth receiver keyboard intf. (0xc713) */ > + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > + USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV), > + .driver_data = recvr_type_dinovo}, > + { /* Logitech Dinovo Edge HID++ / bluetooth receiver mouse intf. (0xc714) */ > + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > + USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV), > + .driver_data = recvr_type_dinovo}, > + { /* Logitech DiNovo Mini HID++ / bluetooth receiver mouse intf. (0xc71e) */ > + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > + USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV), > + .driver_data = recvr_type_dinovo}, > + { /* Logitech DiNovo Mini HID++ / bluetooth receiver keyboard intf. (0xc71f) */ > + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > + USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV), > + .driver_data = recvr_type_dinovo}, > {} > }; > > diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c > index 7a2be0205dfd..8fce238f120d 100644 > --- a/drivers/hid/hid-quirks.c > +++ b/drivers/hid/hid-quirks.c > @@ -439,8 +439,6 @@ static const struct hid_device_id hid_have_special_driver[] = { > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, > - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, > - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, > -- > 2.28.0 >
Hi, On 11/16/20 9:30 AM, Benjamin Tissoires wrote: > Hi Hans, > > Not full review but... > > On Sat, Nov 14, 2020 at 10:21 PM Hans de Goede <hdegoede@redhat.com> wrote: >> >> The Dinovo Edge and Dinovo Mini keyboards with builtin touchpad come with >> a different version of the quad/bt2.0 combo receivers shipped with the >> MX5000 and MX5500 keyboards. These receivers are compatible with one >> another, e.g. the Dinovo Edge keyboard can be paired with the MX5000 >> receiver. >> >> Like the MX5x00 receivers in HID proxy mode these receivers present >> themselves as a hub with multiple USB-HID devices, one for the keyboard >> and one for the mouse. >> >> Where they differ is that the mouse USB-device has 2 input reports for >> reporting mice events. It has the exact same INPUT(2) report as the >> MX5x00 receivers, but it also has a second INPUT(5) mouse report which >> is different; and when the Dinovo receivers are paired with the Dinovo >> keyboards the second INPUT(5) mouse report is actually used for events >> on the builtin touchpad. >> >> Add support for handling the Dinovo quad/bluetooth-2.0 combo receivers >> in HID proxy mode to logitech-dj, like we already do for the similar >> MX5000 and MX5500 receivers. >> >> This adds battery monitoring functionality (through logitech-hidpp) and >> fixes the Phone (Fn + F1) and "[A]" - "[D]" (Fn + F9 - F12) hotkeys not >> working on the Dinovo Edge. >> >> Note these receivers present themselves as a hub with 2 separate USB >> devices for the keyboard and mouse; and the logitech-dj code needs to >> bind to both devices (just as with the MX5x00 receivers). >> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com> >> --- >> drivers/hid/hid-ids.h | 6 ++- >> drivers/hid/hid-lg.c | 24 --------- >> drivers/hid/hid-logitech-dj.c | 91 +++++++++++++++++++++++++++++++++-- >> drivers/hid/hid-quirks.c | 2 - >> 4 files changed, 92 insertions(+), 31 deletions(-) >> >> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h >> index 108081ab5ae3..e17f252ba60f 100644 >> --- a/drivers/hid/hid-ids.h >> +++ b/drivers/hid/hid-ids.h >> @@ -797,12 +797,14 @@ >> #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 >> #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 >> #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 >> -#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 >> -#define USB_DEVICE_ID_DINOVO_MINI 0xc71f >> #define USB_DEVICE_ID_MX5000_RECEIVER_MOUSE_DEV 0xc70a >> #define USB_DEVICE_ID_MX5000_RECEIVER_KBD_DEV 0xc70e >> +#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV 0xc713 >> +#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV 0xc714 >> #define USB_DEVICE_ID_MX5500_RECEIVER_KBD_DEV 0xc71b >> #define USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV 0xc71c >> +#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV 0xc71e >> +#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV 0xc71f >> #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 >> #define USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL 0xca04 >> >> diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c >> index 0dc7cdfc56f7..d40af911df63 100644 >> --- a/drivers/hid/hid-lg.c >> +++ b/drivers/hid/hid-lg.c >> @@ -568,22 +568,6 @@ static int lg_ultrax_remote_mapping(struct hid_input *hi, >> return 1; >> } >> >> -static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage, >> - unsigned long **bit, int *max) >> -{ >> - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) >> - return 0; >> - >> - switch (usage->hid & HID_USAGE) { >> - >> - case 0x00d: lg_map_key_clear(KEY_MEDIA); break; >> - default: >> - return 0; >> - >> - } >> - return 1; >> -} >> - > > I am not sure these changes on hid-logitech-hidpp.c This is not a change to hid-logitech-hidpp.c, it it a change to hid-lg.c, which after this patch will no longer handle the Dinovo Mini ever, since its USB-ID is dropped from its id-table. Also note that the above code was only run on an USB-ID match, so with the USB-ID dropped the hid-lg.c copy of this is dead code (also see below). > are something you > wanted to put in. Looks like the patch reverts the Dinovo Mini in 1/3. 1/3 actually duplicates this bit from hid-lg.c to hid-logitech-hidpp.c so that the Dinovo Mino Media key will work properly independent of it being paired with a receiver handled by hid-lg.c or hid-logitech-dj.c. This patch moves all receiver handling over to hid-logitech-dj.c, after which the Dinovo Mini handling in hid-lg.c is just dead code. I did things this way (with the temporary code duplication) so that 1/3 can go out as a fix for stable kernels while 2 + 3 are for 5.11. Regards, Hans >> static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, >> unsigned long **bit, int *max) >> { >> @@ -668,10 +652,6 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, >> lg_ultrax_remote_mapping(hi, usage, bit, max)) >> return 1; >> >> - if (hdev->product == USB_DEVICE_ID_DINOVO_MINI && >> - lg_dinovo_mapping(hi, usage, bit, max)) >> - return 1; >> - >> if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) >> return 1; >> >> @@ -879,10 +859,6 @@ static const struct hid_device_id lg_devices[] = { >> >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), >> .driver_data = LG_DUPLICATE_USAGES }, >> - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), >> - .driver_data = LG_DUPLICATE_USAGES }, >> - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), >> - .driver_data = LG_DUPLICATE_USAGES }, >> >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), >> .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, >> diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c >> index eaaedbb84a8d..e9e294b66e59 100644 >> --- a/drivers/hid/hid-logitech-dj.c >> +++ b/drivers/hid/hid-logitech-dj.c >> @@ -84,6 +84,7 @@ >> #define STD_MOUSE BIT(2) >> #define MULTIMEDIA BIT(3) >> #define POWER_KEYS BIT(4) >> +#define KBD_MOUSE BIT(5) >> #define MEDIA_CENTER BIT(8) >> #define KBD_LEDS BIT(14) >> /* Fake (bitnr > NUMBER_OF_HID_REPORTS) bit to track HID++ capability */ >> @@ -118,6 +119,7 @@ enum recvr_type { >> recvr_type_mouse_only, >> recvr_type_27mhz, >> recvr_type_bluetooth, >> + recvr_type_dinovo, >> }; >> >> struct dj_report { >> @@ -334,6 +336,47 @@ static const char mse_bluetooth_descriptor[] = { >> 0xC0, /* END_COLLECTION */ >> }; >> >> +/* Mouse descriptor (5) for Bluetooth receiver, normal-res hwheel, 8 buttons */ >> +static const char mse5_bluetooth_descriptor[] = { >> + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ >> + 0x09, 0x02, /* Usage (Mouse) */ >> + 0xa1, 0x01, /* Collection (Application) */ >> + 0x85, 0x05, /* Report ID (5) */ >> + 0x09, 0x01, /* Usage (Pointer) */ >> + 0xa1, 0x00, /* Collection (Physical) */ >> + 0x05, 0x09, /* Usage Page (Button) */ >> + 0x19, 0x01, /* Usage Minimum (1) */ >> + 0x29, 0x08, /* Usage Maximum (8) */ >> + 0x15, 0x00, /* Logical Minimum (0) */ >> + 0x25, 0x01, /* Logical Maximum (1) */ >> + 0x95, 0x08, /* Report Count (8) */ >> + 0x75, 0x01, /* Report Size (1) */ >> + 0x81, 0x02, /* Input (Data,Var,Abs) */ >> + 0x05, 0x01, /* Usage Page (Generic Desktop) */ >> + 0x16, 0x01, 0xf8, /* Logical Minimum (-2047) */ >> + 0x26, 0xff, 0x07, /* Logical Maximum (2047) */ >> + 0x75, 0x0c, /* Report Size (12) */ >> + 0x95, 0x02, /* Report Count (2) */ >> + 0x09, 0x30, /* Usage (X) */ >> + 0x09, 0x31, /* Usage (Y) */ >> + 0x81, 0x06, /* Input (Data,Var,Rel) */ >> + 0x15, 0x81, /* Logical Minimum (-127) */ >> + 0x25, 0x7f, /* Logical Maximum (127) */ >> + 0x75, 0x08, /* Report Size (8) */ >> + 0x95, 0x01, /* Report Count (1) */ >> + 0x09, 0x38, /* Usage (Wheel) */ >> + 0x81, 0x06, /* Input (Data,Var,Rel) */ >> + 0x05, 0x0c, /* Usage Page (Consumer Devices) */ >> + 0x0a, 0x38, 0x02, /* Usage (AC Pan) */ >> + 0x15, 0x81, /* Logical Minimum (-127) */ >> + 0x25, 0x7f, /* Logical Maximum (127) */ >> + 0x75, 0x08, /* Report Size (8) */ >> + 0x95, 0x01, /* Report Count (1) */ >> + 0x81, 0x06, /* Input (Data,Var,Rel) */ >> + 0xc0, /* End Collection */ >> + 0xc0, /* End Collection */ >> +}; >> + >> /* Gaming Mouse descriptor (2) */ >> static const char mse_high_res_descriptor[] = { >> 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ >> @@ -481,6 +524,7 @@ static const char hidpp_descriptor[] = { >> #define MAX_RDESC_SIZE \ >> (sizeof(kbd_descriptor) + \ >> sizeof(mse_bluetooth_descriptor) + \ >> + sizeof(mse5_bluetooth_descriptor) + \ >> sizeof(consumer_descriptor) + \ >> sizeof(syscontrol_descriptor) + \ >> sizeof(media_descriptor) + \ >> @@ -518,6 +562,11 @@ static void delayedwork_callback(struct work_struct *work); >> static LIST_HEAD(dj_hdev_list); >> static DEFINE_MUTEX(dj_hdev_list_lock); >> >> +static bool recvr_type_is_bluetooth(enum recvr_type type) >> +{ >> + return type == recvr_type_bluetooth || type == recvr_type_dinovo; >> +} >> + >> /* >> * dj/HID++ receivers are really a single logical entity, but for BIOS/Windows >> * compatibility they have multiple USB interfaces. On HID++ receivers we need >> @@ -535,7 +584,7 @@ static struct dj_receiver_dev *dj_find_receiver_dev(struct hid_device *hdev, >> * The bluetooth receiver contains a built-in hub and has separate >> * USB-devices for the keyboard and mouse interfaces. >> */ >> - sep = (type == recvr_type_bluetooth) ? '.' : '/'; >> + sep = recvr_type_is_bluetooth(type) ? '.' : '/'; >> >> /* Try to find an already-probed interface from the same device */ >> list_for_each_entry(djrcv_dev, &dj_hdev_list, list) { >> @@ -873,6 +922,14 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev, >> * touchpad to work we must also forward mouse input reports to the dj_hiddev >> * created for the keyboard (instead of forwarding them to a second paired >> * device with a device_type of REPORT_TYPE_MOUSE as we normally would). >> + * >> + * On Dinovo receivers the keyboard's touchpad and an optional paired actual >> + * mouse send separate input reports, INPUT(2) aka STD_MOUSE for the mouse >> + * and INPUT(5) aka KBD_MOUSE for the keyboard's touchpad. >> + * >> + * On MX5x00 receivers (which can also be paired with a Dinovo keyboard) >> + * INPUT(2) is used for both an optional paired actual mouse and for the >> + * keyboard's touchpad. >> */ >> static const u16 kbd_builtin_touchpad_ids[] = { >> 0xb309, /* Dinovo Edge */ >> @@ -899,7 +956,10 @@ static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, >> id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb; >> for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) { >> if (id == kbd_builtin_touchpad_ids[i]) { >> - workitem->reports_supported |= STD_MOUSE; >> + if (djrcv_dev->type == recvr_type_dinovo) >> + workitem->reports_supported |= KBD_MOUSE; >> + else >> + workitem->reports_supported |= STD_MOUSE; >> break; >> } >> } >> @@ -1367,7 +1427,7 @@ static int logi_dj_ll_parse(struct hid_device *hid) >> else if (djdev->dj_receiver_dev->type == recvr_type_27mhz) >> rdcat(rdesc, &rsize, mse_27mhz_descriptor, >> sizeof(mse_27mhz_descriptor)); >> - else if (djdev->dj_receiver_dev->type == recvr_type_bluetooth) >> + else if (recvr_type_is_bluetooth(djdev->dj_receiver_dev->type)) >> rdcat(rdesc, &rsize, mse_bluetooth_descriptor, >> sizeof(mse_bluetooth_descriptor)); >> else >> @@ -1375,6 +1435,13 @@ static int logi_dj_ll_parse(struct hid_device *hid) >> sizeof(mse_descriptor)); >> } >> >> + if (djdev->reports_supported & KBD_MOUSE) { >> + dbg_hid("%s: sending a kbd-mouse descriptor, reports_supported: %llx\n", >> + __func__, djdev->reports_supported); >> + rdcat(rdesc, &rsize, mse5_bluetooth_descriptor, >> + sizeof(mse5_bluetooth_descriptor)); >> + } >> + >> if (djdev->reports_supported & MULTIMEDIA) { >> dbg_hid("%s: sending a multimedia report descriptor: %llx\n", >> __func__, djdev->reports_supported); >> @@ -1692,6 +1759,7 @@ static int logi_dj_probe(struct hid_device *hdev, >> 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; >> + case recvr_type_dinovo: no_dj_interfaces = 2; break; >> } >> if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) { >> intf = to_usb_interface(hdev->dev.parent); >> @@ -1920,6 +1988,23 @@ static const struct hid_device_id logi_dj_receivers[] = { >> HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV), >> .driver_data = recvr_type_bluetooth}, >> + >> + { /* Logitech Dinovo Edge HID++ / bluetooth receiver keyboard intf. (0xc713) */ >> + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> + USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV), >> + .driver_data = recvr_type_dinovo}, >> + { /* Logitech Dinovo Edge HID++ / bluetooth receiver mouse intf. (0xc714) */ >> + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> + USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV), >> + .driver_data = recvr_type_dinovo}, >> + { /* Logitech DiNovo Mini HID++ / bluetooth receiver mouse intf. (0xc71e) */ >> + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> + USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV), >> + .driver_data = recvr_type_dinovo}, >> + { /* Logitech DiNovo Mini HID++ / bluetooth receiver keyboard intf. (0xc71f) */ >> + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> + USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV), >> + .driver_data = recvr_type_dinovo}, >> {} >> }; >> >> diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c >> index 7a2be0205dfd..8fce238f120d 100644 >> --- a/drivers/hid/hid-quirks.c >> +++ b/drivers/hid/hid-quirks.c >> @@ -439,8 +439,6 @@ static const struct hid_device_id hid_have_special_driver[] = { >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, >> - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, >> - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, >> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, >> -- >> 2.28.0 >> >
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 108081ab5ae3..e17f252ba60f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -797,12 +797,14 @@ #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 -#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 -#define USB_DEVICE_ID_DINOVO_MINI 0xc71f #define USB_DEVICE_ID_MX5000_RECEIVER_MOUSE_DEV 0xc70a #define USB_DEVICE_ID_MX5000_RECEIVER_KBD_DEV 0xc70e +#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV 0xc713 +#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV 0xc714 #define USB_DEVICE_ID_MX5500_RECEIVER_KBD_DEV 0xc71b #define USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV 0xc71c +#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV 0xc71e +#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV 0xc71f #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 #define USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL 0xca04 diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 0dc7cdfc56f7..d40af911df63 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -568,22 +568,6 @@ static int lg_ultrax_remote_mapping(struct hid_input *hi, return 1; } -static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) - return 0; - - switch (usage->hid & HID_USAGE) { - - case 0x00d: lg_map_key_clear(KEY_MEDIA); break; - default: - return 0; - - } - return 1; -} - static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, unsigned long **bit, int *max) { @@ -668,10 +652,6 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, lg_ultrax_remote_mapping(hi, usage, bit, max)) return 1; - if (hdev->product == USB_DEVICE_ID_DINOVO_MINI && - lg_dinovo_mapping(hi, usage, bit, max)) - return 1; - if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) return 1; @@ -879,10 +859,6 @@ static const struct hid_device_id lg_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), .driver_data = LG_DUPLICATE_USAGES }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), - .driver_data = LG_DUPLICATE_USAGES }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), - .driver_data = LG_DUPLICATE_USAGES }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index eaaedbb84a8d..e9e294b66e59 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -84,6 +84,7 @@ #define STD_MOUSE BIT(2) #define MULTIMEDIA BIT(3) #define POWER_KEYS BIT(4) +#define KBD_MOUSE BIT(5) #define MEDIA_CENTER BIT(8) #define KBD_LEDS BIT(14) /* Fake (bitnr > NUMBER_OF_HID_REPORTS) bit to track HID++ capability */ @@ -118,6 +119,7 @@ enum recvr_type { recvr_type_mouse_only, recvr_type_27mhz, recvr_type_bluetooth, + recvr_type_dinovo, }; struct dj_report { @@ -334,6 +336,47 @@ static const char mse_bluetooth_descriptor[] = { 0xC0, /* END_COLLECTION */ }; +/* Mouse descriptor (5) for Bluetooth receiver, normal-res hwheel, 8 buttons */ +static const char mse5_bluetooth_descriptor[] = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x02, /* Usage (Mouse) */ + 0xa1, 0x01, /* Collection (Application) */ + 0x85, 0x05, /* Report ID (5) */ + 0x09, 0x01, /* Usage (Pointer) */ + 0xa1, 0x00, /* Collection (Physical) */ + 0x05, 0x09, /* Usage Page (Button) */ + 0x19, 0x01, /* Usage Minimum (1) */ + 0x29, 0x08, /* Usage Maximum (8) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x95, 0x08, /* Report Count (8) */ + 0x75, 0x01, /* Report Size (1) */ + 0x81, 0x02, /* Input (Data,Var,Abs) */ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ + 0x16, 0x01, 0xf8, /* Logical Minimum (-2047) */ + 0x26, 0xff, 0x07, /* Logical Maximum (2047) */ + 0x75, 0x0c, /* Report Size (12) */ + 0x95, 0x02, /* Report Count (2) */ + 0x09, 0x30, /* Usage (X) */ + 0x09, 0x31, /* Usage (Y) */ + 0x81, 0x06, /* Input (Data,Var,Rel) */ + 0x15, 0x81, /* Logical Minimum (-127) */ + 0x25, 0x7f, /* Logical Maximum (127) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x01, /* Report Count (1) */ + 0x09, 0x38, /* Usage (Wheel) */ + 0x81, 0x06, /* Input (Data,Var,Rel) */ + 0x05, 0x0c, /* Usage Page (Consumer Devices) */ + 0x0a, 0x38, 0x02, /* Usage (AC Pan) */ + 0x15, 0x81, /* Logical Minimum (-127) */ + 0x25, 0x7f, /* Logical Maximum (127) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x01, /* Report Count (1) */ + 0x81, 0x06, /* Input (Data,Var,Rel) */ + 0xc0, /* End Collection */ + 0xc0, /* End Collection */ +}; + /* Gaming Mouse descriptor (2) */ static const char mse_high_res_descriptor[] = { 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ @@ -481,6 +524,7 @@ static const char hidpp_descriptor[] = { #define MAX_RDESC_SIZE \ (sizeof(kbd_descriptor) + \ sizeof(mse_bluetooth_descriptor) + \ + sizeof(mse5_bluetooth_descriptor) + \ sizeof(consumer_descriptor) + \ sizeof(syscontrol_descriptor) + \ sizeof(media_descriptor) + \ @@ -518,6 +562,11 @@ static void delayedwork_callback(struct work_struct *work); static LIST_HEAD(dj_hdev_list); static DEFINE_MUTEX(dj_hdev_list_lock); +static bool recvr_type_is_bluetooth(enum recvr_type type) +{ + return type == recvr_type_bluetooth || type == recvr_type_dinovo; +} + /* * dj/HID++ receivers are really a single logical entity, but for BIOS/Windows * compatibility they have multiple USB interfaces. On HID++ receivers we need @@ -535,7 +584,7 @@ static struct dj_receiver_dev *dj_find_receiver_dev(struct hid_device *hdev, * The bluetooth receiver contains a built-in hub and has separate * USB-devices for the keyboard and mouse interfaces. */ - sep = (type == recvr_type_bluetooth) ? '.' : '/'; + sep = recvr_type_is_bluetooth(type) ? '.' : '/'; /* Try to find an already-probed interface from the same device */ list_for_each_entry(djrcv_dev, &dj_hdev_list, list) { @@ -873,6 +922,14 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev, * touchpad to work we must also forward mouse input reports to the dj_hiddev * created for the keyboard (instead of forwarding them to a second paired * device with a device_type of REPORT_TYPE_MOUSE as we normally would). + * + * On Dinovo receivers the keyboard's touchpad and an optional paired actual + * mouse send separate input reports, INPUT(2) aka STD_MOUSE for the mouse + * and INPUT(5) aka KBD_MOUSE for the keyboard's touchpad. + * + * On MX5x00 receivers (which can also be paired with a Dinovo keyboard) + * INPUT(2) is used for both an optional paired actual mouse and for the + * keyboard's touchpad. */ static const u16 kbd_builtin_touchpad_ids[] = { 0xb309, /* Dinovo Edge */ @@ -899,7 +956,10 @@ static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb; for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) { if (id == kbd_builtin_touchpad_ids[i]) { - workitem->reports_supported |= STD_MOUSE; + if (djrcv_dev->type == recvr_type_dinovo) + workitem->reports_supported |= KBD_MOUSE; + else + workitem->reports_supported |= STD_MOUSE; break; } } @@ -1367,7 +1427,7 @@ static int logi_dj_ll_parse(struct hid_device *hid) else if (djdev->dj_receiver_dev->type == recvr_type_27mhz) rdcat(rdesc, &rsize, mse_27mhz_descriptor, sizeof(mse_27mhz_descriptor)); - else if (djdev->dj_receiver_dev->type == recvr_type_bluetooth) + else if (recvr_type_is_bluetooth(djdev->dj_receiver_dev->type)) rdcat(rdesc, &rsize, mse_bluetooth_descriptor, sizeof(mse_bluetooth_descriptor)); else @@ -1375,6 +1435,13 @@ static int logi_dj_ll_parse(struct hid_device *hid) sizeof(mse_descriptor)); } + if (djdev->reports_supported & KBD_MOUSE) { + dbg_hid("%s: sending a kbd-mouse descriptor, reports_supported: %llx\n", + __func__, djdev->reports_supported); + rdcat(rdesc, &rsize, mse5_bluetooth_descriptor, + sizeof(mse5_bluetooth_descriptor)); + } + if (djdev->reports_supported & MULTIMEDIA) { dbg_hid("%s: sending a multimedia report descriptor: %llx\n", __func__, djdev->reports_supported); @@ -1692,6 +1759,7 @@ static int logi_dj_probe(struct hid_device *hdev, 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; + case recvr_type_dinovo: no_dj_interfaces = 2; break; } if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) { intf = to_usb_interface(hdev->dev.parent); @@ -1920,6 +1988,23 @@ static const struct hid_device_id logi_dj_receivers[] = { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV), .driver_data = recvr_type_bluetooth}, + + { /* Logitech Dinovo Edge HID++ / bluetooth receiver keyboard intf. (0xc713) */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV), + .driver_data = recvr_type_dinovo}, + { /* Logitech Dinovo Edge HID++ / bluetooth receiver mouse intf. (0xc714) */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV), + .driver_data = recvr_type_dinovo}, + { /* Logitech DiNovo Mini HID++ / bluetooth receiver mouse intf. (0xc71e) */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV), + .driver_data = recvr_type_dinovo}, + { /* Logitech DiNovo Mini HID++ / bluetooth receiver keyboard intf. (0xc71f) */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV), + .driver_data = recvr_type_dinovo}, {} }; diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 7a2be0205dfd..8fce238f120d 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -439,8 +439,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
The Dinovo Edge and Dinovo Mini keyboards with builtin touchpad come with a different version of the quad/bt2.0 combo receivers shipped with the MX5000 and MX5500 keyboards. These receivers are compatible with one another, e.g. the Dinovo Edge keyboard can be paired with the MX5000 receiver. Like the MX5x00 receivers in HID proxy mode these receivers present themselves as a hub with multiple USB-HID devices, one for the keyboard and one for the mouse. Where they differ is that the mouse USB-device has 2 input reports for reporting mice events. It has the exact same INPUT(2) report as the MX5x00 receivers, but it also has a second INPUT(5) mouse report which is different; and when the Dinovo receivers are paired with the Dinovo keyboards the second INPUT(5) mouse report is actually used for events on the builtin touchpad. Add support for handling the Dinovo quad/bluetooth-2.0 combo receivers in HID proxy mode to logitech-dj, like we already do for the similar MX5000 and MX5500 receivers. This adds battery monitoring functionality (through logitech-hidpp) and fixes the Phone (Fn + F1) and "[A]" - "[D]" (Fn + F9 - F12) hotkeys not working on the Dinovo Edge. Note these receivers present themselves as a hub with 2 separate USB devices for the keyboard and mouse; and the logitech-dj code needs to bind to both devices (just as with the MX5x00 receivers). Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/hid/hid-ids.h | 6 ++- drivers/hid/hid-lg.c | 24 --------- drivers/hid/hid-logitech-dj.c | 91 +++++++++++++++++++++++++++++++++-- drivers/hid/hid-quirks.c | 2 - 4 files changed, 92 insertions(+), 31 deletions(-)