linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Herrmann <dh.herrmann@googlemail.com>
To: linux-input@vger.kernel.org
Cc: jkosina@suse.cz, David Herrmann <dh.herrmann@googlemail.com>
Subject: [PATCH 08/16] HID: wiimote: Register input devices for extensions
Date: Sun, 13 Nov 2011 14:27:11 +0100	[thread overview]
Message-ID: <1321190839-3517-9-git-send-email-dh.herrmann@googlemail.com> (raw)
In-Reply-To: <1321190839-3517-1-git-send-email-dh.herrmann@googlemail.com>

Motion+ and regular extensions are physical adapters for the wiimote so create
one input device for each of them. This also allows to enable only opened
extensions and turn unused extenions off to save battery power.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
 drivers/hid/hid-wiimote-ext.c |  109 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c
index a290ef2..cbfb655 100644
--- a/drivers/hid/hid-wiimote-ext.c
+++ b/drivers/hid/hid-wiimote-ext.c
@@ -19,6 +19,8 @@
 struct wiimote_ext {
 	struct wiimote_data *wdata;
 	struct work_struct worker;
+	struct input_dev *input;
+	struct input_dev *mp_input;
 
 	atomic_t opened;
 	atomic_t mp_opened;
@@ -57,6 +59,9 @@ static bool motionp_read(struct wiimote_ext *ext)
 	ssize_t ret;
 	bool avail = false;
 
+	if (!atomic_read(&ext->mp_opened))
+		return false;
+
 	if (wiimote_cmd_acquire(ext->wdata))
 		return false;
 
@@ -82,7 +87,7 @@ static __u8 ext_read(struct wiimote_ext *ext)
 	__u8 rmem[2], wmem;
 	__u8 type = WIIEXT_NONE;
 
-	if (!ext->plugged)
+	if (!ext->plugged || !atomic_read(&ext->opened))
 		return WIIEXT_NONE;
 
 	if (wiimote_cmd_acquire(ext->wdata))
@@ -234,6 +239,54 @@ static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL);
 
+static int wiiext_input_open(struct input_dev *dev)
+{
+	struct wiimote_ext *ext = input_get_drvdata(dev);
+	int ret;
+
+	ret = hid_hw_open(ext->wdata->hdev);
+	if (ret)
+		return ret;
+
+	atomic_inc(&ext->opened);
+	wiiext_schedule(ext);
+
+	return 0;
+}
+
+static void wiiext_input_close(struct input_dev *dev)
+{
+	struct wiimote_ext *ext = input_get_drvdata(dev);
+
+	atomic_dec(&ext->opened);
+	wiiext_schedule(ext);
+	hid_hw_close(ext->wdata->hdev);
+}
+
+static int wiiext_mp_open(struct input_dev *dev)
+{
+	struct wiimote_ext *ext = input_get_drvdata(dev);
+	int ret;
+
+	ret = hid_hw_open(ext->wdata->hdev);
+	if (ret)
+		return ret;
+
+	atomic_inc(&ext->mp_opened);
+	wiiext_schedule(ext);
+
+	return 0;
+}
+
+static void wiiext_mp_close(struct input_dev *dev)
+{
+	struct wiimote_ext *ext = input_get_drvdata(dev);
+
+	atomic_dec(&ext->mp_opened);
+	wiiext_schedule(ext);
+	hid_hw_close(ext->wdata->hdev);
+}
+
 /* Initializes the extension driver of a wiimote */
 int wiiext_init(struct wiimote_data *wdata)
 {
@@ -248,9 +301,53 @@ int wiiext_init(struct wiimote_data *wdata)
 	ext->wdata = wdata;
 	INIT_WORK(&ext->worker, wiiext_worker);
 
+	ext->input = input_allocate_device();
+	if (!ext->input) {
+		ret = -ENOMEM;
+		goto err_input;
+	}
+
+	input_set_drvdata(ext->input, ext);
+	ext->input->open = wiiext_input_open;
+	ext->input->close = wiiext_input_close;
+	ext->input->dev.parent = &wdata->hdev->dev;
+	ext->input->id.bustype = wdata->hdev->bus;
+	ext->input->id.vendor = wdata->hdev->vendor;
+	ext->input->id.product = wdata->hdev->product;
+	ext->input->id.version = wdata->hdev->version;
+	ext->input->name = WIIMOTE_NAME " Extension";
+
+	ret = input_register_device(ext->input);
+	if (ret) {
+		input_free_device(ext->input);
+		goto err_input;
+	}
+
+	ext->mp_input = input_allocate_device();
+	if (!ext->mp_input) {
+		ret = -ENOMEM;
+		goto err_mp;
+	}
+
+	input_set_drvdata(ext->mp_input, ext);
+	ext->mp_input->open = wiiext_mp_open;
+	ext->mp_input->close = wiiext_mp_close;
+	ext->mp_input->dev.parent = &wdata->hdev->dev;
+	ext->mp_input->id.bustype = wdata->hdev->bus;
+	ext->mp_input->id.vendor = wdata->hdev->vendor;
+	ext->mp_input->id.product = wdata->hdev->product;
+	ext->mp_input->id.version = wdata->hdev->version;
+	ext->mp_input->name = WIIMOTE_NAME " Motion+";
+
+	ret = input_register_device(ext->mp_input);
+	if (ret) {
+		input_free_device(ext->mp_input);
+		goto err_mp;
+	}
+
 	ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension);
 	if (ret)
-		goto err;
+		goto err_dev;
 
 	spin_lock_irqsave(&wdata->state.lock, flags);
 	wdata->ext = ext;
@@ -258,7 +355,11 @@ int wiiext_init(struct wiimote_data *wdata)
 
 	return 0;
 
-err:
+err_dev:
+	input_unregister_device(ext->mp_input);
+err_mp:
+	input_unregister_device(ext->input);
+err_input:
 	kfree(ext);
 	return ret;
 }
@@ -277,6 +378,8 @@ void wiiext_deinit(struct wiimote_data *wdata)
 	spin_unlock_irqrestore(&wdata->state.lock, flags);
 
 	device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
+	input_unregister_device(ext->mp_input);
+	input_unregister_device(ext->input);
 
 	cancel_work_sync(&ext->worker);
 	kfree(ext);
-- 
1.7.7.3


  parent reply	other threads:[~2011-11-13 13:28 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-13 13:27 [PATCH 00/16] Wiimote: Extension and Debug Support David Herrmann
2011-11-13 13:27 ` [PATCH 01/16] HID: wiimote: Rename driver to allow multiple source files David Herrmann
2011-11-13 13:27 ` [PATCH 02/16] HID: wiimote: Move common symbols into header David Herrmann
2011-11-13 13:27 ` [PATCH 03/16] HID: wiimote: Add read-mem helpers David Herrmann
2011-11-13 13:27 ` [PATCH 04/16] HID: wiimote: Add extension support stub David Herrmann
2011-11-14  7:54   ` Oliver Neukum
2011-11-14 11:26     ` David Herrmann
2011-11-14 11:35       ` Oliver Neukum
2011-11-15 19:24         ` David Herrmann
2011-11-13 13:27 ` [PATCH 05/16] HID: wiimote: Add extension initializer stubs David Herrmann
2011-11-13 13:27 ` [PATCH 06/16] HID: wiimote: Add extension initializers David Herrmann
2011-11-13 13:27 ` [PATCH 07/16] HID: wiimote: Add extension sysfs attribute David Herrmann
2011-11-13 13:27 ` David Herrmann [this message]
2011-11-13 13:27 ` [PATCH 09/16] HID: wiimote: Add extension handler stubs David Herrmann
2011-11-13 13:27 ` [PATCH 10/16] HID: wiimote: Parse motion+ data David Herrmann
2011-11-13 13:27 ` [PATCH 11/16] HID: wiimote: Parse nunchuck data David Herrmann
2011-11-13 13:27 ` [PATCH 12/16] HID: wiimote: Parse classic controller data David Herrmann
2011-11-13 13:27 ` [PATCH 13/16] HID: wiimote: Add debugfs support stubs David Herrmann
2011-11-13 13:27 ` [PATCH 14/16] HID: wiimote: Allow direct eeprom access David Herrmann
2011-11-13 13:27 ` [PATCH 15/16] HID: wiimote: Allow direct DRM debug access David Herrmann
2011-11-13 13:27 ` [PATCH 16/16] HID: wiimote: Enable NO_INIT_REPORTS quirk David Herrmann
2011-11-16 17:05   ` Jiri Kosina
2011-11-16 17:49     ` David Herrmann
2011-11-16 18:39       ` Jiri Kosina
2011-11-17 13:11         ` 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=1321190839-3517-9-git-send-email-dh.herrmann@googlemail.com \
    --to=dh.herrmann@googlemail.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).