From patchwork Sat Jan 1 03:00:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christopher Snowhill X-Patchwork-Id: 442681 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 p013Jt84026055 for ; Sat, 1 Jan 2011 03:19:56 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751901Ab1AADTx (ORCPT ); Fri, 31 Dec 2010 22:19:53 -0500 Received: from bender.sjeng.org ([94.75.209.35]:44809 "EHLO mail.sjeng.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751775Ab1AADTw (ORCPT ); Fri, 31 Dec 2010 22:19:52 -0500 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Sat, 01 Jan 2011 03:19:56 +0000 (UTC) X-Greylist: delayed 1160 seconds by postgrey-1.27 at vger.kernel.org; Fri, 31 Dec 2010 22:19:52 EST Received: from sabin.lan (99-130-104-166.lightspeed.irvnca.sbcglobal.net [99.130.104.166]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.sjeng.org (Postfix) with ESMTP id 5214F12C807A; Sat, 1 Jan 2011 04:00:31 +0100 (CET) From: Chris Moeller Organization: NoWork, Inc. To: dmitry.torokhov@gmail.com Subject: Input: Feature/bug fix for xpad driver Date: Fri, 31 Dec 2010 19:00:25 -0800 User-Agent: KMail/1.13.5 (Linux/2.6.35.10-74.fc14.x86_64; KDE/4.5.4; x86_64; ; ) Cc: linux-input@vger.kernel.org MIME-Version: 1.0 Message-Id: <201012311900.25413.kode54@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org --- a/drivers/input/joystick/xpad.c 2010-12-31 12:11:53.186851487 -0800 +++ b/drivers/input/joystick/xpad.c 2010-12-31 17:51:22.212307496 -0800 @@ -240,20 +240,17 @@ struct usb_xpad { struct usb_device *udev; /* usb device */ int pad_present; + + int interface_number; struct urb *irq_in; /* urb for interrupt in report */ unsigned char *idata; /* input data */ dma_addr_t idata_dma; - struct urb *bulk_out; - unsigned char *bdata; - -#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) struct urb *irq_out; /* urb for interrupt out report */ unsigned char *odata; /* output data */ dma_addr_t odata_dma; struct mutex odata_mutex; -#endif #if defined(CONFIG_JOYSTICK_XPAD_LEDS) struct xpad_led *led; @@ -417,13 +414,15 @@ static void xpad360_process_packet(struc * */ +static void xpad_send_led_command(struct usb_xpad *xpad, int command, int mutex); + static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { /* Presence change */ if (data[0] & 0x08) { if (data[1] & 0x80) { xpad->pad_present = 1; - usb_submit_urb(xpad->bulk_out, GFP_ATOMIC); + xpad_send_led_command(xpad, 0x42 + ((xpad->interface_number / 2) & 3), 0); } else xpad->pad_present = 0; } @@ -477,24 +476,6 @@ exit: __func__, retval); } -static void xpad_bulk_out(struct urb *urb) -{ - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, urb->status); - break; - default: - dbg("%s - nonzero urb status received: %d", __func__, urb->status); - } -} - -#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) static void xpad_irq_out(struct urb *urb) { int retval, status; @@ -530,9 +511,6 @@ static int xpad_init_output(struct usb_i struct usb_endpoint_descriptor *ep_irq_out; int error = -ENOMEM; - if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) - return 0; - xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->odata_dma); if (!xpad->odata) @@ -560,23 +538,15 @@ static int xpad_init_output(struct usb_i static void xpad_stop_output(struct usb_xpad *xpad) { - if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) - usb_kill_urb(xpad->irq_out); + usb_kill_urb(xpad->irq_out); } static void xpad_deinit_output(struct usb_xpad *xpad) { - if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) { - usb_free_urb(xpad->irq_out); - usb_free_coherent(xpad->udev, XPAD_PKT_LEN, - xpad->odata, xpad->odata_dma); - } + usb_free_urb(xpad->irq_out); + usb_free_coherent(xpad->udev, XPAD_PKT_LEN, + xpad->odata, xpad->odata_dma); } -#else -static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } -static void xpad_deinit_output(struct usb_xpad *xpad) {} -static void xpad_stop_output(struct usb_xpad *xpad) {} -#endif #ifdef CONFIG_JOYSTICK_XPAD_FF static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) @@ -613,6 +583,23 @@ static int xpad_play_effect(struct input return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); + case XTYPE_XBOX360W: + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x01; + xpad->odata[2] = 0x0F; + xpad->odata[3] = 0xC0; + xpad->odata[4] = 0x00; + xpad->odata[5] = strong / 256; + xpad->odata[6] = weak / 256; + xpad->odata[7] = 0x00; + xpad->odata[8] = 0x00; + xpad->odata[9] = 0x00; + xpad->odata[10] = 0x00; + xpad->odata[11] = 0x00; + xpad->irq_out->transfer_buffer_length = 12; + + return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); + default: dbg("%s - rumble command sent to unsupported xpad type: %d", __func__, xpad->xtype); @@ -625,7 +612,7 @@ static int xpad_play_effect(struct input static int xpad_init_ff(struct usb_xpad *xpad) { - if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) + if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX && xpad->xtype != XTYPE_XBOX360W) return 0;