Ejemplo n.º 1
0
static void em28xx_unregister_dvb(struct em28xx_dvb *dvb)
{
	dvb_net_release(&dvb->net);
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
	dvb_dmxdev_release(&dvb->dmxdev);
	dvb_dmx_release(&dvb->demux);
	if (dvb->fe[1])
		dvb_unregister_frontend(dvb->fe[1]);
	dvb_unregister_frontend(dvb->fe[0]);
	if (dvb->fe[1] && !dvb->dont_attach_fe1)
		dvb_frontend_detach(dvb->fe[1]);
	dvb_frontend_detach(dvb->fe[0]);
	dvb_unregister_adapter(&dvb->adapter);
}
static int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
{
	int ret, i;
	struct dvb_usb_device *d = adap_to_d(adap);

	dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);

	for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
		if (adap->fe[i]) {
			dvb_unregister_frontend(adap->fe[i]);
			dvb_frontend_detach(adap->fe[i]);
		}
	}

	if (d->props->tuner_detach) {
		ret = d->props->tuner_detach(adap);
		if (ret < 0) {
			dev_dbg(&d->udev->dev, "%s: tuner_detach() failed=%d\n",
					__func__, ret);
		}
	}

	if (d->props->frontend_detach) {
		ret = d->props->frontend_detach(adap);
		if (ret < 0) {
			dev_dbg(&d->udev->dev,
					"%s: frontend_detach() failed=%d\n",
					__func__, ret);
		}
	}

	return 0;
}
Ejemplo n.º 3
0
static int attach_xc3028(u8 addr, struct em28xx *dev)
{
    struct dvb_frontend *fe;
    struct xc2028_config cfg;

    memset(&cfg, 0, sizeof(cfg));
    cfg.i2c_adap  = &dev->i2c_adap;
    cfg.i2c_addr  = addr;
    cfg.callback  = em28xx_tuner_callback;

    if (!dev->dvb->frontend) {
        printk(KERN_ERR "%s/2: dvb frontend not attached. "
               "Can't attach xc3028\n",
               dev->name);
        return -EINVAL;
    }

    fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
    if (!fe) {
        printk(KERN_ERR "%s/2: xc3028 attach failed\n",
               dev->name);
        dvb_frontend_detach(dev->dvb->frontend);
        dev->dvb->frontend = NULL;
        return -EINVAL;
    }

    printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name);

    return 0;
}
Ejemplo n.º 4
0
void __devexit saa716x_dvb_exit(struct saa716x_dev *saa716x)
{
	struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap;
	int i;

	for (i = 0; i < saa716x->config->adapters; i++) {

		saa716x_fgpi_exit(saa716x, saa716x->config->adap_config[i].ts_port);

		if (saa716x_adap->fe) {
			dvb_unregister_frontend(saa716x_adap->fe);
			dvb_frontend_detach(saa716x_adap->fe);
		}

//		tasklet_kill(&saa716x->tasklet);
		dvb_net_release(&saa716x_adap->dvb_net);
		saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_mem);
		saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_hw);
		dvb_dmxdev_release(&saa716x_adap->dmxdev);
		dvb_dmx_release(&saa716x_adap->demux);

		dprintk(SAA716x_DEBUG, 1, "dvb_unregister_adapter");
		dvb_unregister_adapter(&saa716x_adap->dvb_adapter);

		saa716x_adap++;
	}

	return;
}
Ejemplo n.º 5
0
/* ------------------------------------------------------------------ */
#if 0				/* Keep */
static int attach_xc5000(u8 addr, struct cx231xx *dev)
{

	struct dvb_frontend *fe;
	struct xc5000_config cfg;

	memset(&cfg, 0, sizeof(cfg));
	cfg.i2c_adap = &dev->i2c_bus[1].i2c_adap;
	cfg.i2c_addr = addr;

	if (!dev->dvb->frontend) {
		printk(KERN_ERR "%s/2: dvb frontend not attached. "
		       "Can't attach xc5000\n", dev->name);
		return -EINVAL;
	}

	fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg);
	if (!fe) {
		printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name);
		dvb_frontend_detach(dev->dvb->frontend);
		dev->dvb->frontend = NULL;
		return -EINVAL;
	}

	printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name);

	return 0;
}
Ejemplo n.º 6
0
static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
{
	struct dvb_frontend *fe;
	struct xc2028_config cfg;
	struct xc2028_ctrl ctl;

	memset(&cfg, 0, sizeof(cfg));
	cfg.i2c_adap  = &dev->i2c_adap[dev->def_i2c_bus];
	cfg.i2c_addr  = addr;

	memset(&ctl, 0, sizeof(ctl));
	em28xx_setup_xc3028(dev, &ctl);
	cfg.ctrl  = &ctl;

	if (!dev->dvb->fe[0]) {
		em28xx_errdev("/2: dvb frontend not attached. "
				"Can't attach xc3028\n");
		return -EINVAL;
	}

	fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg);
	if (!fe) {
		em28xx_errdev("/2: xc3028 attach failed\n");
		dvb_frontend_detach(dev->dvb->fe[0]);
		dev->dvb->fe[0] = NULL;
		return -EINVAL;
	}

	em28xx_info("%s/2: xc3028 attached\n", dev->name);

	return 0;
}
Ejemplo n.º 7
0
int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
{
	int err;

	if (mantis->fe) {
		/*                         */
		err = mantis_frontend_shutdown(mantis);
		if (err != 0)
			dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
		dvb_unregister_frontend(mantis->fe);
		dvb_frontend_detach(mantis->fe);
	}

	tasklet_kill(&mantis->tasklet);
	dvb_net_release(&mantis->dvbnet);

	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);

	dvb_dmxdev_release(&mantis->dmxdev);
	dvb_dmx_release(&mantis->demux);

	dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
	dvb_unregister_adapter(&mantis->dvb_adapter);

	return 0;
}
Ejemplo n.º 8
0
void cx18_dvb_unregister(struct cx18_stream *stream)
{
	struct cx18 *cx = stream->cx;
	struct cx18_dvb *dvb = stream->dvb;
	struct dvb_adapter *dvb_adapter;
	struct dvb_demux *dvbdemux;
	struct dmx_demux *dmx;

	CX18_INFO("unregister DVB\n");

	if (dvb == NULL || !dvb->enabled)
		return;

	dvb_adapter = &dvb->dvb_adapter;
	dvbdemux = &dvb->demux;
	dmx = &dvbdemux->dmx;

	dmx->close(dmx);
	dvb_net_release(&dvb->dvbnet);
	dmx->remove_frontend(dmx, &dvb->mem_frontend);
	dmx->remove_frontend(dmx, &dvb->hw_frontend);
	dvb_dmxdev_release(&dvb->dmxdev);
	dvb_dmx_release(dvbdemux);
	dvb_unregister_frontend(dvb->fe);
	dvb_frontend_detach(dvb->fe);
	dvb_unregister_adapter(dvb_adapter);
}
Ejemplo n.º 9
0
static int attach_xc3028(u8 addr, struct em28xx *dev)
{
	struct dvb_frontend *fe;
	struct xc2028_config cfg;

	memset(&cfg, 0, sizeof(cfg));
	cfg.i2c_adap  = &dev->i2c_adap;
	cfg.i2c_addr  = addr;

	if (!dev->dvb->frontend) {
		em28xx_errdev("/2: dvb frontend not attached. "
				"Can't attach xc3028\n");
		return -EINVAL;
	}

	fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
	if (!fe) {
		em28xx_errdev("/2: xc3028 attach failed\n");
		dvb_frontend_detach(dev->dvb->frontend);
		dev->dvb->frontend = NULL;
		return -EINVAL;
	}

	em28xx_info("%s/2: xc3028 attached\n", dev->name);

	return 0;
}
Ejemplo n.º 10
0
static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
{
	struct pvr2_hdw *hdw = adap->channel.hdw;
	const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
	int ret = 0;

	if (dvb_props == NULL) {
		pvr2_trace(PVR2_TRACE_ERROR_LEGS, "fe_props not defined!");
		return -EINVAL;
	}

	ret = pvr2_channel_limit_inputs(
	    &adap->channel,
	    (1 << PVR2_CVAL_INPUT_DTV));
	if (ret) {
		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
			   "failed to grab control of dtv input (code=%d)",
		    ret);
		return ret;
	}

	if (dvb_props->frontend_attach == NULL) {
		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
			   "frontend_attach not defined!");
		ret = -EINVAL;
		goto done;
	}

	if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {

		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
				   "frontend registration failed!");
			dvb_frontend_detach(adap->fe);
			adap->fe = NULL;
			ret = -ENODEV;
			goto done;
		}

		if (dvb_props->tuner_attach)
			dvb_props->tuner_attach(adap);

		if (adap->fe->ops.analog_ops.standby)
			adap->fe->ops.analog_ops.standby(adap->fe);

		/*                                           */
		adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;

	} else {
		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
			   "no frontend was attached!");
		ret = -ENODEV;
		return ret;
	}

 done:
	pvr2_channel_limit_inputs(&adap->channel, 0);
	return ret;
}
Ejemplo n.º 11
0
static struct dvb_frontend * frontend_init(struct core_config *cfg, int i)
{
	struct tuner_devctl *ctl = NULL;
	struct dvb_frontend *frontend = NULL;

	printk (KERN_INFO "%s >\n", __FUNCTION__);
	
#if defined(UFS912) || defined(HS7810A) || defined(HS7110) || defined(WHITEBOX) || defined(SPARK)
		frontend = stv090x_attach(&tt1600_stv090x_config, cfg->i2c_adap, STV090x_DEMODULATOR_0, STV090x_TUNER1);
#else
	if (i== 0)
		frontend = stv090x_attach(&tt1600_stv090x_config, cfg->i2c_adap, STV090x_DEMODULATOR_0, STV090x_TUNER1);
	else
/* Dagobert commented: is this correct? second tuner uses demod0 ??? */
		frontend = stv090x_attach(&tt1600_stv090x_config, cfg->i2c_adap, STV090x_DEMODULATOR_0, STV090x_TUNER2);
#endif	
	if (frontend) {
		printk("%s: attached\n", __FUNCTION__);
		
		switch (tunerType) {
#if !defined(FORTIS_HDBOX)
		case SHARP7306:
			ctl = dvb_attach(ix7306_attach, frontend, &bs2s7hz7306a_config, cfg->i2c_adap);
			break;
#endif
		case STV6110X:
		default:
			ctl = dvb_attach(stv6110x_attach, frontend, &stv6110x_config, cfg->i2c_adap);
		}

		if(ctl)	{
			printk("%s: %s attached\n", __FUNCTION__, tuner);
			tt1600_stv090x_config.tuner_init	  	  = ctl->tuner_init;
			tt1600_stv090x_config.tuner_set_mode	  = ctl->tuner_set_mode;
			tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
			tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
			tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
			tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
			tt1600_stv090x_config.tuner_set_bbgain	  = ctl->tuner_set_bbgain;
			tt1600_stv090x_config.tuner_get_bbgain	  = ctl->tuner_get_bbgain;
			tt1600_stv090x_config.tuner_set_refclk	  = ctl->tuner_set_refclk;
			tt1600_stv090x_config.tuner_get_status	  = ctl->tuner_get_status;
		} else {
			printk (KERN_INFO "%s: error attaching %s\n", __FUNCTION__, tuner);
			goto error_out;
		}
	} else {
		printk (KERN_INFO "%s: error attaching\n", __FUNCTION__);
		goto error_out;
	}

	return frontend;

error_out:
	printk("core: Frontend registration failed!\n");
	if (frontend) 
		dvb_frontend_detach(frontend);
	return NULL;
}
Ejemplo n.º 12
0
static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
{
	if (adap->fe != NULL) {
		dvb_unregister_frontend(adap->fe);
		dvb_frontend_detach(adap->fe);
	}
	return 0;
}
Ejemplo n.º 13
0
int as102_dvb_unregister_fe(struct dvb_frontend *fe)
{
	
	dvb_unregister_frontend(fe);

	
	dvb_frontend_detach(fe);

	return 0;
}
Ejemplo n.º 14
0
int as102_dvb_unregister_fe(struct dvb_frontend *fe)
{
	/* unregister frontend */
	dvb_unregister_frontend(fe);

	/* detach frontend */
	dvb_frontend_detach(fe);

	return 0;
}
Ejemplo n.º 15
0
static void unregister_dvb(struct em28xx_dvb *dvb)
{
	dvb_net_release(&dvb->net);
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
	dvb_dmxdev_release(&dvb->dmxdev);
	dvb_dmx_release(&dvb->demux);
	dvb_unregister_frontend(dvb->frontend);
	dvb_frontend_detach(dvb->frontend);
	dvb_unregister_adapter(&dvb->adapter);
}
Ejemplo n.º 16
0
int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
{
	int ret, i;

	/* register all given adapter frontends */
	for (i = 0; i < adap->props.num_frontends; i++) {

		if (adap->props.fe[i].frontend_attach == NULL) {
			err("strange: '%s' #%d,%d "
			    "doesn't want to attach a frontend.",
			    adap->dev->desc->name, adap->id, i);

			return 0;
		}

		ret = adap->props.fe[i].frontend_attach(adap);
		if (ret || adap->fe_adap[i].fe == NULL) {
			/* only print error when there is no FE at all */
			if (i == 0)
				err("no frontend was attached by '%s'",
					adap->dev->desc->name);

			return 0;
		}

		adap->fe_adap[i].fe->id = i;

		/* re-assign sleep and wakeup functions */
		adap->fe_adap[i].fe_init = adap->fe_adap[i].fe->ops.init;
		adap->fe_adap[i].fe->ops.init  = dvb_usb_fe_wakeup;
		adap->fe_adap[i].fe_sleep = adap->fe_adap[i].fe->ops.sleep;
		adap->fe_adap[i].fe->ops.sleep = dvb_usb_fe_sleep;

		if (dvb_register_frontend(&adap->dvb_adap, adap->fe_adap[i].fe)) {
			err("Frontend %d registration failed.", i);
			dvb_frontend_detach(adap->fe_adap[i].fe);
			adap->fe_adap[i].fe = NULL;
			/* In error case, do not try register more FEs,
			 * still leaving already registered FEs alive. */
			if (i == 0)
				return -ENODEV;
			else
				return 0;
		}

		/* only attach the tuner if the demod is there */
		if (adap->props.fe[i].tuner_attach != NULL)
			adap->props.fe[i].tuner_attach(adap);

		adap->num_frontends_initialized++;
	}

	return 0;
}
Ejemplo n.º 17
0
static void dib7090_fe_release(struct aml_dvb *advb, struct aml_fe *fe)
{
	if(fe && fe->fe) {
		pr_dbg("release fe Dib7090 %d\n", fe->id);
		dvb_unregister_frontend(fe->fe);
		dvb_frontend_detach(fe->fe);
		dib7090_fe_cfg_put(fe->cfg);
		fe->fe = NULL;
		fe->cfg = NULL;
		fe->id = -1;
	}
}
Ejemplo n.º 18
0
static void cdx2834_fe_release(struct aml_dvb *advb, struct aml_fe *fe)
{
	if(fe && fe->fe) {
		pr_dbg("release GX1001 frontend %d\n", fe->id);
		dvb_unregister_frontend(fe->fe);
		dvb_frontend_detach(fe->fe);
		if(fe->cfg){
			kfree(fe->cfg);
			fe->cfg = NULL;
		}
		fe->id = -1;
	}
}
Ejemplo n.º 19
0
static void ite9173_fe_release(struct aml_dvb *advb, struct aml_fe *fe)
{
	if(fe && fe->fe) {
		pr_dbg("release ite9173 frontend %d\n", fe->id);
		mutex_destroy(&ite_lock);
		dvb_unregister_frontend(fe->fe);
		dvb_frontend_detach(fe->fe);
		if(fe->cfg){
			kfree(fe->cfg);
			fe->cfg = NULL;
		}
		fe->id = -1;
	}
}
Ejemplo n.º 20
0
static int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
{
	int i;
	dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
			adap->id);

	for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
		if (adap->fe[i]) {
			dvb_unregister_frontend(adap->fe[i]);
			dvb_frontend_detach(adap->fe[i]);
		}
	}

	return 0;
}
Ejemplo n.º 21
0
int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
{
	int i = adap->num_frontends_initialized - 1;

	/* unregister all given adapter frontends */
	for (; i >= 0; i--) {
		if (adap->fe_adap[i].fe != NULL) {
			dvb_unregister_frontend(adap->fe_adap[i].fe);
			dvb_frontend_detach(adap->fe_adap[i].fe);
		}
	}
	adap->num_frontends_initialized = 0;

	return 0;
}
Ejemplo n.º 22
0
static struct dvb_frontend *frontend_init(struct core_config *cfg, int i)
{
	struct tuner_devctl *ctl = NULL;
	struct dvb_frontend *frontend = NULL;

	printk(KERN_INFO "%s >\n", __FUNCTION__);

	frontend = stv090x_attach(&vitamin_hd5000_stv090x_config, cfg->i2c_adap, STV090x_DEMODULATOR_0, STV090x_TUNER1);
	if (frontend)
	{
		printk("%s: DEMOD attached\n", __FUNCTION__);

		ctl = dvb_attach(stv6110x_attach, frontend, &stv6110x_config, cfg->i2c_adap);
		if (ctl)
		{
			printk("%s: TUNER attached\n", __FUNCTION__);
			vitamin_hd5000_stv090x_config.tuner_init	  	  = ctl->tuner_init;
			vitamin_hd5000_stv090x_config.tuner_set_mode	  = ctl->tuner_set_mode;
			vitamin_hd5000_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
			vitamin_hd5000_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
			vitamin_hd5000_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
			vitamin_hd5000_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
			vitamin_hd5000_stv090x_config.tuner_set_bbgain	  = ctl->tuner_set_bbgain;
			vitamin_hd5000_stv090x_config.tuner_get_bbgain	  = ctl->tuner_get_bbgain;
			vitamin_hd5000_stv090x_config.tuner_set_refclk	  = ctl->tuner_set_refclk;
			vitamin_hd5000_stv090x_config.tuner_get_status	  = ctl->tuner_get_status;
		}
		else
		{
			printk(KERN_INFO "%s: error attaching TUNER\n", __FUNCTION__);
			goto error_out;
		}
	}
	else
	{
		printk(KERN_INFO "%s: error attaching\n", __FUNCTION__);
		goto error_out;
	}

	return frontend;

error_out:
	printk("core: Frontend registration failed!\n");
	if (frontend)
		dvb_frontend_detach(frontend);
	return NULL;
}
Ejemplo n.º 23
0
void as102_dvb_unregister(struct as102_dev_t *as102_dev)
{
	/* unregister as102 frontend */
	dvb_unregister_frontend(as102_dev->dvb_fe);

	/* detach frontend */
	dvb_frontend_detach(as102_dev->dvb_fe);

	/* unregister demux device */
	dvb_dmxdev_release(&as102_dev->dvb_dmxdev);
	dvb_dmx_release(&as102_dev->dvb_dmx);

	/* unregister dvb adapter */
	dvb_unregister_adapter(&as102_dev->dvb_adap);

	pr_info("Unregistered device %s", as102_dev->name);
}
Ejemplo n.º 24
0
static struct dvb_frontend * frontend_init(struct core_config *cfg, int i)
{
    struct dvb_frontend *frontend = NULL;
    int ad;

    printk (KERN_INFO "%s frontend_init >\n", __FUNCTION__);

    if (i== 0)
        frontend = dvb_attach(stb0899_attach, &stb0899_config_1, cfg->i2c_adap);
    else
        frontend = dvb_attach(stb0899_attach, &stb0899_config_2, cfg->i2c_adap);

    if (frontend)
    {
        printk("fe_core : stb0899 attached OK \n");

        if (i == 0)
        {
            if (dvb_attach(stb6100_attach, frontend, &stb6100_config_1, cfg->i2c_adap) == 0) {
                printk (KERN_INFO "error attaching stb6100\n");
                goto error_out;
            }
        }
        else
        {
            if (dvb_attach(stb6100_attach,frontend, &stb6100_config_2, cfg->i2c_adap) == 0) {
                printk(KERN_INFO " error attaching stb6100\n");
                goto error_out;
            }
        }
        printk("fe_core : stb6100 attached OK \n");
    }
    else
    {
        printk (KERN_INFO "%s: error attaching stb0899\n", __FUNCTION__);
        goto error_out;
    }

    return frontend;

error_out:
    printk("core: Frontend registration failed!\n");
    if (frontend)
        dvb_frontend_detach(frontend);
    return NULL;
}
Ejemplo n.º 25
0
void au0828_dvb_unregister(struct au0828_dev *dev)
{
	struct au0828_dvb *dvb = &dev->dvb;

	dprintk(1, "%s()\n", __func__);

	if (dvb->frontend == NULL)
		return;

	dvb_net_release(&dvb->net);
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
	dvb_dmxdev_release(&dvb->dmxdev);
	dvb_dmx_release(&dvb->demux);
	dvb_unregister_frontend(dvb->frontend);
	dvb_frontend_detach(dvb->frontend);
	dvb_unregister_adapter(&dvb->adapter);
}
Ejemplo n.º 26
0
static struct dvb_frontend * frontend_init(struct core_config *cfg, int i)
{
	
	struct dvb_frontend *frontend = NULL;

	printk (KERN_INFO "%s >\n", __FUNCTION__);


	if (i== 0)
		frontend = stv090x_attach(&tt1600_stv090x_config, cfg->i2c_adap, STV090x_DEMODULATOR_0, STV090x_TUNER1);
	else

		frontend = stv090x_attach(&tt1600_stv090x_config, cfg->i2c_adap, STV090x_DEMODULATOR_1, STV090x_TUNER2);
	
	if (frontend) {
		printk("%s: stv0900 attached\n", __FUNCTION__);
	if (i == 0){
				if (dvb_attach(stb6100_attach, frontend, &stb6100_config, cfg->i2c_adap,STB1) == 0) {
					printk (KERN_INFO "error attaching stb6100\n");
					goto error_out;
					}
				}else{
			
				if (dvb_attach(stb6100_attach,frontend, &stb6100_config_1, cfg->i2c_adap,STB2) == 0) {
					printk(KERN_INFO " error attaching stb6100\n");
					goto error_out;
				}
				 }
				
				
					printk("fe_core : stb6100 attached OK \n");
			} else {
				printk (KERN_INFO "%s: error attaching stv0900\n", __FUNCTION__);
				goto error_out;
			}

	return frontend;
error_out:
	printk("core: Frontend registration failed!\n");
	if (frontend) 
		dvb_frontend_detach(frontend);
	return NULL;
}
Ejemplo n.º 27
0
static int demod_attach_stv0900(struct ngene_channel *chan)
{
    struct i2c_adapter *i2c;
    struct stv090x_config *feconf = (struct stv090x_config *)
                                    chan->dev->card_info->fe_config[chan->number];

    /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
    /* Note: Both adapters share the same i2c bus, but the demod     */
    /*       driver requires that each demod has its own i2c adapter */
    if (chan->number < 2)
        i2c = &chan->dev->channel[0].i2c_adapter;
    else
        i2c = &chan->dev->channel[1].i2c_adapter;

    chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
                          (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
                          : STV090x_DEMODULATOR_1);
    if (chan->fe == NULL) {
        printk(KERN_ERR	DEVICE_NAME ": No STV0900 found!\n");
        return -ENODEV;
    }

    /* store channel info */
    if (feconf->tuner_i2c_lock)
        chan->fe->analog_demod_priv = chan;

    if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
                    0, chan->dev->card_info->lnb[chan->number])) {
        printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
        dvb_frontend_detach(chan->fe);
        chan->fe = NULL;
        return -ENODEV;
    }

    return 0;
}
static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
{
	int ret, i, count_registered = 0;
	struct dvb_usb_device *d = adap_to_d(adap);
	dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);

	memset(adap->fe, 0, sizeof(adap->fe));
	adap->active_fe = -1;

	if (d->props->frontend_attach) {
		ret = d->props->frontend_attach(adap);
		if (ret < 0) {
			dev_dbg(&d->udev->dev,
					"%s: frontend_attach() failed=%d\n",
					__func__, ret);
			goto err_dvb_frontend_detach;
		}
	} else {
		dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n",
				__func__);
		ret = 0;
		goto err;
	}

	for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
		adap->fe[i]->id = i;
		/* re-assign sleep and wakeup functions */
		adap->fe_init[i] = adap->fe[i]->ops.init;
		adap->fe[i]->ops.init = dvb_usb_fe_init;
		adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
		adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;

		ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
		if (ret < 0) {
			dev_err(&d->udev->dev,
					"%s: frontend%d registration failed\n",
					KBUILD_MODNAME, i);
			goto err_dvb_unregister_frontend;
		}

		count_registered++;
	}

	if (d->props->tuner_attach) {
		ret = d->props->tuner_attach(adap);
		if (ret < 0) {
			dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n",
					__func__, ret);
			goto err_dvb_unregister_frontend;
		}
	}

	return 0;

err_dvb_unregister_frontend:
	for (i = count_registered - 1; i >= 0; i--)
		dvb_unregister_frontend(adap->fe[i]);

err_dvb_frontend_detach:
	for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
		if (adap->fe[i]) {
			dvb_frontend_detach(adap->fe[i]);
			adap->fe[i] = NULL;
		}
	}

err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
Ejemplo n.º 29
0
static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module,
			       struct em28xx *dev, struct device *device)
{
	int result;

	mutex_init(&dvb->lock);

	/* register adapter */
	result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
				      adapter_nr);
	if (result < 0) {
		printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
		       dev->name, result);
		goto fail_adapter;
	}

	/* Ensure all frontends negotiate bus access */
	dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
	if (dvb->fe[1])
		dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;

	dvb->adapter.priv = &dev->i2c_bus[dev->def_i2c_bus];

	/* register frontend */
	result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]);
	if (result < 0) {
		printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
		       dev->name, result);
		goto fail_frontend0;
	}

	/* register 2nd frontend */
	if (dvb->fe[1]) {
		result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]);
		if (result < 0) {
			printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
				dev->name, result);
			goto fail_frontend1;
		}
	}

	/* register demux stuff */
	dvb->demux.dmx.capabilities =
		DMX_TS_FILTERING | DMX_SECTION_FILTERING |
		DMX_MEMORY_BASED_FILTERING;
	dvb->demux.priv       = dvb;
	dvb->demux.filternum  = 256;
	dvb->demux.feednum    = 256;
	dvb->demux.start_feed = em28xx_start_feed;
	dvb->demux.stop_feed  = em28xx_stop_feed;

	result = dvb_dmx_init(&dvb->demux);
	if (result < 0) {
		printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
		       dev->name, result);
		goto fail_dmx;
	}

	dvb->dmxdev.filternum    = 256;
	dvb->dmxdev.demux        = &dvb->demux.dmx;
	dvb->dmxdev.capabilities = 0;
	result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
	if (result < 0) {
		printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
		       dev->name, result);
		goto fail_dmxdev;
	}

	dvb->fe_hw.source = DMX_FRONTEND_0;
	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
	if (result < 0) {
		printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
		       dev->name, result);
		goto fail_fe_hw;
	}

	dvb->fe_mem.source = DMX_MEMORY_FE;
	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
	if (result < 0) {
		printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
		       dev->name, result);
		goto fail_fe_mem;
	}

	result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
	if (result < 0) {
		printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n",
		       dev->name, result);
		goto fail_fe_conn;
	}

	/* register network adapter */
	dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
	return 0;

fail_fe_conn:
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
fail_fe_mem:
	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
fail_fe_hw:
	dvb_dmxdev_release(&dvb->dmxdev);
fail_dmxdev:
	dvb_dmx_release(&dvb->demux);
fail_dmx:
	if (dvb->fe[1])
		dvb_unregister_frontend(dvb->fe[1]);
	dvb_unregister_frontend(dvb->fe[0]);
fail_frontend1:
	if (dvb->fe[1])
		dvb_frontend_detach(dvb->fe[1]);
fail_frontend0:
	dvb_frontend_detach(dvb->fe[0]);
	dvb_unregister_adapter(&dvb->adapter);
fail_adapter:
	return result;
}
Ejemplo n.º 30
0
static int em28xx_dvb_init(struct em28xx *dev)
{
	int result = 0, mfe_shared = 0;
	struct em28xx_dvb *dvb;

	if (dev->is_audio_only) {
		/* Shouldn't initialize IR for this interface */
		return 0;
	}

	if (!dev->board.has_dvb) {
		/* This device does not support the extension */
		return 0;
	}

	em28xx_info("Binding DVB extension\n");

	dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
	if (dvb == NULL) {
		em28xx_info("em28xx_dvb: memory allocation failed\n");
		return -ENOMEM;
	}
	dev->dvb = dvb;
	dvb->fe[0] = dvb->fe[1] = NULL;

	/* pre-allocate DVB usb transfer buffers */
	if (dev->dvb_xfer_bulk) {
		result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
					   dev->dvb_xfer_bulk,
					   EM28XX_DVB_NUM_BUFS,
					   512,
					   EM28XX_DVB_BULK_PACKET_MULTIPLIER);
	} else {
		result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
					   dev->dvb_xfer_bulk,
					   EM28XX_DVB_NUM_BUFS,
					   dev->dvb_max_pkt_size_isoc,
					   EM28XX_DVB_NUM_ISOC_PACKETS);
	}
	if (result) {
		em28xx_errdev("em28xx_dvb: failed to pre-allocate USB transfer buffers for DVB.\n");
		kfree(dvb);
		dev->dvb = NULL;
		return result;
	}

	mutex_lock(&dev->lock);
	em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
	/* init frontend */
	switch (dev->model) {
	case EM2874_BOARD_LEADERSHIP_ISDBT:
		dvb->fe[0] = dvb_attach(s921_attach,
				&sharp_isdbt, &dev->i2c_adap[dev->def_i2c_bus]);

		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		break;
	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
		dvb->fe[0] = dvb_attach(lgdt330x_attach,
					   &em2880_lgdt3303_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2880_BOARD_KWORLD_DVB_310U:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_with_xc3028,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
	case EM2882_BOARD_TERRATEC_HYBRID_XS:
	case EM2880_BOARD_EMPIRE_DUAL_TV:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_xc3028_no_i2c_gate,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2880_BOARD_TERRATEC_HYBRID_XS:
	case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
	case EM2881_BOARD_PINNACLE_HYBRID_PRO:
	case EM2882_BOARD_DIKOM_DK300:
	case EM2882_BOARD_KWORLD_VS_DVBT:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_xc3028_no_i2c_gate,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] == NULL) {
			/* This board could have either a zl10353 or a mt352.
			   If the chip id isn't for zl10353, try mt352 */
			dvb->fe[0] = dvb_attach(mt352_attach,
						   &terratec_xs_mt352_cfg,
						   &dev->i2c_adap[dev->def_i2c_bus]);
		}

		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2870_BOARD_KWORLD_355U:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_no_i2c_gate_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL)
			dvb_attach(qt1010_attach, dvb->fe[0],
				   &dev->i2c_adap[dev->def_i2c_bus], &em28xx_qt1010_config);
		break;
	case EM2883_BOARD_KWORLD_HYBRID_330U:
	case EM2882_BOARD_EVGA_INDTUBE:
		dvb->fe[0] = dvb_attach(s5h1409_attach,
					   &em28xx_s5h1409_with_xc3028,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2882_BOARD_KWORLD_ATSC_315U:
		dvb->fe[0] = dvb_attach(lgdt330x_attach,
					   &em2880_lgdt3303_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL) {
			if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
				&dev->i2c_adap[dev->def_i2c_bus], 0x61, TUNER_THOMSON_DTT761X)) {
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
	case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
		dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL,
					   &dev->i2c_adap[dev->def_i2c_bus], &dev->udev->dev);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
		/* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
		dvb->fe[0] = dvb_attach(tda10023_attach,
			&em28xx_tda10023_config,
			&dev->i2c_adap[dev->def_i2c_bus], 0x48);
		if (dvb->fe[0]) {
			if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
				&dev->i2c_adap[dev->def_i2c_bus], 0x60, TUNER_PHILIPS_CU1216L)) {
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2870_BOARD_KWORLD_A340:
		dvb->fe[0] = dvb_attach(lgdt3305_attach,
					   &em2870_lgdt3304_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
			&dev->i2c_adap[dev->def_i2c_bus],
			&kworld_a340_config)) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
		}
		break;
	case EM28174_BOARD_PCTV_290E:
		/* set default GPIO0 for LNA, used if GPIOLIB is undefined */
		dvb->lna_gpio = CXD2820R_GPIO_E | CXD2820R_GPIO_O |
				CXD2820R_GPIO_L;
		dvb->fe[0] = dvb_attach(cxd2820r_attach,
					&em28xx_cxd2820r_config,
					&dev->i2c_adap[dev->def_i2c_bus],
					&dvb->lna_gpio);
		if (dvb->fe[0]) {
			/* FE 0 attach tuner */
			if (!dvb_attach(tda18271_attach,
					dvb->fe[0],
					0x60,
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_cxd2820r_tda18271_config)) {

				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
			}

#ifdef CONFIG_GPIOLIB
			/* enable LNA for DVB-T, DVB-T2 and DVB-C */
			result = gpio_request_one(dvb->lna_gpio,
					GPIOF_OUT_INIT_LOW, NULL);
			if (result)
				em28xx_errdev("gpio request failed %d\n",
						result);
			else
				gpio_free(dvb->lna_gpio);

			result = 0; /* continue even set LNA fails */
#endif
			dvb->fe[0]->ops.set_lna = em28xx_pctv_290e_set_lna;
		}

		break;
	case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
	{
		struct xc5000_config cfg;
		hauppauge_hvr930c_init(dev);

		dvb->fe[0] = dvb_attach(drxk_attach,
					&hauppauge_930c_drxk, &dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}
		/* FIXME: do we need a pll semaphore? */
		dvb->fe[0]->sec_priv = dvb;
		sema_init(&dvb->pll_mutex, 1);
		dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
		dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;

		/* Attach xc5000 */
		memset(&cfg, 0, sizeof(cfg));
		cfg.i2c_address  = 0x61;
		cfg.if_khz = 4000;

		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
		if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus],
				&cfg)) {
			result = -EINVAL;
			goto out_free;
		}
		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);

		break;
	}
	case EM2884_BOARD_TERRATEC_H5:
		terratec_h5_init(dev);

		dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}
		/* FIXME: do we need a pll semaphore? */
		dvb->fe[0]->sec_priv = dvb;
		sema_init(&dvb->pll_mutex, 1);
		dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
		dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;

		/* Attach tda18271 to DVB-C frontend */
		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
		if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60)) {
			result = -EINVAL;
			goto out_free;
		}
		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);

		break;
	case EM2884_BOARD_C3TECH_DIGITAL_DUO:
		dvb->fe[0] = dvb_attach(mb86a20s_attach,
					   &c3tech_duo_mb86a20s_config,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL)
			dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				   &dev->i2c_adap[dev->def_i2c_bus],
				   &c3tech_duo_tda18271_config);
		break;
	case EM28174_BOARD_PCTV_460E:
		/* attach demod */
		dvb->fe[0] = dvb_attach(tda10071_attach,
			&em28xx_tda10071_config, &dev->i2c_adap[dev->def_i2c_bus]);

		/* attach SEC */
		if (dvb->fe[0])
			dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus],
				&em28xx_a8293_config);
		break;
	case EM2874_BOARD_DELOCK_61959:
	case EM2874_BOARD_MAXMEDIA_UB425_TC:
		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
				&dev->i2c_adap[dev->def_i2c_bus]);

		if (dvb->fe[0]) {
			/* disable I2C-gate */
			dvb->fe[0]->ops.i2c_gate_ctrl = NULL;

			/* attach tuner */
			if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_cxd2820r_tda18271_config)) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2884_BOARD_PCTV_510E:
	case EM2884_BOARD_PCTV_520E:
		pctv_520e_init(dev);

		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk,
				&dev->i2c_adap[dev->def_i2c_bus]);

		if (dvb->fe[0]) {
			/* attach tuner */
			if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_cxd2820r_tda18271_config)) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2884_BOARD_CINERGY_HTC_STICK:
		terratec_htc_stick_init(dev);

		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				&dev->i2c_adap[dev->def_i2c_bus],
				&em28xx_cxd2820r_tda18271_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2884_BOARD_TERRATEC_HTC_USB_XS:
		terratec_htc_usb_xs_init(dev);

		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				&dev->i2c_adap[dev->def_i2c_bus],
				&em28xx_cxd2820r_tda18271_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2874_BOARD_KWORLD_UB435Q_V2:
		dvb->fe[0] = dvb_attach(lgdt3305_attach,
					&em2874_lgdt3305_dev,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				&dev->i2c_adap[dev->def_i2c_bus],
				&kworld_ub435q_v2_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2874_BOARD_KWORLD_UB435Q_V3:
		dvb->fe[0] = dvb_attach(lgdt3305_attach,
					&em2874_lgdt3305_nogate_dev,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18212_attach, dvb->fe[0],
				&dev->i2c_adap[dev->def_i2c_bus],
				&kworld_ub435q_v3_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2874_BOARD_PCTV_HD_MINI_80E:
		dvb->fe[0] = dvb_attach(drx39xxj_attach, &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL) {
			dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
						&dev->i2c_adap[dev->def_i2c_bus],
						&pinnacle_80e_dvb_config);
			if (!dvb->fe[0]) {
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM28178_BOARD_PCTV_461E:
		{
			/* demod I2C adapter */
			struct i2c_adapter *i2c_adapter;
			struct i2c_client *client;
			struct i2c_board_info info;
			struct m88ts2022_config m88ts2022_config = {
				.clock = 27000000,
			};
			memset(&info, 0, sizeof(struct i2c_board_info));

			/* attach demod */
			dvb->fe[0] = dvb_attach(m88ds3103_attach,
					&pctv_461e_m88ds3103_config,
					&dev->i2c_adap[dev->def_i2c_bus],
					&i2c_adapter);
			if (dvb->fe[0] == NULL) {
				result = -ENODEV;
				goto out_free;
			}

			/* attach tuner */
			m88ts2022_config.fe = dvb->fe[0];
			strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE);
			info.addr = 0x60;
			info.platform_data = &m88ts2022_config;
			request_module("m88ts2022");
			client = i2c_new_device(i2c_adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -ENODEV;
				goto out_free;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				dvb_frontend_detach(dvb->fe[0]);
				result = -ENODEV;
				goto out_free;
			}

			/* delegate signal strength measurement to tuner */
			dvb->fe[0]->ops.read_signal_strength =
					dvb->fe[0]->ops.tuner_ops.get_rf_strength;

			/* attach SEC */
			if (!dvb_attach(a8293_attach, dvb->fe[0],
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_a8293_config)) {
				module_put(client->dev.driver->owner);
				i2c_unregister_device(client);
				dvb_frontend_detach(dvb->fe[0]);
				result = -ENODEV;
				goto out_free;
			}

			dvb->i2c_client_tuner = client;
		}
		break;
	case EM28178_BOARD_PCTV_292E:
		{
			struct i2c_adapter *adapter;
			struct i2c_client *client;
			struct i2c_board_info info;
			struct si2168_config si2168_config;
			struct si2157_config si2157_config;

			/* attach demod */
			si2168_config.i2c_adapter = &adapter;
			si2168_config.fe = &dvb->fe[0];
			memset(&info, 0, sizeof(struct i2c_board_info));
			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
			info.addr = 0x64;
			info.platform_data = &si2168_config;
			request_module(info.type);
			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
			if (client == NULL || client->dev.driver == NULL) {
				result = -ENODEV;
				goto out_free;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				result = -ENODEV;
				goto out_free;
			}

			dvb->i2c_client_demod = client;

			/* attach tuner */
			memset(&si2157_config, 0, sizeof(si2157_config));
			si2157_config.fe = dvb->fe[0];
			memset(&info, 0, sizeof(struct i2c_board_info));
			strlcpy(info.type, "si2157", I2C_NAME_SIZE);
			info.addr = 0x60;
			info.platform_data = &si2157_config;
			request_module(info.type);
			client = i2c_new_device(adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				module_put(dvb->i2c_client_demod->dev.driver->owner);
				i2c_unregister_device(dvb->i2c_client_demod);
				result = -ENODEV;
				goto out_free;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				module_put(dvb->i2c_client_demod->dev.driver->owner);
				i2c_unregister_device(dvb->i2c_client_demod);
				result = -ENODEV;
				goto out_free;
			}

			dvb->i2c_client_tuner = client;
			dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna;
		}
		break;
	default:
		em28xx_errdev("/2: The frontend of your DVB/ATSC card"
				" isn't supported yet\n");
		break;
	}
	if (NULL == dvb->fe[0]) {
		em28xx_errdev("/2: frontend initialization failed\n");
		result = -EINVAL;
		goto out_free;
	}
	/* define general-purpose callback pointer */
	dvb->fe[0]->callback = em28xx_tuner_callback;
	if (dvb->fe[1])
		dvb->fe[1]->callback = em28xx_tuner_callback;

	/* register everything */
	result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);

	if (result < 0)
		goto out_free;

	/* MFE lock */
	dvb->adapter.mfe_shared = mfe_shared;

	em28xx_info("DVB extension successfully initialized\n");

	kref_get(&dev->ref);

ret:
	em28xx_set_mode(dev, EM28XX_SUSPEND);
	mutex_unlock(&dev->lock);
	return result;

out_free:
	kfree(dvb);
	dev->dvb = NULL;
	goto ret;
}

static inline void prevent_sleep(struct dvb_frontend_ops *ops)
{
	ops->set_voltage = NULL;
	ops->sleep = NULL;
	ops->tuner_ops.sleep = NULL;
}