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