diff options
author | Nicolas Léveillé <knos@free.fr> | 2009-12-29 23:39:05 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-30 02:33:37 -0500 |
commit | b45d44e7e00c1726dac9437b66c05d3d27acb3f0 (patch) | |
tree | 683e4d8df259c5ab0f2b0c9a7406ba52536d2ed7 /drivers/input | |
parent | 1d9f26262aef6d63ff65eba0fd5f1583f342b69b (diff) |
Input: xpad - allow using triggers as buttons rather than axes
Certain devices implement triggers as buttons rather than axes. In
particular, arcade sticks such as the HORI Real Arcade Pro.EX do not
have analog buttons.
These devices are now setup to present buttons rather than axes for
triggers.
User-space applications often also have problems with
axes-as-buttons. Activating MAP_TRIGGERS_TO_BUTTONS for a device
removes the artificial difference between buttons and triggers.
Signed-off-by: Nicolas Léveillé <nicolas@uucidl.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/joystick/xpad.c | 200 |
1 files changed, 121 insertions, 79 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 482cb1204e43..5483fb9bd819 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -86,9 +86,8 @@ | |||
86 | 86 | ||
87 | /* xbox d-pads should map to buttons, as is required for DDR pads | 87 | /* xbox d-pads should map to buttons, as is required for DDR pads |
88 | but we map them to axes when possible to simplify things */ | 88 | but we map them to axes when possible to simplify things */ |
89 | #define MAP_DPAD_TO_BUTTONS 0 | 89 | #define MAP_DPAD_TO_BUTTONS (1 << 0) |
90 | #define MAP_DPAD_TO_AXES 1 | 90 | #define MAP_TRIGGERS_TO_BUTTONS (1 << 1) |
91 | #define MAP_DPAD_UNKNOWN 2 | ||
92 | 91 | ||
93 | #define XTYPE_XBOX 0 | 92 | #define XTYPE_XBOX 0 |
94 | #define XTYPE_XBOX360 1 | 93 | #define XTYPE_XBOX360 1 |
@@ -99,57 +98,61 @@ static int dpad_to_buttons; | |||
99 | module_param(dpad_to_buttons, bool, S_IRUGO); | 98 | module_param(dpad_to_buttons, bool, S_IRUGO); |
100 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); | 99 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); |
101 | 100 | ||
101 | static int triggers_to_buttons; | ||
102 | module_param(triggers_to_buttons, bool, S_IRUGO); | ||
103 | MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads"); | ||
104 | |||
102 | static const struct xpad_device { | 105 | static const struct xpad_device { |
103 | u16 idVendor; | 106 | u16 idVendor; |
104 | u16 idProduct; | 107 | u16 idProduct; |
105 | char *name; | 108 | char *name; |
106 | u8 dpad_mapping; | 109 | u8 mapping; |
107 | u8 xtype; | 110 | u8 xtype; |
108 | } xpad_device[] = { | 111 | } xpad_device[] = { |
109 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 112 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX }, |
110 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 113 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, |
111 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 114 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, |
112 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 115 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, |
113 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | 116 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, |
114 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 117 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
115 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 118 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, |
116 | { 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 119 | { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, |
117 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 120 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, |
118 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 121 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, |
119 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 122 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, |
120 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 123 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, |
121 | { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 124 | { 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX }, |
122 | { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 125 | { 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX }, |
123 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 126 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX }, |
124 | { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 127 | { 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX }, |
125 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 128 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
126 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 129 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, |
127 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 130 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
128 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 131 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
129 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 132 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
130 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 133 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
131 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 134 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, |
132 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 135 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
133 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 136 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, |
134 | { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 137 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, |
135 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 138 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, |
136 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 139 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, |
137 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 140 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX }, |
138 | { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 141 | { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, |
139 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 142 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
140 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 143 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, |
141 | { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 144 | { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, |
142 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 145 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, |
143 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 146 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX }, |
144 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 147 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
145 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 148 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 }, |
146 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 149 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
147 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 150 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, |
148 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 151 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, |
149 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 152 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
150 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 153 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
151 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 154 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, |
152 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } | 155 | { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } |
153 | }; | 156 | }; |
154 | 157 | ||
155 | /* buttons shared with xbox and xbox360 */ | 158 | /* buttons shared with xbox and xbox360 */ |
@@ -165,13 +168,20 @@ static const signed short xpad_btn[] = { | |||
165 | -1 /* terminating entry */ | 168 | -1 /* terminating entry */ |
166 | }; | 169 | }; |
167 | 170 | ||
168 | /* only used if MAP_DPAD_TO_BUTTONS */ | 171 | /* used when dpad is mapped to nuttons */ |
169 | static const signed short xpad_btn_pad[] = { | 172 | static const signed short xpad_btn_pad[] = { |
170 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ | 173 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ |
171 | BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ | 174 | BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ |
172 | -1 /* terminating entry */ | 175 | -1 /* terminating entry */ |
173 | }; | 176 | }; |
174 | 177 | ||
178 | /* used when triggers are mapped to buttons */ | ||
179 | static const signed short xpad_btn_triggers[] = { | ||
180 | BTN_TL2, BTN_TR2, /* triggers left/right */ | ||
181 | -1 | ||
182 | }; | ||
183 | |||
184 | |||
175 | static const signed short xpad360_btn[] = { /* buttons for x360 controller */ | 185 | static const signed short xpad360_btn[] = { /* buttons for x360 controller */ |
176 | BTN_TL, BTN_TR, /* Button LB/RB */ | 186 | BTN_TL, BTN_TR, /* Button LB/RB */ |
177 | BTN_MODE, /* The big X button */ | 187 | BTN_MODE, /* The big X button */ |
@@ -181,16 +191,21 @@ static const signed short xpad360_btn[] = { /* buttons for x360 controller */ | |||
181 | static const signed short xpad_abs[] = { | 191 | static const signed short xpad_abs[] = { |
182 | ABS_X, ABS_Y, /* left stick */ | 192 | ABS_X, ABS_Y, /* left stick */ |
183 | ABS_RX, ABS_RY, /* right stick */ | 193 | ABS_RX, ABS_RY, /* right stick */ |
184 | ABS_Z, ABS_RZ, /* triggers left/right */ | ||
185 | -1 /* terminating entry */ | 194 | -1 /* terminating entry */ |
186 | }; | 195 | }; |
187 | 196 | ||
188 | /* only used if MAP_DPAD_TO_AXES */ | 197 | /* used when dpad is mapped to axes */ |
189 | static const signed short xpad_abs_pad[] = { | 198 | static const signed short xpad_abs_pad[] = { |
190 | ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ | 199 | ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ |
191 | -1 /* terminating entry */ | 200 | -1 /* terminating entry */ |
192 | }; | 201 | }; |
193 | 202 | ||
203 | /* used when triggers are mapped to axes */ | ||
204 | static const signed short xpad_abs_triggers[] = { | ||
205 | ABS_Z, ABS_RZ, /* triggers left/right */ | ||
206 | -1 | ||
207 | }; | ||
208 | |||
194 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only | 209 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only |
195 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we | 210 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we |
196 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, | 211 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, |
@@ -246,7 +261,7 @@ struct usb_xpad { | |||
246 | 261 | ||
247 | char phys[64]; /* physical device path */ | 262 | char phys[64]; /* physical device path */ |
248 | 263 | ||
249 | int dpad_mapping; /* map d-pad to buttons or to axes */ | 264 | int mapping; /* map d-pad to buttons or to axes */ |
250 | int xtype; /* type of xbox device */ | 265 | int xtype; /* type of xbox device */ |
251 | }; | 266 | }; |
252 | 267 | ||
@@ -277,20 +292,25 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d | |||
277 | ~(__s16) le16_to_cpup((__le16 *)(data + 18))); | 292 | ~(__s16) le16_to_cpup((__le16 *)(data + 18))); |
278 | 293 | ||
279 | /* triggers left/right */ | 294 | /* triggers left/right */ |
280 | input_report_abs(dev, ABS_Z, data[10]); | 295 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
281 | input_report_abs(dev, ABS_RZ, data[11]); | 296 | input_report_key(dev, BTN_TL2, data[10]); |
297 | input_report_key(dev, BTN_TR2, data[11]); | ||
298 | } else { | ||
299 | input_report_abs(dev, ABS_Z, data[10]); | ||
300 | input_report_abs(dev, ABS_RZ, data[11]); | ||
301 | } | ||
282 | 302 | ||
283 | /* digital pad */ | 303 | /* digital pad */ |
284 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { | 304 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
285 | input_report_abs(dev, ABS_HAT0X, | ||
286 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
287 | input_report_abs(dev, ABS_HAT0Y, | ||
288 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
289 | } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { | ||
290 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); | 305 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); |
291 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); | 306 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); |
292 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ | 307 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ |
293 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ | 308 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ |
309 | } else { | ||
310 | input_report_abs(dev, ABS_HAT0X, | ||
311 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
312 | input_report_abs(dev, ABS_HAT0Y, | ||
313 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
294 | } | 314 | } |
295 | 315 | ||
296 | /* start/back buttons and stick press left/right */ | 316 | /* start/back buttons and stick press left/right */ |
@@ -328,17 +348,17 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
328 | struct input_dev *dev = xpad->dev; | 348 | struct input_dev *dev = xpad->dev; |
329 | 349 | ||
330 | /* digital pad */ | 350 | /* digital pad */ |
331 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { | 351 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
332 | input_report_abs(dev, ABS_HAT0X, | ||
333 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
334 | input_report_abs(dev, ABS_HAT0Y, | ||
335 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
336 | } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) { | ||
337 | /* dpad as buttons (right, left, down, up) */ | 352 | /* dpad as buttons (right, left, down, up) */ |
338 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); | 353 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); |
339 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); | 354 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); |
340 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ | 355 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ |
341 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ | 356 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ |
357 | } else { | ||
358 | input_report_abs(dev, ABS_HAT0X, | ||
359 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
360 | input_report_abs(dev, ABS_HAT0Y, | ||
361 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
342 | } | 362 | } |
343 | 363 | ||
344 | /* start/back buttons */ | 364 | /* start/back buttons */ |
@@ -371,8 +391,13 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
371 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); | 391 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); |
372 | 392 | ||
373 | /* triggers left/right */ | 393 | /* triggers left/right */ |
374 | input_report_abs(dev, ABS_Z, data[4]); | 394 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
375 | input_report_abs(dev, ABS_RZ, data[5]); | 395 | input_report_key(dev, BTN_TL2, data[4]); |
396 | input_report_key(dev, BTN_TR2, data[5]); | ||
397 | } else { | ||
398 | input_report_abs(dev, ABS_Z, data[4]); | ||
399 | input_report_abs(dev, ABS_RZ, data[5]); | ||
400 | } | ||
376 | 401 | ||
377 | input_sync(dev); | 402 | input_sync(dev); |
378 | } | 403 | } |
@@ -712,11 +737,11 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | |||
712 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); | 737 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); |
713 | break; | 738 | break; |
714 | case ABS_Z: | 739 | case ABS_Z: |
715 | case ABS_RZ: /* the triggers */ | 740 | case ABS_RZ: /* the triggers (if mapped to axes) */ |
716 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | 741 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); |
717 | break; | 742 | break; |
718 | case ABS_HAT0X: | 743 | case ABS_HAT0X: |
719 | case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */ | 744 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ |
720 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); | 745 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); |
721 | break; | 746 | break; |
722 | } | 747 | } |
@@ -752,10 +777,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
752 | goto fail2; | 777 | goto fail2; |
753 | 778 | ||
754 | xpad->udev = udev; | 779 | xpad->udev = udev; |
755 | xpad->dpad_mapping = xpad_device[i].dpad_mapping; | 780 | xpad->mapping = xpad_device[i].mapping; |
756 | xpad->xtype = xpad_device[i].xtype; | 781 | xpad->xtype = xpad_device[i].xtype; |
757 | if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) | 782 | |
758 | xpad->dpad_mapping = !dpad_to_buttons; | ||
759 | if (xpad->xtype == XTYPE_UNKNOWN) { | 783 | if (xpad->xtype == XTYPE_UNKNOWN) { |
760 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { | 784 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { |
761 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) | 785 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) |
@@ -764,7 +788,13 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
764 | xpad->xtype = XTYPE_XBOX360; | 788 | xpad->xtype = XTYPE_XBOX360; |
765 | } else | 789 | } else |
766 | xpad->xtype = XTYPE_XBOX; | 790 | xpad->xtype = XTYPE_XBOX; |
791 | |||
792 | if (dpad_to_buttons) | ||
793 | xpad->mapping |= MAP_DPAD_TO_BUTTONS; | ||
794 | if (triggers_to_buttons) | ||
795 | xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; | ||
767 | } | 796 | } |
797 | |||
768 | xpad->dev = input_dev; | 798 | xpad->dev = input_dev; |
769 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); | 799 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); |
770 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); | 800 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); |
@@ -781,25 +811,37 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
781 | 811 | ||
782 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 812 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
783 | 813 | ||
784 | /* set up buttons */ | 814 | /* set up standard buttons and axes */ |
785 | for (i = 0; xpad_common_btn[i] >= 0; i++) | 815 | for (i = 0; xpad_common_btn[i] >= 0; i++) |
786 | set_bit(xpad_common_btn[i], input_dev->keybit); | 816 | __set_bit(xpad_common_btn[i], input_dev->keybit); |
787 | if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W)) | ||
788 | for (i = 0; xpad360_btn[i] >= 0; i++) | ||
789 | set_bit(xpad360_btn[i], input_dev->keybit); | ||
790 | else | ||
791 | for (i = 0; xpad_btn[i] >= 0; i++) | ||
792 | set_bit(xpad_btn[i], input_dev->keybit); | ||
793 | if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) | ||
794 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | ||
795 | set_bit(xpad_btn_pad[i], input_dev->keybit); | ||
796 | 817 | ||
797 | /* set up axes */ | ||
798 | for (i = 0; xpad_abs[i] >= 0; i++) | 818 | for (i = 0; xpad_abs[i] >= 0; i++) |
799 | xpad_set_up_abs(input_dev, xpad_abs[i]); | 819 | xpad_set_up_abs(input_dev, xpad_abs[i]); |
800 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) | 820 | |
821 | /* Now set up model-specific ones */ | ||
822 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { | ||
823 | for (i = 0; xpad360_btn[i] >= 0; i++) | ||
824 | __set_bit(xpad360_btn[i], input_dev->keybit); | ||
825 | } else { | ||
826 | for (i = 0; xpad_btn[i] >= 0; i++) | ||
827 | __set_bit(xpad_btn[i], input_dev->keybit); | ||
828 | } | ||
829 | |||
830 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { | ||
831 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | ||
832 | __set_bit(xpad_btn_pad[i], input_dev->keybit); | ||
833 | } else { | ||
801 | for (i = 0; xpad_abs_pad[i] >= 0; i++) | 834 | for (i = 0; xpad_abs_pad[i] >= 0; i++) |
802 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); | 835 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); |
836 | } | ||
837 | |||
838 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | ||
839 | for (i = 0; xpad_btn_triggers[i] >= 0; i++) | ||
840 | __set_bit(xpad_btn_triggers[i], input_dev->keybit); | ||
841 | } else { | ||
842 | for (i = 0; xpad_abs_triggers[i] >= 0; i++) | ||
843 | xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); | ||
844 | } | ||
803 | 845 | ||
804 | error = xpad_init_output(intf, xpad); | 846 | error = xpad_init_output(intf, xpad); |
805 | if (error) | 847 | if (error) |