blob: f05f1549d943d529c053f888d114d1bca042aa06 [file] [log] [blame]
David Herrmanncb992212011-11-17 14:12:01 +01001/*
2 * HID driver for Nintendo Wiimote extension devices
3 * Copyright (c) 2011 David Herrmann
4 */
5
6/*
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 */
12
13#include <linux/atomic.h>
14#include <linux/module.h>
15#include <linux/spinlock.h>
16#include <linux/workqueue.h>
17#include "hid-wiimote.h"
18
19struct wiimote_ext {
20 struct wiimote_data *wdata;
21 struct work_struct worker;
David Herrmann479901b2011-11-17 14:12:05 +010022 struct input_dev *input;
23 struct input_dev *mp_input;
David Herrmanncb992212011-11-17 14:12:01 +010024
25 atomic_t opened;
26 atomic_t mp_opened;
27 bool plugged;
David Herrmannb17b57a2011-11-17 14:12:07 +010028 bool mp_plugged;
David Herrmanncb992212011-11-17 14:12:01 +010029 bool motionp;
30 __u8 ext_type;
31};
32
33enum wiiext_type {
34 WIIEXT_NONE, /* placeholder */
35 WIIEXT_CLASSIC, /* Nintendo classic controller */
36 WIIEXT_NUNCHUCK, /* Nintendo nunchuck controller */
37};
38
David Herrmanna5353502011-11-17 14:12:08 +010039enum wiiext_keys {
40 WIIEXT_KEY_C,
41 WIIEXT_KEY_Z,
42 WIIEXT_KEY_COUNT
43};
44
45static __u16 wiiext_keymap[] = {
46 BTN_C, /* WIIEXT_KEY_C */
47 BTN_Z, /* WIIEXT_KEY_Z */
48};
49
David Herrmann82fb1b32011-11-17 14:12:02 +010050/* diable all extensions */
51static void ext_disable(struct wiimote_ext *ext)
52{
53 unsigned long flags;
David Herrmann492ba952011-11-17 14:12:03 +010054 __u8 wmem = 0x55;
55
56 if (!wiimote_cmd_acquire(ext->wdata)) {
57 wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
58 wiimote_cmd_release(ext->wdata);
59 }
David Herrmann82fb1b32011-11-17 14:12:02 +010060
61 spin_lock_irqsave(&ext->wdata->state.lock, flags);
62 ext->motionp = false;
63 ext->ext_type = WIIEXT_NONE;
David Herrmann492ba952011-11-17 14:12:03 +010064 wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
David Herrmann82fb1b32011-11-17 14:12:02 +010065 spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
66}
67
68static bool motionp_read(struct wiimote_ext *ext)
69{
David Herrmann492ba952011-11-17 14:12:03 +010070 __u8 rmem[2], wmem;
71 ssize_t ret;
72 bool avail = false;
73
David Herrmann479901b2011-11-17 14:12:05 +010074 if (!atomic_read(&ext->mp_opened))
75 return false;
76
David Herrmann492ba952011-11-17 14:12:03 +010077 if (wiimote_cmd_acquire(ext->wdata))
78 return false;
79
80 /* initialize motion plus */
81 wmem = 0x55;
82 ret = wiimote_cmd_write(ext->wdata, 0xa600f0, &wmem, sizeof(wmem));
83 if (ret)
84 goto error;
85
86 /* read motion plus ID */
87 ret = wiimote_cmd_read(ext->wdata, 0xa600fe, rmem, 2);
88 if (ret == 2 || rmem[1] == 0x5)
89 avail = true;
90
91error:
92 wiimote_cmd_release(ext->wdata);
93 return avail;
David Herrmann82fb1b32011-11-17 14:12:02 +010094}
95
96static __u8 ext_read(struct wiimote_ext *ext)
97{
David Herrmann492ba952011-11-17 14:12:03 +010098 ssize_t ret;
99 __u8 rmem[2], wmem;
100 __u8 type = WIIEXT_NONE;
101
David Herrmann479901b2011-11-17 14:12:05 +0100102 if (!ext->plugged || !atomic_read(&ext->opened))
David Herrmann492ba952011-11-17 14:12:03 +0100103 return WIIEXT_NONE;
104
105 if (wiimote_cmd_acquire(ext->wdata))
106 return WIIEXT_NONE;
107
108 /* initialize extension */
109 wmem = 0x55;
110 ret = wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
111 if (!ret) {
112 /* disable encryption */
113 wmem = 0x0;
114 wiimote_cmd_write(ext->wdata, 0xa400fb, &wmem, sizeof(wmem));
115 }
116
117 /* read extension ID */
118 ret = wiimote_cmd_read(ext->wdata, 0xa400fe, rmem, 2);
119 if (ret == 2) {
120 if (rmem[0] == 0 && rmem[1] == 0)
121 type = WIIEXT_NUNCHUCK;
122 else if (rmem[0] == 0x01 && rmem[1] == 0x01)
123 type = WIIEXT_CLASSIC;
124 }
125
126 wiimote_cmd_release(ext->wdata);
127
128 return type;
David Herrmann82fb1b32011-11-17 14:12:02 +0100129}
130
131static void ext_enable(struct wiimote_ext *ext, bool motionp, __u8 ext_type)
132{
133 unsigned long flags;
David Herrmann492ba952011-11-17 14:12:03 +0100134 __u8 wmem;
135 int ret;
136
137 if (motionp) {
138 if (wiimote_cmd_acquire(ext->wdata))
139 return;
140
141 if (ext_type == WIIEXT_CLASSIC)
142 wmem = 0x07;
143 else if (ext_type == WIIEXT_NUNCHUCK)
144 wmem = 0x05;
145 else
146 wmem = 0x04;
147
148 ret = wiimote_cmd_write(ext->wdata, 0xa600fe, &wmem, sizeof(wmem));
149 wiimote_cmd_release(ext->wdata);
150 if (ret)
151 return;
152 }
David Herrmann82fb1b32011-11-17 14:12:02 +0100153
154 spin_lock_irqsave(&ext->wdata->state.lock, flags);
155 ext->motionp = motionp;
156 ext->ext_type = ext_type;
David Herrmann492ba952011-11-17 14:12:03 +0100157 wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
David Herrmann82fb1b32011-11-17 14:12:02 +0100158 spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
159}
160
David Herrmanncb992212011-11-17 14:12:01 +0100161static void wiiext_worker(struct work_struct *work)
162{
163 struct wiimote_ext *ext = container_of(work, struct wiimote_ext,
164 worker);
David Herrmann82fb1b32011-11-17 14:12:02 +0100165 bool motionp;
166 __u8 ext_type;
167
168 ext_disable(ext);
169 motionp = motionp_read(ext);
170 ext_type = ext_read(ext);
171 ext_enable(ext, motionp, ext_type);
David Herrmanncb992212011-11-17 14:12:01 +0100172}
173
174/* schedule work only once, otherwise mark for reschedule */
175static void wiiext_schedule(struct wiimote_ext *ext)
176{
177 queue_work(system_nrt_wq, &ext->worker);
178}
179
180/*
181 * Reacts on extension port events
182 * Whenever the driver gets an event from the wiimote that an extension has been
183 * plugged or unplugged, this funtion shall be called. It checks what extensions
184 * are connected and initializes and activates them.
185 * This can be called in atomic context. The initialization is done in a
186 * separate worker thread. The state.lock spinlock must be held by the caller.
187 */
188void wiiext_event(struct wiimote_data *wdata, bool plugged)
189{
190 if (!wdata->ext)
191 return;
192
193 if (wdata->ext->plugged == plugged)
194 return;
195
196 wdata->ext->plugged = plugged;
David Herrmannb17b57a2011-11-17 14:12:07 +0100197
198 if (!plugged)
199 wdata->ext->mp_plugged = false;
200
David Herrmanncb992212011-11-17 14:12:01 +0100201 /*
202 * We need to call wiiext_schedule(wdata->ext) here, however, the
203 * extension initialization logic is not fully understood and so
204 * automatic initialization is not supported, yet.
205 */
206}
207
208/*
209 * Returns true if the current DRM mode should contain extension data and false
210 * if there is no interest in extension data.
211 * All supported extensions send 6 byte extension data so any DRM that contains
212 * extension bytes is fine.
213 * The caller must hold the state.lock spinlock.
214 */
215bool wiiext_active(struct wiimote_data *wdata)
216{
217 if (!wdata->ext)
218 return false;
219
220 return wdata->ext->motionp || wdata->ext->ext_type;
221}
222
David Herrmann0b6815d2011-11-17 14:12:06 +0100223static void handler_motionp(struct wiimote_ext *ext, const __u8 *payload)
224{
David Herrmannb17b57a2011-11-17 14:12:07 +0100225 __s32 x, y, z;
226 bool plugged;
227
228 /* | 8 7 6 5 4 3 | 2 | 1 |
229 * -----+------------------------------+-----+-----+
230 * 1 | Yaw Speed <7:0> |
231 * 2 | Roll Speed <7:0> |
232 * 3 | Pitch Speed <7:0> |
233 * -----+------------------------------+-----+-----+
234 * 4 | Yaw Speed <13:8> | Yaw |Pitch|
235 * -----+------------------------------+-----+-----+
236 * 5 | Roll Speed <13:8> |Roll | Ext |
237 * -----+------------------------------+-----+-----+
238 * 6 | Pitch Speed <13:8> | 1 | 0 |
239 * -----+------------------------------+-----+-----+
240 * The single bits Yaw, Roll, Pitch in the lower right corner specify
241 * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
242 * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
243 * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
244 * and 9 for slow.
245 * If the wiimote is not rotating the sensor reports 2^13 = 8192.
246 * Ext specifies whether an extension is connected to the motionp.
247 */
248
249 x = payload[0];
250 y = payload[1];
251 z = payload[2];
252
253 x |= (((__u16)payload[3]) << 6) & 0xff00;
254 y |= (((__u16)payload[4]) << 6) & 0xff00;
255 z |= (((__u16)payload[5]) << 6) & 0xff00;
256
257 x -= 8192;
258 y -= 8192;
259 z -= 8192;
260
261 if (!(payload[3] & 0x02))
262 x *= 18;
263 else
264 x *= 9;
265 if (!(payload[4] & 0x02))
266 y *= 18;
267 else
268 y *= 9;
269 if (!(payload[3] & 0x01))
270 z *= 18;
271 else
272 z *= 9;
273
274 input_report_abs(ext->mp_input, ABS_RX, x);
275 input_report_abs(ext->mp_input, ABS_RY, y);
276 input_report_abs(ext->mp_input, ABS_RZ, z);
277 input_sync(ext->mp_input);
278
279 plugged = payload[5] & 0x01;
280 if (plugged != ext->mp_plugged)
281 ext->mp_plugged = plugged;
David Herrmann0b6815d2011-11-17 14:12:06 +0100282}
283
284static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload)
285{
David Herrmanna5353502011-11-17 14:12:08 +0100286 __s16 x, y, z, bx, by;
287
288 /* Byte | 8 7 | 6 5 | 4 3 | 2 | 1 |
289 * -----+----------+---------+---------+----+-----+
290 * 1 | Button X <7:0> |
291 * 2 | Button Y <7:0> |
292 * -----+----------+---------+---------+----+-----+
293 * 3 | Speed X <9:2> |
294 * 4 | Speed Y <9:2> |
295 * 5 | Speed Z <9:2> |
296 * -----+----------+---------+---------+----+-----+
297 * 6 | Z <1:0> | Y <1:0> | X <1:0> | BC | BZ |
298 * -----+----------+---------+---------+----+-----+
299 * Button X/Y is the analog stick. Speed X, Y and Z are the
300 * accelerometer data in the same format as the wiimote's accelerometer.
301 * The 6th byte contains the LSBs of the accelerometer data.
302 * BC and BZ are the C and Z buttons: 0 means pressed
303 *
304 * If reported interleaved with motionp, then the layout changes. The
305 * 5th and 6th byte changes to:
306 * -----+-----------------------------------+-----+
307 * 5 | Speed Z <9:3> | EXT |
308 * -----+--------+-----+-----+----+----+----+-----+
309 * 6 |Z <2:1> |Y <1>|X <1>| BC | BZ | 0 | 0 |
310 * -----+--------+-----+-----+----+----+----+-----+
311 * All three accelerometer values lose their LSB. The other data is
312 * still available but slightly moved.
313 *
314 * Center data for button values is 128. Center value for accelerometer
315 * values it 512 / 0x200
316 */
317
318 bx = payload[0];
319 by = payload[1];
320 bx -= 128;
321 by -= 128;
322
323 x = payload[2] << 2;
324 y = payload[3] << 2;
325 z = payload[4] << 2;
326
327 if (ext->motionp) {
328 x |= (payload[5] >> 3) & 0x02;
329 y |= (payload[5] >> 4) & 0x02;
330 z &= ~0x4;
331 z |= (payload[5] >> 5) & 0x06;
332 } else {
333 x |= (payload[5] >> 2) & 0x03;
334 y |= (payload[5] >> 4) & 0x03;
335 z |= (payload[5] >> 6) & 0x03;
336 }
337
338 x -= 0x200;
339 y -= 0x200;
340 z -= 0x200;
341
342 input_report_abs(ext->input, ABS_HAT0X, bx);
343 input_report_abs(ext->input, ABS_HAT0Y, by);
344
345 input_report_abs(ext->input, ABS_RX, x);
346 input_report_abs(ext->input, ABS_RY, y);
347 input_report_abs(ext->input, ABS_RZ, z);
348
349 if (ext->motionp) {
350 input_report_key(ext->input,
351 wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x04));
352 input_report_key(ext->input,
353 wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x08));
354 } else {
355 input_report_key(ext->input,
356 wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x01));
357 input_report_key(ext->input,
358 wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x02));
359 }
360
361 input_sync(ext->input);
David Herrmann0b6815d2011-11-17 14:12:06 +0100362}
363
364static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
365{
366}
367
368/* call this with state.lock spinlock held */
369void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
370{
371 struct wiimote_ext *ext = wdata->ext;
372
373 if (!ext)
374 return;
375
376 if (ext->motionp && (payload[5] & 0x02)) {
377 handler_motionp(ext, payload);
378 } else if (ext->ext_type == WIIEXT_NUNCHUCK) {
379 handler_nunchuck(ext, payload);
380 } else if (ext->ext_type == WIIEXT_CLASSIC) {
381 handler_classic(ext, payload);
382 }
383}
384
David Herrmannc1e51392011-11-17 14:12:04 +0100385static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
386 char *buf)
387{
388 struct wiimote_data *wdata = dev_to_wii(dev);
389 __u8 type = WIIEXT_NONE;
390 bool motionp = false;
391 unsigned long flags;
392
393 spin_lock_irqsave(&wdata->state.lock, flags);
394 if (wdata->ext) {
395 motionp = wdata->ext->motionp;
396 type = wdata->ext->ext_type;
397 }
398 spin_unlock_irqrestore(&wdata->state.lock, flags);
399
400 if (type == WIIEXT_NUNCHUCK) {
401 if (motionp)
402 return sprintf(buf, "motionp+nunchuck\n");
403 else
404 return sprintf(buf, "nunchuck\n");
405 } else if (type == WIIEXT_CLASSIC) {
406 if (motionp)
407 return sprintf(buf, "motionp+classic\n");
408 else
409 return sprintf(buf, "classic\n");
410 } else {
411 if (motionp)
412 return sprintf(buf, "motionp\n");
413 else
414 return sprintf(buf, "none\n");
415 }
416}
417
418static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL);
419
David Herrmann479901b2011-11-17 14:12:05 +0100420static int wiiext_input_open(struct input_dev *dev)
421{
422 struct wiimote_ext *ext = input_get_drvdata(dev);
423 int ret;
424
425 ret = hid_hw_open(ext->wdata->hdev);
426 if (ret)
427 return ret;
428
429 atomic_inc(&ext->opened);
430 wiiext_schedule(ext);
431
432 return 0;
433}
434
435static void wiiext_input_close(struct input_dev *dev)
436{
437 struct wiimote_ext *ext = input_get_drvdata(dev);
438
439 atomic_dec(&ext->opened);
440 wiiext_schedule(ext);
441 hid_hw_close(ext->wdata->hdev);
442}
443
444static int wiiext_mp_open(struct input_dev *dev)
445{
446 struct wiimote_ext *ext = input_get_drvdata(dev);
447 int ret;
448
449 ret = hid_hw_open(ext->wdata->hdev);
450 if (ret)
451 return ret;
452
453 atomic_inc(&ext->mp_opened);
454 wiiext_schedule(ext);
455
456 return 0;
457}
458
459static void wiiext_mp_close(struct input_dev *dev)
460{
461 struct wiimote_ext *ext = input_get_drvdata(dev);
462
463 atomic_dec(&ext->mp_opened);
464 wiiext_schedule(ext);
465 hid_hw_close(ext->wdata->hdev);
466}
467
David Herrmanncb992212011-11-17 14:12:01 +0100468/* Initializes the extension driver of a wiimote */
469int wiiext_init(struct wiimote_data *wdata)
470{
471 struct wiimote_ext *ext;
472 unsigned long flags;
David Herrmanna5353502011-11-17 14:12:08 +0100473 int ret, i;
David Herrmanncb992212011-11-17 14:12:01 +0100474
475 ext = kzalloc(sizeof(*ext), GFP_KERNEL);
476 if (!ext)
477 return -ENOMEM;
478
479 ext->wdata = wdata;
480 INIT_WORK(&ext->worker, wiiext_worker);
481
David Herrmann479901b2011-11-17 14:12:05 +0100482 ext->input = input_allocate_device();
483 if (!ext->input) {
484 ret = -ENOMEM;
485 goto err_input;
486 }
487
488 input_set_drvdata(ext->input, ext);
489 ext->input->open = wiiext_input_open;
490 ext->input->close = wiiext_input_close;
491 ext->input->dev.parent = &wdata->hdev->dev;
492 ext->input->id.bustype = wdata->hdev->bus;
493 ext->input->id.vendor = wdata->hdev->vendor;
494 ext->input->id.product = wdata->hdev->product;
495 ext->input->id.version = wdata->hdev->version;
496 ext->input->name = WIIMOTE_NAME " Extension";
497
David Herrmanna5353502011-11-17 14:12:08 +0100498 set_bit(EV_KEY, ext->input->evbit);
499 for (i = 0; i < WIIEXT_KEY_COUNT; ++i)
500 set_bit(wiiext_keymap[i], ext->input->keybit);
501
502 set_bit(EV_ABS, ext->input->evbit);
503 set_bit(ABS_HAT0X, ext->input->absbit);
504 set_bit(ABS_HAT0Y, ext->input->absbit);
505 input_set_abs_params(ext->input, ABS_HAT0X, -120, 120, 2, 4);
506 input_set_abs_params(ext->input, ABS_HAT0Y, -120, 120, 2, 4);
507 set_bit(ABS_RX, ext->input->absbit);
508 set_bit(ABS_RY, ext->input->absbit);
509 set_bit(ABS_RZ, ext->input->absbit);
510 input_set_abs_params(ext->input, ABS_RX, -500, 500, 2, 4);
511 input_set_abs_params(ext->input, ABS_RY, -500, 500, 2, 4);
512 input_set_abs_params(ext->input, ABS_RZ, -500, 500, 2, 4);
513
David Herrmann479901b2011-11-17 14:12:05 +0100514 ret = input_register_device(ext->input);
515 if (ret) {
516 input_free_device(ext->input);
517 goto err_input;
518 }
519
520 ext->mp_input = input_allocate_device();
521 if (!ext->mp_input) {
522 ret = -ENOMEM;
523 goto err_mp;
524 }
525
526 input_set_drvdata(ext->mp_input, ext);
527 ext->mp_input->open = wiiext_mp_open;
528 ext->mp_input->close = wiiext_mp_close;
529 ext->mp_input->dev.parent = &wdata->hdev->dev;
530 ext->mp_input->id.bustype = wdata->hdev->bus;
531 ext->mp_input->id.vendor = wdata->hdev->vendor;
532 ext->mp_input->id.product = wdata->hdev->product;
533 ext->mp_input->id.version = wdata->hdev->version;
534 ext->mp_input->name = WIIMOTE_NAME " Motion+";
535
David Herrmannb17b57a2011-11-17 14:12:07 +0100536 set_bit(EV_ABS, ext->mp_input->evbit);
537 set_bit(ABS_RX, ext->mp_input->absbit);
538 set_bit(ABS_RY, ext->mp_input->absbit);
539 set_bit(ABS_RZ, ext->mp_input->absbit);
540 input_set_abs_params(ext->mp_input, ABS_RX, -160000, 160000, 4, 8);
541 input_set_abs_params(ext->mp_input, ABS_RY, -160000, 160000, 4, 8);
542 input_set_abs_params(ext->mp_input, ABS_RZ, -160000, 160000, 4, 8);
543
David Herrmann479901b2011-11-17 14:12:05 +0100544 ret = input_register_device(ext->mp_input);
545 if (ret) {
546 input_free_device(ext->mp_input);
547 goto err_mp;
548 }
549
David Herrmannc1e51392011-11-17 14:12:04 +0100550 ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension);
551 if (ret)
David Herrmann479901b2011-11-17 14:12:05 +0100552 goto err_dev;
David Herrmannc1e51392011-11-17 14:12:04 +0100553
David Herrmanncb992212011-11-17 14:12:01 +0100554 spin_lock_irqsave(&wdata->state.lock, flags);
555 wdata->ext = ext;
556 spin_unlock_irqrestore(&wdata->state.lock, flags);
557
558 return 0;
David Herrmannc1e51392011-11-17 14:12:04 +0100559
David Herrmann479901b2011-11-17 14:12:05 +0100560err_dev:
561 input_unregister_device(ext->mp_input);
562err_mp:
563 input_unregister_device(ext->input);
564err_input:
David Herrmannc1e51392011-11-17 14:12:04 +0100565 kfree(ext);
566 return ret;
David Herrmanncb992212011-11-17 14:12:01 +0100567}
568
569/* Deinitializes the extension driver of a wiimote */
570void wiiext_deinit(struct wiimote_data *wdata)
571{
572 struct wiimote_ext *ext = wdata->ext;
573 unsigned long flags;
574
575 if (!ext)
576 return;
577
578 /*
579 * We first unset wdata->ext to avoid further input from the wiimote
580 * core. The worker thread does not access this pointer so it is not
581 * affected by this.
582 * We kill the worker after this so it does not get respawned during
583 * deinitialization.
584 */
585
586 spin_lock_irqsave(&wdata->state.lock, flags);
587 wdata->ext = NULL;
588 spin_unlock_irqrestore(&wdata->state.lock, flags);
589
David Herrmannc1e51392011-11-17 14:12:04 +0100590 device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
David Herrmann479901b2011-11-17 14:12:05 +0100591 input_unregister_device(ext->mp_input);
592 input_unregister_device(ext->input);
David Herrmannc1e51392011-11-17 14:12:04 +0100593
David Herrmanncb992212011-11-17 14:12:01 +0100594 cancel_work_sync(&ext->worker);
595 kfree(ext);
596}