@ -344,6 +344,7 @@ struct usb_xpad {
int mapping ; /* map d-pad to buttons or to axes */
int xtype ; /* type of xbox device */
unsigned long led_no ; /* led to lit on xbox360 controllers */
} ;
/*
@ -488,6 +489,8 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
input_sync ( dev ) ;
}
static void xpad_identify_controller ( struct usb_xpad * xpad ) ;
/*
* xpad360w_process_packet
*
@ -510,6 +513,11 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
if ( data [ 1 ] & 0x80 ) {
xpad - > pad_present = 1 ;
usb_submit_urb ( xpad - > bulk_out , GFP_ATOMIC ) ;
/*
* Light up the segment corresponding to
* controller number .
*/
xpad_identify_controller ( xpad ) ;
} else
xpad - > pad_present = 0 ;
}
@ -881,17 +889,63 @@ struct xpad_led {
struct usb_xpad * xpad ;
} ;
/**
* @ param command
* 0 : off
* 1 : all blink , then previous setting
* 2 : 1 / top - left blink , then on
* 3 : 2 / top - right blink , then on
* 4 : 3 / bottom - left blink , then on
* 5 : 4 / bottom - right blink , then on
* 6 : 1 / top - left on
* 7 : 2 / top - right on
* 8 : 3 / bottom - left on
* 9 : 4 / bottom - right on
* 10 : rotate
* 11 : blink , based on previous setting
* 12 : slow blink , based on previous setting
* 13 : rotate with two lights
* 14 : persistent slow all blink
* 15 : blink once , then previous setting
*/
static void xpad_send_led_command ( struct usb_xpad * xpad , int command )
{
if ( command > = 0 & & command < 14 ) {
mutex_lock ( & xpad - > odata_mutex ) ;
command % = 16 ;
mutex_lock ( & xpad - > odata_mutex ) ;
switch ( xpad - > xtype ) {
case XTYPE_XBOX360 :
xpad - > odata [ 0 ] = 0x01 ;
xpad - > odata [ 1 ] = 0x03 ;
xpad - > odata [ 2 ] = command ;
xpad - > irq_out - > transfer_buffer_length = 3 ;
usb_submit_urb ( xpad - > irq_out , GFP_KERNEL ) ;
mutex_unlock ( & xpad - > odata_mutex ) ;
break ;
case XTYPE_XBOX360W :
xpad - > odata [ 0 ] = 0x00 ;
xpad - > odata [ 1 ] = 0x00 ;
xpad - > odata [ 2 ] = 0x08 ;
xpad - > odata [ 3 ] = 0x40 + command ;
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 ;
break ;
}
usb_submit_urb ( xpad - > irq_out , GFP_KERNEL ) ;
mutex_unlock ( & xpad - > odata_mutex ) ;
}
static void xpad_identify_controller ( struct usb_xpad * xpad )
{
/* Light up the segment corresponding to controller number */
xpad_send_led_command ( xpad , ( xpad - > led_no % 4 ) + 2 ) ;
}
static void xpad_led_set ( struct led_classdev * led_cdev ,
@ -905,22 +959,21 @@ static void xpad_led_set(struct led_classdev *led_cdev,
static int xpad_led_probe ( struct usb_xpad * xpad )
{
static atomic_t led_seq = ATOMIC_INIT ( - 1 ) ;
unsigned long led_no ;
static atomic_t led_seq = ATOMIC_INIT ( - 1 ) ;
struct xpad_led * led ;
struct led_classdev * led_cdev ;
int error ;
if ( xpad - > xtype ! = XTYPE_XBOX360 )
if ( xpad - > xtype ! = XTYPE_XBOX360 & & xpad - > xtype ! = XTYPE_XBOX360W )
return 0 ;
xpad - > led = led = kzalloc ( sizeof ( struct xpad_led ) , GFP_KERNEL ) ;
if ( ! led )
return - ENOMEM ;
led_no = atomic_inc_return ( & led_seq ) ;
xpad - > led_no = atomic_inc_return ( & led_seq ) ;
snprintf ( led - > name , sizeof ( led - > name ) , " xpad%lu " , led_no ) ;
snprintf ( led - > name , sizeof ( led - > name ) , " xpad%lu " , xpad - > led_no ) ;
led - > xpad = xpad ;
led_cdev = & led - > led_cdev ;
@ -934,10 +987,8 @@ static int xpad_led_probe(struct usb_xpad *xpad)
return error ;
}
/*
* Light up the segment corresponding to controller number
*/
xpad_send_led_command ( xpad , ( led_no % 4 ) + 2 ) ;
/* Light up the segment corresponding to controller number */
xpad_identify_controller ( xpad ) ;
return 0 ;
}
@ -954,6 +1005,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad)
# else
static int xpad_led_probe ( struct usb_xpad * xpad ) { return 0 ; }
static void xpad_led_disconnect ( struct usb_xpad * xpad ) { }
static void xpad_identify_controller ( struct usb_xpad * xpad ) { }
# endif