⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 av7110_v4l.c

📁 linux_dvb的驱动程序:linuxtv-dvb-1.1.1.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume		return 0;	}	case VIDIOC_ENUMINPUT:	{		struct v4l2_input *i = arg;		DEB_EE(("VIDIOC_ENUMINPUT: %d\n", i->index));		if (av7110->has_analog_tuner ) {			if (i->index < 0 || i->index >= 2)				return -EINVAL;		} else {			if (i->index != 0)				return -EINVAL;		}		memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));		return 0;	}	case VIDIOC_G_INPUT:	{		int *input = (int *)arg;		*input = av7110->current_input;		DEB_EE(("VIDIOC_G_INPUT: %d\n", *input));		return 0;	}	case VIDIOC_S_INPUT:	{		int input = *(int *)arg;		DEB_EE(("VIDIOC_S_INPUT: %d\n", input));		if (!av7110->has_analog_tuner )			return 0;		if (input < 0 || input >= 2)			return -EINVAL;		/* FIXME: switch inputs here */		av7110->current_input = input;		return av7110_dvb_c_switch(fh);	}	case VIDIOC_G_AUDIO:	{		struct v4l2_audio *a = arg;		DEB_EE(("VIDIOC_G_AUDIO: %d\n", a->index));		if (a->index != 0)			return -EINVAL;		memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));		break;	}	case VIDIOC_S_AUDIO:	{		struct v4l2_audio *a = arg;		DEB_EE(("VIDIOC_S_AUDIO: %d\n", a->index));		break;	}	default:		printk("no such ioctl\n");		return -ENOIOCTLCMD;	}	return 0;}/**************************************************************************** * INITIALIZATION ****************************************************************************/struct saa7146_extension_ioctls ioctls[] = {	{ VIDIOC_ENUMINPUT,	SAA7146_EXCLUSIVE },	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },	{ VIDIOC_G_FREQUENCY,	SAA7146_EXCLUSIVE },	{ VIDIOC_S_FREQUENCY,	SAA7146_EXCLUSIVE },	{ VIDIOC_G_TUNER,	SAA7146_EXCLUSIVE },	{ VIDIOC_S_TUNER,	SAA7146_EXCLUSIVE },	{ VIDIOC_G_AUDIO,	SAA7146_EXCLUSIVE },	{ VIDIOC_S_AUDIO,	SAA7146_EXCLUSIVE },	{ 0, 0 }};static u8 saa7113_init_regs[] = {	0x02, 0xd0,	0x03, 0x23,	0x04, 0x00,	0x05, 0x00,	0x06, 0xe9,	0x07, 0x0d,	0x08, 0x98,	0x09, 0x02,	0x0a, 0x80,	0x0b, 0x40,	0x0c, 0x40,	0x0d, 0x00,	0x0e, 0x01,	0x0f, 0x7c,	0x10, 0x48,	0x11, 0x0c,	0x12, 0x8b,	0x13, 0x1a,	0x14, 0x00,	0x15, 0x00,	0x16, 0x00,	0x17, 0x00,	0x18, 0x00,	0x19, 0x00,	0x1a, 0x00,	0x1b, 0x00,	0x1c, 0x00,	0x1d, 0x00,	0x1e, 0x00,	0x41, 0x77,	0x42, 0x77,	0x43, 0x77,	0x44, 0x77,	0x45, 0x77,	0x46, 0x77,	0x47, 0x77,	0x48, 0x77,	0x49, 0x77,	0x4a, 0x77,	0x4b, 0x77,	0x4c, 0x77,	0x4d, 0x77,	0x4e, 0x77,	0x4f, 0x77,	0x50, 0x77,	0x51, 0x77,	0x52, 0x77,	0x53, 0x77,	0x54, 0x77,	0x55, 0x77,	0x56, 0x77,	0x57, 0xff,	0xff};static struct saa7146_ext_vv av7110_vv_data_st;static struct saa7146_ext_vv av7110_vv_data_c;int av7110_init_analog_module(struct av7110 *av7110){	u16 version1, version2;	if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1	    || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)		return -ENODEV;	printk("av7110(%d): DVB-C analog module detected, initializing MSP3400\n",		av7110->dvb_adapter->num);	av7110->adac_type = DVB_ADAC_MSP;	dvb_delay(100); // the probing above resets the msp...	msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);	msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);	printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n",		av7110->dvb_adapter->num, version1, version2);	msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);	msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone	msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source	msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source	msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume	msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source	msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume	msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART	if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {		INFO(("saa7113 not accessible.\n"));	} else {		u8 *i = saa7113_init_regs;		av7110->has_analog_tuner = 1;		/* init the saa7113 */		while (*i != 0xff) {			if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {				printk("av7110(%d): saa7113 initialization failed",						av7110->dvb_adapter->num);				break;			}			i += 2;		}		/* setup msp for analog sound: B/G Dual-FM */		msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV		msp_writereg(av7110, MSP_WR_DEM, 0x0001,  3); // FIR1		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1		msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1		msp_writereg(av7110, MSP_WR_DEM, 0x0005,  4); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005,  0); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005,  3); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2		msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG		msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz		msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI		msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz		msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI		msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2	}	memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);	/* set dd1 stream a & b */	saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);	saa7146_write(av7110->dev, DD1_INIT, 0x03000700);	saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));	return 0;}int av7110_init_v4l(struct av7110 *av7110){	struct saa7146_dev* dev = av7110->dev;	int ret;	/* special case DVB-C: these cards have an analog tuner	   plus need some special handling, so we have separate	   saa7146_ext_vv data for these... */	if (av7110->has_analog_tuner)		ret = saa7146_vv_init(dev, &av7110_vv_data_c);	else		ret = saa7146_vv_init(dev, &av7110_vv_data_st);	if (ret) {		ERR(("cannot init capture device. skipping.\n"));		return -ENODEV;	}	if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {		ERR(("cannot register capture device. skipping.\n"));		saa7146_vv_release(dev);		return -ENODEV;	}	if (av7110->has_analog_tuner) {		if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {			ERR(("cannot register vbi v4l2 device. skipping.\n"));		} else			/* we use this to remember that this dvb-c card can do vbi */			av7110->has_analog_tuner = 2;	}	return 0;}int av7110_exit_v4l(struct av7110 *av7110){	saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);	if (2 == av7110->has_analog_tuner)		saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);	return 0;}/* FIXME: these values are experimental values that look better than the   values from the latest "official" driver -- at least for me... (MiHu) */static struct saa7146_standard standard[] = {	{		.name	= "PAL",	.id		= V4L2_STD_PAL_BG,		.v_offset	= 0x15,	.v_field	= 288,		.v_calc	= 576,		.h_offset	= 0x48,	.h_pixels	= 708,		.h_calc	= 708,		.v_max_out	= 576,	.h_max_out	= 768,	}, {		.name	= "NTSC",	.id		= V4L2_STD_NTSC,		.v_offset	= 0x10,	.v_field	= 244,		.v_calc	= 480,		.h_offset	= 0x40,	.h_pixels	= 708,		.h_calc	= 708,		.v_max_out	= 480,	.h_max_out	= 640,	}};static struct saa7146_standard analog_standard[] = {	{		.name	= "PAL",	.id		= V4L2_STD_PAL_BG,		.v_offset	= 0x1b,	.v_field	= 288,		.v_calc	= 576,		.h_offset	= 0x08,	.h_pixels	= 708,		.h_calc	= 708,		.v_max_out	= 576,	.h_max_out	= 768,	}, {		.name	= "NTSC",	.id		= V4L2_STD_NTSC,		.v_offset	= 0x10,	.v_field	= 244,		.v_calc	= 480,		.h_offset	= 0x40,	.h_pixels	= 708,		.h_calc	= 708,		.v_max_out	= 480,	.h_max_out	= 640,	}};static struct saa7146_standard dvb_standard[] = {	{		.name	= "PAL",	.id		= V4L2_STD_PAL_BG,		.v_offset	= 0x14,	.v_field	= 288,		.v_calc	= 576,		.h_offset	= 0x48,	.h_pixels	= 708,		.h_calc	= 708,		.v_max_out	= 576,	.h_max_out	= 768,	}, {		.name	= "NTSC",	.id		= V4L2_STD_NTSC,		.v_offset	= 0x10,	.v_field	= 244,		.v_calc	= 480,		.h_offset	= 0x40,	.h_pixels	= 708,		.h_calc	= 708,		.v_max_out	= 480,	.h_max_out	= 640,	}};static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std){	struct av7110 *av7110 = (struct av7110*) dev->ext_priv;	if (std->id == V4L2_STD_PAL) {		av7110->vidmode = VIDEO_MODE_PAL;		av7110_set_vidmode(av7110, av7110->vidmode);	}	else if (std->id == V4L2_STD_NTSC) {		av7110->vidmode = VIDEO_MODE_NTSC;		av7110_set_vidmode(av7110, av7110->vidmode);	}	else		return -1;	return 0;}static struct saa7146_ext_vv av7110_vv_data_st = {	.inputs		= 1,	.audios		= 1,	.capabilities	= 0,	.flags		= 0,	.stds		= &standard[0],	.num_stds	= sizeof(standard) / sizeof(struct saa7146_standard),	.std_callback	= &std_callback,	.ioctls		= &ioctls[0],	.ioctl		= av7110_ioctl,};static struct saa7146_ext_vv av7110_vv_data_c = {	.inputs		= 1,	.audios		= 1,	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,	.flags		= SAA7146_USE_PORT_B_FOR_VBI,	.stds		= &standard[0],	.num_stds	= sizeof(standard) / sizeof(struct saa7146_standard),	.std_callback	= &std_callback,	.ioctls		= &ioctls[0],	.ioctl		= av7110_ioctl,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -