diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-driver.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 86 |
1 files changed, 39 insertions, 47 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index f5a41dd663dc..edbb83c4c564 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -269,11 +269,16 @@ static void cx18_iounmap(struct cx18 *cx) | |||
269 | /* Hauppauge card? get values from tveeprom */ | 269 | /* Hauppauge card? get values from tveeprom */ |
270 | void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) | 270 | void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) |
271 | { | 271 | { |
272 | struct i2c_client c; | ||
272 | u8 eedata[256]; | 273 | u8 eedata[256]; |
273 | 274 | ||
274 | cx->i2c_client[0].addr = 0xA0 >> 1; | 275 | strncpy(c.name, "cx18 tveeprom tmp", sizeof(c.name)); |
275 | tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata)); | 276 | c.name[sizeof(c.name)-1] = '\0'; |
276 | tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata); | 277 | c.adapter = &cx->i2c_adap[0]; |
278 | c.addr = 0xA0 >> 1; | ||
279 | |||
280 | tveeprom_read(&c, eedata, sizeof(eedata)); | ||
281 | tveeprom_hauppauge_analog(&c, tv, eedata); | ||
277 | } | 282 | } |
278 | 283 | ||
279 | static void cx18_process_eeprom(struct cx18 *cx) | 284 | static void cx18_process_eeprom(struct cx18 *cx) |
@@ -553,8 +558,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
553 | cx->base_addr = pci_resource_start(cx->pci_dev, 0); | 558 | cx->base_addr = pci_resource_start(cx->pci_dev, 0); |
554 | 559 | ||
555 | mutex_init(&cx->serialize_lock); | 560 | mutex_init(&cx->serialize_lock); |
556 | mutex_init(&cx->i2c_bus_lock[0]); | ||
557 | mutex_init(&cx->i2c_bus_lock[1]); | ||
558 | mutex_init(&cx->gpio_lock); | 561 | mutex_init(&cx->gpio_lock); |
559 | mutex_init(&cx->epu2apu_mb_lock); | 562 | mutex_init(&cx->epu2apu_mb_lock); |
560 | mutex_init(&cx->epu2cpu_mb_lock); | 563 | mutex_init(&cx->epu2cpu_mb_lock); |
@@ -669,54 +672,41 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, | |||
669 | return 0; | 672 | return 0; |
670 | } | 673 | } |
671 | 674 | ||
672 | #ifdef MODULE | 675 | static void cx18_init_subdevs(struct cx18 *cx) |
673 | static u32 cx18_request_module(struct cx18 *cx, u32 hw, | ||
674 | const char *name, u32 id) | ||
675 | { | ||
676 | if ((hw & id) == 0) | ||
677 | return hw; | ||
678 | if (request_module("%s", name) != 0) { | ||
679 | CX18_ERR("Failed to load module %s\n", name); | ||
680 | return hw & ~id; | ||
681 | } | ||
682 | CX18_DEBUG_INFO("Loaded module %s\n", name); | ||
683 | return hw; | ||
684 | } | ||
685 | #endif | ||
686 | |||
687 | static void cx18_load_and_init_modules(struct cx18 *cx) | ||
688 | { | 676 | { |
689 | u32 hw = cx->card->hw_all; | 677 | u32 hw = cx->card->hw_all; |
678 | u32 device; | ||
690 | int i; | 679 | int i; |
691 | 680 | ||
692 | #ifdef MODULE | 681 | for (i = 0, device = 1; i < 32; i++, device <<= 1) { |
693 | /* load modules */ | ||
694 | #ifdef CONFIG_MEDIA_TUNER_MODULE | ||
695 | hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); | ||
696 | #endif | ||
697 | #ifdef CONFIG_VIDEO_CS5345_MODULE | ||
698 | hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); | ||
699 | #endif | ||
700 | #endif | ||
701 | |||
702 | /* check which i2c devices are actually found */ | ||
703 | for (i = 0; i < 32; i++) { | ||
704 | u32 device = 1 << i; | ||
705 | 682 | ||
706 | if (!(device & hw)) | 683 | if (!(device & hw)) |
707 | continue; | 684 | continue; |
708 | if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM || | 685 | |
709 | device == CX18_HW_CX23418 || device == CX18_HW_DVB) { | 686 | switch (device) { |
710 | /* These 'devices' do not use i2c probing */ | 687 | case CX18_HW_GPIO_AUDIO_MUX: |
688 | case CX18_HW_DVB: | ||
689 | case CX18_HW_TVEEPROM: | ||
690 | /* These subordinate devices do not use probing */ | ||
711 | cx->hw_flags |= device; | 691 | cx->hw_flags |= device; |
712 | continue; | 692 | break; |
713 | } | 693 | case CX18_HW_418_AV: |
714 | cx18_i2c_register(cx, i); | 694 | /* The A/V decoder gets probed earlier to set PLLs */ |
715 | if (cx18_i2c_hw_addr(cx, device) > 0) | 695 | /* Just note that the card uses it (i.e. has analog) */ |
716 | cx->hw_flags |= device; | 696 | cx->hw_flags |= device; |
697 | break; | ||
698 | default: | ||
699 | if (cx18_i2c_register(cx, i) == 0) | ||
700 | cx->hw_flags |= device; | ||
701 | break; | ||
702 | } | ||
717 | } | 703 | } |
718 | 704 | ||
719 | hw = cx->hw_flags; | 705 | if (cx->hw_flags & CX18_HW_418_AV) |
706 | cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV); | ||
707 | |||
708 | if (cx->card->hw_muxer != 0) | ||
709 | cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer); | ||
720 | } | 710 | } |
721 | 711 | ||
722 | static int __devinit cx18_probe(struct pci_dev *pci_dev, | 712 | static int __devinit cx18_probe(struct pci_dev *pci_dev, |
@@ -803,15 +793,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
803 | cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET); | 793 | cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET); |
804 | cx18_init_scb(cx); | 794 | cx18_init_scb(cx); |
805 | 795 | ||
796 | /* Initialize GPIO early so I2C device resets can be performed */ | ||
806 | cx18_gpio_init(cx); | 797 | cx18_gpio_init(cx); |
807 | 798 | ||
808 | retval = cx18_av_probe(cx, &cx->sd_av); | 799 | /* Initialize integrated A/V decoder early to set PLLs, just in case */ |
800 | retval = cx18_av_probe(cx); | ||
809 | if (retval) { | 801 | if (retval) { |
810 | CX18_ERR("Could not register A/V decoder subdevice\n"); | 802 | CX18_ERR("Could not register A/V decoder subdevice\n"); |
811 | goto free_map; | 803 | goto free_map; |
812 | } | 804 | } |
813 | /* Initialize the A/V decoder PLLs to sane defaults */ | 805 | /* Initialize the A/V decoder PLLs to sane defaults */ |
814 | v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_PLLS); | 806 | cx18_call_hw(cx, CX18_HW_418_AV, core, init, (u32) CX18_AV_INIT_PLLS); |
815 | 807 | ||
816 | /* active i2c */ | 808 | /* active i2c */ |
817 | CX18_DEBUG_INFO("activating i2c...\n"); | 809 | CX18_DEBUG_INFO("activating i2c...\n"); |
@@ -873,7 +865,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
873 | initialization. */ | 865 | initialization. */ |
874 | cx18_init_struct2(cx); | 866 | cx18_init_struct2(cx); |
875 | 867 | ||
876 | cx18_load_and_init_modules(cx); | 868 | cx18_init_subdevs(cx); |
877 | 869 | ||
878 | if (cx->std & V4L2_STD_525_60) { | 870 | if (cx->std & V4L2_STD_525_60) { |
879 | cx->is_60hz = 1; | 871 | cx->is_60hz = 1; |
@@ -895,7 +887,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
895 | setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ | 887 | setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ |
896 | setup.tuner_callback = (setup.type == TUNER_XC2028) ? | 888 | setup.tuner_callback = (setup.type == TUNER_XC2028) ? |
897 | cx18_reset_tuner_gpio : NULL; | 889 | cx18_reset_tuner_gpio : NULL; |
898 | cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup); | 890 | cx18_call_all(cx, tuner, s_type_addr, &setup); |
899 | if (setup.type == TUNER_XC2028) { | 891 | if (setup.type == TUNER_XC2028) { |
900 | static struct xc2028_ctrl ctrl = { | 892 | static struct xc2028_ctrl ctrl = { |
901 | .fname = XC2028_DEFAULT_FIRMWARE, | 893 | .fname = XC2028_DEFAULT_FIRMWARE, |
@@ -905,7 +897,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
905 | .tuner = cx->options.tuner, | 897 | .tuner = cx->options.tuner, |
906 | .priv = &ctrl, | 898 | .priv = &ctrl, |
907 | }; | 899 | }; |
908 | cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg); | 900 | cx18_call_all(cx, tuner, s_config, &cfg); |
909 | } | 901 | } |
910 | } | 902 | } |
911 | 903 | ||