diff options
author | Benjamin Valentin <benpicco@zedat.fu-berlin.de> | 2010-01-21 23:19:06 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-01-25 01:42:10 -0500 |
commit | 121873059fbe3b4f1ddb4781b578a2128e78be4a (patch) | |
tree | f0ac6bb2d3c07c1110cc302a922377c39c93e2b6 /drivers/input | |
parent | ce841b945b84bf7360aa32e60ddaa1e9ccae3e96 (diff) |
Input: xpad - add rumble support for original xbox controller
Signed-off-by: Benjamin Valentin <benpicco@zedat.fu-berlin.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/joystick/xpad.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 66be6901619d..9b3353b404da 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -530,7 +530,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
530 | struct usb_endpoint_descriptor *ep_irq_out; | 530 | struct usb_endpoint_descriptor *ep_irq_out; |
531 | int error = -ENOMEM; | 531 | int error = -ENOMEM; |
532 | 532 | ||
533 | if (xpad->xtype != XTYPE_XBOX360) | 533 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
534 | return 0; | 534 | return 0; |
535 | 535 | ||
536 | xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, | 536 | 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) | |||
560 | 560 | ||
561 | static void xpad_stop_output(struct usb_xpad *xpad) | 561 | static void xpad_stop_output(struct usb_xpad *xpad) |
562 | { | 562 | { |
563 | if (xpad->xtype == XTYPE_XBOX360) | 563 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) |
564 | usb_kill_urb(xpad->irq_out); | 564 | usb_kill_urb(xpad->irq_out); |
565 | } | 565 | } |
566 | 566 | ||
567 | static void xpad_deinit_output(struct usb_xpad *xpad) | 567 | static void xpad_deinit_output(struct usb_xpad *xpad) |
568 | { | 568 | { |
569 | if (xpad->xtype == XTYPE_XBOX360) { | 569 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) { |
570 | usb_free_urb(xpad->irq_out); | 570 | usb_free_urb(xpad->irq_out); |
571 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, | 571 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, |
572 | xpad->odata, xpad->odata_dma); | 572 | xpad->odata, xpad->odata_dma); |
@@ -579,24 +579,45 @@ static void xpad_stop_output(struct usb_xpad *xpad) {} | |||
579 | #endif | 579 | #endif |
580 | 580 | ||
581 | #ifdef CONFIG_JOYSTICK_XPAD_FF | 581 | #ifdef CONFIG_JOYSTICK_XPAD_FF |
582 | static int xpad_play_effect(struct input_dev *dev, void *data, | 582 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) |
583 | struct ff_effect *effect) | ||
584 | { | 583 | { |
585 | struct usb_xpad *xpad = input_get_drvdata(dev); | 584 | struct usb_xpad *xpad = input_get_drvdata(dev); |
586 | 585 | ||
587 | if (effect->type == FF_RUMBLE) { | 586 | if (effect->type == FF_RUMBLE) { |
588 | __u16 strong = effect->u.rumble.strong_magnitude; | 587 | __u16 strong = effect->u.rumble.strong_magnitude; |
589 | __u16 weak = effect->u.rumble.weak_magnitude; | 588 | __u16 weak = effect->u.rumble.weak_magnitude; |
590 | xpad->odata[0] = 0x00; | 589 | |
591 | xpad->odata[1] = 0x08; | 590 | switch (xpad->xtype) { |
592 | xpad->odata[2] = 0x00; | 591 | |
593 | xpad->odata[3] = strong / 256; | 592 | case XTYPE_XBOX: |
594 | xpad->odata[4] = weak / 256; | 593 | xpad->odata[0] = 0x00; |
595 | xpad->odata[5] = 0x00; | 594 | xpad->odata[1] = 0x06; |
596 | xpad->odata[6] = 0x00; | 595 | xpad->odata[2] = 0x00; |
597 | xpad->odata[7] = 0x00; | 596 | xpad->odata[3] = strong / 256; /* left actuator */ |
598 | xpad->irq_out->transfer_buffer_length = 8; | 597 | xpad->odata[4] = 0x00; |
599 | usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | 598 | xpad->odata[5] = weak / 256; /* right actuator */ |
599 | xpad->irq_out->transfer_buffer_length = 6; | ||
600 | |||
601 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | ||
602 | |||
603 | case XTYPE_XBOX360: | ||
604 | xpad->odata[0] = 0x00; | ||
605 | xpad->odata[1] = 0x08; | ||
606 | xpad->odata[2] = 0x00; | ||
607 | xpad->odata[3] = strong / 256; /* left actuator? */ | ||
608 | xpad->odata[4] = weak / 256; /* right actuator? */ | ||
609 | xpad->odata[5] = 0x00; | ||
610 | xpad->odata[6] = 0x00; | ||
611 | xpad->odata[7] = 0x00; | ||
612 | xpad->irq_out->transfer_buffer_length = 8; | ||
613 | |||
614 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | ||
615 | |||
616 | default: | ||
617 | dbg("%s - rumble command sent to unsupported xpad type: %d", | ||
618 | __func__, xpad->xtype); | ||
619 | return -1; | ||
620 | } | ||
600 | } | 621 | } |
601 | 622 | ||
602 | return 0; | 623 | return 0; |
@@ -604,7 +625,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, | |||
604 | 625 | ||
605 | static int xpad_init_ff(struct usb_xpad *xpad) | 626 | static int xpad_init_ff(struct usb_xpad *xpad) |
606 | { | 627 | { |
607 | if (xpad->xtype != XTYPE_XBOX360) | 628 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
608 | return 0; | 629 | return 0; |
609 | 630 | ||
610 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | 631 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); |