aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-04-30 17:14:36 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-05-14 01:53:59 -0400
commit0590d91c413fb5144608d69f50710064360aeec8 (patch)
tree2463f92e8957f3f901361690017081759d4a20f8 /drivers
parent6430a5a368208ae6c4bcd13e1f06460c96af66be (diff)
V4L/DVB (7807): cx88: Fix error handling, when dvb_attach() fails
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c251
1 files changed, 134 insertions, 117 deletions
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 1c7fe6862a60..75e2e58349ef 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -509,9 +509,6 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
509 if (!fe) { 509 if (!fe) {
510 printk(KERN_ERR "%s/2: xc3028 attach failed\n", 510 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
511 dev->core->name); 511 dev->core->name);
512 dvb_frontend_detach(dev->dvb.frontend);
513 dvb_unregister_frontend(dev->dvb.frontend);
514 dev->dvb.frontend = NULL;
515 return -EINVAL; 512 return -EINVAL;
516 } 513 }
517 514
@@ -523,20 +520,23 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
523 520
524static int dvb_register(struct cx8802_dev *dev) 521static int dvb_register(struct cx8802_dev *dev)
525{ 522{
523 struct cx88_core *core = dev->core;
524
526 /* init struct videobuf_dvb */ 525 /* init struct videobuf_dvb */
527 dev->dvb.name = dev->core->name; 526 dev->dvb.name = core->name;
528 dev->ts_gen_cntrl = 0x0c; 527 dev->ts_gen_cntrl = 0x0c;
529 528
530 /* init frontend */ 529 /* init frontend */
531 switch (dev->core->boardnr) { 530 switch (core->boardnr) {
532 case CX88_BOARD_HAUPPAUGE_DVB_T1: 531 case CX88_BOARD_HAUPPAUGE_DVB_T1:
533 dev->dvb.frontend = dvb_attach(cx22702_attach, 532 dev->dvb.frontend = dvb_attach(cx22702_attach,
534 &connexant_refboard_config, 533 &connexant_refboard_config,
535 &dev->core->i2c_adap); 534 &core->i2c_adap);
536 if (dev->dvb.frontend != NULL) { 535 if (dev->dvb.frontend != NULL) {
537 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, 536 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
538 &dev->core->i2c_adap, 537 0x61, &core->i2c_adap,
539 DVB_PLL_THOMSON_DTT759X); 538 DVB_PLL_THOMSON_DTT759X))
539 goto frontend_detach;
540 } 540 }
541 break; 541 break;
542 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 542 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
@@ -545,11 +545,12 @@ static int dvb_register(struct cx8802_dev *dev)
545 case CX88_BOARD_WINFAST_DTV1000: 545 case CX88_BOARD_WINFAST_DTV1000:
546 dev->dvb.frontend = dvb_attach(cx22702_attach, 546 dev->dvb.frontend = dvb_attach(cx22702_attach,
547 &connexant_refboard_config, 547 &connexant_refboard_config,
548 &dev->core->i2c_adap); 548 &core->i2c_adap);
549 if (dev->dvb.frontend != NULL) { 549 if (dev->dvb.frontend != NULL) {
550 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, 550 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
551 &dev->core->i2c_adap, 551 0x60, &core->i2c_adap,
552 DVB_PLL_THOMSON_DTT7579); 552 DVB_PLL_THOMSON_DTT7579))
553 goto frontend_detach;
553 } 554 }
554 break; 555 break;
555 case CX88_BOARD_WINFAST_DTV2000H: 556 case CX88_BOARD_WINFAST_DTV2000H:
@@ -559,29 +560,32 @@ static int dvb_register(struct cx8802_dev *dev)
559 case CX88_BOARD_HAUPPAUGE_HVR3000: 560 case CX88_BOARD_HAUPPAUGE_HVR3000:
560 dev->dvb.frontend = dvb_attach(cx22702_attach, 561 dev->dvb.frontend = dvb_attach(cx22702_attach,
561 &hauppauge_hvr_config, 562 &hauppauge_hvr_config,
562 &dev->core->i2c_adap); 563 &core->i2c_adap);
563 if (dev->dvb.frontend != NULL) { 564 if (dev->dvb.frontend != NULL) {
564 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 565 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
565 &dev->core->i2c_adap, 0x61, 566 &core->i2c_adap, 0x61,
566 TUNER_PHILIPS_FMD1216ME_MK3); 567 TUNER_PHILIPS_FMD1216ME_MK3))
568 goto frontend_detach;
567 } 569 }
568 break; 570 break;
569 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 571 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
570 dev->dvb.frontend = dvb_attach(mt352_attach, 572 dev->dvb.frontend = dvb_attach(mt352_attach,
571 &dvico_fusionhdtv, 573 &dvico_fusionhdtv,
572 &dev->core->i2c_adap); 574 &core->i2c_adap);
573 if (dev->dvb.frontend != NULL) { 575 if (dev->dvb.frontend != NULL) {
574 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, 576 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
575 NULL, DVB_PLL_THOMSON_DTT7579); 577 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
578 goto frontend_detach;
576 break; 579 break;
577 } 580 }
578 /* ZL10353 replaces MT352 on later cards */ 581 /* ZL10353 replaces MT352 on later cards */
579 dev->dvb.frontend = dvb_attach(zl10353_attach, 582 dev->dvb.frontend = dvb_attach(zl10353_attach,
580 &dvico_fusionhdtv_plus_v1_1, 583 &dvico_fusionhdtv_plus_v1_1,
581 &dev->core->i2c_adap); 584 &core->i2c_adap);
582 if (dev->dvb.frontend != NULL) { 585 if (dev->dvb.frontend != NULL) {
583 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, 586 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
584 NULL, DVB_PLL_THOMSON_DTT7579); 587 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
588 goto frontend_detach;
585 } 589 }
586 break; 590 break;
587 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: 591 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
@@ -589,28 +593,31 @@ static int dvb_register(struct cx8802_dev *dev)
589 * compatible, with a slightly different MT352 AGC gain. */ 593 * compatible, with a slightly different MT352 AGC gain. */
590 dev->dvb.frontend = dvb_attach(mt352_attach, 594 dev->dvb.frontend = dvb_attach(mt352_attach,
591 &dvico_fusionhdtv_dual, 595 &dvico_fusionhdtv_dual,
592 &dev->core->i2c_adap); 596 &core->i2c_adap);
593 if (dev->dvb.frontend != NULL) { 597 if (dev->dvb.frontend != NULL) {
594 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, 598 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
595 NULL, DVB_PLL_THOMSON_DTT7579); 599 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
600 goto frontend_detach;
596 break; 601 break;
597 } 602 }
598 /* ZL10353 replaces MT352 on later cards */ 603 /* ZL10353 replaces MT352 on later cards */
599 dev->dvb.frontend = dvb_attach(zl10353_attach, 604 dev->dvb.frontend = dvb_attach(zl10353_attach,
600 &dvico_fusionhdtv_plus_v1_1, 605 &dvico_fusionhdtv_plus_v1_1,
601 &dev->core->i2c_adap); 606 &core->i2c_adap);
602 if (dev->dvb.frontend != NULL) { 607 if (dev->dvb.frontend != NULL) {
603 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, 608 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
604 NULL, DVB_PLL_THOMSON_DTT7579); 609 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
610 goto frontend_detach;
605 } 611 }
606 break; 612 break;
607 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 613 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
608 dev->dvb.frontend = dvb_attach(mt352_attach, 614 dev->dvb.frontend = dvb_attach(mt352_attach,
609 &dvico_fusionhdtv, 615 &dvico_fusionhdtv,
610 &dev->core->i2c_adap); 616 &core->i2c_adap);
611 if (dev->dvb.frontend != NULL) { 617 if (dev->dvb.frontend != NULL) {
612 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, 618 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
613 NULL, DVB_PLL_LG_Z201); 619 0x61, NULL, DVB_PLL_LG_Z201))
620 goto frontend_detach;
614 } 621 }
615 break; 622 break;
616 case CX88_BOARD_KWORLD_DVB_T: 623 case CX88_BOARD_KWORLD_DVB_T:
@@ -618,10 +625,11 @@ static int dvb_register(struct cx8802_dev *dev)
618 case CX88_BOARD_ADSTECH_DVB_T_PCI: 625 case CX88_BOARD_ADSTECH_DVB_T_PCI:
619 dev->dvb.frontend = dvb_attach(mt352_attach, 626 dev->dvb.frontend = dvb_attach(mt352_attach,
620 &dntv_live_dvbt_config, 627 &dntv_live_dvbt_config,
621 &dev->core->i2c_adap); 628 &core->i2c_adap);
622 if (dev->dvb.frontend != NULL) { 629 if (dev->dvb.frontend != NULL) {
623 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, 630 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
624 NULL, DVB_PLL_UNKNOWN_1); 631 0x61, NULL, DVB_PLL_UNKNOWN_1))
632 goto frontend_detach;
625 } 633 }
626 break; 634 break;
627 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 635 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
@@ -630,32 +638,35 @@ static int dvb_register(struct cx8802_dev *dev)
630 dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, 638 dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
631 &dev->vp3054->adap); 639 &dev->vp3054->adap);
632 if (dev->dvb.frontend != NULL) { 640 if (dev->dvb.frontend != NULL) {
633 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 641 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
634 &dev->core->i2c_adap, 0x61, 642 &core->i2c_adap, 0x61,
635 TUNER_PHILIPS_FMD1216ME_MK3); 643 TUNER_PHILIPS_FMD1216ME_MK3))
644 goto frontend_detach;
636 } 645 }
637#else 646#else
638 printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name); 647 printk(KERN_ERR "%s/2: built without vp3054 support\n",
648 core->name);
639#endif 649#endif
640 break; 650 break;
641 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: 651 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
642 dev->dvb.frontend = dvb_attach(zl10353_attach, 652 dev->dvb.frontend = dvb_attach(zl10353_attach,
643 &dvico_fusionhdtv_hybrid, 653 &dvico_fusionhdtv_hybrid,
644 &dev->core->i2c_adap); 654 &core->i2c_adap);
645 if (dev->dvb.frontend != NULL) { 655 if (dev->dvb.frontend != NULL) {
646 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 656 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
647 &dev->core->i2c_adap, 0x61, 657 &core->i2c_adap, 0x61,
648 TUNER_THOMSON_FE6600); 658 TUNER_THOMSON_FE6600))
659 goto frontend_detach;
649 } 660 }
650 break; 661 break;
651 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 662 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
652 dev->dvb.frontend = dvb_attach(zl10353_attach, 663 dev->dvb.frontend = dvb_attach(zl10353_attach,
653 &dvico_fusionhdtv_xc3028, 664 &dvico_fusionhdtv_xc3028,
654 &dev->core->i2c_adap); 665 &core->i2c_adap);
655 if (dev->dvb.frontend == NULL) 666 if (dev->dvb.frontend == NULL)
656 dev->dvb.frontend = dvb_attach(mt352_attach, 667 dev->dvb.frontend = dvb_attach(mt352_attach,
657 &dvico_fusionhdtv_mt352_xc3028, 668 &dvico_fusionhdtv_mt352_xc3028,
658 &dev->core->i2c_adap); 669 &core->i2c_adap);
659 /* 670 /*
660 * On this board, the demod provides the I2C bus pullup. 671 * On this board, the demod provides the I2C bus pullup.
661 * We must not permit gate_ctrl to be performed, or 672 * We must not permit gate_ctrl to be performed, or
@@ -668,19 +679,18 @@ static int dvb_register(struct cx8802_dev *dev)
668 break; 679 break;
669 case CX88_BOARD_PCHDTV_HD3000: 680 case CX88_BOARD_PCHDTV_HD3000:
670 dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, 681 dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
671 &dev->core->i2c_adap); 682 &core->i2c_adap);
672 if (dev->dvb.frontend != NULL) { 683 if (dev->dvb.frontend != NULL) {
673 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 684 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
674 &dev->core->i2c_adap, 0x61, 685 &core->i2c_adap, 0x61,
675 TUNER_THOMSON_DTT761X); 686 TUNER_THOMSON_DTT761X))
687 goto frontend_detach;
676 } 688 }
677 break; 689 break;
678 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: 690 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
679 dev->ts_gen_cntrl = 0x08; 691 dev->ts_gen_cntrl = 0x08;
680 {
681 /* Do a hardware reset of chip before using it. */
682 struct cx88_core *core = dev->core;
683 692
693 /* Do a hardware reset of chip before using it. */
684 cx_clear(MO_GP0_IO, 1); 694 cx_clear(MO_GP0_IO, 1);
685 mdelay(100); 695 mdelay(100);
686 cx_set(MO_GP0_IO, 1); 696 cx_set(MO_GP0_IO, 1);
@@ -690,139 +700,138 @@ static int dvb_register(struct cx8802_dev *dev)
690 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; 700 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
691 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 701 dev->dvb.frontend = dvb_attach(lgdt330x_attach,
692 &fusionhdtv_3_gold, 702 &fusionhdtv_3_gold,
693 &dev->core->i2c_adap); 703 &core->i2c_adap);
694 if (dev->dvb.frontend != NULL) { 704 if (dev->dvb.frontend != NULL) {
695 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 705 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
696 &dev->core->i2c_adap, 0x61, 706 &core->i2c_adap, 0x61,
697 TUNER_MICROTUNE_4042FI5); 707 TUNER_MICROTUNE_4042FI5))
698 } 708 goto frontend_detach;
699 } 709 }
700 break; 710 break;
701 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: 711 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
702 dev->ts_gen_cntrl = 0x08; 712 dev->ts_gen_cntrl = 0x08;
703 {
704 /* Do a hardware reset of chip before using it. */
705 struct cx88_core *core = dev->core;
706 713
714 /* Do a hardware reset of chip before using it. */
707 cx_clear(MO_GP0_IO, 1); 715 cx_clear(MO_GP0_IO, 1);
708 mdelay(100); 716 mdelay(100);
709 cx_set(MO_GP0_IO, 9); 717 cx_set(MO_GP0_IO, 9);
710 mdelay(200); 718 mdelay(200);
711 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 719 dev->dvb.frontend = dvb_attach(lgdt330x_attach,
712 &fusionhdtv_3_gold, 720 &fusionhdtv_3_gold,
713 &dev->core->i2c_adap); 721 &core->i2c_adap);
714 if (dev->dvb.frontend != NULL) { 722 if (dev->dvb.frontend != NULL) {
715 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 723 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
716 &dev->core->i2c_adap, 0x61, 724 &core->i2c_adap, 0x61,
717 TUNER_THOMSON_DTT761X); 725 TUNER_THOMSON_DTT761X))
718 } 726 goto frontend_detach;
719 } 727 }
720 break; 728 break;
721 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 729 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
722 dev->ts_gen_cntrl = 0x08; 730 dev->ts_gen_cntrl = 0x08;
723 {
724 /* Do a hardware reset of chip before using it. */
725 struct cx88_core *core = dev->core;
726 731
732 /* Do a hardware reset of chip before using it. */
727 cx_clear(MO_GP0_IO, 1); 733 cx_clear(MO_GP0_IO, 1);
728 mdelay(100); 734 mdelay(100);
729 cx_set(MO_GP0_IO, 1); 735 cx_set(MO_GP0_IO, 1);
730 mdelay(200); 736 mdelay(200);
731 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 737 dev->dvb.frontend = dvb_attach(lgdt330x_attach,
732 &fusionhdtv_5_gold, 738 &fusionhdtv_5_gold,
733 &dev->core->i2c_adap); 739 &core->i2c_adap);
734 if (dev->dvb.frontend != NULL) { 740 if (dev->dvb.frontend != NULL) {
735 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 741 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
736 &dev->core->i2c_adap, 0x61, 742 &core->i2c_adap, 0x61,
737 TUNER_LG_TDVS_H06XF); 743 TUNER_LG_TDVS_H06XF))
738 dvb_attach(tda9887_attach, dev->dvb.frontend, 744 goto frontend_detach;
739 &dev->core->i2c_adap, 0x43); 745 if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
740 } 746 &core->i2c_adap, 0x43))
747 goto frontend_detach;
741 } 748 }
742 break; 749 break;
743 case CX88_BOARD_PCHDTV_HD5500: 750 case CX88_BOARD_PCHDTV_HD5500:
744 dev->ts_gen_cntrl = 0x08; 751 dev->ts_gen_cntrl = 0x08;
745 {
746 /* Do a hardware reset of chip before using it. */
747 struct cx88_core *core = dev->core;
748 752
753 /* Do a hardware reset of chip before using it. */
749 cx_clear(MO_GP0_IO, 1); 754 cx_clear(MO_GP0_IO, 1);
750 mdelay(100); 755 mdelay(100);
751 cx_set(MO_GP0_IO, 1); 756 cx_set(MO_GP0_IO, 1);
752 mdelay(200); 757 mdelay(200);
753 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 758 dev->dvb.frontend = dvb_attach(lgdt330x_attach,
754 &pchdtv_hd5500, 759 &pchdtv_hd5500,
755 &dev->core->i2c_adap); 760 &core->i2c_adap);
756 if (dev->dvb.frontend != NULL) { 761 if (dev->dvb.frontend != NULL) {
757 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 762 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
758 &dev->core->i2c_adap, 0x61, 763 &core->i2c_adap, 0x61,
759 TUNER_LG_TDVS_H06XF); 764 TUNER_LG_TDVS_H06XF))
760 dvb_attach(tda9887_attach, dev->dvb.frontend, 765 goto frontend_detach;
761 &dev->core->i2c_adap, 0x43); 766 if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
762 } 767 &core->i2c_adap, 0x43))
768 goto frontend_detach;
763 } 769 }
764 break; 770 break;
765 case CX88_BOARD_ATI_HDTVWONDER: 771 case CX88_BOARD_ATI_HDTVWONDER:
766 dev->dvb.frontend = dvb_attach(nxt200x_attach, 772 dev->dvb.frontend = dvb_attach(nxt200x_attach,
767 &ati_hdtvwonder, 773 &ati_hdtvwonder,
768 &dev->core->i2c_adap); 774 &core->i2c_adap);
769 if (dev->dvb.frontend != NULL) { 775 if (dev->dvb.frontend != NULL) {
770 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 776 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
771 &dev->core->i2c_adap, 0x61, 777 &core->i2c_adap, 0x61,
772 TUNER_PHILIPS_TUV1236D); 778 TUNER_PHILIPS_TUV1236D))
779 goto frontend_detach;
773 } 780 }
774 break; 781 break;
775 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 782 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
776 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 783 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
777 dev->dvb.frontend = dvb_attach(cx24123_attach, 784 dev->dvb.frontend = dvb_attach(cx24123_attach,
778 &hauppauge_novas_config, 785 &hauppauge_novas_config,
779 &dev->core->i2c_adap); 786 &core->i2c_adap);
780 if (dev->dvb.frontend) { 787 if (dev->dvb.frontend) {
781 dvb_attach(isl6421_attach, dev->dvb.frontend, 788 if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
782 &dev->core->i2c_adap, 0x08, 0x00, 0x00); 789 &core->i2c_adap, 0x08, 0x00, 0x00))
790 goto frontend_detach;
783 } 791 }
784 break; 792 break;
785 case CX88_BOARD_KWORLD_DVBS_100: 793 case CX88_BOARD_KWORLD_DVBS_100:
786 dev->dvb.frontend = dvb_attach(cx24123_attach, 794 dev->dvb.frontend = dvb_attach(cx24123_attach,
787 &kworld_dvbs_100_config, 795 &kworld_dvbs_100_config,
788 &dev->core->i2c_adap); 796 &core->i2c_adap);
789 if (dev->dvb.frontend) { 797 if (dev->dvb.frontend) {
790 dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 798 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
791 dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; 799 dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
792 } 800 }
793 break; 801 break;
794 case CX88_BOARD_GENIATECH_DVBS: 802 case CX88_BOARD_GENIATECH_DVBS:
795 dev->dvb.frontend = dvb_attach(cx24123_attach, 803 dev->dvb.frontend = dvb_attach(cx24123_attach,
796 &geniatech_dvbs_config, 804 &geniatech_dvbs_config,
797 &dev->core->i2c_adap); 805 &core->i2c_adap);
798 if (dev->dvb.frontend) { 806 if (dev->dvb.frontend) {
799 dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 807 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
800 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; 808 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
801 } 809 }
802 break; 810 break;
803 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 811 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
804 dev->dvb.frontend = dvb_attach(s5h1409_attach, 812 dev->dvb.frontend = dvb_attach(s5h1409_attach,
805 &pinnacle_pctv_hd_800i_config, 813 &pinnacle_pctv_hd_800i_config,
806 &dev->core->i2c_adap); 814 &core->i2c_adap);
807 if (dev->dvb.frontend != NULL) { 815 if (dev->dvb.frontend != NULL) {
808 /* tuner_config.video_dev must point to 816 /* tuner_config.video_dev must point to
809 * i2c_adap.algo_data 817 * i2c_adap.algo_data
810 */ 818 */
811 pinnacle_pctv_hd_800i_tuner_config.priv = 819 pinnacle_pctv_hd_800i_tuner_config.priv =
812 dev->core->i2c_adap.algo_data; 820 core->i2c_adap.algo_data;
813 dvb_attach(xc5000_attach, dev->dvb.frontend, 821 if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
814 &dev->core->i2c_adap, 822 &core->i2c_adap,
815 &pinnacle_pctv_hd_800i_tuner_config); 823 &pinnacle_pctv_hd_800i_tuner_config))
824 goto frontend_detach;
816 } 825 }
817 break; 826 break;
818 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: 827 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
819 dev->dvb.frontend = dvb_attach(s5h1409_attach, 828 dev->dvb.frontend = dvb_attach(s5h1409_attach,
820 &dvico_hdtv5_pci_nano_config, 829 &dvico_hdtv5_pci_nano_config,
821 &dev->core->i2c_adap); 830 &core->i2c_adap);
822 if (dev->dvb.frontend != NULL) { 831 if (dev->dvb.frontend != NULL) {
823 struct dvb_frontend *fe; 832 struct dvb_frontend *fe;
824 struct xc2028_config cfg = { 833 struct xc2028_config cfg = {
825 .i2c_adap = &dev->core->i2c_adap, 834 .i2c_adap = &core->i2c_adap,
826 .i2c_addr = 0x61, 835 .i2c_addr = 0x61,
827 .callback = cx88_pci_nano_callback, 836 .callback = cx88_pci_nano_callback,
828 }; 837 };
@@ -841,50 +850,51 @@ static int dvb_register(struct cx8802_dev *dev)
841 case CX88_BOARD_PINNACLE_HYBRID_PCTV: 850 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
842 dev->dvb.frontend = dvb_attach(zl10353_attach, 851 dev->dvb.frontend = dvb_attach(zl10353_attach,
843 &cx88_geniatech_x8000_mt, 852 &cx88_geniatech_x8000_mt,
844 &dev->core->i2c_adap); 853 &core->i2c_adap);
845 if (attach_xc3028(0x61, dev) < 0) 854 if (attach_xc3028(0x61, dev) < 0)
846 return -EINVAL; 855 goto frontend_detach;
847 break; 856 break;
848 case CX88_BOARD_GENIATECH_X8000_MT: 857 case CX88_BOARD_GENIATECH_X8000_MT:
849 dev->ts_gen_cntrl = 0x00; 858 dev->ts_gen_cntrl = 0x00;
850 859
851 dev->dvb.frontend = dvb_attach(zl10353_attach, 860 dev->dvb.frontend = dvb_attach(zl10353_attach,
852 &cx88_geniatech_x8000_mt, 861 &cx88_geniatech_x8000_mt,
853 &dev->core->i2c_adap); 862 &core->i2c_adap);
854 if (attach_xc3028(0x61, dev) < 0) 863 if (attach_xc3028(0x61, dev) < 0)
855 return -EINVAL; 864 goto frontend_detach;
856 break; 865 break;
857 case CX88_BOARD_KWORLD_ATSC_120: 866 case CX88_BOARD_KWORLD_ATSC_120:
858 dev->dvb.frontend = dvb_attach(s5h1409_attach, 867 dev->dvb.frontend = dvb_attach(s5h1409_attach,
859 &kworld_atsc_120_config, 868 &kworld_atsc_120_config,
860 &dev->core->i2c_adap); 869 &core->i2c_adap);
861 if (attach_xc3028(0x61, dev) < 0) 870 if (attach_xc3028(0x61, dev) < 0)
862 return -EINVAL; 871 goto frontend_detach;
863 break; 872 break;
864 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: 873 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
865 dev->dvb.frontend = dvb_attach(s5h1411_attach, 874 dev->dvb.frontend = dvb_attach(s5h1411_attach,
866 &dvico_fusionhdtv7_config, 875 &dvico_fusionhdtv7_config,
867 &dev->core->i2c_adap); 876 &core->i2c_adap);
868 if (dev->dvb.frontend != NULL) { 877 if (dev->dvb.frontend != NULL) {
869 /* tuner_config.video_dev must point to 878 /* tuner_config.video_dev must point to
870 * i2c_adap.algo_data 879 * i2c_adap.algo_data
871 */ 880 */
872 dvico_fusionhdtv7_tuner_config.priv = 881 dvico_fusionhdtv7_tuner_config.priv =
873 dev->core->i2c_adap.algo_data; 882 core->i2c_adap.algo_data;
874 dvb_attach(xc5000_attach, dev->dvb.frontend, 883 if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
875 &dev->core->i2c_adap, 884 &core->i2c_adap,
876 &dvico_fusionhdtv7_tuner_config); 885 &dvico_fusionhdtv7_tuner_config))
886 goto frontend_detach;
877 } 887 }
878 break; 888 break;
879 default: 889 default:
880 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 890 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
881 dev->core->name); 891 core->name);
882 break; 892 break;
883 } 893 }
884 if (NULL == dev->dvb.frontend) { 894 if (NULL == dev->dvb.frontend) {
885 printk(KERN_ERR 895 printk(KERN_ERR
886 "%s/2: frontend initialization failed\n", 896 "%s/2: frontend initialization failed\n",
887 dev->core->name); 897 core->name);
888 return -EINVAL; 898 return -EINVAL;
889 } 899 }
890 900
@@ -892,11 +902,18 @@ static int dvb_register(struct cx8802_dev *dev)
892 dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 902 dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
893 903
894 /* Put the analog decoder in standby to keep it quiet */ 904 /* Put the analog decoder in standby to keep it quiet */
895 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 905 cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
896 906
897 /* register everything */ 907 /* register everything */
898 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, 908 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
899 &dev->pci->dev, adapter_nr); 909 &dev->pci->dev, adapter_nr);
910
911frontend_detach:
912 if (dev->dvb.frontend) {
913 dvb_frontend_detach(dev->dvb.frontend);
914 dev->dvb.frontend = NULL;
915 }
916 return -EINVAL;
900} 917}
901 918
902/* ----------------------------------------------------------- */ 919/* ----------------------------------------------------------- */