aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/dib0700_devices.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb/dib0700_devices.c')
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c160
1 files changed, 11 insertions, 149 deletions
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 44972d01bbd..34eab05afc6 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -472,20 +472,25 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
472 472
473/* Number of keypresses to ignore before start repeating */ 473/* Number of keypresses to ignore before start repeating */
474#define RC_REPEAT_DELAY 6 474#define RC_REPEAT_DELAY 6
475#define RC_REPEAT_DELAY_V1_20 10
476 475
477 476static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
478
479/* Used by firmware versions < 1.20 (deprecated) */
480static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
481 int *state)
482{ 477{
483 u8 key[4]; 478 u8 key[4];
484 int i; 479 int i;
485 struct dvb_usb_rc_key *keymap = d->props.rc_key_map; 480 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
486 struct dib0700_state *st = d->priv; 481 struct dib0700_state *st = d->priv;
482
487 *event = 0; 483 *event = 0;
488 *state = REMOTE_NO_KEY_PRESSED; 484 *state = REMOTE_NO_KEY_PRESSED;
485
486 if (st->fw_version >= 0x10200) {
487 /* For 1.20 firmware , We need to keep the RC polling
488 callback so we can reuse the input device setup in
489 dvb-usb-remote.c. However, the actual work is being done
490 in the bulk URB completion handler. */
491 return 0;
492 }
493
489 i=dib0700_ctrl_rd(d,rc_request,2,key,4); 494 i=dib0700_ctrl_rd(d,rc_request,2,key,4);
490 if (i<=0) { 495 if (i<=0) {
491 err("RC Query Failed"); 496 err("RC Query Failed");
@@ -557,149 +562,6 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
557 return 0; 562 return 0;
558} 563}
559 564
560/* This is the structure of the RC response packet starting in firmware 1.20 */
561struct dib0700_rc_response {
562 u8 report_id;
563 u8 data_state;
564 u16 system;
565 u8 data;
566 u8 not_data;
567};
568
569/* This supports the new IR response format for firmware v1.20 */
570static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
571 int *state)
572{
573 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
574 struct dib0700_state *st = d->priv;
575 struct dib0700_rc_response poll_reply;
576 u8 buf[6];
577 int i;
578 int status;
579 int actlen;
580 int found = 0;
581
582 /* Set initial results in case we exit the function early */
583 *event = 0;
584 *state = REMOTE_NO_KEY_PRESSED;
585
586 /* Firmware v1.20 provides RC data via bulk endpoint 1 */
587 status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
588 sizeof(buf), &actlen, 50);
589 if (status < 0) {
590 /* No data available (meaning no key press) */
591 return 0;
592 }
593
594
595 switch (dvb_usb_dib0700_ir_proto) {
596 case 0:
597 poll_reply.report_id = 0;
598 poll_reply.data_state = 1;
599 poll_reply.system = buf[2];
600 poll_reply.data = buf[4];
601 poll_reply.not_data = buf[5];
602
603 /* NEC protocol sends repeat code as 0 0 0 FF */
604 if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
605 && (poll_reply.not_data == 0xff)) {
606 poll_reply.data_state = 2;
607 break;
608 }
609 break;
610 default:
611 if (actlen != sizeof(buf)) {
612 /* We didn't get back the 6 byte message we expected */
613 err("Unexpected RC response size [%d]", actlen);
614 return -1;
615 }
616
617 poll_reply.report_id = buf[0];
618 poll_reply.data_state = buf[1];
619 poll_reply.system = (buf[2] << 8) | buf[3];
620 poll_reply.data = buf[4];
621 poll_reply.not_data = buf[5];
622
623 break;
624 }
625
626 if ((poll_reply.data + poll_reply.not_data) != 0xff) {
627 /* Key failed integrity check */
628 err("key failed integrity check: %04x %02x %02x",
629 poll_reply.system,
630 poll_reply.data, poll_reply.not_data);
631 return -1;
632 }
633
634
635 /* Find the key in the map */
636 for (i = 0; i < d->props.rc_key_map_size; i++) {
637 if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
638 rc5_data(&keymap[i]) == poll_reply.data) {
639 *event = keymap[i].event;
640 found = 1;
641 break;
642 }
643 }
644
645 if (found == 0) {
646 err("Unknown remote controller key: %04x %02x %02x",
647 poll_reply.system,
648 poll_reply.data, poll_reply.not_data);
649 d->last_event = 0;
650 return 0;
651 }
652
653 if (poll_reply.data_state == 1) {
654 /* New key hit */
655 st->rc_counter = 0;
656 *event = keymap[i].event;
657 *state = REMOTE_KEY_PRESSED;
658 d->last_event = keymap[i].event;
659 } else if (poll_reply.data_state == 2) {
660 /* Key repeated */
661 st->rc_counter++;
662
663 /* prevents unwanted double hits */
664 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
665 *event = d->last_event;
666 *state = REMOTE_KEY_PRESSED;
667 st->rc_counter = RC_REPEAT_DELAY_V1_20;
668 }
669 } else {
670 err("Unknown data state [%d]", poll_reply.data_state);
671 }
672
673 return 0;
674}
675
676static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
677{
678 struct dib0700_state *st = d->priv;
679
680 /* Because some people may have improperly named firmware files,
681 let's figure out whether to use the new firmware call or the legacy
682 call based on the firmware version embedded in the file */
683 if (st->rc_func_version == 0) {
684 u32 hwver, romver, ramver, fwtype;
685 int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
686 &fwtype);
687 if (ret < 0) {
688 err("Could not determine version info");
689 return -1;
690 }
691 if (ramver < 0x10200)
692 st->rc_func_version = 1;
693 else
694 st->rc_func_version = 2;
695 }
696
697 if (st->rc_func_version == 2)
698 return dib0700_rc_query_v1_20(d, event, state);
699 else
700 return dib0700_rc_query_legacy(d, event, state);
701}
702
703static struct dvb_usb_rc_key dib0700_rc_keys[] = { 565static struct dvb_usb_rc_key dib0700_rc_keys[] = {
704 /* Key codes for the tiny Pinnacle remote*/ 566 /* Key codes for the tiny Pinnacle remote*/
705 { 0x0700, KEY_MUTE }, 567 { 0x0700, KEY_MUTE },