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 6
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 6
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, 0x8C, 0x02,
384 0x19, 0x01,
385 0x2A, 0x8C, 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 Unifying Device. Wireless 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
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 break;
963 case 0x08:
964 device_type = "eQUAD step 4 for gamepads";
965 break;
966 case 0x0a:
967 device_type = "eQUAD nano Lite";
968 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
969 break;
970 case 0x0c:
971 device_type = "eQUAD Lightspeed";
972 logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
973 workitem.reports_supported |= STD_KEYBOARD;
974 break;
975 }
976
977 if (workitem.type == WORKITEM_TYPE_EMPTY) {
978 hid_warn(hdev,
979 "unusable device of type %s (0x%02x) connected on slot %d",
980 device_type,
981 hidpp_report->params[HIDPP_PARAM_PROTO_TYPE],
982 hidpp_report->device_index);
983 return;
984 }
985
986 hid_info(hdev, "device of type %s (0x%02x) connected on slot %d",
987 device_type, hidpp_report->params[HIDPP_PARAM_PROTO_TYPE],
988 hidpp_report->device_index);
989
990 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));
991 schedule_work(&djrcv_dev->work);
992}
993
994static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
995 struct dj_report *dj_report)
996{
997
998 unsigned int i;
999 u8 reportbuffer[MAX_REPORT_SIZE];
1000 struct dj_device *djdev;
1001
1002 djdev = djrcv_dev->paired_dj_devices[dj_report->device_index];
1003
1004 memset(reportbuffer, 0, sizeof(reportbuffer));
1005
1006 for (i = 0; i < NUMBER_OF_HID_REPORTS; i++) {
1007 if (djdev->reports_supported & (1 << i)) {
1008 reportbuffer[0] = i;
1009 if (hid_input_report(djdev->hdev,
1010 HID_INPUT_REPORT,
1011 reportbuffer,
1012 hid_reportid_size_map[i], 1)) {
1013 dbg_hid("hid_input_report error sending null "
1014 "report\n");
1015 }
1016 }
1017 }
1018}
1019
1020static void logi_dj_recv_forward_dj(struct dj_receiver_dev *djrcv_dev,
1021 struct dj_report *dj_report)
1022{
1023
1024 struct dj_device *dj_device;
1025
1026 dj_device = djrcv_dev->paired_dj_devices[dj_report->device_index];
1027
1028 if ((dj_report->report_type > ARRAY_SIZE(hid_reportid_size_map) - 1) ||
1029 (hid_reportid_size_map[dj_report->report_type] == 0)) {
1030 dbg_hid("invalid report type:%x\n", dj_report->report_type);
1031 return;
1032 }
1033
1034 if (hid_input_report(dj_device->hdev,
1035 HID_INPUT_REPORT, &dj_report->report_type,
1036 hid_reportid_size_map[dj_report->report_type], 1)) {
1037 dbg_hid("hid_input_report error\n");
1038 }
1039}
1040
1041static void logi_dj_recv_forward_report(struct dj_device *dj_dev, u8 *data,
1042 int size)
1043{
1044
1045 if (hid_input_report(dj_dev->hdev, HID_INPUT_REPORT, data, size, 1))
1046 dbg_hid("hid_input_report error\n");
1047}
1048
1049static void logi_dj_recv_forward_input_report(struct hid_device *hdev,
1050 u8 *data, int size)
1051{
1052 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1053 struct dj_device *dj_dev;
1054 unsigned long flags;
1055 u8 report = data[0];
1056 int i;
1057
1058 if (report > REPORT_TYPE_RFREPORT_LAST) {
1059 hid_err(hdev, "Unexpected input report number %d\n", report);
1060 return;
1061 }
1062
1063 spin_lock_irqsave(&djrcv_dev->lock, flags);
1064 for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {
1065 dj_dev = djrcv_dev->paired_dj_devices[i];
1066 if (dj_dev && (dj_dev->reports_supported & BIT(report))) {
1067 logi_dj_recv_forward_report(dj_dev, data, size);
1068 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1069 return;
1070 }
1071 }
1072
1073 logi_dj_recv_queue_unknown_work(djrcv_dev);
1074 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1075
1076 dbg_hid("No dj-devs handling input report number %d\n", report);
1077}
1078
1079static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
1080 struct dj_report *dj_report)
1081{
1082 struct hid_device *hdev = djrcv_dev->hidpp;
1083 struct hid_report *report;
1084 struct hid_report_enum *output_report_enum;
1085 u8 *data = (u8 *)(&dj_report->device_index);
1086 unsigned int i;
1087
1088 output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
1089 report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
1090
1091 if (!report) {
1092 hid_err(hdev, "%s: unable to find dj report\n", __func__);
1093 return -ENODEV;
1094 }
1095
1096 for (i = 0; i < DJREPORT_SHORT_LENGTH - 1; i++)
1097 report->field[0]->value[i] = data[i];
1098
1099 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1100
1101 return 0;
1102}
1103
1104static int logi_dj_recv_query_hidpp_devices(struct dj_receiver_dev *djrcv_dev)
1105{
1106 static const u8 template[] = {
1107 REPORT_ID_HIDPP_SHORT,
1108 HIDPP_RECEIVER_INDEX,
1109 HIDPP_SET_REGISTER,
1110 HIDPP_REG_CONNECTION_STATE,
1111 HIDPP_FAKE_DEVICE_ARRIVAL,
1112 0x00, 0x00
1113 };
1114 u8 *hidpp_report;
1115 int retval;
1116
1117 hidpp_report = kmemdup(template, sizeof(template), GFP_KERNEL);
1118 if (!hidpp_report)
1119 return -ENOMEM;
1120
1121 retval = hid_hw_raw_request(djrcv_dev->hidpp,
1122 REPORT_ID_HIDPP_SHORT,
1123 hidpp_report, sizeof(template),
1124 HID_OUTPUT_REPORT,
1125 HID_REQ_SET_REPORT);
1126
1127 kfree(hidpp_report);
1128 return (retval < 0) ? retval : 0;
1129}
1130
1131static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
1132{
1133 struct dj_report *dj_report;
1134 int retval;
1135
1136 djrcv_dev->last_query = jiffies;
1137
1138 if (djrcv_dev->type != recvr_type_dj)
1139 return logi_dj_recv_query_hidpp_devices(djrcv_dev);
1140
1141 dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
1142 if (!dj_report)
1143 return -ENOMEM;
1144 dj_report->report_id = REPORT_ID_DJ_SHORT;
1145 dj_report->device_index = 0xFF;
1146 dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES;
1147 retval = logi_dj_recv_send_report(djrcv_dev, dj_report);
1148 kfree(dj_report);
1149 return retval;
1150}
1151
1152
1153static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
1154 unsigned timeout)
1155{
1156 struct hid_device *hdev = djrcv_dev->hidpp;
1157 struct dj_report *dj_report;
1158 u8 *buf;
1159 int retval = 0;
1160
1161 dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
1162 if (!dj_report)
1163 return -ENOMEM;
1164
1165 if (djrcv_dev->type == recvr_type_dj) {
1166 dj_report->report_id = REPORT_ID_DJ_SHORT;
1167 dj_report->device_index = 0xFF;
1168 dj_report->report_type = REPORT_TYPE_CMD_SWITCH;
1169 dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F;
1170 dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] =
1171 (u8)timeout;
1172
1173 retval = logi_dj_recv_send_report(djrcv_dev, dj_report);
1174
1175
1176
1177
1178
1179
1180
1181 msleep(50);
1182 }
1183
1184
1185
1186
1187
1188
1189
1190
1191 buf = (u8 *)dj_report;
1192
1193 memset(buf, 0, HIDPP_REPORT_SHORT_LENGTH);
1194
1195 buf[0] = REPORT_ID_HIDPP_SHORT;
1196 buf[1] = 0xFF;
1197 buf[2] = 0x80;
1198 buf[3] = 0x00;
1199 buf[4] = 0x00;
1200 buf[5] = 0x09;
1201 buf[6] = 0x00;
1202
1203 hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
1204 HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,
1205 HID_REQ_SET_REPORT);
1206
1207 kfree(dj_report);
1208 return retval;
1209}
1210
1211
1212static int logi_dj_ll_open(struct hid_device *hid)
1213{
1214 dbg_hid("%s: %s\n", __func__, hid->phys);
1215 return 0;
1216
1217}
1218
1219static void logi_dj_ll_close(struct hid_device *hid)
1220{
1221 dbg_hid("%s: %s\n", __func__, hid->phys);
1222}
1223
1224
1225
1226
1227
1228static u8 unifying_pairing_query[] = { REPORT_ID_HIDPP_SHORT,
1229 HIDPP_RECEIVER_INDEX,
1230 HIDPP_GET_LONG_REGISTER,
1231 HIDPP_REG_PAIRING_INFORMATION };
1232static u8 unifying_pairing_answer[] = { REPORT_ID_HIDPP_LONG,
1233 HIDPP_RECEIVER_INDEX,
1234 HIDPP_GET_LONG_REGISTER,
1235 HIDPP_REG_PAIRING_INFORMATION };
1236
1237static int logi_dj_ll_raw_request(struct hid_device *hid,
1238 unsigned char reportnum, __u8 *buf,
1239 size_t count, unsigned char report_type,
1240 int reqtype)
1241{
1242 struct dj_device *djdev = hid->driver_data;
1243 struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev;
1244 u8 *out_buf;
1245 int ret;
1246
1247 if ((buf[0] == REPORT_ID_HIDPP_SHORT) ||
1248 (buf[0] == REPORT_ID_HIDPP_LONG) ||
1249 (buf[0] == REPORT_ID_HIDPP_VERY_LONG)) {
1250 if (count < 2)
1251 return -EINVAL;
1252
1253
1254
1255 if (count == 7 && !memcmp(buf, unifying_pairing_query,
1256 sizeof(unifying_pairing_query)))
1257 buf[4] = (buf[4] & 0xf0) | (djdev->device_index - 1);
1258 else
1259 buf[1] = djdev->device_index;
1260 return hid_hw_raw_request(djrcv_dev->hidpp, reportnum, buf,
1261 count, report_type, reqtype);
1262 }
1263
1264 if (buf[0] != REPORT_TYPE_LEDS)
1265 return -EINVAL;
1266
1267 if (djrcv_dev->type != recvr_type_dj && count >= 2) {
1268 if (!djrcv_dev->keyboard) {
1269 hid_warn(hid, "Received REPORT_TYPE_LEDS request before the keyboard interface was enumerated\n");
1270 return 0;
1271 }
1272
1273 return hid_hw_raw_request(djrcv_dev->keyboard, 0, buf, count,
1274 report_type, reqtype);
1275 }
1276
1277 out_buf = kzalloc(DJREPORT_SHORT_LENGTH, GFP_ATOMIC);
1278 if (!out_buf)
1279 return -ENOMEM;
1280
1281 if (count > DJREPORT_SHORT_LENGTH - 2)
1282 count = DJREPORT_SHORT_LENGTH - 2;
1283
1284 out_buf[0] = REPORT_ID_DJ_SHORT;
1285 out_buf[1] = djdev->device_index;
1286 memcpy(out_buf + 2, buf, count);
1287
1288 ret = hid_hw_raw_request(djrcv_dev->hidpp, out_buf[0], out_buf,
1289 DJREPORT_SHORT_LENGTH, report_type, reqtype);
1290
1291 kfree(out_buf);
1292 return ret;
1293}
1294
1295static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)
1296{
1297 memcpy(rdesc + *rsize, data, size);
1298 *rsize += size;
1299}
1300
1301static int logi_dj_ll_parse(struct hid_device *hid)
1302{
1303 struct dj_device *djdev = hid->driver_data;
1304 unsigned int rsize = 0;
1305 char *rdesc;
1306 int retval;
1307
1308 dbg_hid("%s\n", __func__);
1309
1310 djdev->hdev->version = 0x0111;
1311 djdev->hdev->country = 0x00;
1312
1313 rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL);
1314 if (!rdesc)
1315 return -ENOMEM;
1316
1317 if (djdev->reports_supported & STD_KEYBOARD) {
1318 dbg_hid("%s: sending a kbd descriptor, reports_supported: %llx\n",
1319 __func__, djdev->reports_supported);
1320 rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
1321 }
1322
1323 if (djdev->reports_supported & STD_MOUSE) {
1324 dbg_hid("%s: sending a mouse descriptor, reports_supported: %llx\n",
1325 __func__, djdev->reports_supported);
1326 if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp ||
1327 djdev->dj_receiver_dev->type == recvr_type_mouse_only)
1328 rdcat(rdesc, &rsize, mse_high_res_descriptor,
1329 sizeof(mse_high_res_descriptor));
1330 else if (djdev->dj_receiver_dev->type == recvr_type_27mhz)
1331 rdcat(rdesc, &rsize, mse_27mhz_descriptor,
1332 sizeof(mse_27mhz_descriptor));
1333 else if (djdev->dj_receiver_dev->type == recvr_type_bluetooth)
1334 rdcat(rdesc, &rsize, mse_bluetooth_descriptor,
1335 sizeof(mse_bluetooth_descriptor));
1336 else
1337 rdcat(rdesc, &rsize, mse_descriptor,
1338 sizeof(mse_descriptor));
1339 }
1340
1341 if (djdev->reports_supported & MULTIMEDIA) {
1342 dbg_hid("%s: sending a multimedia report descriptor: %llx\n",
1343 __func__, djdev->reports_supported);
1344 rdcat(rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
1345 }
1346
1347 if (djdev->reports_supported & POWER_KEYS) {
1348 dbg_hid("%s: sending a power keys report descriptor: %llx\n",
1349 __func__, djdev->reports_supported);
1350 rdcat(rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
1351 }
1352
1353 if (djdev->reports_supported & MEDIA_CENTER) {
1354 dbg_hid("%s: sending a media center report descriptor: %llx\n",
1355 __func__, djdev->reports_supported);
1356 rdcat(rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
1357 }
1358
1359 if (djdev->reports_supported & KBD_LEDS) {
1360 dbg_hid("%s: need to send kbd leds report descriptor: %llx\n",
1361 __func__, djdev->reports_supported);
1362 }
1363
1364 if (djdev->reports_supported & HIDPP) {
1365 rdcat(rdesc, &rsize, hidpp_descriptor,
1366 sizeof(hidpp_descriptor));
1367 }
1368
1369 retval = hid_parse_report(hid, rdesc, rsize);
1370 kfree(rdesc);
1371
1372 return retval;
1373}
1374
1375static int logi_dj_ll_start(struct hid_device *hid)
1376{
1377 dbg_hid("%s\n", __func__);
1378 return 0;
1379}
1380
1381static void logi_dj_ll_stop(struct hid_device *hid)
1382{
1383 dbg_hid("%s\n", __func__);
1384}
1385
1386
1387static struct hid_ll_driver logi_dj_ll_driver = {
1388 .parse = logi_dj_ll_parse,
1389 .start = logi_dj_ll_start,
1390 .stop = logi_dj_ll_stop,
1391 .open = logi_dj_ll_open,
1392 .close = logi_dj_ll_close,
1393 .raw_request = logi_dj_ll_raw_request,
1394};
1395
1396static int logi_dj_dj_event(struct hid_device *hdev,
1397 struct hid_report *report, u8 *data,
1398 int size)
1399{
1400 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1401 struct dj_report *dj_report = (struct dj_report *) data;
1402 unsigned long flags;
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422 if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
1423 (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
1424
1425
1426
1427
1428
1429 if (dj_report->device_index != DJ_RECEIVER_INDEX)
1430 hid_err(hdev, "%s: invalid device index:%d\n",
1431 __func__, dj_report->device_index);
1432 return false;
1433 }
1434
1435 spin_lock_irqsave(&djrcv_dev->lock, flags);
1436
1437 if (!djrcv_dev->paired_dj_devices[dj_report->device_index]) {
1438
1439 logi_dj_recv_queue_notification(djrcv_dev, dj_report);
1440 goto out;
1441 }
1442
1443 switch (dj_report->report_type) {
1444 case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
1445
1446 break;
1447 case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
1448 logi_dj_recv_queue_notification(djrcv_dev, dj_report);
1449 break;
1450 case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
1451 if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
1452 STATUS_LINKLOSS) {
1453 logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
1454 }
1455 break;
1456 default:
1457 logi_dj_recv_forward_dj(djrcv_dev, dj_report);
1458 }
1459
1460out:
1461 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1462
1463 return true;
1464}
1465
1466static int logi_dj_hidpp_event(struct hid_device *hdev,
1467 struct hid_report *report, u8 *data,
1468 int size)
1469{
1470 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1471 struct hidpp_event *hidpp_report = (struct hidpp_event *) data;
1472 struct dj_device *dj_dev;
1473 unsigned long flags;
1474 u8 device_index = hidpp_report->device_index;
1475
1476 if (device_index == HIDPP_RECEIVER_INDEX) {
1477
1478
1479 if (size == HIDPP_REPORT_LONG_LENGTH &&
1480 !memcmp(data, unifying_pairing_answer,
1481 sizeof(unifying_pairing_answer)))
1482 device_index = (data[4] & 0x0F) + 1;
1483 else
1484 return false;
1485 }
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495 if ((device_index < DJ_DEVICE_INDEX_MIN) ||
1496 (device_index > DJ_DEVICE_INDEX_MAX)) {
1497
1498
1499
1500
1501
1502 hid_err(hdev, "%s: invalid device index:%d\n", __func__,
1503 hidpp_report->device_index);
1504 return false;
1505 }
1506
1507 spin_lock_irqsave(&djrcv_dev->lock, flags);
1508
1509 dj_dev = djrcv_dev->paired_dj_devices[device_index];
1510
1511
1512
1513
1514
1515 if (djrcv_dev->type == recvr_type_27mhz && dj_dev &&
1516 hidpp_report->sub_id == REPORT_TYPE_NOTIF_DEVICE_CONNECTED &&
1517 hidpp_report->params[HIDPP_PARAM_PROTO_TYPE] == 0x02 &&
1518 hidpp_report->params[HIDPP_PARAM_27MHZ_DEVID] !=
1519 dj_dev->hdev->product) {
1520 struct dj_workitem workitem = {
1521 .device_index = hidpp_report->device_index,
1522 .type = WORKITEM_TYPE_UNPAIRED,
1523 };
1524 kfifo_in(&djrcv_dev->notif_fifo, &workitem, sizeof(workitem));
1525
1526 dj_dev = NULL;
1527 }
1528
1529 if (dj_dev) {
1530 logi_dj_recv_forward_report(dj_dev, data, size);
1531 } else {
1532 if (hidpp_report->sub_id == REPORT_TYPE_NOTIF_DEVICE_CONNECTED)
1533 logi_hidpp_recv_queue_notif(hdev, hidpp_report);
1534 else
1535 logi_dj_recv_queue_unknown_work(djrcv_dev);
1536 }
1537
1538 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1539
1540 return false;
1541}
1542
1543static int logi_dj_raw_event(struct hid_device *hdev,
1544 struct hid_report *report, u8 *data,
1545 int size)
1546{
1547 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1548 dbg_hid("%s, size:%d\n", __func__, size);
1549
1550 if (!djrcv_dev)
1551 return 0;
1552
1553 if (!hdev->report_enum[HID_INPUT_REPORT].numbered) {
1554
1555 if (djrcv_dev->unnumbered_application == HID_GD_KEYBOARD) {
1556
1557
1558
1559
1560
1561 data[1] = data[0];
1562 data[0] = REPORT_TYPE_KEYBOARD;
1563
1564 logi_dj_recv_forward_input_report(hdev, data, size);
1565
1566
1567 data[0] = data[1];
1568 data[1] = 0;
1569 }
1570
1571
1572
1573
1574 if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
1575 size <= 8) {
1576 u8 mouse_report[9];
1577
1578
1579 mouse_report[0] = REPORT_TYPE_MOUSE;
1580 memcpy(mouse_report + 1, data, size);
1581 logi_dj_recv_forward_input_report(hdev, mouse_report,
1582 size + 1);
1583 }
1584
1585 return false;
1586 }
1587
1588 switch (data[0]) {
1589 case REPORT_ID_DJ_SHORT:
1590 if (size != DJREPORT_SHORT_LENGTH) {
1591 hid_err(hdev, "Short DJ report bad size (%d)", size);
1592 return false;
1593 }
1594 return logi_dj_dj_event(hdev, report, data, size);
1595 case REPORT_ID_DJ_LONG:
1596 if (size != DJREPORT_LONG_LENGTH) {
1597 hid_err(hdev, "Long DJ report bad size (%d)", size);
1598 return false;
1599 }
1600 return logi_dj_dj_event(hdev, report, data, size);
1601 case REPORT_ID_HIDPP_SHORT:
1602 if (size != HIDPP_REPORT_SHORT_LENGTH) {
1603 hid_err(hdev, "Short HID++ report bad size (%d)", size);
1604 return false;
1605 }
1606 return logi_dj_hidpp_event(hdev, report, data, size);
1607 case REPORT_ID_HIDPP_LONG:
1608 if (size != HIDPP_REPORT_LONG_LENGTH) {
1609 hid_err(hdev, "Long HID++ report bad size (%d)", size);
1610 return false;
1611 }
1612 return logi_dj_hidpp_event(hdev, report, data, size);
1613 }
1614
1615 logi_dj_recv_forward_input_report(hdev, data, size);
1616
1617 return false;
1618}
1619
1620static int logi_dj_probe(struct hid_device *hdev,
1621 const struct hid_device_id *id)
1622{
1623 struct hid_report_enum *rep_enum;
1624 struct hid_report *rep;
1625 struct dj_receiver_dev *djrcv_dev;
1626 struct usb_interface *intf;
1627 unsigned int no_dj_interfaces = 0;
1628 bool has_hidpp = false;
1629 unsigned long flags;
1630 int retval;
1631
1632
1633
1634
1635
1636
1637 retval = hid_parse(hdev);
1638 if (retval) {
1639 hid_err(hdev, "%s: parse failed\n", __func__);
1640 return retval;
1641 }
1642
1643
1644
1645
1646
1647
1648
1649 switch (id->driver_data) {
1650 case recvr_type_dj: no_dj_interfaces = 3; break;
1651 case recvr_type_hidpp: no_dj_interfaces = 2; break;
1652 case recvr_type_gaming_hidpp: no_dj_interfaces = 3; break;
1653 case recvr_type_mouse_only: no_dj_interfaces = 2; break;
1654 case recvr_type_27mhz: no_dj_interfaces = 2; break;
1655 case recvr_type_bluetooth: no_dj_interfaces = 2; break;
1656 }
1657 if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
1658 intf = to_usb_interface(hdev->dev.parent);
1659 if (intf && intf->altsetting->desc.bInterfaceNumber >=
1660 no_dj_interfaces) {
1661 hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
1662 return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
1663 }
1664 }
1665
1666 rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
1667
1668
1669 if (list_empty(&rep_enum->report_list))
1670 return -ENODEV;
1671
1672
1673
1674
1675
1676
1677 list_for_each_entry(rep, &rep_enum->report_list, list) {
1678 if (rep->application == 0xff000001)
1679 has_hidpp = true;
1680 }
1681
1682
1683
1684
1685
1686 if (!has_hidpp && id->driver_data == recvr_type_dj)
1687 return -ENODEV;
1688
1689
1690 rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
1691 djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
1692 rep->application, has_hidpp);
1693 if (!djrcv_dev) {
1694 hid_err(hdev, "%s: dj_get_receiver_dev failed\n", __func__);
1695 return -ENOMEM;
1696 }
1697
1698 if (!rep_enum->numbered)
1699 djrcv_dev->unnumbered_application = rep->application;
1700
1701
1702
1703 retval = hid_hw_start(hdev, HID_CONNECT_HIDRAW|HID_CONNECT_HIDDEV);
1704 if (retval) {
1705 hid_err(hdev, "%s: hid_hw_start returned error\n", __func__);
1706 goto hid_hw_start_fail;
1707 }
1708
1709 if (has_hidpp) {
1710 retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
1711 if (retval < 0) {
1712 hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n",
1713 __func__, retval);
1714 goto switch_to_dj_mode_fail;
1715 }
1716 }
1717
1718
1719 retval = hid_hw_open(hdev);
1720 if (retval < 0) {
1721 hid_err(hdev, "%s: hid_hw_open returned error:%d\n",
1722 __func__, retval);
1723 goto llopen_failed;
1724 }
1725
1726
1727 hid_device_io_start(hdev);
1728
1729 if (has_hidpp) {
1730 spin_lock_irqsave(&djrcv_dev->lock, flags);
1731 djrcv_dev->ready = true;
1732 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1733 retval = logi_dj_recv_query_paired_devices(djrcv_dev);
1734 if (retval < 0) {
1735 hid_err(hdev, "%s: logi_dj_recv_query_paired_devices error:%d\n",
1736 __func__, retval);
1737 goto logi_dj_recv_query_paired_devices_failed;
1738 }
1739 }
1740
1741 return retval;
1742
1743logi_dj_recv_query_paired_devices_failed:
1744 hid_hw_close(hdev);
1745
1746llopen_failed:
1747switch_to_dj_mode_fail:
1748 hid_hw_stop(hdev);
1749
1750hid_hw_start_fail:
1751 dj_put_receiver_dev(hdev);
1752 return retval;
1753}
1754
1755#ifdef CONFIG_PM
1756static int logi_dj_reset_resume(struct hid_device *hdev)
1757{
1758 int retval;
1759 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1760
1761 if (!djrcv_dev || djrcv_dev->hidpp != hdev)
1762 return 0;
1763
1764 retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
1765 if (retval < 0) {
1766 hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n",
1767 __func__, retval);
1768 }
1769
1770 return 0;
1771}
1772#endif
1773
1774static void logi_dj_remove(struct hid_device *hdev)
1775{
1776 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
1777 struct dj_device *dj_dev;
1778 unsigned long flags;
1779 int i;
1780
1781 dbg_hid("%s\n", __func__);
1782
1783 if (!djrcv_dev)
1784 return hid_hw_stop(hdev);
1785
1786
1787
1788
1789
1790 spin_lock_irqsave(&djrcv_dev->lock, flags);
1791 djrcv_dev->ready = false;
1792 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1793
1794 cancel_work_sync(&djrcv_dev->work);
1795
1796 hid_hw_close(hdev);
1797 hid_hw_stop(hdev);
1798
1799
1800
1801
1802
1803
1804
1805
1806 for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {
1807 spin_lock_irqsave(&djrcv_dev->lock, flags);
1808 dj_dev = djrcv_dev->paired_dj_devices[i];
1809 djrcv_dev->paired_dj_devices[i] = NULL;
1810 spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1811 if (dj_dev != NULL) {
1812 hid_destroy_device(dj_dev->hdev);
1813 kfree(dj_dev);
1814 }
1815 }
1816
1817 dj_put_receiver_dev(hdev);
1818}
1819
1820static const struct hid_device_id logi_dj_receivers[] = {
1821 {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1822 USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER),
1823 .driver_data = recvr_type_dj},
1824 {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1825 USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2),
1826 .driver_data = recvr_type_dj},
1827 {
1828 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1829 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER),
1830 .driver_data = recvr_type_mouse_only},
1831 {
1832 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1833 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),
1834 .driver_data = recvr_type_hidpp},
1835 {
1836 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1837 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED),
1838 .driver_data = recvr_type_gaming_hidpp},
1839 {
1840 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
1841 .driver_data = recvr_type_27mhz},
1842 {
1843 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1844 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY),
1845 .driver_data = recvr_type_gaming_hidpp},
1846 {
1847 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1848 USB_DEVICE_ID_S510_RECEIVER_2),
1849 .driver_data = recvr_type_27mhz},
1850 {
1851 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1852 USB_DEVICE_ID_LOGITECH_27MHZ_MOUSE_RECEIVER),
1853 .driver_data = recvr_type_27mhz},
1854 {
1855 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1856 0xc70e),
1857 .driver_data = recvr_type_bluetooth},
1858 {
1859 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1860 0xc70a),
1861 .driver_data = recvr_type_bluetooth},
1862 {
1863 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1864 0xc71b),
1865 .driver_data = recvr_type_bluetooth},
1866 {
1867 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1868 0xc71c),
1869 .driver_data = recvr_type_bluetooth},
1870 {}
1871};
1872
1873MODULE_DEVICE_TABLE(hid, logi_dj_receivers);
1874
1875static struct hid_driver logi_djreceiver_driver = {
1876 .name = "logitech-djreceiver",
1877 .id_table = logi_dj_receivers,
1878 .probe = logi_dj_probe,
1879 .remove = logi_dj_remove,
1880 .raw_event = logi_dj_raw_event,
1881#ifdef CONFIG_PM
1882 .reset_resume = logi_dj_reset_resume,
1883#endif
1884};
1885
1886module_hid_driver(logi_djreceiver_driver);
1887
1888MODULE_LICENSE("GPL");
1889MODULE_AUTHOR("Logitech");
1890MODULE_AUTHOR("Nestor Lopez Casado");
1891MODULE_AUTHOR("nlopezcasad@logitech.com");
1892