• David Herrmann's avatar
    HID: wiimote: add extension hotplug support · 4148b6bf
    David Herrmann authored
    The Wii Remote has several extension ports. The first port (EXT) provides
    hotplug events whenever an extension is plugged. The second port (MP)
    does not provide hotplug events by default. Instead, we have to map MP
    into EXT to get events for it.
    
    This patch introduces hotplug support for extensions. It is fairly
    complicated to get this right because the Wii Remote sends a lot of
    noise-hotplug events while activating extension ports. We need to filter
    the events and only handle the events that are real hotplug events.
    
    Mapping MP into EXT is easy. But if we want both, MP _and_ EXT at the same
    time, we need to map MP into EXT and enable a passthrough-mode. This will
    then send real EXT events through the mapped MP interleaved with real MP
    events. But once MP is mapped, we no longer have access to the real EXT
    registers so we need to perform setup _before_ mapping MP. Furthermore, we
    no longer can read EXT IDs so we cannot verify if EXT is still the same
    extension that we expect it to be.
    We deal with this by unmapping MP whenever we got into a situation where
    EXT might have changed. We then re-read EXT and MP and remap everything.
    
    The real Wii Console takes a fairly easy approach: It simply reconnects to
    the device on hotplug events that it didn't expect. So if a program wants
    MP events, but MP is disconnected, it fails and reconnects so it can wait
    for MP hotplug events again.
    This simplifies hotplugging a lot because we just react on PLUG events and
    ignore UNPLUG events.
    The more sophisticated Wii applications avoid reconnection (well, they
    still reconnect during many weird events, but at least not during UNPLUG)
    but they start polling the device. This allows them to disable the device,
    poll for the extension ports to settle and then initialize them again.
    Unfortunately, this approach fails whenever an extension is replugged
    while it is initialized. We would loose UNPLUG events and polling the
    device later will give unreliable results because the extension port might
    be in some weird state, even though it's actually unplugged.
    
    Our approach is a real HOTPLUG approch. We keep track of the EXT and
    mapped MP hotplug events whenever they occur. We then re-evaluate the
    device state and initialize any possible new extension or deinitialize any
    gone extension. Only during initialization, we set an extension port
    ACTIVE. However, during an unplug event we mark them as INACTIVE. This
    guarantess that a fast UNPLUG -> PLUG event sequence doesn't keep them
    marked as PLUGGED+ACTIVE but only PLUGGED.
    To deal with annoying noise-hotplug events during extension mapping, we
    simply rescan the device before performing any mapping. This allows us to
    ignore all the noise events as long as the device is in the correct state.
    
    Long story short: EXT and MP registers are sparsely known and we need to
    jump through hoops to get reliable HOTPLUG working. But while Nintendo
    needs *FOUR* Bluetooth reconnections for the shortest imaginable
    boot->menu->game->menu->shutdown sequence, we now need *ZERO*.
    
    As always, 3rd party devices tend to break whenever we behave differently
    than the original Wii. So there are also devices which _expect_ a
    disconnect after UNPLUG. Obviously, these devices won't benefit from this
    patch. But all official devices were tested extensively and work great
    during any hotplug sequence. Yay!
    Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    4148b6bf
hid-wiimote-modules.c 21.5 KB