Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/input/joystick/xpad.c
15111 views
1
/*
2
* X-Box gamepad driver
3
*
4
* Copyright (c) 2002 Marko Friedemann <[email protected]>
5
* 2004 Oliver Schwartz <[email protected]>,
6
* Steven Toth <[email protected]>,
7
* Franz Lehner <[email protected]>,
8
* Ivan Hawkes <[email protected]>
9
* 2005 Dominic Cerquetti <[email protected]>
10
* 2006 Adam Buchbinder <[email protected]>
11
* 2007 Jan Kratochvil <[email protected]>
12
* 2010 Christoph Fritz <[email protected]>
13
*
14
* This program is free software; you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License as
16
* published by the Free Software Foundation; either version 2 of
17
* the License, or (at your option) any later version.
18
*
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
23
*
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, write to the Free Software
26
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
*
28
*
29
* This driver is based on:
30
* - information from http://euc.jp/periphs/xbox-controller.ja.html
31
* - the iForce driver drivers/char/joystick/iforce.c
32
* - the skeleton-driver drivers/usb/usb-skeleton.c
33
* - Xbox 360 information http://www.free60.org/wiki/Gamepad
34
*
35
* Thanks to:
36
* - ITO Takayuki for providing essential xpad information on his website
37
* - Vojtech Pavlik - iforce driver / input subsystem
38
* - Greg Kroah-Hartman - usb-skeleton driver
39
* - XBOX Linux project - extra USB id's
40
*
41
* TODO:
42
* - fine tune axes (especially trigger axes)
43
* - fix "analog" buttons (reported as digital now)
44
* - get rumble working
45
* - need USB IDs for other dance pads
46
*
47
* History:
48
*
49
* 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller"
50
*
51
* 2002-07-02 - 0.0.2 : basic working version
52
* - all axes and 9 of the 10 buttons work (german InterAct device)
53
* - the black button does not work
54
*
55
* 2002-07-14 - 0.0.3 : rework by Vojtech Pavlik
56
* - indentation fixes
57
* - usb + input init sequence fixes
58
*
59
* 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3
60
* - verified the lack of HID and report descriptors
61
* - verified that ALL buttons WORK
62
* - fixed d-pad to axes mapping
63
*
64
* 2002-07-17 - 0.0.5 : simplified d-pad handling
65
*
66
* 2004-10-02 - 0.0.6 : DDR pad support
67
* - borrowed from the XBOX linux kernel
68
* - USB id's for commonly used dance pads are present
69
* - dance pads will map D-PAD to buttons, not axes
70
* - pass the module paramater 'dpad_to_buttons' to force
71
* the D-PAD to map to buttons if your pad is not detected
72
*
73
* Later changes can be tracked in SCM.
74
*/
75
76
#include <linux/kernel.h>
77
#include <linux/init.h>
78
#include <linux/slab.h>
79
#include <linux/stat.h>
80
#include <linux/module.h>
81
#include <linux/usb/input.h>
82
83
#define DRIVER_AUTHOR "Marko Friedemann <[email protected]>"
84
#define DRIVER_DESC "X-Box pad driver"
85
86
#define XPAD_PKT_LEN 32
87
88
/* xbox d-pads should map to buttons, as is required for DDR pads
89
but we map them to axes when possible to simplify things */
90
#define MAP_DPAD_TO_BUTTONS (1 << 0)
91
#define MAP_TRIGGERS_TO_BUTTONS (1 << 1)
92
#define MAP_STICKS_TO_NULL (1 << 2)
93
#define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \
94
MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
95
96
#define XTYPE_XBOX 0
97
#define XTYPE_XBOX360 1
98
#define XTYPE_XBOX360W 2
99
#define XTYPE_UNKNOWN 3
100
101
static int dpad_to_buttons;
102
module_param(dpad_to_buttons, bool, S_IRUGO);
103
MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
104
105
static int triggers_to_buttons;
106
module_param(triggers_to_buttons, bool, S_IRUGO);
107
MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads");
108
109
static int sticks_to_null;
110
module_param(sticks_to_null, bool, S_IRUGO);
111
MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
112
113
static const struct xpad_device {
114
u16 idVendor;
115
u16 idProduct;
116
char *name;
117
u8 mapping;
118
u8 xtype;
119
} xpad_device[] = {
120
{ 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX },
121
{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
122
{ 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
123
{ 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
124
{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
125
{ 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX },
126
{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
127
{ 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
128
{ 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
129
{ 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX },
130
{ 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX },
131
{ 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX },
132
{ 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX },
133
{ 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX },
134
{ 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
135
{ 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX },
136
{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
137
{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX },
138
{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
139
{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
140
{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
141
{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
142
{ 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX },
143
{ 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
144
{ 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
145
{ 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
146
{ 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
147
{ 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX },
148
{ 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
149
{ 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
150
{ 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
151
{ 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
152
{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
153
{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
154
{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
155
{ 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
156
{ 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
157
{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 },
158
{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
159
{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
160
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
161
{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
162
{ 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
163
{ 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
164
{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
165
{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
166
};
167
168
/* buttons shared with xbox and xbox360 */
169
static const signed short xpad_common_btn[] = {
170
BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */
171
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
172
-1 /* terminating entry */
173
};
174
175
/* original xbox controllers only */
176
static const signed short xpad_btn[] = {
177
BTN_C, BTN_Z, /* "analog" buttons */
178
-1 /* terminating entry */
179
};
180
181
/* used when dpad is mapped to buttons */
182
static const signed short xpad_btn_pad[] = {
183
BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, /* d-pad left, right */
184
BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, /* d-pad up, down */
185
-1 /* terminating entry */
186
};
187
188
/* used when triggers are mapped to buttons */
189
static const signed short xpad_btn_triggers[] = {
190
BTN_TL2, BTN_TR2, /* triggers left/right */
191
-1
192
};
193
194
195
static const signed short xpad360_btn[] = { /* buttons for x360 controller */
196
BTN_TL, BTN_TR, /* Button LB/RB */
197
BTN_MODE, /* The big X button */
198
-1
199
};
200
201
static const signed short xpad_abs[] = {
202
ABS_X, ABS_Y, /* left stick */
203
ABS_RX, ABS_RY, /* right stick */
204
-1 /* terminating entry */
205
};
206
207
/* used when dpad is mapped to axes */
208
static const signed short xpad_abs_pad[] = {
209
ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */
210
-1 /* terminating entry */
211
};
212
213
/* used when triggers are mapped to axes */
214
static const signed short xpad_abs_triggers[] = {
215
ABS_Z, ABS_RZ, /* triggers left/right */
216
-1
217
};
218
219
/* Xbox 360 has a vendor-specific class, so we cannot match it with only
220
* USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
221
* match against vendor id as well. Wired Xbox 360 devices have protocol 1,
222
* wireless controllers have protocol 129. */
223
#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
224
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
225
.idVendor = (vend), \
226
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
227
.bInterfaceSubClass = 93, \
228
.bInterfaceProtocol = (pr)
229
#define XPAD_XBOX360_VENDOR(vend) \
230
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
231
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
232
233
static struct usb_device_id xpad_table [] = {
234
{ USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
235
XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */
236
XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */
237
XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
238
XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
239
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
240
XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
241
XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */
242
XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
243
{ }
244
};
245
246
MODULE_DEVICE_TABLE (usb, xpad_table);
247
248
struct usb_xpad {
249
struct input_dev *dev; /* input device interface */
250
struct usb_device *udev; /* usb device */
251
252
int pad_present;
253
254
struct urb *irq_in; /* urb for interrupt in report */
255
unsigned char *idata; /* input data */
256
dma_addr_t idata_dma;
257
258
struct urb *bulk_out;
259
unsigned char *bdata;
260
261
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
262
struct urb *irq_out; /* urb for interrupt out report */
263
unsigned char *odata; /* output data */
264
dma_addr_t odata_dma;
265
struct mutex odata_mutex;
266
#endif
267
268
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
269
struct xpad_led *led;
270
#endif
271
272
char phys[64]; /* physical device path */
273
274
int mapping; /* map d-pad to buttons or to axes */
275
int xtype; /* type of xbox device */
276
};
277
278
/*
279
* xpad_process_packet
280
*
281
* Completes a request by converting the data into events for the
282
* input subsystem.
283
*
284
* The used report descriptor was taken from ITO Takayukis website:
285
* http://euc.jp/periphs/xbox-controller.ja.html
286
*/
287
288
static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
289
{
290
struct input_dev *dev = xpad->dev;
291
292
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
293
/* left stick */
294
input_report_abs(dev, ABS_X,
295
(__s16) le16_to_cpup((__le16 *)(data + 12)));
296
input_report_abs(dev, ABS_Y,
297
~(__s16) le16_to_cpup((__le16 *)(data + 14)));
298
299
/* right stick */
300
input_report_abs(dev, ABS_RX,
301
(__s16) le16_to_cpup((__le16 *)(data + 16)));
302
input_report_abs(dev, ABS_RY,
303
~(__s16) le16_to_cpup((__le16 *)(data + 18)));
304
}
305
306
/* triggers left/right */
307
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
308
input_report_key(dev, BTN_TL2, data[10]);
309
input_report_key(dev, BTN_TR2, data[11]);
310
} else {
311
input_report_abs(dev, ABS_Z, data[10]);
312
input_report_abs(dev, ABS_RZ, data[11]);
313
}
314
315
/* digital pad */
316
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
317
/* dpad as buttons (left, right, up, down) */
318
input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
319
input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
320
input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
321
input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
322
} else {
323
input_report_abs(dev, ABS_HAT0X,
324
!!(data[2] & 0x08) - !!(data[2] & 0x04));
325
input_report_abs(dev, ABS_HAT0Y,
326
!!(data[2] & 0x02) - !!(data[2] & 0x01));
327
}
328
329
/* start/back buttons and stick press left/right */
330
input_report_key(dev, BTN_START, data[2] & 0x10);
331
input_report_key(dev, BTN_SELECT, data[2] & 0x20);
332
input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
333
input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
334
335
/* "analog" buttons A, B, X, Y */
336
input_report_key(dev, BTN_A, data[4]);
337
input_report_key(dev, BTN_B, data[5]);
338
input_report_key(dev, BTN_X, data[6]);
339
input_report_key(dev, BTN_Y, data[7]);
340
341
/* "analog" buttons black, white */
342
input_report_key(dev, BTN_C, data[8]);
343
input_report_key(dev, BTN_Z, data[9]);
344
345
input_sync(dev);
346
}
347
348
/*
349
* xpad360_process_packet
350
*
351
* Completes a request by converting the data into events for the
352
* input subsystem. It is version for xbox 360 controller
353
*
354
* The used report descriptor was taken from:
355
* http://www.free60.org/wiki/Gamepad
356
*/
357
358
static void xpad360_process_packet(struct usb_xpad *xpad,
359
u16 cmd, unsigned char *data)
360
{
361
struct input_dev *dev = xpad->dev;
362
363
/* digital pad */
364
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
365
/* dpad as buttons (left, right, up, down) */
366
input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
367
input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
368
input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
369
input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
370
} else {
371
input_report_abs(dev, ABS_HAT0X,
372
!!(data[2] & 0x08) - !!(data[2] & 0x04));
373
input_report_abs(dev, ABS_HAT0Y,
374
!!(data[2] & 0x02) - !!(data[2] & 0x01));
375
}
376
377
/* start/back buttons */
378
input_report_key(dev, BTN_START, data[2] & 0x10);
379
input_report_key(dev, BTN_SELECT, data[2] & 0x20);
380
381
/* stick press left/right */
382
input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
383
input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
384
385
/* buttons A,B,X,Y,TL,TR and MODE */
386
input_report_key(dev, BTN_A, data[3] & 0x10);
387
input_report_key(dev, BTN_B, data[3] & 0x20);
388
input_report_key(dev, BTN_X, data[3] & 0x40);
389
input_report_key(dev, BTN_Y, data[3] & 0x80);
390
input_report_key(dev, BTN_TL, data[3] & 0x01);
391
input_report_key(dev, BTN_TR, data[3] & 0x02);
392
input_report_key(dev, BTN_MODE, data[3] & 0x04);
393
394
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
395
/* left stick */
396
input_report_abs(dev, ABS_X,
397
(__s16) le16_to_cpup((__le16 *)(data + 6)));
398
input_report_abs(dev, ABS_Y,
399
~(__s16) le16_to_cpup((__le16 *)(data + 8)));
400
401
/* right stick */
402
input_report_abs(dev, ABS_RX,
403
(__s16) le16_to_cpup((__le16 *)(data + 10)));
404
input_report_abs(dev, ABS_RY,
405
~(__s16) le16_to_cpup((__le16 *)(data + 12)));
406
}
407
408
/* triggers left/right */
409
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
410
input_report_key(dev, BTN_TL2, data[4]);
411
input_report_key(dev, BTN_TR2, data[5]);
412
} else {
413
input_report_abs(dev, ABS_Z, data[4]);
414
input_report_abs(dev, ABS_RZ, data[5]);
415
}
416
417
input_sync(dev);
418
}
419
420
/*
421
* xpad360w_process_packet
422
*
423
* Completes a request by converting the data into events for the
424
* input subsystem. It is version for xbox 360 wireless controller.
425
*
426
* Byte.Bit
427
* 00.1 - Status change: The controller or headset has connected/disconnected
428
* Bits 01.7 and 01.6 are valid
429
* 01.7 - Controller present
430
* 01.6 - Headset present
431
* 01.1 - Pad state (Bytes 4+) valid
432
*
433
*/
434
435
static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
436
{
437
/* Presence change */
438
if (data[0] & 0x08) {
439
if (data[1] & 0x80) {
440
xpad->pad_present = 1;
441
usb_submit_urb(xpad->bulk_out, GFP_ATOMIC);
442
} else
443
xpad->pad_present = 0;
444
}
445
446
/* Valid pad data */
447
if (!(data[1] & 0x1))
448
return;
449
450
xpad360_process_packet(xpad, cmd, &data[4]);
451
}
452
453
static void xpad_irq_in(struct urb *urb)
454
{
455
struct usb_xpad *xpad = urb->context;
456
int retval, status;
457
458
status = urb->status;
459
460
switch (status) {
461
case 0:
462
/* success */
463
break;
464
case -ECONNRESET:
465
case -ENOENT:
466
case -ESHUTDOWN:
467
/* this urb is terminated, clean up */
468
dbg("%s - urb shutting down with status: %d",
469
__func__, status);
470
return;
471
default:
472
dbg("%s - nonzero urb status received: %d",
473
__func__, status);
474
goto exit;
475
}
476
477
switch (xpad->xtype) {
478
case XTYPE_XBOX360:
479
xpad360_process_packet(xpad, 0, xpad->idata);
480
break;
481
case XTYPE_XBOX360W:
482
xpad360w_process_packet(xpad, 0, xpad->idata);
483
break;
484
default:
485
xpad_process_packet(xpad, 0, xpad->idata);
486
}
487
488
exit:
489
retval = usb_submit_urb(urb, GFP_ATOMIC);
490
if (retval)
491
err ("%s - usb_submit_urb failed with result %d",
492
__func__, retval);
493
}
494
495
static void xpad_bulk_out(struct urb *urb)
496
{
497
switch (urb->status) {
498
case 0:
499
/* success */
500
break;
501
case -ECONNRESET:
502
case -ENOENT:
503
case -ESHUTDOWN:
504
/* this urb is terminated, clean up */
505
dbg("%s - urb shutting down with status: %d", __func__, urb->status);
506
break;
507
default:
508
dbg("%s - nonzero urb status received: %d", __func__, urb->status);
509
}
510
}
511
512
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
513
static void xpad_irq_out(struct urb *urb)
514
{
515
int retval, status;
516
517
status = urb->status;
518
519
switch (status) {
520
case 0:
521
/* success */
522
return;
523
524
case -ECONNRESET:
525
case -ENOENT:
526
case -ESHUTDOWN:
527
/* this urb is terminated, clean up */
528
dbg("%s - urb shutting down with status: %d", __func__, status);
529
return;
530
531
default:
532
dbg("%s - nonzero urb status received: %d", __func__, status);
533
goto exit;
534
}
535
536
exit:
537
retval = usb_submit_urb(urb, GFP_ATOMIC);
538
if (retval)
539
err("%s - usb_submit_urb failed with result %d",
540
__func__, retval);
541
}
542
543
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
544
{
545
struct usb_endpoint_descriptor *ep_irq_out;
546
int error;
547
548
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
549
return 0;
550
551
xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
552
GFP_KERNEL, &xpad->odata_dma);
553
if (!xpad->odata) {
554
error = -ENOMEM;
555
goto fail1;
556
}
557
558
mutex_init(&xpad->odata_mutex);
559
560
xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
561
if (!xpad->irq_out) {
562
error = -ENOMEM;
563
goto fail2;
564
}
565
566
ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;
567
usb_fill_int_urb(xpad->irq_out, xpad->udev,
568
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
569
xpad->odata, XPAD_PKT_LEN,
570
xpad_irq_out, xpad, ep_irq_out->bInterval);
571
xpad->irq_out->transfer_dma = xpad->odata_dma;
572
xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
573
574
return 0;
575
576
fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
577
fail1: return error;
578
}
579
580
static void xpad_stop_output(struct usb_xpad *xpad)
581
{
582
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX)
583
usb_kill_urb(xpad->irq_out);
584
}
585
586
static void xpad_deinit_output(struct usb_xpad *xpad)
587
{
588
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) {
589
usb_free_urb(xpad->irq_out);
590
usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
591
xpad->odata, xpad->odata_dma);
592
}
593
}
594
#else
595
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
596
static void xpad_deinit_output(struct usb_xpad *xpad) {}
597
static void xpad_stop_output(struct usb_xpad *xpad) {}
598
#endif
599
600
#ifdef CONFIG_JOYSTICK_XPAD_FF
601
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
602
{
603
struct usb_xpad *xpad = input_get_drvdata(dev);
604
605
if (effect->type == FF_RUMBLE) {
606
__u16 strong = effect->u.rumble.strong_magnitude;
607
__u16 weak = effect->u.rumble.weak_magnitude;
608
609
switch (xpad->xtype) {
610
611
case XTYPE_XBOX:
612
xpad->odata[0] = 0x00;
613
xpad->odata[1] = 0x06;
614
xpad->odata[2] = 0x00;
615
xpad->odata[3] = strong / 256; /* left actuator */
616
xpad->odata[4] = 0x00;
617
xpad->odata[5] = weak / 256; /* right actuator */
618
xpad->irq_out->transfer_buffer_length = 6;
619
620
return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
621
622
case XTYPE_XBOX360:
623
xpad->odata[0] = 0x00;
624
xpad->odata[1] = 0x08;
625
xpad->odata[2] = 0x00;
626
xpad->odata[3] = strong / 256; /* left actuator? */
627
xpad->odata[4] = weak / 256; /* right actuator? */
628
xpad->odata[5] = 0x00;
629
xpad->odata[6] = 0x00;
630
xpad->odata[7] = 0x00;
631
xpad->irq_out->transfer_buffer_length = 8;
632
633
return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
634
635
default:
636
dbg("%s - rumble command sent to unsupported xpad type: %d",
637
__func__, xpad->xtype);
638
return -1;
639
}
640
}
641
642
return 0;
643
}
644
645
static int xpad_init_ff(struct usb_xpad *xpad)
646
{
647
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
648
return 0;
649
650
input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
651
652
return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
653
}
654
655
#else
656
static int xpad_init_ff(struct usb_xpad *xpad) { return 0; }
657
#endif
658
659
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
660
#include <linux/leds.h>
661
662
struct xpad_led {
663
char name[16];
664
struct led_classdev led_cdev;
665
struct usb_xpad *xpad;
666
};
667
668
static void xpad_send_led_command(struct usb_xpad *xpad, int command)
669
{
670
if (command >= 0 && command < 14) {
671
mutex_lock(&xpad->odata_mutex);
672
xpad->odata[0] = 0x01;
673
xpad->odata[1] = 0x03;
674
xpad->odata[2] = command;
675
xpad->irq_out->transfer_buffer_length = 3;
676
usb_submit_urb(xpad->irq_out, GFP_KERNEL);
677
mutex_unlock(&xpad->odata_mutex);
678
}
679
}
680
681
static void xpad_led_set(struct led_classdev *led_cdev,
682
enum led_brightness value)
683
{
684
struct xpad_led *xpad_led = container_of(led_cdev,
685
struct xpad_led, led_cdev);
686
687
xpad_send_led_command(xpad_led->xpad, value);
688
}
689
690
static int xpad_led_probe(struct usb_xpad *xpad)
691
{
692
static atomic_t led_seq = ATOMIC_INIT(0);
693
long led_no;
694
struct xpad_led *led;
695
struct led_classdev *led_cdev;
696
int error;
697
698
if (xpad->xtype != XTYPE_XBOX360)
699
return 0;
700
701
xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL);
702
if (!led)
703
return -ENOMEM;
704
705
led_no = (long)atomic_inc_return(&led_seq) - 1;
706
707
snprintf(led->name, sizeof(led->name), "xpad%ld", led_no);
708
led->xpad = xpad;
709
710
led_cdev = &led->led_cdev;
711
led_cdev->name = led->name;
712
led_cdev->brightness_set = xpad_led_set;
713
714
error = led_classdev_register(&xpad->udev->dev, led_cdev);
715
if (error) {
716
kfree(led);
717
xpad->led = NULL;
718
return error;
719
}
720
721
/*
722
* Light up the segment corresponding to controller number
723
*/
724
xpad_send_led_command(xpad, (led_no % 4) + 2);
725
726
return 0;
727
}
728
729
static void xpad_led_disconnect(struct usb_xpad *xpad)
730
{
731
struct xpad_led *xpad_led = xpad->led;
732
733
if (xpad_led) {
734
led_classdev_unregister(&xpad_led->led_cdev);
735
kfree(xpad_led);
736
}
737
}
738
#else
739
static int xpad_led_probe(struct usb_xpad *xpad) { return 0; }
740
static void xpad_led_disconnect(struct usb_xpad *xpad) { }
741
#endif
742
743
744
static int xpad_open(struct input_dev *dev)
745
{
746
struct usb_xpad *xpad = input_get_drvdata(dev);
747
748
/* URB was submitted in probe */
749
if(xpad->xtype == XTYPE_XBOX360W)
750
return 0;
751
752
xpad->irq_in->dev = xpad->udev;
753
if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
754
return -EIO;
755
756
return 0;
757
}
758
759
static void xpad_close(struct input_dev *dev)
760
{
761
struct usb_xpad *xpad = input_get_drvdata(dev);
762
763
if (xpad->xtype != XTYPE_XBOX360W)
764
usb_kill_urb(xpad->irq_in);
765
766
xpad_stop_output(xpad);
767
}
768
769
static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
770
{
771
set_bit(abs, input_dev->absbit);
772
773
switch (abs) {
774
case ABS_X:
775
case ABS_Y:
776
case ABS_RX:
777
case ABS_RY: /* the two sticks */
778
input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128);
779
break;
780
case ABS_Z:
781
case ABS_RZ: /* the triggers (if mapped to axes) */
782
input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
783
break;
784
case ABS_HAT0X:
785
case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */
786
input_set_abs_params(input_dev, abs, -1, 1, 0, 0);
787
break;
788
}
789
}
790
791
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
792
{
793
struct usb_device *udev = interface_to_usbdev(intf);
794
struct usb_xpad *xpad;
795
struct input_dev *input_dev;
796
struct usb_endpoint_descriptor *ep_irq_in;
797
int i, error;
798
799
for (i = 0; xpad_device[i].idVendor; i++) {
800
if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
801
(le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
802
break;
803
}
804
805
xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
806
input_dev = input_allocate_device();
807
if (!xpad || !input_dev) {
808
error = -ENOMEM;
809
goto fail1;
810
}
811
812
xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
813
GFP_KERNEL, &xpad->idata_dma);
814
if (!xpad->idata) {
815
error = -ENOMEM;
816
goto fail1;
817
}
818
819
xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
820
if (!xpad->irq_in) {
821
error = -ENOMEM;
822
goto fail2;
823
}
824
825
xpad->udev = udev;
826
xpad->mapping = xpad_device[i].mapping;
827
xpad->xtype = xpad_device[i].xtype;
828
829
if (xpad->xtype == XTYPE_UNKNOWN) {
830
if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
831
if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
832
xpad->xtype = XTYPE_XBOX360W;
833
else
834
xpad->xtype = XTYPE_XBOX360;
835
} else
836
xpad->xtype = XTYPE_XBOX;
837
838
if (dpad_to_buttons)
839
xpad->mapping |= MAP_DPAD_TO_BUTTONS;
840
if (triggers_to_buttons)
841
xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
842
if (sticks_to_null)
843
xpad->mapping |= MAP_STICKS_TO_NULL;
844
}
845
846
xpad->dev = input_dev;
847
usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
848
strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
849
850
input_dev->name = xpad_device[i].name;
851
input_dev->phys = xpad->phys;
852
usb_to_input_id(udev, &input_dev->id);
853
input_dev->dev.parent = &intf->dev;
854
855
input_set_drvdata(input_dev, xpad);
856
857
input_dev->open = xpad_open;
858
input_dev->close = xpad_close;
859
860
input_dev->evbit[0] = BIT_MASK(EV_KEY);
861
862
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
863
input_dev->evbit[0] |= BIT_MASK(EV_ABS);
864
/* set up axes */
865
for (i = 0; xpad_abs[i] >= 0; i++)
866
xpad_set_up_abs(input_dev, xpad_abs[i]);
867
}
868
869
/* set up standard buttons */
870
for (i = 0; xpad_common_btn[i] >= 0; i++)
871
__set_bit(xpad_common_btn[i], input_dev->keybit);
872
873
/* set up model-specific ones */
874
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
875
for (i = 0; xpad360_btn[i] >= 0; i++)
876
__set_bit(xpad360_btn[i], input_dev->keybit);
877
} else {
878
for (i = 0; xpad_btn[i] >= 0; i++)
879
__set_bit(xpad_btn[i], input_dev->keybit);
880
}
881
882
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
883
for (i = 0; xpad_btn_pad[i] >= 0; i++)
884
__set_bit(xpad_btn_pad[i], input_dev->keybit);
885
} else {
886
for (i = 0; xpad_abs_pad[i] >= 0; i++)
887
xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
888
}
889
890
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
891
for (i = 0; xpad_btn_triggers[i] >= 0; i++)
892
__set_bit(xpad_btn_triggers[i], input_dev->keybit);
893
} else {
894
for (i = 0; xpad_abs_triggers[i] >= 0; i++)
895
xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
896
}
897
898
error = xpad_init_output(intf, xpad);
899
if (error)
900
goto fail3;
901
902
error = xpad_init_ff(xpad);
903
if (error)
904
goto fail4;
905
906
error = xpad_led_probe(xpad);
907
if (error)
908
goto fail5;
909
910
ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
911
usb_fill_int_urb(xpad->irq_in, udev,
912
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
913
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
914
xpad, ep_irq_in->bInterval);
915
xpad->irq_in->transfer_dma = xpad->idata_dma;
916
xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
917
918
error = input_register_device(xpad->dev);
919
if (error)
920
goto fail6;
921
922
usb_set_intfdata(intf, xpad);
923
924
if (xpad->xtype == XTYPE_XBOX360W) {
925
/*
926
* Setup the message to set the LEDs on the
927
* controller when it shows up
928
*/
929
xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
930
if (!xpad->bulk_out) {
931
error = -ENOMEM;
932
goto fail7;
933
}
934
935
xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
936
if (!xpad->bdata) {
937
error = -ENOMEM;
938
goto fail8;
939
}
940
941
xpad->bdata[2] = 0x08;
942
switch (intf->cur_altsetting->desc.bInterfaceNumber) {
943
case 0:
944
xpad->bdata[3] = 0x42;
945
break;
946
case 2:
947
xpad->bdata[3] = 0x43;
948
break;
949
case 4:
950
xpad->bdata[3] = 0x44;
951
break;
952
case 6:
953
xpad->bdata[3] = 0x45;
954
}
955
956
ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
957
usb_fill_bulk_urb(xpad->bulk_out, udev,
958
usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
959
xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);
960
961
/*
962
* Submit the int URB immediately rather than waiting for open
963
* because we get status messages from the device whether
964
* or not any controllers are attached. In fact, it's
965
* exactly the message that a controller has arrived that
966
* we're waiting for.
967
*/
968
xpad->irq_in->dev = xpad->udev;
969
error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
970
if (error)
971
goto fail9;
972
}
973
974
return 0;
975
976
fail9: kfree(xpad->bdata);
977
fail8: usb_free_urb(xpad->bulk_out);
978
fail7: input_unregister_device(input_dev);
979
input_dev = NULL;
980
fail6: xpad_led_disconnect(xpad);
981
fail5: if (input_dev)
982
input_ff_destroy(input_dev);
983
fail4: xpad_deinit_output(xpad);
984
fail3: usb_free_urb(xpad->irq_in);
985
fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
986
fail1: input_free_device(input_dev);
987
kfree(xpad);
988
return error;
989
990
}
991
992
static void xpad_disconnect(struct usb_interface *intf)
993
{
994
struct usb_xpad *xpad = usb_get_intfdata (intf);
995
996
xpad_led_disconnect(xpad);
997
input_unregister_device(xpad->dev);
998
xpad_deinit_output(xpad);
999
1000
if (xpad->xtype == XTYPE_XBOX360W) {
1001
usb_kill_urb(xpad->bulk_out);
1002
usb_free_urb(xpad->bulk_out);
1003
usb_kill_urb(xpad->irq_in);
1004
}
1005
1006
usb_free_urb(xpad->irq_in);
1007
usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
1008
xpad->idata, xpad->idata_dma);
1009
1010
kfree(xpad->bdata);
1011
kfree(xpad);
1012
1013
usb_set_intfdata(intf, NULL);
1014
}
1015
1016
static struct usb_driver xpad_driver = {
1017
.name = "xpad",
1018
.probe = xpad_probe,
1019
.disconnect = xpad_disconnect,
1020
.id_table = xpad_table,
1021
};
1022
1023
static int __init usb_xpad_init(void)
1024
{
1025
return usb_register(&xpad_driver);
1026
}
1027
1028
static void __exit usb_xpad_exit(void)
1029
{
1030
usb_deregister(&xpad_driver);
1031
}
1032
1033
module_init(usb_xpad_init);
1034
module_exit(usb_xpad_exit);
1035
1036
MODULE_AUTHOR(DRIVER_AUTHOR);
1037
MODULE_DESCRIPTION(DRIVER_DESC);
1038
MODULE_LICENSE("GPL");
1039
1040