|
@@ -145,6 +145,110 @@ static inline int drff_init(struct hid_device *hid)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+/*
|
|
|
+ * The original descriptor of joystick with PID 0x0011, represented by DVTech PC
|
|
|
+ * JS19. It seems both copied from another device and a result of confusion
|
|
|
+ * either about the specification or about the program used to create the
|
|
|
+ * descriptor. In any case, it's a wonder it works on Windows.
|
|
|
+ *
|
|
|
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
|
|
|
+ * Usage (Joystik), ; Joystik (04h, application collection)
|
|
|
+ * Collection (Application),
|
|
|
+ * Collection (Logical),
|
|
|
+ * Report Size (8),
|
|
|
+ * Report Count (5),
|
|
|
+ * Logical Minimum (0),
|
|
|
+ * Logical Maximum (255),
|
|
|
+ * Physical Minimum (0),
|
|
|
+ * Physical Maximum (255),
|
|
|
+ * Usage (X), ; X (30h, dynamic value)
|
|
|
+ * Usage (X), ; X (30h, dynamic value)
|
|
|
+ * Usage (X), ; X (30h, dynamic value)
|
|
|
+ * Usage (X), ; X (30h, dynamic value)
|
|
|
+ * Usage (Y), ; Y (31h, dynamic value)
|
|
|
+ * Input (Variable),
|
|
|
+ * Report Size (4),
|
|
|
+ * Report Count (1),
|
|
|
+ * Logical Maximum (7),
|
|
|
+ * Physical Maximum (315),
|
|
|
+ * Unit (Degrees),
|
|
|
+ * Usage (00h),
|
|
|
+ * Input (Variable, Null State),
|
|
|
+ * Unit,
|
|
|
+ * Report Size (1),
|
|
|
+ * Report Count (10),
|
|
|
+ * Logical Maximum (1),
|
|
|
+ * Physical Maximum (1),
|
|
|
+ * Usage Page (Button), ; Button (09h)
|
|
|
+ * Usage Minimum (01h),
|
|
|
+ * Usage Maximum (0Ah),
|
|
|
+ * Input (Variable),
|
|
|
+ * Usage Page (FF00h), ; FF00h, vendor-defined
|
|
|
+ * Report Size (1),
|
|
|
+ * Report Count (10),
|
|
|
+ * Logical Maximum (1),
|
|
|
+ * Physical Maximum (1),
|
|
|
+ * Usage (01h),
|
|
|
+ * Input (Variable),
|
|
|
+ * End Collection,
|
|
|
+ * Collection (Logical),
|
|
|
+ * Report Size (8),
|
|
|
+ * Report Count (4),
|
|
|
+ * Physical Maximum (255),
|
|
|
+ * Logical Maximum (255),
|
|
|
+ * Usage (02h),
|
|
|
+ * Output (Variable),
|
|
|
+ * End Collection,
|
|
|
+ * End Collection
|
|
|
+ */
|
|
|
+
|
|
|
+/* Size of the original descriptor of the PID 0x0011 joystick */
|
|
|
+#define PID0011_RDESC_ORIG_SIZE 101
|
|
|
+
|
|
|
+/* Fixed report descriptor for PID 0x011 joystick */
|
|
|
+static __u8 pid0011_rdesc_fixed[] = {
|
|
|
+ 0x05, 0x01, /* Usage Page (Desktop), */
|
|
|
+ 0x09, 0x04, /* Usage (Joystik), */
|
|
|
+ 0xA1, 0x01, /* Collection (Application), */
|
|
|
+ 0xA1, 0x02, /* Collection (Logical), */
|
|
|
+ 0x14, /* Logical Minimum (0), */
|
|
|
+ 0x75, 0x08, /* Report Size (8), */
|
|
|
+ 0x95, 0x03, /* Report Count (3), */
|
|
|
+ 0x81, 0x01, /* Input (Constant), */
|
|
|
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
|
|
+ 0x95, 0x02, /* Report Count (2), */
|
|
|
+ 0x09, 0x30, /* Usage (X), */
|
|
|
+ 0x09, 0x31, /* Usage (Y), */
|
|
|
+ 0x81, 0x02, /* Input (Variable), */
|
|
|
+ 0x75, 0x01, /* Report Size (1), */
|
|
|
+ 0x95, 0x04, /* Report Count (4), */
|
|
|
+ 0x81, 0x01, /* Input (Constant), */
|
|
|
+ 0x25, 0x01, /* Logical Maximum (1), */
|
|
|
+ 0x95, 0x0A, /* Report Count (10), */
|
|
|
+ 0x05, 0x09, /* Usage Page (Button), */
|
|
|
+ 0x19, 0x01, /* Usage Minimum (01h), */
|
|
|
+ 0x29, 0x0A, /* Usage Maximum (0Ah), */
|
|
|
+ 0x81, 0x02, /* Input (Variable), */
|
|
|
+ 0x95, 0x0A, /* Report Count (10), */
|
|
|
+ 0x81, 0x01, /* Input (Constant), */
|
|
|
+ 0xC0, /* End Collection, */
|
|
|
+ 0xC0 /* End Collection */
|
|
|
+};
|
|
|
+
|
|
|
+static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|
|
+ unsigned int *rsize)
|
|
|
+{
|
|
|
+ switch (hdev->product) {
|
|
|
+ case 0x0011:
|
|
|
+ if (*rsize == PID0011_RDESC_ORIG_SIZE) {
|
|
|
+ rdesc = pid0011_rdesc_fixed;
|
|
|
+ *rsize = sizeof(pid0011_rdesc_fixed);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return rdesc;
|
|
|
+}
|
|
|
+
|
|
|
static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|
|
{
|
|
|
int ret;
|
|
@@ -163,7 +267,16 @@ static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
- drff_init(hdev);
|
|
|
+ switch (hdev->product) {
|
|
|
+ case 0x0006:
|
|
|
+ ret = drff_init(hdev);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&hdev->dev, "force feedback init failed\n");
|
|
|
+ hid_hw_stop(hdev);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
err:
|
|
@@ -172,6 +285,7 @@ err:
|
|
|
|
|
|
static const struct hid_device_id dr_devices[] = {
|
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), },
|
|
|
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011), },
|
|
|
{ }
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(hid, dr_devices);
|
|
@@ -179,6 +293,7 @@ MODULE_DEVICE_TABLE(hid, dr_devices);
|
|
|
static struct hid_driver dr_driver = {
|
|
|
.name = "dragonrise",
|
|
|
.id_table = dr_devices,
|
|
|
+ .report_fixup = dr_report_fixup,
|
|
|
.probe = dr_probe,
|
|
|
};
|
|
|
|