aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joystick/xpad.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/joystick/xpad.c')
-rw-r--r--drivers/input/joystick/xpad.c109
1 files changed, 65 insertions, 44 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index c1087ce4cef9..f9fb7fa10af3 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -9,6 +9,7 @@
9 * 2005 Dominic Cerquetti <binary1230@yahoo.com> 9 * 2005 Dominic Cerquetti <binary1230@yahoo.com>
10 * 2006 Adam Buchbinder <adam.buchbinder@gmail.com> 10 * 2006 Adam Buchbinder <adam.buchbinder@gmail.com>
11 * 2007 Jan Kratochvil <honza@jikos.cz> 11 * 2007 Jan Kratochvil <honza@jikos.cz>
12 * 2010 Christoph Fritz <chf.fritz@googlemail.com>
12 * 13 *
13 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as 15 * modify it under the terms of the GNU General Public License as
@@ -88,6 +89,9 @@
88 but we map them to axes when possible to simplify things */ 89 but we map them to axes when possible to simplify things */
89#define MAP_DPAD_TO_BUTTONS (1 << 0) 90#define MAP_DPAD_TO_BUTTONS (1 << 0)
90#define MAP_TRIGGERS_TO_BUTTONS (1 << 1) 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)
91 95
92#define XTYPE_XBOX 0 96#define XTYPE_XBOX 0
93#define XTYPE_XBOX360 1 97#define XTYPE_XBOX360 1
@@ -102,6 +106,10 @@ static int triggers_to_buttons;
102module_param(triggers_to_buttons, bool, S_IRUGO); 106module_param(triggers_to_buttons, bool, S_IRUGO);
103MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads"); 107MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads");
104 108
109static int sticks_to_null;
110module_param(sticks_to_null, bool, S_IRUGO);
111MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
112
105static const struct xpad_device { 113static const struct xpad_device {
106 u16 idVendor; 114 u16 idVendor;
107 u16 idProduct; 115 u16 idProduct;
@@ -114,7 +122,7 @@ static const struct xpad_device {
114 { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, 122 { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
115 { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, 123 { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
116 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 124 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
117 { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, 125 { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX },
118 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, 126 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
119 { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, 127 { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
120 { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, 128 { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
@@ -140,6 +148,7 @@ static const struct xpad_device {
140 { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX }, 148 { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
141 { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, 149 { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
142 { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, 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 },
143 { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, 152 { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
144 { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, 153 { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
145 { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, 154 { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
@@ -151,6 +160,7 @@ static const struct xpad_device {
151 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, 160 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
152 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, 161 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
153 { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_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 },
154 { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, 164 { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
155 { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } 165 { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
156}; 166};
@@ -158,7 +168,7 @@ static const struct xpad_device {
158/* buttons shared with xbox and xbox360 */ 168/* buttons shared with xbox and xbox360 */
159static const signed short xpad_common_btn[] = { 169static const signed short xpad_common_btn[] = {
160 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ 170 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */
161 BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ 171 BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
162 -1 /* terminating entry */ 172 -1 /* terminating entry */
163}; 173};
164 174
@@ -168,10 +178,10 @@ static const signed short xpad_btn[] = {
168 -1 /* terminating entry */ 178 -1 /* terminating entry */
169}; 179};
170 180
171/* used when dpad is mapped to nuttons */ 181/* used when dpad is mapped to buttons */
172static const signed short xpad_btn_pad[] = { 182static const signed short xpad_btn_pad[] = {
173 BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ 183 BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, /* d-pad left, right */
174 BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ 184 BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, /* d-pad up, down */
175 -1 /* terminating entry */ 185 -1 /* terminating entry */
176}; 186};
177 187
@@ -279,17 +289,19 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
279{ 289{
280 struct input_dev *dev = xpad->dev; 290 struct input_dev *dev = xpad->dev;
281 291
282 /* left stick */ 292 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
283 input_report_abs(dev, ABS_X, 293 /* left stick */
284 (__s16) le16_to_cpup((__le16 *)(data + 12))); 294 input_report_abs(dev, ABS_X,
285 input_report_abs(dev, ABS_Y, 295 (__s16) le16_to_cpup((__le16 *)(data + 12)));
286 ~(__s16) le16_to_cpup((__le16 *)(data + 14))); 296 input_report_abs(dev, ABS_Y,
287 297 ~(__s16) le16_to_cpup((__le16 *)(data + 14)));
288 /* right stick */ 298
289 input_report_abs(dev, ABS_RX, 299 /* right stick */
290 (__s16) le16_to_cpup((__le16 *)(data + 16))); 300 input_report_abs(dev, ABS_RX,
291 input_report_abs(dev, ABS_RY, 301 (__s16) le16_to_cpup((__le16 *)(data + 16)));
292 ~(__s16) le16_to_cpup((__le16 *)(data + 18))); 302 input_report_abs(dev, ABS_RY,
303 ~(__s16) le16_to_cpup((__le16 *)(data + 18)));
304 }
293 305
294 /* triggers left/right */ 306 /* triggers left/right */
295 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 307 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -302,10 +314,11 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
302 314
303 /* digital pad */ 315 /* digital pad */
304 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 316 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
305 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 317 /* dpad as buttons (left, right, up, down) */
306 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 318 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
307 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 319 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
308 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 320 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
321 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
309 } else { 322 } else {
310 input_report_abs(dev, ABS_HAT0X, 323 input_report_abs(dev, ABS_HAT0X,
311 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 324 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -315,7 +328,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
315 328
316 /* start/back buttons and stick press left/right */ 329 /* start/back buttons and stick press left/right */
317 input_report_key(dev, BTN_START, data[2] & 0x10); 330 input_report_key(dev, BTN_START, data[2] & 0x10);
318 input_report_key(dev, BTN_BACK, data[2] & 0x20); 331 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
319 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 332 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
320 input_report_key(dev, BTN_THUMBR, data[2] & 0x80); 333 input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
321 334
@@ -349,11 +362,11 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
349 362
350 /* digital pad */ 363 /* digital pad */
351 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 364 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
352 /* dpad as buttons (right, left, down, up) */ 365 /* dpad as buttons (left, right, up, down) */
353 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 366 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
354 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 367 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
355 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 368 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
356 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 369 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
357 } else { 370 } else {
358 input_report_abs(dev, ABS_HAT0X, 371 input_report_abs(dev, ABS_HAT0X,
359 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 372 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -363,7 +376,7 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
363 376
364 /* start/back buttons */ 377 /* start/back buttons */
365 input_report_key(dev, BTN_START, data[2] & 0x10); 378 input_report_key(dev, BTN_START, data[2] & 0x10);
366 input_report_key(dev, BTN_BACK, data[2] & 0x20); 379 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
367 380
368 /* stick press left/right */ 381 /* stick press left/right */
369 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 382 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
@@ -378,17 +391,19 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
378 input_report_key(dev, BTN_TR, data[3] & 0x02); 391 input_report_key(dev, BTN_TR, data[3] & 0x02);
379 input_report_key(dev, BTN_MODE, data[3] & 0x04); 392 input_report_key(dev, BTN_MODE, data[3] & 0x04);
380 393
381 /* left stick */ 394 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
382 input_report_abs(dev, ABS_X, 395 /* left stick */
383 (__s16) le16_to_cpup((__le16 *)(data + 6))); 396 input_report_abs(dev, ABS_X,
384 input_report_abs(dev, ABS_Y, 397 (__s16) le16_to_cpup((__le16 *)(data + 6)));
385 ~(__s16) le16_to_cpup((__le16 *)(data + 8))); 398 input_report_abs(dev, ABS_Y,
386 399 ~(__s16) le16_to_cpup((__le16 *)(data + 8)));
387 /* right stick */ 400
388 input_report_abs(dev, ABS_RX, 401 /* right stick */
389 (__s16) le16_to_cpup((__le16 *)(data + 10))); 402 input_report_abs(dev, ABS_RX,
390 input_report_abs(dev, ABS_RY, 403 (__s16) le16_to_cpup((__le16 *)(data + 10)));
391 ~(__s16) le16_to_cpup((__le16 *)(data + 12))); 404 input_report_abs(dev, ABS_RY,
405 ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
406 }
392 407
393 /* triggers left/right */ 408 /* triggers left/right */
394 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 409 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -814,6 +829,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
814 xpad->mapping |= MAP_DPAD_TO_BUTTONS; 829 xpad->mapping |= MAP_DPAD_TO_BUTTONS;
815 if (triggers_to_buttons) 830 if (triggers_to_buttons)
816 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; 831 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
832 if (sticks_to_null)
833 xpad->mapping |= MAP_STICKS_TO_NULL;
817 } 834 }
818 835
819 xpad->dev = input_dev; 836 xpad->dev = input_dev;
@@ -830,16 +847,20 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
830 input_dev->open = xpad_open; 847 input_dev->open = xpad_open;
831 input_dev->close = xpad_close; 848 input_dev->close = xpad_close;
832 849
833 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 850 input_dev->evbit[0] = BIT_MASK(EV_KEY);
851
852 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
853 input_dev->evbit[0] |= BIT_MASK(EV_ABS);
854 /* set up axes */
855 for (i = 0; xpad_abs[i] >= 0; i++)
856 xpad_set_up_abs(input_dev, xpad_abs[i]);
857 }
834 858
835 /* set up standard buttons and axes */ 859 /* set up standard buttons */
836 for (i = 0; xpad_common_btn[i] >= 0; i++) 860 for (i = 0; xpad_common_btn[i] >= 0; i++)
837 __set_bit(xpad_common_btn[i], input_dev->keybit); 861 __set_bit(xpad_common_btn[i], input_dev->keybit);
838 862
839 for (i = 0; xpad_abs[i] >= 0; i++) 863 /* set up model-specific ones */
840 xpad_set_up_abs(input_dev, xpad_abs[i]);
841
842 /* Now set up model-specific ones */
843 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { 864 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
844 for (i = 0; xpad360_btn[i] >= 0; i++) 865 for (i = 0; xpad360_btn[i] >= 0; i++)
845 __set_bit(xpad360_btn[i], input_dev->keybit); 866 __set_bit(xpad360_btn[i], input_dev->keybit);