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

📄 saa7134-video.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			crop->c.top = b->top + b->height;		if (crop->c.height > b->top - crop->c.top + b->height)			crop->c.height = b->top - crop->c.top + b->height;		if (crop->c.left < b->left)			crop->c.top = b->left;		if (crop->c.left > b->left + b->width)			crop->c.top = b->left + b->width;		if (crop->c.width > b->left - crop->c.left + b->width)			crop->c.width = b->left - crop->c.left + b->width;		dev->crop_current = crop->c;		return 0;	}	/* --- tuner ioctls ------------------------------------------ */	case VIDIOC_G_TUNER:	{		struct v4l2_tuner *t = arg;		int n;		if (0 != t->index)			return -EINVAL;		memset(t,0,sizeof(*t));		for (n = 0; n < SAA7134_INPUT_MAX; n++)			if (card_in(dev,n).tv)				break;		if (NULL != card_in(dev,n).name) {			strcpy(t->name, "Television");			t->capability = V4L2_TUNER_CAP_NORM |				V4L2_TUNER_CAP_STEREO |				V4L2_TUNER_CAP_LANG1 |				V4L2_TUNER_CAP_LANG2;			t->rangehigh = 0xffffffffUL;			t->rxsubchans = saa7134_tvaudio_getstereo(dev);			t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);		}		if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))			t->signal = 0xffff;		return 0;	}	case VIDIOC_S_TUNER:	{		struct v4l2_tuner *t = arg;		int rx,mode;		mode = dev->thread.mode;		if (UNSET == mode) {			rx   = saa7134_tvaudio_getstereo(dev);			mode = saa7134_tvaudio_rx2mode(t->rxsubchans);		}		if (mode != t->audmode) {			dev->thread.mode = t->audmode;		}		return 0;	}	case VIDIOC_G_FREQUENCY:	{		struct v4l2_frequency *f = arg;		memset(f,0,sizeof(*f));		f->type = V4L2_TUNER_ANALOG_TV;		f->frequency = dev->ctl_freq;		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;		down(&dev->lock);		dev->ctl_freq = f->frequency;#ifdef V4L2_I2C_CLIENTS		saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);#else		saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);#endif		saa7134_tvaudio_do_scan(dev);		up(&dev->lock);		return 0;	}			/* --- control ioctls ---------------------------------------- */	case VIDIOC_ENUMINPUT:	case VIDIOC_G_INPUT:	case VIDIOC_S_INPUT:	case VIDIOC_QUERYCTRL:	case VIDIOC_G_CTRL:	case VIDIOC_S_CTRL:		return saa7134_common_ioctl(dev, cmd, arg);	case VIDIOC_G_AUDIO:	{		struct v4l2_audio *a = arg;		memset(a,0,sizeof(*a));		strcpy(a->name,"audio");		return 0;	}	case VIDIOC_S_AUDIO:		return 0;        case VIDIOC_G_PARM:        {                struct v4l2_captureparm *parm = arg;                memset(parm,0,sizeof(*parm));                return 0;        }#ifdef VIDIOC_G_PRIORITY        case VIDIOC_G_PRIORITY:        {                enum v4l2_priority *p = arg;                *p = v4l2_prio_max(&dev->prio);                return 0;        }        case VIDIOC_S_PRIORITY:        {                enum v4l2_priority *prio = arg;                return v4l2_prio_change(&dev->prio, &fh->prio, *prio);        }#endif	/* --- preview ioctls ---------------------------------------- */	case VIDIOC_ENUM_FMT:	{		struct v4l2_fmtdesc *f = arg;		enum v4l2_buf_type type;		unsigned int index;		index = f->index;		type  = f->type;		switch (type) {		case V4L2_BUF_TYPE_VIDEO_CAPTURE:		case V4L2_BUF_TYPE_VIDEO_OVERLAY:			if (index >= FORMATS)				return -EINVAL;			if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&			    formats[index].planar)				return -EINVAL;			memset(f,0,sizeof(*f));			f->index = index;			f->type  = type;			strlcpy(f->description,formats[index].name,sizeof(f->description));			f->pixelformat = formats[index].fourcc;			break;		case V4L2_BUF_TYPE_VBI_CAPTURE:			if (0 != index)				return -EINVAL;			memset(f,0,sizeof(*f));			f->index = index;			f->type  = type;			f->pixelformat = V4L2_PIX_FMT_GREY;			strcpy(f->description,"vbi data");			break;		default:			return -EINVAL;			}		return 0;	}	case VIDIOC_G_FBUF:	{		struct v4l2_framebuffer *fb = arg;		*fb = dev->ovbuf;		fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;		return 0;	}	case VIDIOC_S_FBUF:	{		struct v4l2_framebuffer *fb = arg;		struct saa7134_format *fmt;				if(!capable(CAP_SYS_ADMIN) &&		   !capable(CAP_SYS_RAWIO))			return -EPERM;		/* check args */		fmt = format_by_fourcc(fb->fmt.pixelformat);		if (NULL == fmt)			return -EINVAL;		/* ok, accept it */		dev->ovbuf = *fb;		dev->ovfmt = fmt;		if (0 == dev->ovbuf.fmt.bytesperline)			dev->ovbuf.fmt.bytesperline =				dev->ovbuf.fmt.width*fmt->depth/8;		return 0;	}	case VIDIOC_OVERLAY:	{		int *on = arg;		if (*on) {			if (!res_get(dev,fh,RESOURCE_OVERLAY))				return -EBUSY;			spin_lock_irqsave(&dev->slock,flags);			start_preview(dev,fh);			spin_unlock_irqrestore(&dev->slock,flags);		}		if (!*on) {			if (!res_check(fh, RESOURCE_OVERLAY))				return -EINVAL;			spin_lock_irqsave(&dev->slock,flags);			stop_preview(dev,fh);			spin_unlock_irqrestore(&dev->slock,flags);			res_free(dev,fh,RESOURCE_OVERLAY);		}		return 0;	}	/* --- capture ioctls ---------------------------------------- */	case VIDIOC_G_FMT:	{		struct v4l2_format *f = arg;		return saa7134_g_fmt(dev,fh,f);	}	case VIDIOC_S_FMT:	{		struct v4l2_format *f = arg;		return saa7134_s_fmt(dev,fh,f);	}	case VIDIOC_TRY_FMT:	{		struct v4l2_format *f = arg;		return saa7134_try_fmt(dev,fh,f);	}		case VIDIOCGMBUF:	{		struct video_mbuf *mbuf = arg;		struct videobuf_queue *q;		struct v4l2_requestbuffers req;		unsigned int i;		q = saa7134_queue(fh);		memset(&req,0,sizeof(req));		req.type   = q->type;		req.count  = gbuffers;		req.memory = V4L2_MEMORY_MMAP;		err = videobuf_reqbufs(file,q,&req);		if (err < 0)			return err;		memset(mbuf,0,sizeof(*mbuf));		mbuf->frames = req.count;		mbuf->size   = 0;		for (i = 0; i < mbuf->frames; i++) {			mbuf->offsets[i]  = q->bufs[i]->boff;			mbuf->size       += q->bufs[i]->bsize;		}		return 0;	}	case VIDIOC_REQBUFS:		return videobuf_reqbufs(file,saa7134_queue(fh),arg);	case VIDIOC_QUERYBUF:		return videobuf_querybuf(saa7134_queue(fh),arg);	case VIDIOC_QBUF:		return videobuf_qbuf(file,saa7134_queue(fh),arg);	case VIDIOC_DQBUF:		return videobuf_dqbuf(file,saa7134_queue(fh),arg);	case VIDIOC_STREAMON:	{		int res = saa7134_resource(fh);                if (!res_get(dev,fh,res))			return -EBUSY;		return videobuf_streamon(file,saa7134_queue(fh));	}	case VIDIOC_STREAMOFF:	{		int res = saa7134_resource(fh);		err = videobuf_streamoff(file,saa7134_queue(fh));		if (err < 0)			return err;		res_free(dev,fh,res);		return 0;	}	default:		return v4l_compat_translate_ioctl(inode,file,cmd,arg,						  video_do_ioctl);	}	return 0;}static int video_ioctl(struct inode *inode, struct file *file,		       unsigned int cmd, unsigned long arg){	return video_usercopy(inode, file, cmd, arg, video_do_ioctl);}static int radio_do_ioctl(struct inode *inode, struct file *file,			  unsigned int cmd, void *arg){	struct saa7134_fh *fh = file->private_data;	struct saa7134_dev *dev = fh->dev;		if (video_debug > 1)		saa7134_print_ioctl(dev->name,cmd);	switch (cmd) {	case VIDIOC_QUERYCAP:	{		struct v4l2_capability *cap = arg;		memset(cap,0,sizeof(*cap));                strcpy(cap->driver, "saa7134");		strlcpy(cap->card, saa7134_boards[dev->board].name,			sizeof(cap->card));		sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));		cap->version = SAA7134_VERSION_CODE;		cap->capabilities = V4L2_CAP_TUNER;		return 0;	}	case VIDIOC_G_TUNER:	{		struct v4l2_tuner *t = arg;		if (0 != t->index)			return -EINVAL;		memset(t,0,sizeof(*t));		strcpy(t->name, "Radio");                t->rangelow  = (int)(65*16);                t->rangehigh = (int)(108*16);#ifdef V4L2_I2C_CLIENTS		saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t);#else		{			struct video_tuner vt;			memset(&vt,0,sizeof(vt));			saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt);			t->signal = vt.signal;		}#endif		return 0;	}	case VIDIOC_ENUMINPUT:	{		struct v4l2_input *i = arg;				if (i->index != 0)			return -EINVAL;		strcpy(i->name,"Radio");		i->type = V4L2_INPUT_TYPE_TUNER;		return 0;	}	case VIDIOC_G_INPUT:	{		int *i = arg;		*i = 0;		return 0;	}	case VIDIOC_G_AUDIO:	{		struct v4l2_audio *a = arg;		memset(a,0,sizeof(*a));		strcpy(a->name,"Radio");		return 0;	}	case VIDIOC_G_STD:	{		v4l2_std_id *id = arg;		*id = 0;		return 0;	}	case VIDIOC_S_AUDIO:	case VIDIOC_S_TUNER:	case VIDIOC_S_INPUT:	case VIDIOC_S_STD:		return 0;	case VIDIOC_QUERYCTRL:	{		const struct v4l2_queryctrl *ctrl;		struct v4l2_queryctrl *c = arg;		if (c->id <  V4L2_CID_BASE ||		    c->id >= V4L2_CID_LASTP1)			return -EINVAL;		if (c->id == V4L2_CID_AUDIO_MUTE) {			ctrl = ctrl_by_id(c->id);			*c = *ctrl;		} else			*c = no_ctrl;		return 0;	}	case VIDIOC_G_CTRL:	case VIDIOC_S_CTRL:	case VIDIOC_G_FREQUENCY:	case VIDIOC_S_FREQUENCY:		return video_do_ioctl(inode,file,cmd,arg);			default:		return v4l_compat_translate_ioctl(inode,file,cmd,arg,						  radio_do_ioctl);	}	return 0;}static int radio_ioctl(struct inode *inode, struct file *file,		       unsigned int cmd, unsigned long arg){	return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);}static struct file_operations video_fops ={	.owner	  = THIS_MODULE,	.open	  = video_open,	.release  = video_release,	.read	  = video_read,	.poll     = video_poll,	.mmap	  = video_mmap,	.ioctl	  = video_ioctl,	.llseek   = no_llseek,};static struct file_operations radio_fops ={	.owner	  = THIS_MODULE,	.open	  = video_open,	.release  = video_release,	.ioctl	  = radio_ioctl,	.llseek   = no_llseek,};/* ----------------------------------------------------------- *//* exported stuff                                              */struct video_device saa7134_video_template ={	.name          = "saa7134-video",	.type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|	                 VID_TYPE_CLIPPING|VID_TYPE_SCALES,	.hardware      = 0,	.fops          = &video_fops,	.minor         = -1,};struct video_device saa7134_vbi_template ={	.name          = "saa7134-vbi",	.type          = VID_TYPE_TUNER|VID_TYPE_TELETEXT,	.hardware      = 0,	.fops          = &video_fops,	.minor         = -1,};struct video_device saa7134_radio_template ={	.name          = "saa7134-radio",	.type          = VID_TYPE_TUNER,	.hardware      = 0,	.fops          = &radio_fops,	.minor         = -1,};int saa7134_video_init1(struct saa7134_dev *dev){	/* sanitycheck insmod options */	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)		gbuffers = 2;	if (gbufsize < 0 || gbufsize > gbufsize_max)		gbufsize = gbufsize_max;	gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;	/* put some sensible defaults into the data structures ... */	dev->ctl_bright     = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value;	dev->ctl_contrast   = ctrl_by_id(V4L2_CID_CONTRAST)->default_value;	dev->ctl_hue        = ctrl_by_id(V4L2_CID_HUE)->default_value;	dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;	dev->ctl_volume     = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;	dev->ctl_invert     = 0;	dev->ctl_mute       = 1;	dev->automute       = 0;        INIT_LIST_HEAD(&dev->video_q.queue);	init_timer(&dev->video_q.timeout);	dev->video_q.timeout.function = saa7134_buffer_timeout;	dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);	dev->video_q.dev              = dev;	if (saa7134_boards[dev->board].video_out) {		/* enable video output */		int vo = saa7134_boards[dev->board].video_out;		saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);		saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);	} 	return 0;}int saa7134_video_init2(struct saa7134_dev *dev){	/* init video hw */	set_tvnorm(dev,&tvnorms[0]);	video_mux(dev,0);	saa7134_tvaudio_setmute(dev);	saa7134_tvaudio_setvolume(dev,dev->ctl_volume);	return 0;}int saa7134_video_fini(struct saa7134_dev *dev){	/* nothing */	return 0;}void saa7134_irq_video_intl(struct saa7134_dev *dev){	static const char *st[] = {		"no signal", "found NTSC", "found PAL", "found SECAM" };	int norm;	norm = saa_readb(SAA7134_STATUS_VIDEO1) & 0x03;	dprintk("DCSDT: %s\n",st[norm]);		if (0 != norm) {		/* wake up tvaudio audio carrier scan thread */		saa7134_tvaudio_do_scan(dev);	} else {		/* no video signal -> mute audio */		dev->automute = 1;		saa7134_tvaudio_setmute(dev);	}}void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status){	enum v4l2_field field;		spin_lock(&dev->slock);	if (dev->video_q.curr) {		dev->video_fieldcount++;		field = dev->video_q.curr->vb.field;		if (V4L2_FIELD_HAS_BOTH(field)) {			/* make sure we have seen both fields */			if ((status & 0x10) == 0x00) {				dev->video_q.curr->top_seen = 1;				goto done;			}			if (!dev->video_q.curr->top_seen)				goto done;		} else if (field == V4L2_FIELD_TOP) {			if ((status & 0x10) != 0x10)				goto done;		} else if (field == V4L2_FIELD_BOTTOM) {			if ((status & 0x10) != 0x00)				goto done;		}		dev->video_q.curr->vb.field_count = dev->video_fieldcount;		saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE);	}	saa7134_buffer_next(dev,&dev->video_q); done:	spin_unlock(&dev->slock);}/* ----------------------------------------------------------- *//* * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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