예제 #1
0
int
main()
{
	unsigned int i = 0;

	for (i=0; i<5; i++) {
	  call_all();
	  write_data();
	  call_all();
	  read_data();
	}

	/* This won't hopefully return becasue it crashes */
	write_to_code();
	exit(0);
}
예제 #2
0
static void cx231xx_config_tuner(struct cx231xx *dev)
{
	struct tuner_setup tun_setup;
	struct v4l2_frequency f;

	if (dev->tuner_type == TUNER_ABSENT)
		return;

	tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
	tun_setup.type = dev->tuner_type;
	tun_setup.addr = dev->tuner_addr;
	tun_setup.tuner_callback = cx231xx_tuner_callback;

	tuner_call(dev, tuner, s_type_addr, &tun_setup);

#if 0
	if (tun_setup.type == TUNER_XC5000) {
		static struct xc2028_ctrl ctrl = {
			.fname = XC5000_DEFAULT_FIRMWARE,
			.max_len = 64,
			.demod = 0;
		};
		struct v4l2_priv_tun_config cfg = {
			.tuner = dev->tuner_type,
			.priv = &ctrl,
		};
		tuner_call(dev, tuner, s_config, &cfg);
	}
#endif
	/* configure tuner */
	f.tuner = 0;
	f.type = V4L2_TUNER_ANALOG_TV;
	f.frequency = 9076;	/* just a magic number */
	dev->ctl_freq = f.frequency;
	call_all(dev, tuner, s_frequency, &f);

}

void cx231xx_card_setup(struct cx231xx *dev)
{

	cx231xx_set_model(dev);

	dev->tuner_type = cx231xx_boards[dev->model].tuner_type;
	if (cx231xx_boards[dev->model].tuner_addr)
		dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr;

	/* request some modules */
	if (dev->board.decoder == CX231XX_AVDECODER) {
		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
					&dev->i2c_bus[0].i2c_adap,
					"cx25840", 0x88 >> 1, NULL);
		if (dev->sd_cx25840 == NULL)
			cx231xx_info("cx25840 subdev registration failure\n");
		cx25840_call(dev, core, load_fw);

	}
예제 #3
0
int cx88_video_mux(struct cx88_core *core, unsigned int input)
{
	

	dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
		input, INPUT(input).vmux,
		INPUT(input).gpio0,INPUT(input).gpio1,
		INPUT(input).gpio2,INPUT(input).gpio3);
	core->input = input;
	cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input).vmux << 14);
	cx_write(MO_GP3_IO, INPUT(input).gpio3);
	cx_write(MO_GP0_IO, INPUT(input).gpio0);
	cx_write(MO_GP1_IO, INPUT(input).gpio1);
	cx_write(MO_GP2_IO, INPUT(input).gpio2);

	switch (INPUT(input).type) {
	case CX88_VMUX_SVIDEO:
		cx_set(MO_AFECFG_IO,    0x00000001);
		cx_set(MO_INPUT_FORMAT, 0x00010010);
		cx_set(MO_FILTER_EVEN,  0x00002020);
		cx_set(MO_FILTER_ODD,   0x00002020);
		break;
	default:
		cx_clear(MO_AFECFG_IO,    0x00000001);
		cx_clear(MO_INPUT_FORMAT, 0x00010010);
		cx_clear(MO_FILTER_EVEN,  0x00002020);
		cx_clear(MO_FILTER_ODD,   0x00002020);
		break;
	}

	
	if (INPUT(input).audioroute) {
		
		if (core->board.audio_chip &&
		    core->board.audio_chip == V4L2_IDENT_WM8775) {
			call_all(core, audio, s_routing,
					INPUT(input).audioroute, 0, 0);
		}
		
		if (INPUT(input).type != CX88_VMUX_TELEVISION ) {
			
			core->tvaudio = WW_I2SADC;
			cx88_set_tvaudio(core);
		} else {
			
			cx_write(AUD_I2SCNTL, 0x0);
			cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
		}
	}

	return 0;
}
예제 #4
0
static ssize_t show_brightness(struct device *cd,
			       struct device_attribute *attr, char *buf)
{
	struct video_device *vdev =
		container_of(cd, struct video_device, dev);
	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
	struct v4l2_control ctrl;
	ctrl.id = V4L2_CID_BRIGHTNESS;
	ctrl.value = 0;
	if (usbvision->user)
		call_all(usbvision, core, g_ctrl, &ctrl);
	return sprintf(buf, "%d\n", ctrl.value);
}
예제 #5
0
static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
{
	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
		__func__,
		(unsigned int)norm,
		v4l2_norm_to_name(norm));

	dev->tvnorm = norm;

	call_all(dev, core, s_std, norm);

	return 0;
}
예제 #6
0
static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
{
	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
	struct mxb *mxb = (struct mxb *)dev->ext_priv;

	if (t->index) {
		DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
		return -EINVAL;
	}

	mxb->cur_mode = t->audmode;
	return call_all(dev, tuner, s_tuner, t);
}
예제 #7
0
int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
{
	struct v4l2_subdev_format format = {
		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
		.format.code = MEDIA_BUS_FMT_FIXED,
	};

	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
		__func__,
		(unsigned int)norm,
		v4l2_norm_to_name(norm));

	if (dev->tvnorm == norm)
		return 0;

	if (dev->tvnorm != norm) {
		if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
		    vb2_is_busy(&dev->vb2_mpegq))
			return -EBUSY;
	}

	dev->tvnorm = norm;
	dev->width = 720;
	dev->height = norm_maxh(norm);
	dev->field = V4L2_FIELD_INTERLACED;

	call_all(dev, video, s_std, norm);

	format.format.width = dev->width;
	format.format.height = dev->height;
	format.format.field = dev->field;
	call_all(dev, pad, set_fmt, NULL, &format);

	return 0;
}

static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
				    struct pci_dev *pci,
				    struct video_device *template,
예제 #8
0
int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
{
	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
		__func__,
		(unsigned int)norm,
		v4l2_norm_to_name(norm));

	if (dev->tvnorm != norm) {
		if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
		    vb2_is_busy(&dev->vb2_mpegq))
			return -EBUSY;
	}

	dev->tvnorm = norm;

	call_all(dev, video, s_std, norm);

	return 0;
}
예제 #9
0
static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
{
	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
	struct mxb *mxb = (struct mxb *)dev->ext_priv;

	if (t->index) {
		DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
		return -EINVAL;
	}

	DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));

	memset(t, 0, sizeof(*t));
	strlcpy(t->name, "TV Tuner", sizeof(t->name));
	t->type = V4L2_TUNER_ANALOG_TV;
	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
	t->audmode = mxb->cur_mode;
	return call_all(dev, tuner, g_tuner, t);
}
int cx23885_s_register(struct file *file, void *fh,
		       const struct v4l2_dbg_register *reg)
{
	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
		switch (reg->match.addr) {
		case 0:
			return cx23885_s_host_register(dev, reg);
		case 1:
			return cx23417_s_register(dev, reg);
		default:
			break;
		}
	}

	/* FIXME - any error returns should not be ignored */
	call_all(dev, core, s_register, reg);
	return 0;
}
예제 #11
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);
예제 #12
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;

	/* 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;
}
예제 #13
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;
}
예제 #14
0
static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
{
	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;

	return call_all(dev, core, s_register, reg);
}
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;
}
int cx23885_g_chip_ident(struct file *file, void *fh,
			 struct v4l2_dbg_chip_ident *chip)
{
	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
	int err = 0;
	u8 rev;

	chip->ident = V4L2_IDENT_NONE;
	chip->revision = 0;
	switch (chip->match.type) {
	case V4L2_CHIP_MATCH_HOST:
		switch (chip->match.addr) {
		case 0:
			rev = cx_read(RDR_CFG2) & 0xff;
			switch (dev->pci->device) {
			case 0x8852:
				/* rev 0x04 could be '885 or '888. Pick '888. */
				if (rev == 0x04)
					chip->ident = V4L2_IDENT_CX23888;
				else
					chip->ident = V4L2_IDENT_CX23885;
				break;
			case 0x8880:
				if (rev == 0x0e || rev == 0x0f)
					chip->ident = V4L2_IDENT_CX23887;
				else
					chip->ident = V4L2_IDENT_CX23888;
				break;
			default:
				chip->ident = V4L2_IDENT_UNKNOWN;
				break;
			}
			chip->revision = (dev->pci->device << 16) | (rev << 8) |
					 (dev->hwrevision & 0xff);
			break;
		case 1:
			if (dev->v4l_device != NULL) {
				chip->ident = V4L2_IDENT_CX23417;
				chip->revision = 0;
			}
			break;
		case 2:
			/*
			 * The integrated IR controller on the CX23888 is
			 * host chip 2.  It may not be used/initialized or sd_ir
			 * may be pointing at the cx25840 subdevice for the
			 * IR controller on the CX23885.  Thus we find it
			 * without using the dev->sd_ir pointer.
			 */
			call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
				chip);
			break;
		default:
			err = -EINVAL; /* per V4L2 spec */
			break;
		}
		break;
	case V4L2_CHIP_MATCH_I2C_DRIVER:
		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
		call_all(dev, core, g_chip_ident, chip);
		break;
	case V4L2_CHIP_MATCH_I2C_ADDR:
		/*
		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
		 * to look if a chip is at the address with no driver.  That's a
		 * dangerous thing to do with EEPROMs anyway.
		 */
		call_all(dev, core, g_chip_ident, chip);
		break;
	default:
		err = -EINVAL;
		break;
	}
	return err;
}
예제 #17
0
void
do_work(unsigned int start)
{
	unsigned int stack_array[STACK_ARRAY_ELEMS];
	unsigned int i = 0;
  unsigned int array1_start = start;
  unsigned int array2_start = start + (ELEMS / (ELEMS_PER_PAGE)) + 10;

  printf("Checking uninitialized array1 pid = %d\n", getpid());
	/* check the uninitialized array1 before initialization */
	for (i=0; i<ELEMS; i++) {
		if (array1[i] != 0) {
			printf("FAILED in file %s at line %d: array1[%d] = %u != %d\n", __FILE__, __LINE__, i, array1[i], 0);
			exit(1);
		}
	}

  printf("Checking uninitialized array2 pid = %d\n", getpid());
	/* check the uninitialized array2 before initialization */
	for (i=0; i<ELEMS; i++) {
		if (array2[i] != 0) {
			printf("FAILED in file %s at line %d: array2[%d] = %u != %d\n", __FILE__, __LINE__, i, array2[i], 0);
			exit(1);
		}
	}

	for (i=0; i<STACK_ARRAY_ELEMS; i++) {
		stack_array[i] = i * 1000;
	}

	for (i=0; i<2; i++) {
	  call_all();
	  write_data(array1, array1_start);
	  call_all();
    printf("Checking initialized array1 pid = %d\n", getpid());
	  read_data(array1, array1_start, "array1");
	}

	/* check the uninitialized array2 again before initialization */
  printf("Checking initialized array2 again pid = %d\n", getpid());
	for (i=0; i<ELEMS; i++) {
		if (array2[i] != 0) {
			printf("FAILED in file %s at line %d: array2[%d] = %u != %d\n", __FILE__, __LINE__, i, array2[i], 0);
			exit(1);
		}
	}

  printf("Checking initialized stack_array pid = %d\n", getpid());
	for (i=0; i<STACK_ARRAY_ELEMS; i++) {
		if (stack_array[i] != i * 1000) {
			printf("FAILED in file %s at line %d: stack_array[%d] = %u != %d\n", __FILE__, __LINE__, i, stack_array[i], i);
			exit(1);
		}
	}

  printf("Checking initialized init pid = %d\n", getpid());
	/* check the initialized array */
	for (i=0; i<INIT_ARRAY_ELEMS; i++) {
		if (init[i] != i) {
			printf("FAILED in file %s at line %d: init[%d] = %u != %d\n", __FILE__, __LINE__, i, init[i], i);
			exit(1);
		}
	}

	for (i=0; i<2; i++) {
	  call_all();
	  write_data(array2, array2_start);
	  call_all();
    printf("Checking initialized array2 pid = %d\n", getpid());
	  read_data(array2, array2_start, "array2");
	}

  printf("Checking initialized stack_array pid = %d\n", getpid());
	for (i=0; i<STACK_ARRAY_ELEMS; i++) {
		if (stack_array[i] != i * 1000) {
			printf("FAILED in file %s at line %d: stack_array[%d] = %u != %d\n", __FILE__, __LINE__, i, stack_array[i], i);
			exit(1);
		}
	}

	/* check the initialized array */
  printf("Checking initialized init pid = %d\n", getpid());
	for (i=0; i<INIT_ARRAY_ELEMS; i++) {
		if (init[i] != i) {
			printf("FAILED in file %s at line %d: init[%d] = %u != %d\n", __FILE__, __LINE__, i, init[i], i);
			exit(1);
		}
	}


  printf("Checking initialized array1 for the last time pid = %d\n", getpid());
	read_data(array1, array1_start, "array1");
  printf("Checking initialized array2 for the last time pid = %d\n", getpid());
	read_data(array2, array2_start, "array2");


	printf("Pid = %d SUCCEEDED\n", getpid());
}
int usbvision_i2c_register(struct usb_usbvision *usbvision)
{
	static unsigned short saa711x_addrs[] = {
		0x4a >> 1, 0x48 >> 1,	/*                               */
		0x42 >> 1, 0x40 >> 1,	/*                              */
		I2C_CLIENT_END };

	if (usbvision->registered_i2c)
		return 0;

	memcpy(&usbvision->i2c_adap, &i2c_adap_template,
	       sizeof(struct i2c_adapter));

	sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name,
		usbvision->dev->bus->busnum, usbvision->dev->devpath);
	PDEBUG(DBG_I2C, "Adaptername: %s", usbvision->i2c_adap.name);
	usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;

	i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);

	if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
		printk(KERN_ERR "usbvision_i2c_register: can't write reg\n");
		return -EBUSY;
	}

	PDEBUG(DBG_I2C, "I2C   debugging is enabled [i2c]");
	PDEBUG(DBG_I2C, "ALGO   debugging is enabled [i2c]");

	/*                                       */

	usbvision->i2c_adap.algo = &usbvision_algo;

	usbvision->i2c_adap.timeout = 100;	/*                              */
	usbvision->i2c_adap.retries = 3;	/*                              */

	i2c_add_adapter(&usbvision->i2c_adap);

	PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);

	/*                                             */
	switch (usbvision_device_data[usbvision->dev_model].codec) {
	case CODEC_SAA7113:
	case CODEC_SAA7111:
		/*                                                   
                   */
		mdelay(10);
		v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
				&usbvision->i2c_adap,
				"saa7115_auto", 0, saa711x_addrs);
		break;
	}
	if (usbvision_device_data[usbvision->dev_model].tuner == 1) {
		struct v4l2_subdev *sd;
		enum v4l2_i2c_tuner_type type;
		struct tuner_setup tun_setup;

		sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
				&usbvision->i2c_adap,
				"tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
		/*                                                     
                     */
		type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;

		sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
				&usbvision->i2c_adap,
				"tuner", 0, v4l2_i2c_tuner_addrs(type));

		if (sd == NULL)
			return -ENODEV;
		if (usbvision->tuner_type != -1) {
			tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
			tun_setup.type = usbvision->tuner_type;
			tun_setup.addr = v4l2_i2c_subdev_addr(sd);
			call_all(usbvision, tuner, s_type_addr, &tun_setup);
		}
	}
	usbvision->registered_i2c = 1;

	return 0;
}
예제 #19
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; /* 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;
}
예제 #20
0
int main() {
   functions f;
      f.emplace_back(&one);
      f.emplace_back(&two);
   call_all(f, 21);
}