diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-30 17:14:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-05-14 01:53:59 -0400 |
commit | 0590d91c413fb5144608d69f50710064360aeec8 (patch) | |
tree | 2463f92e8957f3f901361690017081759d4a20f8 /drivers | |
parent | 6430a5a368208ae6c4bcd13e1f06460c96af66be (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.c | 251 |
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 | ||
524 | static int dvb_register(struct cx8802_dev *dev) | 521 | static 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 | |||
911 | frontend_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 | /* ----------------------------------------------------------- */ |