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 v2 05/15] HID: wiimote: Add IR input device
Date: Tue, 6 Sep 2011 13:50:30 +0200 [thread overview]
Message-ID: <1315309840-4664-6-git-send-email-dh.herrmann@googlemail.com> (raw)
In-Reply-To: <1315309840-4664-1-git-send-email-dh.herrmann@googlemail.com>
The IR cam of the wiimote reports 4 trackable lights as absolute values. Since
we can turn the IR cam on and off, we register a separate input device so we can
react on open/close callbacks to save wiimote battery power when IR cam is not
needed.
The cam can be in four states: off, basic, extended and full
The DRM chooser automatically selects a proper DRM that includes all required IR
data so no information is lost.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
drivers/hid/hid-wiimote.c | 71 ++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index de9aadf..4cdaaf6 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -38,6 +38,7 @@ struct wiimote_data {
struct input_dev *input;
struct led_classdev *leds[4];
struct input_dev *accel;
+ struct input_dev *ir;
spinlock_t qlock;
__u8 head;
@@ -54,8 +55,13 @@ struct wiimote_data {
#define WIIPROTO_FLAG_LED4 0x08
#define WIIPROTO_FLAG_RUMBLE 0x10
#define WIIPROTO_FLAG_ACCEL 0x20
+#define WIIPROTO_FLAG_IR_BASIC 0x40
+#define WIIPROTO_FLAG_IR_EXT 0x80
+#define WIIPROTO_FLAG_IR_FULL 0xc0 /* IR_BASIC | IR_EXT */
#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
+#define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \
+ WIIPROTO_FLAG_IR_FULL)
/* return flag for led \num */
#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
@@ -71,6 +77,7 @@ enum wiiproto_reqs {
WIIPROTO_REQ_DRM_KA = 0x31,
WIIPROTO_REQ_DRM_KAI = 0x33,
WIIPROTO_REQ_DRM_KAE = 0x35,
+ WIIPROTO_REQ_DRM_KIE = 0x36,
WIIPROTO_REQ_DRM_KAIE = 0x37,
WIIPROTO_REQ_DRM_SKAI1 = 0x3e,
WIIPROTO_REQ_DRM_SKAI2 = 0x3f,
@@ -248,10 +255,23 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
*/
static __u8 select_drm(struct wiimote_data *wdata)
{
- if (wdata->state.flags & WIIPROTO_FLAG_ACCEL)
- return WIIPROTO_REQ_DRM_KA;
- else
- return WIIPROTO_REQ_DRM_K;
+ __u8 ir = wdata->state.flags & WIIPROTO_FLAGS_IR;
+
+ if (ir == WIIPROTO_FLAG_IR_BASIC) {
+ if (wdata->state.flags & WIIPROTO_FLAG_ACCEL)
+ return WIIPROTO_REQ_DRM_KAIE;
+ else
+ return WIIPROTO_REQ_DRM_KIE;
+ } else if (ir == WIIPROTO_FLAG_IR_EXT) {
+ return WIIPROTO_REQ_DRM_KAI;
+ } else if (ir == WIIPROTO_FLAG_IR_FULL) {
+ return WIIPROTO_REQ_DRM_SKAI1;
+ } else {
+ if (wdata->state.flags & WIIPROTO_FLAG_ACCEL)
+ return WIIPROTO_REQ_DRM_KA;
+ else
+ return WIIPROTO_REQ_DRM_K;
+ }
}
static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
@@ -681,6 +701,36 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4);
input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4);
+ wdata->ir = input_allocate_device();
+ if (!wdata->ir)
+ goto err_ir;
+
+ input_set_drvdata(wdata->ir, wdata);
+ wdata->ir->dev.parent = &wdata->hdev->dev;
+ wdata->ir->id.bustype = wdata->hdev->bus;
+ wdata->ir->id.vendor = wdata->hdev->vendor;
+ wdata->ir->id.product = wdata->hdev->product;
+ wdata->ir->id.version = wdata->hdev->version;
+ wdata->ir->name = WIIMOTE_NAME " IR";
+
+ set_bit(EV_ABS, wdata->ir->evbit);
+ set_bit(ABS_HAT0X, wdata->ir->absbit);
+ set_bit(ABS_HAT0Y, wdata->ir->absbit);
+ set_bit(ABS_HAT1X, wdata->ir->absbit);
+ set_bit(ABS_HAT1Y, wdata->ir->absbit);
+ set_bit(ABS_HAT2X, wdata->ir->absbit);
+ set_bit(ABS_HAT2Y, wdata->ir->absbit);
+ set_bit(ABS_HAT3X, wdata->ir->absbit);
+ set_bit(ABS_HAT3Y, wdata->ir->absbit);
+ input_set_abs_params(wdata->ir, ABS_HAT0X, 0, 1023, 2, 4);
+ input_set_abs_params(wdata->ir, ABS_HAT0Y, 0, 767, 2, 4);
+ input_set_abs_params(wdata->ir, ABS_HAT1X, 0, 1023, 2, 4);
+ input_set_abs_params(wdata->ir, ABS_HAT1Y, 0, 767, 2, 4);
+ input_set_abs_params(wdata->ir, ABS_HAT2X, 0, 1023, 2, 4);
+ input_set_abs_params(wdata->ir, ABS_HAT2Y, 0, 767, 2, 4);
+ input_set_abs_params(wdata->ir, ABS_HAT3X, 0, 1023, 2, 4);
+ input_set_abs_params(wdata->ir, ABS_HAT3Y, 0, 767, 2, 4);
+
spin_lock_init(&wdata->qlock);
INIT_WORK(&wdata->worker, wiimote_worker);
@@ -688,6 +738,8 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
return wdata;
+err_ir:
+ input_free_device(wdata->accel);
err_input:
input_free_device(wdata->input);
err:
@@ -700,6 +752,7 @@ static void wiimote_destroy(struct wiimote_data *wdata)
wiimote_leds_destroy(wdata);
input_unregister_device(wdata->accel);
+ input_unregister_device(wdata->ir);
input_unregister_device(wdata->input);
cancel_work_sync(&wdata->worker);
hid_hw_stop(wdata->hdev);
@@ -737,6 +790,12 @@ static int wiimote_hid_probe(struct hid_device *hdev,
goto err_stop;
}
+ ret = input_register_device(wdata->ir);
+ if (ret) {
+ hid_err(hdev, "Cannot register input device\n");
+ goto err_ir;
+ }
+
ret = input_register_device(wdata->input);
if (ret) {
hid_err(hdev, "Cannot register input device\n");
@@ -761,11 +820,15 @@ err_free:
return ret;
err_input:
+ input_unregister_device(wdata->ir);
+ wdata->ir = NULL;
+err_ir:
input_unregister_device(wdata->accel);
wdata->accel = NULL;
err_stop:
hid_hw_stop(hdev);
err:
+ input_free_device(wdata->ir);
input_free_device(wdata->accel);
input_free_device(wdata->input);
kfree(wdata);
--
1.7.6.1
next prev parent reply other threads:[~2011-09-06 11:51 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-06 11:50 [PATCH v2 00/15] Extended Wiimote Support David Herrmann
2011-09-06 11:50 ` [PATCH v2 01/15] HID: wiimote: Support rumble device David Herrmann
2011-09-06 11:50 ` [PATCH v2 02/15] HID: wiimote: Add force-feedback support David Herrmann
2011-09-06 11:50 ` [PATCH v2 03/15] HID: wiimote: Add accelerometer input device David Herrmann
2011-09-06 11:50 ` [PATCH v2 04/15] HID: wiimote: Parse accelerometer data David Herrmann
2011-09-06 11:50 ` David Herrmann [this message]
2011-09-06 11:50 ` [PATCH v2 06/15] HID: wiimote: Parse IR data David Herrmann
2011-09-06 11:50 ` [PATCH v2 07/15] HID: wiimote: Add missing extension DRM handlers David Herrmann
2011-09-06 11:50 ` [PATCH v2 08/15] HID: wiimote: Add register/eeprom memory support David Herrmann
2011-09-06 11:50 ` [PATCH v2 09/15] HID: wiimote: Helper functions for synchronous requests David Herrmann
2011-09-06 11:50 ` [PATCH v2 10/15] HID: wiimote: Add write-register helpers David Herrmann
2011-09-06 11:50 ` [PATCH v2 11/15] HID: wiimote: Add IR initializer David Herrmann
2011-09-06 11:50 ` [PATCH v2 12/15] HID: wiimote: Initialize IR cam on request David Herrmann
2011-09-06 11:50 ` [PATCH v2 13/15] HID: wiimote: Add status request David Herrmann
2011-09-06 11:50 ` [PATCH v2 14/15] HID: wiimote: Read wiimote battery charge level David Herrmann
2011-09-06 11:50 ` [PATCH v2 15/15] HID: wiimote: Add MAINTAINERS entry David Herrmann
2011-09-07 11:29 ` [PATCH v2 00/15] Extended Wiimote Support Jiri Kosina
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=1315309840-4664-6-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).