summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/cx88/cx88-dvb.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-dvb.c')
-rw-r--r--linux/drivers/media/video/cx88/cx88-dvb.c200
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);