aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Rojtberg <rojtberg@gmail.com>2015-10-10 09:33:52 -0700
committerMister Oyster <oysterized@gmail.com>2017-04-11 10:57:31 +0200
commit78bf85e8ba95a3bb9c797a6d1d2f508b43bedefe (patch)
tree78eac3509b7b9a5a88a4e84b95da0a5d86468cdb
parent5efcd944a321557644fc33fc6df4da7543fbb1c2 (diff)
Input: xpad - x360w: report dpad as buttons and axes
as discussed here[0], x360w is the only pad that maps dpad_to_button. This is bad for downstream developers as they have to differ between x360 and x360w which is not intuitive. This patch implements the suggested solution of exposing the dpad both as axes and as buttons. This retains backward compatibility with software already dealing with the difference while makes new software work as expected across x360/ x360w pads. [0] http://www.spinics.net/lists/linux-input/msg34421.html Signed-off-by: Pavel Rojtberg <rojtberg@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Tim Clark <tim.clark.82@gmail.com>
-rw-r--r--drivers/input/joystick/xpad.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index d28c0edcd..9942f7064 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -436,7 +436,16 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
- } else {
+ }
+
+ /*
+ * This should be a simple else block. However historically
+ * xbox360w has mapped DPAD to buttons while xbox360 did not. This
+ * made no sense, but now we can not just switch back and have to
+ * support both behaviors.
+ */
+ if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) ||
+ xpad->xtype == XTYPE_XBOX360W) {
input_report_abs(dev, ABS_HAT0X,
!!(data[2] & 0x08) - !!(data[2] & 0x04));
input_report_abs(dev, ABS_HAT0Y,
@@ -1162,7 +1171,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
for (i = 0; xpad_btn_pad[i] >= 0; i++)
__set_bit(xpad_btn_pad[i], input_dev->keybit);
- } else {
+ }
+
+ /*
+ * This should be a simple else block. However historically
+ * xbox360w has mapped DPAD to buttons while xbox360 did not. This
+ * made no sense, but now we can not just switch back and have to
+ * support both behaviors.
+ */
+ if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) ||
+ xpad->xtype == XTYPE_XBOX360W) {
for (i = 0; xpad_abs_pad[i] >= 0; i++)
xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
}