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

📄 mxb.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		switch( input ) {			case TUNER:			case AUX1:			{				if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {					printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");					return -EFAULT;				}				break;			}			default:			{				break;			}		}						/* switch video in saa7111a */		if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {			printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");		}					/* switch the audio-source only if necessary */		if( 0 == mxb->cur_mute ) {			mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);			mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);		}		return 0;	}	case VIDIOC_G_TUNER:	{		struct v4l2_tuner *t = arg;		int byte = 0;		if( 0 != 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));		strcpy(t->name, "Television");		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->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */		t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */		/* FIXME: add the real signal strength here */		t->signal = 0xffff;		t->afc = 0;				mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);		t->audmode = mxb->cur_mode;				if( byte < 0 ) {			t->rxsubchans  = V4L2_TUNER_SUB_MONO;		} else {			switch(byte) {				case TDA9840_MONO_DETECT: {					t->rxsubchans 	= V4L2_TUNER_SUB_MONO;					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));					break;				}				case TDA9840_DUAL_DETECT: {					t->rxsubchans 	= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));					break;				}				case TDA9840_STEREO_DETECT: {					t->rxsubchans 	= V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;					DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));					break;				}				default: { /* TDA9840_INCORRECT_DETECT */					t->rxsubchans 	= V4L2_TUNER_MODE_MONO;					DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));					break;				}			}		}		return 0;	}	case VIDIOC_S_TUNER:	{		struct v4l2_tuner *t = arg;		int result = 0;		int byte = 0;				if( 0 != t->index ) {			DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));			return -EINVAL;		}			switch(t->audmode) {			case V4L2_TUNER_MODE_STEREO: {				mxb->cur_mode = V4L2_TUNER_MODE_STEREO;				byte = TDA9840_SET_STEREO;				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));				break;			}			case V4L2_TUNER_MODE_LANG1: {				mxb->cur_mode = V4L2_TUNER_MODE_LANG1;				byte = TDA9840_SET_LANG1;				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));				break;			}			case V4L2_TUNER_MODE_LANG2: {				mxb->cur_mode = V4L2_TUNER_MODE_LANG2;				byte = TDA9840_SET_LANG2;				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));				break;			}			default: { /* case V4L2_TUNER_MODE_MONO: {*/				mxb->cur_mode = V4L2_TUNER_MODE_MONO;				byte = TDA9840_SET_MONO;				DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));				break;			}		}		if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {			printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);		}						return 0;	}	case VIDIOC_G_FREQUENCY:	{		struct v4l2_frequency *f = arg;		if(0 != mxb->cur_input) {			DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));			return -EINVAL;		}		*f = mxb->cur_freq;		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));		return 0;	}	case VIDIOC_S_FREQUENCY:	{		struct v4l2_frequency *f = arg;		if (0 != f->tuner)			return -EINVAL;		if (V4L2_TUNER_ANALOG_TV != f->type)			return -EINVAL;				if(0 != mxb->cur_input) {			DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));			return -EINVAL;		}		mxb->cur_freq = *f;		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));		/* tune in desired frequency */					mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);		/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */		spin_lock(&dev->slock);		vv->vbi_fieldcount = 0;		spin_unlock(&dev->slock);		return 0;	}	case MXB_S_AUDIO_CD:	{		int i = *(int*)arg;						if( i < 0 || i >= MXB_AUDIOS ) {			DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));			return -EINVAL;		}				DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);		return 0;	}	case MXB_S_AUDIO_LINE:	{		int i = *(int*)arg;						if( i < 0 || i >= MXB_AUDIOS ) {			DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));			return -EINVAL;		}				DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);		return 0;	}	case VIDIOC_G_AUDIO:	{		struct v4l2_audio *a = arg;		if( a->index < 0 || a->index > MXB_INPUTS ) {	 		DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));			return -EINVAL;		}		 		DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));		memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));				return 0;	}	case VIDIOC_S_AUDIO:	{		struct v4l2_audio *a = arg;		DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));		return 0;	}		default:/*		DEB2(printk("does not handle this ioctl.\n"));*/		return -ENOIOCTLCMD;	}	return 0;}static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std){	struct mxb* mxb = (struct mxb*)dev->ext_priv;	int zero = 0;	int one = 1;	if(V4L2_STD_PAL_I == std->id ) {		DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));		/* set the 7146 gpio register -- I don't know what this does exactly */      		saa7146_write(dev, GPIO_CTRL, 0x00404050);		/* unset the 7111 gpio register -- I don't know what this does exactly */		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);	} else {		DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));		/* set the 7146 gpio register -- I don't know what this does exactly */      		saa7146_write(dev, GPIO_CTRL, 0x00404050);		/* set the 7111 gpio register -- I don't know what this does exactly */		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);	}	return 0;}static struct saa7146_standard standard[] = {	{		.name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,		.v_offset	= 0x17,	.v_field 	= 288,		.h_offset	= 0x14,	.h_pixels 	= 680,		.v_max_out	= 576,	.h_max_out	= 768,	}, {		.name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,		.v_offset	= 0x17,	.v_field 	= 288,		.h_offset	= 0x14,	.h_pixels 	= 680,		.v_max_out	= 576,	.h_max_out	= 768,	}, {		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,		.v_offset	= 0x16,	.v_field 	= 240,		.h_offset	= 0x06,	.h_pixels 	= 708,		.v_max_out	= 480,	.h_max_out	= 640,	}, {		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,		.v_offset	= 0x14,	.v_field 	= 288,		.h_offset	= 0x14,	.h_pixels 	= 720,		.v_max_out	= 576,	.h_max_out	= 768,	}};static struct saa7146_pci_extension_data mxb = {        .ext_priv = "Multimedia eXtension Board",        .ext = &extension,};static struct pci_device_id pci_tbl[] = {	{		.vendor    = PCI_VENDOR_ID_PHILIPS,		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,		.subvendor = 0x0000,		.subdevice = 0x0000,		.driver_data = (unsigned long)&mxb,	}, {		.vendor	= 0,	}};MODULE_DEVICE_TABLE(pci, pci_tbl);static struct saa7146_ext_vv vv_data = {	.inputs		= MXB_INPUTS,	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,	.stds		= &standard[0],	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),	.std_callback	= &std_callback, 	.ioctls		= &ioctls[0],	.ioctl		= mxb_ioctl,};static struct saa7146_extension extension = {	.name		= MXB_IDENTIFIER,	.flags		= SAA7146_USE_I2C_IRQ,		.pci_tbl	= &pci_tbl[0],	.module		= THIS_MODULE,	.probe		= mxb_probe,	.attach		= mxb_attach,	.detach		= mxb_detach,	.irq_mask	= 0,	.irq_func	= NULL,};	static int __init mxb_init_module(void){	if( 0 != saa7146_register_extension(&extension)) {		DEB_S(("failed to register extension.\n"));		return -ENODEV;	}		return 0;}static void __exit mxb_cleanup_module(void){	saa7146_unregister_extension(&extension);}module_init(mxb_init_module);module_exit(mxb_cleanup_module);MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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