diff options
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-dvb.c')
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-dvb.c | 200 |
1 files changed, 107 insertions, 93 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index 1a0f971c6..5a9fafd25 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -121,7 +121,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe); if (!fe_id) { - printk(KERN_ERR "%s() No frontend found\n", __FUNCTION__); + printk(KERN_ERR "%s() No frontend found\n", __func__); return -EINVAL; } @@ -582,14 +582,14 @@ static struct cx24116_config tevii_s460_config = { static struct stv0299_config tevii_tuner_sharp_config = { .demod_address = 0x68, - .inittab = sharp_z0194a__inittab, + .inittab = sharp_z0194a_inittab, .mclk = 88000000UL, .invert = 1, .skip_reinit = 0, .lock_output = 1, .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, - .set_symbol_rate = sharp_z0194a__set_symbol_rate, + .set_symbol_rate = sharp_z0194a_set_symbol_rate, .set_ts_params = cx24116_set_ts_param, }; @@ -605,10 +605,15 @@ static int dvb_register(struct cx8802_dev *dev) struct videobuf_dvb_frontend *fe0, *fe1 = NULL; int mfe_shared = 0; /* bus not shared by default */ + if (0 != core->i2c_rc) { + printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); + goto frontend_detach; + } + /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); if (!fe0) - return -EINVAL; + goto frontend_detach; /* multi-frontend gate control is undefined or defaults to fe0 */ dev->frontends.gate = 0; @@ -655,38 +660,35 @@ static int dvb_register(struct cx8802_dev *dev) } break; case CX88_BOARD_HAUPPAUGE_HVR3000: + /* MFE frontend 1 */ + mfe_shared = 1; + dev->frontends.gate = 2; /* DVB-S init */ fe0->dvb.frontend = dvb_attach(cx24123_attach, - &hauppauge_novas_config, - &dev->core->i2c_adap); + &hauppauge_novas_config, + &dev->core->i2c_adap); if (fe0->dvb.frontend) { - if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, - &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { - dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __FUNCTION__); - } - } else { - dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __FUNCTION__); + if (!dvb_attach(isl6421_attach, + fe0->dvb.frontend, + &dev->core->i2c_adap, + 0x08, ISL6421_DCL, 0x00)) + goto frontend_detach; } - /* DVB-T init */ + /* MFE frontend 2 */ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); - if (fe1) { - dev->frontends.gate = 2; - mfe_shared = 1; - fe1->dvb.frontend = dvb_attach(cx22702_attach, - &hauppauge_hvr_config, - &dev->core->i2c_adap); - if (fe1->dvb.frontend) { - fe1->dvb.frontend->id = 1; - if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3)) { - dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __FUNCTION__); - } - } else { - dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __FUNCTION__); - } - } else { - dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__); + if (!fe1) + goto frontend_detach; + /* DVB-T init */ + fe1->dvb.frontend = dvb_attach(cx22702_attach, + &hauppauge_hvr_config, + &dev->core->i2c_adap); + if (fe1->dvb.frontend) { + fe1->dvb.frontend->id = 1; + if (!dvb_attach(simple_tuner_attach, + fe1->dvb.frontend, + &dev->core->i2c_adap, + 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: @@ -796,7 +798,7 @@ static int dvb_register(struct cx8802_dev *dev) if (fe0->dvb.frontend) fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) - return -EINVAL; + goto frontend_detach; break; case CX88_BOARD_PCHDTV_HD3000: fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, @@ -1000,50 +1002,51 @@ static int dvb_register(struct cx8802_dev *dev) } break; case CX88_BOARD_HAUPPAUGE_HVR4000: + /* MFE frontend 1 */ + mfe_shared = 1; + dev->frontends.gate = 2; /* DVB-S/S2 Init */ fe0->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &dev->core->i2c_adap); + &hauppauge_hvr4000_config, + &dev->core->i2c_adap); if (fe0->dvb.frontend) { - if(!dvb_attach(isl6421_attach, fe0->dvb.frontend, - &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { - dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __FUNCTION__); - } - } else { - dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __FUNCTION__); + if (!dvb_attach(isl6421_attach, + fe0->dvb.frontend, + &dev->core->i2c_adap, + 0x08, ISL6421_DCL, 0x00)) + goto frontend_detach; } - /* DVB-T Init */ + /* MFE frontend 2 */ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); - if (fe1) { - dev->frontends.gate = 2; - mfe_shared = 1; - fe1->dvb.frontend = dvb_attach(cx22702_attach, - &hauppauge_hvr_config, - &dev->core->i2c_adap); - if (fe1->dvb.frontend) { - fe1->dvb.frontend->id = 1; - if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3)) { - dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __FUNCTION__); - } - } else { - dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __FUNCTION__); - } - } else { - dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__); + if (!fe1) + goto frontend_detach; + /* DVB-T Init */ + fe1->dvb.frontend = dvb_attach(cx22702_attach, + &hauppauge_hvr_config, + &dev->core->i2c_adap); + if (fe1->dvb.frontend) { + fe1->dvb.frontend->id = 1; + if (!dvb_attach(simple_tuner_attach, + fe1->dvb.frontend, + &dev->core->i2c_adap, + 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) + goto frontend_detach; } break; case CX88_BOARD_HAUPPAUGE_HVR4000LITE: fe0->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &dev->core->i2c_adap); + &hauppauge_hvr4000_config, + &dev->core->i2c_adap); if (fe0->dvb.frontend) { - dvb_attach(isl6421_attach, fe0->dvb.frontend, - &dev->core->i2c_adap, - 0x08, ISL6421_DCL, 0x00); + if (!dvb_attach(isl6421_attach, + fe0->dvb.frontend, + &dev->core->i2c_adap, + 0x08, ISL6421_DCL, 0x00)) + goto frontend_detach; } break; + case CX88_BOARD_PROF_6200: + case CX88_BOARD_TBS_8910: case CX88_BOARD_TEVII_S420: fe0->dvb.frontend = dvb_attach(stv0299_attach, &tevii_tuner_sharp_config, @@ -1065,7 +1068,6 @@ static int dvb_register(struct cx8802_dev *dev) goto frontend_detach; core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - } } break; @@ -1073,21 +1075,18 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(cx24116_attach, &tevii_s460_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; + if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - } break; case CX88_BOARD_OMICOM_SS4_PCI: case CX88_BOARD_TBS_8920: case CX88_BOARD_PROF_7300: + case CX88_BOARD_SATTRADE_ST4200: fe0->dvb.frontend = dvb_attach(cx24116_attach, &hauppauge_hvr4000_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; + if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", @@ -1099,7 +1098,7 @@ static int dvb_register(struct cx8802_dev *dev) printk(KERN_ERR "%s/2: frontend initialization failed\n", core->name); - return -EINVAL; + goto frontend_detach; } /* define general-purpose callback pointer */ fe0->dvb.frontend->callback = cx88_tuner_callback; @@ -1117,10 +1116,7 @@ static int dvb_register(struct cx8802_dev *dev) &dev->pci->dev, adapter_nr, mfe_shared); frontend_detach: - if (fe0->dvb.frontend) { - dvb_frontend_detach(fe0->dvb.frontend); - fe0->dvb.frontend = NULL; - } + videobuf_dvb_dealloc_frontends(&dev->frontends); return -EINVAL; } @@ -1208,8 +1204,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; - int err, i; - struct videobuf_dvb_frontend *fe; + int err; dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", @@ -1225,39 +1220,58 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) /* If vp3054 isn't enabled, a stub will just return 0 */ err = vp3054_i2c_probe(dev); if (0 != err) - goto fail_core; + goto fail_probe; /* dvb stuff */ printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); dev->ts_gen_cntrl = 0x0c; - for (i = 1; i <= core->board.num_frontends; i++) { - fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); - if (!fe) { - printk(KERN_ERR "%s() failed to get frontend(%d)\n", __FUNCTION__, i); - continue; + err = -ENODEV; + if (core->board.num_frontends) { + struct videobuf_dvb_frontend *fe; + int i; + + for (i = 1; i <= core->board.num_frontends; i++) { + fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); + if (fe == NULL) { + printk(KERN_ERR "%s() failed to get frontend(%d)\n", + __func__, i); + goto fail_probe; + } + videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, + &dev->pci->dev, &dev->slock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_TOP, + sizeof(struct cx88_buffer), + dev); + /* init struct videobuf_dvb */ + fe->dvb.name = dev->core->name; } - videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_TOP, - sizeof(struct cx88_buffer), - dev); - /* init struct videobuf_dvb */ - fe->dvb.name = dev->core->name; + } else { + /* no frontends allocated */ + printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n", + core->name); + goto fail_core; } err = dvb_register(dev); - if (err != 0) + if (err) + /* frontends/adapter de-allocated in dvb_register */ printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", core->name, err); + return err; +fail_probe: + videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends); fail_core: return err; } static int cx8802_dvb_remove(struct cx8802_driver *drv) { + struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; + dprintk( 1, "%s\n", __func__); + videobuf_dvb_unregister_bus(&dev->frontends); vp3054_i2c_remove(dev); |