diff mbox

[RFC,24/26] HID: wiimote: support Nintendo Wii U Pro Controller

Message ID CANq1E4S7F9tZJxXX2i+1h1hkPfiCNhSTkqLw14NhPQ-vJjBtFg@mail.gmail.com (mailing list archive)
State New, archived
Delegated to: Jiri Kosina
Headers show

Commit Message

David Herrmann May 13, 2013, 5:03 p.m. UTC
Hi Todd & Dmitry

On Wed, May 8, 2013 at 7:26 PM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> We should take existing in-kernel mapping (that would be XBOX and other
> less advanced gamepads in drivers/input/joystick), alias
> NORTH/SOUTH/EAST/WEST accordingly, have new users use NSEW button
> definitions.

I tried to put up some documentation. Comments welcome. If no problems
arise with it, I will send a proper series later.

Regards
David

(As a hint: read this with a monospace font)

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Todd Showalter May 13, 2013, 5:40 p.m. UTC | #1
On Mon, May 13, 2013 at 1:03 PM, David Herrmann <dh.herrmann@gmail.com> wrote:

> I tried to put up some documentation. Comments welcome. If no problems
> arise with it, I will send a proper series later.

    I'd be inclined to add something about the mode button; it's
somewhat special.  Not special in the sense of anything magical
happening in the hardware, just special in the sense that it's the
control that isn't game related.  The hardware that has something that
maps to MODE generally intends the button to mean "pause the game and
let me interact with the OS.".  That's certainly the case for the PS
button on the sixaxis, the backlit X button on the 360 controller and
the home button on the Wii controllers.

    Force feedback is a land of crawling madness and chaos; I'm not
sure there's much right now that can be done to unify it.  You've got
devices with linear motors, rotary motors, speakers, resistance
systems, and combinations of those.  The motor systems are mounted at
different angles in different hardware.  You've potentially got
strange power limitations; there's hardware out there where the
combined draw of all the feedback motors is more than the cable
supplies to the gamepad, so you can't run them all at the same time.
You've got sound feedback vs. rumble feedback vs. active feedback (ie:
the joystick or wheel is actively pushing back against you or trying
to pull you around).  I'd love a unified force feedback system, but
there's so little commonality between devices that I'm not sure
there's any useful set to abstract over.

    I'd be inclined to make two button systems map to BTN_SOUTH and
BTN_EAST; those are the two button that fall most easily under your
thumb with a 4 button gamepad.  BTN_NORTH and BTN_WEST require you to
reach over the other two buttons, which is fine for most people but
less ideal for people with smaller hands.  Even people with large
hands usually find SOUTH and EAST the easiest to reach, so for most
games (at least in my experience) those two buttons wind up being
mapped to the actions we expect people to do the most.  A game might
still have to remap (or throw its hands up and tell you that a two
button controller means you need to keep the keyboard nearby), but I
think making BTN_SOUTH and BTN_EAST the defaults on a 2 button
controller (and adding NORTH or WEST for 3) will be most likely to
work out of the box with most games.

    For the cases where you have buttons in a square pattern rather
than a diamond, yes, I guess we just have to pick a 45 degree rotation
of the compass and live with that.  Having SOUTH and EAST along the
right side makes as much sense as the alternative, so I'm good with
this.

    Could we do explicit BTN_DPAD_UP/DOWN/LEFT/RIGHT?  It feels like
the HAPPY buttons are placeholder defines.

    On the menu pad, I think in practice there's quite often a button
labelled "start".  Granted, it's usually on the right, but see (for
example) the original xbox S controller, where "start" is indeed the
button on the right hand side (and "back" is the one on the left), but
the actual "menu pad" is to the left of the dpad.

    I'd prefer if things were mapped to a pair of digital buttons and
a pair of analog linear pot triggers for the shoulders; that covers a
lot of existing hardware (the xbox series gamepads, wii classic
gamepad, and playstation series gamepad can all be made to fit this
model without undue violence).

    Overall: My complaints are largely minor; there are some tweaks
I'd appreciate, but there's nothing fundamentally wrong here.

                                            Todd.

--
 Todd Showalter, President,
 Electron Jump Games, Inc.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Herrmann May 22, 2013, 12:10 p.m. UTC | #2
Hi

On Mon, May 13, 2013 at 7:40 PM, Todd Showalter <todd@electronjump.com> wrote:
> On Mon, May 13, 2013 at 1:03 PM, David Herrmann <dh.herrmann@gmail.com> wrote:
>
>> I tried to put up some documentation. Comments welcome. If no problems
>> arise with it, I will send a proper series later.
>
>     I'd be inclined to add something about the mode button; it's
> somewhat special.  Not special in the sense of anything magical
> happening in the hardware, just special in the sense that it's the
> control that isn't game related.  The hardware that has something that
> maps to MODE generally intends the button to mean "pause the game and
> let me interact with the OS.".  That's certainly the case for the PS
> button on the sixaxis, the backlit X button on the 360 controller and
> the home button on the Wii controllers.

Sure, I will add a note that this is more like a "system button", than
a button an application should use for normal operations. See below.

>     Force feedback is a land of crawling madness and chaos; I'm not
> sure there's much right now that can be done to unify it.  You've got
> devices with linear motors, rotary motors, speakers, resistance
> systems, and combinations of those.  The motor systems are mounted at
> different angles in different hardware.  You've potentially got
> strange power limitations; there's hardware out there where the
> combined draw of all the feedback motors is more than the cable
> supplies to the gamepad, so you can't run them all at the same time.
> You've got sound feedback vs. rumble feedback vs. active feedback (ie:
> the joystick or wheel is actively pushing back against you or trying
> to pull you around).  I'd love a unified force feedback system, but
> there's so little commonality between devices that I'm not sure
> there's any useful set to abstract over.

I think the kernel provides a pretty nice FF interface. It even
provides emulations for the different kinds of FF if not all are
supported by hardware. Anyway, that's beyond the scope of this
definition and mostly belongs to joysticks. Gamepads normally only
have rumble-motors, don't they?

>     I'd be inclined to make two button systems map to BTN_SOUTH and
> BTN_EAST; those are the two button that fall most easily under your
> thumb with a 4 button gamepad.  BTN_NORTH and BTN_WEST require you to
> reach over the other two buttons, which is fine for most people but
> less ideal for people with smaller hands.  Even people with large
> hands usually find SOUTH and EAST the easiest to reach, so for most
> games (at least in my experience) those two buttons wind up being
> mapped to the actions we expect people to do the most.  A game might
> still have to remap (or throw its hands up and tell you that a two
> button controller means you need to keep the keyboard nearby), but I
> think making BTN_SOUTH and BTN_EAST the defaults on a 2 button
> controller (and adding NORTH or WEST for 3) will be most likely to
> work out of the box with most games.

I wanted to have BTN_NORTH/A/GAMEPAD mapped for all gamepads, but
you're right, the commercial systems use SOUTH/EAST for all trivial
operations. I will change this and see whether we can get another key
that is always mapped (probably BTN_SOUTH? and make this an alias for
BTN_GAMEPAD).

>     For the cases where you have buttons in a square pattern rather
> than a diamond, yes, I guess we just have to pick a 45 degree rotation
> of the compass and live with that.  Having SOUTH and EAST along the
> right side makes as much sense as the alternative, so I'm good with
> this.
>
>     Could we do explicit BTN_DPAD_UP/DOWN/LEFT/RIGHT?  It feels like
> the HAPPY buttons are placeholder defines.

Yep, I added them now.

>     On the menu pad, I think in practice there's quite often a button
> labelled "start".  Granted, it's usually on the right, but see (for
> example) the original xbox S controller, where "start" is indeed the
> button on the right hand side (and "back" is the one on the left), but
> the actual "menu pad" is to the left of the dpad.

I changed the menu-pad definition a little bit. 1-button PADs map to
BTN_START, 2-button pads to START and SELECT. BTN_MODE is no longer
mapped as 3rd button but instead is a special button to acknowledge
the fact that it is mostly some fancy branded button that isn't mapped
by applications.
So the menu-pad no longer _has_ to be in the middle, but I still map
the right button to START and the left to SELECT to keep the "map by
position, not by label" definition.

>     I'd prefer if things were mapped to a pair of digital buttons and
> a pair of analog linear pot triggers for the shoulders; that covers a
> lot of existing hardware (the xbox series gamepads, wii classic
> gamepad, and playstation series gamepad can all be made to fit this
> model without undue violence).

Ugh? I don't understand what you mean here.

>     Overall: My complaints are largely minor; there are some tweaks
> I'd appreciate, but there's nothing fundamentally wrong here.

Thanks a lot! Unfortunately, I don't have all hardware at home so I
can only test the Nintendo devices. However, I am trying to assemble a
list of supported gamepads and how they are mapped. This will give us
a better overview and we can see whether this definition actually
makes sense.

I will send a proper series soon. Thanks for your comments!
David
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Todd Showalter May 22, 2013, 4:18 p.m. UTC | #3
On Wed, May 22, 2013 at 8:10 AM, David Herrmann <dh.herrmann@gmail.com> wrote:

> I think the kernel provides a pretty nice FF interface. It even
> provides emulations for the different kinds of FF if not all are
> supported by hardware. Anyway, that's beyond the scope of this
> definition and mostly belongs to joysticks. Gamepads normally only
> have rumble-motors, don't they?

    From an end-use point of view, (at least on casual reading, which
is as much as I can claim to have done at this point), the problem
with the force feedback API is that you find out what something is by
enumerating its capabilities, but the capabilities aren't specific
enough.

    Let's say I have a controller with two rotary motors.  I can
examine the FF caps and see that there are two motors, and possibly
even infer a little about them, but I don't think I can tell what
direction they are mounted in and how strong they are.

    There were some games on the PS2/PS3 that did some clever tricks
with force feedback; subtle stuff like making the controller fake a
gentle heartbeat that got faster and more uneven the more hurt your
character got, or gave feedback in time to the soundtrack.  To do that
really effectively, you need to understand the power, positioning,
response speed and orientation of the force feedback device.  Without
that complex understanding all you can really do is buzz or thump in a
fairly generic way.

> I wanted to have BTN_NORTH/A/GAMEPAD mapped for all gamepads, but
> you're right, the commercial systems use SOUTH/EAST for all trivial
> operations. I will change this and see whether we can get another key
> that is always mapped (probably BTN_SOUTH? and make this an alias for
> BTN_GAMEPAD).

    Sounds good.

> I changed the menu-pad definition a little bit. 1-button PADs map to
> BTN_START, 2-button pads to START and SELECT. BTN_MODE is no longer
> mapped as 3rd button but instead is a special button to acknowledge
> the fact that it is mostly some fancy branded button that isn't mapped
> by applications.
> So the menu-pad no longer _has_ to be in the middle, but I still map
> the right button to START and the left to SELECT to keep the "map by
> position, not by label" definition.

    Ok.

>>     I'd prefer if things were mapped to a pair of digital buttons and
>> a pair of analog linear pot triggers for the shoulders; that covers a
>> lot of existing hardware (the xbox series gamepads, wii classic
>> gamepad, and playstation series gamepad can all be made to fit this
>> model without undue violence).
>
> Ugh? I don't understand what you mean here.

    If you look at (for example) the XBox 360 controller, it has two
digital shoulder buttons (LB and RB, IIRC) and two analog shoulder
triggers (LT and RT).  The Wii Classic controller has the same; L and
R are analog, ZL and ZR are digital.  The PS series controllers have
four pressure sensitive buttons (L1, L2, R1, R2) which can be digital
or analog depending on whether you read the button bit or the pressure
sensor byte.  Other controllers all map onto this model reasonably
well.

    It's not ideal, but it's a fairly close.

> Thanks a lot! Unfortunately, I don't have all hardware at home so I
> can only test the Nintendo devices. However, I am trying to assemble a
> list of supported gamepads and how they are mapped. This will give us
> a better overview and we can see whether this definition actually
> makes sense.

    I've an original XBox S controller (with a Lik Sang USB adapter),
an XBox 360 wired controller (Microsoft-branded), a PS3 controller
(Sony-branded, but has to be plugged in since I don't have bluetooth),
and can probably dig up my gamecube/ps2/dreamcast USB adapter if given
time.

                                           Todd.

--
 Todd Showalter, President,
 Electron Jump Games, Inc.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/input/gamepad.txt b/Documentation/input/gamepad.txt
index e69de29..6afb1dc 100644
--- a/Documentation/input/gamepad.txt
+++ b/Documentation/input/gamepad.txt
@@ -0,0 +1,154 @@ 
+                            Linux Gamepad API
+----------------------------------------------------------------------------
+
+1. Intro
+~~~~~~~~
+Linux provides many different input drivers for gamepad hardware. To avoid
+having user-space deal with different button-mappings for each gamepad, this
+document defines how gamepads are supposed to report their data.
+
+2. Geometry
+~~~~~~~~~~~
+As "gamepad" we define devices which roughly look like this:
+
+            ____________________________              __
+           / [__ZL__]          [__ZR__] \               |
+          / [__ TL __]        [__ TR __] \              | Front Triggers
+       __/________________________________\__         __|
+      /                                  _   \          |
+     /      /\                          (N)   \         |
+    /       ||      __   __   __     _       _ \        | Main Pad
+   |    <===DP===> |SE| |MO| |ST|   (W) -|- (E) |       |
+    \       ||    ___          ___       _     /        |
+    /\      \/   /   \        /   \     (S)   /\      __|
+   /  \________ | LS  | ____ |  RS | ________/  \       |
+  |         /  \ \___/ /    \ \___/ /  \         |      | Control Sticks
+  |        /    \_____/      \_____/    \        |    __|
+  |       /                              \       |
+   \_____/                                \_____/
+
+       |________|______|    |______|___________|
+         D-Pad    Left       Right   Action Pad
+                 Stick       Stick
+
+                   |_____________|
+                      Menu Pad
+
+Most gamepads have the following features:
+  - Action-Pad
+    4 buttons in diamonds-layout (on the right side). The buttons are
+    differently labeled on most devices so we define them as NORTH,
+    SOUTH, WEST and EAST.
+  - D-Pad (Direction-pad)
+    4 buttons (on the left side) that point up, down, left and right.
+  - Menu-Pad
+    Different constellations, but most-times 3 buttons: SELECT - MODE - START
+  - Analog-Sticks
+    Analog-sticks provide freely moveable sticks to control directions. Not
+    all devices have both or any, but they are present at most times.
+    Analog-sticks may also provide a digital button if you press them.
+  - Triggers
+    Triggers are located on the upper-side of the pad in vertical direction.
+    Not all devices provide them, but the upper buttons are normally named
+    Left- and Right-Triggers, the lower buttons Z-Left and Z-Right.
+  - Rumble
+    Many devices provide force-feedback features. But are mostly just
+    simple rumble motors.
+
+3. Detection
+~~~~~~~~~~~~
+All gamepads that follow the protocol described here map BTN_GAMEPAD. This is
+an alias for BTN_NORTH/BTN_A. It can be used to identify a gamepad as such.
+However, not all gamepads provide all features, so you need to test for all
+features that you need, first. How each feature is mapped is described below.
+
+Legacy drivers often don't comply to these rules. As we cannot change them
+for backwards-compatibility reasons, you need to provide fixup mappings in
+user-space yourself. Some of them might also provide module-options that
+change the mappings so you can adivce users to set these.
+
+All new gamepads are supposed to comply with this mapping. Please report any
+bugs, if they don't.
+
+There are a lot of less-featured/less-powerful devices out there, which re-use
+the buttons from this protocol. However, they try to do this in a compatible
+fashion. For example, the "Nintendo Wii Nunchuk" provides two trigger buttons
+and one analog stick. It reports them as if it were a gamepad with only one
+analog stick and two trigger buttons on the right side.
+But that means, that if you only support "real" gamepads, you must test
+devices for _all_ reported events that need. Otherwise, you will also get
+devices that report a small subset of the events.
+
+No other devices, that do not look/feel like a gamepad, shall report these
+events.
+
+4. Events
+~~~~~~~~~
+Gamepads report the following events:
+
+Action-Pad:
+  Every gamepad device has at least 2 action buttons. This means, that every
+  device reports BTN_NORTH (which BTN_GAMEPAD is an alias for). Regardless
+  of the labels on the buttons, the codes are sent according to the
+  physical position of the buttons.
+  Please note that 2- and 3-button pads are fairly rare and old. You might
+  want to filter gamepads that do not report all four.
+    2-Button Pad:
+      If only 2 action-buttons are present, they are reported as BTN_NORTH and
+      BTN_SOUTH. For vertical layouts, the upper button is BTN_NORTH. For
+      horizontal layouts, the button more on the left is BTN_NORTH.
+    3-Button Pad:
+      If only 3 action-buttons are present, they are reported as (from left
+      to right): BTN_WEST, BTN_NORTH, BTN_EAST
+      If the buttons are aligned perfectly vertically, they are reported as
+      (from bottom up): BTN_WEST, BTN_NORTH, BTN_EAST
+    4-Button Pad:
+      If all 4 action-buttons are present, they can be aligned in two
+      different formations. If diamond-shaped, they are reported as BTN_NORTH,
+      BTN_WEST, BTN_SOUTH, BTN_EAST according to their physical location.
+      If rectangular-shaped, the upper-left button is BTN_NORTH, lower-left
+      is BTN_WEST, lower-right is BTN_SOUTH and upper-right is BTN_EAST.
+
+D-Pad:
+  Every gamepad provides a D-Pad with four directions: Up, Down, Left, Right
+  Some of these are available as digital buttons, some as analog buttons. Some
+  may even report both. The kernel does not convert between these so
+  applications should support both and choose what is more appropriate if
+  both are reported.
+  Digital buttons are reported as BTN_TRIGGER_HAPPY_X, with:
+    Left is BTN_TRIGGER_HAPPY1, right is BTN_TRIGGER_HAPPY2, up is
+    BTN_TRIGGER_HAPPY3 and down is BTN_TRIGGER_HAPPY4.
+  Analog buttons are reported as:
+    ABS_HAT0X and ABS_HAT0Y
+
+Analog-Sticks:
+  The first (left) analog-stick is reported as ABS_X, ABS_Y. The second (right)
+  analog stick is reported as ABS_RX, ABS_RY. If only one stick is present,
+  ABS_RX and ABS_RY will be unmapped.
+  If analog-sticks provide digital buttons, they are mapped accordingly as
+  BTN_THUMBL (first/left) and BTN_THUMBR (second/right).
+
+Triggers:
+  Trigger buttons can be available as digital or analog buttons or both. User-
+  space must correctly deal with any situation and choose the most appropriate
+  mode.
+  Upper trigger buttons are reported as BTN_TR or ABS_HAT1X (right) and BTN_TL
+  or ABS_HAT1Y (left). Lower trigger buttons are reported as BTN_TR2 or
+  ABS_HAT2X (right/ZR) and BTN_TL2 or ABS_HAT2Y (left/ZL).
+  If only one trigger-button combination is present (upper+lower), they are
+  reported as "right" triggers (BTN_TR/ABS_HAT1X).
+
+Menu-Pad:
+  Menu buttons are always digital and are mapped according to their location
+  instead of their labels. That is:
+    1-button Pad: Mapped as BTN_START
+    2-button Pad: Left button mapped as BTN_SELECT, right button mapped as
+                  BTN_START
+    3-button Pad: Mapped (from left to right) as BTN_SELECT, BTN_MODE,
+                  BTN_START
+
+Rumble:
+  Rumble is advertices as FF_RUMBLE.
+
+----------------------------------------------------------------------------
+  Written 2013 by David Herrmann <dh.herrmann@gmail.com>
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index 935119c..f6c18b2 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -507,10 +507,14 @@  struct input_keymap_entry {

 #define BTN_GAMEPAD 0x130
 #define BTN_A 0x130
+#define BTN_NORTH 0x130
 #define BTN_B 0x131
+#define BTN_SOUTH 0x131
 #define BTN_C 0x132
 #define BTN_X 0x133
+#define BTN_EAST 0x133
 #define BTN_Y 0x134
+#define BTN_WEST 0x134
 #define BTN_Z 0x135
 #define BTN_TL 0x136
 #define BTN_TR 0x137