From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756006AbcAWKfp (ORCPT ); Sat, 23 Jan 2016 05:35:45 -0500 Received: from devoid-pointer.net ([31.31.77.140]:34697 "EHLO smtp.devoid-pointer.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751921AbcAWKfH (ORCPT ); Sat, 23 Jan 2016 05:35:07 -0500 From: =?UTF-8?q?Michal=20Mal=C3=BD?= To: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: dmitry.torokhov@gmail.com, jikos@kernel.org, elias.vds@gmail.com, edwin@velds.nl, simon@mungewell.org, =?UTF-8?q?Michal=20Mal=C3=BD?= Subject: [PATCH 2/2] Use usb_skelswitch module to switch Logitech G920 Racing Wheel to HID mode. Date: Sat, 23 Jan 2016 11:35:11 +0100 Message-Id: <1453545311-5721-3-git-send-email-madcatxster@devoid-pointer.net> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1453545311-5721-1-git-send-email-madcatxster@devoid-pointer.net> References: <1453545311-5721-1-git-send-email-madcatxster@devoid-pointer.net> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Tested-by: Elias Vanderstuyft Signed-off-by: Michal MalĂ˝ --- drivers/usb/common/Kconfig | 2 ++ drivers/usb/common/usb-skelswitch.c | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/drivers/usb/common/Kconfig b/drivers/usb/common/Kconfig index 6d9ec79..8ae9a1e 100644 --- a/drivers/usb/common/Kconfig +++ b/drivers/usb/common/Kconfig @@ -11,5 +11,7 @@ config USB_SKELSWITCH appear as a generic USB device. Say Y if you intend to use a device that requires this initial switch. + Devices that currently require this module: + - Logitech G920 Racing Wheel endif # USB_COMMON diff --git a/drivers/usb/common/usb-skelswitch.c b/drivers/usb/common/usb-skelswitch.c index ae72068..fc85c70 100644 --- a/drivers/usb/common/usb-skelswitch.c +++ b/drivers/usb/common/usb-skelswitch.c @@ -14,10 +14,70 @@ struct usb_skelswitch_vendor { }; static const struct usb_device_id usb_skelswitch_table[] = { + { USB_DEVICE(0x046d, 0xc261) }, { } }; +MODULE_DEVICE_TABLE(usb, usb_skelswitch_table); + +static int usb_skelswitch_lg_g920(struct usb_interface *intf) +{ + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev; + int idx; + int ret; + int xferred; + size_t buffer_size; + unsigned char cmd[] = { 0x0f, 0x00, 0x01, 0x01, 0x42 }; + const size_t cmd_len = ARRAY_SIZE(cmd); + u8 intr_out_addr = 0; + + udev = usb_get_dev(interface_to_usbdev(intf)); + iface_desc = intf->cur_altsetting; + for (idx = 0; idx < iface_desc->desc.bNumEndpoints; idx++) { + endpoint = &iface_desc->endpoint[idx].desc; + + if (usb_endpoint_is_int_out(endpoint)) { + intr_out_addr = endpoint->bEndpointAddress; + buffer_size = usb_endpoint_maxp(endpoint); + break; + } + } + + if (!intr_out_addr) { + dev_err(&udev->dev, "Logitech G920 - No interrupt out endpoint found"); + return -ENODEV; + } + + if (buffer_size < cmd_len) { + dev_err(&udev->dev, "usb_skelswitch: Logitech G920 - Output buffer is too small"); + return -ENODEV; + } + + + ret = usb_interrupt_msg(udev, usb_sndintpipe(udev, intr_out_addr), + cmd, cmd_len, &xferred, USB_CTRL_SET_TIMEOUT); + + if (ret) { + dev_err(&udev->dev, "LG G920: Failed to submit URB, errno: %d", ret); + return ret; + } + if (xferred != cmd_len) { + dev_err(&udev->dev, "LG G920: Incorrect number of bytes transferred: %d", xferred); + return -EIO; + } + + return 0; +} + +static const struct usb_skelswitch_product usb_skelswitch_logitech_devs[] = { + { 0xc261, usb_skelswitch_lg_g920 }, + { 0, NULL } +}; + static const struct usb_skelswitch_vendor usb_skelswitch_vendors[] = { + { 0x046d, usb_skelswitch_logitech_devs }, { 0, NULL } }; -- 2.7.0