linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Herrmann <dh.herrmann@gmail.com>
To: linux-input@vger.kernel.org
Cc: Jiri Kosina <jkosina@suse.cz>, David Herrmann <dh.herrmann@gmail.com>
Subject: [PATCH 17/26] HID: wiimote: add Motion Plus extension module
Date: Sun,  5 May 2013 23:13:01 +0200	[thread overview]
Message-ID: <1367788390-29835-18-git-send-email-dh.herrmann@gmail.com> (raw)
In-Reply-To: <1367788390-29835-1-git-send-email-dh.herrmann@gmail.com>

Add parsers for motion plus data so we can hotplug motion plus extensions
and make use of them. This is mostly the same as the old static motion
plus parser.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 drivers/hid/hid-wiimote-modules.c | 144 ++++++++++++++++++++++++++++++++++++++
 drivers/hid/hid-wiimote.h         |   1 +
 2 files changed, 145 insertions(+)

diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index daeb679..aee1b2c 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -1475,11 +1475,155 @@ static const struct wiimod_ops wiimod_bboard = {
 
 /*
  * Motion Plus
+ * The Motion Plus extension provides rotation sensors (gyro) as a small
+ * extension device for Wii Remotes. Many devices have them built-in so
+ * you cannot see them from the outside.
+ * Motion Plus extensions are special because they are on a separate extension
+ * port and allow other extensions to be used simultaneously. This is all
+ * handled by the Wiimote Core so we don't have to deal with it.
  */
 
+static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext)
+{
+	__s32 x, y, z;
+
+	/*        |   8    7    6    5    4    3 |  2  |  1  |
+	 *   -----+------------------------------+-----+-----+
+	 *    1   |               Yaw Speed <7:0>            |
+	 *    2   |              Roll Speed <7:0>            |
+	 *    3   |             Pitch Speed <7:0>            |
+	 *   -----+------------------------------+-----+-----+
+	 *    4   |       Yaw Speed <13:8>       | Yaw |Pitch|
+	 *   -----+------------------------------+-----+-----+
+	 *    5   |      Roll Speed <13:8>       |Roll | Ext |
+	 *   -----+------------------------------+-----+-----+
+	 *    6   |     Pitch Speed <13:8>       |  1  |  0  |
+	 *   -----+------------------------------+-----+-----+
+	 * The single bits Yaw, Roll, Pitch in the lower right corner specify
+	 * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
+	 * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
+	 * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
+	 * and 9 for slow.
+	 * If the wiimote is not rotating the sensor reports 2^13 = 8192.
+	 * Ext specifies whether an extension is connected to the motionp.
+	 * which is parsed by wiimote-core.
+	 */
+
+	x = ext[0];
+	y = ext[1];
+	z = ext[2];
+
+	x |= (((__u16)ext[3]) << 6) & 0xff00;
+	y |= (((__u16)ext[4]) << 6) & 0xff00;
+	z |= (((__u16)ext[5]) << 6) & 0xff00;
+
+	x -= 8192;
+	y -= 8192;
+	z -= 8192;
+
+	if (!(ext[3] & 0x02))
+		x *= 18;
+	else
+		x *= 9;
+	if (!(ext[4] & 0x02))
+		y *= 18;
+	else
+		y *= 9;
+	if (!(ext[3] & 0x01))
+		z *= 18;
+	else
+		z *= 9;
+
+	input_report_abs(wdata->mp, ABS_RX, x);
+	input_report_abs(wdata->mp, ABS_RY, y);
+	input_report_abs(wdata->mp, ABS_RZ, z);
+	input_sync(wdata->mp);
+}
+
+static int wiimod_mp_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_MP_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	__wiimote_schedule(wdata);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_mp_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	__wiimote_schedule(wdata);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_mp_probe(const struct wiimod_ops *ops,
+			   struct wiimote_data *wdata)
+{
+	int ret;
+
+	wdata->mp = input_allocate_device();
+	if (!wdata->mp)
+		return -ENOMEM;
+
+	input_set_drvdata(wdata->mp, wdata);
+	wdata->mp->open = wiimod_mp_open;
+	wdata->mp->close = wiimod_mp_close;
+	wdata->mp->dev.parent = &wdata->hdev->dev;
+	wdata->mp->id.bustype = wdata->hdev->bus;
+	wdata->mp->id.vendor = wdata->hdev->vendor;
+	wdata->mp->id.product = wdata->hdev->product;
+	wdata->mp->id.version = wdata->hdev->version;
+	wdata->mp->name = WIIMOTE_NAME " Motion Plus";
+
+	set_bit(EV_ABS, wdata->mp->evbit);
+	set_bit(ABS_RX, wdata->mp->absbit);
+	set_bit(ABS_RY, wdata->mp->absbit);
+	set_bit(ABS_RZ, wdata->mp->absbit);
+	input_set_abs_params(wdata->mp,
+			     ABS_RX, -16000, 16000, 4, 8);
+	input_set_abs_params(wdata->mp,
+			     ABS_RY, -16000, 16000, 4, 8);
+	input_set_abs_params(wdata->mp,
+			     ABS_RZ, -16000, 16000, 4, 8);
+
+	ret = input_register_device(wdata->mp);
+	if (ret)
+		goto err_free;
+
+	return 0;
+
+err_free:
+	input_free_device(wdata->mp);
+	wdata->mp = NULL;
+	return ret;
+}
+
+static void wiimod_mp_remove(const struct wiimod_ops *ops,
+			     struct wiimote_data *wdata)
+{
+	if (!wdata->mp)
+		return;
+
+	input_unregister_device(wdata->mp);
+	wdata->mp = NULL;
+}
+
 const struct wiimod_ops wiimod_mp = {
 	.flags = 0,
 	.arg = 0,
+	.probe = wiimod_mp_probe,
+	.remove = wiimod_mp_remove,
+	.in_mp = wiimod_mp_in_mp,
 };
 
 /* module table */
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 118520a..3a8bdb9 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -139,6 +139,7 @@ struct wiimote_data {
 	struct input_dev *accel;
 	struct input_dev *ir;
 	struct power_supply battery;
+	struct input_dev *mp;
 	struct timer_list timer;
 	struct wiimote_ext *ext;
 	struct wiimote_debug *debug;
-- 
1.8.2.2


  parent reply	other threads:[~2013-05-05 21:14 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-05 21:12 [PATCH 00/26] Wii Remote Extension Hotplugging Support David Herrmann
2013-05-05 21:12 ` [PATCH 01/26] HID: wiimote: extend driver description David Herrmann
2013-06-03  9:19   ` Jiri Kosina
2013-06-03 20:28     ` David Herrmann
2013-05-05 21:12 ` [PATCH 02/26] HID: wiimote: move queue handling into separate struct David Herrmann
2013-05-05 21:12 ` [PATCH 03/26] HID: wiimote: keep HID device open David Herrmann
2013-05-05 21:12 ` [PATCH 04/26] HID: wiimote: add device detection David Herrmann
2013-05-05 21:12 ` [PATCH 05/26] HID: wiimote: use cached battery values on I/O failure David Herrmann
2013-05-05 21:12 ` [PATCH 06/26] HID: wiimote: wake up if output queue failed David Herrmann
2013-05-05 21:12 ` [PATCH 07/26] HID: wiimote: add sub-device module infrastructure David Herrmann
2013-05-05 21:12 ` [PATCH 08/26] HID: wiimote: convert KEYS and RUMBLE to modules David Herrmann
2013-05-05 21:12 ` [PATCH 09/26] HID: wiimote: convert BATTERY to module David Herrmann
2013-05-05 21:12 ` [PATCH 10/26] HID: wiimote: convert LEDS to modules David Herrmann
2013-05-05 21:12 ` [PATCH 11/26] HID: wiimote: convert ACCEL to module David Herrmann
2013-05-05 21:12 ` [PATCH 12/26] HID: wiimote: convert IR " David Herrmann
2013-05-05 21:12 ` [PATCH 13/26] HID: wiimote: add extension hotplug support David Herrmann
2013-05-23 10:53   ` David Herrmann
2013-05-23 12:28     ` Jiri Kosina
2013-05-05 21:12 ` [PATCH 14/26] HID: wiimote: add Balance Board support David Herrmann
2013-05-05 21:12 ` [PATCH 15/26] HID: wiimote: add Nunchuk support David Herrmann
2013-05-05 21:13 ` [PATCH 16/26] HID: wiimote: add Classic Controller extension David Herrmann
2013-05-06  0:39   ` Todd Showalter
2013-05-06  5:40     ` David Herrmann
2013-05-06 14:15       ` Todd Showalter
2013-05-05 21:13 ` David Herrmann [this message]
2013-05-05 21:13 ` [PATCH 18/26] HID: wiimote: fix ctx pointer in debugfs DRM-write David Herrmann
2013-05-05 21:13 ` [PATCH 19/26] HID: wiimote: lock DRM mode during debugfs overwrite David Herrmann
2013-05-05 21:13 ` [PATCH 20/26] HID: wiimote: add sysfs extension/device-type attrs David Herrmann
2013-05-05 21:13 ` [PATCH 21/26] HID: wiimote: add "bboard_calib" attribute David Herrmann
2013-05-05 21:13 ` [PATCH 22/26] HID: wiimote: remove old static extension support David Herrmann
2013-05-05 21:13 ` [PATCH 23/26] HID: wiimote: add MP quirks David Herrmann
2013-05-05 21:13 ` [RFC 24/26] HID: wiimote: support Nintendo Wii U Pro Controller David Herrmann
2013-05-06  0:43   ` Todd Showalter
2013-05-06  5:49     ` David Herrmann
2013-05-06 14:14       ` Todd Showalter
2013-05-08 15:33         ` David Herrmann
2013-05-08 16:40           ` Todd Showalter
2013-05-08 17:05             ` Dmitry Torokhov
2013-05-08 17:20               ` Todd Showalter
2013-05-08 17:25                 ` David Herrmann
2013-05-08 17:26                 ` Dmitry Torokhov
2013-05-13 17:03                   ` David Herrmann
2013-05-13 17:40                     ` Todd Showalter
2013-05-22 12:10                       ` David Herrmann
2013-05-22 16:18                         ` Todd Showalter
2013-05-05 21:13 ` [PATCH 25/26] HID: wiimote: fix DRM debug-attr to correctly parse input David Herrmann
2013-05-05 21:13 ` [RFC 26/26] HID/ALSA: wiimote: add speaker support David Herrmann
2013-05-26 20:55 ` [PATCH 27/26] HID: wiimote: init EXT/MP during device detection David Herrmann
2013-05-26 20:55   ` [PATCH 28/26] HID: wiimote: discard invalid EXT data reports David Herrmann
2013-05-26 20:55   ` [PATCH 29/26] HID: wiimote: fix classic controller parsing David Herrmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1367788390-29835-18-git-send-email-dh.herrmann@gmail.com \
    --to=dh.herrmann@gmail.com \
    --cc=jkosina@suse.cz \
    --cc=linux-input@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).