From patchwork Thu Jan 13 18:56:42 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolai Kondrashov X-Patchwork-Id: 476521 X-Patchwork-Delegate: jikos@jikos.cz Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0DIvEZB015564 for ; Thu, 13 Jan 2011 18:57:16 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756689Ab1AMS5P (ORCPT ); Thu, 13 Jan 2011 13:57:15 -0500 Received: from mail-ey0-f174.google.com ([209.85.215.174]:50053 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751835Ab1AMS5O (ORCPT ); Thu, 13 Jan 2011 13:57:14 -0500 Received: by eye27 with SMTP id 27so1038768eye.19 for ; Thu, 13 Jan 2011 10:57:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=jJlfJEIITdRGtk/mmSpcw8Z+W/d39c79gyj9ekxVAIA=; b=vBfmTF4ZWsDVKfCKRI9OBbVnE/nx09tpfbx/tTn+dEfuN7oacFRB1pii1TQooNV7Uu H1by/G2AdWHWFDPFCXDrkhz2/dZtVs89SAFolNEil4rYFnVTwcJiE98bHVSbRouKqWET ysqNRa9HWOo+HLiZfpxjek06Qzn4RjsfZ3ycU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=NkLy5cmpB0+oDycaJKLagRVugPy+P2HaI1A5YaxWAIWALCPw5q1ADdN/zxrZmF5GCa VcLa4zXNKQJa653GhTY5cA2jRUolaarZzxVkzCPjudAoHwRklW2PrmtL+hZeoWO+6CFb e3VKXZrjBQ4DQkkt8odim7HVBCpGlU7K9yMgU= Received: by 10.14.11.147 with SMTP id 19mr2071895eex.14.1294945033178; Thu, 13 Jan 2011 10:57:13 -0800 (PST) Received: from pippin.ponomarevs.spb.ru ([93.100.118.145]) by mx.google.com with ESMTPS id v59sm271013eeh.21.2011.01.13.10.57.10 (version=SSLv3 cipher=RC4-MD5); Thu, 13 Jan 2011 10:57:11 -0800 (PST) From: Nikolai Kondrashov To: Dmitry Torokhov Cc: linux-input , Vladislav Naumov , Nikolai Kondrashov Subject: [PATCH 2/3] Input: add support for DragonRise PID 0011 gamepad Date: Thu, 13 Jan 2011 21:56:42 +0300 Message-Id: <1294945003-7687-3-git-send-email-spbnick@gmail.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1294945003-7687-1-git-send-email-spbnick@gmail.com> References: <1294945003-7687-1-git-send-email-spbnick@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 13 Jan 2011 18:57:17 +0000 (UTC) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 88cb04e..bae1c09 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1298,6 +1298,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index bafd530..21c9f6b 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c @@ -19,6 +19,110 @@ #include "hid-ids.h" #include "hid-dr.h" +/* + * 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; @@ -37,7 +141,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: @@ -46,6 +159,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); @@ -53,6 +167,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, };