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