42
42
#define REPORT_ID_DJ_SHORT 0x20
43
43
#define REPORT_ID_DJ_LONG 0x21
44
44
45
+ #define REPORT_ID_HIDPP_SHORT 0x10
46
+ #define REPORT_ID_HIDPP_LONG 0x11
47
+
48
+ #define HIDPP_REPORT_SHORT_LENGTH 7
49
+ #define HIDPP_REPORT_LONG_LENGTH 20
50
+
51
+ #define HIDPP_RECEIVER_INDEX 0xff
52
+
53
+ #define REPORT_TYPE_RFREPORT_FIRST 0x01
45
54
#define REPORT_TYPE_RFREPORT_LAST 0x1F
46
55
47
56
/* Command Switch to DJ mode */
@@ -242,6 +251,57 @@ static const char media_descriptor[] = {
242
251
0xc0 , /* EndCollection */
243
252
}; /* */
244
253
254
+ /* HIDPP descriptor */
255
+ static const char hidpp_descriptor [] = {
256
+ 0x06 , 0x00 , 0xff , /* Usage Page (Vendor Defined Page 1) */
257
+ 0x09 , 0x01 , /* Usage (Vendor Usage 1) */
258
+ 0xa1 , 0x01 , /* Collection (Application) */
259
+ 0x85 , 0x10 , /* Report ID (16) */
260
+ 0x75 , 0x08 , /* Report Size (8) */
261
+ 0x95 , 0x06 , /* Report Count (6) */
262
+ 0x15 , 0x00 , /* Logical Minimum (0) */
263
+ 0x26 , 0xff , 0x00 , /* Logical Maximum (255) */
264
+ 0x09 , 0x01 , /* Usage (Vendor Usage 1) */
265
+ 0x81 , 0x00 , /* Input (Data,Arr,Abs) */
266
+ 0x09 , 0x01 , /* Usage (Vendor Usage 1) */
267
+ 0x91 , 0x00 , /* Output (Data,Arr,Abs) */
268
+ 0xc0 , /* End Collection */
269
+ 0x06 , 0x00 , 0xff , /* Usage Page (Vendor Defined Page 1) */
270
+ 0x09 , 0x02 , /* Usage (Vendor Usage 2) */
271
+ 0xa1 , 0x01 , /* Collection (Application) */
272
+ 0x85 , 0x11 , /* Report ID (17) */
273
+ 0x75 , 0x08 , /* Report Size (8) */
274
+ 0x95 , 0x13 , /* Report Count (19) */
275
+ 0x15 , 0x00 , /* Logical Minimum (0) */
276
+ 0x26 , 0xff , 0x00 , /* Logical Maximum (255) */
277
+ 0x09 , 0x02 , /* Usage (Vendor Usage 2) */
278
+ 0x81 , 0x00 , /* Input (Data,Arr,Abs) */
279
+ 0x09 , 0x02 , /* Usage (Vendor Usage 2) */
280
+ 0x91 , 0x00 , /* Output (Data,Arr,Abs) */
281
+ 0xc0 , /* End Collection */
282
+ 0x06 , 0x00 , 0xff , /* Usage Page (Vendor Defined Page 1) */
283
+ 0x09 , 0x04 , /* Usage (Vendor Usage 0x04) */
284
+ 0xa1 , 0x01 , /* Collection (Application) */
285
+ 0x85 , 0x20 , /* Report ID (32) */
286
+ 0x75 , 0x08 , /* Report Size (8) */
287
+ 0x95 , 0x0e , /* Report Count (14) */
288
+ 0x15 , 0x00 , /* Logical Minimum (0) */
289
+ 0x26 , 0xff , 0x00 , /* Logical Maximum (255) */
290
+ 0x09 , 0x41 , /* Usage (Vendor Usage 0x41) */
291
+ 0x81 , 0x00 , /* Input (Data,Arr,Abs) */
292
+ 0x09 , 0x41 , /* Usage (Vendor Usage 0x41) */
293
+ 0x91 , 0x00 , /* Output (Data,Arr,Abs) */
294
+ 0x85 , 0x21 , /* Report ID (33) */
295
+ 0x95 , 0x1f , /* Report Count (31) */
296
+ 0x15 , 0x00 , /* Logical Minimum (0) */
297
+ 0x26 , 0xff , 0x00 , /* Logical Maximum (255) */
298
+ 0x09 , 0x42 , /* Usage (Vendor Usage 0x42) */
299
+ 0x81 , 0x00 , /* Input (Data,Arr,Abs) */
300
+ 0x09 , 0x42 , /* Usage (Vendor Usage 0x42) */
301
+ 0x91 , 0x00 , /* Output (Data,Arr,Abs) */
302
+ 0xc0 , /* End Collection */
303
+ };
304
+
245
305
/* Maximum size of all defined hid reports in bytes (including report id) */
246
306
#define MAX_REPORT_SIZE 8
247
307
@@ -251,7 +311,8 @@ static const char media_descriptor[] = {
251
311
sizeof(mse_descriptor) + \
252
312
sizeof(consumer_descriptor) + \
253
313
sizeof(syscontrol_descriptor) + \
254
- sizeof(media_descriptor))
314
+ sizeof(media_descriptor) + \
315
+ sizeof(hidpp_descriptor))
255
316
256
317
/* Number of possible hid report types that can be created by this driver.
257
318
*
@@ -512,6 +573,13 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
512
573
}
513
574
}
514
575
576
+ static void logi_dj_recv_forward_hidpp (struct dj_device * dj_dev , u8 * data ,
577
+ int size )
578
+ {
579
+ /* We are called from atomic context (tasklet && djrcv->lock held) */
580
+ if (hid_input_report (dj_dev -> hdev , HID_INPUT_REPORT , data , size , 1 ))
581
+ dbg_hid ("hid_input_report error\n" );
582
+ }
515
583
516
584
static int logi_dj_recv_send_report (struct dj_receiver_dev * djrcv_dev ,
517
585
struct dj_report * dj_report )
@@ -609,6 +677,16 @@ static int logi_dj_ll_raw_request(struct hid_device *hid,
609
677
u8 * out_buf ;
610
678
int ret ;
611
679
680
+ if ((buf [0 ] == REPORT_ID_HIDPP_SHORT ) ||
681
+ (buf [0 ] == REPORT_ID_HIDPP_LONG )) {
682
+ if (count < 2 )
683
+ return - EINVAL ;
684
+
685
+ buf [1 ] = djdev -> device_index ;
686
+ return hid_hw_raw_request (djrcv_dev -> hdev , reportnum , buf ,
687
+ count , report_type , reqtype );
688
+ }
689
+
612
690
if (buf [0 ] != REPORT_TYPE_LEDS )
613
691
return - EINVAL ;
614
692
@@ -687,6 +765,8 @@ static int logi_dj_ll_parse(struct hid_device *hid)
687
765
__func__ , djdev -> reports_supported );
688
766
}
689
767
768
+ rdcat (rdesc , & rsize , hidpp_descriptor , sizeof (hidpp_descriptor ));
769
+
690
770
retval = hid_parse_report (hid , rdesc , rsize );
691
771
kfree (rdesc );
692
772
@@ -714,45 +794,32 @@ static struct hid_ll_driver logi_dj_ll_driver = {
714
794
.raw_request = logi_dj_ll_raw_request ,
715
795
};
716
796
717
-
718
- static int logi_dj_raw_event (struct hid_device * hdev ,
797
+ static int logi_dj_dj_event (struct hid_device * hdev ,
719
798
struct hid_report * report , u8 * data ,
720
799
int size )
721
800
{
722
801
struct dj_receiver_dev * djrcv_dev = hid_get_drvdata (hdev );
723
802
struct dj_report * dj_report = (struct dj_report * ) data ;
724
803
unsigned long flags ;
725
804
726
- dbg_hid ("%s, size:%d\n" , __func__ , size );
727
-
728
- /* Here we receive all data coming from iface 2, there are 4 cases:
729
- *
730
- * 1) Data should continue its normal processing i.e. data does not
731
- * come from the DJ collection, in which case we do nothing and
732
- * return 0, so hid-core can continue normal processing (will forward
733
- * to associated hidraw device)
805
+ /*
806
+ * Here we receive all data coming from iface 2, there are 3 cases:
734
807
*
735
- * 2 ) Data is from DJ collection, and is intended for this driver i. e.
736
- * data contains arrival, departure, etc notifications, in which case
737
- * we queue them for delayed processing by the work queue. We return 1
738
- * to hid-core as no further processing is required from it.
808
+ * 1 ) Data is intended for this driver i. e. data contains arrival,
809
+ * departure, etc notifications, in which case we queue them for delayed
810
+ * processing by the work queue. We return 1 to hid-core as no further
811
+ * processing is required from it.
739
812
*
740
- * 3) Data is from DJ collection, and informs a connection change,
741
- * if the change means rf link loss, then we must send a null report
742
- * to the upper layer to discard potentially pressed keys that may be
743
- * repeated forever by the input layer. Return 1 to hid-core as no
744
- * further processing is required.
813
+ * 2) Data informs a connection change, if the change means rf link
814
+ * loss, then we must send a null report to the upper layer to discard
815
+ * potentially pressed keys that may be repeated forever by the input
816
+ * layer. Return 1 to hid-core as no further processing is required.
745
817
*
746
- * 4) Data is from DJ collection and is an actual input event from
747
- * a paired DJ device in which case we forward it to the correct hid
748
- * device (via hid_input_report() ) and return 1 so hid-core does not do
749
- * anything else with it.
818
+ * 3) Data is an actual input event from a paired DJ device in which
819
+ * case we forward it to the correct hid device (via hid_input_report()
820
+ * ) and return 1 so hid-core does not anything else with it.
750
821
*/
751
822
752
- /* case 1) */
753
- if (data [0 ] != REPORT_ID_DJ_SHORT )
754
- return false;
755
-
756
823
if ((dj_report -> device_index < DJ_DEVICE_INDEX_MIN ) ||
757
824
(dj_report -> device_index > DJ_DEVICE_INDEX_MAX )) {
758
825
/*
@@ -797,6 +864,71 @@ static int logi_dj_raw_event(struct hid_device *hdev,
797
864
return true;
798
865
}
799
866
867
+ static int logi_dj_hidpp_event (struct hid_device * hdev ,
868
+ struct hid_report * report , u8 * data ,
869
+ int size )
870
+ {
871
+ struct dj_receiver_dev * djrcv_dev = hid_get_drvdata (hdev );
872
+ struct dj_report * dj_report = (struct dj_report * ) data ;
873
+ unsigned long flags ;
874
+ u8 device_index = dj_report -> device_index ;
875
+
876
+ if (device_index == HIDPP_RECEIVER_INDEX )
877
+ return false;
878
+
879
+ /*
880
+ * Data is from the HID++ collection, in this case, we forward the
881
+ * data to the corresponding child dj device and return 0 to hid-core
882
+ * so he data also goes to the hidraw device of the receiver. This
883
+ * allows a user space application to implement the full HID++ routing
884
+ * via the receiver.
885
+ */
886
+
887
+ if ((device_index < DJ_DEVICE_INDEX_MIN ) ||
888
+ (device_index > DJ_DEVICE_INDEX_MAX )) {
889
+ /*
890
+ * Device index is wrong, bail out.
891
+ * This driver can ignore safely the receiver notifications,
892
+ * so ignore those reports too.
893
+ */
894
+ dev_err (& hdev -> dev , "%s: invalid device index:%d\n" ,
895
+ __func__ , dj_report -> device_index );
896
+ return false;
897
+ }
898
+
899
+ spin_lock_irqsave (& djrcv_dev -> lock , flags );
900
+
901
+ if (!djrcv_dev -> paired_dj_devices [device_index ])
902
+ /* received an event for an unknown device, bail out */
903
+ goto out ;
904
+
905
+ logi_dj_recv_forward_hidpp (djrcv_dev -> paired_dj_devices [device_index ],
906
+ data , size );
907
+
908
+ out :
909
+ spin_unlock_irqrestore (& djrcv_dev -> lock , flags );
910
+
911
+ return false;
912
+ }
913
+
914
+ static int logi_dj_raw_event (struct hid_device * hdev ,
915
+ struct hid_report * report , u8 * data ,
916
+ int size )
917
+ {
918
+ dbg_hid ("%s, size:%d\n" , __func__ , size );
919
+
920
+ switch (data [0 ]) {
921
+ case REPORT_ID_DJ_SHORT :
922
+ return logi_dj_dj_event (hdev , report , data , size );
923
+ case REPORT_ID_HIDPP_SHORT :
924
+ /* intentional fallthrough */
925
+ case REPORT_ID_HIDPP_LONG :
926
+ return logi_dj_hidpp_event (hdev , report , data , size );
927
+ }
928
+
929
+ return false;
930
+ }
931
+
800
932
static int logi_dj_probe (struct hid_device * hdev ,
801
933
const struct hid_device_id * id )
802
934
{
0 commit comments