aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-09-06 07:50:31 -0400
committerJiri Kosina <jkosina@suse.cz>2011-09-07 07:25:16 -0400
commiteac39e7eda47cec9de44d64661ef44c6b37dd45f (patch)
tree1f43a69259d276effc378f12e3e068308844e512 /drivers/hid
parentf363e4f6ab71168cbdaadeef974b515512b41636 (diff)
HID: wiimote: Parse IR data
Parse IR data and report it to IR input-device. IR data is sent in 3 different formats, but we only support the basic format as there is no way to send the additional information to userspace. All three formats are compatible with the basic IR data format so we need only one parser. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-wiimote.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index 4cdaaf6e0307..3a7dec0c9fe6 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -479,6 +479,50 @@ static void handler_accel(struct wiimote_data *wdata, const __u8 *payload)
479 input_sync(wdata->accel); 479 input_sync(wdata->accel);
480} 480}
481 481
482#define ir_to_input0(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
483 ABS_HAT0X, ABS_HAT0Y)
484#define ir_to_input1(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
485 ABS_HAT1X, ABS_HAT1Y)
486#define ir_to_input2(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
487 ABS_HAT2X, ABS_HAT2Y)
488#define ir_to_input3(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
489 ABS_HAT3X, ABS_HAT3Y)
490
491static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir,
492 bool packed, __u8 xid, __u8 yid)
493{
494 __u16 x, y;
495
496 if (!(wdata->state.flags & WIIPROTO_FLAGS_IR))
497 return;
498
499 /*
500 * Basic IR data is encoded into 3 bytes. The first two bytes are the
501 * upper 8 bit of the X/Y data, the 3rd byte contains the lower 2 bits
502 * of both.
503 * If data is packed, then the 3rd byte is put first and slightly
504 * reordered. This allows to interleave packed and non-packed data to
505 * have two IR sets in 5 bytes instead of 6.
506 * The resulting 10bit X/Y values are passed to the ABS_HATXY input dev.
507 */
508
509 if (packed) {
510 x = ir[1] << 2;
511 y = ir[2] << 2;
512
513 x |= ir[0] & 0x3;
514 y |= (ir[0] >> 2) & 0x3;
515 } else {
516 x = ir[0] << 2;
517 y = ir[1] << 2;
518
519 x |= (ir[2] >> 4) & 0x3;
520 y |= (ir[2] >> 6) & 0x3;
521 }
522
523 input_report_abs(wdata->ir, xid, x);
524 input_report_abs(wdata->ir, yid, y);
525}
482 526
483static void handler_status(struct wiimote_data *wdata, const __u8 *payload) 527static void handler_status(struct wiimote_data *wdata, const __u8 *payload)
484{ 528{
@@ -510,6 +554,21 @@ static void handler_drm_KAI(struct wiimote_data *wdata, const __u8 *payload)
510{ 554{
511 handler_keys(wdata, payload); 555 handler_keys(wdata, payload);
512 handler_accel(wdata, payload); 556 handler_accel(wdata, payload);
557 ir_to_input0(wdata, &payload[5], false);
558 ir_to_input1(wdata, &payload[8], false);
559 ir_to_input2(wdata, &payload[11], false);
560 ir_to_input3(wdata, &payload[14], false);
561 input_sync(wdata->ir);
562}
563
564static void handler_drm_KIE(struct wiimote_data *wdata, const __u8 *payload)
565{
566 handler_keys(wdata, payload);
567 ir_to_input0(wdata, &payload[2], false);
568 ir_to_input1(wdata, &payload[4], true);
569 ir_to_input2(wdata, &payload[7], false);
570 ir_to_input3(wdata, &payload[9], true);
571 input_sync(wdata->ir);
513} 572}
514 573
515static void handler_drm_KAE(struct wiimote_data *wdata, const __u8 *payload) 574static void handler_drm_KAE(struct wiimote_data *wdata, const __u8 *payload)
@@ -522,6 +581,11 @@ static void handler_drm_KAIE(struct wiimote_data *wdata, const __u8 *payload)
522{ 581{
523 handler_keys(wdata, payload); 582 handler_keys(wdata, payload);
524 handler_accel(wdata, payload); 583 handler_accel(wdata, payload);
584 ir_to_input0(wdata, &payload[5], false);
585 ir_to_input1(wdata, &payload[7], true);
586 ir_to_input2(wdata, &payload[10], false);
587 ir_to_input3(wdata, &payload[12], true);
588 input_sync(wdata->ir);
525} 589}
526 590
527static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload) 591static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload)
@@ -531,6 +595,10 @@ static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload)
531 wdata->state.accel_split[0] = payload[2]; 595 wdata->state.accel_split[0] = payload[2];
532 wdata->state.accel_split[1] = (payload[0] >> 1) & (0x10 | 0x20); 596 wdata->state.accel_split[1] = (payload[0] >> 1) & (0x10 | 0x20);
533 wdata->state.accel_split[1] |= (payload[1] << 1) & (0x40 | 0x80); 597 wdata->state.accel_split[1] |= (payload[1] << 1) & (0x40 | 0x80);
598
599 ir_to_input0(wdata, &payload[3], false);
600 ir_to_input1(wdata, &payload[12], false);
601 input_sync(wdata->ir);
534} 602}
535 603
536static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload) 604static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload)
@@ -548,6 +616,10 @@ static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload)
548 buf[3] = payload[2]; 616 buf[3] = payload[2];
549 buf[4] = wdata->state.accel_split[1]; 617 buf[4] = wdata->state.accel_split[1];
550 handler_accel(wdata, buf); 618 handler_accel(wdata, buf);
619
620 ir_to_input2(wdata, &payload[3], false);
621 ir_to_input3(wdata, &payload[12], false);
622 input_sync(wdata->ir);
551} 623}
552 624
553struct wiiproto_handler { 625struct wiiproto_handler {
@@ -563,6 +635,7 @@ static struct wiiproto_handler handlers[] = {
563 { .id = WIIPROTO_REQ_DRM_KA, .size = 5, .func = handler_drm_KA }, 635 { .id = WIIPROTO_REQ_DRM_KA, .size = 5, .func = handler_drm_KA },
564 { .id = WIIPROTO_REQ_DRM_KAI, .size = 17, .func = handler_drm_KAI }, 636 { .id = WIIPROTO_REQ_DRM_KAI, .size = 17, .func = handler_drm_KAI },
565 { .id = WIIPROTO_REQ_DRM_KAE, .size = 21, .func = handler_drm_KAE }, 637 { .id = WIIPROTO_REQ_DRM_KAE, .size = 21, .func = handler_drm_KAE },
638 { .id = WIIPROTO_REQ_DRM_KIE, .size = 21, .func = handler_drm_KIE },
566 { .id = WIIPROTO_REQ_DRM_KAIE, .size = 21, .func = handler_drm_KAIE }, 639 { .id = WIIPROTO_REQ_DRM_KAIE, .size = 21, .func = handler_drm_KAIE },
567 { .id = WIIPROTO_REQ_DRM_SKAI1, .size = 21, .func = handler_drm_SKAI1 }, 640 { .id = WIIPROTO_REQ_DRM_SKAI1, .size = 21, .func = handler_drm_SKAI1 },
568 { .id = WIIPROTO_REQ_DRM_SKAI2, .size = 21, .func = handler_drm_SKAI2 }, 641 { .id = WIIPROTO_REQ_DRM_SKAI2, .size = 21, .func = handler_drm_SKAI2 },