1
2
3
4
5
6
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>
16#include <asm/unaligned.h>
17#include "hid-ids.h"
18
19#define DJ_MAX_PAIRED_DEVICES 7
20#define DJ_MAX_NUMBER_NOTIFS 8
21#define DJ_RECEIVER_INDEX 0
22#define DJ_DEVICE_INDEX_MIN 1
23#define DJ_DEVICE_INDEX_MAX 7
24
25#define DJREPORT_SHORT_LENGTH 15
26#define DJREPORT_LONG_LENGTH 32
27
28#define REPORT_ID_DJ_SHORT 0x20
29#define REPORT_ID_DJ_LONG 0x21
30
31#define REPORT_ID_HIDPP_SHORT 0x10
32#define REPORT_ID_HIDPP_LONG 0x11
33#define REPORT_ID_HIDPP_VERY_LONG 0x12
34
35#define HIDPP_REPORT_SHORT_LENGTH 7
36#define HIDPP_REPORT_LONG_LENGTH 20
37
38#define HIDPP_RECEIVER_INDEX 0xff
39
40#define REPORT_TYPE_RFREPORT_FIRST 0x01
41#define REPORT_TYPE_RFREPORT_LAST 0x1F
42
43
44#define REPORT_TYPE_CMD_SWITCH 0x80
45#define CMD_SWITCH_PARAM_DEVBITFIELD 0x00
46#define CMD_SWITCH_PARAM_TIMEOUT_SECONDS 0x01
47#define TIMEOUT_NO_KEEPALIVE 0x00
48
49
50#define REPORT_TYPE_CMD_GET_PAIRED_DEVICES 0x81
51
52
53#define REPORT_TYPE_NOTIF_DEVICE_PAIRED 0x41
54#define SPFUNCTION_MORE_NOTIF_EXPECTED 0x01
55#define SPFUNCTION_DEVICE_LIST_EMPTY 0x02
56#define DEVICE_PAIRED_PARAM_SPFUNCTION 0x00
57#define DEVICE_PAIRED_PARAM_EQUAD_ID_LSB 0x01
58#define DEVICE_PAIRED_PARAM_EQUAD_ID_MSB 0x02
59#define DEVICE_PAIRED_RF_REPORT_TYPE 0x03
60
61
62#define REPORT_TYPE_NOTIF_DEVICE_UNPAIRED 0x40
63
64
65#define REPORT_TYPE_NOTIF_CONNECTION_STATUS 0x42
66#define CONNECTION_STATUS_PARAM_STATUS 0x00
67#define STATUS_LINKLOSS 0x01
68
69
70#define REPORT_TYPE_NOTIF_ERROR 0x7F
71#define NOTIF_ERROR_PARAM_ETYPE 0x00
72#define ETYPE_KEEPALIVE_TIMEOUT 0x01
73
74
75#define REPORT_TYPE_KEYBOARD 0x01
76#define REPORT_TYPE_MOUSE 0x02
77#define REPORT_TYPE_CONSUMER_CONTROL 0x03
78#define REPORT_TYPE_SYSTEM_CONTROL 0x04
79#define REPORT_TYPE_MEDIA_CENTER 0x08
80#define REPORT_TYPE_LEDS 0x0E
81
82
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 MEDIA_CENTER BIT(8)
88#define KBD_LEDS BIT(14)
89
90#define HIDPP BIT_ULL(63)
91
92
93#define REPORT_TYPE_NOTIF_DEVICE_CONNECTED 0x41
94#define HIDPP_PARAM_PROTO_TYPE 0x00
95#define HIDPP_PARAM_DEVICE_INFO 0x01
96#define HIDPP_PARAM_EQUAD_LSB 0x02
97#define HIDPP_PARAM_EQUAD_MSB 0x03
98#define HIDPP_PARAM_27MHZ_DEVID 0x03
99#define HIDPP_DEVICE_TYPE_MASK GENMASK(3, 0)
100#define HIDPP_LINK_STATUS_MASK BIT(6)
101#define HIDPP_MANUFACTURER_MASK BIT(7)
102
103#define HIDPP_DEVICE_TYPE_KEYBOARD 1
104#define HIDPP_DEVICE_TYPE_MOUSE 2
105
106#define HIDPP_SET_REGISTER 0x80
107#define HIDPP_GET_LONG_REGISTER 0x83
108#define HIDPP_REG_CONNECTION_STATE 0x02
109#define HIDPP_REG_PAIRING_INFORMATION 0xB5
110#define HIDPP_PAIRING_INFORMATION 0x20
111#define HIDPP_FAKE_DEVICE_ARRIVAL 0x02
112
113enum recvr_type {
114 recvr_type_dj,
115 recvr_type_hidpp,
116 recvr_type_gaming_hidpp,
117 recvr_type_mouse_only,
118 recvr_type_27mhz,
119 recvr_type_bluetooth,
120};
121
122struct dj_report {
123 u8 report_id;
124 u8 device_index;
125 u8 report_type;
126 u8 report_params[DJREPORT_SHORT_LENGTH - 3];
127};
128
129struct hidpp_event {
130 u8 report_id;
131 u8 device_index;
132 u8 sub_id;
133 u8 params[HIDPP_REPORT_LONG_LENGTH - 3U];
134} __packed;
135
136struct dj_receiver_dev {
137 struct hid_device *mouse;
138 struct hid_device *keyboard;
139 struct hid_device *hidpp;
140 struct dj_device *paired_dj_devices[DJ_MAX_PAIRED_DEVICES +
141 DJ_DEVICE_INDEX_MIN];
142 struct list_head list;
143 struct kref kref;
144 struct work_struct work;
145 struct kfifo notif_fifo;
146 unsigned long last_query;
147 bool ready;
148 enum recvr_type type;
149 unsigned int unnumbered_application;
150 spinlock_t lock;
151};
152
153struct dj_device {
154 struct hid_device *hdev;
155 struct dj_receiver_dev *dj_receiver_dev;
156 u64 reports_supported;
157 u8 device_index;
158};
159
160#define WORKITEM_TYPE_EMPTY 0
161#define WORKITEM_TYPE_PAIRED 1
162#define WORKITEM_TYPE_UNPAIRED 2
163#define WORKITEM_TYPE_UNKNOWN 255
164
165struct dj_workitem {
166 u8 type;
167 u8 device_index;
168 u8 device_type;
169 u8 quad_id_msb;
170 u8 quad_id_lsb;
171 u64 reports_supported;
172};
173
174
175static const char kbd_descriptor[] = {
176 0x05, 0x01,
177 0x09, 0x06,
178 0xA1, 0x01,
179 0x85, 0x01,
180 0x95, 0x08,
181 0x75, 0x01,
182 0x15, 0x00,
183 0x25, 0x01,
184 0x05, 0x07,
185 0x19, 0xE0,
186 0x29, 0xE7,
187 0x81, 0x02,
188 0x95, 0x06,
189 0x75, 0x08,
190 0x15, 0x00,
191 0x26, 0xFF, 0x00,
192 0x05, 0x07,
193 0x19, 0x00,
194 0x2A, 0xFF, 0x00,
195 0x81, 0x00,
196 0x85, 0x0e,
197 0x05, 0x08,
198 0x95, 0x05,
199 0x75, 0x01,
200 0x15, 0x00,
201 0x25, 0x01,
202 0x19, 0x01,
203 0x29, 0x05,
204 0x91, 0x02,
205 0x95, 0x01,
206 0x75, 0x03,
207 0x91, 0x01,
208 0xC0
209};
210
211
212static const char mse_descriptor[] = {
213 0x05, 0x01,
214 0x09, 0x02,
215 0xA1, 0x01,
216 0x85, 0x02,
217 0x09, 0x01,
218 0xA1, 0x00,
219 0x05, 0x09,
220 0x19, 0x01,
221 0x29, 0x10,
222 0x15, 0x00,
223 0x25, 0x01,
224 0x95, 0x10,
225 0x75, 0x01,
226 0x81, 0x02,
227 0x05, 0x01,
228 0x16, 0x01, 0xF8,
229 0x26, 0xFF, 0x07,
230 0x75, 0x0C,
231 0x95, 0x02,
232 0x09, 0x30,
233 0x09, 0x31,
234 0x81, 0x06,
235 0x15, 0x81,
236 0x25, 0x7F,
237 0x75, 0x08,
238 0x95, 0x01,
239 0x09, 0x38,
240 0x81, 0x06,
241 0x05, 0x0C,
242 0x0A, 0x38, 0x02,
243 0x95, 0x01,
244 0x81, 0x06,
245 0xC0,
246 0xC0,
247};
248
249
250static const char mse_27mhz_descriptor[] = {
251 0x05, 0x01,
252 0x09, 0x02,
253 0xA1, 0x01,
254 0x85, 0x02,
255 0x09, 0x01,
256 0xA1, 0x00,
257 0x05, 0x09,
258 0x19, 0x01,
259 0x29, 0x08,
260 0x15, 0x00,
261 0x25, 0x01,
262 0x95, 0x08,
263 0x75, 0x01,
264 0x81, 0x02,
265 0x05, 0x01,
266 0x16, 0x01, 0xF8,
267 0x26, 0xFF, 0x07,
268 0x75, 0x0C,
269 0x95, 0x02,
270 0x09, 0x30,
271 0x09, 0x31,
272 0x81, 0x06,
273 0x15, 0x81,
274 0x25, 0x7F,
275 0x75, 0x08,
276 0x95, 0x01,
277 0x09, 0x38,
278 0x81, 0x06,
279 0x05, 0x0C,
280 0x0A, 0x38, 0x02,
281 0x95, 0x01,
282 0x81, 0x06,
283 0xC0,
284 0xC0,
285};
286
287
288static const char mse_bluetooth_descriptor[] = {
289 0x05, 0x01,
290 0x09, 0x02,
291 0xA1, 0x01,
292 0x85, 0x02,
293 0x09, 0x01,
294 0xA1, 0x00,
295 0x05, 0x09,
296 0x19, 0x01,
297 0x29, 0x08,
298 0x15, 0x00,
299 0x25, 0x01,
300 0x95, 0x08,
301 0x75, 0x01,
302 0x81, 0x02,
303 0x05, 0x01,
304 0x16, 0x01, 0xF8,
305 0x26, 0xFF, 0x07,
306 0x75, 0x0C,
307 0x95, 0x02,
308 0x09, 0x30,
309 0x09, 0x31,
310 0x81, 0x06,
311 0x15, 0x81,
312 0x25, 0x7F,
313 0x75, 0x08,
314 0x95, 0x01,
315 0x09, 0x38,
316 0x81, 0x06,
317 0x05, 0x0C,
318 0x0A, 0x38, 0x02,
319 0x15, 0xF9,
320 0x25, 0x07,
321 0x75, 0x04,
322 0x95, 0x01,
323 0x81, 0x06,
324 0x05, 0x09,
325 0x19, 0x09,
326 0x29, 0x0C,
327 0x15, 0x00,
328 0x25, 0x01,
329 0x75, 0x01,
330 0x95, 0x04,
331 0x81, 0x06,
332 0xC0,
333 0xC0,
334};
335
336
337static const char mse_high_res_descriptor[] = {
338 0x05, 0x01,
339 0x09, 0x02,
340 0xA1, 0x01,
341 0x85, 0x02,
342 0x09, 0x01,
343 0xA1, 0x00,
344 0x05, 0x09,
345 0x19, 0x01,
346 0x29, 0x10,
347 0x15, 0x00,
348 0x25, 0x01,
349 0x95, 0x10,
350 0x75, 0x01,
351 0x81, 0x02,
352 0x05, 0x01,
353 0x16, 0x01, 0x80,
354 0x26, 0xFF, 0x7F,
355 0x75, 0x10,
356 0x95, 0x02,
357 0x09, 0x30,
358 0x09, 0x31,
359 0x81, 0x06,
360 0x15, 0x81,
361 0x25, 0x7F,
362 0x75, 0x08,
363 0x95, 0x01,
364 0x09, 0x38,
365 0x81, 0x06,
366 0x05, 0x0C,
367 0x0A, 0x38, 0x02,
368 0x95, 0x01,
369 0x81, 0x06,
370 0xC0,
371 0xC0,
372};
373
374
375static const char consumer_descriptor[] = {
376 0x05, 0x0C,
377 0x09, 0x01,
378 0xA1, 0x01,
379 0x85, 0x03,
380 0x75, 0x10,
381 0x95, 0x02,
382 0x15, 0x01,
383 0x26, 0xFF, 0x02,
384 0x19, 0x01,
385 0x2A, 0xFF, 0x02,
386 0x81, 0x00,
387 0xC0,
388};
389
390
391static const char syscontrol_descriptor[] = {
392 0x05, 0x01,
393 0x09, 0x80,
394 0xA1, 0x01,
395 0x85, 0x04,
396 0x75, 0x02,
397 0x95, 0x01,
398 0x15, 0x01,
399 0x25, 0x03,
400 0x09, 0x82,
401 0x09, 0x81,
402 0x09, 0x83,
403 0x81, 0x60,
404 0x75, 0x06,
405 0x81, 0x03,
406 0xC0,
407};
408
409
410static const char media_descriptor[] = {
411 0x06, 0xbc, 0xff,
412 0x09, 0x88,
413 0xa1, 0x01,
414 0x85, 0x08,
415 0x19, 0x01,
416 0x29, 0xff,
417 0x15, 0x01,
418 0x26, 0xff, 0x00,
419 0x75, 0x08,
420 0x95, 0x01,
421 0x81, 0x00,
422 0xc0,
423};
424
425
426static const char hidpp_descriptor[] = {
427 0x06, 0x00, 0xff,
428 0x09, 0x01,
429 0xa1, 0x01,
430 0x85, 0x10,
431 0x75, 0x08,
432 0x95, 0x06,
433 0x15, 0x00,
434 0x26, 0xff, 0x00,
435 0x09, 0x01,
436 0x81, 0x00,
437 0x09, 0x01,
438 0x91, 0x00,
439 0xc0,
440 0x06, 0x00, 0xff,
441 0x09, 0x02,
442 0xa1, 0x01,
443 0x85, 0x11,
444 0x75, 0x08,
445 0x95, 0x13,
446 0x15, 0x00,
447 0x26, 0xff, 0x00,
448 0x09, 0x02,
449 0x81, 0x00,
450 0x09, 0x02,
451 0x91, 0x00,
452 0xc0,
453 0x06, 0x00, 0xff,
454 0x09, 0x04,
455 0xa1, 0x01,
456 0x85, 0x20,
457 0x75, 0x08,
458 0x95, 0x0e,
459 0x15, 0x00,
460 0x26, 0xff, 0x00,
461 0x09, 0x41,
462 0x81, 0x00,
463 0x09, 0x41,
464 0x91, 0x00,
465 0x85, 0x21,
466 0x95, 0x1f,
467 0x15, 0x00,
468 0x26, 0xff, 0x00,
469 0x09, 0x42,
470 0x81, 0x00,
471 0x09, 0x42,
472 0x91, 0x00,
473 0xc0,
474};
475
476
477#define MAX_REPORT_SIZE 8
478
479
480#define MAX_RDESC_SIZE \
481 (sizeof(kbd_descriptor) + \
482 sizeof(mse_bluetooth_descriptor) + \
483 sizeof(consumer_descriptor) + \
484 sizeof(syscontrol_descriptor) + \
485 sizeof(media_descriptor) + \
486 sizeof(hidpp_descriptor))
487
488
489
490
491
492
493
494
495
496
497
498
499
500#define NUMBER_OF_HID_REPORTS 32
501static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = {
502 [1] = 8,
503 [2] = 8,
504 [3] = 5,
505 [4] = 2,
506 [8] = 2,
507};
508
509
510#define LOGITECH_DJ_INTERFACE_NUMBER 0x02
511
512static struct hid_ll_driver logi_dj_ll_driver;
513
514static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
515static void delayedwork_callback(struct work_struct *work);
516
517static LIST_HEAD(dj_hdev_list);
518static DEFINE_MUTEX(dj_hdev_list_lock);
519
520
521
522
523
524
525
526
527static struct dj_receiver_dev *dj_find_receiver_dev(struct hid_device *hdev,
528 enum recvr_type type)
529{
530 struct dj_receiver_dev *djrcv_dev;
531 char sep;
532
533
534
535
536
537 sep = (type == recvr_type_bluetooth) ? '.' : '/';
538
539
540 list_for_each_entry(djrcv_dev, &dj_hdev_list, list) {
541 if (djrcv_dev->mouse &&
542 hid_compare_device_paths(hdev, djrcv_dev->mouse, sep)) {
543 kref_get(&djrcv_dev->kref);
544 return djrcv_dev;
545 }
546 if (djrcv_dev->keyboard &&
547 hid_compare_device_paths(hdev, djrcv_dev->keyboard, sep)) {
548 kref_get(&djrcv_dev->kref);
549 return djrcv_dev;
550 }
551 if (djrcv_dev->hidpp &&
552 hid_compare_device_paths(hdev, djrcv_dev->hidpp, sep)) {
553 kref_get(&djrcv_dev->kref);
554 return djrcv_dev;
555 }
556 }
557
558 return NULL;
559}
560
561static void dj_release_receiver_dev(struct kref *kref)
562{
563 struct dj_receiver_dev *djrcv_dev = container_of(kref, struct dj_receiver_dev, kref);
564
565 list_del(&djrcv_dev->list);
566 kfifo_free(&djrcv_dev->notif_fifo);
567 kfree(djrcv_dev);
568}
569
570static void dj_put_receiver_dev(struct hid_device *hdev)
571{
572 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
573
574 mutex_lock(&dj_hdev_list_lock);
575
576 if (djrcv_dev->mouse == hdev)
577 djrcv_dev->mouse = NULL;
578 if (djrcv_dev->keyboard == hdev)
579 djrcv_dev->keyboard = NULL;
580 if (djrcv_dev->hidpp == hdev)
581 djrcv_dev->hidpp = NULL;
582
583 kref_put(&djrcv_dev->kref, dj_release_receiver_dev);
584
585 mutex_unlock(&dj_hdev_list_lock);
586}
587
588static struct dj_receiver_dev *dj_get_receiver_dev(struct hid_device *hdev,
589 enum recvr_type type,
590 unsigned int application,
591 bool is_hidpp)
592{
593 struct dj_receiver_dev *djrcv_dev;
594
595 mutex_lock(&dj_hdev_list_lock);
596
597 djrcv_dev = dj_find_receiver_dev(hdev, type);
598 if (!djrcv_dev) {
599 djrcv_dev = kzalloc(sizeof(*djrcv_dev), GFP_KERNEL);
600 if (!djrcv_dev)
601 goto out;
602
603 INIT_WORK(&djrcv_dev->work, delayedwork_callback);
604 spin_lock_init(&djrcv_dev->lock);
605 if (kfifo_alloc(&djrcv_dev->notif_fifo,
606 DJ_MAX_NUMBER_NOTIFS * sizeof(struct dj_workitem),
607 GFP_KERNEL)) {
608 kfree(djrcv_dev);
609 djrcv_dev = NULL;
610 goto out;
611 }
612 kref_init(&djrcv_dev->kref);
613 list_add_tail(&djrcv_dev->list, &dj_hdev_list);
614 djrcv_dev->last_query = jiffies;
615 djrcv_dev->type = type;
616 }
617
618 if (application == HID_GD_KEYBOARD)
619 djrcv_dev->keyboard = hdev;
620 if (application == HID_GD_MOUSE)
621 djrcv_dev->mouse = hdev;
622 if (is_hidpp)
623 djrcv_dev->hidpp = hdev;
624
625 hid_set_drvdata(hdev, djrcv_dev);
626out:
627 mutex_unlock(&dj_hdev_list_lock);
628 return djrcv_dev;
629}
630
631static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
632 struct dj_workitem *workitem)
633{
634
635 struct dj_device *dj_dev;
636 unsigned long flags;
637
638 spin_lock_irqsave(&djrcv_dev->lock, flags);
639 dj_dev = djrcv_dev->paired_dj_devices[workitem->device_index];
640 djrcv_dev->paired_dj_devices[workitem->device_index] = NULL;
641 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
642
643 if (dj_dev != NULL) {
644 hid_destroy_device(dj_dev->hdev);
645 kfree(dj_dev);
646 } else {
647 hid_err(djrcv_dev->hidpp, "%s: can't destroy a NULL device\n",
648 __func__);
649 }
650}
651
652static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
653 struct dj_workitem *workitem)
654{
655
656 struct hid_device *djrcv_hdev = djrcv_dev->hidpp;
657 struct hid_device *dj_hiddev;
658 struct dj_device *dj_dev;
659 u8 device_index = workitem->device_index;
660 unsigned long flags;
661
662
663
664
665 unsigned char tmpstr[3];
666
667
668 if (djrcv_dev->paired_dj_devices[device_index]) {
669
670 dbg_hid("%s: device is already known\n", __func__);
671 return;
672 }
673
674 dj_hiddev = hid_allocate_device();
675 if (IS_ERR(dj_hiddev)) {
676 hid_err(djrcv_hdev, "%s: hid_allocate_dev failed\n", __func__);
677 return;
678 }
679
680 dj_hiddev->ll_driver = &logi_dj_ll_driver;
681
682 dj_hiddev->dev.parent = &djrcv_hdev->dev;
683 dj_hiddev->bus = BUS_USB;
684 dj_hiddev->vendor = djrcv_hdev->vendor;
685 dj_hiddev->product = (workitem->quad_id_msb << 8) |
686 workitem->quad_id_lsb;
687 if (workitem->device_type) {
688 const char *type_str = "Device";
689
690 switch (workitem->device_type) {
691 case 0x01: type_str = "Keyboard"; break;
692 case 0x02: type_str = "Mouse"; break;
693 case 0x03: type_str = "Numpad"; break;
694 case 0x04: type_str = "Presenter"; break;
695 case 0x07: type_str = "Remote Control"; break;
696 case 0x08: type_str = "Trackball"; break;
697 case 0x09: type_str = "Touchpad"; break;
698 }
699 snprintf(dj_hiddev->name, sizeof(dj_hiddev->name),
700 "Logitech Wireless %s PID:%04x",
701 type_str, dj_hiddev->product);
702 } else {
703 snprintf(dj_hiddev->name, sizeof(dj_hiddev->name),
704 "Logitech Wireless Device PID:%04x",
705 dj_hiddev->product);
706 }
707
708 if (djrcv_dev->type == recvr_type_27mhz)
709 dj_hiddev->group = HID_GROUP_LOGITECH_27MHZ_DEVICE;
710 else
711 dj_hiddev->group = HID_GROUP_LOGITECH_DJ_DEVICE;
712
713 memcpy(dj_hiddev->phys, djrcv_hdev->phys, sizeof(djrcv_hdev->phys));
714 snprintf(tmpstr, sizeof(tmpstr), ":%d", device_index);
715 strlcat(dj_hiddev->phys, tmpstr, sizeof(dj_hiddev->phys));
716
717 dj_dev = kzalloc(sizeof(struct dj_device), GFP_KERNEL);
718
719 if (!dj_dev) {
720 hid_err(djrcv_hdev, "%s: failed allocating dj_dev\n", __func__);
721 goto dj_device_allocate_fail;
722 }
723
724 dj_dev->reports_supported = workitem->reports_supported;
725 dj_dev->hdev = dj_hiddev;
726 dj_dev->dj_receiver_dev = djrcv_dev;
727 dj_dev->device_index = device_index;
728 dj_hiddev->driver_data = dj_dev;
729
730 spin_lock_irqsave(&djrcv_dev->lock, flags);
731 djrcv_dev->paired_dj_devices[device_index] = dj_dev;
732 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
733
734 if (hid_add_device(dj_hiddev)) {
735 hid_err(djrcv_hdev, "%s: failed adding dj_device\n", __func__);
736 goto hid_add_device_fail;
737 }
738
739 return;
740
741hid_add_device_fail:
742 spin_lock_irqsave(&djrcv_dev->lock, flags);
743 djrcv_dev->paired_dj_devices[device_index] = NULL;
744 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
745 kfree(dj_dev);
746dj_device_allocate_fail:
747 hid_destroy_device(dj_hiddev);
748}
749
750static void delayedwork_callback(struct work_struct *work)
751{
752 struct dj_receiver_dev *djrcv_dev =
753 container_of(work, struct dj_receiver_dev, work);
754
755 struct dj_workitem workitem;
756 unsigned long flags;
757 int count;
758 int retval;
759
760 dbg_hid("%s\n", __func__);
761
762 spin_lock_irqsave(&djrcv_dev->lock, flags);
763
764
765
766
767
768 if (!djrcv_dev->ready) {
769 pr_warn("%s: delayedwork queued before hidpp interface was enumerated\n",
770 __func__);
771 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
772 return;
773 }
774
775 count = kfifo_out(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));
776
777 if (count != sizeof(workitem)) {
778 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
779 return;
780 }
781
782 if (!kfifo_is_empty(&djrcv_dev->notif_fifo))
783 schedule_work(&djrcv_dev->work);
784
785 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
786
787 switch (workitem.type) {
788 case WORKITEM_TYPE_PAIRED:
789 logi_dj_recv_add_djhid_device(djrcv_dev, &workitem);
790 break;
791 case WORKITEM_TYPE_UNPAIRED:
792 logi_dj_recv_destroy_djhid_device(djrcv_dev, &workitem);
793 break;
794 case WORKITEM_TYPE_UNKNOWN:
795 retval = logi_dj_recv_query_paired_devices(djrcv_dev);
796 if (retval) {
797 hid_err(djrcv_dev->hidpp, "%s: logi_dj_recv_query_paired_devices error: %d\n",
798 __func__, retval);
799 }
800 break;
801 case WORKITEM_TYPE_EMPTY:
802 dbg_hid("%s: device list is empty\n", __func__);
803 break;
804 }
805}
806
807
808
809
810
811
812
813
814
815
816
817
818
819static void logi_dj_recv_queue_unknown_work(struct dj_receiver_dev *djrcv_dev)
820{
821 struct dj_workitem workitem = { .type = WORKITEM_TYPE_UNKNOWN };
822
823
824 if (time_before(jiffies, djrcv_dev->last_query + HZ / 2))
825 return;
826
827 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));
828 schedule_work(&djrcv_dev->work);
829}
830
831static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
832 struct dj_report *dj_report)
833{
834
835 struct dj_workitem workitem = {
836 .device_index = dj_report->device_index,
837 };
838
839 switch (dj_report->report_type) {
840 case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
841 workitem.type = WORKITEM_TYPE_PAIRED;
842 if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
843 SPFUNCTION_DEVICE_LIST_EMPTY) {
844 workitem.type = WORKITEM_TYPE_EMPTY;
845 break;
846 }
847 fallthrough;
848 case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
849 workitem.quad_id_msb =
850 dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_MSB];
851 workitem.quad_id_lsb =
852 dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB];
853 workitem.reports_supported = get_unaligned_le32(
854 dj_report->report_params +
855 DEVICE_PAIRED_RF_REPORT_TYPE);
856 workitem.reports_supported |= HIDPP;
857 if (dj_report->report_type == REPORT_TYPE_NOTIF_DEVICE_UNPAIRED)
858 workitem.type = WORKITEM_TYPE_UNPAIRED;
859 break;
860 default:
861 logi_dj_recv_queue_unknown_work(djrcv_dev);
862 return;
863 }
864
865 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));
866 schedule_work(&djrcv_dev->work);
867}
868
869static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
870 struct hidpp_event *hidpp_report,
871 struct dj_workitem *workitem)
872{
873 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
874
875 workitem->type = WORKITEM_TYPE_PAIRED;
876 workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
877 HIDPP_DEVICE_TYPE_MASK;
878 workitem->quad_id_msb = hidpp_report->params[HIDPP_PARAM_EQUAD_MSB];
879 workitem->quad_id_lsb = hidpp_report->params[HIDPP_PARAM_EQUAD_LSB];
880 switch (workitem->device_type) {
881 case REPORT_TYPE_KEYBOARD:
882 workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA |
883 POWER_KEYS | MEDIA_CENTER |
884 HIDPP;
885 break;
886 case REPORT_TYPE_MOUSE:
887 workitem->reports_supported |= STD_MOUSE | HIDPP;
888 if (djrcv_dev->type == recvr_type_mouse_only)
889 workitem->reports_supported |= MULTIMEDIA;
890 break;
891 }
892}
893
894static void logi_hidpp_dev_conn_notif_27mhz(struct hid_device *hdev,
895 struct hidpp_event *hidpp_report,
896 struct dj_workitem *workitem)
897{
898 workitem->type = WORKITEM_TYPE_PAIRED;
899 workitem->quad_id_lsb = hidpp_report->params[HIDPP_PARAM_27MHZ_DEVID];
900 switch (hidpp_report->device_index) {
901 case 1:
902 case 2:
903 workitem->device_type = HIDPP_DEVICE_TYPE_MOUSE;
904 workitem->reports_supported |= STD_MOUSE | HIDPP;
905 break;
906 case 3:
907 case 4:
908 workitem->device_type = HIDPP_DEVICE_TYPE_KEYBOARD;
909 workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA |
910 POWER_KEYS | HIDPP;
911 break;
912 default:
913 hid_warn(hdev, "%s: unexpected device-index %d", __func__,
914 hidpp_report->device_index);
915 }
916}
917
918static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
919 struct hidpp_event *hidpp_report)
920{
921
922 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
923 const char *device_type = "UNKNOWN";
924 struct dj_workitem workitem = {
925 .type = WORKITEM_TYPE_EMPTY,
926 .device_index = hidpp_report->device_index,
927 };
928
929 switch (hidpp_report->params[HIDPP_PARAM_PROTO_TYPE]) {
930 case 0x01:
931 device_type = "Bluetooth";
932
933 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
934 if (!(hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
935 HIDPP_MANUFACTURER_MASK)) {
936 hid_info(hdev, "Non Logitech device connected on slot %d\n",
937 hidpp_report->device_index);
938 workitem.reports_supported &= ~HIDPP;
939 }
940 break;
941 case 0x02:
942 device_type = "27 Mhz";
943 logi_hidpp_dev_conn_notif_27mhz(hdev, hidpp_report, &workitem);
944 break;
945 case 0x03:
946 device_type = "QUAD or eQUAD";
947 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
948 break;
949 case 0x04:
950 device_type = "eQUAD step 4 DJ";
951 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
952 break;
953 case 0x05:
954 device_type = "DFU Lite";
955 break;
956 case 0x06:
957 device_type = "eQUAD step 4 Lite";
958 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
959 break;
960 case 0x07:
961 device_type = "eQUAD step 4 Gaming";
962 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
963 break;
964 case 0x08:
965 device_type = "eQUAD step 4 for gamepads";
966 break;
967 case 0x0a:
968 device_type = "eQUAD nano Lite";
969 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
970 break;
971 case 0x0c:
972 device_type = "eQUAD Lightspeed 1";
973 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
974 workitem.reports_supported |= STD_KEYBOARD;
975 break;
976 case 0x0d:
977 device_type = "eQUAD Lightspeed 1_1";
978 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
979 workitem.reports_supported |= STD_KEYBOARD;
980 break;
981 }
982
983
984 if (hidpp_report->device_index == 7) {
985 workitem.reports_supported |= HIDPP;
986 }
987
988 if (workitem.type == WORKITEM_TYPE_EMPTY) {
989 hid_warn(hdev,
990 "unusable device of type %s (0x%02x) connected on slot %d",
991 device_type,
992 hidpp_report->params[HIDPP_PARAM_PROTO_TYPE],
993 hidpp_report->device_index);
994 return;
995 }
996
997 hid_info(hdev, "device of type %s (0x%02x) connected on slot %d",
998 device_type, hidpp_report->params[HIDPP_PARAM_PROTO_TYPE],
999 hidpp_report->device_index);
1000
1001 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));
1002 schedule_work(&djrcv_dev->work);
1003}
1004
1005static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
1006 struct dj_report *dj_report)
1007{
1008
1009 unsigned int i;
1010 u8 reportbuffer[MAX_REPORT_SIZE];
1011 struct dj_device *djdev;
1012
1013 djdev = djrcv_dev->paired_dj_devices[dj_report->device_index];
1014
1015 memset(reportbuffer, 0, sizeof(reportbuffer));
1016
1017 for (i = 0; i < NUMBER_OF_HID_REPORTS; i++) {
1018 if (djdev->reports_supported & (1 << i)) {
1019 reportbuffer[0] = i;
1020 if (hid_input_report(djdev->hdev,
1021 HID_INPUT_REPORT,
1022 reportbuffer,
1023 hid_reportid_size_map[i], 1)) {
1024 dbg_hid("hid_input_report error sending null "
1025 "report\n");
1026 }
1027 }
1028 }
1029}
1030
1031static void logi_dj_recv_forward_dj(struct dj_receiver_dev *djrcv_dev,
1032 struct dj_report *dj_report)
1033{
1034
1035 struct dj_device *dj_device;
1036
1037 dj_device = djrcv_dev->paired_dj_devices[dj_report->device_index];
1038
1039 if ((dj_report->report_type > ARRAY_SIZE(hid_reportid_size_map) - 1) ||
1040 (hid_reportid_size_map[dj_report->report_type] == 0)) {
1041 dbg_hid("invalid report type:%x\n", dj_report->report_type);
1042 return;
1043 }
1044
1045 if (hid_input_report(dj_device->hdev,
1046 HID_INPUT_REPORT, &dj_report->report_type,
1047 hid_reportid_size_map[dj_report->report_type], 1)) {
1048 dbg_hid("hid_input_report error\n");
1049 }
1050}
1051
1052static void logi_dj_recv_forward_report(struct dj_device *dj_dev, u8 *data,
1053 int size)
1054{
1055
1056 if (hid_input_report(dj_dev->hdev, HID_INPUT_REPORT, data, size, 1))
1057 dbg_hid("hid_input_report error\n");
1058}
1059
1060static void logi_dj_recv_forward_input_report(struct hid_device *hdev,
1061 u8 *data, int size)
1062{
1063 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1064 struct dj_device *dj_dev;
1065 unsigned long flags;
1066 u8 report = data[0];
1067 int i;
1068
1069 if (report > REPORT_TYPE_RFREPORT_LAST) {
1070 hid_err(hdev, "Unexpected input report number %d\n", report);
1071 return;
1072 }
1073
1074 spin_lock_irqsave(&djrcv_dev->lock, flags);
1075 for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {
1076 dj_dev = djrcv_dev->paired_dj_devices[i];
1077 if (dj_dev && (dj_dev->reports_supported & BIT(report))) {
1078 logi_dj_recv_forward_report(dj_dev, data, size);
1079 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1080 return;
1081 }
1082 }
1083
1084 logi_dj_recv_queue_unknown_work(djrcv_dev);
1085 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1086
1087 dbg_hid("No dj-devs handling input report number %d\n", report);
1088}
1089
1090static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
1091 struct dj_report *dj_report)
1092{
1093 struct hid_device *hdev = djrcv_dev->hidpp;
1094 struct hid_report *report;
1095 struct hid_report_enum *output_report_enum;
1096 u8 *data = (u8 *)(&dj_report->device_index);
1097 unsigned int i;
1098
1099 output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
1100 report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
1101
1102 if (!report) {
1103 hid_err(hdev, "%s: unable to find dj report\n", __func__);
1104 return -ENODEV;
1105 }
1106
1107 for (i = 0; i < DJREPORT_SHORT_LENGTH - 1; i++)
1108 report->field[0]->value[i] = data[i];
1109
1110 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1111
1112 return 0;
1113}
1114
1115static int logi_dj_recv_query_hidpp_devices(struct dj_receiver_dev *djrcv_dev)
1116{
1117 static const u8 template[] = {
1118 REPORT_ID_HIDPP_SHORT,
1119 HIDPP_RECEIVER_INDEX,
1120 HIDPP_SET_REGISTER,
1121 HIDPP_REG_CONNECTION_STATE,
1122 HIDPP_FAKE_DEVICE_ARRIVAL,
1123 0x00, 0x00
1124 };
1125 u8 *hidpp_report;
1126 int retval;
1127
1128 hidpp_report = kmemdup(template, sizeof(template), GFP_KERNEL);
1129 if (!hidpp_report)
1130 return -ENOMEM;
1131
1132 retval = hid_hw_raw_request(djrcv_dev->hidpp,
1133 REPORT_ID_HIDPP_SHORT,
1134 hidpp_report, sizeof(template),
1135 HID_OUTPUT_REPORT,
1136 HID_REQ_SET_REPORT);
1137
1138 kfree(hidpp_report);
1139 return (retval < 0) ? retval : 0;
1140}
1141
1142static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
1143{
1144 struct dj_report *dj_report;
1145 int retval;
1146
1147 djrcv_dev->last_query = jiffies;
1148
1149 if (djrcv_dev->type != recvr_type_dj)
1150 return logi_dj_recv_query_hidpp_devices(djrcv_dev);
1151
1152 dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
1153 if (!dj_report)
1154 return -ENOMEM;
1155 dj_report->report_id = REPORT_ID_DJ_SHORT;
1156 dj_report->device_index = HIDPP_RECEIVER_INDEX;
1157 dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES;
1158 retval = logi_dj_recv_send_report(djrcv_dev, dj_report);
1159 kfree(dj_report);
1160 return retval;
1161}
1162
1163
1164static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
1165 unsigned timeout)
1166{
1167 struct hid_device *hdev = djrcv_dev->hidpp;
1168 struct dj_report *dj_report;
1169 u8 *buf;
1170 int retval = 0;
1171
1172 dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
1173 if (!dj_report)
1174 return -ENOMEM;
1175
1176 if (djrcv_dev->type == recvr_type_dj) {
1177 dj_report->report_id = REPORT_ID_DJ_SHORT;
1178 dj_report->device_index = HIDPP_RECEIVER_INDEX;
1179 dj_report->report_type = REPORT_TYPE_CMD_SWITCH;
1180 dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F;
1181 dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] =
1182 (u8)timeout;
1183
1184 retval = logi_dj_recv_send_report(djrcv_dev, dj_report);
1185
1186
1187
1188
1189
1190
1191
1192 msleep(50);
1193 }
1194
1195
1196
1197
1198
1199
1200
1201
1202 buf = (u8 *)dj_report;
1203
1204 memset(buf, 0, HIDPP_REPORT_SHORT_LENGTH);
1205
1206 buf[0] = REPORT_ID_HIDPP_SHORT;
1207 buf[1] = HIDPP_RECEIVER_INDEX;
1208 buf[2] = 0x80;
1209 buf[3] = 0x00;
1210 buf[4] = 0x00;
1211 buf[5] = 0x09;
1212 buf[6] = 0x00;
1213
1214 hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
1215 HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,
1216 HID_REQ_SET_REPORT);
1217
1218 kfree(dj_report);
1219 return retval;
1220}
1221
1222
1223static int logi_dj_ll_open(struct hid_device *hid)
1224{
1225 dbg_hid("%s: %s\n", __func__, hid->phys);
1226 return 0;
1227
1228}
1229
1230static void logi_dj_ll_close(struct hid_device *hid)
1231{
1232 dbg_hid("%s: %s\n", __func__, hid->phys);
1233}
1234
1235
1236
1237
1238
1239static u8 unifying_pairing_query[] = { REPORT_ID_HIDPP_SHORT,
1240 HIDPP_RECEIVER_INDEX,
1241 HIDPP_GET_LONG_REGISTER,
1242 HIDPP_REG_PAIRING_INFORMATION };
1243static u8 unifying_pairing_answer[] = { REPORT_ID_HIDPP_LONG,
1244 HIDPP_RECEIVER_INDEX,
1245 HIDPP_GET_LONG_REGISTER,
1246 HIDPP_REG_PAIRING_INFORMATION };
1247
1248static int logi_dj_ll_raw_request(struct hid_device *hid,
1249 unsigned char reportnum, __u8 *buf,
1250 size_t count, unsigned char report_type,
1251 int reqtype)
1252{
1253 struct dj_device *djdev = hid->driver_data;
1254 struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev;
1255 u8 *out_buf;
1256 int ret;
1257
1258 if ((buf[0] == REPORT_ID_HIDPP_SHORT) ||
1259 (buf[0] == REPORT_ID_HIDPP_LONG) ||
1260 (buf[0] == REPORT_ID_HIDPP_VERY_LONG)) {
1261 if (count < 2)
1262 return -EINVAL;
1263
1264
1265
1266 if (count == 7 && !memcmp(buf, unifying_pairing_query,
1267 sizeof(unifying_pairing_query)))
1268 buf[4] = (buf[4] & 0xf0) | (djdev->device_index - 1);
1269 else
1270 buf[1] = djdev->device_index;
1271 return hid_hw_raw_request(djrcv_dev->hidpp, reportnum, buf,
1272 count, report_type, reqtype);
1273 }
1274
1275 if (buf[0] != REPORT_TYPE_LEDS)
1276 return -EINVAL;
1277
1278 if (djrcv_dev->type != recvr_type_dj && count >= 2) {
1279 if (!djrcv_dev->keyboard) {
1280 hid_warn(hid, "Received REPORT_TYPE_LEDS request before the keyboard interface was enumerated\n");
1281 return 0;
1282 }
1283
1284 return hid_hw_raw_request(djrcv_dev->keyboard, 0, buf, count,
1285 report_type, reqtype);
1286 }
1287
1288 out_buf = kzalloc(DJREPORT_SHORT_LENGTH, GFP_ATOMIC);
1289 if (!out_buf)
1290 return -ENOMEM;
1291
1292 if (count > DJREPORT_SHORT_LENGTH - 2)
1293 count = DJREPORT_SHORT_LENGTH - 2;
1294
1295 out_buf[0] = REPORT_ID_DJ_SHORT;
1296 out_buf[1] = djdev->device_index;
1297 memcpy(out_buf + 2, buf, count);
1298
1299 ret = hid_hw_raw_request(djrcv_dev->hidpp, out_buf[0], out_buf,
1300 DJREPORT_SHORT_LENGTH, report_type, reqtype);
1301
1302 kfree(out_buf);
1303 return ret;
1304}
1305
1306static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)
1307{
1308 memcpy(rdesc + *rsize, data, size);
1309 *rsize += size;
1310}
1311
1312static int logi_dj_ll_parse(struct hid_device *hid)
1313{
1314 struct dj_device *djdev = hid->driver_data;
1315 unsigned int rsize = 0;
1316 char *rdesc;
1317 int retval;
1318
1319 dbg_hid("%s\n", __func__);
1320
1321 djdev->hdev->version = 0x0111;
1322 djdev->hdev->country = 0x00;
1323
1324 rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL);
1325 if (!rdesc)
1326 return -ENOMEM;
1327
1328 if (djdev->reports_supported & STD_KEYBOARD) {
1329 dbg_hid("%s: sending a kbd descriptor, reports_supported: %llx\n",
1330 __func__, djdev->reports_supported);
1331 rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
1332 }
1333
1334 if (djdev->reports_supported & STD_MOUSE) {
1335 dbg_hid("%s: sending a mouse descriptor, reports_supported: %llx\n",
1336 __func__, djdev->reports_supported);
1337 if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp ||
1338 djdev->dj_receiver_dev->type == recvr_type_mouse_only)
1339 rdcat(rdesc, &rsize, mse_high_res_descriptor,
1340 sizeof(mse_high_res_descriptor));
1341 else if (djdev->dj_receiver_dev->type == recvr_type_27mhz)
1342 rdcat(rdesc, &rsize, mse_27mhz_descriptor,
1343 sizeof(mse_27mhz_descriptor));
1344 else if (djdev->dj_receiver_dev->type == recvr_type_bluetooth)
1345 rdcat(rdesc, &rsize, mse_bluetooth_descriptor,
1346 sizeof(mse_bluetooth_descriptor));
1347 else
1348 rdcat(rdesc, &rsize, mse_descriptor,
1349 sizeof(mse_descriptor));
1350 }
1351
1352 if (djdev->reports_supported & MULTIMEDIA) {
1353 dbg_hid("%s: sending a multimedia report descriptor: %llx\n",
1354 __func__, djdev->reports_supported);
1355 rdcat(rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
1356 }
1357
1358 if (djdev->reports_supported & POWER_KEYS) {
1359 dbg_hid("%s: sending a power keys report descriptor: %llx\n",
1360 __func__, djdev->reports_supported);
1361 rdcat(rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
1362 }
1363
1364 if (djdev->reports_supported & MEDIA_CENTER) {
1365 dbg_hid("%s: sending a media center report descriptor: %llx\n",
1366 __func__, djdev->reports_supported);
1367 rdcat(rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
1368 }
1369
1370 if (djdev->reports_supported & KBD_LEDS) {
1371 dbg_hid("%s: need to send kbd leds report descriptor: %llx\n",
1372 __func__, djdev->reports_supported);
1373 }
1374
1375 if (djdev->reports_supported & HIDPP) {
1376 dbg_hid("%s: sending a HID++ descriptor, reports_supported: %llx\n",
1377 __func__, djdev->reports_supported);
1378 rdcat(rdesc, &rsize, hidpp_descriptor,
1379 sizeof(hidpp_descriptor));
1380 }
1381
1382 retval = hid_parse_report(hid, rdesc, rsize);
1383 kfree(rdesc);
1384
1385 return retval;
1386}
1387
1388static int logi_dj_ll_start(struct hid_device *hid)
1389{
1390 dbg_hid("%s\n", __func__);
1391 return 0;
1392}
1393
1394static void logi_dj_ll_stop(struct hid_device *hid)
1395{
1396 dbg_hid("%s\n", __func__);
1397}
1398
1399
1400static struct hid_ll_driver logi_dj_ll_driver = {
1401 .parse = logi_dj_ll_parse,
1402 .start = logi_dj_ll_start,
1403 .stop = logi_dj_ll_stop,
1404 .open = logi_dj_ll_open,
1405 .close = logi_dj_ll_close,
1406 .raw_request = logi_dj_ll_raw_request,
1407};
1408
1409static int logi_dj_dj_event(struct hid_device *hdev,
1410 struct hid_report *report, u8 *data,
1411 int size)
1412{
1413 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1414 struct dj_report *dj_report = (struct dj_report *) data;
1415 unsigned long flags;
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
1436 (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
1437
1438
1439
1440
1441
1442 if (dj_report->device_index != DJ_RECEIVER_INDEX)
1443 hid_err(hdev, "%s: invalid device index:%d\n",
1444 __func__, dj_report->device_index);
1445 return false;
1446 }
1447
1448 spin_lock_irqsave(&djrcv_dev->lock, flags);
1449
1450 if (!djrcv_dev->paired_dj_devices[dj_report->device_index]) {
1451
1452 logi_dj_recv_queue_notification(djrcv_dev, dj_report);
1453 goto out;
1454 }
1455
1456 switch (dj_report->report_type) {
1457 case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
1458
1459 break;
1460 case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
1461 logi_dj_recv_queue_notification(djrcv_dev, dj_report);
1462 break;
1463 case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
1464 if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
1465 STATUS_LINKLOSS) {
1466 logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
1467 }
1468 break;
1469 default:
1470 logi_dj_recv_forward_dj(djrcv_dev, dj_report);
1471 }
1472
1473out:
1474 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1475
1476 return true;
1477}
1478
1479static int logi_dj_hidpp_event(struct hid_device *hdev,
1480 struct hid_report *report, u8 *data,
1481 int size)
1482{
1483 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1484 struct hidpp_event *hidpp_report = (struct hidpp_event *) data;
1485 struct dj_device *dj_dev;
1486 unsigned long flags;
1487 u8 device_index = hidpp_report->device_index;
1488
1489 if (device_index == HIDPP_RECEIVER_INDEX) {
1490
1491
1492 if (size == HIDPP_REPORT_LONG_LENGTH &&
1493 !memcmp(data, unifying_pairing_answer,
1494 sizeof(unifying_pairing_answer)))
1495 device_index = (data[4] & 0x0F) + 1;
1496 else
1497 return false;
1498 }
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508 if ((device_index < DJ_DEVICE_INDEX_MIN) ||
1509 (device_index > DJ_DEVICE_INDEX_MAX)) {
1510
1511
1512
1513
1514
1515 hid_err(hdev, "%s: invalid device index:%d\n", __func__,
1516 hidpp_report->device_index);
1517 return false;
1518 }
1519
1520 spin_lock_irqsave(&djrcv_dev->lock, flags);
1521
1522 dj_dev = djrcv_dev->paired_dj_devices[device_index];
1523
1524
1525
1526
1527
1528 if (djrcv_dev->type == recvr_type_27mhz && dj_dev &&
1529 hidpp_report->sub_id == REPORT_TYPE_NOTIF_DEVICE_CONNECTED &&
1530 hidpp_report->params[HIDPP_PARAM_PROTO_TYPE] == 0x02 &&
1531 hidpp_report->params[HIDPP_PARAM_27MHZ_DEVID] !=
1532 dj_dev->hdev->product) {
1533 struct dj_workitem workitem = {
1534 .device_index = hidpp_report->device_index,
1535 .type = WORKITEM_TYPE_UNPAIRED,
1536 };
1537 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));
1538
1539 dj_dev = NULL;
1540 }
1541
1542 if (dj_dev) {
1543 logi_dj_recv_forward_report(dj_dev, data, size);
1544 } else {
1545 if (hidpp_report->sub_id == REPORT_TYPE_NOTIF_DEVICE_CONNECTED)
1546 logi_hidpp_recv_queue_notif(hdev, hidpp_report);
1547 else
1548 logi_dj_recv_queue_unknown_work(djrcv_dev);
1549 }
1550
1551 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1552
1553 return false;
1554}
1555
1556static int logi_dj_raw_event(struct hid_device *hdev,
1557 struct hid_report *report, u8 *data,
1558 int size)
1559{
1560 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1561 dbg_hid("%s, size:%d\n", __func__, size);
1562
1563 if (!djrcv_dev)
1564 return 0;
1565
1566 if (!hdev->report_enum[HID_INPUT_REPORT].numbered) {
1567
1568 if (djrcv_dev->unnumbered_application == HID_GD_KEYBOARD) {
1569
1570
1571
1572
1573
1574 data[1] = data[0];
1575 data[0] = REPORT_TYPE_KEYBOARD;
1576
1577 logi_dj_recv_forward_input_report(hdev, data, size);
1578
1579
1580 data[0] = data[1];
1581 data[1] = 0;
1582 }
1583
1584
1585
1586
1587 if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
1588 size <= 8) {
1589 u8 mouse_report[9];
1590
1591
1592 mouse_report[0] = REPORT_TYPE_MOUSE;
1593 memcpy(mouse_report + 1, data, size);
1594 logi_dj_recv_forward_input_report(hdev, mouse_report,
1595 size + 1);
1596 }
1597
1598 return false;
1599 }
1600
1601 switch (data[0]) {
1602 case REPORT_ID_DJ_SHORT:
1603 if (size != DJREPORT_SHORT_LENGTH) {
1604 hid_err(hdev, "Short DJ report bad size (%d)", size);
1605 return false;
1606 }
1607 return logi_dj_dj_event(hdev, report, data, size);
1608 case REPORT_ID_DJ_LONG:
1609 if (size != DJREPORT_LONG_LENGTH) {
1610 hid_err(hdev, "Long DJ report bad size (%d)", size);
1611 return false;
1612 }
1613 return logi_dj_dj_event(hdev, report, data, size);
1614 case REPORT_ID_HIDPP_SHORT:
1615 if (size != HIDPP_REPORT_SHORT_LENGTH) {
1616 hid_err(hdev, "Short HID++ report bad size (%d)", size);
1617 return false;
1618 }
1619 return logi_dj_hidpp_event(hdev, report, data, size);
1620 case REPORT_ID_HIDPP_LONG:
1621 if (size != HIDPP_REPORT_LONG_LENGTH) {
1622 hid_err(hdev, "Long HID++ report bad size (%d)", size);
1623 return false;
1624 }
1625 return logi_dj_hidpp_event(hdev, report, data, size);
1626 }
1627
1628 logi_dj_recv_forward_input_report(hdev, data, size);
1629
1630 return false;
1631}
1632
1633static int logi_dj_probe(struct hid_device *hdev,
1634 const struct hid_device_id *id)
1635{
1636 struct hid_report_enum *rep_enum;
1637 struct hid_report *rep;
1638 struct dj_receiver_dev *djrcv_dev;
1639 struct usb_interface *intf;
1640 unsigned int no_dj_interfaces = 0;
1641 bool has_hidpp = false;
1642 unsigned long flags;
1643 int retval;
1644
1645
1646
1647
1648
1649
1650 retval = hid_parse(hdev);
1651 if (retval) {
1652 hid_err(hdev, "%s: parse failed\n", __func__);
1653 return retval;
1654 }
1655
1656
1657
1658
1659
1660
1661
1662 switch (id->driver_data) {
1663 case recvr_type_dj: no_dj_interfaces = 3; break;
1664 case recvr_type_hidpp: no_dj_interfaces = 2; break;
1665 case recvr_type_gaming_hidpp: no_dj_interfaces = 3; break;
1666 case recvr_type_mouse_only: no_dj_interfaces = 2; break;
1667 case recvr_type_27mhz: no_dj_interfaces = 2; break;
1668 case recvr_type_bluetooth: no_dj_interfaces = 2; break;
1669 }
1670 if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
1671 intf = to_usb_interface(hdev->dev.parent);
1672 if (intf && intf->altsetting->desc.bInterfaceNumber >=
1673 no_dj_interfaces) {
1674 hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
1675 return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
1676 }
1677 }
1678
1679 rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
1680
1681
1682 if (list_empty(&rep_enum->report_list))
1683 return -ENODEV;
1684
1685
1686
1687
1688
1689
1690 list_for_each_entry(rep, &rep_enum->report_list, list) {
1691 if (rep->application == 0xff000001)
1692 has_hidpp = true;
1693 }
1694
1695
1696
1697
1698
1699 if (!has_hidpp && id->driver_data == recvr_type_dj)
1700 return -ENODEV;
1701
1702
1703 rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
1704 djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
1705 rep->application, has_hidpp);
1706 if (!djrcv_dev) {
1707 hid_err(hdev, "%s: dj_get_receiver_dev failed\n", __func__);
1708 return -ENOMEM;
1709 }
1710
1711 if (!rep_enum->numbered)
1712 djrcv_dev->unnumbered_application = rep->application;
1713
1714
1715
1716 retval = hid_hw_start(hdev, HID_CONNECT_HIDRAW|HID_CONNECT_HIDDEV);
1717 if (retval) {
1718 hid_err(hdev, "%s: hid_hw_start returned error\n", __func__);
1719 goto hid_hw_start_fail;
1720 }
1721
1722 if (has_hidpp) {
1723 retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
1724 if (retval < 0) {
1725 hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n",
1726 __func__, retval);
1727 goto switch_to_dj_mode_fail;
1728 }
1729 }
1730
1731
1732 retval = hid_hw_open(hdev);
1733 if (retval < 0) {
1734 hid_err(hdev, "%s: hid_hw_open returned error:%d\n",
1735 __func__, retval);
1736 goto llopen_failed;
1737 }
1738
1739
1740 hid_device_io_start(hdev);
1741
1742 if (has_hidpp) {
1743 spin_lock_irqsave(&djrcv_dev->lock, flags);
1744 djrcv_dev->ready = true;
1745 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1746 retval = logi_dj_recv_query_paired_devices(djrcv_dev);
1747 if (retval < 0) {
1748 hid_err(hdev, "%s: logi_dj_recv_query_paired_devices error:%d\n",
1749 __func__, retval);
1750
1751
1752
1753
1754 }
1755 }
1756
1757 return 0;
1758
1759llopen_failed:
1760switch_to_dj_mode_fail:
1761 hid_hw_stop(hdev);
1762
1763hid_hw_start_fail:
1764 dj_put_receiver_dev(hdev);
1765 return retval;
1766}
1767
1768#ifdef CONFIG_PM
1769static int logi_dj_reset_resume(struct hid_device *hdev)
1770{
1771 int retval;
1772 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1773
1774 if (!djrcv_dev || djrcv_dev->hidpp != hdev)
1775 return 0;
1776
1777 retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
1778 if (retval < 0) {
1779 hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n",
1780 __func__, retval);
1781 }
1782
1783 return 0;
1784}
1785#endif
1786
1787static void logi_dj_remove(struct hid_device *hdev)
1788{
1789 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1790 struct dj_device *dj_dev;
1791 unsigned long flags;
1792 int i;
1793
1794 dbg_hid("%s\n", __func__);
1795
1796 if (!djrcv_dev)
1797 return hid_hw_stop(hdev);
1798
1799
1800
1801
1802
1803 spin_lock_irqsave(&djrcv_dev->lock, flags);
1804 djrcv_dev->ready = false;
1805 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1806
1807 cancel_work_sync(&djrcv_dev->work);
1808
1809 hid_hw_close(hdev);
1810 hid_hw_stop(hdev);
1811
1812
1813
1814
1815
1816
1817
1818
1819 for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {
1820 spin_lock_irqsave(&djrcv_dev->lock, flags);
1821 dj_dev = djrcv_dev->paired_dj_devices[i];
1822 djrcv_dev->paired_dj_devices[i] = NULL;
1823 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1824 if (dj_dev != NULL) {
1825 hid_destroy_device(dj_dev->hdev);
1826 kfree(dj_dev);
1827 }
1828 }
1829
1830 dj_put_receiver_dev(hdev);
1831}
1832
1833static const struct hid_device_id logi_dj_receivers[] = {
1834 {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1835 USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER),
1836 .driver_data = recvr_type_dj},
1837 {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1838 USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2),
1839 .driver_data = recvr_type_dj},
1840 {
1841 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1842 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER),
1843 .driver_data = recvr_type_mouse_only},
1844 {
1845 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1846 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),
1847 .driver_data = recvr_type_hidpp},
1848 {
1849 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1850 0xc531),
1851 .driver_data = recvr_type_gaming_hidpp},
1852 {
1853 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1854 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1),
1855 .driver_data = recvr_type_gaming_hidpp},
1856 {
1857 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1858 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
1859 .driver_data = recvr_type_gaming_hidpp},
1860 {
1861 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
1862 .driver_data = recvr_type_27mhz},
1863 {
1864 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1865 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY),
1866 .driver_data = recvr_type_gaming_hidpp},
1867 {
1868 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1869 USB_DEVICE_ID_S510_RECEIVER_2),
1870 .driver_data = recvr_type_27mhz},
1871 {
1872 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1873 USB_DEVICE_ID_LOGITECH_27MHZ_MOUSE_RECEIVER),
1874 .driver_data = recvr_type_27mhz},
1875 {
1876 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1877 0xc70e),
1878 .driver_data = recvr_type_bluetooth},
1879 {
1880 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1881 0xc70a),
1882 .driver_data = recvr_type_bluetooth},
1883 {
1884 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1885 0xc71b),
1886 .driver_data = recvr_type_bluetooth},
1887 {
1888 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1889 0xc71c),
1890 .driver_data = recvr_type_bluetooth},
1891 {}
1892};
1893
1894MODULE_DEVICE_TABLE(hid, logi_dj_receivers);
1895
1896static struct hid_driver logi_djreceiver_driver = {
1897 .name = "logitech-djreceiver",
1898 .id_table = logi_dj_receivers,
1899 .probe = logi_dj_probe,
1900 .remove = logi_dj_remove,
1901 .raw_event = logi_dj_raw_event,
1902#ifdef CONFIG_PM
1903 .reset_resume = logi_dj_reset_resume,
1904#endif
1905};
1906
1907module_hid_driver(logi_djreceiver_driver);
1908
1909MODULE_LICENSE("GPL");
1910MODULE_AUTHOR("Logitech");
1911MODULE_AUTHOR("Nestor Lopez Casado");
1912MODULE_AUTHOR("nlopezcasad@logitech.com");
1913