553603699550df6c69b10992cc680eb9e9b80b0a
[reactos.git] / reactos / drivers / usb / cromwell / sys / xpad.c
1 /*
2 * Simple XPAD driver for XBOX
3 *
4 * (c) 2003-07-04, Georg Acher (georg@acher.org)
5 *
6 * Inspired by linux/drivers/usb/input/xpad.c
7 * by Marko Friedemann <mfr@bmx-chemnitz.de>
8 *
9 */
10
11
12
13 #include "../usb_wrapper.h"
14 #include "config.h"
15
16 // history for the Rising - falling events
17 unsigned char xpad_button_history[7];
18
19 /* Stores time and XPAD state */
20 struct xpad_data XPAD_current[4];
21 struct xpad_data XPAD_last[4];
22
23 struct xpad_info
24 {
25 struct urb *urb;
26 int num;
27 unsigned char data[32];
28 };
29
30 int xpad_num=0;
31 /*------------------------------------------------------------------------*/
32 static void xpad_irq(struct urb *urb, struct pt_regs *regs)
33 {
34 struct xpad_info *xpi = urb->context;
35 unsigned char* data= urb->transfer_buffer;
36
37 // struct xpad_data *xp=&XPAD_current[xpi->num];
38 // struct xpad_data *xpo=&XPAD_last[xpi->num];
39
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 */
44
45 struct xpad_data *xp=&XPAD_current[0];
46 struct xpad_data *xpo=&XPAD_last[0];
47
48 if (xpi->num<0 || xpi->num>3)
49 return;
50
51 memcpy(xpo,xp,sizeof(struct xpad_data));
52
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);
69
70 }
71 /*------------------------------------------------------------------------*/
72 static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
73 {
74 struct urb *urb;
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;
79
80 xpi=kmalloc(sizeof(struct xpad_info),GFP_KERNEL);
81 if (!xpi) return -1;
82
83 urb=usb_alloc_urb(0,0);
84 if (!urb) return -1;
85
86 xpi->urb=urb;
87 xpi->num=xpad_num;
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,
92 xpi, 32);
93
94 usb_submit_urb(urb,GFP_ATOMIC);
95
96 usb_set_intfdata(intf,xpi);
97 usbprintk("XPAD #%i connected\n",xpad_num);
98 #ifdef XPAD_VIBRA_STARTUP
99 {
100 // Brum Brum
101 char data1[6]={0,6,0,120,0,120};
102 char data2[6]={0,6,0,0,0,0};
103 int dummy;
104
105 usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
106 data1, 6, &dummy, 500);
107 wait_ms(500);
108 usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
109 data2, 6, &dummy, 500);
110 }
111 #endif
112 xpad_num++;
113 return 0;
114 }
115 /*------------------------------------------------------------------------*/
116 static void xpad_disconnect(struct usb_interface *intf)
117 {
118 struct xpad_info *xpi=usb_get_intfdata (intf);
119 usb_unlink_urb(xpi->urb);
120 usb_free_urb(xpi->urb);
121 kfree(xpi);
122 xpad_num--;
123 }
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 */
147 };
148
149
150 static struct usb_driver xpad_driver = {
151 .owner = THIS_MODULE,
152 .name = "XPAD",
153 .probe = xpad_probe,
154 .disconnect = xpad_disconnect,
155 .id_table = xpad_ids,
156 };
157
158 /*------------------------------------------------------------------------*/
159 void XPADInit(void)
160 {
161 int n;
162 for(n=0;n<4;n++)
163 {
164 memset(&XPAD_current[n], 0, sizeof(struct xpad_data));
165 memset(&XPAD_last[n], 0, sizeof(struct xpad_data));
166 }
167 memset(&xpad_button_history, 0, sizeof(xpad_button_history));
168
169 usbprintk("XPAD probe %p ",xpad_probe);
170 if (usb_register(&xpad_driver) < 0) {
171 err("Unable to register XPAD driver");
172 return;
173 }
174 }
175 /*------------------------------------------------------------------------*/
176 void XPADRemove(void) {
177 usb_deregister(&xpad_driver);
178 }
179
180 /*------------------------------------------------------------------------*/
181
182
183