Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-08 Thread Dmitry Torokhov
Hi Jan,

On Thursday 03 May 2007 17:41, Jan Kratochvil wrote:
> Hi again,
>what do you think about this? (This patch will work only against last 
> gamepad rumble support patch)
> 
> Thanks for your time
>   Jan Kratochvil
> 
> BigX button on xbox360 gamepad is surrounded by 4 green leds. This
> patch adds support to control them.
> 
> This device understand to 14 messages (described at 
> http://www.free60.org/wiki/Gamepad#LED_Control).
> 
> Control is done through event interface, message type EV_LED. EV_LED isn't 
> perfect match because you are actualy not turning some led on or off but 
> more likely you are telling the gamepad what "flash effect" it should 
> play.
> 

I would rather it used led subsystem for this.

-- 
Dmitry
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-08 Thread Dmitry Torokhov
On Thursday 03 May 2007 09:04, Jan Kratochvil wrote:
> Hi Dmitry,
>thanks for feedback. Improved version of this patch follows:
> 
> It is enabled only if CONFIG_XPAD_FF is set to y.
> 
> Implementation is using force feedback support for memoryless devices.

Applied with couple cosmetic changes, thank you.

-- 
Dmitry
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-08 Thread Dmitry Torokhov
On Thursday 03 May 2007 09:04, Jan Kratochvil wrote:
 Hi Dmitry,
thanks for feedback. Improved version of this patch follows:
 
 It is enabled only if CONFIG_XPAD_FF is set to y.
 
 Implementation is using force feedback support for memoryless devices.

Applied with couple cosmetic changes, thank you.

-- 
Dmitry
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-08 Thread Dmitry Torokhov
Hi Jan,

On Thursday 03 May 2007 17:41, Jan Kratochvil wrote:
 Hi again,
what do you think about this? (This patch will work only against last 
 gamepad rumble support patch)
 
 Thanks for your time
   Jan Kratochvil
 
 BigX button on xbox360 gamepad is surrounded by 4 green leds. This
 patch adds support to control them.
 
 This device understand to 14 messages (described at 
 http://www.free60.org/wiki/Gamepad#LED_Control).
 
 Control is done through event interface, message type EV_LED. EV_LED isn't 
 perfect match because you are actualy not turning some led on or off but 
 more likely you are telling the gamepad what flash effect it should 
 play.
 

I would rather it used led subsystem for this.

-- 
Dmitry
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-03 Thread Jan Kratochvil

Hi again,
  what do you think about this? (This patch will work only against last 
gamepad rumble support patch)


Thanks for your time
Jan Kratochvil

BigX button on xbox360 gamepad is surrounded by 4 green leds. This
patch adds support to control them.

This device understand to 14 messages (described at 
http://www.free60.org/wiki/Gamepad#LED_Control).


Control is done through event interface, message type EV_LED. EV_LED isn't 
perfect match because you are actualy not turning some led on or off but 
more likely you are telling the gamepad what "flash effect" it should 
play.


Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]>
---
 drivers/usb/input/xpad.c |   31 ---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index d117e71..8b38990 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -397,13 +397,33 @@ int xpad_play_effect(struct input_dev *d
return 0;
 }

+int xpad_input_event(struct input_dev *dev, unsigned int type,
+unsigned int code, int value)
+{
+   switch (type) {
+   case EV_FF:
+   return input_ff_event(dev,type,code,value);
+   case EV_LED: {
+   struct usb_xpad *xpad = dev->private;
+   change_bit(code,dev->led);
+   xpad->odata[0] = 0x01;
+   xpad->odata[1] = 0x03;
+   xpad->odata[2] = code;
+   usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+   return 0;
+   }
+   default:
+   return -EINVAL;
+   }
+}
+
 static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
 {
if (xpad->xtype == TYPE_XBOX360) {
struct usb_endpoint_descriptor *ep_irq_out;
-   int rv;
+   int i;

-   xpad->dev->evbit[0] |= BIT(EV_FF);
+   xpad->dev->evbit[0] |= BIT(EV_FF) | BIT(EV_LED);

xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
   GFP_ATOMIC, >odata_dma );
@@ -422,11 +442,16 @@ static int xpad_init_ff(struct usb_inter
xpad->irq_out->transfer_dma = xpad->odata_dma;
xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

-   set_bit( FF_RUMBLE, xpad->dev->ffbit );
+   set_bit(FF_RUMBLE, xpad->dev->ffbit);
+   for (i=0;i<16;++i)
+   set_bit(i, xpad->dev->ledbit);
+
if (input_ff_create_memless(xpad->dev, NULL, xpad_play_effect)) 
{
goto fail2;
}

+   xpad->dev->event = xpad_input_event;
+
return 0;

 fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, 
xpad->odata_dma);
--
1.4.3.4



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-03 Thread Jan Kratochvil

Hi Dmitry,
  thanks for feedback. Improved version of this patch follows:

It is enabled only if CONFIG_XPAD_FF is set to y.

Implementation is using force feedback support for memoryless devices.

Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]>
---
 drivers/usb/input/Kconfig |7 +++
 drivers/usb/input/xpad.c  |  116 -
 2 files changed, 122 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index a792e42..8963522 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -149,6 +149,13 @@ config USB_XPAD
  To compile this driver as a module, choose M here: the
  module will be called xpad.

+config XPAD_FF
+   bool "X-Box gamepad rumble support"
+   depends on USB_XPAD && INPUT
+   select INPUT_FF_MEMLESS
+   ---help---
+	  Say Y here if you want to take advantage of xbox 360 rumble features. 
+

 config USB_ATI_REMOTE
tristate "ATI / X10 USB RF remote control"
depends on USB && INPUT
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 75d1a62..d117e71 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -192,6 +192,12 @@ struct usb_xpad {
unsigned char *idata;   /* input data */
dma_addr_t idata_dma;

+#ifdef CONFIG_XPAD_FF
+   struct urb *irq_out;/* urb for interrupt out report */
+   unsigned char *odata;   /* output data */
+   dma_addr_t odata_dma;
+#endif
+
char phys[65];  /* physical device path */

int dpad_mapping;   /* map d-pad to buttons or to axes */
@@ -344,6 +350,106 @@ exit:
 __FUNCTION__, retval);
 }

+#ifdef CONFIG_XPAD_FF
+static void xpad_irq_out(struct urb *urb)
+{
+   int retval;
+
+   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",  
__FUNCTION__, urb->status);
+   return;
+   default:
+   dbg("%s - nonzero urb status received: %d",  __FUNCTION__, 
urb->status);
+   goto exit;
+   }
+
+exit:
+   retval = usb_submit_urb(urb, GFP_ATOMIC);
+   if (retval)
+   err("%s - usb_submit_urb failed with result %d",
+  __FUNCTION__, retval);
+} 
+

+int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect 
*effect)
+{
+   struct usb_xpad *xpad = dev->private;
+   if (effect->type == FF_RUMBLE) {
+   __u16 strong = effect->u.rumble.strong_magnitude;
+   __u16 weak = effect->u.rumble.weak_magnitude;
+		xpad->odata[0] = 0x00; 
+		xpad->odata[1] = 0x08; 
+		xpad->odata[2] = 0x00; 
+		xpad->odata[3] = strong / 256;
+		xpad->odata[4] = weak / 256; 
+		xpad->odata[5] = 0x00;

+   xpad->odata[6] = 0x00;
+   xpad->odata[7] = 0x00;
+   usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+   }
+
+   return 0;
+}
+
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad->xtype == XTYPE_XBOX360) {
+   struct usb_endpoint_descriptor *ep_irq_out;
+   int rv;
+
+   xpad->dev->evbit[0] |= BIT(EV_FF);
+
+		xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, 
+	   GFP_ATOMIC, >odata_dma );

+   if (!xpad->idata)
+   goto fail1;
+
+   xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
+   if (!xpad->irq_out)
+   goto fail2;
+
+   ep_irq_out = >cur_altsetting->endpoint[1].desc;
+   usb_fill_int_urb(xpad->irq_out, xpad->udev,
+usb_sndintpipe(xpad->udev, 
ep_irq_out->bEndpointAddress),
+xpad->odata, XPAD_PKT_LEN,
+xpad_irq_out, xpad, ep_irq_out->bInterval);
+   xpad->irq_out->transfer_dma = xpad->odata_dma;
+   xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+   set_bit( FF_RUMBLE, xpad->dev->ffbit );
+   if (input_ff_create_memless(xpad->dev, NULL, xpad_play_effect)) 
{
+			goto fail2; 
+		}

+
+   return 0;
+
+fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, 
xpad->odata_dma);
+fail1: 
+		return -ENOMEM;

+   }
+   return 0;
+}
+
+static void xpad_deinit_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad->xtype == XTYPE_XBOX360) {
+   usb_free_urb(xpad->irq_out);
+   usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+   xpad->odata, xpad->odata_dma);
+   }
+}
+#else

Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-03 Thread Jan Kratochvil

Hi Dmitry,
  thanks for feedback. Improved version of this patch follows:

It is enabled only if CONFIG_XPAD_FF is set to y.

Implementation is using force feedback support for memoryless devices.

Signed-off-by: Jan Kratochvil [EMAIL PROTECTED]
---
 drivers/usb/input/Kconfig |7 +++
 drivers/usb/input/xpad.c  |  116 -
 2 files changed, 122 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index a792e42..8963522 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -149,6 +149,13 @@ config USB_XPAD
  To compile this driver as a module, choose M here: the
  module will be called xpad.

+config XPAD_FF
+   bool X-Box gamepad rumble support
+   depends on USB_XPAD  INPUT
+   select INPUT_FF_MEMLESS
+   ---help---
+	  Say Y here if you want to take advantage of xbox 360 rumble features. 
+

 config USB_ATI_REMOTE
tristate ATI / X10 USB RF remote control
depends on USB  INPUT
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 75d1a62..d117e71 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -192,6 +192,12 @@ struct usb_xpad {
unsigned char *idata;   /* input data */
dma_addr_t idata_dma;

+#ifdef CONFIG_XPAD_FF
+   struct urb *irq_out;/* urb for interrupt out report */
+   unsigned char *odata;   /* output data */
+   dma_addr_t odata_dma;
+#endif
+
char phys[65];  /* physical device path */

int dpad_mapping;   /* map d-pad to buttons or to axes */
@@ -344,6 +350,106 @@ exit:
 __FUNCTION__, retval);
 }

+#ifdef CONFIG_XPAD_FF
+static void xpad_irq_out(struct urb *urb)
+{
+   int retval;
+
+   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,  
__FUNCTION__, urb-status);
+   return;
+   default:
+   dbg(%s - nonzero urb status received: %d,  __FUNCTION__, 
urb-status);
+   goto exit;
+   }
+
+exit:
+   retval = usb_submit_urb(urb, GFP_ATOMIC);
+   if (retval)
+   err(%s - usb_submit_urb failed with result %d,
+  __FUNCTION__, retval);
+} 
+

+int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect 
*effect)
+{
+   struct usb_xpad *xpad = dev-private;
+   if (effect-type == FF_RUMBLE) {
+   __u16 strong = effect-u.rumble.strong_magnitude;
+   __u16 weak = effect-u.rumble.weak_magnitude;
+		xpad-odata[0] = 0x00; 
+		xpad-odata[1] = 0x08; 
+		xpad-odata[2] = 0x00; 
+		xpad-odata[3] = strong / 256;
+		xpad-odata[4] = weak / 256; 
+		xpad-odata[5] = 0x00;

+   xpad-odata[6] = 0x00;
+   xpad-odata[7] = 0x00;
+   usb_submit_urb(xpad-irq_out, GFP_KERNEL);
+   }
+
+   return 0;
+}
+
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad-xtype == XTYPE_XBOX360) {
+   struct usb_endpoint_descriptor *ep_irq_out;
+   int rv;
+
+   xpad-dev-evbit[0] |= BIT(EV_FF);
+
+		xpad-odata = usb_buffer_alloc(xpad-udev, XPAD_PKT_LEN, 
+	   GFP_ATOMIC, xpad-odata_dma );

+   if (!xpad-idata)
+   goto fail1;
+
+   xpad-irq_out = usb_alloc_urb(0, GFP_KERNEL);
+   if (!xpad-irq_out)
+   goto fail2;
+
+   ep_irq_out = intf-cur_altsetting-endpoint[1].desc;
+   usb_fill_int_urb(xpad-irq_out, xpad-udev,
+usb_sndintpipe(xpad-udev, 
ep_irq_out-bEndpointAddress),
+xpad-odata, XPAD_PKT_LEN,
+xpad_irq_out, xpad, ep_irq_out-bInterval);
+   xpad-irq_out-transfer_dma = xpad-odata_dma;
+   xpad-irq_out-transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+   set_bit( FF_RUMBLE, xpad-dev-ffbit );
+   if (input_ff_create_memless(xpad-dev, NULL, xpad_play_effect)) 
{
+			goto fail2; 
+		}

+
+   return 0;
+
+fail2: usb_buffer_free(xpad-udev, XPAD_PKT_LEN, xpad-odata, 
xpad-odata_dma);
+fail1: 
+		return -ENOMEM;

+   }
+   return 0;
+}
+
+static void xpad_deinit_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad-xtype == XTYPE_XBOX360) {
+   usb_free_urb(xpad-irq_out);
+   usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+   xpad-odata, xpad-odata_dma);
+   }
+}
+#else
+static int xpad_init_ff(struct usb_interface *intf, 

Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-03 Thread Jan Kratochvil

Hi again,
  what do you think about this? (This patch will work only against last 
gamepad rumble support patch)


Thanks for your time
Jan Kratochvil

BigX button on xbox360 gamepad is surrounded by 4 green leds. This
patch adds support to control them.

This device understand to 14 messages (described at 
http://www.free60.org/wiki/Gamepad#LED_Control).


Control is done through event interface, message type EV_LED. EV_LED isn't 
perfect match because you are actualy not turning some led on or off but 
more likely you are telling the gamepad what flash effect it should 
play.


Signed-off-by: Jan Kratochvil [EMAIL PROTECTED]
---
 drivers/usb/input/xpad.c |   31 ---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index d117e71..8b38990 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -397,13 +397,33 @@ int xpad_play_effect(struct input_dev *d
return 0;
 }

+int xpad_input_event(struct input_dev *dev, unsigned int type,
+unsigned int code, int value)
+{
+   switch (type) {
+   case EV_FF:
+   return input_ff_event(dev,type,code,value);
+   case EV_LED: {
+   struct usb_xpad *xpad = dev-private;
+   change_bit(code,dev-led);
+   xpad-odata[0] = 0x01;
+   xpad-odata[1] = 0x03;
+   xpad-odata[2] = code;
+   usb_submit_urb(xpad-irq_out, GFP_KERNEL);
+   return 0;
+   }
+   default:
+   return -EINVAL;
+   }
+}
+
 static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
 {
if (xpad-xtype == TYPE_XBOX360) {
struct usb_endpoint_descriptor *ep_irq_out;
-   int rv;
+   int i;

-   xpad-dev-evbit[0] |= BIT(EV_FF);
+   xpad-dev-evbit[0] |= BIT(EV_FF) | BIT(EV_LED);

xpad-odata = usb_buffer_alloc(xpad-udev, XPAD_PKT_LEN,
   GFP_ATOMIC, xpad-odata_dma );
@@ -422,11 +442,16 @@ static int xpad_init_ff(struct usb_inter
xpad-irq_out-transfer_dma = xpad-odata_dma;
xpad-irq_out-transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

-   set_bit( FF_RUMBLE, xpad-dev-ffbit );
+   set_bit(FF_RUMBLE, xpad-dev-ffbit);
+   for (i=0;i16;++i)
+   set_bit(i, xpad-dev-ledbit);
+
if (input_ff_create_memless(xpad-dev, NULL, xpad_play_effect)) 
{
goto fail2;
}

+   xpad-dev-event = xpad_input_event;
+
return 0;

 fail2: usb_buffer_free(xpad-udev, XPAD_PKT_LEN, xpad-odata, 
xpad-odata_dma);
--
1.4.3.4



-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-02 Thread Dmitry Torokhov
On Wednesday 02 May 2007 11:05, Jan Kratochvil wrote:
> 
> +config XPAD_FF
> + default n

Please don't default to anything.

>  
> +#ifdef CONFIG_XPAD_FF
> +/**
> + * xpad_irq_out
> + */

Comments are welcome when they say something...

> +static void xpad_irq_out(struct urb *urb)
> +{
> + int retval;
> +
> + 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",  
> __FUNCTION__, urb->status);
> + return;
> + default:
> + dbg("%s - nonzero urb status received: %d",  
> __FUNCTION__, urb->status);
> + goto exit;
> + }
> +
> +exit:
> + retval = usb_submit_urb(urb, GFP_ATOMIC);
> + if (retval)
> + err("%s - usb_submit_urb failed with result %d",
> +__FUNCTION__, retval);
> +} 
> +
> +int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect 
> *effect)
> +{
> + struct usb_xpad *xpad = dev->private;
> + if (effect->type == FF_RUMBLE) {
> + __u16 strong = effect->u.rumble.strong_magnitude;
> + __u16 weak = effect->u.rumble.weak_magnitude;
> + xpad->odata[0] = 0x00; 
> + xpad->odata[1] = 0x08; 
> + xpad->odata[2] = 0x00; 
> + xpad->odata[3] = strong / 256;
> + xpad->odata[4] = weak / 256; 
> + xpad->odata[5] = 0x00;
> + xpad->odata[6] = 0x00;
> + xpad->odata[7] = 0x00;
> + usb_submit_urb(xpad->irq_out, GFP_KERNEL);
> + }
> +
> + return 0;
> +}
> +
> +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
> +{
> + if (xpad->flags & XPAD_FLAGS_XBOX360) {
> + struct usb_endpoint_descriptor *ep_irq_out;
> + int rv;
> +
> + xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, 
> +GFP_ATOMIC, >odata_dma );
> + if (!xpad->idata)
> + goto fail1;
> +
> + xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
> + if (!xpad->irq_out)
> + goto fail2;
> +
> +
> + ep_irq_out = >cur_altsetting->endpoint[1].desc;
> + usb_fill_int_urb(xpad->irq_out, xpad->udev,
> +  usb_sndintpipe(xpad->udev, 
> ep_irq_out->bEndpointAddress),
> +  xpad->odata, XPAD_PKT_LEN,
> +  xpad_irq_out, xpad, ep_irq_out->bInterval);
> + xpad->irq_out->transfer_dma = xpad->odata_dma;
> + xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
> +
> + set_bit( FF_RUMBLE, xpad->dev->ffbit );
> + rv = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
> +

Error handling seems to be missing.

> + return 0;
> +
> +fail2:   usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, 
> xpad->odata_dma);
> +fail1:   
> + return -ENOMEM;
> + }
> + return 0;
> +}
> +
> +static void xpad_deinit_ff(struct usb_interface *intf, struct usb_xpad *xpad)
> +{
> + if (xpad->flags & XPAD_FLAGS_XBOX360) {
> + usb_kill_urb(xpad->irq_out);

You may want to do that in xpad_close().

> + usb_free_urb(xpad->irq_out);
> + usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
> + xpad->odata, xpad->odata_dma);
> + }
> +}
> +#endif
> +
>  static int xpad_open (struct input_dev *dev)
>  {
>   struct usb_xpad *xpad = dev->private;
> @@ -432,6 +535,11 @@ static int xpad_probe(struct usb_interface *intf, const 
> struct usb_device_id *id
>  
>   input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
>  
> +#ifdef CONFIG_XPAD_FF
> + if (xpad->flags & XPAD_FLAGS_XBOX360)
> + input_dev->evbit[0] |= BIT(EV_FF);
> +#endif

Can this be moved into xpad_init_ff?

> +
>   /* set up buttons */
>   for (i = 0; xpad_btn[i] >= 0; i++)
>   set_bit(xpad_btn[i], input_dev->keybit);
> @@ -449,6 +557,11 @@ static int xpad_probe(struct usb_interface *intf, const 
> struct usb_device_id *id
>   for (i = 0; xpad_abs_pad[i] >= 0; i++)
>   xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
>  
> +#ifdef CONFIG_XPAD_FF
> + if (xpad_init_ff(intf, xpad))
> + goto fail2;
> +#endif
> +

Normally we define dummy fucntions when corresponding config option is disabled
to avoid littering main code with #ifdefs.

>   ep_irq_in = >cur_altsetting->endpoint[0].desc;
>   usb_fill_int_urb(xpad->irq_in, udev,
>usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
> @@ -476,6 +589,9 @@ static void 

[PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-02 Thread Jan Kratochvil
It is enabled only if CONFIG_XPAD_FF is set to y.

Implementation is using force feedback support for memoryless devices.

Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]>
---
 drivers/usb/input/Kconfig |8 +++
 drivers/usb/input/xpad.c  |  116 +
 2 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index a792e42..2066200 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -149,6 +149,14 @@ config USB_XPAD
  To compile this driver as a module, choose M here: the
  module will be called xpad.
  
+config XPAD_FF
+   default n
+   bool "X-Box gamepad rumble support"
+   depends on USB_XPAD && INPUT
+   select INPUT_FF_MEMLESS
+   ---help---
+ Say Y here if you want to take advantage of xbox 360 rumble features. 
+
 config USB_ATI_REMOTE
tristate "ATI / X10 USB RF remote control"
depends on USB && INPUT
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index bac9ec2..2dabde5 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -189,6 +189,12 @@ struct usb_xpad {
unsigned char *idata;   /* input data */
dma_addr_t idata_dma;
 
+#ifdef CONFIG_XPAD_FF
+   struct urb *irq_out;/* urb for interrupt out report */
+   unsigned char *odata;   /* output data */
+   dma_addr_t odata_dma;
+#endif
+
char phys[65];  /* physical device path */
 
u8 flags;   /* combination of XPAD_FLAGS_* */
@@ -340,6 +346,103 @@ exit:
 __FUNCTION__, retval);
 }
 
+#ifdef CONFIG_XPAD_FF
+/**
+ * xpad_irq_out
+ */
+static void xpad_irq_out(struct urb *urb)
+{
+   int retval;
+
+   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",  
__FUNCTION__, urb->status);
+   return;
+   default:
+   dbg("%s - nonzero urb status received: %d",  
__FUNCTION__, urb->status);
+   goto exit;
+   }
+
+exit:
+   retval = usb_submit_urb(urb, GFP_ATOMIC);
+   if (retval)
+   err("%s - usb_submit_urb failed with result %d",
+  __FUNCTION__, retval);
+} 
+
+int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect 
*effect)
+{
+   struct usb_xpad *xpad = dev->private;
+   if (effect->type == FF_RUMBLE) {
+   __u16 strong = effect->u.rumble.strong_magnitude;
+   __u16 weak = effect->u.rumble.weak_magnitude;
+   xpad->odata[0] = 0x00; 
+   xpad->odata[1] = 0x08; 
+   xpad->odata[2] = 0x00; 
+   xpad->odata[3] = strong / 256;
+   xpad->odata[4] = weak / 256; 
+   xpad->odata[5] = 0x00;
+   xpad->odata[6] = 0x00;
+   xpad->odata[7] = 0x00;
+   usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+   }
+
+   return 0;
+}
+
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad->flags & XPAD_FLAGS_XBOX360) {
+   struct usb_endpoint_descriptor *ep_irq_out;
+   int rv;
+
+   xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, 
+  GFP_ATOMIC, >odata_dma );
+   if (!xpad->idata)
+   goto fail1;
+
+   xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
+   if (!xpad->irq_out)
+   goto fail2;
+
+
+   ep_irq_out = >cur_altsetting->endpoint[1].desc;
+   usb_fill_int_urb(xpad->irq_out, xpad->udev,
+usb_sndintpipe(xpad->udev, 
ep_irq_out->bEndpointAddress),
+xpad->odata, XPAD_PKT_LEN,
+xpad_irq_out, xpad, ep_irq_out->bInterval);
+   xpad->irq_out->transfer_dma = xpad->odata_dma;
+   xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+   set_bit( FF_RUMBLE, xpad->dev->ffbit );
+   rv = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
+
+   return 0;
+
+fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, 
xpad->odata_dma);
+fail1: 
+   return -ENOMEM;
+   }
+   return 0;
+}
+
+static void xpad_deinit_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad->flags & XPAD_FLAGS_XBOX360) {
+   usb_kill_urb(xpad->irq_out);
+   usb_free_urb(xpad->irq_out);
+   

[PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-02 Thread Jan Kratochvil
It is enabled only if CONFIG_XPAD_FF is set to y.

Implementation is using force feedback support for memoryless devices.

Signed-off-by: Jan Kratochvil [EMAIL PROTECTED]
---
 drivers/usb/input/Kconfig |8 +++
 drivers/usb/input/xpad.c  |  116 +
 2 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index a792e42..2066200 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -149,6 +149,14 @@ config USB_XPAD
  To compile this driver as a module, choose M here: the
  module will be called xpad.
  
+config XPAD_FF
+   default n
+   bool X-Box gamepad rumble support
+   depends on USB_XPAD  INPUT
+   select INPUT_FF_MEMLESS
+   ---help---
+ Say Y here if you want to take advantage of xbox 360 rumble features. 
+
 config USB_ATI_REMOTE
tristate ATI / X10 USB RF remote control
depends on USB  INPUT
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index bac9ec2..2dabde5 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -189,6 +189,12 @@ struct usb_xpad {
unsigned char *idata;   /* input data */
dma_addr_t idata_dma;
 
+#ifdef CONFIG_XPAD_FF
+   struct urb *irq_out;/* urb for interrupt out report */
+   unsigned char *odata;   /* output data */
+   dma_addr_t odata_dma;
+#endif
+
char phys[65];  /* physical device path */
 
u8 flags;   /* combination of XPAD_FLAGS_* */
@@ -340,6 +346,103 @@ exit:
 __FUNCTION__, retval);
 }
 
+#ifdef CONFIG_XPAD_FF
+/**
+ * xpad_irq_out
+ */
+static void xpad_irq_out(struct urb *urb)
+{
+   int retval;
+
+   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,  
__FUNCTION__, urb-status);
+   return;
+   default:
+   dbg(%s - nonzero urb status received: %d,  
__FUNCTION__, urb-status);
+   goto exit;
+   }
+
+exit:
+   retval = usb_submit_urb(urb, GFP_ATOMIC);
+   if (retval)
+   err(%s - usb_submit_urb failed with result %d,
+  __FUNCTION__, retval);
+} 
+
+int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect 
*effect)
+{
+   struct usb_xpad *xpad = dev-private;
+   if (effect-type == FF_RUMBLE) {
+   __u16 strong = effect-u.rumble.strong_magnitude;
+   __u16 weak = effect-u.rumble.weak_magnitude;
+   xpad-odata[0] = 0x00; 
+   xpad-odata[1] = 0x08; 
+   xpad-odata[2] = 0x00; 
+   xpad-odata[3] = strong / 256;
+   xpad-odata[4] = weak / 256; 
+   xpad-odata[5] = 0x00;
+   xpad-odata[6] = 0x00;
+   xpad-odata[7] = 0x00;
+   usb_submit_urb(xpad-irq_out, GFP_KERNEL);
+   }
+
+   return 0;
+}
+
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad-flags  XPAD_FLAGS_XBOX360) {
+   struct usb_endpoint_descriptor *ep_irq_out;
+   int rv;
+
+   xpad-odata = usb_buffer_alloc(xpad-udev, XPAD_PKT_LEN, 
+  GFP_ATOMIC, xpad-odata_dma );
+   if (!xpad-idata)
+   goto fail1;
+
+   xpad-irq_out = usb_alloc_urb(0, GFP_KERNEL);
+   if (!xpad-irq_out)
+   goto fail2;
+
+
+   ep_irq_out = intf-cur_altsetting-endpoint[1].desc;
+   usb_fill_int_urb(xpad-irq_out, xpad-udev,
+usb_sndintpipe(xpad-udev, 
ep_irq_out-bEndpointAddress),
+xpad-odata, XPAD_PKT_LEN,
+xpad_irq_out, xpad, ep_irq_out-bInterval);
+   xpad-irq_out-transfer_dma = xpad-odata_dma;
+   xpad-irq_out-transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+   set_bit( FF_RUMBLE, xpad-dev-ffbit );
+   rv = input_ff_create_memless(xpad-dev, NULL, xpad_play_effect);
+
+   return 0;
+
+fail2: usb_buffer_free(xpad-udev, XPAD_PKT_LEN, xpad-odata, 
xpad-odata_dma);
+fail1: 
+   return -ENOMEM;
+   }
+   return 0;
+}
+
+static void xpad_deinit_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad-flags  XPAD_FLAGS_XBOX360) {
+   usb_kill_urb(xpad-irq_out);
+   usb_free_urb(xpad-irq_out);
+   usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+   

Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-02 Thread Dmitry Torokhov
On Wednesday 02 May 2007 11:05, Jan Kratochvil wrote:
 
 +config XPAD_FF
 + default n

Please don't default to anything.

  
 +#ifdef CONFIG_XPAD_FF
 +/**
 + * xpad_irq_out
 + */

Comments are welcome when they say something...

 +static void xpad_irq_out(struct urb *urb)
 +{
 + int retval;
 +
 + 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,  
 __FUNCTION__, urb-status);
 + return;
 + default:
 + dbg(%s - nonzero urb status received: %d,  
 __FUNCTION__, urb-status);
 + goto exit;
 + }
 +
 +exit:
 + retval = usb_submit_urb(urb, GFP_ATOMIC);
 + if (retval)
 + err(%s - usb_submit_urb failed with result %d,
 +__FUNCTION__, retval);
 +} 
 +
 +int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect 
 *effect)
 +{
 + struct usb_xpad *xpad = dev-private;
 + if (effect-type == FF_RUMBLE) {
 + __u16 strong = effect-u.rumble.strong_magnitude;
 + __u16 weak = effect-u.rumble.weak_magnitude;
 + xpad-odata[0] = 0x00; 
 + xpad-odata[1] = 0x08; 
 + xpad-odata[2] = 0x00; 
 + xpad-odata[3] = strong / 256;
 + xpad-odata[4] = weak / 256; 
 + xpad-odata[5] = 0x00;
 + xpad-odata[6] = 0x00;
 + xpad-odata[7] = 0x00;
 + usb_submit_urb(xpad-irq_out, GFP_KERNEL);
 + }
 +
 + return 0;
 +}
 +
 +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
 +{
 + if (xpad-flags  XPAD_FLAGS_XBOX360) {
 + struct usb_endpoint_descriptor *ep_irq_out;
 + int rv;
 +
 + xpad-odata = usb_buffer_alloc(xpad-udev, XPAD_PKT_LEN, 
 +GFP_ATOMIC, xpad-odata_dma );
 + if (!xpad-idata)
 + goto fail1;
 +
 + xpad-irq_out = usb_alloc_urb(0, GFP_KERNEL);
 + if (!xpad-irq_out)
 + goto fail2;
 +
 +
 + ep_irq_out = intf-cur_altsetting-endpoint[1].desc;
 + usb_fill_int_urb(xpad-irq_out, xpad-udev,
 +  usb_sndintpipe(xpad-udev, 
 ep_irq_out-bEndpointAddress),
 +  xpad-odata, XPAD_PKT_LEN,
 +  xpad_irq_out, xpad, ep_irq_out-bInterval);
 + xpad-irq_out-transfer_dma = xpad-odata_dma;
 + xpad-irq_out-transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 +
 + set_bit( FF_RUMBLE, xpad-dev-ffbit );
 + rv = input_ff_create_memless(xpad-dev, NULL, xpad_play_effect);
 +

Error handling seems to be missing.

 + return 0;
 +
 +fail2:   usb_buffer_free(xpad-udev, XPAD_PKT_LEN, xpad-odata, 
 xpad-odata_dma);
 +fail1:   
 + return -ENOMEM;
 + }
 + return 0;
 +}
 +
 +static void xpad_deinit_ff(struct usb_interface *intf, struct usb_xpad *xpad)
 +{
 + if (xpad-flags  XPAD_FLAGS_XBOX360) {
 + usb_kill_urb(xpad-irq_out);

You may want to do that in xpad_close().

 + usb_free_urb(xpad-irq_out);
 + usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
 + xpad-odata, xpad-odata_dma);
 + }
 +}
 +#endif
 +
  static int xpad_open (struct input_dev *dev)
  {
   struct usb_xpad *xpad = dev-private;
 @@ -432,6 +535,11 @@ static int xpad_probe(struct usb_interface *intf, const 
 struct usb_device_id *id
  
   input_dev-evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
  
 +#ifdef CONFIG_XPAD_FF
 + if (xpad-flags  XPAD_FLAGS_XBOX360)
 + input_dev-evbit[0] |= BIT(EV_FF);
 +#endif

Can this be moved into xpad_init_ff?

 +
   /* set up buttons */
   for (i = 0; xpad_btn[i] = 0; i++)
   set_bit(xpad_btn[i], input_dev-keybit);
 @@ -449,6 +557,11 @@ static int xpad_probe(struct usb_interface *intf, const 
 struct usb_device_id *id
   for (i = 0; xpad_abs_pad[i] = 0; i++)
   xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
  
 +#ifdef CONFIG_XPAD_FF
 + if (xpad_init_ff(intf, xpad))
 + goto fail2;
 +#endif
 +

Normally we define dummy fucntions when corresponding config option is disabled
to avoid littering main code with #ifdefs.

   ep_irq_in = intf-cur_altsetting-endpoint[0].desc;
   usb_fill_int_urb(xpad-irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in-bEndpointAddress),
 @@ -476,6 +589,9 @@ static void xpad_disconnect(struct usb_interface *intf)
   usb_set_intfdata(intf, NULL);
   if (xpad) {
   usb_kill_urb(xpad-irq_in);

This is extra - we already did that in xpad_close.