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.c108
1 files changed, 64 insertions, 44 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index c1087ce4cef9..269a846f3694 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 },
@@ -151,6 +159,7 @@ static const struct xpad_device {
151 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, 159 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
152 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, 160 { 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 }, 161 { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
162 { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
154 { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, 163 { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
155 { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } 164 { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
156}; 165};
@@ -158,7 +167,7 @@ static const struct xpad_device {
158/* buttons shared with xbox and xbox360 */ 167/* buttons shared with xbox and xbox360 */
159static const signed short xpad_common_btn[] = { 168static const signed short xpad_common_btn[] = {
160 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ 169 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */
161 BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ 170 BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
162 -1 /* terminating entry */ 171 -1 /* terminating entry */
163}; 172};
164 173
@@ -168,10 +177,10 @@ static const signed short xpad_btn[] = {
168 -1 /* terminating entry */ 177 -1 /* terminating entry */
169}; 178};
170 179
171/* used when dpad is mapped to nuttons */ 180/* used when dpad is mapped to buttons */
172static const signed short xpad_btn_pad[] = { 181static const signed short xpad_btn_pad[] = {
173 BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ 182 BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, /* d-pad left, right */
174 BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ 183 BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, /* d-pad up, down */
175 -1 /* terminating entry */ 184 -1 /* terminating entry */
176}; 185};
177 186
@@ -279,17 +288,19 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
279{ 288{
280 struct input_dev *dev = xpad->dev; 289 struct input_dev *dev = xpad->dev;
281 290
282 /* left stick */ 291 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
283 input_report_abs(dev, ABS_X, 292 /* left stick */
284 (__s16) le16_to_cpup((__le16 *)(data + 12))); 293 input_report_abs(dev, ABS_X,
285 input_report_abs(dev, ABS_Y, 294 (__s16) le16_to_cpup((__le16 *)(data + 12)));
286 ~(__s16) le16_to_cpup((__le16 *)(data + 14))); 295 input_report_abs(dev, ABS_Y,
287 296 ~(__s16) le16_to_cpup((__le16 *)(data + 14)));
288 /* right stick */ 297
289 input_report_abs(dev, ABS_RX, 298 /* right stick */
290 (__s16) le16_to_cpup((__le16 *)(data + 16))); 299 input_report_abs(dev, ABS_RX,
291 input_report_abs(dev, ABS_RY, 300 (__s16) le16_to_cpup((__le16 *)(data + 16)));
292 ~(__s16) le16_to_cpup((__le16 *)(data + 18))); 301 input_report_abs(dev, ABS_RY,
302 ~(__s16) le16_to_cpup((__le16 *)(data + 18)));
303 }
293 304
294 /* triggers left/right */ 305 /* triggers left/right */
295 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 306 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -302,10 +313,11 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
302 313
303 /* digital pad */ 314 /* digital pad */
304 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 315 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
305 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 316 /* dpad as buttons (left, right, up, down) */
306 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 317 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
307 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 318 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
308 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 319 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
320 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
309 } else { 321 } else {
310 input_report_abs(dev, ABS_HAT0X, 322 input_report_abs(dev, ABS_HAT0X,
311 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 323 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -315,7 +327,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
315 327
316 /* start/back buttons and stick press left/right */ 328 /* start/back buttons and stick press left/right */
317 input_report_key(dev, BTN_START, data[2] & 0x10); 329 input_report_key(dev, BTN_START, data[2] & 0x10);
318 input_report_key(dev, BTN_BACK, data[2] & 0x20); 330 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
319 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 331 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
320 input_report_key(dev, BTN_THUMBR, data[2] & 0x80); 332 input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
321 333
@@ -349,11 +361,11 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
349 361
350 /* digital pad */ 362 /* digital pad */
351 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 363 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
352 /* dpad as buttons (right, left, down, up) */ 364 /* dpad as buttons (left, right, up, down) */
353 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 365 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
354 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 366 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
355 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 367 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
356 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 368 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
357 } else { 369 } else {
358 input_report_abs(dev, ABS_HAT0X, 370 input_report_abs(dev, ABS_HAT0X,
359 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 371 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -363,7 +375,7 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
363 375
364 /* start/back buttons */ 376 /* start/back buttons */
365 input_report_key(dev, BTN_START, data[2] & 0x10); 377 input_report_key(dev, BTN_START, data[2] & 0x10);
366 input_report_key(dev, BTN_BACK, data[2] & 0x20); 378 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
367 379
368 /* stick press left/right */ 380 /* stick press left/right */
369 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 381 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
@@ -378,17 +390,19 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
378 input_report_key(dev, BTN_TR, data[3] & 0x02); 390 input_report_key(dev, BTN_TR, data[3] & 0x02);
379 input_report_key(dev, BTN_MODE, data[3] & 0x04); 391 input_report_key(dev, BTN_MODE, data[3] & 0x04);
380 392
381 /* left stick */ 393 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
382 input_report_abs(dev, ABS_X, 394 /* left stick */
383 (__s16) le16_to_cpup((__le16 *)(data + 6))); 395 input_report_abs(dev, ABS_X,
384 input_report_abs(dev, ABS_Y, 396 (__s16) le16_to_cpup((__le16 *)(data + 6)));
385 ~(__s16) le16_to_cpup((__le16 *)(data + 8))); 397 input_report_abs(dev, ABS_Y,
386 398 ~(__s16) le16_to_cpup((__le16 *)(data + 8)));
387 /* right stick */ 399
388 input_report_abs(dev, ABS_RX, 400 /* right stick */
389 (__s16) le16_to_cpup((__le16 *)(data + 10))); 401 input_report_abs(dev, ABS_RX,
390 input_report_abs(dev, ABS_RY, 402 (__s16) le16_to_cpup((__le16 *)(data + 10)));
391 ~(__s16) le16_to_cpup((__le16 *)(data + 12))); 403 input_report_abs(dev, ABS_RY,
404 ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
405 }
392 406
393 /* triggers left/right */ 407 /* triggers left/right */
394 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 408 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -814,6 +828,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
814 xpad->mapping |= MAP_DPAD_TO_BUTTONS; 828 xpad->mapping |= MAP_DPAD_TO_BUTTONS;
815 if (triggers_to_buttons) 829 if (triggers_to_buttons)
816 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; 830 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
831 if (sticks_to_null)
832 xpad->mapping |= MAP_STICKS_TO_NULL;
817 } 833 }
818 834
819 xpad->dev = input_dev; 835 xpad->dev = input_dev;
@@ -830,16 +846,20 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
830 input_dev->open = xpad_open; 846 input_dev->open = xpad_open;
831 input_dev->close = xpad_close; 847 input_dev->close = xpad_close;
832 848
833 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 849 input_dev->evbit[0] = BIT_MASK(EV_KEY);
850
851 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
852 input_dev->evbit[0] |= BIT_MASK(EV_ABS);
853 /* set up axes */
854 for (i = 0; xpad_abs[i] >= 0; i++)
855 xpad_set_up_abs(input_dev, xpad_abs[i]);
856 }
834 857
835 /* set up standard buttons and axes */ 858 /* set up standard buttons */
836 for (i = 0; xpad_common_btn[i] >= 0; i++) 859 for (i = 0; xpad_common_btn[i] >= 0; i++)
837 __set_bit(xpad_common_btn[i], input_dev->keybit); 860 __set_bit(xpad_common_btn[i], input_dev->keybit);
838 861
839 for (i = 0; xpad_abs[i] >= 0; i++) 862 /* 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) { 863 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
844 for (i = 0; xpad360_btn[i] >= 0; i++) 864 for (i = 0; xpad360_btn[i] >= 0; i++)
845 __set_bit(xpad360_btn[i], input_dev->keybit); 865 __set_bit(xpad360_btn[i], input_dev->keybit);