aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorChristoph Fritz <chf.fritz@googlemail.com>2010-07-13 12:42:33 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-07-13 12:43:50 -0400
commit7beae7028acec3bb235fa079fd7e45cc289c0fd7 (patch)
treead03212ea1ed8546cb0939651351fc066b9fb074 /drivers/input
parentbf77499faa1c566ccfb1bbb3a85ae5eb5ca926c6 (diff)
Input: xpad - remove mouse buttons and axes for dance pads
Dance pads don't have any axes/sticks, only buttons for directions. For example buttons like left+right will get triggered at once, an axis can't handle this anyway. So this patch adds a module parameter named "sticks_to_null" for unknown devices. A known dance pad makes use of it by changing to a new mapping-option named DANCEPAD_MAP_CONFIG. Other tested devices may follow by adding this mapping-option too. Some buttons of xpad-devices are addressing mouse-buttons instead of gamepad-buttons. This gets fixed too. Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/joystick/xpad.c107
1 files changed, 63 insertions, 44 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index c1087ce4cef9..c41d012c88dc 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 },
@@ -158,7 +166,7 @@ static const struct xpad_device {
158/* buttons shared with xbox and xbox360 */ 166/* buttons shared with xbox and xbox360 */
159static const signed short xpad_common_btn[] = { 167static const signed short xpad_common_btn[] = {
160 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ 168 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */
161 BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ 169 BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
162 -1 /* terminating entry */ 170 -1 /* terminating entry */
163}; 171};
164 172
@@ -168,10 +176,10 @@ static const signed short xpad_btn[] = {
168 -1 /* terminating entry */ 176 -1 /* terminating entry */
169}; 177};
170 178
171/* used when dpad is mapped to nuttons */ 179/* used when dpad is mapped to buttons */
172static const signed short xpad_btn_pad[] = { 180static const signed short xpad_btn_pad[] = {
173 BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ 181 BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, /* d-pad left, right */
174 BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ 182 BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, /* d-pad up, down */
175 -1 /* terminating entry */ 183 -1 /* terminating entry */
176}; 184};
177 185
@@ -279,17 +287,19 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
279{ 287{
280 struct input_dev *dev = xpad->dev; 288 struct input_dev *dev = xpad->dev;
281 289
282 /* left stick */ 290 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
283 input_report_abs(dev, ABS_X, 291 /* left stick */
284 (__s16) le16_to_cpup((__le16 *)(data + 12))); 292 input_report_abs(dev, ABS_X,
285 input_report_abs(dev, ABS_Y, 293 (__s16) le16_to_cpup((__le16 *)(data + 12)));
286 ~(__s16) le16_to_cpup((__le16 *)(data + 14))); 294 input_report_abs(dev, ABS_Y,
287 295 ~(__s16) le16_to_cpup((__le16 *)(data + 14)));
288 /* right stick */ 296
289 input_report_abs(dev, ABS_RX, 297 /* right stick */
290 (__s16) le16_to_cpup((__le16 *)(data + 16))); 298 input_report_abs(dev, ABS_RX,
291 input_report_abs(dev, ABS_RY, 299 (__s16) le16_to_cpup((__le16 *)(data + 16)));
292 ~(__s16) le16_to_cpup((__le16 *)(data + 18))); 300 input_report_abs(dev, ABS_RY,
301 ~(__s16) le16_to_cpup((__le16 *)(data + 18)));
302 }
293 303
294 /* triggers left/right */ 304 /* triggers left/right */
295 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 305 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -302,10 +312,11 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
302 312
303 /* digital pad */ 313 /* digital pad */
304 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 314 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
305 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 315 /* dpad as buttons (left, right, up, down) */
306 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 316 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
307 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 317 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
308 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 318 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
319 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
309 } else { 320 } else {
310 input_report_abs(dev, ABS_HAT0X, 321 input_report_abs(dev, ABS_HAT0X,
311 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 322 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -315,7 +326,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
315 326
316 /* start/back buttons and stick press left/right */ 327 /* start/back buttons and stick press left/right */
317 input_report_key(dev, BTN_START, data[2] & 0x10); 328 input_report_key(dev, BTN_START, data[2] & 0x10);
318 input_report_key(dev, BTN_BACK, data[2] & 0x20); 329 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
319 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 330 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
320 input_report_key(dev, BTN_THUMBR, data[2] & 0x80); 331 input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
321 332
@@ -349,11 +360,11 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
349 360
350 /* digital pad */ 361 /* digital pad */
351 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 362 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
352 /* dpad as buttons (right, left, down, up) */ 363 /* dpad as buttons (left, right, up, down) */
353 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 364 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
354 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 365 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
355 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 366 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
356 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 367 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
357 } else { 368 } else {
358 input_report_abs(dev, ABS_HAT0X, 369 input_report_abs(dev, ABS_HAT0X,
359 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 370 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -363,7 +374,7 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
363 374
364 /* start/back buttons */ 375 /* start/back buttons */
365 input_report_key(dev, BTN_START, data[2] & 0x10); 376 input_report_key(dev, BTN_START, data[2] & 0x10);
366 input_report_key(dev, BTN_BACK, data[2] & 0x20); 377 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
367 378
368 /* stick press left/right */ 379 /* stick press left/right */
369 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 380 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
@@ -378,17 +389,19 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
378 input_report_key(dev, BTN_TR, data[3] & 0x02); 389 input_report_key(dev, BTN_TR, data[3] & 0x02);
379 input_report_key(dev, BTN_MODE, data[3] & 0x04); 390 input_report_key(dev, BTN_MODE, data[3] & 0x04);
380 391
381 /* left stick */ 392 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
382 input_report_abs(dev, ABS_X, 393 /* left stick */
383 (__s16) le16_to_cpup((__le16 *)(data + 6))); 394 input_report_abs(dev, ABS_X,
384 input_report_abs(dev, ABS_Y, 395 (__s16) le16_to_cpup((__le16 *)(data + 6)));
385 ~(__s16) le16_to_cpup((__le16 *)(data + 8))); 396 input_report_abs(dev, ABS_Y,
386 397 ~(__s16) le16_to_cpup((__le16 *)(data + 8)));
387 /* right stick */ 398
388 input_report_abs(dev, ABS_RX, 399 /* right stick */
389 (__s16) le16_to_cpup((__le16 *)(data + 10))); 400 input_report_abs(dev, ABS_RX,
390 input_report_abs(dev, ABS_RY, 401 (__s16) le16_to_cpup((__le16 *)(data + 10)));
391 ~(__s16) le16_to_cpup((__le16 *)(data + 12))); 402 input_report_abs(dev, ABS_RY,
403 ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
404 }
392 405
393 /* triggers left/right */ 406 /* triggers left/right */
394 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 407 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -814,6 +827,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
814 xpad->mapping |= MAP_DPAD_TO_BUTTONS; 827 xpad->mapping |= MAP_DPAD_TO_BUTTONS;
815 if (triggers_to_buttons) 828 if (triggers_to_buttons)
816 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; 829 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
830 if (sticks_to_null)
831 xpad->mapping |= MAP_STICKS_TO_NULL;
817 } 832 }
818 833
819 xpad->dev = input_dev; 834 xpad->dev = input_dev;
@@ -830,16 +845,20 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
830 input_dev->open = xpad_open; 845 input_dev->open = xpad_open;
831 input_dev->close = xpad_close; 846 input_dev->close = xpad_close;
832 847
833 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 848 input_dev->evbit[0] = BIT_MASK(EV_KEY);
849
850 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
851 input_dev->evbit[0] |= BIT_MASK(EV_ABS);
852 /* set up axes */
853 for (i = 0; xpad_abs[i] >= 0; i++)
854 xpad_set_up_abs(input_dev, xpad_abs[i]);
855 }
834 856
835 /* set up standard buttons and axes */ 857 /* set up standard buttons */
836 for (i = 0; xpad_common_btn[i] >= 0; i++) 858 for (i = 0; xpad_common_btn[i] >= 0; i++)
837 __set_bit(xpad_common_btn[i], input_dev->keybit); 859 __set_bit(xpad_common_btn[i], input_dev->keybit);
838 860
839 for (i = 0; xpad_abs[i] >= 0; i++) 861 /* 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) { 862 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
844 for (i = 0; xpad360_btn[i] >= 0; i++) 863 for (i = 0; xpad360_btn[i] >= 0; i++)
845 __set_bit(xpad360_btn[i], input_dev->keybit); 864 __set_bit(xpad360_btn[i], input_dev->keybit);