aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2010-01-04 00:43:19 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:32 -0500
commit6a2071006b72bf887e38c025c60f98d2998ceacb (patch)
tree4abae89a6dbaf42cb312317e521ba53a75245b76 /drivers/media/dvb/dvb-usb
parenteac8f5fa5f5dcaf228694fe23e19b02b98e68879 (diff)
V4L/DVB (13930): dib0700: rework IR logic for firmware 1.20
When firmware 1.20 was introduced, the dib0700 switched from a polling model using a USB control message, to the messages being delivered on a USB bulk pipe. The code I originally added would do a blocking read on the pipe with a 50ms timeout. Because the dvb-usb-remote code makes use of the global workqueue, this resulted in the global workqueue being blocked 50% of the time. Also, the synchronous urb_bulk_msg() call would burn excess CPU time (reflected as an abnormal increase in the system's load average when devices were connected). Rework the logic so that we now setup an asynchronous callback on the bulk pipe, so that we now only handle RC data when it arrives on the pipe. Note that we provide a stub function for the RC polling callback so that we can continue to leverage the shared code in dvb-usb-rc for the setting up of the input device. Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c196
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c160
3 files changed, 206 insertions, 151 deletions
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 495a90577c5f..83fc24a6c31a 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -42,7 +42,6 @@ struct dib0700_state {
42 u16 mt2060_if1[2]; 42 u16 mt2060_if1[2];
43 u8 rc_toggle; 43 u8 rc_toggle;
44 u8 rc_counter; 44 u8 rc_counter;
45 u8 rc_func_version;
46 u8 is_dib7000pc; 45 u8 is_dib7000pc;
47 u8 fw_use_new_i2c_api; 46 u8 fw_use_new_i2c_api;
48 u8 disable_streaming_master_mode; 47 u8 disable_streaming_master_mode;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 0d3c9a9a33be..4450214e2c64 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -471,14 +471,208 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
471 return dib0700_ctrl_wr(adap->dev, b, 4); 471 return dib0700_ctrl_wr(adap->dev, b, 4);
472} 472}
473 473
474/* Number of keypresses to ignore before start repeating */
475#define RC_REPEAT_DELAY_V1_20 10
476
477/* This is the structure of the RC response packet starting in firmware 1.20 */
478struct dib0700_rc_response {
479 u8 report_id;
480 u8 data_state;
481 u16 system;
482 u8 data;
483 u8 not_data;
484};
485#define RC_MSG_SIZE_V1_20 6
486
487static void dib0700_rc_urb_completion(struct urb *purb)
488{
489 struct dvb_usb_device *d = purb->context;
490 struct dvb_usb_rc_key *keymap;
491 struct dib0700_state *st;
492 struct dib0700_rc_response poll_reply;
493 u8 *buf;
494 int found = 0;
495 u32 event;
496 int state;
497 int i;
498
499 deb_info("%s()\n", __func__);
500 if (d == NULL)
501 return;
502
503 if (d->rc_input_dev == NULL) {
504 /* This will occur if disable_rc_polling=1 */
505 usb_free_urb(purb);
506 return;
507 }
508
509 keymap = d->props.rc_key_map;
510 st = d->priv;
511 buf = (u8 *)purb->transfer_buffer;
512
513 if (purb->status < 0) {
514 deb_info("discontinuing polling\n");
515 usb_free_urb(purb);
516 return;
517 }
518
519 if (purb->actual_length != RC_MSG_SIZE_V1_20) {
520 deb_info("malformed rc msg size=%d\n", purb->actual_length);
521 goto resubmit;
522 }
523
524 /* Set initial results in case we exit the function early */
525 event = 0;
526 state = REMOTE_NO_KEY_PRESSED;
527
528 deb_data("IR raw %02X %02X %02X %02X %02X %02X (len %d)\n", buf[0],
529 buf[1], buf[2], buf[3], buf[4], buf[5], purb->actual_length);
530
531 switch (dvb_usb_dib0700_ir_proto) {
532 case 0:
533 /* NEC Protocol */
534 poll_reply.report_id = 0;
535 poll_reply.data_state = 1;
536 poll_reply.system = buf[2];
537 poll_reply.data = buf[4];
538 poll_reply.not_data = buf[5];
539
540 /* NEC protocol sends repeat code as 0 0 0 FF */
541 if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
542 && (poll_reply.not_data == 0xff)) {
543 poll_reply.data_state = 2;
544 break;
545 }
546 break;
547 default:
548 /* RC5 Protocol */
549 poll_reply.report_id = buf[0];
550 poll_reply.data_state = buf[1];
551 poll_reply.system = (buf[2] << 8) | buf[3];
552 poll_reply.data = buf[4];
553 poll_reply.not_data = buf[5];
554 break;
555 }
556
557 if ((poll_reply.data + poll_reply.not_data) != 0xff) {
558 /* Key failed integrity check */
559 err("key failed integrity check: %04x %02x %02x",
560 poll_reply.system,
561 poll_reply.data, poll_reply.not_data);
562 goto resubmit;
563 }
564
565 deb_data("rid=%02x ds=%02x sm=%04x d=%02x nd=%02x\n",
566 poll_reply.report_id, poll_reply.data_state,
567 poll_reply.system, poll_reply.data, poll_reply.not_data);
568
569 /* Find the key in the map */
570 for (i = 0; i < d->props.rc_key_map_size; i++) {
571 if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
572 rc5_data(&keymap[i]) == poll_reply.data) {
573 event = keymap[i].event;
574 found = 1;
575 break;
576 }
577 }
578
579 if (found == 0) {
580 err("Unknown remote controller key: %04x %02x %02x",
581 poll_reply.system, poll_reply.data, poll_reply.not_data);
582 d->last_event = 0;
583 goto resubmit;
584 }
585
586 if (poll_reply.data_state == 1) {
587 /* New key hit */
588 st->rc_counter = 0;
589 event = keymap[i].event;
590 state = REMOTE_KEY_PRESSED;
591 d->last_event = keymap[i].event;
592 } else if (poll_reply.data_state == 2) {
593 /* Key repeated */
594 st->rc_counter++;
595
596 /* prevents unwanted double hits */
597 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
598 event = d->last_event;
599 state = REMOTE_KEY_PRESSED;
600 st->rc_counter = RC_REPEAT_DELAY_V1_20;
601 }
602 } else {
603 err("Unknown data state [%d]", poll_reply.data_state);
604 }
605
606 switch (state) {
607 case REMOTE_NO_KEY_PRESSED:
608 break;
609 case REMOTE_KEY_PRESSED:
610 deb_info("key pressed\n");
611 d->last_event = event;
612 case REMOTE_KEY_REPEAT:
613 deb_info("key repeated\n");
614 input_event(d->rc_input_dev, EV_KEY, event, 1);
615 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
616 input_sync(d->rc_input_dev);
617 break;
618 default:
619 break;
620 }
621
622resubmit:
623 /* Clean the buffer before we requeue */
624 memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
625
626 /* Requeue URB */
627 usb_submit_urb(purb, GFP_ATOMIC);
628}
629
474int dib0700_rc_setup(struct dvb_usb_device *d) 630int dib0700_rc_setup(struct dvb_usb_device *d)
475{ 631{
632 struct dib0700_state *st = d->priv;
476 u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; 633 u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
477 int i = dib0700_ctrl_wr(d, rc_setup, 3); 634 struct urb *purb;
635 int ret;
636 int i;
637
638 if (d->props.rc_key_map == NULL)
639 return 0;
640
641 /* Set the IR mode */
642 i = dib0700_ctrl_wr(d, rc_setup, 3);
478 if (i<0) { 643 if (i<0) {
479 err("ir protocol setup failed"); 644 err("ir protocol setup failed");
480 return -1; 645 return -1;
481 } 646 }
647
648 if (st->fw_version < 0x10200)
649 return 0;
650
651 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
652 purb = usb_alloc_urb(0, GFP_KERNEL);
653 if (purb == NULL) {
654 err("rc usb alloc urb failed\n");
655 return -1;
656 }
657
658 purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
659 if (purb->transfer_buffer == NULL) {
660 err("rc kzalloc failed\n");
661 usb_free_urb(purb);
662 return -1;
663 }
664
665 purb->status = -EINPROGRESS;
666 usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
667 purb->transfer_buffer, RC_MSG_SIZE_V1_20,
668 dib0700_rc_urb_completion, d);
669
670 ret = usb_submit_urb(purb, GFP_ATOMIC);
671 if (ret != 0) {
672 err("rc submit urb failed\n");
673 return -1;
674 }
675
482 return 0; 676 return 0;
483} 677}
484 678
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 44972d01bbd0..34eab05afc6c 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 },