553603699550df6c69b10992cc680eb9e9b80b0a
2 * Simple XPAD driver for XBOX
4 * (c) 2003-07-04, Georg Acher (georg@acher.org)
6 * Inspired by linux/drivers/usb/input/xpad.c
7 * by Marko Friedemann <mfr@bmx-chemnitz.de>
13 #include "../usb_wrapper.h"
16 // history for the Rising - falling events
17 unsigned char xpad_button_history
[7];
19 /* Stores time and XPAD state */
20 struct xpad_data XPAD_current
[4];
21 struct xpad_data XPAD_last
[4];
27 unsigned char data
[32];
31 /*------------------------------------------------------------------------*/
32 static void xpad_irq(struct urb
*urb
, struct pt_regs
*regs
)
34 struct xpad_info
*xpi
= urb
->context
;
35 unsigned char* data
= urb
->transfer_buffer
;
37 // struct xpad_data *xp=&XPAD_current[xpi->num];
38 // struct xpad_data *xpo=&XPAD_last[xpi->num];
40 /* This hack means the xpad event always gets posted to the
41 * first xpad - avoids problems iterating over multiple xpads
42 * as the xpi->num entries are not reused when xpads are
43 * connected, then removed */
45 struct xpad_data
*xp
=&XPAD_current
[0];
46 struct xpad_data
*xpo
=&XPAD_last
[0];
48 if (xpi
->num
<0 || xpi
->num
>3)
51 memcpy(xpo
,xp
,sizeof(struct xpad_data
));
53 xp
->stick_left_x
=(short) (((short)data
[13] << 8) | data
[12]);
54 xp
->stick_left_y
=(short) (((short)data
[15] << 8) | data
[14]);
55 xp
->stick_right_x
=(short) (((short)data
[17] << 8) | data
[16]);
56 xp
->stick_right_y
=(short) (((short)data
[19] << 8) | data
[18]);
57 xp
->trig_left
= data
[10];
58 xp
->trig_right
= data
[11];
59 xp
->pad
= data
[2]&0xf;
60 xp
->state
= (data
[2]>>4)&0xf;
61 xp
->keys
[0] = data
[4]; // a
62 xp
->keys
[1] = data
[5]; // b
63 xp
->keys
[2] = data
[6]; // x
64 xp
->keys
[3] = data
[7]; // y
65 xp
->keys
[4] = data
[8]; // black
66 xp
->keys
[5] = data
[9]; // white
67 xp
->timestamp
=jiffies
; // FIXME: A more uniform flowing time would be better...
68 usb_submit_urb(urb
,GFP_ATOMIC
);
71 /*------------------------------------------------------------------------*/
72 static int xpad_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
75 struct usb_device
*udev
= interface_to_usbdev (intf
);
76 struct usb_endpoint_descriptor
*ep_irq_in
;
77 struct usb_endpoint_descriptor
*ep_irq_out
;
78 struct xpad_info
*xpi
;
80 xpi
=kmalloc(sizeof(struct xpad_info
),GFP_KERNEL
);
83 urb
=usb_alloc_urb(0,0);
88 ep_irq_in
= &intf
->altsetting
[0].endpoint
[0].desc
;
89 usb_fill_int_urb(urb
, udev
,
90 usb_rcvintpipe(udev
, ep_irq_in
->bEndpointAddress
),
91 xpi
->data
, 32, xpad_irq
,
94 usb_submit_urb(urb
,GFP_ATOMIC
);
96 usb_set_intfdata(intf
,xpi
);
97 usbprintk("XPAD #%i connected\n",xpad_num
);
98 #ifdef XPAD_VIBRA_STARTUP
101 char data1
[6]={0,6,0,120,0,120};
102 char data2
[6]={0,6,0,0,0,0};
105 usb_bulk_msg(udev
, usb_sndbulkpipe(udev
,2),
106 data1
, 6, &dummy
, 500);
108 usb_bulk_msg(udev
, usb_sndbulkpipe(udev
,2),
109 data2
, 6, &dummy
, 500);
115 /*------------------------------------------------------------------------*/
116 static void xpad_disconnect(struct usb_interface
*intf
)
118 struct xpad_info
*xpi
=usb_get_intfdata (intf
);
119 usb_unlink_urb(xpi
->urb
);
120 usb_free_urb(xpi
->urb
);
124 /*------------------------------------------------------------------------*/
125 static struct usb_device_id xpad_ids
[] = {
126 { USB_DEVICE(0x044f, 0x0f07) },//Thrustmaster, Inc. Controller
127 { USB_DEVICE(0x045e, 0x0202) },//Microsoft Xbox Controller
128 { USB_DEVICE(0x045e, 0x0285) },//Microsoft Xbox Controller S
129 { USB_DEVICE(0x045e, 0x0289) },//Microsoft Xbox Controller S
130 { USB_DEVICE(0x046d, 0xca88) },//Logitech Compact Controller for Xbox
131 { USB_DEVICE(0x05fd, 0x1007) },//???Mad Catz Controller???
132 { USB_DEVICE(0x05fd, 0x107a) },//InterAct PowerPad Pro
133 { USB_DEVICE(0x0738, 0x4516) },//Mad Catz Control Pad
134 { USB_DEVICE(0x0738, 0x4522) },//Mad Catz LumiCON
135 { USB_DEVICE(0x0738, 0x4526) },//Mad Catz Control Pad Pro
136 { USB_DEVICE(0x0738, 0x4536) },//Mad Catz MicroCON
137 { USB_DEVICE(0x0738, 0x4556) },//Mad Catz Lynx Wireless Controller
138 { USB_DEVICE(0x0c12, 0x9902) },//HAMA VibraX - *FAULTY HARDWARE*
139 { USB_DEVICE(0x0e4c, 0x1097) },//Radica Gamester Controller
140 { USB_DEVICE(0x0e4c, 0x2390) },//Radica Games Jtech Controller
141 { USB_DEVICE(0x0e6f, 0x0003) },//Logic3 Freebird wireless Controller
142 { USB_DEVICE(0x0e6f, 0x0005) },//Eclipse wireless Controlle
143 { USB_DEVICE(0x0f30, 0x0202) },//Joytech Advanced Controller
144 { USB_DEVICE(0xffff, 0xffff) },//Chinese-made Xbox Controller
145 { USB_DEVICE(0x0000, 0x0000) }, // nothing detected - FAIL
146 { } /* Terminating entry */
150 static struct usb_driver xpad_driver
= {
151 .owner
= THIS_MODULE
,
154 .disconnect
= xpad_disconnect
,
155 .id_table
= xpad_ids
,
158 /*------------------------------------------------------------------------*/
164 memset(&XPAD_current
[n
], 0, sizeof(struct xpad_data
));
165 memset(&XPAD_last
[n
], 0, sizeof(struct xpad_data
));
167 memset(&xpad_button_history
, 0, sizeof(xpad_button_history
));
169 usbprintk("XPAD probe %p ",xpad_probe
);
170 if (usb_register(&xpad_driver
) < 0) {
171 err("Unable to register XPAD driver");
175 /*------------------------------------------------------------------------*/
176 void XPADRemove(void) {
177 usb_deregister(&xpad_driver
);
180 /*------------------------------------------------------------------------*/