diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2019-04-20 13:21:55 +0200 |
---|---|---|
committer | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2019-04-23 18:01:26 +0200 |
commit | f5fb57a74e88bd1788f57bf77d587c91d4dc9d57 (patch) | |
tree | 9e3b6f7e451ffa8a08f5c8c9f98f5b9937b10620 /drivers/hid | |
parent | 74808f9115cee2bb53e7161432959f3e87b631e4 (diff) | |
download | linux-f5fb57a74e88bd1788f57bf77d587c91d4dc9d57.tar.bz2 |
HID: logitech-dj: add support for the gaming unifying receiver
This receiver is almost identical to the normal unifying ones except:
- it is supposed to be paired to only one device (for performance reasons)
- the mice reports have a greater ranges in their values, so they are
using a different report ID.
Tested on a G403 and a G900.
Co-authored-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-ids.h | 1 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-dj.c | 58 |
2 files changed, 58 insertions, 1 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f24ed89920df..bd2dcd757484 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -766,6 +766,7 @@ #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER 0xc52f #define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 0xc532 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534 +#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_GAMING 0xc539 #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index d880ce641345..9ece9aca40a0 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -119,6 +119,7 @@ enum recvr_type { recvr_type_dj, recvr_type_hidpp, + recvr_type_gaming_hidpp, }; struct dj_report { @@ -247,6 +248,44 @@ static const char mse_descriptor[] = { 0xC0, /* END_COLLECTION */ }; +/* Gaming Mouse descriptor (2) */ +static const char mse_high_res_descriptor[] = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x02, /* USAGE (Mouse) */ + 0xA1, 0x01, /* COLLECTION (Application) */ + 0x85, 0x02, /* REPORT_ID = 2 */ + 0x09, 0x01, /* USAGE (pointer) */ + 0xA1, 0x00, /* COLLECTION (physical) */ + 0x05, 0x09, /* USAGE_PAGE (buttons) */ + 0x19, 0x01, /* USAGE_MIN (1) */ + 0x29, 0x10, /* USAGE_MAX (16) */ + 0x15, 0x00, /* LOGICAL_MIN (0) */ + 0x25, 0x01, /* LOGICAL_MAX (1) */ + 0x95, 0x10, /* REPORT_COUNT (16) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (data var abs) */ + 0x05, 0x01, /* USAGE_PAGE (generic desktop) */ + 0x16, 0x01, 0x80, /* LOGICAL_MIN (-32767) */ + 0x26, 0xFF, 0x7F, /* LOGICAL_MAX (32767) */ + 0x75, 0x10, /* REPORT_SIZE (16) */ + 0x95, 0x02, /* REPORT_COUNT (2) */ + 0x09, 0x30, /* USAGE (X) */ + 0x09, 0x31, /* USAGE (Y) */ + 0x81, 0x06, /* INPUT */ + 0x15, 0x81, /* LOGICAL_MIN (-127) */ + 0x25, 0x7F, /* LOGICAL_MAX (127) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x09, 0x38, /* USAGE (wheel) */ + 0x81, 0x06, /* INPUT */ + 0x05, 0x0C, /* USAGE_PAGE(consumer) */ + 0x0A, 0x38, 0x02, /* USAGE(AC Pan) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x81, 0x06, /* INPUT */ + 0xC0, /* END_COLLECTION */ + 0xC0, /* END_COLLECTION */ +}; + /* Consumer Control descriptor (3) */ static const char consumer_descriptor[] = { 0x05, 0x0C, /* USAGE_PAGE (Consumer Devices) */ @@ -788,6 +827,8 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev, break; case 0x0c: device_type = "eQUAD Lightspeed"; + logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem); + workitem.reports_supported |= STD_KEYBOARD; break; } @@ -1142,7 +1183,12 @@ static int logi_dj_ll_parse(struct hid_device *hid) if (djdev->reports_supported & STD_MOUSE) { dbg_hid("%s: sending a mouse descriptor, reports_supported: " "%x\n", __func__, djdev->reports_supported); - rdcat(rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor)); + if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp) + rdcat(rdesc, &rsize, mse_high_res_descriptor, + sizeof(mse_high_res_descriptor)); + else + rdcat(rdesc, &rsize, mse_descriptor, + sizeof(mse_descriptor)); } if (djdev->reports_supported & MULTIMEDIA) { @@ -1360,6 +1406,12 @@ static int logi_dj_raw_event(struct hid_device *hdev, return false; } return logi_dj_dj_event(hdev, report, data, size); + case REPORT_ID_DJ_LONG: + if (size != DJREPORT_LONG_LENGTH) { + dev_err(&hdev->dev, "DJ report of bad size (%d)", size); + return false; + } + return logi_dj_dj_event(hdev, report, data, size); case REPORT_ID_HIDPP_SHORT: if (size != HIDPP_REPORT_SHORT_LENGTH) { dev_err(&hdev->dev, @@ -1572,6 +1624,10 @@ static const struct hid_device_id logi_dj_receivers[] = { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2), .driver_data = recvr_type_hidpp}, + { /* Logitech gaming receiver (0xc539) */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_GAMING), + .driver_data = recvr_type_gaming_hidpp}, {} }; |