Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12187305 authored by Benjamin Valentin's avatar Benjamin Valentin Committed by Dmitry Torokhov
Browse files

Input: xpad - add rumble support for original xbox controller

parent ce841b94
Loading
Loading
Loading
Loading
+37 −16
Original line number Diff line number Diff line
@@ -530,7 +530,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
	struct usb_endpoint_descriptor *ep_irq_out;
	int error = -ENOMEM;

	if (xpad->xtype != XTYPE_XBOX360)
	if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
		return 0;

	xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
@@ -560,13 +560,13 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)

static void xpad_stop_output(struct usb_xpad *xpad)
{
	if (xpad->xtype == XTYPE_XBOX360)
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX)
		usb_kill_urb(xpad->irq_out);
}

static void xpad_deinit_output(struct usb_xpad *xpad)
{
	if (xpad->xtype == XTYPE_XBOX360) {
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) {
		usb_free_urb(xpad->irq_out);
		usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
				xpad->odata, xpad->odata_dma);
@@ -579,24 +579,45 @@ 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)
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{
	struct usb_xpad *xpad = input_get_drvdata(dev);

	if (effect->type == FF_RUMBLE) {
		__u16 strong = effect->u.rumble.strong_magnitude;
		__u16 weak = effect->u.rumble.weak_magnitude;

		switch (xpad->xtype) {

		case XTYPE_XBOX:
			xpad->odata[0] = 0x00;
			xpad->odata[1] = 0x06;
			xpad->odata[2] = 0x00;
			xpad->odata[3] = strong / 256;	/* left actuator */
			xpad->odata[4] = 0x00;
			xpad->odata[5] = weak / 256;	/* right actuator */
			xpad->irq_out->transfer_buffer_length = 6;

			return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);

		case XTYPE_XBOX360:
			xpad->odata[0] = 0x00;
			xpad->odata[1] = 0x08;
			xpad->odata[2] = 0x00;
		xpad->odata[3] = strong / 256;
		xpad->odata[4] = weak / 256;
			xpad->odata[3] = strong / 256;  /* left actuator? */
			xpad->odata[4] = weak / 256;	/* right actuator? */
			xpad->odata[5] = 0x00;
			xpad->odata[6] = 0x00;
			xpad->odata[7] = 0x00;
			xpad->irq_out->transfer_buffer_length = 8;
		usb_submit_urb(xpad->irq_out, GFP_ATOMIC);

			return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);

		default:
			dbg("%s - rumble command sent to unsupported xpad type: %d",
				__func__, xpad->xtype);
			return -1;
		}
	}

	return 0;
@@ -604,7 +625,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data,

static int xpad_init_ff(struct usb_xpad *xpad)
{
	if (xpad->xtype != XTYPE_XBOX360)
	if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
		return 0;

	input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);