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