| From foo@baz Fri Jan 24 11:58:18 PST 2014 |
| Date: Fri, 24 Jan 2014 11:58:18 -0800 |
| To: Greg KH <gregkh@linuxfoundation.org> |
| From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> |
| Subject: [PATCH] Input: xpad: disconnect all Wireless controllers at init |
| |
| From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> |
| |
| We initializing the driver/device, we really don't know how many |
| controllers are connected. So send a "disconnect all" command to the |
| base-station, and let the user pair the controllers in the order in |
| which they want them assigned. |
| |
| Note, this means we now do not "preallocate" all 4 devices when a single |
| wireless base station is seen, but require the device to be properly |
| connected to the base station before that can happen. The allocation of |
| the device happens in the next patch, not here, so in a way, this patch |
| breaks all wireless devices... |
| |
| Because we want to talk to the device, we have to set up the output urbs |
| no matter if we have CONFIG_JOYSTICK_XPAD_FF or |
| CONFIG_JOYSTICK_XPAD_LEDS enabled not, so take out the code that allows |
| those variables and code to be disabled (it's so small it should never |
| matter...) |
| |
| Signed-off-by: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/input/joystick/xpad.c | 46 +++++++++++++++++++++++++++++++----------- |
| 1 file changed, 34 insertions(+), 12 deletions(-) |
| |
| --- a/drivers/input/joystick/xpad.c |
| +++ b/drivers/input/joystick/xpad.c |
| @@ -278,12 +278,10 @@ struct usb_xpad { |
| 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; |
| @@ -537,7 +535,6 @@ static void xpad_bulk_out(struct urb *ur |
| } |
| } |
| |
| -#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) |
| static void xpad_irq_out(struct urb *urb) |
| { |
| struct usb_xpad *xpad = urb->context; |
| @@ -623,11 +620,6 @@ static void xpad_deinit_output(struct us |
| 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) |
| @@ -1091,11 +1083,41 @@ static int xpad_probe(struct usb_interfa |
| usb_kill_urb(xpad->irq_in); |
| goto fail9; |
| } |
| + |
| + /* |
| + * We don't know how to check the controller state at driver |
| + * load, so just disconnect them all, requiring the user to |
| + * repair the device in the order they want them used. Good |
| + * point is that we don't connect devices in "random" order, |
| + * but the extra step seems a bit harsh as other operating |
| + * systems don't require this at the moment. |
| + * |
| + * Power-off packet information came from an OS-X |
| + * reverse-engineered driver located at: |
| + * http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver#toc1 |
| + */ |
| + mutex_lock(&xpad->odata_mutex); |
| + xpad->odata[0] = 0x00; |
| + xpad->odata[1] = 0x00; |
| + xpad->odata[2] = 0x08; |
| + xpad->odata[3] = 0xC0; |
| + xpad->odata[4] = 0x00; |
| + xpad->odata[5] = 0x00; |
| + xpad->odata[6] = 0x00; |
| + 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; |
| + usb_submit_urb(xpad->irq_out, GFP_KERNEL); |
| + mutex_unlock(&xpad->odata_mutex); |
| + } else { |
| + xpad->pad_present = 1; |
| + error = xpad_init_input(xpad); |
| + if (error) |
| + goto fail9; |
| } |
| - xpad->pad_present = 1; |
| - error = xpad_init_input(xpad); |
| - if (error) |
| - goto fail9; |
| |
| return 0; |
| |