07 Sep, 2020

2 commits


24 Aug, 2020

1 commit

  • Replace the existing /* fall through */ comments and its variants with
    the new pseudo-keyword macro fallthrough[1]. Also, remove unnecessary
    fall-through markings when it is the case.

    [1] https://www.kernel.org/doc/html/v5.7/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through

    Signed-off-by: Gustavo A. R. Silva

    Gustavo A. R. Silva
     

19 Jun, 2020

1 commit

  • The controllers from the Super Nintendo Classic Edition (AKA the SNES
    Mini) appear as a Classic Controller Pro when connected to a Wii
    Remote. All the buttons work as the same, with the d-pad being mapped
    the same as the d-pad on the Classic Controller Pro. This differs from
    the behaviour of most controllers with d-pads and no analogue sticks,
    where the d-pad maps to ABS_HAT1X for left and right, and ABS_HAT1Y
    for up and down. This patch adds an option to the hid-wiimote module
    to make the Super Nintendo Classic Controller behave this way.

    The patch has been tested with a Super Nintendo Classic Controller
    plugged into a Wii Remote in both with the option both enabled and
    disabled. When enabled the d-pad acts as the analogue control, and
    when disabled it acts as it did before the patch was applied. This
    patch has not been tested with e Wii Classic Controller (either the
    original or the pro version) as I do not have one of these
    controllers.

    Although I have not tested it with these controllers, I think it is
    likely this patch will also work with the NES Classic Edition
    Controllers.

    Signed-off-by: Daniel G. Morse
    Reviewed-by: David Rheinsberg
    Signed-off-by: Jiri Kosina

    Daniel G. Morse
     

31 May, 2019

1 commit

  • Based on 1 normalized pattern(s):

    this program is free software you can redistribute it and or modify
    it under the terms of the gnu general public license as published by
    the free software foundation either version 2 of the license or at
    your option any later version

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-or-later

    has been chosen to replace the boilerplate/reference in 3029 file(s).

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Allison Randal
    Cc: linux-spdx@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

25 Jun, 2018

1 commit

  • This adds the drums and guitar extensions for Wiimote devices.

    Devices are reported as "Nintendo Wii Remote Guitar/Drums". If I ever
    get my hands on "RockBand" guitars, I will try to report them via the
    same interface so user-space does not have to bother which device it
    deals with.

    This is a rebase of the original commits 8e22ecb603c8 and 73f8645db191.
    They were reverted several years ago, since they were dependent on the
    ABS_* rework of the input core. Sadly, this never worked out so these
    commits were never pushed into a release. This rebase now uses the
    ABS_HAT* event codes to report all pressure information.

    Signed-off-by: Nicolas.Adenis-Lamarre
    (Original commits by Nicolas, adapted to v4.18 by David)
    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    Nicolas Adenis-Lamarre
     

22 Nov, 2017

1 commit

  • This converts all remaining cases of the old setup_timer() API into using
    timer_setup(), where the callback argument is the structure already
    holding the struct timer_list. These should have no behavioral changes,
    since they just change which pointer is passed into the callback with
    the same available pointers after conversion. It handles the following
    examples, in addition to some other variations.

    Casting from unsigned long:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, ptr);

    and forced object casts:

    void my_callback(struct something *ptr)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr);

    become:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    Direct function assignments:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    ptr->my_timer.function = my_callback;

    have a temporary cast added, along with converting the args:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback;

    And finally, callbacks without a data assignment:

    void my_callback(unsigned long data)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, 0);

    have their argument renamed to verify they're unused during conversion:

    void my_callback(struct timer_list *unused)
    {
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    The conversion is done with the following Coccinelle script:

    spatch --very-quiet --all-includes --include-headers \
    -I ./arch/x86/include -I ./arch/x86/include/generated \
    -I ./include -I ./arch/x86/include/uapi \
    -I ./arch/x86/include/generated/uapi -I ./include/uapi \
    -I ./include/generated/uapi --include ./include/linux/kconfig.h \
    --dir . \
    --cocci-file ~/src/data/timer_setup.cocci

    @fix_address_of@
    expression e;
    @@

    setup_timer(
    -&(e)
    +&e
    , ...)

    // Update any raw setup_timer() usages that have a NULL callback, but
    // would otherwise match change_timer_function_usage, since the latter
    // will update all function assignments done in the face of a NULL
    // function initialization in setup_timer().
    @change_timer_function_usage_NULL@
    expression _E;
    identifier _timer;
    type _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, NULL, _E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E->_timer, NULL, (_cast_data)_E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, &_E);
    +timer_setup(&_E._timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, (_cast_data)&_E);
    +timer_setup(&_E._timer, NULL, 0);
    )

    @change_timer_function_usage@
    expression _E;
    identifier _timer;
    struct timer_list _stl;
    identifier _callback;
    type _cast_func, _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, _callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    _E->_timer@_stl.function = _callback;
    |
    _E->_timer@_stl.function = &_callback;
    |
    _E->_timer@_stl.function = (_cast_func)_callback;
    |
    _E->_timer@_stl.function = (_cast_func)&_callback;
    |
    _E._timer@_stl.function = _callback;
    |
    _E._timer@_stl.function = &_callback;
    |
    _E._timer@_stl.function = (_cast_func)_callback;
    |
    _E._timer@_stl.function = (_cast_func)&_callback;
    )

    // callback(unsigned long arg)
    @change_callback_handle_cast
    depends on change_timer_function_usage@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    (
    ... when != _origarg
    _handletype *_handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    )
    }

    // callback(unsigned long arg) without existing variable
    @change_callback_handle_cast_no_arg
    depends on change_timer_function_usage &&
    !change_callback_handle_cast@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    + _handletype *_origarg = from_timer(_origarg, t, _timer);
    +
    ... when != _origarg
    - (_handletype *)_origarg
    + _origarg
    ... when != _origarg
    }

    // Avoid already converted callbacks.
    @match_callback_converted
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    { ... }

    // callback(struct something *handle)
    @change_callback_handle_arg
    depends on change_timer_function_usage &&
    !match_callback_converted &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_handletype *_handle
    +struct timer_list *t
    )
    {
    + _handletype *_handle = from_timer(_handle, t, _timer);
    ...
    }

    // If change_callback_handle_arg ran on an empty function, remove
    // the added handler.
    @unchange_callback_handle_arg
    depends on change_timer_function_usage &&
    change_callback_handle_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    {
    - _handletype *_handle = from_timer(_handle, t, _timer);
    }

    // We only want to refactor the setup_timer() data argument if we've found
    // the matching callback. This undoes changes in change_timer_function_usage.
    @unchange_timer_function_usage
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg &&
    !change_callback_handle_arg@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type change_timer_function_usage._cast_data;
    @@

    (
    -timer_setup(&_E->_timer, _callback, 0);
    +setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    |
    -timer_setup(&_E._timer, _callback, 0);
    +setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    )

    // If we fixed a callback from a .function assignment, fix the
    // assignment cast now.
    @change_timer_function_assignment
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_func;
    typedef TIMER_FUNC_TYPE;
    @@

    (
    _E->_timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -&_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    )

    // Sometimes timer functions are called directly. Replace matched args.
    @change_timer_function_calls
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression _E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_data;
    @@

    _callback(
    (
    -(_cast_data)_E
    +&_E->_timer
    |
    -(_cast_data)&_E
    +&_E._timer
    |
    -_E
    +&_E->_timer
    )
    )

    // If a timer has been configured without a data argument, it can be
    // converted without regard to the callback argument, since it is unused.
    @match_timer_function_unused_data@
    expression _E;
    identifier _timer;
    identifier _callback;
    @@

    (
    -setup_timer(&_E->_timer, _callback, 0);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0L);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0UL);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0L);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0UL);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0L);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0UL);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0L);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0UL);
    +timer_setup(_timer, _callback, 0);
    )

    @change_callback_unused_data
    depends on match_timer_function_unused_data@
    identifier match_timer_function_unused_data._callback;
    type _origtype;
    identifier _origarg;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *unused
    )
    {
    ... when != _origarg
    }

    Signed-off-by: Kees Cook

    Kees Cook
     

17 Feb, 2014

2 commits


19 Nov, 2013

1 commit

  • This reverts commit 86b84167d4e67372376a57ea9955c5d53dae232f as it introduced a
    VID/PID conflict with its original owner: hid-wiimote got
    hid:b0005g*v0000054Cp00000306 added but hid-sony already has this id for the
    PS3 Remote (and the ID is oficically assigned to Sony).

    Revert the commit to avoid hid-sony regression. David is working on a
    bluez patch to force proper ID on the wiimote.

    Reported-by: David Herrmann
    Reported-by: Michel Kraus
    Signed-off-by: Jiri Kosina

    Jiri Kosina
     

21 Oct, 2013

1 commit


08 Sep, 2013

1 commit

  • This reverts commits 61e00655e9cb, 73f8645db191 and 8e22ecb603c8:
    "Input: introduce BTN/ABS bits for drums and guitars"
    "HID: wiimote: add support for Guitar-Hero drums"
    "HID: wiimote: add support for Guitar-Hero guitars"

    The extra new ABS_xx values resulted in ABS_MAX no longer being a
    power-of-two, which broke the comparison logic. It also caused the
    ioctl numbers to overflow into the next byte, causing problems for that.

    We'll try again for 3.13.

    Reported-by: Markus Trippelsdorf
    Reported-by: Linus Torvalds
    Acked-by: David Herrmann
    Acked-by: Dmitry Torokhov
    Cc: Benjamin Tissoires
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

04 Sep, 2013

3 commits

  • Instead of passing each byte through stack let's use %*phC specifier to dump
    buffer as a hex string.

    Signed-off-by: Andy Shevchenko
    Acked-by: David Herrmann
    Signed-off-by: Jiri Kosina

    Andy Shevchenko
     
  • Apart from drums, Guitar-Hero also ships with guitars. Use the recently
    introduced input ABS/BTN-bits to report this to user-space.

    Devices are reported as "Nintendo Wii Remote Guitar". If I ever get my
    hands on "RockBand" guitars, I will try to report them via the same
    interface so user-space does not have to bother which device it deals
    with.

    Signed-off-by: Nicolas.Adenis-Lamarre
    (add commit-msg and adjust to new BTN_* IDs)
    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    Nicolas Adenis-Lamarre
     
  • Guitar-Hero comes with a drums extension. Use the newly introduced input
    drums-bits to report this back to user-space. This is a usual extension
    like any other device. Nothing special to take care of.

    We report this to user-space as "Nintendo Wii Remote Drums". There are
    other drums (like "RockBand" drums) which we currently do not support and
    maybe will at some point. However, it is quite likely that we can report
    these via the same interface. This allows user-space to work with them
    without knowing the exact branding.
    I couldn't find anyone who owns a "RockBand" device, though.

    Initial-work-by: Nicolas Adenis-Lamarre
    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     

05 Aug, 2013

1 commit

  • GEN10 and earlier devices seem to not support DRM_KAI if we run in basic
    IR mode. Use DRM_KAIE instead. This might increases overhead slightly as
    the extension port is read and streamed but we stream accelerometer data
    constantly, too, so this is negligible.

    Note that our parsers are hardcoded on IR-formats, so we cannot actually
    use 96-bit IR DRMs for basic IR data. We would have to adjust the parsers.
    But as only GEN20 and newer support this, we simply avoid mixed DRMs.

    This fixes a bug where GEN10 devices didn't provide IR data if
    accelerometer and IR are enabled simultaneously. As a workaround, you can
    enable DRM_KAIE without this patch via (disables device power-management):
    echo "37" >/sys/kernel/debug/hid//drm

    Cc: stable@vger.kernel.org
    Signed-off-by: David Herrmann
    Reported-by: Nicolas Adenis-Lamarre
    Signed-off-by: Jiri Kosina

    David Herrmann
     

27 Jun, 2013

1 commit

  • The Wii U Pro Controller is a new Nintendo remote device that looks very
    similar to the XBox controller. It has nearly the same features and uses
    the same protocol as the Wii Remote.

    We add a new wiimote extension device so the Pro Controller is properly
    detected and supported.

    The device reports MP support, which is odd and I couldn't get it working,
    yet. Hence, we disable MP registers for now. Further investigation is
    needed to see what extra capabilities are provided.

    There are some other unknown bits in the extension reports that I couldn't
    figure out what they do. You can use hidraw to access these if you're
    interested.

    We might want to hook up the "charging" and "USB" bits to the battery
    device so user-space can query whether it is currently charged via USB.

    Signed-off-by: Jiri Kosina

    David Herrmann
     

03 Jun, 2013

21 commits

  • If an extension device isn't initialized properly, or during hardware
    initialization, a device might send extension data which is all 0xff.
    This is ambigious because this is also a valid normal data report. But
    it is impossible, under normal conditions, to trigger valid reports with
    all 0xff. Hence, we can safely ignore them.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • We normally get EXT hotplug events or poll for MP hotplugging so we
    don't need to force extension port initialization during device setup.
    But for gen20 devices, we disable MP polling because MP is always
    present. However, this prevents MP initialization during device setup
    and users need to plug another extension to trigger EXT/MP detection.

    Therefore, we now trigger EXT/MP detection during device setup
    automatically. This also avoids slightly delayed extension detection
    and provides sysfs child-devices prior to the "changed"-uevent during
    device setup.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Devices which have built-in motion plus ports don't need MP detection
    logic. The new WIIMOD_BUILTIN_MP modules sets the WIIPROTO_FLAG_BUILTIN_MP
    flag which disables polling for MP.

    Some other devices erroneously report that they support motion-plus. For
    these devices and all devices without extension ports, we load
    WIIMOD_NO_MP which sets WIIPROTO_FLAG_NO_MP. This effectively disables all
    MP detection logic.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Two new attributes, "extension" and "devtype" now allow user-space to read
    the extension type and device type. As device detection is asynchronous,
    we send a CHANGED event after it is done. This also allows user-space to
    wait for a device to settle before opening its input event devices.

    The "extension" device is compatible with the old "extension" sysfs field
    (which was registered by the static extension support code).

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • If we write a DRM mode via debugfs, we shouldn't allow normal operations
    to overwrite this DRM mode. This is important if we want to debug
    3rd-party devices and we want to see what data is sent on each mode.

    If we write NULL/0 as DRM, the lock is removed again so the best matching
    DRM is chosen by wiimote core.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Add a new extension module for the classic controller so we get hotplug
    support for this device. It is mostly the same as the old static classic
    controller parser.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • This moves the nunchuk parser over to an extension module. This allows to
    make use of hotplugged Nunchuks instead of the old static parser.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • This adds Nintendo Wii Balance Board support to the new HOTPLUG capable
    wiimote core. It is mostly copied from the old extension.

    This also adds Balance Board device detection. Whenever we find a device
    that supports the balance-board extension, we assume that it is a real
    balance board and disable unsupported hardward like accelerometer, IR,
    rumble and more.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • 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: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • IR is the last piece that still is handled natively. This patch converts
    it into a sub-device module like all other sub-devices. It mainly moves
    code and doesn't change semantics.

    We also implicitly sync IR data on ir_to_input3 now so the explicit
    input_sync() calls are no longer needed.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Accelerometer data is very similar to KEYS handling. Therefore, convert
    all ACCEL related handling into a sub-device module similar to KEYS.

    This doesn't change any semantics but only moves code over to
    wiimote-modules.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Each of the 4 LEDs may be supported individually by devices. Therefore,
    we need one module for each device. To avoid code-duplication, we simply
    pass the LED ID as "arg" argument to the module loading code.

    This just moves the code over to wiimote-module. The semantics stay the
    same as before.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • This introduces a new sub-device module for the BATTERY handlers. It
    moves the whole power_supply battery handling over to wiimote-modules.

    This doesn't change any semantics or ABI but only converts the battery
    handling into a sub-device module.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • This introduces the first sub-device modules by converting the KEYS and
    RUMBLE sub-devices into wiimote modules. Both must be converted at once
    because they depend on the built-in shared input device.

    This mostly moves code from wiimote-core to wiimote-modules and doesn't
    change any semantics or ABI.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • To avoid loading all sub-device drivers for every Wii Remote, even though
    the required hardware might not be available, we introduce a module layer.

    The module layer specifies which sub-devices are available on each
    device-type. After device detection, we only load the modules for the
    detected device. If module loading fails, we unload everything and mark
    the device as WIIMOTE_DEV_UNKNOWN. As long as a device is marked as
    "unknown", no sub-devices will be used and the device is considered
    unsupported.

    All the different sub-devices, including KEYS, RUMBLE, BATTERY, LEDS,
    ACCELEROMETER, IR and more will be ported in follow-up patches to the new
    module layer.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Our output queue is asynchronous but synchronous reports may wait for a
    response to their request. Therefore, wake them up unconditionally if an
    output report couldn't be sent. But keep the report ID intact so we don't
    incorrectly assume our request succeeded.

    Note that the underlying connection is required to be reliable and does
    retransmission itself. So it is safe to assume that if the transmission
    fails, the device is in inconsistent state. Hence, we abort every request
    if any output report fails. No need to verify which report failed.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Battery reports are sent along every status report of the Wii Remote.
    So chances are pretty high that we have an up-to-date battery
    cache at any time. Therefore, initialize the battery-cache to 100% and
    then return battery values from the cache if the query fails.

    This works around a power_supply limitation in that it requires us to be
    able to query the device during power_supply registration and
    removal. Otherwise, "add" or "remove" udev events are not sent. If
    we answer these requests from our cache instead, we avoid dropping these
    events and no longer cause warnings printed.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • Nintendo produced many different devices that are internally based on the
    Wii Remote protocol but provide different peripherals. To support these
    devices, we need to schedule a device detection during initialization.

    Device detection includes requesting a status report, reading extension
    information and then evaluating which device we may be dealing with.

    We currently detect gen1 and gen2 Wii Remote devices. All other devices
    are marked as generic devices. More detections will be added later.

    In followup patches we will be using these device IDs to control which
    peripherals to initialize. For instance if a device is known to have no IR
    camera, there is no need to provide the IR input device nor trying to
    access IR registers. In fact, there are 3rd party devices that break if we
    try things like this (hurray!).

    The init_worker will be scheduled whenever we get hotplug events. This
    isn't implemented, yet and will be added later. However, we need to make
    sure that this worker can be called multiple times.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • We need constant I/O to keep the state up-to-date and not miss any
    packets. Hence, call hid_hw_open() during setup and hid_hw_close() during
    destruction.

    These are no-ops for Bluetooth HIDP, but lets be safe.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • The output queue is independent of the other wiimote modules and can run
    on its own. Therefore, move its members into a separate struct so we don't
    run into name collisions with other modules.

    This is only a syntactic change that renames all queue members to queue.*.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • The hid-wiimote driver supports more than the Wii Remote. Nintendo
    produced many devices based on the Wii Remote, which have extension
    devices built-in. It is not clear to many users, that these devices have
    anything in common with the Wii Remote, so fix the driver description.

    This also updates the copyright information for the coming hotplugging
    rework.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     

04 Apr, 2013

2 commits

  • It turns out the Wii accepts any status reports from clients reduced to
    "BB BB" key data only, as long as the report actually includes key data at
    the first two bytes.

    The official devices don't send these reduced reports, but of course, 3rd
    party devices make great use of this feature.

    Hence, add parsers for these reduced reports for every matching report.
    Also change the logic how we find handlers. There is no reason to call
    multiple handlers on a single report, but instead find the best handler
    and call it only once.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • This adds the 2nd generation Wii Remote IDs. They have a different
    Bluetooth chipset (CSR instead of Broadcom) and are more restrictive in
    what they accept as input. Hence, you need up-to-date BlueZ and
    Bluetooth HIDP modules to use these devices.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann