2 * HID driver for Nintendo Wiimote extension devices
3 * Copyright (c) 2011 David Herrmann
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)
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"
20 struct wiimote_data
*wdata
;
21 struct work_struct worker
;
22 struct input_dev
*input
;
23 struct input_dev
*mp_input
;
34 WIIEXT_NONE
, /* placeholder */
35 WIIEXT_CLASSIC
, /* Nintendo classic controller */
36 WIIEXT_NUNCHUCK
, /* Nintendo nunchuck controller */
60 static __u16 wiiext_keymap
[] = {
61 BTN_C
, /* WIIEXT_KEY_C */
62 BTN_Z
, /* WIIEXT_KEY_Z */
63 BTN_A
, /* WIIEXT_KEY_A */
64 BTN_B
, /* WIIEXT_KEY_B */
65 BTN_X
, /* WIIEXT_KEY_X */
66 BTN_Y
, /* WIIEXT_KEY_Y */
67 BTN_TL2
, /* WIIEXT_KEY_ZL */
68 BTN_TR2
, /* WIIEXT_KEY_ZR */
69 KEY_NEXT
, /* WIIEXT_KEY_PLUS */
70 KEY_PREVIOUS
, /* WIIEXT_KEY_MINUS */
71 BTN_MODE
, /* WIIEXT_KEY_HOME */
72 KEY_LEFT
, /* WIIEXT_KEY_LEFT */
73 KEY_RIGHT
, /* WIIEXT_KEY_RIGHT */
74 KEY_UP
, /* WIIEXT_KEY_UP */
75 KEY_DOWN
, /* WIIEXT_KEY_DOWN */
76 BTN_TL
, /* WIIEXT_KEY_LT */
77 BTN_TR
, /* WIIEXT_KEY_RT */
80 /* diable all extensions */
81 static void ext_disable(struct wiimote_ext
*ext
)
86 if (!wiimote_cmd_acquire(ext
->wdata
)) {
87 wiimote_cmd_write(ext
->wdata
, 0xa400f0, &wmem
, sizeof(wmem
));
88 wiimote_cmd_release(ext
->wdata
);
91 spin_lock_irqsave(&ext
->wdata
->state
.lock
, flags
);
93 ext
->ext_type
= WIIEXT_NONE
;
94 wiiproto_req_drm(ext
->wdata
, WIIPROTO_REQ_NULL
);
95 spin_unlock_irqrestore(&ext
->wdata
->state
.lock
, flags
);
98 static bool motionp_read(struct wiimote_ext
*ext
)
104 if (!atomic_read(&ext
->mp_opened
))
107 if (wiimote_cmd_acquire(ext
->wdata
))
110 /* initialize motion plus */
112 ret
= wiimote_cmd_write(ext
->wdata
, 0xa600f0, &wmem
, sizeof(wmem
));
116 /* read motion plus ID */
117 ret
= wiimote_cmd_read(ext
->wdata
, 0xa600fe, rmem
, 2);
118 if (ret
== 2 || rmem
[1] == 0x5)
122 wiimote_cmd_release(ext
->wdata
);
126 static __u8
ext_read(struct wiimote_ext
*ext
)
130 __u8 type
= WIIEXT_NONE
;
132 if (!ext
->plugged
|| !atomic_read(&ext
->opened
))
135 if (wiimote_cmd_acquire(ext
->wdata
))
138 /* initialize extension */
140 ret
= wiimote_cmd_write(ext
->wdata
, 0xa400f0, &wmem
, sizeof(wmem
));
142 /* disable encryption */
144 wiimote_cmd_write(ext
->wdata
, 0xa400fb, &wmem
, sizeof(wmem
));
147 /* read extension ID */
148 ret
= wiimote_cmd_read(ext
->wdata
, 0xa400fe, rmem
, 2);
150 if (rmem
[0] == 0 && rmem
[1] == 0)
151 type
= WIIEXT_NUNCHUCK
;
152 else if (rmem
[0] == 0x01 && rmem
[1] == 0x01)
153 type
= WIIEXT_CLASSIC
;
156 wiimote_cmd_release(ext
->wdata
);
161 static void ext_enable(struct wiimote_ext
*ext
, bool motionp
, __u8 ext_type
)
168 if (wiimote_cmd_acquire(ext
->wdata
))
171 if (ext_type
== WIIEXT_CLASSIC
)
173 else if (ext_type
== WIIEXT_NUNCHUCK
)
178 ret
= wiimote_cmd_write(ext
->wdata
, 0xa600fe, &wmem
, sizeof(wmem
));
179 wiimote_cmd_release(ext
->wdata
);
184 spin_lock_irqsave(&ext
->wdata
->state
.lock
, flags
);
185 ext
->motionp
= motionp
;
186 ext
->ext_type
= ext_type
;
187 wiiproto_req_drm(ext
->wdata
, WIIPROTO_REQ_NULL
);
188 spin_unlock_irqrestore(&ext
->wdata
->state
.lock
, flags
);
191 static void wiiext_worker(struct work_struct
*work
)
193 struct wiimote_ext
*ext
= container_of(work
, struct wiimote_ext
,
199 motionp
= motionp_read(ext
);
200 ext_type
= ext_read(ext
);
201 ext_enable(ext
, motionp
, ext_type
);
204 /* schedule work only once, otherwise mark for reschedule */
205 static void wiiext_schedule(struct wiimote_ext
*ext
)
207 queue_work(system_nrt_wq
, &ext
->worker
);
211 * Reacts on extension port events
212 * Whenever the driver gets an event from the wiimote that an extension has been
213 * plugged or unplugged, this funtion shall be called. It checks what extensions
214 * are connected and initializes and activates them.
215 * This can be called in atomic context. The initialization is done in a
216 * separate worker thread. The state.lock spinlock must be held by the caller.
218 void wiiext_event(struct wiimote_data
*wdata
, bool plugged
)
223 if (wdata
->ext
->plugged
== plugged
)
226 wdata
->ext
->plugged
= plugged
;
229 wdata
->ext
->mp_plugged
= false;
232 * We need to call wiiext_schedule(wdata->ext) here, however, the
233 * extension initialization logic is not fully understood and so
234 * automatic initialization is not supported, yet.
239 * Returns true if the current DRM mode should contain extension data and false
240 * if there is no interest in extension data.
241 * All supported extensions send 6 byte extension data so any DRM that contains
242 * extension bytes is fine.
243 * The caller must hold the state.lock spinlock.
245 bool wiiext_active(struct wiimote_data
*wdata
)
250 return wdata
->ext
->motionp
|| wdata
->ext
->ext_type
;
253 static void handler_motionp(struct wiimote_ext
*ext
, const __u8
*payload
)
258 /* | 8 7 6 5 4 3 | 2 | 1 |
259 * -----+------------------------------+-----+-----+
260 * 1 | Yaw Speed <7:0> |
261 * 2 | Roll Speed <7:0> |
262 * 3 | Pitch Speed <7:0> |
263 * -----+------------------------------+-----+-----+
264 * 4 | Yaw Speed <13:8> | Yaw |Pitch|
265 * -----+------------------------------+-----+-----+
266 * 5 | Roll Speed <13:8> |Roll | Ext |
267 * -----+------------------------------+-----+-----+
268 * 6 | Pitch Speed <13:8> | 1 | 0 |
269 * -----+------------------------------+-----+-----+
270 * The single bits Yaw, Roll, Pitch in the lower right corner specify
271 * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
272 * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
273 * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
275 * If the wiimote is not rotating the sensor reports 2^13 = 8192.
276 * Ext specifies whether an extension is connected to the motionp.
283 x
|= (((__u16
)payload
[3]) << 6) & 0xff00;
284 y
|= (((__u16
)payload
[4]) << 6) & 0xff00;
285 z
|= (((__u16
)payload
[5]) << 6) & 0xff00;
291 if (!(payload
[3] & 0x02))
295 if (!(payload
[4] & 0x02))
299 if (!(payload
[3] & 0x01))
304 input_report_abs(ext
->mp_input
, ABS_RX
, x
);
305 input_report_abs(ext
->mp_input
, ABS_RY
, y
);
306 input_report_abs(ext
->mp_input
, ABS_RZ
, z
);
307 input_sync(ext
->mp_input
);
309 plugged
= payload
[5] & 0x01;
310 if (plugged
!= ext
->mp_plugged
)
311 ext
->mp_plugged
= plugged
;
314 static void handler_nunchuck(struct wiimote_ext
*ext
, const __u8
*payload
)
316 __s16 x
, y
, z
, bx
, by
;
318 /* Byte | 8 7 | 6 5 | 4 3 | 2 | 1 |
319 * -----+----------+---------+---------+----+-----+
320 * 1 | Button X <7:0> |
321 * 2 | Button Y <7:0> |
322 * -----+----------+---------+---------+----+-----+
323 * 3 | Speed X <9:2> |
324 * 4 | Speed Y <9:2> |
325 * 5 | Speed Z <9:2> |
326 * -----+----------+---------+---------+----+-----+
327 * 6 | Z <1:0> | Y <1:0> | X <1:0> | BC | BZ |
328 * -----+----------+---------+---------+----+-----+
329 * Button X/Y is the analog stick. Speed X, Y and Z are the
330 * accelerometer data in the same format as the wiimote's accelerometer.
331 * The 6th byte contains the LSBs of the accelerometer data.
332 * BC and BZ are the C and Z buttons: 0 means pressed
334 * If reported interleaved with motionp, then the layout changes. The
335 * 5th and 6th byte changes to:
336 * -----+-----------------------------------+-----+
337 * 5 | Speed Z <9:3> | EXT |
338 * -----+--------+-----+-----+----+----+----+-----+
339 * 6 |Z <2:1> |Y <1>|X <1>| BC | BZ | 0 | 0 |
340 * -----+--------+-----+-----+----+----+----+-----+
341 * All three accelerometer values lose their LSB. The other data is
342 * still available but slightly moved.
344 * Center data for button values is 128. Center value for accelerometer
345 * values it 512 / 0x200
358 x
|= (payload
[5] >> 3) & 0x02;
359 y
|= (payload
[5] >> 4) & 0x02;
361 z
|= (payload
[5] >> 5) & 0x06;
363 x
|= (payload
[5] >> 2) & 0x03;
364 y
|= (payload
[5] >> 4) & 0x03;
365 z
|= (payload
[5] >> 6) & 0x03;
372 input_report_abs(ext
->input
, ABS_HAT0X
, bx
);
373 input_report_abs(ext
->input
, ABS_HAT0Y
, by
);
375 input_report_abs(ext
->input
, ABS_RX
, x
);
376 input_report_abs(ext
->input
, ABS_RY
, y
);
377 input_report_abs(ext
->input
, ABS_RZ
, z
);
380 input_report_key(ext
->input
,
381 wiiext_keymap
[WIIEXT_KEY_Z
], !!(payload
[5] & 0x04));
382 input_report_key(ext
->input
,
383 wiiext_keymap
[WIIEXT_KEY_C
], !!(payload
[5] & 0x08));
385 input_report_key(ext
->input
,
386 wiiext_keymap
[WIIEXT_KEY_Z
], !!(payload
[5] & 0x01));
387 input_report_key(ext
->input
,
388 wiiext_keymap
[WIIEXT_KEY_C
], !!(payload
[5] & 0x02));
391 input_sync(ext
->input
);
394 static void handler_classic(struct wiimote_ext
*ext
, const __u8
*payload
)
396 __s8 rx
, ry
, lx
, ly
, lt
, rt
;
398 /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
399 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
400 * 1 | RX <5:4> | LX <5:0> |
401 * 2 | RX <3:2> | LY <5:0> |
402 * -----+-----+-----+-----+-----------------------------+
403 * 3 |RX<1>| LT <5:4> | RY <5:1> |
404 * -----+-----+-----------+-----------------------------+
405 * 4 | LT <3:1> | RT <5:1> |
406 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
407 * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 |
408 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
409 * 6 | BZL | BB | BY | BA | BX | BZR | BDL | BDU |
410 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
411 * All buttons are 0 if pressed
412 * RX and RY are right analog stick
413 * LX and LY are left analog stick
414 * LT is left trigger, RT is right trigger
415 * BLT is 0 if left trigger is fully pressed
416 * BRT is 0 if right trigger is fully pressed
417 * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
418 * BZL is left Z button and BZR is right Z button
419 * B-, BH, B+ are +, HOME and - buttons
420 * BB, BY, BA, BX are A, B, X, Y buttons
421 * LSB of RX, RY, LT, and RT are not transmitted and always 0.
423 * With motionp enabled it changes slightly to this:
424 * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
425 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
426 * 1 | RX <4:3> | LX <5:1> | BDU |
427 * 2 | RX <2:1> | LY <5:1> | BDL |
428 * -----+-----+-----+-----+-----------------------+-----+
429 * 3 |RX<0>| LT <4:3> | RY <4:0> |
430 * -----+-----+-----------+-----------------------------+
431 * 4 | LT <2:0> | RT <4:0> |
432 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
433 * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | EXT |
434 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
435 * 6 | BZL | BB | BY | BA | BX | BZR | 0 | 0 |
436 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
437 * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest
438 * is the same as before.
442 lx
= payload
[0] & 0x3e;
443 ly
= payload
[0] & 0x3e;
445 lx
= payload
[0] & 0x3f;
446 ly
= payload
[0] & 0x3f;
449 rx
= (payload
[0] >> 3) & 0x14;
450 rx
|= (payload
[1] >> 5) & 0x06;
451 rx
|= (payload
[2] >> 7) & 0x01;
452 ry
= payload
[2] & 0x1f;
454 rt
= payload
[3] & 0x1f;
455 lt
= (payload
[2] >> 2) & 0x18;
456 lt
|= (payload
[3] >> 5) & 0x07;
463 input_report_abs(ext
->input
, ABS_HAT1X
, lx
- 0x20);
464 input_report_abs(ext
->input
, ABS_HAT1Y
, ly
- 0x20);
465 input_report_abs(ext
->input
, ABS_HAT2X
, rx
- 0x20);
466 input_report_abs(ext
->input
, ABS_HAT2Y
, ry
- 0x20);
467 input_report_abs(ext
->input
, ABS_HAT3X
, rt
- 0x20);
468 input_report_abs(ext
->input
, ABS_HAT3Y
, lt
- 0x20);
470 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_RIGHT
],
471 !!(payload
[4] & 0x80));
472 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_DOWN
],
473 !!(payload
[4] & 0x40));
474 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_LT
],
475 !!(payload
[4] & 0x20));
476 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_MINUS
],
477 !!(payload
[4] & 0x10));
478 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_HOME
],
479 !!(payload
[4] & 0x08));
480 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_PLUS
],
481 !!(payload
[4] & 0x04));
482 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_RT
],
483 !!(payload
[4] & 0x02));
484 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_ZL
],
485 !!(payload
[5] & 0x80));
486 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_B
],
487 !!(payload
[5] & 0x40));
488 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_Y
],
489 !!(payload
[5] & 0x20));
490 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_A
],
491 !!(payload
[5] & 0x10));
492 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_X
],
493 !!(payload
[5] & 0x08));
494 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_ZR
],
495 !!(payload
[5] & 0x04));
498 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_UP
],
499 !!(payload
[0] & 0x01));
500 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_LEFT
],
501 !!(payload
[1] & 0x01));
503 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_UP
],
504 !!(payload
[5] & 0x01));
505 input_report_key(ext
->input
, wiiext_keymap
[WIIEXT_KEY_LEFT
],
506 !!(payload
[5] & 0x02));
509 input_sync(ext
->input
);
512 /* call this with state.lock spinlock held */
513 void wiiext_handle(struct wiimote_data
*wdata
, const __u8
*payload
)
515 struct wiimote_ext
*ext
= wdata
->ext
;
520 if (ext
->motionp
&& (payload
[5] & 0x02)) {
521 handler_motionp(ext
, payload
);
522 } else if (ext
->ext_type
== WIIEXT_NUNCHUCK
) {
523 handler_nunchuck(ext
, payload
);
524 } else if (ext
->ext_type
== WIIEXT_CLASSIC
) {
525 handler_classic(ext
, payload
);
529 static ssize_t
wiiext_show(struct device
*dev
, struct device_attribute
*attr
,
532 struct wiimote_data
*wdata
= dev_to_wii(dev
);
533 __u8 type
= WIIEXT_NONE
;
534 bool motionp
= false;
537 spin_lock_irqsave(&wdata
->state
.lock
, flags
);
539 motionp
= wdata
->ext
->motionp
;
540 type
= wdata
->ext
->ext_type
;
542 spin_unlock_irqrestore(&wdata
->state
.lock
, flags
);
544 if (type
== WIIEXT_NUNCHUCK
) {
546 return sprintf(buf
, "motionp+nunchuck\n");
548 return sprintf(buf
, "nunchuck\n");
549 } else if (type
== WIIEXT_CLASSIC
) {
551 return sprintf(buf
, "motionp+classic\n");
553 return sprintf(buf
, "classic\n");
556 return sprintf(buf
, "motionp\n");
558 return sprintf(buf
, "none\n");
562 static DEVICE_ATTR(extension
, S_IRUGO
, wiiext_show
, NULL
);
564 static int wiiext_input_open(struct input_dev
*dev
)
566 struct wiimote_ext
*ext
= input_get_drvdata(dev
);
569 ret
= hid_hw_open(ext
->wdata
->hdev
);
573 atomic_inc(&ext
->opened
);
574 wiiext_schedule(ext
);
579 static void wiiext_input_close(struct input_dev
*dev
)
581 struct wiimote_ext
*ext
= input_get_drvdata(dev
);
583 atomic_dec(&ext
->opened
);
584 wiiext_schedule(ext
);
585 hid_hw_close(ext
->wdata
->hdev
);
588 static int wiiext_mp_open(struct input_dev
*dev
)
590 struct wiimote_ext
*ext
= input_get_drvdata(dev
);
593 ret
= hid_hw_open(ext
->wdata
->hdev
);
597 atomic_inc(&ext
->mp_opened
);
598 wiiext_schedule(ext
);
603 static void wiiext_mp_close(struct input_dev
*dev
)
605 struct wiimote_ext
*ext
= input_get_drvdata(dev
);
607 atomic_dec(&ext
->mp_opened
);
608 wiiext_schedule(ext
);
609 hid_hw_close(ext
->wdata
->hdev
);
612 /* Initializes the extension driver of a wiimote */
613 int wiiext_init(struct wiimote_data
*wdata
)
615 struct wiimote_ext
*ext
;
619 ext
= kzalloc(sizeof(*ext
), GFP_KERNEL
);
624 INIT_WORK(&ext
->worker
, wiiext_worker
);
626 ext
->input
= input_allocate_device();
632 input_set_drvdata(ext
->input
, ext
);
633 ext
->input
->open
= wiiext_input_open
;
634 ext
->input
->close
= wiiext_input_close
;
635 ext
->input
->dev
.parent
= &wdata
->hdev
->dev
;
636 ext
->input
->id
.bustype
= wdata
->hdev
->bus
;
637 ext
->input
->id
.vendor
= wdata
->hdev
->vendor
;
638 ext
->input
->id
.product
= wdata
->hdev
->product
;
639 ext
->input
->id
.version
= wdata
->hdev
->version
;
640 ext
->input
->name
= WIIMOTE_NAME
" Extension";
642 set_bit(EV_KEY
, ext
->input
->evbit
);
643 for (i
= 0; i
< WIIEXT_KEY_COUNT
; ++i
)
644 set_bit(wiiext_keymap
[i
], ext
->input
->keybit
);
646 set_bit(EV_ABS
, ext
->input
->evbit
);
647 set_bit(ABS_HAT0X
, ext
->input
->absbit
);
648 set_bit(ABS_HAT0Y
, ext
->input
->absbit
);
649 set_bit(ABS_HAT1X
, ext
->input
->absbit
);
650 set_bit(ABS_HAT1Y
, ext
->input
->absbit
);
651 set_bit(ABS_HAT2X
, ext
->input
->absbit
);
652 set_bit(ABS_HAT2Y
, ext
->input
->absbit
);
653 set_bit(ABS_HAT3X
, ext
->input
->absbit
);
654 set_bit(ABS_HAT3Y
, ext
->input
->absbit
);
655 input_set_abs_params(ext
->input
, ABS_HAT0X
, -120, 120, 2, 4);
656 input_set_abs_params(ext
->input
, ABS_HAT0Y
, -120, 120, 2, 4);
657 input_set_abs_params(ext
->input
, ABS_HAT1X
, -30, 30, 1, 1);
658 input_set_abs_params(ext
->input
, ABS_HAT1Y
, -30, 30, 1, 1);
659 input_set_abs_params(ext
->input
, ABS_HAT2X
, -30, 30, 1, 1);
660 input_set_abs_params(ext
->input
, ABS_HAT2Y
, -30, 30, 1, 1);
661 input_set_abs_params(ext
->input
, ABS_HAT3X
, -30, 30, 1, 1);
662 input_set_abs_params(ext
->input
, ABS_HAT3Y
, -30, 30, 1, 1);
663 set_bit(ABS_RX
, ext
->input
->absbit
);
664 set_bit(ABS_RY
, ext
->input
->absbit
);
665 set_bit(ABS_RZ
, ext
->input
->absbit
);
666 input_set_abs_params(ext
->input
, ABS_RX
, -500, 500, 2, 4);
667 input_set_abs_params(ext
->input
, ABS_RY
, -500, 500, 2, 4);
668 input_set_abs_params(ext
->input
, ABS_RZ
, -500, 500, 2, 4);
670 ret
= input_register_device(ext
->input
);
672 input_free_device(ext
->input
);
676 ext
->mp_input
= input_allocate_device();
677 if (!ext
->mp_input
) {
682 input_set_drvdata(ext
->mp_input
, ext
);
683 ext
->mp_input
->open
= wiiext_mp_open
;
684 ext
->mp_input
->close
= wiiext_mp_close
;
685 ext
->mp_input
->dev
.parent
= &wdata
->hdev
->dev
;
686 ext
->mp_input
->id
.bustype
= wdata
->hdev
->bus
;
687 ext
->mp_input
->id
.vendor
= wdata
->hdev
->vendor
;
688 ext
->mp_input
->id
.product
= wdata
->hdev
->product
;
689 ext
->mp_input
->id
.version
= wdata
->hdev
->version
;
690 ext
->mp_input
->name
= WIIMOTE_NAME
" Motion+";
692 set_bit(EV_ABS
, ext
->mp_input
->evbit
);
693 set_bit(ABS_RX
, ext
->mp_input
->absbit
);
694 set_bit(ABS_RY
, ext
->mp_input
->absbit
);
695 set_bit(ABS_RZ
, ext
->mp_input
->absbit
);
696 input_set_abs_params(ext
->mp_input
, ABS_RX
, -160000, 160000, 4, 8);
697 input_set_abs_params(ext
->mp_input
, ABS_RY
, -160000, 160000, 4, 8);
698 input_set_abs_params(ext
->mp_input
, ABS_RZ
, -160000, 160000, 4, 8);
700 ret
= input_register_device(ext
->mp_input
);
702 input_free_device(ext
->mp_input
);
706 ret
= device_create_file(&wdata
->hdev
->dev
, &dev_attr_extension
);
710 spin_lock_irqsave(&wdata
->state
.lock
, flags
);
712 spin_unlock_irqrestore(&wdata
->state
.lock
, flags
);
717 input_unregister_device(ext
->mp_input
);
719 input_unregister_device(ext
->input
);
725 /* Deinitializes the extension driver of a wiimote */
726 void wiiext_deinit(struct wiimote_data
*wdata
)
728 struct wiimote_ext
*ext
= wdata
->ext
;
735 * We first unset wdata->ext to avoid further input from the wiimote
736 * core. The worker thread does not access this pointer so it is not
738 * We kill the worker after this so it does not get respawned during
742 spin_lock_irqsave(&wdata
->state
.lock
, flags
);
744 spin_unlock_irqrestore(&wdata
->state
.lock
, flags
);
746 device_remove_file(&wdata
->hdev
->dev
, &dev_attr_extension
);
747 input_unregister_device(ext
->mp_input
);
748 input_unregister_device(ext
->input
);
750 cancel_work_sync(&ext
->worker
);