diff options
Diffstat (limited to 'drivers/media/dvb/bt8xx/dst.c')
-rw-r--r-- | drivers/media/dvb/bt8xx/dst.c | 606 |
1 files changed, 477 insertions, 129 deletions
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 1cfa5e5035d..d687a14ec0a 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -38,6 +38,10 @@ static unsigned int dst_addons; | |||
38 | module_param(dst_addons, int, 0644); | 38 | module_param(dst_addons, int, 0644); |
39 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); | 39 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); |
40 | 40 | ||
41 | static unsigned int dst_algo; | ||
42 | module_param(dst_algo, int, 0644); | ||
43 | MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); | ||
44 | |||
41 | #define HAS_LOCK 1 | 45 | #define HAS_LOCK 1 |
42 | #define ATTEMPT_TUNE 2 | 46 | #define ATTEMPT_TUNE 2 |
43 | #define HAS_POWER 4 | 47 | #define HAS_POWER 4 |
@@ -47,20 +51,24 @@ MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); | |||
47 | #define DST_INFO 2 | 51 | #define DST_INFO 2 |
48 | #define DST_DEBUG 3 | 52 | #define DST_DEBUG 3 |
49 | 53 | ||
50 | #define dprintk(x, y, z, format, arg...) do { \ | 54 | #define dprintk(x, y, z, format, arg...) do { \ |
51 | if (z) { \ | 55 | if (z) { \ |
52 | if ((x > DST_ERROR) && (x > y)) \ | 56 | if ((x > DST_ERROR) && (x > y)) \ |
53 | printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \ | 57 | printk(KERN_ERR "dst(%d) %s: " format "\n", \ |
54 | else if ((x > DST_NOTICE) && (x > y)) \ | 58 | state->bt->nr, __func__ , ##arg); \ |
55 | printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \ | 59 | else if ((x > DST_NOTICE) && (x > y)) \ |
56 | else if ((x > DST_INFO) && (x > y)) \ | 60 | printk(KERN_NOTICE "dst(%d) %s: " format "\n", \ |
57 | printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \ | 61 | state->bt->nr, __func__ , ##arg); \ |
58 | else if ((x > DST_DEBUG) && (x > y)) \ | 62 | else if ((x > DST_INFO) && (x > y)) \ |
59 | printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \ | 63 | printk(KERN_INFO "dst(%d) %s: " format "\n", \ |
60 | } else { \ | 64 | state->bt->nr, __func__ , ##arg); \ |
61 | if (x > y) \ | 65 | else if ((x > DST_DEBUG) && (x > y)) \ |
62 | printk(format, ##arg); \ | 66 | printk(KERN_DEBUG "dst(%d) %s: " format "\n", \ |
63 | } \ | 67 | state->bt->nr, __func__ , ##arg); \ |
68 | } else { \ | ||
69 | if (x > y) \ | ||
70 | printk(format, ##arg); \ | ||
71 | } \ | ||
64 | } while(0) | 72 | } while(0) |
65 | 73 | ||
66 | 74 | ||
@@ -110,7 +118,7 @@ int dst_gpio_inb(struct dst_state *state, u8 *result) | |||
110 | 118 | ||
111 | *result = 0; | 119 | *result = 0; |
112 | if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { | 120 | if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { |
113 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err); | 121 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err); |
114 | return -EREMOTEIO; | 122 | return -EREMOTEIO; |
115 | } | 123 | } |
116 | *result = (u8) rd_packet.rd.value; | 124 | *result = (u8) rd_packet.rd.value; |
@@ -363,6 +371,17 @@ static int dst_set_freq(struct dst_state *state, u32 freq) | |||
363 | state->tx_tuna[2] = (freq >> 16) & 0xff; | 371 | state->tx_tuna[2] = (freq >> 16) & 0xff; |
364 | state->tx_tuna[3] = (freq >> 8) & 0xff; | 372 | state->tx_tuna[3] = (freq >> 8) & 0xff; |
365 | state->tx_tuna[4] = (u8) freq; | 373 | state->tx_tuna[4] = (u8) freq; |
374 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
375 | freq = freq / 1000; | ||
376 | if (freq < 51000 || freq > 858000) | ||
377 | return -EINVAL; | ||
378 | state->tx_tuna[2] = (freq >> 16) & 0xff; | ||
379 | state->tx_tuna[3] = (freq >> 8) & 0xff; | ||
380 | state->tx_tuna[4] = (u8) freq; | ||
381 | state->tx_tuna[5] = 0x00; /* ATSC */ | ||
382 | state->tx_tuna[6] = 0x00; | ||
383 | if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG) | ||
384 | state->tx_tuna[7] = 0x00; /* Digital */ | ||
366 | } else | 385 | } else |
367 | return -EINVAL; | 386 | return -EINVAL; |
368 | 387 | ||
@@ -447,29 +466,41 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) | |||
447 | } | 466 | } |
448 | dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); | 467 | dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); |
449 | srate /= 1000; | 468 | srate /= 1000; |
450 | if (state->type_flags & DST_TYPE_HAS_SYMDIV) { | 469 | if (state->dst_type == DST_TYPE_IS_SAT) { |
451 | sval = srate; | 470 | if (state->type_flags & DST_TYPE_HAS_SYMDIV) { |
452 | sval <<= 20; | 471 | sval = srate; |
453 | do_div(sval, 88000); | 472 | sval <<= 20; |
454 | symcalc = (u32) sval; | 473 | do_div(sval, 88000); |
455 | dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); | 474 | symcalc = (u32) sval; |
456 | state->tx_tuna[5] = (u8) (symcalc >> 12); | 475 | dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); |
457 | state->tx_tuna[6] = (u8) (symcalc >> 4); | 476 | state->tx_tuna[5] = (u8) (symcalc >> 12); |
458 | state->tx_tuna[7] = (u8) (symcalc << 4); | 477 | state->tx_tuna[6] = (u8) (symcalc >> 4); |
459 | } else { | 478 | state->tx_tuna[7] = (u8) (symcalc << 4); |
460 | state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; | 479 | } else { |
461 | state->tx_tuna[6] = (u8) (srate >> 8); | 480 | state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; |
462 | state->tx_tuna[7] = (u8) srate; | 481 | state->tx_tuna[6] = (u8) (srate >> 8); |
463 | } | 482 | state->tx_tuna[7] = (u8) srate; |
464 | state->tx_tuna[8] &= ~0x20; | 483 | } |
465 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { | 484 | state->tx_tuna[8] &= ~0x20; |
466 | if (srate > 8000) | 485 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { |
467 | state->tx_tuna[8] |= 0x20; | 486 | if (srate > 8000) |
487 | state->tx_tuna[8] |= 0x20; | ||
488 | } | ||
489 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
490 | dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name); | ||
491 | if (!strncmp(state->fw_name, "DCTNEW", 6)) { | ||
492 | state->tx_tuna[5] = (u8) (srate >> 8); | ||
493 | state->tx_tuna[6] = (u8) srate; | ||
494 | state->tx_tuna[7] = 0x00; | ||
495 | } else if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
496 | state->tx_tuna[5] = 0x00; | ||
497 | state->tx_tuna[6] = (u8) (srate >> 8); | ||
498 | state->tx_tuna[7] = (u8) srate; | ||
499 | } | ||
468 | } | 500 | } |
469 | return 0; | 501 | return 0; |
470 | } | 502 | } |
471 | 503 | ||
472 | |||
473 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) | 504 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) |
474 | { | 505 | { |
475 | if (state->dst_type != DST_TYPE_IS_CABLE) | 506 | if (state->dst_type != DST_TYPE_IS_CABLE) |
@@ -490,7 +521,10 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio | |||
490 | state->tx_tuna[8] = 0x80; | 521 | state->tx_tuna[8] = 0x80; |
491 | break; | 522 | break; |
492 | case QAM_256: | 523 | case QAM_256: |
493 | state->tx_tuna[8] = 0x00; | 524 | if (!strncmp(state->fw_name, "DCTNEW", 6)) |
525 | state->tx_tuna[8] = 0xff; | ||
526 | else if (!strncmp(state->fw_name, "DCT-CI", 6)) | ||
527 | state->tx_tuna[8] = 0x00; | ||
494 | break; | 528 | break; |
495 | case QPSK: | 529 | case QPSK: |
496 | case QAM_AUTO: | 530 | case QAM_AUTO: |
@@ -523,13 +557,19 @@ u8 dst_check_sum(u8 *buf, u32 len) | |||
523 | } | 557 | } |
524 | EXPORT_SYMBOL(dst_check_sum); | 558 | EXPORT_SYMBOL(dst_check_sum); |
525 | 559 | ||
526 | static void dst_type_flags_print(u32 type_flags) | 560 | static void dst_type_flags_print(struct dst_state *state) |
527 | { | 561 | { |
562 | u32 type_flags = state->type_flags; | ||
563 | |||
528 | dprintk(verbose, DST_ERROR, 0, "DST type flags :"); | 564 | dprintk(verbose, DST_ERROR, 0, "DST type flags :"); |
529 | if (type_flags & DST_TYPE_HAS_NEWTUNE) | 565 | if (type_flags & DST_TYPE_HAS_TS188) |
530 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE); | 566 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188); |
567 | if (type_flags & DST_TYPE_HAS_NEWTUNE_2) | ||
568 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2); | ||
531 | if (type_flags & DST_TYPE_HAS_TS204) | 569 | if (type_flags & DST_TYPE_HAS_TS204) |
532 | dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); | 570 | dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); |
571 | if (type_flags & DST_TYPE_HAS_VLF) | ||
572 | dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF); | ||
533 | if (type_flags & DST_TYPE_HAS_SYMDIV) | 573 | if (type_flags & DST_TYPE_HAS_SYMDIV) |
534 | dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); | 574 | dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); |
535 | if (type_flags & DST_TYPE_HAS_FW_1) | 575 | if (type_flags & DST_TYPE_HAS_FW_1) |
@@ -542,7 +582,7 @@ static void dst_type_flags_print(u32 type_flags) | |||
542 | } | 582 | } |
543 | 583 | ||
544 | 584 | ||
545 | static int dst_type_print(u8 type) | 585 | static int dst_type_print(struct dst_state *state, u8 type) |
546 | { | 586 | { |
547 | char *otype; | 587 | char *otype; |
548 | switch (type) { | 588 | switch (type) { |
@@ -558,6 +598,10 @@ static int dst_type_print(u8 type) | |||
558 | otype = "cable"; | 598 | otype = "cable"; |
559 | break; | 599 | break; |
560 | 600 | ||
601 | case DST_TYPE_IS_ATSC: | ||
602 | otype = "atsc"; | ||
603 | break; | ||
604 | |||
561 | default: | 605 | default: |
562 | dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); | 606 | dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); |
563 | return -EINVAL; | 607 | return -EINVAL; |
@@ -567,6 +611,127 @@ static int dst_type_print(u8 type) | |||
567 | return 0; | 611 | return 0; |
568 | } | 612 | } |
569 | 613 | ||
614 | struct tuner_types tuner_list[] = { | ||
615 | { | ||
616 | .tuner_type = TUNER_TYPE_L64724, | ||
617 | .tuner_name = "L 64724", | ||
618 | .board_name = "UNKNOWN", | ||
619 | .fw_name = "UNKNOWN" | ||
620 | }, | ||
621 | |||
622 | { | ||
623 | .tuner_type = TUNER_TYPE_STV0299, | ||
624 | .tuner_name = "STV 0299", | ||
625 | .board_name = "VP1020", | ||
626 | .fw_name = "DST-MOT" | ||
627 | }, | ||
628 | |||
629 | { | ||
630 | .tuner_type = TUNER_TYPE_STV0299, | ||
631 | .tuner_name = "STV 0299", | ||
632 | .board_name = "VP1020", | ||
633 | .fw_name = "DST-03T" | ||
634 | }, | ||
635 | |||
636 | { | ||
637 | .tuner_type = TUNER_TYPE_MB86A15, | ||
638 | .tuner_name = "MB 86A15", | ||
639 | .board_name = "VP1022", | ||
640 | .fw_name = "DST-03T" | ||
641 | }, | ||
642 | |||
643 | { | ||
644 | .tuner_type = TUNER_TYPE_MB86A15, | ||
645 | .tuner_name = "MB 86A15", | ||
646 | .board_name = "VP1025", | ||
647 | .fw_name = "DST-03T" | ||
648 | }, | ||
649 | |||
650 | { | ||
651 | .tuner_type = TUNER_TYPE_STV0299, | ||
652 | .tuner_name = "STV 0299", | ||
653 | .board_name = "VP1030", | ||
654 | .fw_name = "DST-CI" | ||
655 | }, | ||
656 | |||
657 | { | ||
658 | .tuner_type = TUNER_TYPE_STV0299, | ||
659 | .tuner_name = "STV 0299", | ||
660 | .board_name = "VP1030", | ||
661 | .fw_name = "DSTMCI" | ||
662 | }, | ||
663 | |||
664 | { | ||
665 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
666 | .tuner_name = "UNKNOWN", | ||
667 | .board_name = "VP2021", | ||
668 | .fw_name = "DCTNEW" | ||
669 | }, | ||
670 | |||
671 | { | ||
672 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
673 | .tuner_name = "UNKNOWN", | ||
674 | .board_name = "VP2030", | ||
675 | .fw_name = "DCT-CI" | ||
676 | }, | ||
677 | |||
678 | { | ||
679 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
680 | .tuner_name = "UNKNOWN", | ||
681 | .board_name = "VP2031", | ||
682 | .fw_name = "DCT-CI" | ||
683 | }, | ||
684 | |||
685 | { | ||
686 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
687 | .tuner_name = "UNKNOWN", | ||
688 | .board_name = "VP2040", | ||
689 | .fw_name = "DCT-CI" | ||
690 | }, | ||
691 | |||
692 | { | ||
693 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
694 | .tuner_name = "UNKNOWN", | ||
695 | .board_name = "VP3020", | ||
696 | .fw_name = "DTTFTA" | ||
697 | }, | ||
698 | |||
699 | { | ||
700 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
701 | .tuner_name = "UNKNOWN", | ||
702 | .board_name = "VP3021", | ||
703 | .fw_name = "DTTFTA" | ||
704 | }, | ||
705 | |||
706 | { | ||
707 | .tuner_type = TUNER_TYPE_TDA10046, | ||
708 | .tuner_name = "TDA10046", | ||
709 | .board_name = "VP3040", | ||
710 | .fw_name = "DTT-CI" | ||
711 | }, | ||
712 | |||
713 | { | ||
714 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
715 | .tuner_name = "UNKNOWN", | ||
716 | .board_name = "VP3051", | ||
717 | .fw_name = "DTTNXT" | ||
718 | }, | ||
719 | |||
720 | { | ||
721 | .tuner_type = TUNER_TYPE_NXT200x, | ||
722 | .tuner_name = "NXT200x", | ||
723 | .board_name = "VP3220", | ||
724 | .fw_name = "ATSCDI" | ||
725 | }, | ||
726 | |||
727 | { | ||
728 | .tuner_type = TUNER_TYPE_NXT200x, | ||
729 | .tuner_name = "NXT200x", | ||
730 | .board_name = "VP3250", | ||
731 | .fw_name = "ATSCAD" | ||
732 | }, | ||
733 | }; | ||
734 | |||
570 | /* | 735 | /* |
571 | Known cards list | 736 | Known cards list |
572 | Satellite | 737 | Satellite |
@@ -608,7 +773,8 @@ static struct dst_types dst_tlist[] = { | |||
608 | .offset = 0, | 773 | .offset = 0, |
609 | .dst_type = DST_TYPE_IS_SAT, | 774 | .dst_type = DST_TYPE_IS_SAT, |
610 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, | 775 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, |
611 | .dst_feature = 0 | 776 | .dst_feature = 0, |
777 | .tuner_type = 0 | ||
612 | }, /* obsolete */ | 778 | }, /* obsolete */ |
613 | 779 | ||
614 | { | 780 | { |
@@ -616,15 +782,17 @@ static struct dst_types dst_tlist[] = { | |||
616 | .offset = 0, | 782 | .offset = 0, |
617 | .dst_type = DST_TYPE_IS_SAT, | 783 | .dst_type = DST_TYPE_IS_SAT, |
618 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | 784 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, |
619 | .dst_feature = 0 | 785 | .dst_feature = 0, |
786 | .tuner_type = 0 | ||
620 | }, /* obsolete */ | 787 | }, /* obsolete */ |
621 | 788 | ||
622 | { | 789 | { |
623 | .device_id = "DST-030", | 790 | .device_id = "DST-030", |
624 | .offset = 0, | 791 | .offset = 0, |
625 | .dst_type = DST_TYPE_IS_SAT, | 792 | .dst_type = DST_TYPE_IS_SAT, |
626 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 793 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, |
627 | .dst_feature = 0 | 794 | .dst_feature = 0, |
795 | .tuner_type = 0 | ||
628 | }, /* obsolete */ | 796 | }, /* obsolete */ |
629 | 797 | ||
630 | { | 798 | { |
@@ -633,7 +801,8 @@ static struct dst_types dst_tlist[] = { | |||
633 | .dst_type = DST_TYPE_IS_SAT, | 801 | .dst_type = DST_TYPE_IS_SAT, |
634 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, | 802 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, |
635 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 | 803 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 |
636 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO | 804 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO, |
805 | .tuner_type = TUNER_TYPE_MULTI | ||
637 | }, | 806 | }, |
638 | 807 | ||
639 | { | 808 | { |
@@ -641,57 +810,63 @@ static struct dst_types dst_tlist[] = { | |||
641 | .offset = 0, | 810 | .offset = 0, |
642 | .dst_type = DST_TYPE_IS_SAT, | 811 | .dst_type = DST_TYPE_IS_SAT, |
643 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | 812 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, |
644 | .dst_feature = 0 | 813 | .dst_feature = 0, |
814 | .tuner_type = 0 | ||
645 | }, /* obsolete */ | 815 | }, /* obsolete */ |
646 | 816 | ||
647 | { | 817 | { |
648 | .device_id = "DST-CI", | 818 | .device_id = "DST-CI", |
649 | .offset = 1, | 819 | .offset = 1, |
650 | .dst_type = DST_TYPE_IS_SAT, | 820 | .dst_type = DST_TYPE_IS_SAT, |
651 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 821 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1, |
652 | .dst_feature = DST_TYPE_HAS_CA | 822 | .dst_feature = DST_TYPE_HAS_CA, |
823 | .tuner_type = 0 | ||
653 | }, /* An OEM board */ | 824 | }, /* An OEM board */ |
654 | 825 | ||
655 | { | 826 | { |
656 | .device_id = "DSTMCI", | 827 | .device_id = "DSTMCI", |
657 | .offset = 1, | 828 | .offset = 1, |
658 | .dst_type = DST_TYPE_IS_SAT, | 829 | .dst_type = DST_TYPE_IS_SAT, |
659 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT, | 830 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF, |
660 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | 831 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 |
661 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC | 832 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC, |
833 | .tuner_type = TUNER_TYPE_MULTI | ||
662 | }, | 834 | }, |
663 | 835 | ||
664 | { | 836 | { |
665 | .device_id = "DSTFCI", | 837 | .device_id = "DSTFCI", |
666 | .offset = 1, | 838 | .offset = 1, |
667 | .dst_type = DST_TYPE_IS_SAT, | 839 | .dst_type = DST_TYPE_IS_SAT, |
668 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 840 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, |
669 | .dst_feature = 0 | 841 | .dst_feature = 0, |
842 | .tuner_type = 0 | ||
670 | }, /* unknown to vendor */ | 843 | }, /* unknown to vendor */ |
671 | 844 | ||
672 | { | 845 | { |
673 | .device_id = "DCT-CI", | 846 | .device_id = "DCT-CI", |
674 | .offset = 1, | 847 | .offset = 1, |
675 | .dst_type = DST_TYPE_IS_CABLE, | 848 | .dst_type = DST_TYPE_IS_CABLE, |
676 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 | 849 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF, |
677 | | DST_TYPE_HAS_FW_2, | 850 | .dst_feature = DST_TYPE_HAS_CA, |
678 | .dst_feature = DST_TYPE_HAS_CA | 851 | .tuner_type = 0 |
679 | }, | 852 | }, |
680 | 853 | ||
681 | { | 854 | { |
682 | .device_id = "DCTNEW", | 855 | .device_id = "DCTNEW", |
683 | .offset = 1, | 856 | .offset = 1, |
684 | .dst_type = DST_TYPE_IS_CABLE, | 857 | .dst_type = DST_TYPE_IS_CABLE, |
685 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD, | 858 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE, |
686 | .dst_feature = 0 | 859 | .dst_feature = 0, |
860 | .tuner_type = 0 | ||
687 | }, | 861 | }, |
688 | 862 | ||
689 | { | 863 | { |
690 | .device_id = "DTT-CI", | 864 | .device_id = "DTT-CI", |
691 | .offset = 1, | 865 | .offset = 1, |
692 | .dst_type = DST_TYPE_IS_TERR, | 866 | .dst_type = DST_TYPE_IS_TERR, |
693 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE, | 867 | .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF, |
694 | .dst_feature = DST_TYPE_HAS_CA | 868 | .dst_feature = DST_TYPE_HAS_CA, |
869 | .tuner_type = 0 | ||
695 | }, | 870 | }, |
696 | 871 | ||
697 | { | 872 | { |
@@ -699,7 +874,8 @@ static struct dst_types dst_tlist[] = { | |||
699 | .offset = 1, | 874 | .offset = 1, |
700 | .dst_type = DST_TYPE_IS_TERR, | 875 | .dst_type = DST_TYPE_IS_TERR, |
701 | .type_flags = DST_TYPE_HAS_FW_2, | 876 | .type_flags = DST_TYPE_HAS_FW_2, |
702 | .dst_feature = 0 | 877 | .dst_feature = 0, |
878 | .tuner_type = 0 | ||
703 | }, | 879 | }, |
704 | 880 | ||
705 | { | 881 | { |
@@ -707,7 +883,8 @@ static struct dst_types dst_tlist[] = { | |||
707 | .offset = 1, | 883 | .offset = 1, |
708 | .dst_type = DST_TYPE_IS_TERR, | 884 | .dst_type = DST_TYPE_IS_TERR, |
709 | .type_flags = DST_TYPE_HAS_FW_2, | 885 | .type_flags = DST_TYPE_HAS_FW_2, |
710 | .dst_feature = DST_TYPE_HAS_ANALOG | 886 | .dst_feature = DST_TYPE_HAS_ANALOG, |
887 | .tuner_type = 0 | ||
711 | }, | 888 | }, |
712 | 889 | ||
713 | { | 890 | { |
@@ -715,15 +892,17 @@ static struct dst_types dst_tlist[] = { | |||
715 | .offset = 1, | 892 | .offset = 1, |
716 | .dst_type = DST_TYPE_IS_ATSC, | 893 | .dst_type = DST_TYPE_IS_ATSC, |
717 | .type_flags = DST_TYPE_HAS_FW_2, | 894 | .type_flags = DST_TYPE_HAS_FW_2, |
718 | .dst_feature = 0 | 895 | .dst_feature = 0, |
896 | .tuner_type = 0 | ||
719 | }, | 897 | }, |
720 | 898 | ||
721 | { | 899 | { |
722 | .device_id = "ATSCAD", | 900 | .device_id = "ATSCAD", |
723 | .offset = 1, | 901 | .offset = 1, |
724 | .dst_type = DST_TYPE_IS_ATSC, | 902 | .dst_type = DST_TYPE_IS_ATSC, |
725 | .type_flags = DST_TYPE_HAS_FW_2, | 903 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, |
726 | .dst_feature = 0 | 904 | .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG, |
905 | .tuner_type = 0 | ||
727 | }, | 906 | }, |
728 | 907 | ||
729 | { } | 908 | { } |
@@ -768,6 +947,9 @@ static int dst_fw_ver(struct dst_state *state) | |||
768 | 947 | ||
769 | static int dst_card_type(struct dst_state *state) | 948 | static int dst_card_type(struct dst_state *state) |
770 | { | 949 | { |
950 | int j; | ||
951 | struct tuner_types *p_tuner_list = NULL; | ||
952 | |||
771 | u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 953 | u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
772 | get_type[7] = dst_check_sum(get_type, 7); | 954 | get_type[7] = dst_check_sum(get_type, 7); |
773 | if (dst_command(state, get_type, 8) < 0) { | 955 | if (dst_command(state, get_type, 8) < 0) { |
@@ -775,9 +957,17 @@ static int dst_card_type(struct dst_state *state) | |||
775 | return -1; | 957 | return -1; |
776 | } | 958 | } |
777 | memset(&state->card_info, '\0', 8); | 959 | memset(&state->card_info, '\0', 8); |
778 | memcpy(&state->card_info, &state->rxbuffer, 8); | 960 | memcpy(&state->card_info, &state->rxbuffer, 7); |
779 | dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); | 961 | dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); |
780 | 962 | ||
963 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
964 | if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { | ||
965 | state->tuner_type = p_tuner_list->tuner_type; | ||
966 | dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]", | ||
967 | p_tuner_list->tuner_name, p_tuner_list->tuner_type); | ||
968 | } | ||
969 | } | ||
970 | |||
781 | return 0; | 971 | return 0; |
782 | } | 972 | } |
783 | 973 | ||
@@ -790,12 +980,64 @@ static int dst_get_vendor(struct dst_state *state) | |||
790 | return -1; | 980 | return -1; |
791 | } | 981 | } |
792 | memset(&state->vendor, '\0', 8); | 982 | memset(&state->vendor, '\0', 8); |
793 | memcpy(&state->vendor, &state->rxbuffer, 8); | 983 | memcpy(&state->vendor, &state->rxbuffer, 7); |
794 | dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); | 984 | dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); |
795 | 985 | ||
796 | return 0; | 986 | return 0; |
797 | } | 987 | } |
798 | 988 | ||
989 | static void debug_dst_buffer(struct dst_state *state) | ||
990 | { | ||
991 | int i; | ||
992 | |||
993 | if (verbose > 2) { | ||
994 | printk("%s: [", __func__); | ||
995 | for (i = 0; i < 8; i++) | ||
996 | printk(" %02x", state->rxbuffer[i]); | ||
997 | printk("]\n"); | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | static int dst_check_stv0299(struct dst_state *state) | ||
1002 | { | ||
1003 | u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1004 | |||
1005 | check_stv0299[7] = dst_check_sum(check_stv0299, 7); | ||
1006 | if (dst_command(state, check_stv0299, 8) < 0) { | ||
1007 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed"); | ||
1008 | return -1; | ||
1009 | } | ||
1010 | debug_dst_buffer(state); | ||
1011 | |||
1012 | if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { | ||
1013 | dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM"); | ||
1014 | state->tuner_type = TUNER_TYPE_STV0299; | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | return -1; | ||
1019 | } | ||
1020 | |||
1021 | static int dst_check_mb86a15(struct dst_state *state) | ||
1022 | { | ||
1023 | u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1024 | |||
1025 | check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); | ||
1026 | if (dst_command(state, check_mb86a15, 8) < 0) { | ||
1027 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed"); | ||
1028 | return -1; | ||
1029 | } | ||
1030 | debug_dst_buffer(state); | ||
1031 | |||
1032 | if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { | ||
1033 | dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM"); | ||
1034 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1035 | return 0; | ||
1036 | } | ||
1037 | |||
1038 | return -1; | ||
1039 | } | ||
1040 | |||
799 | static int dst_get_tuner_info(struct dst_state *state) | 1041 | static int dst_get_tuner_info(struct dst_state *state) |
800 | { | 1042 | { |
801 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 1043 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
@@ -803,60 +1045,59 @@ static int dst_get_tuner_info(struct dst_state *state) | |||
803 | 1045 | ||
804 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); | 1046 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); |
805 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); | 1047 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); |
1048 | dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE"); | ||
806 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | 1049 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { |
807 | if (dst_command(state, get_tuner_2, 8) < 0) { | 1050 | if (dst_command(state, get_tuner_1, 8) < 0) { |
808 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | 1051 | dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported"); |
809 | return -1; | 1052 | goto force; |
810 | } | 1053 | } |
811 | } else { | 1054 | } else { |
812 | if (dst_command(state, get_tuner_1, 8) < 0) { | 1055 | if (dst_command(state, get_tuner_2, 8) < 0) { |
813 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | 1056 | dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported"); |
814 | return -1; | 1057 | goto force; |
815 | } | 1058 | } |
816 | } | 1059 | } |
817 | memset(&state->board_info, '\0', 8); | 1060 | memset(&state->board_info, '\0', 8); |
818 | memcpy(&state->board_info, &state->rxbuffer, 8); | 1061 | memcpy(&state->board_info, &state->rxbuffer, 8); |
819 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | 1062 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { |
820 | if (state->board_info[1] == 0x0b) { | 1063 | dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); |
821 | if (state->type_flags & DST_TYPE_HAS_TS204) | 1064 | } |
822 | state->type_flags &= ~DST_TYPE_HAS_TS204; | 1065 | if (state->board_info[0] == 0xbc) { |
823 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | 1066 | if (state->type_flags != DST_TYPE_IS_ATSC) |
824 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188"); | 1067 | state->type_flags |= DST_TYPE_HAS_TS188; |
825 | } else { | 1068 | else |
826 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1069 | state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; |
827 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | 1070 | |
828 | state->type_flags |= DST_TYPE_HAS_TS204; | 1071 | if (state->board_info[1] == 0x01) { |
829 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204"); | 1072 | state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; |
830 | } | 1073 | dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard"); |
831 | } else { | ||
832 | if (state->board_info[0] == 0xbc) { | ||
833 | if (state->type_flags & DST_TYPE_HAS_TS204) | ||
834 | state->type_flags &= ~DST_TYPE_HAS_TS204; | ||
835 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | ||
836 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]); | ||
837 | |||
838 | } else if (state->board_info[0] == 0xcc) { | ||
839 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | ||
840 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | ||
841 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
842 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]); | ||
843 | } | 1074 | } |
844 | } | 1075 | } |
845 | 1076 | ||
846 | return 0; | 1077 | return 0; |
1078 | force: | ||
1079 | if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
1080 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
1081 | dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name); | ||
1082 | } | ||
1083 | |||
1084 | return -1; | ||
847 | } | 1085 | } |
848 | 1086 | ||
849 | static int dst_get_device_id(struct dst_state *state) | 1087 | static int dst_get_device_id(struct dst_state *state) |
850 | { | 1088 | { |
851 | u8 reply; | 1089 | u8 reply; |
852 | 1090 | ||
853 | int i; | 1091 | int i, j; |
854 | struct dst_types *p_dst_type; | 1092 | struct dst_types *p_dst_type = NULL; |
1093 | struct tuner_types *p_tuner_list = NULL; | ||
1094 | |||
855 | u8 use_dst_type = 0; | 1095 | u8 use_dst_type = 0; |
856 | u32 use_type_flags = 0; | 1096 | u32 use_type_flags = 0; |
857 | 1097 | ||
858 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | 1098 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; |
859 | 1099 | ||
1100 | state->tuner_type = 0; | ||
860 | device_type[7] = dst_check_sum(device_type, 7); | 1101 | device_type[7] = dst_check_sum(device_type, 7); |
861 | 1102 | ||
862 | if (write_dst(state, device_type, FIXED_COMM)) | 1103 | if (write_dst(state, device_type, FIXED_COMM)) |
@@ -888,8 +1129,34 @@ static int dst_get_device_id(struct dst_state *state) | |||
888 | 1129 | ||
889 | /* Card capabilities */ | 1130 | /* Card capabilities */ |
890 | state->dst_hw_cap = p_dst_type->dst_feature; | 1131 | state->dst_hw_cap = p_dst_type->dst_feature; |
891 | dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id); | 1132 | dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id); |
892 | 1133 | strncpy(&state->fw_name[0], p_dst_type->device_id, 6); | |
1134 | /* Multiple tuners */ | ||
1135 | if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { | ||
1136 | switch (use_dst_type) { | ||
1137 | case DST_TYPE_IS_SAT: | ||
1138 | /* STV0299 check */ | ||
1139 | if (dst_check_stv0299(state) < 0) { | ||
1140 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1141 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1142 | } | ||
1143 | break; | ||
1144 | default: | ||
1145 | break; | ||
1146 | } | ||
1147 | if (dst_check_mb86a15(state) < 0) | ||
1148 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1149 | /* Single tuner */ | ||
1150 | } else { | ||
1151 | state->tuner_type = p_dst_type->tuner_type; | ||
1152 | } | ||
1153 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
1154 | if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && | ||
1155 | p_tuner_list->tuner_type == state->tuner_type) { | ||
1156 | dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]", | ||
1157 | p_dst_type->device_id, p_tuner_list->tuner_name); | ||
1158 | } | ||
1159 | } | ||
893 | break; | 1160 | break; |
894 | } | 1161 | } |
895 | } | 1162 | } |
@@ -900,10 +1167,10 @@ static int dst_get_device_id(struct dst_state *state) | |||
900 | use_dst_type = DST_TYPE_IS_SAT; | 1167 | use_dst_type = DST_TYPE_IS_SAT; |
901 | use_type_flags = DST_TYPE_HAS_SYMDIV; | 1168 | use_type_flags = DST_TYPE_HAS_SYMDIV; |
902 | } | 1169 | } |
903 | dst_type_print(use_dst_type); | 1170 | dst_type_print(state, use_dst_type); |
904 | state->type_flags = use_type_flags; | 1171 | state->type_flags = use_type_flags; |
905 | state->dst_type = use_dst_type; | 1172 | state->dst_type = use_dst_type; |
906 | dst_type_flags_print(state->type_flags); | 1173 | dst_type_flags_print(state); |
907 | 1174 | ||
908 | return 0; | 1175 | return 0; |
909 | } | 1176 | } |
@@ -911,15 +1178,15 @@ static int dst_get_device_id(struct dst_state *state) | |||
911 | static int dst_probe(struct dst_state *state) | 1178 | static int dst_probe(struct dst_state *state) |
912 | { | 1179 | { |
913 | mutex_init(&state->dst_mutex); | 1180 | mutex_init(&state->dst_mutex); |
914 | if ((rdc_8820_reset(state)) < 0) { | 1181 | if (dst_addons & DST_TYPE_HAS_CA) { |
915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | 1182 | if ((rdc_8820_reset(state)) < 0) { |
916 | return -1; | 1183 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); |
917 | } | 1184 | return -1; |
918 | if (dst_addons & DST_TYPE_HAS_CA) | 1185 | } |
919 | msleep(4000); | 1186 | msleep(4000); |
920 | else | 1187 | } else { |
921 | msleep(100); | 1188 | msleep(100); |
922 | 1189 | } | |
923 | if ((dst_comm_init(state)) < 0) { | 1190 | if ((dst_comm_init(state)) < 0) { |
924 | dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); | 1191 | dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); |
925 | return -1; | 1192 | return -1; |
@@ -931,7 +1198,6 @@ static int dst_probe(struct dst_state *state) | |||
931 | } | 1198 | } |
932 | if (dst_get_mac(state) < 0) { | 1199 | if (dst_get_mac(state) < 0) { |
933 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); | 1200 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); |
934 | return 0; | ||
935 | } | 1201 | } |
936 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { | 1202 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { |
937 | if (dst_get_tuner_info(state) < 0) | 1203 | if (dst_get_tuner_info(state) < 0) |
@@ -1048,6 +1314,10 @@ static int dst_get_signal(struct dst_state *state) | |||
1048 | state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; | 1314 | state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; |
1049 | state->decode_strength = state->rxbuffer[4] << 8; | 1315 | state->decode_strength = state->rxbuffer[4] << 8; |
1050 | state->decode_snr = state->rxbuffer[3] << 8; | 1316 | state->decode_snr = state->rxbuffer[3] << 8; |
1317 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
1318 | state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0; | ||
1319 | state->decode_strength = state->rxbuffer[4] << 8; | ||
1320 | state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; | ||
1051 | } | 1321 | } |
1052 | state->cur_jiff = jiffies; | 1322 | state->cur_jiff = jiffies; |
1053 | } | 1323 | } |
@@ -1078,8 +1348,9 @@ static int dst_get_tuna(struct dst_state *state) | |||
1078 | state->diseq_flags &= ~(HAS_LOCK); | 1348 | state->diseq_flags &= ~(HAS_LOCK); |
1079 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1349 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
1080 | return -EIO; | 1350 | return -EIO; |
1081 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1351 | if ((state->type_flags & DST_TYPE_HAS_VLF) && |
1082 | /* how to get variable length reply ???? */ | 1352 | !(state->dst_type == DST_TYPE_IS_ATSC)) |
1353 | |||
1083 | retval = read_dst(state, state->rx_tuna, 10); | 1354 | retval = read_dst(state, state->rx_tuna, 10); |
1084 | else | 1355 | else |
1085 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); | 1356 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); |
@@ -1087,7 +1358,10 @@ static int dst_get_tuna(struct dst_state *state) | |||
1087 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); | 1358 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); |
1088 | return retval; | 1359 | return retval; |
1089 | } | 1360 | } |
1090 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1361 | if ((state->type_flags & DST_TYPE_HAS_VLF) && |
1362 | !(state->dst_type == DST_TYPE_IS_CABLE) && | ||
1363 | !(state->dst_type == DST_TYPE_IS_ATSC)) { | ||
1364 | |||
1091 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | 1365 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { |
1092 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); | 1366 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); |
1093 | return -EIO; | 1367 | return -EIO; |
@@ -1133,7 +1407,10 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
1133 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); | 1407 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); |
1134 | goto error; | 1408 | goto error; |
1135 | } | 1409 | } |
1136 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1410 | // if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
1411 | if ((state->type_flags & DST_TYPE_HAS_VLF) && | ||
1412 | (!(state->dst_type == DST_TYPE_IS_ATSC))) { | ||
1413 | |||
1137 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); | 1414 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); |
1138 | retval = write_dst(state, &state->tx_tuna[0], 10); | 1415 | retval = write_dst(state, &state->tx_tuna[0], 10); |
1139 | } else { | 1416 | } else { |
@@ -1189,9 +1466,12 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd | |||
1189 | 1466 | ||
1190 | if (state->dst_type != DST_TYPE_IS_SAT) | 1467 | if (state->dst_type != DST_TYPE_IS_SAT) |
1191 | return 0; | 1468 | return 0; |
1192 | if (cmd->msg_len == 0 || cmd->msg_len > 4) | 1469 | if (cmd->msg_len > 0 && cmd->msg_len < 5) |
1470 | memcpy(&paket[3], cmd->msg, cmd->msg_len); | ||
1471 | else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) | ||
1472 | memcpy(&paket[2], cmd->msg, cmd->msg_len); | ||
1473 | else | ||
1193 | return -EINVAL; | 1474 | return -EINVAL; |
1194 | memcpy(&paket[3], cmd->msg, cmd->msg_len); | ||
1195 | paket[7] = dst_check_sum(&paket[0], 7); | 1475 | paket[7] = dst_check_sum(&paket[0], 7); |
1196 | dst_command(state, paket, 8); | 1476 | dst_command(state, paket, 8); |
1197 | return 0; | 1477 | return 0; |
@@ -1287,8 +1567,9 @@ static int dst_init(struct dvb_frontend *fe) | |||
1287 | static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; | 1567 | static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; |
1288 | static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1568 | static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1289 | static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1569 | static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1290 | static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1291 | static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1570 | static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1571 | static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1572 | static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1292 | 1573 | ||
1293 | state->inversion = INVERSION_OFF; | 1574 | state->inversion = INVERSION_OFF; |
1294 | state->voltage = SEC_VOLTAGE_13; | 1575 | state->voltage = SEC_VOLTAGE_13; |
@@ -1298,11 +1579,13 @@ static int dst_init(struct dvb_frontend *fe) | |||
1298 | state->bandwidth = BANDWIDTH_7_MHZ; | 1579 | state->bandwidth = BANDWIDTH_7_MHZ; |
1299 | state->cur_jiff = jiffies; | 1580 | state->cur_jiff = jiffies; |
1300 | if (state->dst_type == DST_TYPE_IS_SAT) | 1581 | if (state->dst_type == DST_TYPE_IS_SAT) |
1301 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); | 1582 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); |
1302 | else if (state->dst_type == DST_TYPE_IS_TERR) | 1583 | else if (state->dst_type == DST_TYPE_IS_TERR) |
1303 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); | 1584 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); |
1304 | else if (state->dst_type == DST_TYPE_IS_CABLE) | 1585 | else if (state->dst_type == DST_TYPE_IS_CABLE) |
1305 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); | 1586 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); |
1587 | else if (state->dst_type == DST_TYPE_IS_ATSC) | ||
1588 | memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); | ||
1306 | 1589 | ||
1307 | return 0; | 1590 | return 0; |
1308 | } | 1591 | } |
@@ -1341,7 +1624,36 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
1341 | return 0; | 1624 | return 0; |
1342 | } | 1625 | } |
1343 | 1626 | ||
1344 | static int dst_set_frontend(struct dvb_frontend* fe, | 1627 | static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
1628 | { | ||
1629 | struct dst_state *state = fe->demodulator_priv; | ||
1630 | |||
1631 | if (p != NULL) { | ||
1632 | dst_set_freq(state, p->frequency); | ||
1633 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | ||
1634 | |||
1635 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1636 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1637 | dst_set_inversion(state, p->inversion); | ||
1638 | dst_set_fec(state, p->u.qpsk.fec_inner); | ||
1639 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); | ||
1640 | dst_set_polarization(state); | ||
1641 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); | ||
1642 | |||
1643 | } else if (state->dst_type == DST_TYPE_IS_TERR) | ||
1644 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); | ||
1645 | else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
1646 | dst_set_fec(state, p->u.qam.fec_inner); | ||
1647 | dst_set_symbolrate(state, p->u.qam.symbol_rate); | ||
1648 | dst_set_modulation(state, p->u.qam.modulation); | ||
1649 | } | ||
1650 | dst_write_tuna(fe); | ||
1651 | } | ||
1652 | |||
1653 | return 0; | ||
1654 | } | ||
1655 | |||
1656 | static int dst_tune_frontend(struct dvb_frontend* fe, | ||
1345 | struct dvb_frontend_parameters* p, | 1657 | struct dvb_frontend_parameters* p, |
1346 | unsigned int mode_flags, | 1658 | unsigned int mode_flags, |
1347 | int *delay, | 1659 | int *delay, |
@@ -1378,6 +1690,11 @@ static int dst_set_frontend(struct dvb_frontend* fe, | |||
1378 | return 0; | 1690 | return 0; |
1379 | } | 1691 | } |
1380 | 1692 | ||
1693 | static int dst_get_tuning_algo(struct dvb_frontend *fe) | ||
1694 | { | ||
1695 | return dst_algo; | ||
1696 | } | ||
1697 | |||
1381 | static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 1698 | static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
1382 | { | 1699 | { |
1383 | struct dst_state *state = fe->demodulator_priv; | 1700 | struct dst_state *state = fe->demodulator_priv; |
@@ -1408,6 +1725,7 @@ static void dst_release(struct dvb_frontend *fe) | |||
1408 | static struct dvb_frontend_ops dst_dvbt_ops; | 1725 | static struct dvb_frontend_ops dst_dvbt_ops; |
1409 | static struct dvb_frontend_ops dst_dvbs_ops; | 1726 | static struct dvb_frontend_ops dst_dvbs_ops; |
1410 | static struct dvb_frontend_ops dst_dvbc_ops; | 1727 | static struct dvb_frontend_ops dst_dvbc_ops; |
1728 | static struct dvb_frontend_ops dst_atsc_ops; | ||
1411 | 1729 | ||
1412 | struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) | 1730 | struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) |
1413 | { | 1731 | { |
@@ -1417,24 +1735,25 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad | |||
1417 | return NULL; | 1735 | return NULL; |
1418 | } | 1736 | } |
1419 | /* determine settings based on type */ | 1737 | /* determine settings based on type */ |
1738 | /* create dvb_frontend */ | ||
1420 | switch (state->dst_type) { | 1739 | switch (state->dst_type) { |
1421 | case DST_TYPE_IS_TERR: | 1740 | case DST_TYPE_IS_TERR: |
1422 | memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); | 1741 | memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); |
1423 | break; | 1742 | break; |
1424 | case DST_TYPE_IS_CABLE: | 1743 | case DST_TYPE_IS_CABLE: |
1425 | memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); | 1744 | memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); |
1426 | break; | 1745 | break; |
1427 | case DST_TYPE_IS_SAT: | 1746 | case DST_TYPE_IS_SAT: |
1428 | memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); | 1747 | memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); |
1748 | break; | ||
1749 | case DST_TYPE_IS_ATSC: | ||
1750 | memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); | ||
1429 | break; | 1751 | break; |
1430 | default: | 1752 | default: |
1431 | dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); | 1753 | dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); |
1432 | kfree(state); | 1754 | kfree(state); |
1433 | return NULL; | 1755 | return NULL; |
1434 | } | 1756 | } |
1435 | |||
1436 | /* create dvb_frontend */ | ||
1437 | state->frontend.ops = &state->ops; | ||
1438 | state->frontend.demodulator_priv = state; | 1757 | state->frontend.demodulator_priv = state; |
1439 | 1758 | ||
1440 | return state; /* Manu (DST is a card not a frontend) */ | 1759 | return state; /* Manu (DST is a card not a frontend) */ |
@@ -1455,8 +1774,10 @@ static struct dvb_frontend_ops dst_dvbt_ops = { | |||
1455 | 1774 | ||
1456 | .release = dst_release, | 1775 | .release = dst_release, |
1457 | .init = dst_init, | 1776 | .init = dst_init, |
1458 | .tune = dst_set_frontend, | 1777 | .tune = dst_tune_frontend, |
1778 | .set_frontend = dst_set_frontend, | ||
1459 | .get_frontend = dst_get_frontend, | 1779 | .get_frontend = dst_get_frontend, |
1780 | .get_frontend_algo = dst_get_tuning_algo, | ||
1460 | .read_status = dst_read_status, | 1781 | .read_status = dst_read_status, |
1461 | .read_signal_strength = dst_read_signal_strength, | 1782 | .read_signal_strength = dst_read_signal_strength, |
1462 | .read_snr = dst_read_snr, | 1783 | .read_snr = dst_read_snr, |
@@ -1479,8 +1800,10 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
1479 | 1800 | ||
1480 | .release = dst_release, | 1801 | .release = dst_release, |
1481 | .init = dst_init, | 1802 | .init = dst_init, |
1482 | .tune = dst_set_frontend, | 1803 | .tune = dst_tune_frontend, |
1804 | .set_frontend = dst_set_frontend, | ||
1483 | .get_frontend = dst_get_frontend, | 1805 | .get_frontend = dst_get_frontend, |
1806 | .get_frontend_algo = dst_get_tuning_algo, | ||
1484 | .read_status = dst_read_status, | 1807 | .read_status = dst_read_status, |
1485 | .read_signal_strength = dst_read_signal_strength, | 1808 | .read_signal_strength = dst_read_signal_strength, |
1486 | .read_snr = dst_read_snr, | 1809 | .read_snr = dst_read_snr, |
@@ -1506,13 +1829,38 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
1506 | 1829 | ||
1507 | .release = dst_release, | 1830 | .release = dst_release, |
1508 | .init = dst_init, | 1831 | .init = dst_init, |
1509 | .tune = dst_set_frontend, | 1832 | .tune = dst_tune_frontend, |
1833 | .set_frontend = dst_set_frontend, | ||
1834 | .get_frontend = dst_get_frontend, | ||
1835 | .get_frontend_algo = dst_get_tuning_algo, | ||
1836 | .read_status = dst_read_status, | ||
1837 | .read_signal_strength = dst_read_signal_strength, | ||
1838 | .read_snr = dst_read_snr, | ||
1839 | }; | ||
1840 | |||
1841 | static struct dvb_frontend_ops dst_atsc_ops = { | ||
1842 | .info = { | ||
1843 | .name = "DST ATSC", | ||
1844 | .type = FE_ATSC, | ||
1845 | .frequency_stepsize = 62500, | ||
1846 | .frequency_min = 510000000, | ||
1847 | .frequency_max = 858000000, | ||
1848 | .symbol_rate_min = 1000000, | ||
1849 | .symbol_rate_max = 45000000, | ||
1850 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | ||
1851 | }, | ||
1852 | |||
1853 | .release = dst_release, | ||
1854 | .init = dst_init, | ||
1855 | .tune = dst_tune_frontend, | ||
1856 | .set_frontend = dst_set_frontend, | ||
1510 | .get_frontend = dst_get_frontend, | 1857 | .get_frontend = dst_get_frontend, |
1858 | .get_frontend_algo = dst_get_tuning_algo, | ||
1511 | .read_status = dst_read_status, | 1859 | .read_status = dst_read_status, |
1512 | .read_signal_strength = dst_read_signal_strength, | 1860 | .read_signal_strength = dst_read_signal_strength, |
1513 | .read_snr = dst_read_snr, | 1861 | .read_snr = dst_read_snr, |
1514 | }; | 1862 | }; |
1515 | 1863 | ||
1516 | MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); | 1864 | MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver"); |
1517 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); | 1865 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); |
1518 | MODULE_LICENSE("GPL"); | 1866 | MODULE_LICENSE("GPL"); |