/** * prev2resz_open - Initializes and opens the device */ static int prev2resz_open(struct inode *inode, struct file *fp) { struct prev2resz_fhdl *fh; int ret = 0; fh = kzalloc(sizeof(struct prev2resz_fhdl), GFP_KERNEL); if (NULL == fh) return -ENOMEM; fh->isp = isp_get(); if (fh->isp == NULL) { dev_err(p2r_device, "Can't get ISP device\n"); ret = -EBUSY; goto err_isp; } fh->isp_dev = dev_get_drvdata(fh->isp); if (fh->isp_dev == NULL) { dev_err(p2r_device, "Can't get ISP driver data\n"); ret = -EBUSY; goto err_isp; } fh->isp_prev = &fh->isp_dev->isp_prev; fh->isp_resz = &fh->isp_dev->isp_res; fh->src_vbq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; fh->dst_vbq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; p2r_ctx.status.prv_busy = PREV2RESZ_FREE; p2r_ctx.status.rsz_busy = PREV2RESZ_FREE; init_completion(&p2r_ctx.resz_complete); p2r_ctx.opened++; fp->private_data = fh; videobuf_queue_sg_init(&fh->src_vbq, &p2r_ctx.vbq_ops, NULL, &fh->src_vbq_lock, fh->src_vbq.type, V4L2_FIELD_NONE, sizeof(struct videobuf_buffer), fh); spin_lock_init(&fh->src_vbq_lock); videobuf_queue_sg_init(&fh->dst_vbq, &p2r_ctx.vbq_ops, NULL, &fh->dst_vbq_lock, fh->dst_vbq.type, V4L2_FIELD_NONE, sizeof(struct videobuf_buffer), fh); spin_lock_init(&fh->dst_vbq_lock); return 0; err_isp: isp_put(); kfree(fh); return ret; }
/** * previewer_open - Initializes and opens the Preview Wrapper * @inode: Inode structure associated with the Preview Wrapper * @filp: File structure associated with the Preview Wrapper * * Returns 0 if successful, -EACCES if its unable to initialize default config, * -EBUSY if its already opened or the ISP module is not available, or -ENOMEM * if its unable to allocate the device in kernel space memory. **/ static int previewer_open(struct inode *inode, struct file *filp) { int ret = 0; struct prev_device *device = prevdevice; struct prev_params *config = isppreview_get_config(); struct prev_fh *fh; if (config == NULL) { dev_err(prev_dev, "Unable to initialize default config " "from isppreviewer\n\n"); return -EACCES; } if (device->opened || (filp->f_flags & O_NONBLOCK)) { dev_err(prev_dev, "previewer_open: device is already " "opened\n"); return -EBUSY; } fh = kzalloc(sizeof(struct prev_fh), GFP_KERNEL); if (NULL == fh) return -ENOMEM; isp_get(); ret = isppreview_request(); if (ret) { isp_put(); dev_err(prev_dev, "Can't acquire isppreview\n"); return ret; } device->params = config; device->opened = 1; filp->private_data = fh; fh->inout_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fh->lsc_type = V4L2_BUF_TYPE_PRIVATE; fh->device = device; videobuf_queue_sg_init(&fh->inout_vbq, &device->vbq_ops, NULL, &device->inout_vbq_lock, fh->inout_type, V4L2_FIELD_NONE, sizeof(struct videobuf_buffer), fh); videobuf_queue_sg_init(&fh->lsc_vbq, &device->vbq_ops, NULL, &device->lsc_vbq_lock, fh->lsc_type, V4L2_FIELD_NONE, sizeof(struct videobuf_buffer), fh); init_completion(&device->wfc); device->wfc.done = 0; mutex_init(&device->prevwrap_mutex); return 0; }
static void omap1_cam_init_videobuf(struct videobuf_queue *q, struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct omap1_cam_dev *pcdev = ici->priv; if (!sg_mode) videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops, icd->dev.parent, &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, sizeof(struct omap1_cam_buf), icd, &icd->video_lock); else videobuf_queue_sg_init(q, &omap1_videobuf_ops, icd->dev.parent, &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, sizeof(struct omap1_cam_buf), icd, &icd->video_lock); /* use videobuf mode (auto)selected with the module parameter */ pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG; /* * Ensure we substitute the videobuf-dma-contig version of the * mmap_mapper() callback with our own wrapper, used for switching * automatically to videobuf-dma-sg on buffer allocation failure. */ if (!sg_mode && q->int_ops->mmap_mapper != omap1_cam_mmap_mapper) { pcdev->mmap_mapper = q->int_ops->mmap_mapper; q->int_ops->mmap_mapper = omap1_cam_mmap_mapper; } }
static int vbi_open(struct saa7146_dev *dev, struct file *file) { struct saa7146_fh *fh = file->private_data; u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1); int ret = 0; DEB_VBI(("dev:%p, fh:%p\n",dev,fh)); ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS); if (0 == ret) { DEB_S(("cannot get vbi RESOURCE_DMA3_BRS resource\n")); return -EBUSY; } /* adjust arbitrition control for video dma 3 */ arbtr_ctrl &= ~0x1f0000; arbtr_ctrl |= 0x1d0000; saa7146_write(dev, PCI_BT_V1, arbtr_ctrl); saa7146_write(dev, MC2, (MASK_04|MASK_20)); memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt)); fh->vbi_fmt.sampling_rate = 27000000; fh->vbi_fmt.offset = 248; /* todo */ fh->vbi_fmt.samples_per_line = vbi_pixel_to_capture; fh->vbi_fmt.sample_format = V4L2_PIX_FMT_GREY; fh->vbi_fmt.start[0] = 5; fh->vbi_fmt.count[0] = 16; fh->vbi_fmt.start[1] = 312; fh->vbi_fmt.count[1] = 16; videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VBI_CAPTURE, V4L2_FIELD_SEQ_TB, sizeof(struct saa7146_buf), file); init_timer(&fh->vbi_read_timeout); fh->vbi_read_timeout.function = vbi_read_timeout; fh->vbi_read_timeout.data = (unsigned long)file; /* initialize the brs */ if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) { saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19)); } else { saa7146_write(dev, BRS_CTRL, 0x00000001); if (0 != (ret = vbi_workaround(dev))) { DEB_VBI(("vbi workaround failed!\n")); /* return ret;*/ } } /* upload brs register */ saa7146_write(dev, MC2, (MASK_08|MASK_24)); return 0; }
static int omap24xxcam_open(struct file *file) { int minor = video_devdata(file)->minor; struct omap24xxcam_device *cam = omap24xxcam.priv; struct omap24xxcam_fh *fh; struct v4l2_format format; if (!cam || !cam->vfd || (cam->vfd->minor != minor)) return -ENODEV; fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (fh == NULL) return -ENOMEM; mutex_lock(&cam->mutex); if (cam->sdev == NULL || !try_module_get(cam->sdev->module)) { mutex_unlock(&cam->mutex); goto out_try_module_get; } if (atomic_inc_return(&cam->users) == 1) { omap24xxcam_hwinit(cam); if (omap24xxcam_sensor_enable(cam)) { mutex_unlock(&cam->mutex); goto out_omap24xxcam_sensor_enable; } } mutex_unlock(&cam->mutex); fh->cam = cam; mutex_lock(&cam->mutex); vidioc_int_g_fmt_cap(cam->sdev, &format); mutex_unlock(&cam->mutex); /* FIXME: how about fh->pix when there are more users? */ fh->pix = format.fmt.pix; file->private_data = fh; spin_lock_init(&fh->vbq_lock); videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL, &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, sizeof(struct videobuf_buffer), fh); return 0; out_omap24xxcam_sensor_enable: omap24xxcam_poweron_reset(cam); module_put(cam->sdev->module); out_try_module_get: kfree(fh); return -ENODEV; }
static int video_open(struct saa7146_dev *dev, struct file *file) { struct saa7146_fh *fh = file->private_data; videobuf_queue_sg_init(&fh->video_q, &video_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct saa7146_buf), file, &dev->v4l2_lock); return 0; }
static int vbi_open(struct saa7146_dev *dev, struct file *file) { struct saa7146_fh *fh = file->private_data; struct saa7146_vv *vv = fh->dev->vv_data; u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1); int ret = 0; DEB_VBI("dev:%p, fh:%p\n", dev, fh); ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS); if (0 == ret) { DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n"); return -EBUSY; } /* adjust arbitrition control for video dma 3 */ arbtr_ctrl &= ~0x1f0000; arbtr_ctrl |= 0x1d0000; saa7146_write(dev, PCI_BT_V1, arbtr_ctrl); saa7146_write(dev, MC2, (MASK_04|MASK_20)); videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VBI_CAPTURE, V4L2_FIELD_SEQ_TB, // FIXME: does this really work? sizeof(struct saa7146_buf), file, &dev->v4l2_lock); vv->vbi_read_timeout.function = vbi_read_timeout; vv->vbi_read_timeout.data = (unsigned long)file; /* initialize the brs */ if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) { saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19)); } else { saa7146_write(dev, BRS_CTRL, 0x00000001); if (0 != (ret = vbi_workaround(dev))) { DEB_VBI("vbi workaround failed!\n"); /* return ret;*/ } } /* upload brs register */ saa7146_write(dev, MC2, (MASK_08|MASK_24)); return 0; }
static int video_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; printk("open dev=%s type=%s\n", video_device_node_name(vdev), v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (NULL == fh) return -ENOMEM; lock_kernel(); file->private_data = fh; fh->dev = dev; fh->type = type; fh->width = 720; if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) fh->height = 576; else fh->height = 480; dev->channel_opened = SRAM_CH01; pix_format = (dev->pixel_formats[dev->channel_opened] == PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV; fh->fmt = format_by_fourcc(pix_format); v4l2_prio_open(&dev->prio, &fh->prio); videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), fh); dprintk(1, "post videobuf_queue_init()\n"); unlock_kernel(); return 0; }
static int empress_init(struct saa7134_dev *dev) { int err; dprintk("%s: %s\n",dev->name,__func__); dev->empress_dev = video_device_alloc(); if (NULL == dev->empress_dev) return -ENOMEM; *(dev->empress_dev) = saa7134_empress_template; dev->empress_dev->parent = &dev->pci->dev; dev->empress_dev->release = video_device_release; snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), "%s empress (%s)", dev->name, saa7134_boards[dev->board].name); INIT_WORK(&dev->empress_workqueue, empress_signal_update); video_set_drvdata(dev->empress_dev, dev); err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, empress_nr[dev->nr]); if (err < 0) { printk(KERN_INFO "%s: can't register video device\n", dev->name); video_device_release(dev->empress_dev); dev->empress_dev = NULL; return err; } printk(KERN_INFO "%s: registered device %s [mpeg]\n", dev->name, video_device_node_name(dev->empress_dev)); videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_ALTERNATE, sizeof(struct saa7134_buf), dev); empress_signal_update(&dev->empress_workqueue); return 0; }
static int video_open(struct saa7146_dev *dev, struct file *file) { struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data; struct saa7146_format *sfmt; fh->video_fmt.width = 384; fh->video_fmt.height = 288; fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24; fh->video_fmt.bytesperline = 0; fh->video_fmt.field = V4L2_FIELD_ANY; sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8; videobuf_queue_sg_init(&fh->video_q, &video_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct saa7146_buf), file); return 0; }
static int attach_xc3028(u8 addr, struct cx8802_dev *dev) { struct dvb_frontend *fe; struct videobuf_dvb_frontend *fe0 = NULL; struct xc2028_ctrl ctl; struct xc2028_config cfg = { .i2c_adap = &dev->core->i2c_adap, .i2c_addr = addr, .ctrl = &ctl, }; /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); if (!fe0) return -EINVAL; if (!fe0->dvb.frontend) { printk(KERN_ERR "%s/2: dvb frontend not attached. " "Can't attach xc3028\n", dev->core->name); return -EINVAL; } /* * Some xc3028 devices may be hidden by an I2C gate. This is known * to happen with some s5h1409-based devices. * Now that I2C gate is open, sets up xc3028 configuration */ cx88_setup_xc3028(dev->core, &ctl); fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->core->name); dvb_frontend_detach(fe0->dvb.frontend); dvb_unregister_frontend(fe0->dvb.frontend); fe0->dvb.frontend = NULL; return -EINVAL; } printk(KERN_INFO "%s/2: xc3028 attached\n", dev->core->name); return 0; } static int cx24116_set_ts_param(struct dvb_frontend *fe, int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; dev->ts_gen_cntrl = 0x2; return 0; } static int cx24116_reset_device(struct dvb_frontend *fe) { struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; /* Reset the part */ /* Put the cx24116 into reset */ cx_write(MO_SRST_IO, 0); msleep(10); /* Take the cx24116 out of reset */ cx_write(MO_SRST_IO, 1); msleep(10); return 0; } static struct cx24116_config hauppauge_hvr4000_config = { .demod_address = 0x05, .set_ts_params = cx24116_set_ts_param, .reset_device = cx24116_reset_device, }; static struct cx24116_config tevii_s460_config = { .demod_address = 0x55, .set_ts_params = cx24116_set_ts_param, .reset_device = cx24116_reset_device, }; static struct stv0299_config tevii_tuner_sharp_config = { .demod_address = 0x68, .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_ts_params = cx24116_set_ts_param, }; static struct stv0288_config tevii_tuner_earda_config = { .demod_address = 0x68, .min_delay_ms = 100, .set_ts_params = cx24116_set_ts_param, }; static int cx8802_alloc_frontends(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; struct videobuf_dvb_frontend *fe = NULL; int i; mutex_init(&dev->frontends.lock); INIT_LIST_HEAD(&dev->frontends.felist); if (!core->board.num_frontends) return -ENODEV; printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); for (i = 1; i <= core->board.num_frontends; i++) { fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); if (!fe) { printk(KERN_ERR "%s() failed to alloc\n", __func__); videobuf_dvb_dealloc_frontends(&dev->frontends); return -ENOMEM; } } return 0; } static int dvb_register(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; 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) goto frontend_detach; /* multi-frontend gate control is undefined or defaults to fe0 */ dev->frontends.gate = 0; /* Sets the gate control callback to be used by i2c command calls */ core->gate_ctrl = cx88_dvb_gate_ctrl; /* init frontend(s) */ switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_DVB_T1: fe0->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, &core->i2c_adap, DVB_PLL_THOMSON_DTT759X)) goto frontend_detach; } break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: fe0->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_WINFAST_DTV2000H: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: case CX88_BOARD_HAUPPAUGE_HVR1300: fe0->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } 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); if (fe0->dvb.frontend) { if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) goto frontend_detach; } /* MFE frontend 2 */ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 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: fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* The tin box says DEE1601, but it seems to be DTT7579 * compatible, with a slightly different MT352 AGC gain. */ fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_LG_Z201)) goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_UNKNOWN_1)) goto frontend_detach; } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) /* MT352 is on a secondary I2C bus made from some GPIO lines */ fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &dev->vp3054->adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } #else printk(KERN_ERR "%s/2: built without vp3054 support\n", core->name); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_FE6600)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &core->i2c_adap); if (fe0->dvb.frontend == NULL) fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_mt352_xc3028, &core->i2c_adap); /* * On this board, the demod provides the I2C bus pullup. * We must not permit gate_ctrl to be performed, or * the xc3028 cannot communicate on the bus. */ if (fe0->dvb.frontend) fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_PCHDTV_HD3000: fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); /* Select RF connector callback */ fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_MICROTUNE_4042FI5)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } break; case CX88_BOARD_PCHDTV_HD5500: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } break; case CX88_BOARD_ATI_HDTVWONDER: fe0->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_TUV1236D)) goto frontend_detach; } break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: fe0->dvb.frontend = dvb_attach(cx24123_attach, &hauppauge_novas_config, &core->i2c_adap); if (fe0->dvb.frontend) { if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, &core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVBS_100: fe0->dvb.frontend = dvb_attach(cx24123_attach, &kworld_dvbs_100_config, &core->i2c_adap); if (fe0->dvb.frontend) { core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; } break; case CX88_BOARD_GENIATECH_DVBS: fe0->dvb.frontend = dvb_attach(cx24123_attach, &geniatech_dvbs_config, &core->i2c_adap); if (fe0->dvb.frontend) { core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; } break; case CX88_BOARD_PINNACLE_PCTV_HD_800i: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &pinnacle_pctv_hd_800i_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, &core->i2c_adap, &pinnacle_pctv_hd_800i_tuner_config)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_hdtv5_pci_nano_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &core->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .scode_table = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX88_BOARD_PINNACLE_HYBRID_PCTV: fe0->dvb.frontend = dvb_attach(zl10353_attach, &cx88_pinnacle_hybrid_pctv, &core->i2c_adap); if (fe0->dvb.frontend) { fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; } break; case CX88_BOARD_GENIATECH_X8000_MT: dev->ts_gen_cntrl = 0x00; fe0->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_KWORLD_ATSC_120: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &kworld_atsc_120_config, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: fe0->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_fusionhdtv7_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, &core->i2c_adap, &dvico_fusionhdtv7_tuner_config)) goto frontend_detach; } 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); if (fe0->dvb.frontend) { if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) goto frontend_detach; } /* MFE frontend 2 */ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 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); if (fe0->dvb.frontend) { 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, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_OPERA1)) goto frontend_detach; core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; } else { fe0->dvb.frontend = dvb_attach(stv0288_attach, &tevii_tuner_earda_config, &core->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61, &core->i2c_adap)) goto frontend_detach; core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; } } break; case CX88_BOARD_TEVII_S460: fe0->dvb.frontend = dvb_attach(cx24116_attach, &tevii_s460_config, &core->i2c_adap); 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) fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; break; case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII: fe0->dvb.frontend = dvb_attach(zl10353_attach, &cx88_terratec_cinergy_ht_pci_mkii_config, &core->i2c_adap); if (fe0->dvb.frontend) { fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", core->name); break; } if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) { printk(KERN_ERR "%s/2: frontend initialization failed\n", core->name); goto frontend_detach; } /* define general-purpose callback pointer */ fe0->dvb.frontend->callback = cx88_tuner_callback; /* Ensure all frontends negotiate bus access */ fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; if (fe1) fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ call_all(core, tuner, s_standby); /* register everything */ return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, &dev->pci->dev, adapter_nr, mfe_shared); frontend_detach: core->gate_ctrl = NULL; videobuf_dvb_dealloc_frontends(&dev->frontends); return -EINVAL; } /* ----------------------------------------------------------- */ /* CX8802 MPEG -> mini driver - We have been given the hardware */ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* We arrive here with either the cx23416 or the cx22702 * on the bus. Take the bus from the cx23416 and enable the * cx22702 demod */ /* Toggle reset on cx22702 leaving i2c active */ cx_set(MO_GP0_IO, 0x00000080); udelay(1000); cx_clear(MO_GP0_IO, 0x00000080); udelay(50); cx_set(MO_GP0_IO, 0x00000080); udelay(1000); /* enable the cx22702 pins */ cx_clear(MO_GP0_IO, 0x00000004); udelay(1000); break; case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR4000: /* Toggle reset on cx22702 leaving i2c active */ cx_set(MO_GP0_IO, 0x00000080); udelay(1000); cx_clear(MO_GP0_IO, 0x00000080); udelay(50); cx_set(MO_GP0_IO, 0x00000080); udelay(1000); switch (core->dvbdev->frontends.active_fe_id) { case 1: /* DVB-S/S2 Enabled */ /* tri-state the cx22702 pins */ cx_set(MO_GP0_IO, 0x00000004); /* Take the cx24116/cx24123 out of reset */ cx_write(MO_SRST_IO, 1); core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */ break; case 2: /* DVB-T Enabled */ /* Put the cx24116/cx24123 into reset */ cx_write(MO_SRST_IO, 0); /* enable the cx22702 pins */ cx_clear(MO_GP0_IO, 0x00000004); core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */ break; } udelay(1000); break; default: err = -ENODEV; } return err; } /* CX8802 MPEG -> mini driver - We no longer have the hardware */ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* Do Nothing, leave the cx22702 on the bus. */ break; case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR4000: break; default: err = -ENODEV; } return err; } static int cx8802_dvb_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; int err; struct videobuf_dvb_frontend *fe; int i; dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->boardnr, core->name, core->pci_bus, core->pci_slot); err = -ENODEV; if (!(core->board.mpeg & CX88_MPEG_DVB)) goto fail_core; /* If vp3054 isn't enabled, a stub will just return 0 */ err = vp3054_i2c_probe(dev); if (0 != err) goto fail_core; /* dvb stuff */ printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); dev->ts_gen_cntrl = 0x0c; err = cx8802_alloc_frontends(dev); if (err) goto fail_core; err = -ENODEV; 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; } err = dvb_register(dev); 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); core->gate_ctrl = NULL; return 0; } static struct cx8802_driver cx8802_dvb_driver = { .type_id = CX88_MPEG_DVB, .hw_access = CX8802_DRVCTL_SHARED, .probe = cx8802_dvb_probe, .remove = cx8802_dvb_remove, .advise_acquire = cx8802_dvb_advise_acquire, .advise_release = cx8802_dvb_advise_release, }; static int dvb_init(void) { printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, CX88_VERSION_CODE & 0xff); #ifdef SNAPSHOT printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif return cx8802_register_driver(&cx8802_dvb_driver); } static void dvb_fini(void) { cx8802_unregister_driver(&cx8802_dvb_driver); } module_init(dvb_init); module_exit(dvb_fini);
static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; struct videobuf_dvb_frontend *fe0; int ret; /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (!fe0) return -EINVAL; /* init struct videobuf_dvb */ fe0->dvb.name = dev->name; /* init frontend */ switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt3305_attach, &hauppauge_lgdt3305_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr127x_config); } /* FIXME: temporary hack */ /* define bridge override to set_frontend */ port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend; fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend; break; case CX23885_BOARD_HAUPPAUGE_HVR1255: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; switch (alt_tuner) { case 1: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case 0: default: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); break; } break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_hvr1500q_tunerconfig); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1200_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1210: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1210_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1210_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1400: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(dib7000p_attach, &i2c_bus->i2c_adap, 0x12, &hauppauge_hvr1400_dib7000_config); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, }; static struct xc2028_ctrl ctl = { .fname = XC3028L_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_DIBCOM52, /* This is true for all demods with v36 firmware? */ .type = XC2028_D2633, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend == NULL) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; } case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_TBS_6920: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &tbs_cx24116_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; break; case CX23885_BOARD_TEVII_S470: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &tevii_cx24116_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; break; case CX23885_BOARD_DVBWORLD_2005: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &dvbworld_cx24116_config, &i2c_bus->i2c_adap); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: i2c_bus = &dev->i2c_bus[0]; switch (port->nr) { /* port B */ case 1: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 0); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_a, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL, LNBH24_TTX, 0x09)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; /* port C */ case 2: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 1); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_b, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL, LNBH24_TTX, 0x0a)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; } break; case CX23885_BOARD_MYGICA_X8506: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &mygica_x8506_lgs8gl5_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &mygica_x8506_xc5000_config); } break; case CX23885_BOARD_MAGICPRO_PROHDTVE2: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &magicpro_prohdtve2_lgs8g75_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &magicpro_prohdtve2_xc5000_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1850: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[0].i2c_adap, &hauppauge_tda18271_config); break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", dev->name); break; } if (NULL == fe0->dvb.frontend) { printk(KERN_ERR "%s: frontend initialization failed\n", dev->name); return -1; } /* define general-purpose callback pointer */ fe0->dvb.frontend->callback = cx23885_tuner_callback; /* Put the analog decoder in standby to keep it quiet */ call_all(dev, tuner, s_standby); if (fe0->dvb.frontend->ops.analog_ops.standby) fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); /* register everything */ ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, &dev->pci->dev, adapter_nr, 0); /* init CI & MAC */ switch (dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: { static struct netup_card_info cinfo; netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); memcpy(port->frontends.adapter.proposed_mac, cinfo.port[port->nr - 1].mac, 6); printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=" "%02X:%02X:%02X:%02X:%02X:%02X\n", port->nr, port->frontends.adapter.proposed_mac[0], port->frontends.adapter.proposed_mac[1], port->frontends.adapter.proposed_mac[2], port->frontends.adapter.proposed_mac[3], port->frontends.adapter.proposed_mac[4], port->frontends.adapter.proposed_mac[5]); netup_ci_init(port); break; } } return ret; } int cx23885_dvb_register(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; struct cx23885_dev *dev = port->dev; int err, i; /* Here we need to allocate the correct number of frontends, * as reflected in the cards struct. The reality is that currently * no cx23885 boards support this - yet. But, if we don't modify this * code then the second frontend would never be allocated (later) * and fail with error before the attach in dvb_register(). * Without these changes we risk an OOPS later. The changes here * are for safety, and should provide a good foundation for the * future addition of any multi-frontend cx23885 based boards. */ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, port->num_frontends); for (i = 1; i <= port->num_frontends; i++) { if (videobuf_dvb_alloc_frontend( &port->frontends, i) == NULL) { printk(KERN_ERR "%s() failed to alloc\n", __func__); return -ENOMEM; } fe0 = videobuf_dvb_get_frontend(&port->frontends, i); if (!fe0) err = -EINVAL; dprintk(1, "%s\n", __func__); dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", dev->board, dev->name, dev->pci_bus, dev->pci_slot); err = -ENODEV; /* dvb stuff */ /* We have to init the queue for each frontend on a port. */ printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx23885_buffer), port); } err = dvb_register(port); if (err != 0) printk(KERN_ERR "%s() dvb_register failed err = %d\n", __func__, err); return err; } int cx23885_dvb_unregister(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; /* FIXME: in an error condition where the we have * an expected number of frontends (attach problem) * then this might not clean up correctly, if 1 * is invalid. * This comment only applies to future boards IF they * implement MFE support. */ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (fe0->dvb.frontend) videobuf_dvb_unregister_bus(&port->frontends); switch (port->dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: netup_ci_exit(port); break; } return 0; }
static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; struct videobuf_dvb_frontend *fe0, *fe1 = NULL; int mfe_shared = 0; int ret; fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (!fe0) return -EINVAL; fe0->dvb.name = dev->name; port->frontends.gate = 0; port->gate_ctrl = cx23885_dvb_gate_ctrl; switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt3305_attach, &hauppauge_lgdt3305_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr127x_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1255: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; switch (alt_tuner) { case 1: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case 0: default: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); break; } break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_hvr1500q_tunerconfig); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1200_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1210: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1210_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1210_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1400: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(dib7000p_attach, &i2c_bus->i2c_adap, 0x12, &hauppauge_hvr1400_dib7000_config); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, }; static struct xc2028_ctrl ctl = { .fname = XC3028L_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_DIBCOM52, .type = XC2028_D2633, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend == NULL) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; } case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc4000_config cfg = { .i2c_address = 0x61, .default_pm = 0, .dvb_amplitude = 134, .set_smoothedcvbs = 1, .if_khz = 4560 }; fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc4000 attach failed\n", dev->name); goto frontend_detach; } } break; case CX23885_BOARD_TBS_6920: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &tbs_cx24116_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; break; case CX23885_BOARD_TEVII_S470: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(ds3000_attach, &tevii_ds3000_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; break; case CX23885_BOARD_DVBWORLD_2005: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &dvbworld_cx24116_config, &i2c_bus->i2c_adap); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: i2c_bus = &dev->i2c_bus[0]; switch (port->nr) { case 1: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 0); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_a, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL | LNBH24_TTX, LNBH24_TEN, 0x09)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; case 2: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 1); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_b, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL | LNBH24_TTX, LNBH24_TEN, 0x0a)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; } break; case CX23885_BOARD_MYGICA_X8506: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &mygica_x8506_lgs8gl5_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &mygica_x8506_xc5000_config); } break; case CX23885_BOARD_MAGICPRO_PROHDTVE2: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &magicpro_prohdtve2_lgs8g75_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &magicpro_prohdtve2_xc5000_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1850: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[0].i2c_adap, &hauppauge_tda18271_config); tda18271_attach(&dev->ts1.analog_fe, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); break; case CX23885_BOARD_HAUPPAUGE_HVR1290: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[0].i2c_adap, &hauppauge_tda18271_config); break; case CX23885_BOARD_MYGICA_X8558PRO: switch (port->nr) { case 1: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(atbm8830_attach, &mygica_x8558pro_atbm8830_cfg1, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(max2165_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &mygic_x8558pro_max2165_cfg1); } break; case 2: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(atbm8830_attach, &mygica_x8558pro_atbm8830_cfg2, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(max2165_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &mygic_x8558pro_max2165_cfg2); } break; } break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: i2c_bus = &dev->i2c_bus[0]; mfe_shared = 1; port->frontends.gate = 0; fe0->dvb.frontend = dvb_attach(stv0367ter_attach, &netup_stv0367_config[port->nr - 1], &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { if (NULL == dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &netup_xc5000_config[port->nr - 1])) goto frontend_detach; fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); } fe1 = videobuf_dvb_get_frontend(&port->frontends, 2); if (fe1 == NULL) goto frontend_detach; fe1->dvb.frontend = dvb_attach(stv0367cab_attach, &netup_stv0367_config[port->nr - 1], &i2c_bus->i2c_adap); if (fe1->dvb.frontend != NULL) { fe1->dvb.frontend->id = 1; if (NULL == dvb_attach(xc5000_attach, fe1->dvb.frontend, &i2c_bus->i2c_adap, &netup_xc5000_config[port->nr - 1])) goto frontend_detach; } break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; switch (port->nr) { case 1: fe0->dvb.frontend = dvb_attach(drxk_attach, &terratec_drxk_config[0], &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(mt2063_attach, fe0->dvb.frontend, &terratec_mt2063_config[0], &i2c_bus2->i2c_adap)) goto frontend_detach; } break; case 2: fe0->dvb.frontend = dvb_attach(drxk_attach, &terratec_drxk_config[1], &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(mt2063_attach, fe0->dvb.frontend, &terratec_mt2063_config[1], &i2c_bus2->i2c_adap)) goto frontend_detach; } break; } break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", dev->name); break; } if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) { printk(KERN_ERR "%s: frontend initialization failed\n", dev->name); goto frontend_detach; } fe0->dvb.frontend->callback = cx23885_tuner_callback; if (fe1) fe1->dvb.frontend->callback = cx23885_tuner_callback; #if 0 fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; if (fe1) fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; #endif call_all(dev, core, s_power, 0); if (fe0->dvb.frontend->ops.analog_ops.standby) fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, &dev->pci->dev, adapter_nr, mfe_shared, NULL); if (ret) goto frontend_detach; switch (dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: { static struct netup_card_info cinfo; netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); memcpy(port->frontends.adapter.proposed_mac, cinfo.port[port->nr - 1].mac, 6); printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n", port->nr, port->frontends.adapter.proposed_mac); netup_ci_init(port); break; } case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: { struct altera_ci_config netup_ci_cfg = { .dev = dev, .adapter = &port->frontends.adapter, .demux = &fe0->dvb.demux, .fpga_rw = netup_altera_fpga_rw, }; altera_ci_init(&netup_ci_cfg, port->nr); break; } case CX23885_BOARD_TEVII_S470: { u8 eeprom[256]; if (port->nr != 1) break; dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); printk(KERN_INFO "TeVii S470 MAC= %pM\n", eeprom + 0xa0); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); break; } } return ret; frontend_detach: port->gate_ctrl = NULL; videobuf_dvb_dealloc_frontends(&port->frontends); return -EINVAL; } int cx23885_dvb_register(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; struct cx23885_dev *dev = port->dev; int err, i; printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, port->num_frontends); for (i = 1; i <= port->num_frontends; i++) { if (videobuf_dvb_alloc_frontend( &port->frontends, i) == NULL) { printk(KERN_ERR "%s() failed to alloc\n", __func__); return -ENOMEM; } fe0 = videobuf_dvb_get_frontend(&port->frontends, i); if (!fe0) err = -EINVAL; dprintk(1, "%s\n", __func__); dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", dev->board, dev->name, dev->pci_bus, dev->pci_slot); err = -ENODEV; printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx23885_buffer), port, NULL); } err = dvb_register(port); if (err != 0) printk(KERN_ERR "%s() dvb_register failed err = %d\n", __func__, err); return err; } int cx23885_dvb_unregister(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (fe0 && fe0->dvb.frontend) videobuf_dvb_unregister_bus(&port->frontends); switch (port->dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: netup_ci_exit(port); break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: altera_ci_release(port->dev, port->nr); break; } port->gate_ctrl = NULL; return 0; }
static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL; struct videobuf_dvb_frontend *fe0; /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (!fe0) return -EINVAL; /* init struct videobuf_dvb */ fe0->dvb.name = dev->name; /* init frontend */ switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; switch (alt_tuner) { case 1: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case 0: default: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); break; } break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_hvr1500q_tunerconfig); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .scode_table = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1200_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1400: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(dib7000p_attach, &i2c_bus->i2c_adap, 0x12, &hauppauge_hvr1400_dib7000_config); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, }; static struct xc2028_ctrl ctl = { .fname = XC3028L_DEFAULT_FIRMWARE, .max_len = 64, .demod = 5000, /* This is true for all demods with v36 firmware? */ .type = XC2028_D2633, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend == NULL) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; } case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", dev->name); break; } if (NULL == fe0->dvb.frontend) { printk(KERN_ERR "%s: frontend initialization failed\n", dev->name); return -1; } /* define general-purpose callback pointer */ fe0->dvb.frontend->callback = cx23885_tuner_callback; /* Put the analog decoder in standby to keep it quiet */ cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); if (fe0->dvb.frontend->ops.analog_ops.standby) fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); /* register everything */ return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, &dev->pci->dev, adapter_nr, 0); } int cx23885_dvb_register(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; struct cx23885_dev *dev = port->dev; int err, i; /* Here we need to allocate the correct number of frontends, * as reflected in the cards struct. The reality is that currrently * no cx23885 boards support this - yet. But, if we don't modify this * code then the second frontend would never be allocated (later) * and fail with error before the attach in dvb_register(). * Without these changes we risk an OOPS later. The changes here * are for safety, and should provide a good foundation for the * future addition of any multi-frontend cx23885 based boards. */ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, port->num_frontends); for (i = 1; i <= port->num_frontends; i++) { if (videobuf_dvb_alloc_frontend( &port->frontends, i) == NULL) { printk(KERN_ERR "%s() failed to alloc\n", __func__); return -ENOMEM; } fe0 = videobuf_dvb_get_frontend(&port->frontends, i); if (!fe0) err = -EINVAL; dprintk(1, "%s\n", __func__); dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", dev->board, dev->name, dev->pci_bus, dev->pci_slot); err = -ENODEV; /* dvb stuff */ /* We have to init the queue for each frontend on a port. */ printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx23885_buffer), port); } err = dvb_register(port); if (err != 0) printk(KERN_ERR "%s() dvb_register failed err = %d\n", __func__, err); return err; } int cx23885_dvb_unregister(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; /* FIXME: in an error condition where the we have * an expected number of frontends (attach problem) * then this might not clean up correctly, if 1 * is invalid. * This comment only applies to future boards IF they * implement MFE support. */ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (fe0->dvb.frontend) videobuf_dvb_unregister_bus(&port->frontends); return 0; }
static int attach_xc3028(u8 addr, struct cx8802_dev *dev) { struct dvb_frontend *fe; struct xc2028_ctrl ctl; struct xc2028_config cfg = { .i2c_adap = &dev->core->i2c_adap, .i2c_addr = addr, .ctrl = &ctl, .callback = cx88_tuner_callback, }; if (!dev->dvb.frontend) { printk(KERN_ERR "%s/2: dvb frontend not attached. " "Can't attach xc3028\n", dev->core->name); return -EINVAL; } /* * Some xc3028 devices may be hidden by an I2C gate. This is known * to happen with some s5h1409-based devices. * Now that I2C gate is open, sets up xc3028 configuration */ cx88_setup_xc3028(dev->core, &ctl); fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->core->name); return -EINVAL; } printk(KERN_INFO "%s/2: xc3028 attached\n", dev->core->name); return 0; } static int dvb_register(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; /* init struct videobuf_dvb */ dev->dvb.name = core->name; dev->ts_gen_cntrl = 0x0c; /* init frontend */ switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_DVB_T1: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &core->i2c_adap, DVB_PLL_THOMSON_DTT759X)) goto frontend_detach; } break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_WINFAST_DTV2000H: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: case CX88_BOARD_HAUPPAUGE_HVR1300: case CX88_BOARD_HAUPPAUGE_HVR3000: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* The tin box says DEE1601, but it seems to be DTT7579 * compatible, with a slightly different MT352 AGC gain. */ dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_LG_Z201)) goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_UNKNOWN_1)) goto frontend_detach; } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) /* MT352 is on a secondary I2C bus made from some GPIO lines */ dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &dev->vp3054->adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } #else printk(KERN_ERR "%s/2: built without vp3054 support\n", core->name); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_FE6600)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &core->i2c_adap); if (dev->dvb.frontend == NULL) dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_mt352_xc3028, &core->i2c_adap); /* * On this board, the demod provides the I2C bus pullup. * We must not permit gate_ctrl to be performed, or * the xc3028 cannot communicate on the bus. */ if (dev->dvb.frontend) dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) return -EINVAL; break; case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); /* Select RF connector callback */ fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_MICROTUNE_4042FI5)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, dev->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } break; case CX88_BOARD_PCHDTV_HD5500: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, dev->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } break; case CX88_BOARD_ATI_HDTVWONDER: dev->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_TUV1236D)) goto frontend_detach; } break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: dev->dvb.frontend = dvb_attach(cx24123_attach, &hauppauge_novas_config, &core->i2c_adap); if (dev->dvb.frontend) { if (!dvb_attach(isl6421_attach, dev->dvb.frontend, &core->i2c_adap, 0x08, 0x00, 0x00)) goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVBS_100: dev->dvb.frontend = dvb_attach(cx24123_attach, &kworld_dvbs_100_config, &core->i2c_adap); if (dev->dvb.frontend) { core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; } break; case CX88_BOARD_GENIATECH_DVBS: dev->dvb.frontend = dvb_attach(cx24123_attach, &geniatech_dvbs_config, &core->i2c_adap); if (dev->dvb.frontend) { core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; } break; case CX88_BOARD_PINNACLE_PCTV_HD_800i: dev->dvb.frontend = dvb_attach(s5h1409_attach, &pinnacle_pctv_hd_800i_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { /* tuner_config.video_dev must point to * i2c_adap.algo_data */ if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, &pinnacle_pctv_hd_800i_tuner_config, core->i2c_adap.algo_data)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: dev->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_hdtv5_pci_nano_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &core->i2c_adap, .i2c_addr = 0x61, .callback = cx88_pci_nano_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", .max_len = 64, .scode_table = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX88_BOARD_PINNACLE_HYBRID_PCTV: dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_GENIATECH_X8000_MT: dev->ts_gen_cntrl = 0x00; dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_KWORLD_ATSC_120: dev->dvb.frontend = dvb_attach(s5h1409_attach, &kworld_atsc_120_config, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: dev->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_fusionhdtv7_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { /* tuner_config.video_dev must point to * i2c_adap.algo_data */ if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, &dvico_fusionhdtv7_tuner_config, core->i2c_adap.algo_data)) goto frontend_detach; } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", core->name); break; } if (NULL == dev->dvb.frontend) { printk(KERN_ERR "%s/2: frontend initialization failed\n", core->name); return -EINVAL; } /* Ensure all frontends negotiate bus access */ dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, adapter_nr); frontend_detach: if (dev->dvb.frontend) { dvb_frontend_detach(dev->dvb.frontend); dev->dvb.frontend = NULL; } return -EINVAL; } /* ----------------------------------------------------------- */ /* CX8802 MPEG -> mini driver - We have been given the hardware */ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* We arrive here with either the cx23416 or the cx22702 * on the bus. Take the bus from the cx23416 and enable the * cx22702 demod */ cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ cx_clear(MO_GP0_IO, 0x00000004); udelay(1000); break; default: err = -ENODEV; } return err; } /* CX8802 MPEG -> mini driver - We no longer have the hardware */ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* Do Nothing, leave the cx22702 on the bus. */ break; default: err = -ENODEV; } return err; } static int cx8802_dvb_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; int err; dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->boardnr, core->name, core->pci_bus, core->pci_slot); err = -ENODEV; if (!(core->board.mpeg & CX88_MPEG_DVB)) goto fail_core; /* If vp3054 isn't enabled, a stub will just return 0 */ err = vp3054_i2c_probe(dev); if (0 != err) goto fail_core; /* dvb stuff */ printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer), dev); err = dvb_register(dev); if (err != 0) printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", core->name, err); fail_core: return err; } static int cx8802_dvb_remove(struct cx8802_driver *drv) { struct cx8802_dev *dev = drv->core->dvbdev; /* dvb */ if (dev->dvb.frontend) videobuf_dvb_unregister(&dev->dvb); vp3054_i2c_remove(dev); return 0; } static struct cx8802_driver cx8802_dvb_driver = { .type_id = CX88_MPEG_DVB, .hw_access = CX8802_DRVCTL_SHARED, .probe = cx8802_dvb_probe, .remove = cx8802_dvb_remove, .advise_acquire = cx8802_dvb_advise_acquire, .advise_release = cx8802_dvb_advise_release, }; static int dvb_init(void) { printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, CX88_VERSION_CODE & 0xff); #ifdef SNAPSHOT printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif return cx8802_register_driver(&cx8802_dvb_driver); } static void dvb_fini(void) { cx8802_unregister_driver(&cx8802_dvb_driver); } module_init(dvb_init); module_exit(dvb_fini);
static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; struct videobuf_dvb_frontend *fe0, *fe1 = NULL; int mfe_shared = 0; /* bus not shared by default */ int ret; /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (!fe0) return -EINVAL; /* init struct videobuf_dvb */ fe0->dvb.name = dev->name; /* multi-frontend gate control is undefined or defaults to fe0 */ port->frontends.gate = 0; /* Sets the gate control callback to be used by i2c command calls */ port->gate_ctrl = cx23885_dvb_gate_ctrl; /* init frontend */ switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt3305_attach, &hauppauge_lgdt3305_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr127x_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } tda18271_attach(&dev->ts1.analog_fe, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; switch (alt_tuner) { case 1: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case 0: default: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); break; } break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_hvr1500q_tunerconfig); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1200_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1210: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1210_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1210_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1400: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(dib7000p_attach, &i2c_bus->i2c_adap, 0x12, &hauppauge_hvr1400_dib7000_config); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, }; static struct xc2028_ctrl ctl = { .fname = XC3028L_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_DIBCOM52, /* This is true for all demods with v36 firmware? */ .type = XC2028_D2633, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend == NULL) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; } case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc4000_config cfg = { .i2c_address = 0x61, .default_pm = 0, .dvb_amplitude = 134, .set_smoothedcvbs = 1, .if_khz = 4560 }; fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc4000 attach failed\n", dev->name); goto frontend_detach; } } break; case CX23885_BOARD_TBS_6920: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &tbs_cx24116_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; break; case CX23885_BOARD_TEVII_S470: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(ds3000_attach, &tevii_ds3000_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(ts2020_attach, fe0->dvb.frontend, &tevii_ts2020_config, &i2c_bus->i2c_adap); fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; } break; case CX23885_BOARD_DVBWORLD_2005: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &dvbworld_cx24116_config, &i2c_bus->i2c_adap); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: i2c_bus = &dev->i2c_bus[0]; switch (port->nr) { /* port B */ case 1: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 0); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_a, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL | LNBH24_TTX, LNBH24_TEN, 0x09)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; /* port C */ case 2: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 1); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_b, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL | LNBH24_TTX, LNBH24_TEN, 0x0a)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; } break; case CX23885_BOARD_MYGICA_X8506: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &mygica_x8506_lgs8gl5_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &mygica_x8506_xc5000_config); } break; case CX23885_BOARD_MAGICPRO_PROHDTVE2: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &magicpro_prohdtve2_lgs8g75_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &magicpro_prohdtve2_xc5000_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1850: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[0].i2c_adap, &hauppauge_tda18271_config); tda18271_attach(&dev->ts1.analog_fe, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); break; case CX23885_BOARD_HAUPPAUGE_HVR1290: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[0].i2c_adap, &hauppauge_tda18271_config); break; case CX23885_BOARD_MYGICA_X8558PRO: switch (port->nr) { /* port B */ case 1: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(atbm8830_attach, &mygica_x8558pro_atbm8830_cfg1, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(max2165_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &mygic_x8558pro_max2165_cfg1); } break; /* port C */ case 2: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(atbm8830_attach, &mygica_x8558pro_atbm8830_cfg2, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(max2165_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &mygic_x8558pro_max2165_cfg2); } break; } break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: i2c_bus = &dev->i2c_bus[0]; mfe_shared = 1;/* MFE */ port->frontends.gate = 0;/* not clear for me yet */ /* ports B, C */ /* MFE frontend 1 DVB-T */ fe0->dvb.frontend = dvb_attach(stv0367ter_attach, &netup_stv0367_config[port->nr - 1], &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { if (NULL == dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &netup_xc5000_config[port->nr - 1])) goto frontend_detach; /* load xc5000 firmware */ fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); } /* MFE frontend 2 */ fe1 = videobuf_dvb_get_frontend(&port->frontends, 2); if (fe1 == NULL) goto frontend_detach; /* DVB-C init */ fe1->dvb.frontend = dvb_attach(stv0367cab_attach, &netup_stv0367_config[port->nr - 1], &i2c_bus->i2c_adap); if (fe1->dvb.frontend != NULL) { fe1->dvb.frontend->id = 1; if (NULL == dvb_attach(xc5000_attach, fe1->dvb.frontend, &i2c_bus->i2c_adap, &netup_xc5000_config[port->nr - 1])) goto frontend_detach; } break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; switch (port->nr) { /* port b */ case 1: fe0->dvb.frontend = dvb_attach(drxk_attach, &terratec_drxk_config[0], &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(mt2063_attach, fe0->dvb.frontend, &terratec_mt2063_config[0], &i2c_bus2->i2c_adap)) goto frontend_detach; } break; /* port c */ case 2: fe0->dvb.frontend = dvb_attach(drxk_attach, &terratec_drxk_config[1], &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(mt2063_attach, fe0->dvb.frontend, &terratec_mt2063_config[1], &i2c_bus2->i2c_adap)) goto frontend_detach; } break; } break; case CX23885_BOARD_TEVII_S471: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(ds3000_attach, &tevii_ds3000_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(ts2020_attach, fe0->dvb.frontend, &tevii_ts2020_config, &i2c_bus->i2c_adap); } break; case CX23885_BOARD_PROF_8000: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(stv090x_attach, &prof_8000_stv090x_config, &i2c_bus->i2c_adap, STV090x_DEMODULATOR_0); if (fe0->dvb.frontend != NULL) { if (!dvb_attach(stb6100_attach, fe0->dvb.frontend, &prof_8000_stb6100_config, &i2c_bus->i2c_adap)) goto frontend_detach; fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage; } break; case CX23885_BOARD_HAUPPAUGE_HVR4400: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10071_attach, &hauppauge_tda10071_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(a8293_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_a8293_config); } break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", dev->name); break; } if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) { printk(KERN_ERR "%s: frontend initialization failed\n", dev->name); goto frontend_detach; } /* define general-purpose callback pointer */ fe0->dvb.frontend->callback = cx23885_tuner_callback; if (fe1) fe1->dvb.frontend->callback = cx23885_tuner_callback; #if 0 /* Ensure all frontends negotiate bus access */ fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; if (fe1) fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; #endif /* Put the analog decoder in standby to keep it quiet */ call_all(dev, core, s_power, 0); if (fe0->dvb.frontend->ops.analog_ops.standby) fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); /* register everything */ ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, &dev->pci->dev, adapter_nr, mfe_shared); if (ret) goto frontend_detach; /* init CI & MAC */ switch (dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: { static struct netup_card_info cinfo; netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); memcpy(port->frontends.adapter.proposed_mac, cinfo.port[port->nr - 1].mac, 6); printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n", port->nr, port->frontends.adapter.proposed_mac); netup_ci_init(port); break; } case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: { struct altera_ci_config netup_ci_cfg = { .dev = dev,/* magic number to identify*/ .adapter = &port->frontends.adapter,/* for CI */ .demux = &fe0->dvb.demux,/* for hw pid filter */ .fpga_rw = netup_altera_fpga_rw, }; altera_ci_init(&netup_ci_cfg, port->nr); break; } case CX23885_BOARD_TEVII_S470: { u8 eeprom[256]; /* 24C02 i2c eeprom */ if (port->nr != 1) break; /* Read entire EEPROM */ dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); printk(KERN_INFO "TeVii S470 MAC= %pM\n", eeprom + 0xa0); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); break; } } return ret; frontend_detach: port->gate_ctrl = NULL; videobuf_dvb_dealloc_frontends(&port->frontends); return -EINVAL; } int cx23885_dvb_register(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; struct cx23885_dev *dev = port->dev; int err, i; /* Here we need to allocate the correct number of frontends, * as reflected in the cards struct. The reality is that currently * no cx23885 boards support this - yet. But, if we don't modify this * code then the second frontend would never be allocated (later) * and fail with error before the attach in dvb_register(). * Without these changes we risk an OOPS later. The changes here * are for safety, and should provide a good foundation for the * future addition of any multi-frontend cx23885 based boards. */ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, port->num_frontends); for (i = 1; i <= port->num_frontends; i++) { if (videobuf_dvb_alloc_frontend( &port->frontends, i) == NULL) { printk(KERN_ERR "%s() failed to alloc\n", __func__); return -ENOMEM; } fe0 = videobuf_dvb_get_frontend(&port->frontends, i); if (!fe0) err = -EINVAL; dprintk(1, "%s\n", __func__); dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", dev->board, dev->name, dev->pci_bus, dev->pci_slot); err = -ENODEV; /* dvb stuff */ /* We have to init the queue for each frontend on a port. */ printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx23885_buffer), port, NULL); } err = dvb_register(port); if (err != 0) printk(KERN_ERR "%s() dvb_register failed err = %d\n", __func__, err); return err; } int cx23885_dvb_unregister(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; /* FIXME: in an error condition where the we have * an expected number of frontends (attach problem) * then this might not clean up correctly, if 1 * is invalid. * This comment only applies to future boards IF they * implement MFE support. */ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (fe0 && fe0->dvb.frontend) videobuf_dvb_unregister_bus(&port->frontends); switch (port->dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: netup_ci_exit(port); break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: altera_ci_release(port->dev, port->nr); break; } port->gate_ctrl = NULL; return 0; }
static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; struct videobuf_dvb_frontend *fe0; int ret; fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (!fe0) return -EINVAL; fe0->dvb.name = dev->name; switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt3305_attach, &hauppauge_lgdt3305_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr127x_config); } port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend; fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend; break; case CX23885_BOARD_HAUPPAUGE_HVR1255: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; switch (alt_tuner) { case 1: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case 0: default: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); break; } break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(mt2131_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_hvr1500q_tunerconfig); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500_config, &dev->i2c_bus[0].i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda829x_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1200_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1210: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1210_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1210_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1400: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(dib7000p_attach, &i2c_bus->i2c_adap, 0x12, &hauppauge_hvr1400_dib7000_config); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, }; static struct xc2028_ctrl ctl = { .fname = XC3028L_DEFAULT_FIRMWARE, .max_len = 64, .demod = 5000, .type = XC2028_D2633, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend == NULL) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { i2c_bus = &dev->i2c_bus[port->nr - 1]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; } case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x61, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_TBS_6920: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &tbs_cx24116_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; break; case CX23885_BOARD_TEVII_S470: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &tevii_cx24116_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; break; case CX23885_BOARD_DVBWORLD_2005: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, &dvbworld_cx24116_config, &i2c_bus->i2c_adap); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: i2c_bus = &dev->i2c_bus[0]; switch (port->nr) { case 1: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 0); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_a, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL, LNBH24_TTX, 0x09)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; case 2: fe0->dvb.frontend = dvb_attach(stv0900_attach, &netup_stv0900_config, &i2c_bus->i2c_adap, 1); if (fe0->dvb.frontend != NULL) { if (dvb_attach(stv6110_attach, fe0->dvb.frontend, &netup_stv6110_tunerconfig_b, &i2c_bus->i2c_adap)) { if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, LNBH24_PCL, LNBH24_TTX, 0x0a)) printk(KERN_ERR "No LNBH24 found!\n"); } } break; } break; case CX23885_BOARD_MYGICA_X8506: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &mygica_x8506_lgs8gl5_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &mygica_x8506_xc5000_config); } break; case CX23885_BOARD_MAGICPRO_PROHDTVE2: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &magicpro_prohdtve2_lgs8g75_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) { dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus2->i2c_adap, &magicpro_prohdtve2_xc5000_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1850: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_bus[0].i2c_adap, &hauppauge_tda18271_config); break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", dev->name); break; } if (NULL == fe0->dvb.frontend) { printk(KERN_ERR "%s: frontend initialization failed\n", dev->name); return -1; } fe0->dvb.frontend->callback = cx23885_tuner_callback; call_all(dev, tuner, s_standby); if (fe0->dvb.frontend->ops.analog_ops.standby) fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, &dev->pci->dev, adapter_nr, 0); switch (dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: { static struct netup_card_info cinfo; netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); memcpy(port->frontends.adapter.proposed_mac, cinfo.port[port->nr - 1].mac, 6); printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=" "%02X:%02X:%02X:%02X:%02X:%02X\n", port->nr, port->frontends.adapter.proposed_mac[0], port->frontends.adapter.proposed_mac[1], port->frontends.adapter.proposed_mac[2], port->frontends.adapter.proposed_mac[3], port->frontends.adapter.proposed_mac[4], port->frontends.adapter.proposed_mac[5]); netup_ci_init(port); break; } } return ret; } int cx23885_dvb_register(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; struct cx23885_dev *dev = port->dev; int err, i; printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, port->num_frontends); for (i = 1; i <= port->num_frontends; i++) { if (videobuf_dvb_alloc_frontend( &port->frontends, i) == NULL) { printk(KERN_ERR "%s() failed to alloc\n", __func__); return -ENOMEM; } fe0 = videobuf_dvb_get_frontend(&port->frontends, i); if (!fe0) err = -EINVAL; dprintk(1, "%s\n", __func__); dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", dev->board, dev->name, dev->pci_bus, dev->pci_slot); err = -ENODEV; printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx23885_buffer), port); } err = dvb_register(port); if (err != 0) printk(KERN_ERR "%s() dvb_register failed err = %d\n", __func__, err); return err; } int cx23885_dvb_unregister(struct cx23885_tsport *port) { struct videobuf_dvb_frontend *fe0; fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); if (fe0->dvb.frontend) videobuf_dvb_unregister_bus(&port->frontends); switch (port->dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: netup_ci_exit(port); break; } return 0; }
static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL; /* init struct videobuf_dvb */ port->dvb.name = dev->name; /* init frontend */ switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: i2c_bus = &dev->i2c_bus[0]; port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) { dvb_attach(mt2131_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; switch (alt_tuner) { case 1: port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) { dvb_attach(tda829x_attach, port->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, port->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case 0: default: port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) dvb_attach(mt2131_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); break; } break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: i2c_bus = &dev->i2c_bus[0]; port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) { dvb_attach(mt2131_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; port->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) { dvb_attach(simple_tuner_attach, port->dvb.frontend, &i2c_bus->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_hvr1500q_tunerconfig, i2c_bus); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500_config, &dev->i2c_bus[0].i2c_adap); if (port->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, .callback = cx23885_hvr1500_xc3028_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", .max_len = 64, .scode_table = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, port->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: i2c_bus = &dev->i2c_bus[0]; port->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) { dvb_attach(tda829x_attach, port->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); dvb_attach(tda18271_attach, port->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1200_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1400: i2c_bus = &dev->i2c_bus[0]; port->dvb.frontend = dvb_attach(dib7000p_attach, &i2c_bus->i2c_adap, 0x12, &hauppauge_hvr1400_dib7000_config); if (port->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, .callback = cx23885_hvr1500_xc3028_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028L-v36.fw", .max_len = 64, .demod = 5000, .d2633 = 1 }; fe = dvb_attach(xc2028_attach, port->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: i2c_bus = &dev->i2c_bus[port->nr - 1]; port->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); if (port->dvb.frontend == NULL) port->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig, i2c_bus); break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); break; } if (NULL == port->dvb.frontend) { printk("%s: frontend initialization failed\n", dev->name); return -1; } /* Put the analog decoder in standby to keep it quiet */ cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); if (port->dvb.frontend->ops.analog_ops.standby) port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend); /* register everything */ return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, &dev->pci->dev, adapter_nr); } int cx23885_dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; int err; dprintk(1, "%s\n", __func__); dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", dev->board, dev->name, dev->pci_bus, dev->pci_slot); err = -ENODEV; /* dvb stuff */ printk("%s: cx23885 based dvb card\n", dev->name); videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx23885_buffer), port); err = dvb_register(port); if (err != 0) printk("%s() dvb_register failed err = %d\n", __func__, err); return err; } int cx23885_dvb_unregister(struct cx23885_tsport *port) { /* dvb */ if(port->dvb.frontend) videobuf_dvb_unregister(&port->dvb); return 0; }