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; }
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; }
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; }
/* ------------------------------------------------------------------ */ #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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
int as102_dvb_unregister_fe(struct dvb_frontend *fe) { dvb_unregister_frontend(fe); dvb_frontend_detach(fe); return 0; }
int as102_dvb_unregister_fe(struct dvb_frontend *fe) { /* unregister frontend */ dvb_unregister_frontend(fe); /* detach frontend */ dvb_frontend_detach(fe); return 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); }
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; }
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; } }
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; } }
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; } }
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; }
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; }
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; }
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); }
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; }
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); }
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; }
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; }
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; }
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; }