aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-wiimote-ext.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c
index f05f1549d943..aa958706c0e5 100644
--- a/drivers/hid/hid-wiimote-ext.c
+++ b/drivers/hid/hid-wiimote-ext.c
@@ -39,12 +39,42 @@ enum wiiext_type {
39enum wiiext_keys { 39enum wiiext_keys {
40 WIIEXT_KEY_C, 40 WIIEXT_KEY_C,
41 WIIEXT_KEY_Z, 41 WIIEXT_KEY_Z,
42 WIIEXT_KEY_A,
43 WIIEXT_KEY_B,
44 WIIEXT_KEY_X,
45 WIIEXT_KEY_Y,
46 WIIEXT_KEY_ZL,
47 WIIEXT_KEY_ZR,
48 WIIEXT_KEY_PLUS,
49 WIIEXT_KEY_MINUS,
50 WIIEXT_KEY_HOME,
51 WIIEXT_KEY_LEFT,
52 WIIEXT_KEY_RIGHT,
53 WIIEXT_KEY_UP,
54 WIIEXT_KEY_DOWN,
55 WIIEXT_KEY_LT,
56 WIIEXT_KEY_RT,
42 WIIEXT_KEY_COUNT 57 WIIEXT_KEY_COUNT
43}; 58};
44 59
45static __u16 wiiext_keymap[] = { 60static __u16 wiiext_keymap[] = {
46 BTN_C, /* WIIEXT_KEY_C */ 61 BTN_C, /* WIIEXT_KEY_C */
47 BTN_Z, /* WIIEXT_KEY_Z */ 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 */
48}; 78};
49 79
50/* diable all extensions */ 80/* diable all extensions */
@@ -363,6 +393,120 @@ static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload)
363 393
364static void handler_classic(struct wiimote_ext *ext, const __u8 *payload) 394static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
365{ 395{
396 __s8 rx, ry, lx, ly, lt, rt;
397
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.
422 *
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.
439 */
440
441 if (ext->motionp) {
442 lx = payload[0] & 0x3e;
443 ly = payload[0] & 0x3e;
444 } else {
445 lx = payload[0] & 0x3f;
446 ly = payload[0] & 0x3f;
447 }
448
449 rx = (payload[0] >> 3) & 0x14;
450 rx |= (payload[1] >> 5) & 0x06;
451 rx |= (payload[2] >> 7) & 0x01;
452 ry = payload[2] & 0x1f;
453
454 rt = payload[3] & 0x1f;
455 lt = (payload[2] >> 2) & 0x18;
456 lt |= (payload[3] >> 5) & 0x07;
457
458 rx <<= 1;
459 ry <<= 1;
460 rt <<= 1;
461 lt <<= 1;
462
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);
469
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));
496
497 if (ext->motionp) {
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));
502 } else {
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));
507 }
508
509 input_sync(ext->input);
366} 510}
367 511
368/* call this with state.lock spinlock held */ 512/* call this with state.lock spinlock held */
@@ -502,8 +646,20 @@ int wiiext_init(struct wiimote_data *wdata)
502 set_bit(EV_ABS, ext->input->evbit); 646 set_bit(EV_ABS, ext->input->evbit);
503 set_bit(ABS_HAT0X, ext->input->absbit); 647 set_bit(ABS_HAT0X, ext->input->absbit);
504 set_bit(ABS_HAT0Y, 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);
505 input_set_abs_params(ext->input, ABS_HAT0X, -120, 120, 2, 4); 655 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); 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);
507 set_bit(ABS_RX, ext->input->absbit); 663 set_bit(ABS_RX, ext->input->absbit);
508 set_bit(ABS_RY, ext->input->absbit); 664 set_bit(ABS_RY, ext->input->absbit);
509 set_bit(ABS_RZ, ext->input->absbit); 665 set_bit(ABS_RZ, ext->input->absbit);