2055 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * HID driver for Logitech receivers4 *5 * Copyright (c) 2011 Logitech6 */7 8 9 10#include <linux/device.h>11#include <linux/hid.h>12#include <linux/module.h>13#include <linux/kfifo.h>14#include <linux/delay.h>15#include <linux/usb.h> /* For to_usb_interface for kvm extra intf check */16#include <linux/unaligned.h>17#include "hid-ids.h"18 19#define DJ_MAX_PAIRED_DEVICES 720#define DJ_MAX_NUMBER_NOTIFS 821#define DJ_RECEIVER_INDEX 022#define DJ_DEVICE_INDEX_MIN 123#define DJ_DEVICE_INDEX_MAX 724 25#define DJREPORT_SHORT_LENGTH 1526#define DJREPORT_LONG_LENGTH 3227 28#define REPORT_ID_DJ_SHORT 0x2029#define REPORT_ID_DJ_LONG 0x2130 31#define REPORT_ID_HIDPP_SHORT 0x1032#define REPORT_ID_HIDPP_LONG 0x1133#define REPORT_ID_HIDPP_VERY_LONG 0x1234 35#define HIDPP_REPORT_SHORT_LENGTH 736#define HIDPP_REPORT_LONG_LENGTH 2037 38#define HIDPP_RECEIVER_INDEX 0xff39 40#define REPORT_TYPE_RFREPORT_FIRST 0x0141#define REPORT_TYPE_RFREPORT_LAST 0x1F42 43/* Command Switch to DJ mode */44#define REPORT_TYPE_CMD_SWITCH 0x8045#define CMD_SWITCH_PARAM_DEVBITFIELD 0x0046#define CMD_SWITCH_PARAM_TIMEOUT_SECONDS 0x0147#define TIMEOUT_NO_KEEPALIVE 0x0048 49/* Command to Get the list of Paired devices */50#define REPORT_TYPE_CMD_GET_PAIRED_DEVICES 0x8151 52/* Device Paired Notification */53#define REPORT_TYPE_NOTIF_DEVICE_PAIRED 0x4154#define SPFUNCTION_MORE_NOTIF_EXPECTED 0x0155#define SPFUNCTION_DEVICE_LIST_EMPTY 0x0256#define DEVICE_PAIRED_PARAM_SPFUNCTION 0x0057#define DEVICE_PAIRED_PARAM_EQUAD_ID_LSB 0x0158#define DEVICE_PAIRED_PARAM_EQUAD_ID_MSB 0x0259#define DEVICE_PAIRED_RF_REPORT_TYPE 0x0360 61/* Device Un-Paired Notification */62#define REPORT_TYPE_NOTIF_DEVICE_UNPAIRED 0x4063 64/* Connection Status Notification */65#define REPORT_TYPE_NOTIF_CONNECTION_STATUS 0x4266#define CONNECTION_STATUS_PARAM_STATUS 0x0067#define STATUS_LINKLOSS 0x0168 69/* Error Notification */70#define REPORT_TYPE_NOTIF_ERROR 0x7F71#define NOTIF_ERROR_PARAM_ETYPE 0x0072#define ETYPE_KEEPALIVE_TIMEOUT 0x0173 74/* supported DJ HID && RF report types */75#define REPORT_TYPE_KEYBOARD 0x0176#define REPORT_TYPE_MOUSE 0x0277#define REPORT_TYPE_CONSUMER_CONTROL 0x0378#define REPORT_TYPE_SYSTEM_CONTROL 0x0479#define REPORT_TYPE_MEDIA_CENTER 0x0880#define REPORT_TYPE_LEDS 0x0E81 82/* RF Report types bitfield */83#define STD_KEYBOARD BIT(1)84#define STD_MOUSE BIT(2)85#define MULTIMEDIA BIT(3)86#define POWER_KEYS BIT(4)87#define KBD_MOUSE BIT(5)88#define MEDIA_CENTER BIT(8)89#define KBD_LEDS BIT(14)90/* Fake (bitnr > NUMBER_OF_HID_REPORTS) bit to track HID++ capability */91#define HIDPP BIT_ULL(63)92 93/* HID++ Device Connected Notification */94#define REPORT_TYPE_NOTIF_DEVICE_CONNECTED 0x4195#define HIDPP_PARAM_PROTO_TYPE 0x0096#define HIDPP_PARAM_DEVICE_INFO 0x0197#define HIDPP_PARAM_EQUAD_LSB 0x0298#define HIDPP_PARAM_EQUAD_MSB 0x0399#define HIDPP_PARAM_27MHZ_DEVID 0x03100#define HIDPP_DEVICE_TYPE_MASK GENMASK(3, 0)101#define HIDPP_LINK_STATUS_MASK BIT(6)102#define HIDPP_MANUFACTURER_MASK BIT(7)103#define HIDPP_27MHZ_SECURE_MASK BIT(7)104 105#define HIDPP_DEVICE_TYPE_KEYBOARD 1106#define HIDPP_DEVICE_TYPE_MOUSE 2107 108#define HIDPP_SET_REGISTER 0x80109#define HIDPP_GET_LONG_REGISTER 0x83110#define HIDPP_REG_CONNECTION_STATE 0x02111#define HIDPP_REG_PAIRING_INFORMATION 0xB5112#define HIDPP_PAIRING_INFORMATION 0x20113#define HIDPP_FAKE_DEVICE_ARRIVAL 0x02114 115enum recvr_type {116 recvr_type_dj,117 recvr_type_hidpp,118 recvr_type_gaming_hidpp,119 recvr_type_mouse_only,120 recvr_type_27mhz,121 recvr_type_bluetooth,122 recvr_type_dinovo,123};124 125struct dj_report {126 u8 report_id;127 u8 device_index;128 u8 report_type;129 u8 report_params[DJREPORT_SHORT_LENGTH - 3];130};131 132struct hidpp_event {133 u8 report_id;134 u8 device_index;135 u8 sub_id;136 u8 params[HIDPP_REPORT_LONG_LENGTH - 3U];137} __packed;138 139struct dj_receiver_dev {140 struct hid_device *mouse;141 struct hid_device *keyboard;142 struct hid_device *hidpp;143 struct dj_device *paired_dj_devices[DJ_MAX_PAIRED_DEVICES +144 DJ_DEVICE_INDEX_MIN];145 struct list_head list;146 struct kref kref;147 struct work_struct work;148 struct kfifo notif_fifo;149 unsigned long last_query; /* in jiffies */150 bool ready;151 enum recvr_type type;152 unsigned int unnumbered_application;153 spinlock_t lock;154};155 156struct dj_device {157 struct hid_device *hdev;158 struct dj_receiver_dev *dj_receiver_dev;159 u64 reports_supported;160 u8 device_index;161};162 163#define WORKITEM_TYPE_EMPTY 0164#define WORKITEM_TYPE_PAIRED 1165#define WORKITEM_TYPE_UNPAIRED 2166#define WORKITEM_TYPE_UNKNOWN 255167 168struct dj_workitem {169 u8 type; /* WORKITEM_TYPE_* */170 u8 device_index;171 u8 device_type;172 u8 quad_id_msb;173 u8 quad_id_lsb;174 u64 reports_supported;175};176 177/* Keyboard descriptor (1) */178static const char kbd_descriptor[] = {179 0x05, 0x01, /* USAGE_PAGE (generic Desktop) */180 0x09, 0x06, /* USAGE (Keyboard) */181 0xA1, 0x01, /* COLLECTION (Application) */182 0x85, 0x01, /* REPORT_ID (1) */183 0x95, 0x08, /* REPORT_COUNT (8) */184 0x75, 0x01, /* REPORT_SIZE (1) */185 0x15, 0x00, /* LOGICAL_MINIMUM (0) */186 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */187 0x05, 0x07, /* USAGE_PAGE (Keyboard) */188 0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */189 0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */190 0x81, 0x02, /* INPUT (Data,Var,Abs) */191 0x95, 0x06, /* REPORT_COUNT (6) */192 0x75, 0x08, /* REPORT_SIZE (8) */193 0x15, 0x00, /* LOGICAL_MINIMUM (0) */194 0x26, 0xFF, 0x00, /* LOGICAL_MAXIMUM (255) */195 0x05, 0x07, /* USAGE_PAGE (Keyboard) */196 0x19, 0x00, /* USAGE_MINIMUM (no event) */197 0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */198 0x81, 0x00, /* INPUT (Data,Ary,Abs) */199 0x85, 0x0e, /* REPORT_ID (14) */200 0x05, 0x08, /* USAGE PAGE (LED page) */201 0x95, 0x05, /* REPORT COUNT (5) */202 0x75, 0x01, /* REPORT SIZE (1) */203 0x15, 0x00, /* LOGICAL_MINIMUM (0) */204 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */205 0x19, 0x01, /* USAGE MINIMUM (1) */206 0x29, 0x05, /* USAGE MAXIMUM (5) */207 0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */208 0x95, 0x01, /* REPORT COUNT (1) */209 0x75, 0x03, /* REPORT SIZE (3) */210 0x91, 0x01, /* OUTPUT (Constant) */211 0xC0212};213 214/* Mouse descriptor (2) */215static const char mse_descriptor[] = {216 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */217 0x09, 0x02, /* USAGE (Mouse) */218 0xA1, 0x01, /* COLLECTION (Application) */219 0x85, 0x02, /* REPORT_ID = 2 */220 0x09, 0x01, /* USAGE (pointer) */221 0xA1, 0x00, /* COLLECTION (physical) */222 0x05, 0x09, /* USAGE_PAGE (buttons) */223 0x19, 0x01, /* USAGE_MIN (1) */224 0x29, 0x10, /* USAGE_MAX (16) */225 0x15, 0x00, /* LOGICAL_MIN (0) */226 0x25, 0x01, /* LOGICAL_MAX (1) */227 0x95, 0x10, /* REPORT_COUNT (16) */228 0x75, 0x01, /* REPORT_SIZE (1) */229 0x81, 0x02, /* INPUT (data var abs) */230 0x05, 0x01, /* USAGE_PAGE (generic desktop) */231 0x16, 0x01, 0xF8, /* LOGICAL_MIN (-2047) */232 0x26, 0xFF, 0x07, /* LOGICAL_MAX (2047) */233 0x75, 0x0C, /* REPORT_SIZE (12) */234 0x95, 0x02, /* REPORT_COUNT (2) */235 0x09, 0x30, /* USAGE (X) */236 0x09, 0x31, /* USAGE (Y) */237 0x81, 0x06, /* INPUT */238 0x15, 0x81, /* LOGICAL_MIN (-127) */239 0x25, 0x7F, /* LOGICAL_MAX (127) */240 0x75, 0x08, /* REPORT_SIZE (8) */241 0x95, 0x01, /* REPORT_COUNT (1) */242 0x09, 0x38, /* USAGE (wheel) */243 0x81, 0x06, /* INPUT */244 0x05, 0x0C, /* USAGE_PAGE(consumer) */245 0x0A, 0x38, 0x02, /* USAGE(AC Pan) */246 0x95, 0x01, /* REPORT_COUNT (1) */247 0x81, 0x06, /* INPUT */248 0xC0, /* END_COLLECTION */249 0xC0, /* END_COLLECTION */250};251 252/* Mouse descriptor (2) for 27 MHz receiver, only 8 buttons */253static const char mse_27mhz_descriptor[] = {254 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */255 0x09, 0x02, /* USAGE (Mouse) */256 0xA1, 0x01, /* COLLECTION (Application) */257 0x85, 0x02, /* REPORT_ID = 2 */258 0x09, 0x01, /* USAGE (pointer) */259 0xA1, 0x00, /* COLLECTION (physical) */260 0x05, 0x09, /* USAGE_PAGE (buttons) */261 0x19, 0x01, /* USAGE_MIN (1) */262 0x29, 0x08, /* USAGE_MAX (8) */263 0x15, 0x00, /* LOGICAL_MIN (0) */264 0x25, 0x01, /* LOGICAL_MAX (1) */265 0x95, 0x08, /* REPORT_COUNT (8) */266 0x75, 0x01, /* REPORT_SIZE (1) */267 0x81, 0x02, /* INPUT (data var abs) */268 0x05, 0x01, /* USAGE_PAGE (generic desktop) */269 0x16, 0x01, 0xF8, /* LOGICAL_MIN (-2047) */270 0x26, 0xFF, 0x07, /* LOGICAL_MAX (2047) */271 0x75, 0x0C, /* REPORT_SIZE (12) */272 0x95, 0x02, /* REPORT_COUNT (2) */273 0x09, 0x30, /* USAGE (X) */274 0x09, 0x31, /* USAGE (Y) */275 0x81, 0x06, /* INPUT */276 0x15, 0x81, /* LOGICAL_MIN (-127) */277 0x25, 0x7F, /* LOGICAL_MAX (127) */278 0x75, 0x08, /* REPORT_SIZE (8) */279 0x95, 0x01, /* REPORT_COUNT (1) */280 0x09, 0x38, /* USAGE (wheel) */281 0x81, 0x06, /* INPUT */282 0x05, 0x0C, /* USAGE_PAGE(consumer) */283 0x0A, 0x38, 0x02, /* USAGE(AC Pan) */284 0x95, 0x01, /* REPORT_COUNT (1) */285 0x81, 0x06, /* INPUT */286 0xC0, /* END_COLLECTION */287 0xC0, /* END_COLLECTION */288};289 290/* Mouse descriptor (2) for Bluetooth receiver, low-res hwheel, 12 buttons */291static const char mse_bluetooth_descriptor[] = {292 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */293 0x09, 0x02, /* USAGE (Mouse) */294 0xA1, 0x01, /* COLLECTION (Application) */295 0x85, 0x02, /* REPORT_ID = 2 */296 0x09, 0x01, /* USAGE (pointer) */297 0xA1, 0x00, /* COLLECTION (physical) */298 0x05, 0x09, /* USAGE_PAGE (buttons) */299 0x19, 0x01, /* USAGE_MIN (1) */300 0x29, 0x08, /* USAGE_MAX (8) */301 0x15, 0x00, /* LOGICAL_MIN (0) */302 0x25, 0x01, /* LOGICAL_MAX (1) */303 0x95, 0x08, /* REPORT_COUNT (8) */304 0x75, 0x01, /* REPORT_SIZE (1) */305 0x81, 0x02, /* INPUT (data var abs) */306 0x05, 0x01, /* USAGE_PAGE (generic desktop) */307 0x16, 0x01, 0xF8, /* LOGICAL_MIN (-2047) */308 0x26, 0xFF, 0x07, /* LOGICAL_MAX (2047) */309 0x75, 0x0C, /* REPORT_SIZE (12) */310 0x95, 0x02, /* REPORT_COUNT (2) */311 0x09, 0x30, /* USAGE (X) */312 0x09, 0x31, /* USAGE (Y) */313 0x81, 0x06, /* INPUT */314 0x15, 0x81, /* LOGICAL_MIN (-127) */315 0x25, 0x7F, /* LOGICAL_MAX (127) */316 0x75, 0x08, /* REPORT_SIZE (8) */317 0x95, 0x01, /* REPORT_COUNT (1) */318 0x09, 0x38, /* USAGE (wheel) */319 0x81, 0x06, /* INPUT */320 0x05, 0x0C, /* USAGE_PAGE(consumer) */321 0x0A, 0x38, 0x02, /* USAGE(AC Pan) */322 0x15, 0xF9, /* LOGICAL_MIN (-7) */323 0x25, 0x07, /* LOGICAL_MAX (7) */324 0x75, 0x04, /* REPORT_SIZE (4) */325 0x95, 0x01, /* REPORT_COUNT (1) */326 0x81, 0x06, /* INPUT */327 0x05, 0x09, /* USAGE_PAGE (buttons) */328 0x19, 0x09, /* USAGE_MIN (9) */329 0x29, 0x0C, /* USAGE_MAX (12) */330 0x15, 0x00, /* LOGICAL_MIN (0) */331 0x25, 0x01, /* LOGICAL_MAX (1) */332 0x75, 0x01, /* REPORT_SIZE (1) */333 0x95, 0x04, /* REPORT_COUNT (4) */334 0x81, 0x02, /* INPUT (Data,Var,Abs) */335 0xC0, /* END_COLLECTION */336 0xC0, /* END_COLLECTION */337};338 339/* Mouse descriptor (5) for Bluetooth receiver, normal-res hwheel, 8 buttons */340static const char mse5_bluetooth_descriptor[] = {341 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */342 0x09, 0x02, /* Usage (Mouse) */343 0xa1, 0x01, /* Collection (Application) */344 0x85, 0x05, /* Report ID (5) */345 0x09, 0x01, /* Usage (Pointer) */346 0xa1, 0x00, /* Collection (Physical) */347 0x05, 0x09, /* Usage Page (Button) */348 0x19, 0x01, /* Usage Minimum (1) */349 0x29, 0x08, /* Usage Maximum (8) */350 0x15, 0x00, /* Logical Minimum (0) */351 0x25, 0x01, /* Logical Maximum (1) */352 0x95, 0x08, /* Report Count (8) */353 0x75, 0x01, /* Report Size (1) */354 0x81, 0x02, /* Input (Data,Var,Abs) */355 0x05, 0x01, /* Usage Page (Generic Desktop) */356 0x16, 0x01, 0xf8, /* Logical Minimum (-2047) */357 0x26, 0xff, 0x07, /* Logical Maximum (2047) */358 0x75, 0x0c, /* Report Size (12) */359 0x95, 0x02, /* Report Count (2) */360 0x09, 0x30, /* Usage (X) */361 0x09, 0x31, /* Usage (Y) */362 0x81, 0x06, /* Input (Data,Var,Rel) */363 0x15, 0x81, /* Logical Minimum (-127) */364 0x25, 0x7f, /* Logical Maximum (127) */365 0x75, 0x08, /* Report Size (8) */366 0x95, 0x01, /* Report Count (1) */367 0x09, 0x38, /* Usage (Wheel) */368 0x81, 0x06, /* Input (Data,Var,Rel) */369 0x05, 0x0c, /* Usage Page (Consumer Devices) */370 0x0a, 0x38, 0x02, /* Usage (AC Pan) */371 0x15, 0x81, /* Logical Minimum (-127) */372 0x25, 0x7f, /* Logical Maximum (127) */373 0x75, 0x08, /* Report Size (8) */374 0x95, 0x01, /* Report Count (1) */375 0x81, 0x06, /* Input (Data,Var,Rel) */376 0xc0, /* End Collection */377 0xc0, /* End Collection */378};379 380/* Gaming Mouse descriptor (2) */381static const char mse_high_res_descriptor[] = {382 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */383 0x09, 0x02, /* USAGE (Mouse) */384 0xA1, 0x01, /* COLLECTION (Application) */385 0x85, 0x02, /* REPORT_ID = 2 */386 0x09, 0x01, /* USAGE (pointer) */387 0xA1, 0x00, /* COLLECTION (physical) */388 0x05, 0x09, /* USAGE_PAGE (buttons) */389 0x19, 0x01, /* USAGE_MIN (1) */390 0x29, 0x10, /* USAGE_MAX (16) */391 0x15, 0x00, /* LOGICAL_MIN (0) */392 0x25, 0x01, /* LOGICAL_MAX (1) */393 0x95, 0x10, /* REPORT_COUNT (16) */394 0x75, 0x01, /* REPORT_SIZE (1) */395 0x81, 0x02, /* INPUT (data var abs) */396 0x05, 0x01, /* USAGE_PAGE (generic desktop) */397 0x16, 0x01, 0x80, /* LOGICAL_MIN (-32767) */398 0x26, 0xFF, 0x7F, /* LOGICAL_MAX (32767) */399 0x75, 0x10, /* REPORT_SIZE (16) */400 0x95, 0x02, /* REPORT_COUNT (2) */401 0x09, 0x30, /* USAGE (X) */402 0x09, 0x31, /* USAGE (Y) */403 0x81, 0x06, /* INPUT */404 0x15, 0x81, /* LOGICAL_MIN (-127) */405 0x25, 0x7F, /* LOGICAL_MAX (127) */406 0x75, 0x08, /* REPORT_SIZE (8) */407 0x95, 0x01, /* REPORT_COUNT (1) */408 0x09, 0x38, /* USAGE (wheel) */409 0x81, 0x06, /* INPUT */410 0x05, 0x0C, /* USAGE_PAGE(consumer) */411 0x0A, 0x38, 0x02, /* USAGE(AC Pan) */412 0x95, 0x01, /* REPORT_COUNT (1) */413 0x81, 0x06, /* INPUT */414 0xC0, /* END_COLLECTION */415 0xC0, /* END_COLLECTION */416};417 418/* Consumer Control descriptor (3) */419static const char consumer_descriptor[] = {420 0x05, 0x0C, /* USAGE_PAGE (Consumer Devices) */421 0x09, 0x01, /* USAGE (Consumer Control) */422 0xA1, 0x01, /* COLLECTION (Application) */423 0x85, 0x03, /* REPORT_ID = 3 */424 0x75, 0x10, /* REPORT_SIZE (16) */425 0x95, 0x02, /* REPORT_COUNT (2) */426 0x15, 0x01, /* LOGICAL_MIN (1) */427 0x26, 0xFF, 0x02, /* LOGICAL_MAX (767) */428 0x19, 0x01, /* USAGE_MIN (1) */429 0x2A, 0xFF, 0x02, /* USAGE_MAX (767) */430 0x81, 0x00, /* INPUT (Data Ary Abs) */431 0xC0, /* END_COLLECTION */432}; /* */433 434/* System control descriptor (4) */435static const char syscontrol_descriptor[] = {436 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */437 0x09, 0x80, /* USAGE (System Control) */438 0xA1, 0x01, /* COLLECTION (Application) */439 0x85, 0x04, /* REPORT_ID = 4 */440 0x75, 0x02, /* REPORT_SIZE (2) */441 0x95, 0x01, /* REPORT_COUNT (1) */442 0x15, 0x01, /* LOGICAL_MIN (1) */443 0x25, 0x03, /* LOGICAL_MAX (3) */444 0x09, 0x82, /* USAGE (System Sleep) */445 0x09, 0x81, /* USAGE (System Power Down) */446 0x09, 0x83, /* USAGE (System Wake Up) */447 0x81, 0x60, /* INPUT (Data Ary Abs NPrf Null) */448 0x75, 0x06, /* REPORT_SIZE (6) */449 0x81, 0x03, /* INPUT (Cnst Var Abs) */450 0xC0, /* END_COLLECTION */451};452 453/* Media descriptor (8) */454static const char media_descriptor[] = {455 0x06, 0xbc, 0xff, /* Usage Page 0xffbc */456 0x09, 0x88, /* Usage 0x0088 */457 0xa1, 0x01, /* BeginCollection */458 0x85, 0x08, /* Report ID 8 */459 0x19, 0x01, /* Usage Min 0x0001 */460 0x29, 0xff, /* Usage Max 0x00ff */461 0x15, 0x01, /* Logical Min 1 */462 0x26, 0xff, 0x00, /* Logical Max 255 */463 0x75, 0x08, /* Report Size 8 */464 0x95, 0x01, /* Report Count 1 */465 0x81, 0x00, /* Input */466 0xc0, /* EndCollection */467}; /* */468 469/* HIDPP descriptor */470static const char hidpp_descriptor[] = {471 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */472 0x09, 0x01, /* Usage (Vendor Usage 1) */473 0xa1, 0x01, /* Collection (Application) */474 0x85, 0x10, /* Report ID (16) */475 0x75, 0x08, /* Report Size (8) */476 0x95, 0x06, /* Report Count (6) */477 0x15, 0x00, /* Logical Minimum (0) */478 0x26, 0xff, 0x00, /* Logical Maximum (255) */479 0x09, 0x01, /* Usage (Vendor Usage 1) */480 0x81, 0x00, /* Input (Data,Arr,Abs) */481 0x09, 0x01, /* Usage (Vendor Usage 1) */482 0x91, 0x00, /* Output (Data,Arr,Abs) */483 0xc0, /* End Collection */484 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */485 0x09, 0x02, /* Usage (Vendor Usage 2) */486 0xa1, 0x01, /* Collection (Application) */487 0x85, 0x11, /* Report ID (17) */488 0x75, 0x08, /* Report Size (8) */489 0x95, 0x13, /* Report Count (19) */490 0x15, 0x00, /* Logical Minimum (0) */491 0x26, 0xff, 0x00, /* Logical Maximum (255) */492 0x09, 0x02, /* Usage (Vendor Usage 2) */493 0x81, 0x00, /* Input (Data,Arr,Abs) */494 0x09, 0x02, /* Usage (Vendor Usage 2) */495 0x91, 0x00, /* Output (Data,Arr,Abs) */496 0xc0, /* End Collection */497 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */498 0x09, 0x04, /* Usage (Vendor Usage 0x04) */499 0xa1, 0x01, /* Collection (Application) */500 0x85, 0x20, /* Report ID (32) */501 0x75, 0x08, /* Report Size (8) */502 0x95, 0x0e, /* Report Count (14) */503 0x15, 0x00, /* Logical Minimum (0) */504 0x26, 0xff, 0x00, /* Logical Maximum (255) */505 0x09, 0x41, /* Usage (Vendor Usage 0x41) */506 0x81, 0x00, /* Input (Data,Arr,Abs) */507 0x09, 0x41, /* Usage (Vendor Usage 0x41) */508 0x91, 0x00, /* Output (Data,Arr,Abs) */509 0x85, 0x21, /* Report ID (33) */510 0x95, 0x1f, /* Report Count (31) */511 0x15, 0x00, /* Logical Minimum (0) */512 0x26, 0xff, 0x00, /* Logical Maximum (255) */513 0x09, 0x42, /* Usage (Vendor Usage 0x42) */514 0x81, 0x00, /* Input (Data,Arr,Abs) */515 0x09, 0x42, /* Usage (Vendor Usage 0x42) */516 0x91, 0x00, /* Output (Data,Arr,Abs) */517 0xc0, /* End Collection */518};519 520/* Maximum size of all defined hid reports in bytes (including report id) */521#define MAX_REPORT_SIZE 8522 523/* Make sure all descriptors are present here */524#define MAX_RDESC_SIZE \525 (sizeof(kbd_descriptor) + \526 sizeof(mse_bluetooth_descriptor) + \527 sizeof(mse5_bluetooth_descriptor) + \528 sizeof(consumer_descriptor) + \529 sizeof(syscontrol_descriptor) + \530 sizeof(media_descriptor) + \531 sizeof(hidpp_descriptor))532 533/* Number of possible hid report types that can be created by this driver.534 *535 * Right now, RF report types have the same report types (or report id's)536 * than the hid report created from those RF reports. In the future537 * this doesnt have to be true.538 *539 * For instance, RF report type 0x01 which has a size of 8 bytes, corresponds540 * to hid report id 0x01, this is standard keyboard. Same thing applies to mice541 * reports and consumer control, etc. If a new RF report is created, it doesn't542 * has to have the same report id as its corresponding hid report, so an543 * translation may have to take place for future report types.544 */545#define NUMBER_OF_HID_REPORTS 32546static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = {547 [1] = 8, /* Standard keyboard */548 [2] = 8, /* Standard mouse */549 [3] = 5, /* Consumer control */550 [4] = 2, /* System control */551 [8] = 2, /* Media Center */552};553 554 555#define LOGITECH_DJ_INTERFACE_NUMBER 0x02556 557static const struct hid_ll_driver logi_dj_ll_driver;558 559static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);560static void delayedwork_callback(struct work_struct *work);561 562static LIST_HEAD(dj_hdev_list);563static DEFINE_MUTEX(dj_hdev_list_lock);564 565static bool recvr_type_is_bluetooth(enum recvr_type type)566{567 return type == recvr_type_bluetooth || type == recvr_type_dinovo;568}569 570/*571 * dj/HID++ receivers are really a single logical entity, but for BIOS/Windows572 * compatibility they have multiple USB interfaces. On HID++ receivers we need573 * to listen for input reports on both interfaces. The functions below are used574 * to create a single struct dj_receiver_dev for all interfaces belonging to575 * a single USB-device / receiver.576 */577static struct dj_receiver_dev *dj_find_receiver_dev(struct hid_device *hdev,578 enum recvr_type type)579{580 struct dj_receiver_dev *djrcv_dev;581 char sep;582 583 /*584 * The bluetooth receiver contains a built-in hub and has separate585 * USB-devices for the keyboard and mouse interfaces.586 */587 sep = recvr_type_is_bluetooth(type) ? '.' : '/';588 589 /* Try to find an already-probed interface from the same device */590 list_for_each_entry(djrcv_dev, &dj_hdev_list, list) {591 if (djrcv_dev->mouse &&592 hid_compare_device_paths(hdev, djrcv_dev->mouse, sep)) {593 kref_get(&djrcv_dev->kref);594 return djrcv_dev;595 }596 if (djrcv_dev->keyboard &&597 hid_compare_device_paths(hdev, djrcv_dev->keyboard, sep)) {598 kref_get(&djrcv_dev->kref);599 return djrcv_dev;600 }601 if (djrcv_dev->hidpp &&602 hid_compare_device_paths(hdev, djrcv_dev->hidpp, sep)) {603 kref_get(&djrcv_dev->kref);604 return djrcv_dev;605 }606 }607 608 return NULL;609}610 611static void dj_release_receiver_dev(struct kref *kref)612{613 struct dj_receiver_dev *djrcv_dev = container_of(kref, struct dj_receiver_dev, kref);614 615 list_del(&djrcv_dev->list);616 kfifo_free(&djrcv_dev->notif_fifo);617 kfree(djrcv_dev);618}619 620static void dj_put_receiver_dev(struct hid_device *hdev)621{622 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);623 624 mutex_lock(&dj_hdev_list_lock);625 626 if (djrcv_dev->mouse == hdev)627 djrcv_dev->mouse = NULL;628 if (djrcv_dev->keyboard == hdev)629 djrcv_dev->keyboard = NULL;630 if (djrcv_dev->hidpp == hdev)631 djrcv_dev->hidpp = NULL;632 633 kref_put(&djrcv_dev->kref, dj_release_receiver_dev);634 635 mutex_unlock(&dj_hdev_list_lock);636}637 638static struct dj_receiver_dev *dj_get_receiver_dev(struct hid_device *hdev,639 enum recvr_type type,640 unsigned int application,641 bool is_hidpp)642{643 struct dj_receiver_dev *djrcv_dev;644 645 mutex_lock(&dj_hdev_list_lock);646 647 djrcv_dev = dj_find_receiver_dev(hdev, type);648 if (!djrcv_dev) {649 djrcv_dev = kzalloc(sizeof(*djrcv_dev), GFP_KERNEL);650 if (!djrcv_dev)651 goto out;652 653 INIT_WORK(&djrcv_dev->work, delayedwork_callback);654 spin_lock_init(&djrcv_dev->lock);655 if (kfifo_alloc(&djrcv_dev->notif_fifo,656 DJ_MAX_NUMBER_NOTIFS * sizeof(struct dj_workitem),657 GFP_KERNEL)) {658 kfree(djrcv_dev);659 djrcv_dev = NULL;660 goto out;661 }662 kref_init(&djrcv_dev->kref);663 list_add_tail(&djrcv_dev->list, &dj_hdev_list);664 djrcv_dev->last_query = jiffies;665 djrcv_dev->type = type;666 }667 668 if (application == HID_GD_KEYBOARD)669 djrcv_dev->keyboard = hdev;670 if (application == HID_GD_MOUSE)671 djrcv_dev->mouse = hdev;672 if (is_hidpp)673 djrcv_dev->hidpp = hdev;674 675 hid_set_drvdata(hdev, djrcv_dev);676out:677 mutex_unlock(&dj_hdev_list_lock);678 return djrcv_dev;679}680 681static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,682 struct dj_workitem *workitem)683{684 /* Called in delayed work context */685 struct dj_device *dj_dev;686 unsigned long flags;687 688 spin_lock_irqsave(&djrcv_dev->lock, flags);689 dj_dev = djrcv_dev->paired_dj_devices[workitem->device_index];690 djrcv_dev->paired_dj_devices[workitem->device_index] = NULL;691 spin_unlock_irqrestore(&djrcv_dev->lock, flags);692 693 if (dj_dev != NULL) {694 hid_destroy_device(dj_dev->hdev);695 kfree(dj_dev);696 } else {697 hid_err(djrcv_dev->hidpp, "%s: can't destroy a NULL device\n",698 __func__);699 }700}701 702static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,703 struct dj_workitem *workitem)704{705 /* Called in delayed work context */706 struct hid_device *djrcv_hdev = djrcv_dev->hidpp;707 struct hid_device *dj_hiddev;708 struct dj_device *dj_dev;709 u8 device_index = workitem->device_index;710 unsigned long flags;711 712 /* Device index goes from 1 to 6, we need 3 bytes to store the713 * semicolon, the index, and a null terminator714 */715 unsigned char tmpstr[3];716 717 /* We are the only one ever adding a device, no need to lock */718 if (djrcv_dev->paired_dj_devices[device_index]) {719 /* The device is already known. No need to reallocate it. */720 dbg_hid("%s: device is already known\n", __func__);721 return;722 }723 724 dj_hiddev = hid_allocate_device();725 if (IS_ERR(dj_hiddev)) {726 hid_err(djrcv_hdev, "%s: hid_allocate_dev failed\n", __func__);727 return;728 }729 730 dj_hiddev->ll_driver = &logi_dj_ll_driver;731 732 dj_hiddev->dev.parent = &djrcv_hdev->dev;733 dj_hiddev->bus = BUS_USB;734 dj_hiddev->vendor = djrcv_hdev->vendor;735 dj_hiddev->product = (workitem->quad_id_msb << 8) |736 workitem->quad_id_lsb;737 if (workitem->device_type) {738 const char *type_str = "Device";739 740 switch (workitem->device_type) {741 case 0x01: type_str = "Keyboard"; break;742 case 0x02: type_str = "Mouse"; break;743 case 0x03: type_str = "Numpad"; break;744 case 0x04: type_str = "Presenter"; break;745 case 0x07: type_str = "Remote Control"; break;746 case 0x08: type_str = "Trackball"; break;747 case 0x09: type_str = "Touchpad"; break;748 }749 snprintf(dj_hiddev->name, sizeof(dj_hiddev->name),750 "Logitech Wireless %s PID:%04x",751 type_str, dj_hiddev->product);752 } else {753 snprintf(dj_hiddev->name, sizeof(dj_hiddev->name),754 "Logitech Wireless Device PID:%04x",755 dj_hiddev->product);756 }757 758 if (djrcv_dev->type == recvr_type_27mhz)759 dj_hiddev->group = HID_GROUP_LOGITECH_27MHZ_DEVICE;760 else761 dj_hiddev->group = HID_GROUP_LOGITECH_DJ_DEVICE;762 763 memcpy(dj_hiddev->phys, djrcv_hdev->phys, sizeof(djrcv_hdev->phys));764 snprintf(tmpstr, sizeof(tmpstr), ":%d", device_index);765 strlcat(dj_hiddev->phys, tmpstr, sizeof(dj_hiddev->phys));766 767 dj_dev = kzalloc(sizeof(struct dj_device), GFP_KERNEL);768 769 if (!dj_dev) {770 hid_err(djrcv_hdev, "%s: failed allocating dj_dev\n", __func__);771 goto dj_device_allocate_fail;772 }773 774 dj_dev->reports_supported = workitem->reports_supported;775 dj_dev->hdev = dj_hiddev;776 dj_dev->dj_receiver_dev = djrcv_dev;777 dj_dev->device_index = device_index;778 dj_hiddev->driver_data = dj_dev;779 780 spin_lock_irqsave(&djrcv_dev->lock, flags);781 djrcv_dev->paired_dj_devices[device_index] = dj_dev;782 spin_unlock_irqrestore(&djrcv_dev->lock, flags);783 784 if (hid_add_device(dj_hiddev)) {785 hid_err(djrcv_hdev, "%s: failed adding dj_device\n", __func__);786 goto hid_add_device_fail;787 }788 789 return;790 791hid_add_device_fail:792 spin_lock_irqsave(&djrcv_dev->lock, flags);793 djrcv_dev->paired_dj_devices[device_index] = NULL;794 spin_unlock_irqrestore(&djrcv_dev->lock, flags);795 kfree(dj_dev);796dj_device_allocate_fail:797 hid_destroy_device(dj_hiddev);798}799 800static void delayedwork_callback(struct work_struct *work)801{802 struct dj_receiver_dev *djrcv_dev =803 container_of(work, struct dj_receiver_dev, work);804 805 struct dj_workitem workitem;806 unsigned long flags;807 int count;808 int retval;809 810 dbg_hid("%s\n", __func__);811 812 spin_lock_irqsave(&djrcv_dev->lock, flags);813 814 /*815 * Since we attach to multiple interfaces, we may get scheduled before816 * we are bound to the HID++ interface, catch this.817 */818 if (!djrcv_dev->ready) {819 pr_warn("%s: delayedwork queued before hidpp interface was enumerated\n",820 __func__);821 spin_unlock_irqrestore(&djrcv_dev->lock, flags);822 return;823 }824 825 count = kfifo_out(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));826 827 if (count != sizeof(workitem)) {828 spin_unlock_irqrestore(&djrcv_dev->lock, flags);829 return;830 }831 832 if (!kfifo_is_empty(&djrcv_dev->notif_fifo))833 schedule_work(&djrcv_dev->work);834 835 spin_unlock_irqrestore(&djrcv_dev->lock, flags);836 837 switch (workitem.type) {838 case WORKITEM_TYPE_PAIRED:839 logi_dj_recv_add_djhid_device(djrcv_dev, &workitem);840 break;841 case WORKITEM_TYPE_UNPAIRED:842 logi_dj_recv_destroy_djhid_device(djrcv_dev, &workitem);843 break;844 case WORKITEM_TYPE_UNKNOWN:845 retval = logi_dj_recv_query_paired_devices(djrcv_dev);846 if (retval) {847 hid_err(djrcv_dev->hidpp, "%s: logi_dj_recv_query_paired_devices error: %d\n",848 __func__, retval);849 }850 break;851 case WORKITEM_TYPE_EMPTY:852 dbg_hid("%s: device list is empty\n", __func__);853 break;854 }855}856 857/*858 * Sometimes we receive reports for which we do not have a paired dj_device859 * associated with the device_index or report-type to forward the report to.860 * This means that the original "device paired" notification corresponding861 * to the dj_device never arrived to this driver. Possible reasons for this are:862 * 1) hid-core discards all packets coming from a device during probe().863 * 2) if the receiver is plugged into a KVM switch then the pairing reports864 * are only forwarded to it if the focus is on this PC.865 * This function deals with this by re-asking the receiver for the list of866 * connected devices in the delayed work callback.867 * This function MUST be called with djrcv->lock held.868 */869static void logi_dj_recv_queue_unknown_work(struct dj_receiver_dev *djrcv_dev)870{871 struct dj_workitem workitem = { .type = WORKITEM_TYPE_UNKNOWN };872 873 /* Rate limit queries done because of unhandled reports to 2/sec */874 if (time_before(jiffies, djrcv_dev->last_query + HZ / 2))875 return;876 877 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));878 schedule_work(&djrcv_dev->work);879}880 881static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,882 struct dj_report *dj_report)883{884 /* We are called from atomic context (tasklet && djrcv->lock held) */885 struct dj_workitem workitem = {886 .device_index = dj_report->device_index,887 };888 889 switch (dj_report->report_type) {890 case REPORT_TYPE_NOTIF_DEVICE_PAIRED:891 workitem.type = WORKITEM_TYPE_PAIRED;892 if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &893 SPFUNCTION_DEVICE_LIST_EMPTY) {894 workitem.type = WORKITEM_TYPE_EMPTY;895 break;896 }897 fallthrough;898 case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:899 workitem.quad_id_msb =900 dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_MSB];901 workitem.quad_id_lsb =902 dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB];903 workitem.reports_supported = get_unaligned_le32(904 dj_report->report_params +905 DEVICE_PAIRED_RF_REPORT_TYPE);906 workitem.reports_supported |= HIDPP;907 if (dj_report->report_type == REPORT_TYPE_NOTIF_DEVICE_UNPAIRED)908 workitem.type = WORKITEM_TYPE_UNPAIRED;909 break;910 default:911 logi_dj_recv_queue_unknown_work(djrcv_dev);912 return;913 }914 915 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));916 schedule_work(&djrcv_dev->work);917}918 919/*920 * Some quad/bluetooth keyboards have a builtin touchpad in this case we see921 * only 1 paired device with a device_type of REPORT_TYPE_KEYBOARD. For the922 * touchpad to work we must also forward mouse input reports to the dj_hiddev923 * created for the keyboard (instead of forwarding them to a second paired924 * device with a device_type of REPORT_TYPE_MOUSE as we normally would).925 *926 * On Dinovo receivers the keyboard's touchpad and an optional paired actual927 * mouse send separate input reports, INPUT(2) aka STD_MOUSE for the mouse928 * and INPUT(5) aka KBD_MOUSE for the keyboard's touchpad.929 *930 * On MX5x00 receivers (which can also be paired with a Dinovo keyboard)931 * INPUT(2) is used for both an optional paired actual mouse and for the932 * keyboard's touchpad.933 */934static const u16 kbd_builtin_touchpad_ids[] = {935 0xb309, /* Dinovo Edge */936 0xb30c, /* Dinovo Mini */937};938 939static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,940 struct hidpp_event *hidpp_report,941 struct dj_workitem *workitem)942{943 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);944 int i, id;945 946 workitem->type = WORKITEM_TYPE_PAIRED;947 workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &948 HIDPP_DEVICE_TYPE_MASK;949 workitem->quad_id_msb = hidpp_report->params[HIDPP_PARAM_EQUAD_MSB];950 workitem->quad_id_lsb = hidpp_report->params[HIDPP_PARAM_EQUAD_LSB];951 switch (workitem->device_type) {952 case REPORT_TYPE_KEYBOARD:953 workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA |954 POWER_KEYS | MEDIA_CENTER |955 HIDPP;956 id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb;957 for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) {958 if (id == kbd_builtin_touchpad_ids[i]) {959 if (djrcv_dev->type == recvr_type_dinovo)960 workitem->reports_supported |= KBD_MOUSE;961 else962 workitem->reports_supported |= STD_MOUSE;963 break;964 }965 }966 break;967 case REPORT_TYPE_MOUSE:968 workitem->reports_supported |= STD_MOUSE | HIDPP | MULTIMEDIA;969 break;970 }971}972 973static void logi_hidpp_dev_conn_notif_27mhz(struct hid_device *hdev,974 struct hidpp_event *hidpp_report,975 struct dj_workitem *workitem)976{977 workitem->type = WORKITEM_TYPE_PAIRED;978 workitem->quad_id_lsb = hidpp_report->params[HIDPP_PARAM_27MHZ_DEVID];979 switch (hidpp_report->device_index) {980 case 1: /* Index 1 is always a mouse */981 case 2: /* Index 2 is always a mouse */982 workitem->device_type = HIDPP_DEVICE_TYPE_MOUSE;983 workitem->reports_supported |= STD_MOUSE | HIDPP;984 break;985 case 3: /* Index 3 is always the keyboard */986 if (hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] & HIDPP_27MHZ_SECURE_MASK) {987 hid_info(hdev, "Keyboard connection is encrypted\n");988 } else {989 hid_warn(hdev, "Keyboard events are send over the air in plain-text / unencrypted\n");990 hid_warn(hdev, "See: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup/\n");991 }992 fallthrough;993 case 4: /* Index 4 is used for an optional separate numpad */994 workitem->device_type = HIDPP_DEVICE_TYPE_KEYBOARD;995 workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA |996 POWER_KEYS | HIDPP;997 break;998 default:999 hid_warn(hdev, "%s: unexpected device-index %d", __func__,1000 hidpp_report->device_index);1001 }1002}1003 1004static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,1005 struct hidpp_event *hidpp_report)1006{1007 /* We are called from atomic context (tasklet && djrcv->lock held) */1008 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);1009 const char *device_type = "UNKNOWN";1010 struct dj_workitem workitem = {1011 .type = WORKITEM_TYPE_EMPTY,1012 .device_index = hidpp_report->device_index,1013 };1014 1015 switch (hidpp_report->params[HIDPP_PARAM_PROTO_TYPE]) {1016 case 0x01:1017 device_type = "Bluetooth";1018 /* Bluetooth connect packet contents is the same as (e)QUAD */1019 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1020 if (!(hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &1021 HIDPP_MANUFACTURER_MASK)) {1022 hid_info(hdev, "Non Logitech device connected on slot %d\n",1023 hidpp_report->device_index);1024 workitem.reports_supported &= ~HIDPP;1025 }1026 break;1027 case 0x02:1028 device_type = "27 Mhz";1029 logi_hidpp_dev_conn_notif_27mhz(hdev, hidpp_report, &workitem);1030 break;1031 case 0x03:1032 device_type = "QUAD or eQUAD";1033 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1034 break;1035 case 0x04:1036 device_type = "eQUAD step 4 DJ";1037 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1038 break;1039 case 0x05:1040 device_type = "DFU Lite";1041 break;1042 case 0x06:1043 device_type = "eQUAD step 4 Lite";1044 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1045 break;1046 case 0x07:1047 device_type = "eQUAD step 4 Gaming";1048 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1049 workitem.reports_supported |= STD_KEYBOARD;1050 break;1051 case 0x08:1052 device_type = "eQUAD step 4 for gamepads";1053 break;1054 case 0x0a:1055 device_type = "eQUAD nano Lite";1056 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1057 break;1058 case 0x0c:1059 device_type = "eQUAD Lightspeed 1";1060 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1061 workitem.reports_supported |= STD_KEYBOARD;1062 break;1063 case 0x0d:1064 device_type = "eQUAD Lightspeed 1.1";1065 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1066 workitem.reports_supported |= STD_KEYBOARD;1067 break;1068 case 0x0f:1069 case 0x11:1070 device_type = "eQUAD Lightspeed 1.2";1071 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);1072 workitem.reports_supported |= STD_KEYBOARD;1073 break;1074 }1075 1076 /* custom receiver device (eg. powerplay) */1077 if (hidpp_report->device_index == 7) {1078 workitem.reports_supported |= HIDPP;1079 }1080 1081 if (workitem.type == WORKITEM_TYPE_EMPTY) {1082 hid_warn(hdev,1083 "unusable device of type %s (0x%02x) connected on slot %d",1084 device_type,1085 hidpp_report->params[HIDPP_PARAM_PROTO_TYPE],1086 hidpp_report->device_index);1087 return;1088 }1089 1090 hid_info(hdev, "device of type %s (0x%02x) connected on slot %d",1091 device_type, hidpp_report->params[HIDPP_PARAM_PROTO_TYPE],1092 hidpp_report->device_index);1093 1094 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));1095 schedule_work(&djrcv_dev->work);1096}1097 1098static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,1099 struct dj_report *dj_report)1100{1101 /* We are called from atomic context (tasklet && djrcv->lock held) */1102 unsigned int i;1103 u8 reportbuffer[MAX_REPORT_SIZE];1104 struct dj_device *djdev;1105 1106 djdev = djrcv_dev->paired_dj_devices[dj_report->device_index];1107 1108 memset(reportbuffer, 0, sizeof(reportbuffer));1109 1110 for (i = 0; i < NUMBER_OF_HID_REPORTS; i++) {1111 if (djdev->reports_supported & (1 << i)) {1112 reportbuffer[0] = i;1113 if (hid_input_report(djdev->hdev,1114 HID_INPUT_REPORT,1115 reportbuffer,1116 hid_reportid_size_map[i], 1)) {1117 dbg_hid("hid_input_report error sending null "1118 "report\n");1119 }1120 }1121 }1122}1123 1124static void logi_dj_recv_forward_dj(struct dj_receiver_dev *djrcv_dev,1125 struct dj_report *dj_report)1126{1127 /* We are called from atomic context (tasklet && djrcv->lock held) */1128 struct dj_device *dj_device;1129 1130 dj_device = djrcv_dev->paired_dj_devices[dj_report->device_index];1131 1132 if ((dj_report->report_type > ARRAY_SIZE(hid_reportid_size_map) - 1) ||1133 (hid_reportid_size_map[dj_report->report_type] == 0)) {1134 dbg_hid("invalid report type:%x\n", dj_report->report_type);1135 return;1136 }1137 1138 if (hid_input_report(dj_device->hdev,1139 HID_INPUT_REPORT, &dj_report->report_type,1140 hid_reportid_size_map[dj_report->report_type], 1)) {1141 dbg_hid("hid_input_report error\n");1142 }1143}1144 1145static void logi_dj_recv_forward_report(struct dj_device *dj_dev, u8 *data,1146 int size)1147{1148 /* We are called from atomic context (tasklet && djrcv->lock held) */1149 if (hid_input_report(dj_dev->hdev, HID_INPUT_REPORT, data, size, 1))1150 dbg_hid("hid_input_report error\n");1151}1152 1153static void logi_dj_recv_forward_input_report(struct hid_device *hdev,1154 u8 *data, int size)1155{1156 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);1157 struct dj_device *dj_dev;1158 unsigned long flags;1159 u8 report = data[0];1160 int i;1161 1162 if (report > REPORT_TYPE_RFREPORT_LAST) {1163 hid_err(hdev, "Unexpected input report number %d\n", report);1164 return;1165 }1166 1167 spin_lock_irqsave(&djrcv_dev->lock, flags);1168 for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {1169 dj_dev = djrcv_dev->paired_dj_devices[i];1170 if (dj_dev && (dj_dev->reports_supported & BIT(report))) {1171 logi_dj_recv_forward_report(dj_dev, data, size);1172 spin_unlock_irqrestore(&djrcv_dev->lock, flags);1173 return;1174 }1175 }1176 1177 logi_dj_recv_queue_unknown_work(djrcv_dev);1178 spin_unlock_irqrestore(&djrcv_dev->lock, flags);1179 1180 dbg_hid("No dj-devs handling input report number %d\n", report);1181}1182 1183static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,1184 struct dj_report *dj_report)1185{1186 struct hid_device *hdev = djrcv_dev->hidpp;1187 struct hid_report *report;1188 struct hid_report_enum *output_report_enum;1189 u8 *data = (u8 *)(&dj_report->device_index);1190 unsigned int i;1191 1192 output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];1193 report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];1194 1195 if (!report) {1196 hid_err(hdev, "%s: unable to find dj report\n", __func__);1197 return -ENODEV;1198 }1199 1200 for (i = 0; i < DJREPORT_SHORT_LENGTH - 1; i++)1201 report->field[0]->value[i] = data[i];1202 1203 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);1204 1205 return 0;1206}1207 1208static int logi_dj_recv_query_hidpp_devices(struct dj_receiver_dev *djrcv_dev)1209{1210 static const u8 template[] = {1211 REPORT_ID_HIDPP_SHORT,1212 HIDPP_RECEIVER_INDEX,1213 HIDPP_SET_REGISTER,1214 HIDPP_REG_CONNECTION_STATE,1215 HIDPP_FAKE_DEVICE_ARRIVAL,1216 0x00, 0x001217 };1218 u8 *hidpp_report;1219 int retval;1220 1221 hidpp_report = kmemdup(template, sizeof(template), GFP_KERNEL);1222 if (!hidpp_report)1223 return -ENOMEM;1224 1225 retval = hid_hw_raw_request(djrcv_dev->hidpp,1226 REPORT_ID_HIDPP_SHORT,1227 hidpp_report, sizeof(template),1228 HID_OUTPUT_REPORT,1229 HID_REQ_SET_REPORT);1230 1231 kfree(hidpp_report);1232 return (retval < 0) ? retval : 0;1233}1234 1235static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)1236{1237 struct dj_report *dj_report;1238 int retval;1239 1240 djrcv_dev->last_query = jiffies;1241 1242 if (djrcv_dev->type != recvr_type_dj)1243 return logi_dj_recv_query_hidpp_devices(djrcv_dev);1244 1245 dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);1246 if (!dj_report)1247 return -ENOMEM;1248 dj_report->report_id = REPORT_ID_DJ_SHORT;1249 dj_report->device_index = HIDPP_RECEIVER_INDEX;1250 dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES;1251 retval = logi_dj_recv_send_report(djrcv_dev, dj_report);1252 kfree(dj_report);1253 return retval;1254}1255 1256 1257static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,1258 unsigned timeout)1259{1260 struct hid_device *hdev = djrcv_dev->hidpp;1261 struct dj_report *dj_report;1262 u8 *buf;1263 int retval = 0;1264 1265 dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);1266 if (!dj_report)1267 return -ENOMEM;1268 1269 if (djrcv_dev->type == recvr_type_dj) {1270 dj_report->report_id = REPORT_ID_DJ_SHORT;1271 dj_report->device_index = HIDPP_RECEIVER_INDEX;1272 dj_report->report_type = REPORT_TYPE_CMD_SWITCH;1273 dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F;1274 dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] =1275 (u8)timeout;1276 1277 retval = logi_dj_recv_send_report(djrcv_dev, dj_report);1278 1279 /*1280 * Ugly sleep to work around a USB 3.0 bug when the receiver is1281 * still processing the "switch-to-dj" command while we send an1282 * other command.1283 * 50 msec should gives enough time to the receiver to be ready.1284 */1285 msleep(50);1286 1287 if (retval) {1288 kfree(dj_report);1289 return retval;1290 }1291 }1292 1293 /*1294 * Magical bits to set up hidpp notifications when the dj devices1295 * are connected/disconnected.1296 *1297 * We can reuse dj_report because HIDPP_REPORT_SHORT_LENGTH is smaller1298 * than DJREPORT_SHORT_LENGTH.1299 */1300 buf = (u8 *)dj_report;1301 1302 memset(buf, 0, HIDPP_REPORT_SHORT_LENGTH);1303 1304 buf[0] = REPORT_ID_HIDPP_SHORT;1305 buf[1] = HIDPP_RECEIVER_INDEX;1306 buf[2] = 0x80;1307 buf[3] = 0x00;1308 buf[4] = 0x00;1309 buf[5] = 0x09;1310 buf[6] = 0x00;1311 1312 retval = hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,1313 HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,1314 HID_REQ_SET_REPORT);1315 1316 kfree(dj_report);1317 return retval;1318}1319 1320 1321static int logi_dj_ll_open(struct hid_device *hid)1322{1323 dbg_hid("%s: %s\n", __func__, hid->phys);1324 return 0;1325 1326}1327 1328static void logi_dj_ll_close(struct hid_device *hid)1329{1330 dbg_hid("%s: %s\n", __func__, hid->phys);1331}1332 1333/*1334 * Register 0xB5 is "pairing information". It is solely intended for the1335 * receiver, so do not overwrite the device index.1336 */1337static u8 unifying_pairing_query[] = { REPORT_ID_HIDPP_SHORT,1338 HIDPP_RECEIVER_INDEX,1339 HIDPP_GET_LONG_REGISTER,1340 HIDPP_REG_PAIRING_INFORMATION };1341static u8 unifying_pairing_answer[] = { REPORT_ID_HIDPP_LONG,1342 HIDPP_RECEIVER_INDEX,1343 HIDPP_GET_LONG_REGISTER,1344 HIDPP_REG_PAIRING_INFORMATION };1345 1346static int logi_dj_ll_raw_request(struct hid_device *hid,1347 unsigned char reportnum, __u8 *buf,1348 size_t count, unsigned char report_type,1349 int reqtype)1350{1351 struct dj_device *djdev = hid->driver_data;1352 struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev;1353 u8 *out_buf;1354 int ret;1355 1356 if ((buf[0] == REPORT_ID_HIDPP_SHORT) ||1357 (buf[0] == REPORT_ID_HIDPP_LONG) ||1358 (buf[0] == REPORT_ID_HIDPP_VERY_LONG)) {1359 if (count < 2)1360 return -EINVAL;1361 1362 /* special case where we should not overwrite1363 * the device_index */1364 if (count == 7 && !memcmp(buf, unifying_pairing_query,1365 sizeof(unifying_pairing_query)))1366 buf[4] = (buf[4] & 0xf0) | (djdev->device_index - 1);1367 else1368 buf[1] = djdev->device_index;1369 return hid_hw_raw_request(djrcv_dev->hidpp, reportnum, buf,1370 count, report_type, reqtype);1371 }1372 1373 if (buf[0] != REPORT_TYPE_LEDS)1374 return -EINVAL;1375 1376 if (djrcv_dev->type != recvr_type_dj && count >= 2) {1377 if (!djrcv_dev->keyboard) {1378 hid_warn(hid, "Received REPORT_TYPE_LEDS request before the keyboard interface was enumerated\n");1379 return 0;1380 }1381 /* usbhid overrides the report ID and ignores the first byte */1382 return hid_hw_raw_request(djrcv_dev->keyboard, 0, buf, count,1383 report_type, reqtype);1384 }1385 1386 out_buf = kzalloc(DJREPORT_SHORT_LENGTH, GFP_ATOMIC);1387 if (!out_buf)1388 return -ENOMEM;1389 1390 if (count > DJREPORT_SHORT_LENGTH - 2)1391 count = DJREPORT_SHORT_LENGTH - 2;1392 1393 out_buf[0] = REPORT_ID_DJ_SHORT;1394 out_buf[1] = djdev->device_index;1395 memcpy(out_buf + 2, buf, count);1396 1397 ret = hid_hw_raw_request(djrcv_dev->hidpp, out_buf[0], out_buf,1398 DJREPORT_SHORT_LENGTH, report_type, reqtype);1399 1400 kfree(out_buf);1401 return ret;1402}1403 1404static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)1405{1406 memcpy(rdesc + *rsize, data, size);1407 *rsize += size;1408}1409 1410static int logi_dj_ll_parse(struct hid_device *hid)1411{1412 struct dj_device *djdev = hid->driver_data;1413 unsigned int rsize = 0;1414 char *rdesc;1415 int retval;1416 1417 dbg_hid("%s\n", __func__);1418 1419 djdev->hdev->version = 0x0111;1420 djdev->hdev->country = 0x00;1421 1422 rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL);1423 if (!rdesc)1424 return -ENOMEM;1425 1426 if (djdev->reports_supported & STD_KEYBOARD) {1427 dbg_hid("%s: sending a kbd descriptor, reports_supported: %llx\n",1428 __func__, djdev->reports_supported);1429 rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));1430 }1431 1432 if (djdev->reports_supported & STD_MOUSE) {1433 dbg_hid("%s: sending a mouse descriptor, reports_supported: %llx\n",1434 __func__, djdev->reports_supported);1435 if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp ||1436 djdev->dj_receiver_dev->type == recvr_type_mouse_only)1437 rdcat(rdesc, &rsize, mse_high_res_descriptor,1438 sizeof(mse_high_res_descriptor));1439 else if (djdev->dj_receiver_dev->type == recvr_type_27mhz)1440 rdcat(rdesc, &rsize, mse_27mhz_descriptor,1441 sizeof(mse_27mhz_descriptor));1442 else if (recvr_type_is_bluetooth(djdev->dj_receiver_dev->type))1443 rdcat(rdesc, &rsize, mse_bluetooth_descriptor,1444 sizeof(mse_bluetooth_descriptor));1445 else1446 rdcat(rdesc, &rsize, mse_descriptor,1447 sizeof(mse_descriptor));1448 }1449 1450 if (djdev->reports_supported & KBD_MOUSE) {1451 dbg_hid("%s: sending a kbd-mouse descriptor, reports_supported: %llx\n",1452 __func__, djdev->reports_supported);1453 rdcat(rdesc, &rsize, mse5_bluetooth_descriptor,1454 sizeof(mse5_bluetooth_descriptor));1455 }1456 1457 if (djdev->reports_supported & MULTIMEDIA) {1458 dbg_hid("%s: sending a multimedia report descriptor: %llx\n",1459 __func__, djdev->reports_supported);1460 rdcat(rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));1461 }1462 1463 if (djdev->reports_supported & POWER_KEYS) {1464 dbg_hid("%s: sending a power keys report descriptor: %llx\n",1465 __func__, djdev->reports_supported);1466 rdcat(rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));1467 }1468 1469 if (djdev->reports_supported & MEDIA_CENTER) {1470 dbg_hid("%s: sending a media center report descriptor: %llx\n",1471 __func__, djdev->reports_supported);1472 rdcat(rdesc, &rsize, media_descriptor, sizeof(media_descriptor));1473 }1474 1475 if (djdev->reports_supported & KBD_LEDS) {1476 dbg_hid("%s: need to send kbd leds report descriptor: %llx\n",1477 __func__, djdev->reports_supported);1478 }1479 1480 if (djdev->reports_supported & HIDPP) {1481 dbg_hid("%s: sending a HID++ descriptor, reports_supported: %llx\n",1482 __func__, djdev->reports_supported);1483 rdcat(rdesc, &rsize, hidpp_descriptor,1484 sizeof(hidpp_descriptor));1485 }1486 1487 retval = hid_parse_report(hid, rdesc, rsize);1488 kfree(rdesc);1489 1490 return retval;1491}1492 1493static int logi_dj_ll_start(struct hid_device *hid)1494{1495 dbg_hid("%s\n", __func__);1496 return 0;1497}1498 1499static void logi_dj_ll_stop(struct hid_device *hid)1500{1501 dbg_hid("%s\n", __func__);1502}1503 1504static bool logi_dj_ll_may_wakeup(struct hid_device *hid)1505{1506 struct dj_device *djdev = hid->driver_data;1507 struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev;1508 1509 return hid_hw_may_wakeup(djrcv_dev->hidpp);1510}1511 1512static const struct hid_ll_driver logi_dj_ll_driver = {1513 .parse = logi_dj_ll_parse,1514 .start = logi_dj_ll_start,1515 .stop = logi_dj_ll_stop,1516 .open = logi_dj_ll_open,1517 .close = logi_dj_ll_close,1518 .raw_request = logi_dj_ll_raw_request,1519 .may_wakeup = logi_dj_ll_may_wakeup,1520};1521 1522static int logi_dj_dj_event(struct hid_device *hdev,1523 struct hid_report *report, u8 *data,1524 int size)1525{1526 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);1527 struct dj_report *dj_report = (struct dj_report *) data;1528 unsigned long flags;1529 1530 /*1531 * Here we receive all data coming from iface 2, there are 3 cases:1532 *1533 * 1) Data is intended for this driver i. e. data contains arrival,1534 * departure, etc notifications, in which case we queue them for delayed1535 * processing by the work queue. We return 1 to hid-core as no further1536 * processing is required from it.1537 *1538 * 2) Data informs a connection change, if the change means rf link1539 * loss, then we must send a null report to the upper layer to discard1540 * potentially pressed keys that may be repeated forever by the input1541 * layer. Return 1 to hid-core as no further processing is required.1542 *1543 * 3) Data is an actual input event from a paired DJ device in which1544 * case we forward it to the correct hid device (via hid_input_report()1545 * ) and return 1 so hid-core does not anything else with it.1546 */1547 1548 if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||1549 (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {1550 /*1551 * Device index is wrong, bail out.1552 * This driver can ignore safely the receiver notifications,1553 * so ignore those reports too.1554 */1555 if (dj_report->device_index != DJ_RECEIVER_INDEX)1556 hid_err(hdev, "%s: invalid device index:%d\n",1557 __func__, dj_report->device_index);1558 return false;1559 }1560 1561 spin_lock_irqsave(&djrcv_dev->lock, flags);1562 1563 if (!djrcv_dev->paired_dj_devices[dj_report->device_index]) {1564 /* received an event for an unknown device, bail out */1565 logi_dj_recv_queue_notification(djrcv_dev, dj_report);1566 goto out;1567 }1568 1569 switch (dj_report->report_type) {1570 case REPORT_TYPE_NOTIF_DEVICE_PAIRED:1571 /* pairing notifications are handled above the switch */1572 break;1573 case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:1574 logi_dj_recv_queue_notification(djrcv_dev, dj_report);1575 break;1576 case REPORT_TYPE_NOTIF_CONNECTION_STATUS:1577 if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==1578 STATUS_LINKLOSS) {1579 logi_dj_recv_forward_null_report(djrcv_dev, dj_report);1580 }1581 break;1582 default:1583 logi_dj_recv_forward_dj(djrcv_dev, dj_report);1584 }1585 1586out:1587 spin_unlock_irqrestore(&djrcv_dev->lock, flags);1588 1589 return true;1590}1591 1592static int logi_dj_hidpp_event(struct hid_device *hdev,1593 struct hid_report *report, u8 *data,1594 int size)1595{1596 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);1597 struct hidpp_event *hidpp_report = (struct hidpp_event *) data;1598 struct dj_device *dj_dev;1599 unsigned long flags;1600 u8 device_index = hidpp_report->device_index;1601 1602 if (device_index == HIDPP_RECEIVER_INDEX) {1603 /* special case were the device wants to know its unifying1604 * name */1605 if (size == HIDPP_REPORT_LONG_LENGTH &&1606 !memcmp(data, unifying_pairing_answer,1607 sizeof(unifying_pairing_answer)))1608 device_index = (data[4] & 0x0F) + 1;1609 else1610 return false;1611 }1612 1613 /*1614 * Data is from the HID++ collection, in this case, we forward the1615 * data to the corresponding child dj device and return 0 to hid-core1616 * so he data also goes to the hidraw device of the receiver. This1617 * allows a user space application to implement the full HID++ routing1618 * via the receiver.1619 */1620 1621 if ((device_index < DJ_DEVICE_INDEX_MIN) ||1622 (device_index > DJ_DEVICE_INDEX_MAX)) {1623 /*1624 * Device index is wrong, bail out.1625 * This driver can ignore safely the receiver notifications,1626 * so ignore those reports too.1627 */1628 hid_err(hdev, "%s: invalid device index:%d\n", __func__,1629 hidpp_report->device_index);1630 return false;1631 }1632 1633 spin_lock_irqsave(&djrcv_dev->lock, flags);1634 1635 dj_dev = djrcv_dev->paired_dj_devices[device_index];1636 1637 /*1638 * With 27 MHz receivers, we do not get an explicit unpair event,1639 * remove the old device if the user has paired a *different* device.1640 */1641 if (djrcv_dev->type == recvr_type_27mhz && dj_dev &&1642 hidpp_report->sub_id == REPORT_TYPE_NOTIF_DEVICE_CONNECTED &&1643 hidpp_report->params[HIDPP_PARAM_PROTO_TYPE] == 0x02 &&1644 hidpp_report->params[HIDPP_PARAM_27MHZ_DEVID] !=1645 dj_dev->hdev->product) {1646 struct dj_workitem workitem = {1647 .device_index = hidpp_report->device_index,1648 .type = WORKITEM_TYPE_UNPAIRED,1649 };1650 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));1651 /* logi_hidpp_recv_queue_notif will queue the work */1652 dj_dev = NULL;1653 }1654 1655 if (dj_dev) {1656 logi_dj_recv_forward_report(dj_dev, data, size);1657 } else {1658 if (hidpp_report->sub_id == REPORT_TYPE_NOTIF_DEVICE_CONNECTED)1659 logi_hidpp_recv_queue_notif(hdev, hidpp_report);1660 else1661 logi_dj_recv_queue_unknown_work(djrcv_dev);1662 }1663 1664 spin_unlock_irqrestore(&djrcv_dev->lock, flags);1665 1666 return false;1667}1668 1669static int logi_dj_raw_event(struct hid_device *hdev,1670 struct hid_report *report, u8 *data,1671 int size)1672{1673 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);1674 dbg_hid("%s, size:%d\n", __func__, size);1675 1676 if (!djrcv_dev)1677 return 0;1678 1679 if (!hdev->report_enum[HID_INPUT_REPORT].numbered) {1680 1681 if (djrcv_dev->unnumbered_application == HID_GD_KEYBOARD) {1682 /*1683 * For the keyboard, we can reuse the same report by1684 * using the second byte which is constant in the USB1685 * HID report descriptor.1686 */1687 data[1] = data[0];1688 data[0] = REPORT_TYPE_KEYBOARD;1689 1690 logi_dj_recv_forward_input_report(hdev, data, size);1691 1692 /* restore previous state */1693 data[0] = data[1];1694 data[1] = 0;1695 }1696 /*1697 * Mouse-only receivers send unnumbered mouse data. The 27 MHz1698 * receiver uses 6 byte packets, the nano receiver 8 bytes.1699 */1700 if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&1701 size <= 8) {1702 u8 mouse_report[9];1703 1704 /* Prepend report id */1705 mouse_report[0] = REPORT_TYPE_MOUSE;1706 memcpy(mouse_report + 1, data, size);1707 logi_dj_recv_forward_input_report(hdev, mouse_report,1708 size + 1);1709 }1710 1711 return false;1712 }1713 1714 switch (data[0]) {1715 case REPORT_ID_DJ_SHORT:1716 if (size != DJREPORT_SHORT_LENGTH) {1717 hid_err(hdev, "Short DJ report bad size (%d)", size);1718 return false;1719 }1720 return logi_dj_dj_event(hdev, report, data, size);1721 case REPORT_ID_DJ_LONG:1722 if (size != DJREPORT_LONG_LENGTH) {1723 hid_err(hdev, "Long DJ report bad size (%d)", size);1724 return false;1725 }1726 return logi_dj_dj_event(hdev, report, data, size);1727 case REPORT_ID_HIDPP_SHORT:1728 if (size != HIDPP_REPORT_SHORT_LENGTH) {1729 hid_err(hdev, "Short HID++ report bad size (%d)", size);1730 return false;1731 }1732 return logi_dj_hidpp_event(hdev, report, data, size);1733 case REPORT_ID_HIDPP_LONG:1734 if (size != HIDPP_REPORT_LONG_LENGTH) {1735 hid_err(hdev, "Long HID++ report bad size (%d)", size);1736 return false;1737 }1738 return logi_dj_hidpp_event(hdev, report, data, size);1739 }1740 1741 logi_dj_recv_forward_input_report(hdev, data, size);1742 1743 return false;1744}1745 1746static int logi_dj_probe(struct hid_device *hdev,1747 const struct hid_device_id *id)1748{1749 struct hid_report_enum *rep_enum;1750 struct hid_report *rep;1751 struct dj_receiver_dev *djrcv_dev;1752 struct usb_interface *intf;1753 unsigned int no_dj_interfaces = 0;1754 bool has_hidpp = false;1755 unsigned long flags;1756 int retval;1757 1758 /*1759 * Call to usbhid to fetch the HID descriptors of the current1760 * interface subsequently call to the hid/hid-core to parse the1761 * fetched descriptors.1762 */1763 retval = hid_parse(hdev);1764 if (retval) {1765 hid_err(hdev, "%s: parse failed\n", __func__);1766 return retval;1767 }1768 1769 /*1770 * Some KVMs add an extra interface for e.g. mouse emulation. If we1771 * treat these as logitech-dj interfaces then this causes input events1772 * reported through this extra interface to not be reported correctly.1773 * To avoid this, we treat these as generic-hid devices.1774 */1775 switch (id->driver_data) {1776 case recvr_type_dj: no_dj_interfaces = 3; break;1777 case recvr_type_hidpp: no_dj_interfaces = 2; break;1778 case recvr_type_gaming_hidpp: no_dj_interfaces = 3; break;1779 case recvr_type_mouse_only: no_dj_interfaces = 2; break;1780 case recvr_type_27mhz: no_dj_interfaces = 2; break;1781 case recvr_type_bluetooth: no_dj_interfaces = 2; break;1782 case recvr_type_dinovo: no_dj_interfaces = 2; break;1783 }1784 if (hid_is_usb(hdev)) {1785 intf = to_usb_interface(hdev->dev.parent);1786 if (intf && intf->altsetting->desc.bInterfaceNumber >=1787 no_dj_interfaces) {1788 hdev->quirks |= HID_QUIRK_INPUT_PER_APP;1789 return hid_hw_start(hdev, HID_CONNECT_DEFAULT);1790 }1791 }1792 1793 rep_enum = &hdev->report_enum[HID_INPUT_REPORT];1794 1795 /* no input reports, bail out */1796 if (list_empty(&rep_enum->report_list))1797 return -ENODEV;1798 1799 /*1800 * Check for the HID++ application.1801 * Note: we should theoretically check for HID++ and DJ1802 * collections, but this will do.1803 */1804 list_for_each_entry(rep, &rep_enum->report_list, list) {1805 if (rep->application == 0xff000001)1806 has_hidpp = true;1807 }1808 1809 /*1810 * Ignore interfaces without DJ/HID++ collection, they will not carry1811 * any data, dont create any hid_device for them.1812 */1813 if (!has_hidpp && id->driver_data == recvr_type_dj)1814 return -ENODEV;1815 1816 /* get the current application attached to the node */1817 rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);1818 djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,1819 rep->application, has_hidpp);1820 if (!djrcv_dev) {1821 hid_err(hdev, "%s: dj_get_receiver_dev failed\n", __func__);1822 return -ENOMEM;1823 }1824 1825 if (!rep_enum->numbered)1826 djrcv_dev->unnumbered_application = rep->application;1827 1828 /* Starts the usb device and connects to upper interfaces hiddev and1829 * hidraw */1830 retval = hid_hw_start(hdev, HID_CONNECT_HIDRAW|HID_CONNECT_HIDDEV);1831 if (retval) {1832 hid_err(hdev, "%s: hid_hw_start returned error\n", __func__);1833 goto hid_hw_start_fail;1834 }1835 1836 if (has_hidpp) {1837 retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);1838 if (retval < 0) {1839 hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n",1840 __func__, retval);1841 goto switch_to_dj_mode_fail;1842 }1843 }1844 1845 /* This is enabling the polling urb on the IN endpoint */1846 retval = hid_hw_open(hdev);1847 if (retval < 0) {1848 hid_err(hdev, "%s: hid_hw_open returned error:%d\n",1849 __func__, retval);1850 goto llopen_failed;1851 }1852 1853 /* Allow incoming packets to arrive: */1854 hid_device_io_start(hdev);1855 1856 if (has_hidpp) {1857 spin_lock_irqsave(&djrcv_dev->lock, flags);1858 djrcv_dev->ready = true;1859 spin_unlock_irqrestore(&djrcv_dev->lock, flags);1860 retval = logi_dj_recv_query_paired_devices(djrcv_dev);1861 if (retval < 0) {1862 hid_err(hdev, "%s: logi_dj_recv_query_paired_devices error:%d\n",1863 __func__, retval);1864 /*1865 * This can happen with a KVM, let the probe succeed,1866 * logi_dj_recv_queue_unknown_work will retry later.1867 */1868 }1869 }1870 1871 return 0;1872 1873llopen_failed:1874switch_to_dj_mode_fail:1875 hid_hw_stop(hdev);1876 1877hid_hw_start_fail:1878 dj_put_receiver_dev(hdev);1879 return retval;1880}1881 1882#ifdef CONFIG_PM1883static int logi_dj_reset_resume(struct hid_device *hdev)1884{1885 int retval;1886 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);1887 1888 if (!djrcv_dev || djrcv_dev->hidpp != hdev)1889 return 0;1890 1891 retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);1892 if (retval < 0) {1893 hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n",1894 __func__, retval);1895 }1896 1897 return 0;1898}1899#endif1900 1901static void logi_dj_remove(struct hid_device *hdev)1902{1903 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);1904 struct dj_device *dj_dev;1905 unsigned long flags;1906 int i;1907 1908 dbg_hid("%s\n", __func__);1909 1910 if (!djrcv_dev)1911 return hid_hw_stop(hdev);1912 1913 /*1914 * This ensures that if the work gets requeued from another1915 * interface of the same receiver it will be a no-op.1916 */1917 spin_lock_irqsave(&djrcv_dev->lock, flags);1918 djrcv_dev->ready = false;1919 spin_unlock_irqrestore(&djrcv_dev->lock, flags);1920 1921 cancel_work_sync(&djrcv_dev->work);1922 1923 hid_hw_close(hdev);1924 hid_hw_stop(hdev);1925 1926 /*1927 * For proper operation we need access to all interfaces, so we destroy1928 * the paired devices when we're unbound from any interface.1929 *1930 * Note we may still be bound to other interfaces, sharing the same1931 * djrcv_dev, so we need locking here.1932 */1933 for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {1934 spin_lock_irqsave(&djrcv_dev->lock, flags);1935 dj_dev = djrcv_dev->paired_dj_devices[i];1936 djrcv_dev->paired_dj_devices[i] = NULL;1937 spin_unlock_irqrestore(&djrcv_dev->lock, flags);1938 if (dj_dev != NULL) {1939 hid_destroy_device(dj_dev->hdev);1940 kfree(dj_dev);1941 }1942 }1943 1944 dj_put_receiver_dev(hdev);1945}1946 1947static const struct hid_device_id logi_dj_receivers[] = {1948 { /* Logitech unifying receiver (0xc52b) */1949 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1950 USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER),1951 .driver_data = recvr_type_dj},1952 { /* Logitech unifying receiver (0xc532) */1953 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1954 USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2),1955 .driver_data = recvr_type_dj},1956 1957 { /* Logitech Nano mouse only receiver (0xc52f) */1958 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1959 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER),1960 .driver_data = recvr_type_mouse_only},1961 { /* Logitech Nano (non DJ) receiver (0xc534) */1962 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1963 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),1964 .driver_data = recvr_type_hidpp},1965 1966 { /* Logitech G700(s) receiver (0xc531) */1967 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1968 USB_DEVICE_ID_LOGITECH_G700_RECEIVER),1969 .driver_data = recvr_type_gaming_hidpp},1970 { /* Logitech G602 receiver (0xc537) */1971 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1972 0xc537),1973 .driver_data = recvr_type_gaming_hidpp},1974 { /* Logitech lightspeed receiver (0xc539) */1975 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1976 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1),1977 .driver_data = recvr_type_gaming_hidpp},1978 { /* Logitech powerplay receiver (0xc53a) */1979 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1980 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY),1981 .driver_data = recvr_type_gaming_hidpp},1982 { /* Logitech lightspeed receiver (0xc53f) */1983 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1984 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),1985 .driver_data = recvr_type_gaming_hidpp},1986 1987 { /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */1988 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),1989 .driver_data = recvr_type_27mhz},1990 { /* Logitech 27 MHz HID++ 1.0 receiver (0xc517) */1991 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1992 USB_DEVICE_ID_S510_RECEIVER_2),1993 .driver_data = recvr_type_27mhz},1994 { /* Logitech 27 MHz HID++ 1.0 mouse-only receiver (0xc51b) */1995 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,1996 USB_DEVICE_ID_LOGITECH_27MHZ_MOUSE_RECEIVER),1997 .driver_data = recvr_type_27mhz},1998 1999 { /* Logitech MX5000 HID++ / bluetooth receiver keyboard intf. (0xc70e) */2000 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2001 USB_DEVICE_ID_MX5000_RECEIVER_KBD_DEV),2002 .driver_data = recvr_type_bluetooth},2003 { /* Logitech MX5000 HID++ / bluetooth receiver mouse intf. (0xc70a) */2004 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2005 USB_DEVICE_ID_MX5000_RECEIVER_MOUSE_DEV),2006 .driver_data = recvr_type_bluetooth},2007 { /* Logitech MX5500 HID++ / bluetooth receiver keyboard intf. (0xc71b) */2008 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2009 USB_DEVICE_ID_MX5500_RECEIVER_KBD_DEV),2010 .driver_data = recvr_type_bluetooth},2011 { /* Logitech MX5500 HID++ / bluetooth receiver mouse intf. (0xc71c) */2012 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2013 USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV),2014 .driver_data = recvr_type_bluetooth},2015 2016 { /* Logitech Dinovo Edge HID++ / bluetooth receiver keyboard intf. (0xc713) */2017 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2018 USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV),2019 .driver_data = recvr_type_dinovo},2020 { /* Logitech Dinovo Edge HID++ / bluetooth receiver mouse intf. (0xc714) */2021 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2022 USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV),2023 .driver_data = recvr_type_dinovo},2024 { /* Logitech DiNovo Mini HID++ / bluetooth receiver mouse intf. (0xc71e) */2025 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2026 USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV),2027 .driver_data = recvr_type_dinovo},2028 { /* Logitech DiNovo Mini HID++ / bluetooth receiver keyboard intf. (0xc71f) */2029 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,2030 USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV),2031 .driver_data = recvr_type_dinovo},2032 {}2033};2034 2035MODULE_DEVICE_TABLE(hid, logi_dj_receivers);2036 2037static struct hid_driver logi_djreceiver_driver = {2038 .name = "logitech-djreceiver",2039 .id_table = logi_dj_receivers,2040 .probe = logi_dj_probe,2041 .remove = logi_dj_remove,2042 .raw_event = logi_dj_raw_event,2043#ifdef CONFIG_PM2044 .reset_resume = logi_dj_reset_resume,2045#endif2046};2047 2048module_hid_driver(logi_djreceiver_driver);2049 2050MODULE_DESCRIPTION("HID driver for Logitech receivers");2051MODULE_LICENSE("GPL");2052MODULE_AUTHOR("Logitech");2053MODULE_AUTHOR("Nestor Lopez Casado");2054MODULE_AUTHOR("nlopezcasad@logitech.com");2055