.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * HID driver for some logitech "special" devices |
---|
3 | 4 | * |
---|
.. | .. |
---|
10 | 11 | */ |
---|
11 | 12 | |
---|
12 | 13 | /* |
---|
13 | | - * This program is free software; you can redistribute it and/or modify it |
---|
14 | | - * under the terms of the GNU General Public License as published by the Free |
---|
15 | | - * Software Foundation; either version 2 of the License, or (at your option) |
---|
16 | | - * any later version. |
---|
17 | 14 | */ |
---|
18 | 15 | |
---|
19 | 16 | #include <linux/device.h> |
---|
.. | .. |
---|
50 | 47 | #define MOMO_RDESC_ORIG_SIZE 87 |
---|
51 | 48 | #define MOMO2_RDESC_ORIG_SIZE 87 |
---|
52 | 49 | #define FFG_RDESC_ORIG_SIZE 85 |
---|
| 50 | +#define FG_RDESC_ORIG_SIZE 82 |
---|
53 | 51 | |
---|
54 | 52 | /* Fixed report descriptors for Logitech Driving Force (and Pro) |
---|
55 | 53 | * wheel controllers |
---|
.. | .. |
---|
381 | 379 | 0xC0 /* End Collection */ |
---|
382 | 380 | }; |
---|
383 | 381 | |
---|
| 382 | +static __u8 fg_rdesc_fixed[] = { |
---|
| 383 | +0x05, 0x01, /* Usage Page (Desktop), */ |
---|
| 384 | +0x09, 0x04, /* Usage (Joystik), */ |
---|
| 385 | +0xA1, 0x01, /* Collection (Application), */ |
---|
| 386 | +0xA1, 0x02, /* Collection (Logical), */ |
---|
| 387 | +0x15, 0x00, /* Logical Minimum (0), */ |
---|
| 388 | +0x26, 0xFF, 0x00, /* Logical Maximum (255), */ |
---|
| 389 | +0x35, 0x00, /* Physical Minimum (0), */ |
---|
| 390 | +0x46, 0xFF, 0x00, /* Physical Maximum (255), */ |
---|
| 391 | +0x75, 0x08, /* Report Size (8), */ |
---|
| 392 | +0x95, 0x01, /* Report Count (1), */ |
---|
| 393 | +0x09, 0x30, /* Usage (X), */ |
---|
| 394 | +0x81, 0x02, /* Input (Variable), */ |
---|
| 395 | +0xA4, /* Push, */ |
---|
| 396 | +0x25, 0x01, /* Logical Maximum (1), */ |
---|
| 397 | +0x45, 0x01, /* Physical Maximum (1), */ |
---|
| 398 | +0x75, 0x01, /* Report Size (1), */ |
---|
| 399 | +0x95, 0x02, /* Report Count (2), */ |
---|
| 400 | +0x81, 0x01, /* Input (Constant), */ |
---|
| 401 | +0x95, 0x06, /* Report Count (6), */ |
---|
| 402 | +0x05, 0x09, /* Usage Page (Button), */ |
---|
| 403 | +0x19, 0x01, /* Usage Minimum (01h), */ |
---|
| 404 | +0x29, 0x06, /* Usage Maximum (06h), */ |
---|
| 405 | +0x81, 0x02, /* Input (Variable), */ |
---|
| 406 | +0x05, 0x01, /* Usage Page (Desktop), */ |
---|
| 407 | +0xB4, /* Pop, */ |
---|
| 408 | +0x81, 0x02, /* Input (Constant), */ |
---|
| 409 | +0x09, 0x31, /* Usage (Y), */ |
---|
| 410 | +0x81, 0x02, /* Input (Variable), */ |
---|
| 411 | +0x09, 0x32, /* Usage (Z), */ |
---|
| 412 | +0x81, 0x02, /* Input (Variable), */ |
---|
| 413 | +0xC0, /* End Collection, */ |
---|
| 414 | +0xA1, 0x02, /* Collection (Logical), */ |
---|
| 415 | +0x26, 0xFF, 0x00, /* Logical Maximum (255), */ |
---|
| 416 | +0x46, 0xFF, 0x00, /* Physical Maximum (255), */ |
---|
| 417 | +0x75, 0x08, /* Report Size (8), */ |
---|
| 418 | +0x95, 0x04, /* Report Count (4), */ |
---|
| 419 | +0x09, 0x02, /* Usage (02h), */ |
---|
| 420 | +0xB1, 0x02, /* Feature (Variable), */ |
---|
| 421 | +0xC0, /* End Collection, */ |
---|
| 422 | +0xC0 /* End Collection, */ |
---|
| 423 | +}; |
---|
| 424 | + |
---|
384 | 425 | /* |
---|
385 | 426 | * Certain Logitech keyboards send in report #3 keys which are far |
---|
386 | 427 | * above the logical maximum described in descriptor. This extends |
---|
.. | .. |
---|
407 | 448 | } |
---|
408 | 449 | |
---|
409 | 450 | switch (hdev->product) { |
---|
| 451 | + |
---|
| 452 | + case USB_DEVICE_ID_LOGITECH_WINGMAN_FG: |
---|
| 453 | + if (*rsize == FG_RDESC_ORIG_SIZE) { |
---|
| 454 | + hid_info(hdev, |
---|
| 455 | + "fixing up Logitech Wingman Formula GP report descriptor\n"); |
---|
| 456 | + rdesc = fg_rdesc_fixed; |
---|
| 457 | + *rsize = sizeof(fg_rdesc_fixed); |
---|
| 458 | + } else { |
---|
| 459 | + hid_info(hdev, |
---|
| 460 | + "rdesc size test failed for formula gp\n"); |
---|
| 461 | + } |
---|
| 462 | + break; |
---|
| 463 | + |
---|
410 | 464 | |
---|
411 | 465 | case USB_DEVICE_ID_LOGITECH_WINGMAN_FFG: |
---|
412 | 466 | if (*rsize == FFG_RDESC_ORIG_SIZE) { |
---|
.. | .. |
---|
664 | 718 | usage->code == ABS_RZ)) { |
---|
665 | 719 | switch (hdev->product) { |
---|
666 | 720 | case USB_DEVICE_ID_LOGITECH_G29_WHEEL: |
---|
| 721 | + case USB_DEVICE_ID_LOGITECH_WINGMAN_FG: |
---|
667 | 722 | case USB_DEVICE_ID_LOGITECH_WINGMAN_FFG: |
---|
668 | 723 | case USB_DEVICE_ID_LOGITECH_WHEEL: |
---|
669 | 724 | case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: |
---|
.. | .. |
---|
822 | 877 | } |
---|
823 | 878 | |
---|
824 | 879 | static const struct hid_device_id lg_devices[] = { |
---|
825 | | - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), |
---|
826 | | - .driver_data = LG_RDESC | LG_WIRELESS }, |
---|
827 | 880 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER), |
---|
828 | | - .driver_data = LG_RDESC | LG_WIRELESS }, |
---|
829 | | - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2), |
---|
830 | 881 | .driver_data = LG_RDESC | LG_WIRELESS }, |
---|
831 | 882 | |
---|
832 | 883 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER), |
---|
.. | .. |
---|
879 | 930 | .driver_data = LG_NOGET | LG_FF4 }, |
---|
880 | 931 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), |
---|
881 | 932 | .driver_data = LG_FF4 }, |
---|
| 933 | + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FG), |
---|
| 934 | + .driver_data = LG_NOGET }, |
---|
882 | 935 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG), |
---|
883 | 936 | .driver_data = LG_NOGET | LG_FF4 }, |
---|
884 | 937 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), |
---|