From patchwork Sat Feb 7 13:48:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lauri Kasanen X-Patchwork-Id: 5796171 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0AD969F30C for ; Sat, 7 Feb 2015 13:47:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1CB3920154 for ; Sat, 7 Feb 2015 13:47:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 918D520125 for ; Sat, 7 Feb 2015 13:47:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753949AbbBGNqy (ORCPT ); Sat, 7 Feb 2015 08:46:54 -0500 Received: from mout.gmx.net ([212.227.17.21]:54423 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753304AbbBGNqx (ORCPT ); Sat, 7 Feb 2015 08:46:53 -0500 Received: from Valinor ([84.251.16.90]) by mail.gmx.com (mrgmx103) with ESMTPA (Nemesis) id 0Lqyi7-1XgKvJ2hOd-00eaNH; Sat, 07 Feb 2015 14:46:42 +0100 Date: Sat, 7 Feb 2015 15:48:59 +0200 From: Lauri Kasanen To: jkosina@suse.cz, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Cc: ao2@ao2.it, AndrewD207@aol.com Subject: [PATCH] HID: sony: Enable Gasia third-party PS3 controllers Message-Id: <20150207154859.89a7e4e3.cand@gmx.com> X-Mailer: Sylpheed 3.1.4 (GTK+ 2.18.6; x86_64-unknown-linux-gnu) Mime-Version: 1.0 X-Provags-ID: V03:K0:ezCK3cX8YHguNam+lbXUSGSLXQFShEE8vLqfchPiEqWOc6GCXOV 7tNNVW1+7mhq/5+t2vLMQ6CJQ7PpC4Xe2+8SV5zUwQQGbRKX2TxEOXiHeqwl6IE/34s+9Ps n7FKinUER1yMNCDCVoxgWVRHrtqkka4GAfjfGXO89j/i5UTQkThoK0Lhx8o2A7ocdlJ0u3N XdE/mdEKk75UMUHYtShsQ== X-UI-Out-Filterresults: notjunk:1; Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Without this, my "Gasia Co.,Ltd PS(R) Gamepad" would not send any events. Now everything works including the leds. Based on work by Andrew Haines and Antonio Ospite. cc: Antonio Ospite cc: Andrew Haines Signed-off-by: Lauri Kasanen --- drivers/hid/hid-sony.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) Antonio's original approach was not enough; it enabled the events, but only for a few seconds, then the controller timed out and sent no more. Andrew's did more than was necessary. This is a combination of the two, against Linus' git. diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 31e9d25..de93386 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "hid-ids.h" @@ -1130,8 +1131,12 @@ static void sony_input_configured(struct hid_device *hdev, */ static int sixaxis_set_operational_usb(struct hid_device *hdev) { + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct usb_device *dev = interface_to_usbdev(intf); int ret; - char *buf = kmalloc(18, GFP_KERNEL); + char *buf = kmalloc(65, GFP_KERNEL); + unsigned char buf2[] = { 0x00 }; + int transfered; if (!buf) return -ENOMEM; @@ -1140,7 +1145,24 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) HID_REQ_GET_REPORT); if (ret < 0) - hid_err(hdev, "can't set operational mode\n"); + hid_err(hdev, "can't set operational mode on the control EP\n"); + + /* + * Some compatible controllers like the Speedlink Strike FX and + * Gasia need another query plus an USB interrupt to get operational. + */ + ret = hid_hw_raw_request(hdev, 0xf5, buf, 64, HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + + if (ret < 0) + hid_err(hdev, "can't set operational mode on the interrupt EP\n"); + + ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x02), + buf2, sizeof(buf2), + &transfered, USB_CTRL_SET_TIMEOUT); + + if (ret < 0) + hid_err(hdev, "can't set operational mode on the interrupt EP\n"); kfree(buf);