Age | Commit message (Collapse) | Author |
|
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 <nicolas.adenis.lamarre@gmail.com>
(Original commits by Nicolas, adapted to v4.18 by David)
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <keescook@chromium.org>
|
|
output requests
For BT transport layer,
ret = hid_output_raw_report(A, B, C, HID_OUTPUT_REPORT);
is equivalent to
ret = hid_hw_output_report(A, B, C);
So use the new API where available
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Add a helper to access hdev->hid_output_raw_report().
To convert the drivers, use the following snippets:
for i in drivers/hid/*.c
do
sed -i.bak "s/[^ \t]*->hid_output_raw_report(/hid_output_raw_report(/g" $i
done
Then manually fix for checkpatch.pl
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Reported-by: Michel Kraus <mksolpa@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
The LEGO-wiimote uses a different VID than the Nintendo ID. The device is
technically the same so add the ID.
Cc: <stable@vger.kernel.org> # 3.11+
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <markus@trippelsdorf.de>
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Instead of passing each byte through stack let's use %*phC specifier to dump
buffer as a hex string.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <nicolas.adenis.lamarre@gmail.com>
(add commit-msg and adjust to new BTN_* IDs)
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <nicolas.adenis.lamarre@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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/<dev>/drm
Cc: stable@vger.kernel.org
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Reported-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
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 <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Battery device names must be unique, otherwise registration fails if
multiple Wii Remotes are connected.
This breaks the sysfs API, but there is no known application that uses the
Wii Remote battery that I know of so we should go ahead and apply this.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Use the new module_hid_driver macro in all HID drivers that have
a simple register/unregister init/exit.
This also converts the hid drivers that test for a failure of
hid_register_driver() and report the failure. Using module_hid_driver
in those drivers removes the failure message.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
We incorrectly parse incoming IR data. The extra byte contains the upper
bits and not the lower bits of the x/y coordinates. User-space expects
absolute position data from us so this patch does not break existing
applications. On the contrary, it extends the virtual view and fixes
garbage reports for margin areas of the virtual screen.
Cc: stable@kernel.org
Reported-by: Peter Bukovsky <bukovsky.peter@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Analogically to d7cb3dbd1 ("HID: wacom: Fix invalid power_supply_powers
calls"), fix also the same occurence in wiimote driver.
Reported-by: przemo@firszt.eu
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
* git://git.infradead.org/battery-2.6: (68 commits)
power_supply: Mark da9052 driver as broken
power_supply: Drop usage of nowarn variant of sysfs_create_link()
s3c_adc_battery: Average over more than one adc sample
power_supply: Add DA9052 battery driver
isp1704_charger: Fix missing check
jz4740-battery: Fix signedness bug
power_supply: Assume mains power by default
sbs-battery: Fix devicetree match table
ARM: rx51: Add bq27200 i2c board info
sbs-battery: Change power supply name
devicetree-bindings: Propagate bq20z75->sbs rename to dt bindings
devicetree-bindings: Add vendor entry for Smart Battery Systems
sbs-battery: Rename internals to new name
bq20z75: Rename to sbs-battery
wm97xx_battery: Use DEFINE_MUTEX() for work_lock
max8997_charger: Remove duplicate module.h
lp8727_charger: Some minor fixes for the header
lp8727_charger: Add header file
power_supply: Convert drivers/power/* to use module_platform_driver()
power_supply: Add "unknown" in power supply type
...
|
|
Newer bluetooth stack supports the NO_INIT_REPORTS quirk. The wiimote does not
support report initialization so enable it by default.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
The version number is not needed at all for in-tree drivers. Upstream git is
used to track module versions.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Keep track of current drm and add new debugfs file which reads or writes the
current DRM.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
The wiimote provides direct access to parts of its eeprom. This implements read
support for small chunks of the eeprom. This isn't very fast but prevents the
reader from blocking the wiimote stream for too long.
Write support is not yet supported as the wiimote breaks if we overwrite its
memory. Use hidraw to reverse-engineer the eeprom before implementing write
support here.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Add initializer and deinitializer for debugfs support. This will later allow raw
eeprom access and direct DRM modifications to debug wiimote behaviour and
further protocol reverse-engineerings.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
All supported extensions report data as 6 byte block. All DRMs with extension
data provide at least 6 extension bytes. Hence a generic handler for all
extension bytes is sufficient and can be called on all DRMs.
The handler distinguishes the input and passes it to the right handler. Motion+
passes data interleaved so we can have Motion+ and a regular extension enabled
simultaneously.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
The wiimote supports several extensions. This adds a separate source file which
handles all extensions and can be disabled at compile-time.
The driver reacts on "plug"-events on the extension port and starts a worker
which initializes or deinitializes the extensions.
Currently, the initialization logic is not fully understood and we can only
detect and enable all extensions when all extensions are deactivated. Therefore,
we need to disable all extensions, then detect and activate them again to react
on "plug"-events.
However, deactivating extensions will generate a new "plug"-event and we will
never leave that loop. Hence, we only support extensions if they are plugged
before the wiimote is connected (or before the ext-input device is opened). In
the future we may support full extension hotplug support, but
reverse-engineering this may take a while.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Add helper functions similar to the write-mem helpers but for reading wiimote
memory and eeprom.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Wiimote extension and sound support need access to several symbols so move them
into a new header.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Extension and sound support for the wiimote are quite complex and will be
implemented in separate source files. Hence rename the current driver to "-core"
suffix so multiple files can be linked into this module.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|