recvr_type_dj,
recvr_type_hidpp,
recvr_type_gaming_hidpp,
+ recvr_type_gaming_hidpp_ls_1_3,
recvr_type_mouse_only,
recvr_type_27mhz,
recvr_type_bluetooth,
0xC0
};
+/* Gaming Keyboard descriptor (1) */
+static const char kbd_lightspeed_1_3_descriptor[] = {
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x06, /* Usage (Keyboard) */
+ 0xA1, 0x01, /* Collection (Application) */
+ 0x85, 0x01, /* Report ID (1) */
+ 0x05, 0x07, /* Usage Page (Kbrd/Keypad) */
+ 0x19, 0xE0, /* Usage Minimum (0xE0) */
+ 0x29, 0xE7, /* Usage Maximum (0xE7) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x01, /* Logical Maximum (1) */
+ 0x75, 0x01, /* Report Size (1) */
+ 0x95, 0x08, /* Report Count (8) */
+ 0x81, 0x02, /* Input (Data,Var) */
+ 0x95, 0x70, /* Report Count (112) */
+ 0x19, 0x04, /* Usage Minimum (0x04) */
+ 0x29, 0x73, /* Usage Maximum (0x73) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x95, 0x05, /* Report Count (5) */
+ 0x19, 0x87, /* Usage Minimum (0x87) */
+ 0x29, 0x8B, /* Usage Maximum (0x8B) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x95, 0x03, /* Report Count (3) */
+ 0x19, 0x90, /* Usage Minimum (0x90) */
+ 0x29, 0x92, /* Usage Maximum (0x92) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x95, 0x05, /* Report Count (5) */
+ 0x85, 0x0E, /* Report ID (14) */
+ 0x05, 0x08, /* Usage Page (LEDs) */
+ 0x19, 0x01, /* Usage Minimum (Num Lock) */
+ 0x29, 0x05, /* Usage Maximum (Kana) */
+ 0x91, 0x02, /* Output (Data,Var,Abs) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x75, 0x03, /* Report Size (3) */
+ 0x91, 0x03, /* Output (Const,Var,Abs) */
+ 0xC0, /* End Collection */
+};
+
/* Mouse descriptor (2) */
static const char mse_descriptor[] = {
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0xC0, /* END_COLLECTION */
};
+/* Gaming Mouse descriptor with vendor data (2) */
+static const char mse_high_res_ls_1_3_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) */
+ 0x95, 0x10, /* Report Count (16) */
+ 0x75, 0x01, /* Report Size (1) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x01, /* Logical Maximum (1) */
+ 0x05, 0x09, /* Usage Page (Button) */
+ 0x19, 0x01, /* Usage Minimum (0x01) */
+ 0x29, 0x10, /* Usage Maximum (0x10) */
+ 0x81, 0x02, /* Input (Data,Var,Abs) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x75, 0x10, /* Report Size (16) */
+ 0x16, 0x01, 0x80, /* Logical Minimum (-32767) */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767) */
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x81, 0x06, /* Input (Data,Var,Rel) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x15, 0x81, /* Logical Minimum (-127) */
+ 0x25, 0x7F, /* Logical Maximum (127) */
+ 0x09, 0x38, /* Usage (Wheel) */
+ 0x81, 0x06, /* Input (Data,Var,Rel) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x05, 0x0C, /* Usage Page (Consumer) */
+ 0x0A, 0x38, 0x02, /* Usage (AC Pan) */
+ 0x81, 0x06, /* Input (Data,Var,Rel) */
+ 0xC0, /* End Collection */
+ 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */
+ 0x09, 0xF1, /* Usage (0xF1) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x05, /* Report Count (5) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
+ 0x81, 0x00, /* Input (Data,Array,Abs) */
+ 0xC0, /* End Collection */
+};
+
/* Consumer Control descriptor (3) */
static const char consumer_descriptor[] = {
0x05, 0x0C, /* USAGE_PAGE (Consumer Devices) */
/* Maximum size of all defined hid reports in bytes (including report id) */
#define MAX_REPORT_SIZE 8
-/* Make sure all descriptors are present here */
+/* Make sure the largest of each descriptor type is present here */
#define MAX_RDESC_SIZE \
- (sizeof(kbd_descriptor) + \
+ (sizeof(kbd_lightspeed_1_3_descriptor) +\
sizeof(mse_bluetooth_descriptor) + \
sizeof(mse5_bluetooth_descriptor) + \
sizeof(consumer_descriptor) + \
return -EINVAL;
if (djrcv_dev->type != recvr_type_dj && count >= 2) {
+ unsigned char led_report_id = 0;
+
if (!djrcv_dev->keyboard) {
hid_warn(hid, "Received REPORT_TYPE_LEDS request before the keyboard interface was enumerated\n");
return 0;
}
+
+ /* This Lightspeed receiver expects LED reports with report ID 1 */
+ if (djrcv_dev->type == recvr_type_gaming_hidpp_ls_1_3)
+ led_report_id = 1;
+
/* usbhid overrides the report ID and ignores the first byte */
- return hid_hw_raw_request(djrcv_dev->keyboard, 0, buf, count,
+ return hid_hw_raw_request(djrcv_dev->keyboard, led_report_id, buf, count,
report_type, reqtype);
}
if (djdev->reports_supported & STD_KEYBOARD) {
dbg_hid("%s: sending a kbd descriptor, reports_supported: %llx\n",
__func__, djdev->reports_supported);
- rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
+ if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp_ls_1_3)
+ rdcat(rdesc, &rsize, kbd_lightspeed_1_3_descriptor,
+ sizeof(kbd_lightspeed_1_3_descriptor));
+ else
+ rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
}
if (djdev->reports_supported & STD_MOUSE) {
djdev->dj_receiver_dev->type == recvr_type_mouse_only)
rdcat(rdesc, &rsize, mse_high_res_descriptor,
sizeof(mse_high_res_descriptor));
+ else if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp_ls_1_3)
+ rdcat(rdesc, &rsize, mse_high_res_ls_1_3_descriptor,
+ sizeof(mse_high_res_ls_1_3_descriptor));
else if (djdev->dj_receiver_dev->type == recvr_type_27mhz)
rdcat(rdesc, &rsize, mse_27mhz_descriptor,
sizeof(mse_27mhz_descriptor));
}
/*
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
- * receiver uses 6 byte packets, the nano receiver 8 bytes.
+ * receiver uses 6 byte packets, the nano receiver 8 bytes,
+ * the lightspeed receiver (Pro X Superlight) 13 bytes.
*/
if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
- size <= 8) {
- u8 mouse_report[9];
+ size <= 13){
+ u8 mouse_report[14];
/* Prepend report id */
mouse_report[0] = REPORT_TYPE_MOUSE;
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_ls_1_3: 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;
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
.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_3),
+ .driver_data = recvr_type_gaming_hidpp_ls_1_3},
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),