Source
43
43
#define LG_FF3 0x1000
44
44
#define LG_FF4 0x2000
45
45
46
46
/* Size of the original descriptors of the Driving Force (and Pro) wheels */
47
47
#define DF_RDESC_ORIG_SIZE 130
48
48
#define DFP_RDESC_ORIG_SIZE 97
49
49
#define FV_RDESC_ORIG_SIZE 130
50
50
#define MOMO_RDESC_ORIG_SIZE 87
51
51
#define MOMO2_RDESC_ORIG_SIZE 87
52
52
#define FFG_RDESC_ORIG_SIZE 85
53
+
#define FG_RDESC_ORIG_SIZE 82
53
54
54
55
/* Fixed report descriptors for Logitech Driving Force (and Pro)
55
56
* wheel controllers
56
57
*
57
58
* The original descriptors hide the separate throttle and brake axes in
58
59
* a custom vendor usage page, providing only a combined value as
59
60
* GenericDesktop.Y.
60
61
* These descriptors remove the combined Y axis and instead report
61
62
* separate throttle (Y) and brake (RZ).
62
63
*/
374
375
0x81, 0x02, /* Input (Variable), */
375
376
0xC0, /* End Collection, */
376
377
0xA1, 0x02, /* Collection (Logical), */
377
378
0x09, 0x02, /* Usage (02h), */
378
379
0x95, 0x07, /* Report Count (7), */
379
380
0x91, 0x02, /* Output (Variable), */
380
381
0xC0, /* End Collection, */
381
382
0xC0 /* End Collection */
382
383
};
383
384
385
+
static __u8 fg_rdesc_fixed[] = {
386
+
0x05, 0x01, /* Usage Page (Desktop), */
387
+
0x09, 0x04, /* Usage (Joystik), */
388
+
0xA1, 0x01, /* Collection (Application), */
389
+
0xA1, 0x02, /* Collection (Logical), */
390
+
0x15, 0x00, /* Logical Minimum (0), */
391
+
0x26, 0xFF, 0x00, /* Logical Maximum (255), */
392
+
0x35, 0x00, /* Physical Minimum (0), */
393
+
0x46, 0xFF, 0x00, /* Physical Maximum (255), */
394
+
0x75, 0x08, /* Report Size (8), */
395
+
0x95, 0x01, /* Report Count (1), */
396
+
0x09, 0x30, /* Usage (X), */
397
+
0x81, 0x02, /* Input (Variable), */
398
+
0xA4, /* Push, */
399
+
0x25, 0x01, /* Logical Maximum (1), */
400
+
0x45, 0x01, /* Physical Maximum (1), */
401
+
0x75, 0x01, /* Report Size (1), */
402
+
0x95, 0x02, /* Report Count (2), */
403
+
0x81, 0x01, /* Input (Constant), */
404
+
0x95, 0x06, /* Report Count (6), */
405
+
0x05, 0x09, /* Usage Page (Button), */
406
+
0x19, 0x01, /* Usage Minimum (01h), */
407
+
0x29, 0x06, /* Usage Maximum (06h), */
408
+
0x81, 0x02, /* Input (Variable), */
409
+
0x05, 0x01, /* Usage Page (Desktop), */
410
+
0xB4, /* Pop, */
411
+
0x81, 0x02, /* Input (Constant), */
412
+
0x09, 0x31, /* Usage (Y), */
413
+
0x81, 0x02, /* Input (Variable), */
414
+
0x09, 0x32, /* Usage (Z), */
415
+
0x81, 0x02, /* Input (Variable), */
416
+
0xC0, /* End Collection, */
417
+
0xA1, 0x02, /* Collection (Logical), */
418
+
0x26, 0xFF, 0x00, /* Logical Maximum (255), */
419
+
0x46, 0xFF, 0x00, /* Physical Maximum (255), */
420
+
0x75, 0x08, /* Report Size (8), */
421
+
0x95, 0x04, /* Report Count (4), */
422
+
0x09, 0x02, /* Usage (02h), */
423
+
0xB1, 0x02, /* Feature (Variable), */
424
+
0xC0, /* End Collection, */
425
+
0xC0 /* End Collection, */
426
+
};
427
+
384
428
/*
385
429
* Certain Logitech keyboards send in report #3 keys which are far
386
430
* above the logical maximum described in descriptor. This extends
387
431
* the original value of 0x28c of logical maximum to 0x104d
388
432
*/
389
433
static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
390
434
unsigned int *rsize)
391
435
{
392
436
struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
393
437
401
445
if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 51 &&
402
446
rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
403
447
rdesc[49] == 0x81 && rdesc[50] == 0x06) {
404
448
hid_info(hdev,
405
449
"fixing up rel/abs in Logitech report descriptor\n");
406
450
rdesc[33] = rdesc[50] = 0x02;
407
451
}
408
452
409
453
switch (hdev->product) {
410
454
455
+
case USB_DEVICE_ID_LOGITECH_WINGMAN_FG:
456
+
if (*rsize == FG_RDESC_ORIG_SIZE) {
457
+
hid_info(hdev,
458
+
"fixing up Logitech Wingman Formula GP report descriptor\n");
459
+
rdesc = fg_rdesc_fixed;
460
+
*rsize = sizeof(fg_rdesc_fixed);
461
+
} else {
462
+
hid_info(hdev,
463
+
"rdesc size test failed for formula gp\n");
464
+
}
465
+
break;
466
+
467
+
411
468
case USB_DEVICE_ID_LOGITECH_WINGMAN_FFG:
412
469
if (*rsize == FFG_RDESC_ORIG_SIZE) {
413
470
hid_info(hdev,
414
471
"fixing up Logitech Wingman Formula Force GP report descriptor\n");
415
472
rdesc = ffg_rdesc_fixed;
416
473
*rsize = sizeof(ffg_rdesc_fixed);
417
474
}
418
475
break;
419
476
420
477
/* Several wheels report as this id when operating in emulation mode. */
657
714
if ((drv_data->quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
658
715
usage->type == EV_REL || usage->type == EV_ABS))
659
716
clear_bit(usage->code, *bit);
660
717
661
718
/* Ensure that Logitech wheels are not given a default fuzz/flat value */
662
719
if (usage->type == EV_ABS && (usage->code == ABS_X ||
663
720
usage->code == ABS_Y || usage->code == ABS_Z ||
664
721
usage->code == ABS_RZ)) {
665
722
switch (hdev->product) {
666
723
case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
724
+
case USB_DEVICE_ID_LOGITECH_WINGMAN_FG:
667
725
case USB_DEVICE_ID_LOGITECH_WINGMAN_FFG:
668
726
case USB_DEVICE_ID_LOGITECH_WHEEL:
669
727
case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
670
728
case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
671
729
case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
672
730
case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
673
731
case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
674
732
case USB_DEVICE_ID_LOGITECH_WII_WHEEL:
675
733
case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
676
734
case USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL:
864
922
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
865
923
.driver_data = LG_FF4 },
866
924
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
867
925
.driver_data = LG_FF4 },
868
926
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL),
869
927
.driver_data = LG_FF4 },
870
928
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
871
929
.driver_data = LG_NOGET | LG_FF4 },
872
930
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
873
931
.driver_data = LG_FF4 },
932
+
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FG),
933
+
.driver_data = LG_NOGET },
874
934
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG),
875
935
.driver_data = LG_NOGET | LG_FF4 },
876
936
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
877
937
.driver_data = LG_NOGET | LG_FF2 },
878
938
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940),
879
939
.driver_data = LG_FF3 },
880
940
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
881
941
.driver_data = LG_RDESC_REL_ABS },
882
942
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
883
943
.driver_data = LG_RDESC_REL_ABS },