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

📄 saa7134-video.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	return videobuf_mmap_mapper(saa7134_queue(fh), vma);}/* ------------------------------------------------------------------ */static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,						struct v4l2_format *f){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	struct saa7134_tvnorm *norm = dev->tvnorm;	f->fmt.vbi.sampling_rate = 6750000 * 4;	f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;	f->fmt.vbi.offset = 64 * 4;	f->fmt.vbi.start[0] = norm->vbi_v_start_0;	f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;	f->fmt.vbi.start[1] = norm->vbi_v_start_1;	f->fmt.vbi.count[1] = f->fmt.vbi.count[0];	f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */#if 0	if (V4L2_STD_PAL == norm->id) {		/* FIXME */		f->fmt.vbi.start[0] += 3;		f->fmt.vbi.start[1] += 3*2;	}#endif	return 0;}static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,				struct v4l2_format *f){	struct saa7134_fh *fh = priv;	f->fmt.pix.width        = fh->width;	f->fmt.pix.height       = fh->height;	f->fmt.pix.field        = fh->cap.field;	f->fmt.pix.pixelformat  = fh->fmt->fourcc;	f->fmt.pix.bytesperline =		(f->fmt.pix.width * fh->fmt->depth) >> 3;	f->fmt.pix.sizeimage =		f->fmt.pix.height * f->fmt.pix.bytesperline;	return 0;}static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,				struct v4l2_format *f){	struct saa7134_fh *fh = priv;	if (saa7134_no_overlay > 0) {		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");		return -EINVAL;	}	f->fmt.win = fh->win;	return 0;}static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,						struct v4l2_format *f){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	struct saa7134_format *fmt;	enum v4l2_field field;	unsigned int maxw, maxh;	fmt = format_by_fourcc(f->fmt.pix.pixelformat);	if (NULL == fmt)		return -EINVAL;	field = f->fmt.pix.field;	maxw  = min(dev->crop_current.width*4,  dev->crop_bounds.width);	maxh  = min(dev->crop_current.height*4, dev->crop_bounds.height);	if (V4L2_FIELD_ANY == field) {		field = (f->fmt.pix.height > maxh/2)			? V4L2_FIELD_INTERLACED			: V4L2_FIELD_BOTTOM;	}	switch (field) {	case V4L2_FIELD_TOP:	case V4L2_FIELD_BOTTOM:		maxh = maxh / 2;		break;	case V4L2_FIELD_INTERLACED:		break;	default:		return -EINVAL;	}	f->fmt.pix.field = field;	if (f->fmt.pix.width  < 48)		f->fmt.pix.width  = 48;	if (f->fmt.pix.height < 32)		f->fmt.pix.height = 32;	if (f->fmt.pix.width > maxw)		f->fmt.pix.width = maxw;	if (f->fmt.pix.height > maxh)		f->fmt.pix.height = maxh;	f->fmt.pix.width &= ~0x03;	f->fmt.pix.bytesperline =		(f->fmt.pix.width * fmt->depth) >> 3;	f->fmt.pix.sizeimage =		f->fmt.pix.height * f->fmt.pix.bytesperline;	return 0;}static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,						struct v4l2_format *f){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	if (saa7134_no_overlay > 0) {		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");		return -EINVAL;	}	return verify_preview(dev, &f->fmt.win);}static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,					struct v4l2_format *f){	struct saa7134_fh *fh = priv;	int err;	err = saa7134_try_fmt_vid_cap(file, priv, f);	if (0 != err)		return err;	fh->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);	fh->width     = f->fmt.pix.width;	fh->height    = f->fmt.pix.height;	fh->cap.field = f->fmt.pix.field;	return 0;}static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,					struct v4l2_format *f){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	int err;	unsigned long flags;	if (saa7134_no_overlay > 0) {		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");		return -EINVAL;	}	err = verify_preview(dev, &f->fmt.win);	if (0 != err)		return err;	mutex_lock(&dev->lock);	fh->win    = f->fmt.win;	fh->nclips = f->fmt.win.clipcount;	if (fh->nclips > 8)		fh->nclips = 8;	if (copy_from_user(fh->clips, f->fmt.win.clips,			   sizeof(struct v4l2_clip)*fh->nclips)) {		mutex_unlock(&dev->lock);		return -EFAULT;	}	if (res_check(fh, RESOURCE_OVERLAY)) {		spin_lock_irqsave(&dev->slock, flags);		stop_preview(dev, fh);		start_preview(dev, fh);		spin_unlock_irqrestore(&dev->slock, flags);	}	mutex_unlock(&dev->lock);	return 0;}int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c){	const struct v4l2_queryctrl *ctrl;	if ((c->id <  V4L2_CID_BASE ||	     c->id >= V4L2_CID_LASTP1) &&	    (c->id <  V4L2_CID_PRIVATE_BASE ||	     c->id >= V4L2_CID_PRIVATE_LASTP1))		return -EINVAL;	ctrl = ctrl_by_id(c->id);	*c = (NULL != ctrl) ? *ctrl : no_ctrl;	return 0;}EXPORT_SYMBOL_GPL(saa7134_queryctrl);static int saa7134_enum_input(struct file *file, void *priv,					struct v4l2_input *i){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	unsigned int n;	n = i->index;	if (n >= SAA7134_INPUT_MAX)		return -EINVAL;	if (NULL == card_in(dev, i->index).name)		return -EINVAL;	memset(i, 0, sizeof(*i));	i->index = n;	i->type  = V4L2_INPUT_TYPE_CAMERA;	strcpy(i->name, card_in(dev, n).name);	if (card_in(dev, n).tv)		i->type = V4L2_INPUT_TYPE_TUNER;	i->audioset = 1;	if (n == dev->ctl_input) {		int v1 = saa_readb(SAA7134_STATUS_VIDEO1);		int v2 = saa_readb(SAA7134_STATUS_VIDEO2);		if (0 != (v1 & 0x40))			i->status |= V4L2_IN_ST_NO_H_LOCK;		if (0 != (v2 & 0x40))			i->status |= V4L2_IN_ST_NO_SYNC;		if (0 != (v2 & 0x0e))			i->status |= V4L2_IN_ST_MACROVISION;	}	i->std = SAA7134_NORMS;	return 0;}static int saa7134_g_input(struct file *file, void *priv, unsigned int *i){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	*i = dev->ctl_input;	return 0;}static int saa7134_s_input(struct file *file, void *priv, unsigned int i){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	int err;	err = v4l2_prio_check(&dev->prio, &fh->prio);	if (0 != err)		return err;	if (i < 0  ||  i >= SAA7134_INPUT_MAX)		return -EINVAL;	if (NULL == card_in(dev, i).name)		return -EINVAL;	mutex_lock(&dev->lock);	video_mux(dev, i);	mutex_unlock(&dev->lock);	return 0;}static int saa7134_querycap(struct file *file, void  *priv,					struct v4l2_capability *cap){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	unsigned int tuner_type = dev->tuner_type;	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_VIDEO_CAPTURE |		V4L2_CAP_VBI_CAPTURE |		V4L2_CAP_READWRITE |		V4L2_CAP_STREAMING |		V4L2_CAP_TUNER;	if (saa7134_no_overlay <= 0)		cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;	if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))		cap->capabilities &= ~V4L2_CAP_TUNER;		return 0;}int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id){	unsigned long flags;	unsigned int i;	v4l2_std_id fixup;	int err;	/* When called from the empress code fh == NULL.	   That needs to be fixed somehow, but for now this is	   good enough. */	if (fh) {		err = v4l2_prio_check(&dev->prio, &fh->prio);		if (0 != err)			return err;	} else if (res_locked(dev, RESOURCE_OVERLAY)) {		/* Don't change the std from the mpeg device		   if overlay is active. */		return -EBUSY;	}	for (i = 0; i < TVNORMS; i++)		if (*id == tvnorms[i].id)			break;	if (i == TVNORMS)		for (i = 0; i < TVNORMS; i++)			if (*id & tvnorms[i].id)				break;	if (i == TVNORMS)		return -EINVAL;	if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) {		if (secam[0] == 'L' || secam[0] == 'l') {			if (secam[1] == 'C' || secam[1] == 'c')				fixup = V4L2_STD_SECAM_LC;			else				fixup = V4L2_STD_SECAM_L;		} else {			if (secam[0] == 'D' || secam[0] == 'd')				fixup = V4L2_STD_SECAM_DK;			else				fixup = V4L2_STD_SECAM;		}		for (i = 0; i < TVNORMS; i++)			if (fixup == tvnorms[i].id)				break;	}	*id = tvnorms[i].id;	mutex_lock(&dev->lock);	if (fh && res_check(fh, RESOURCE_OVERLAY)) {		spin_lock_irqsave(&dev->slock, flags);		stop_preview(dev, fh);		spin_unlock_irqrestore(&dev->slock, flags);		set_tvnorm(dev, &tvnorms[i]);		spin_lock_irqsave(&dev->slock, flags);		start_preview(dev, fh);		spin_unlock_irqrestore(&dev->slock, flags);	} else		set_tvnorm(dev, &tvnorms[i]);	saa7134_tvaudio_do_scan(dev);	mutex_unlock(&dev->lock);	return 0;}EXPORT_SYMBOL_GPL(saa7134_s_std_internal);static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id){	struct saa7134_fh *fh = priv;	return saa7134_s_std_internal(fh->dev, fh, id);}static int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	*id = dev->tvnorm->id;	return 0;}static int saa7134_cropcap(struct file *file, void *priv,					struct v4l2_cropcap *cap){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&	    cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)		return -EINVAL;	cap->bounds  = dev->crop_bounds;	cap->defrect = dev->crop_defrect;	cap->pixelaspect.numerator   = 1;	cap->pixelaspect.denominator = 1;	if (dev->tvnorm->id & V4L2_STD_525_60) {		cap->pixelaspect.numerator   = 11;		cap->pixelaspect.denominator = 10;	}	if (dev->tvnorm->id & V4L2_STD_625_50) {		cap->pixelaspect.numerator   = 54;		cap->pixelaspect.denominator = 59;	}	return 0;}static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop){	struct saa7134_fh *fh = f;	struct saa7134_dev *dev = fh->dev;	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&	    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)		return -EINVAL;	crop->c = dev->crop_current;	return 0;}static int saa7134_s_crop(struct file *file, void *f, struct v4l2_crop *crop){	struct saa7134_fh *fh = f;	struct saa7134_dev *dev = fh->dev;	struct v4l2_rect *b = &dev->crop_bounds;	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&	    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)		return -EINVAL;	if (crop->c.height < 0)		return -EINVAL;	if (crop->c.width < 0)		return -EINVAL;	if (res_locked(fh->dev, RESOURCE_OVERLAY))		return -EBUSY;	if (res_locked(fh->dev, RESOURCE_VIDEO))		return -EBUSY;	if (crop->c.top < b->top)		crop->c.top = b->top;	if (crop->c.top > b->top + b->height)		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.left = b->left;	if (crop->c.left > b->left + b->width)		crop->c.left = 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;}static int saa7134_g_tuner(struct file *file, void *priv,					struct v4l2_tuner *t){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	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->type = V4L2_TUNER_ANALOG_TV;		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;}static int saa7134_s_tuner(struct file *file, void *priv,					struct v4l2_tuner *t){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;	int rx, mode, err;	err = v4l2_prio_check(&dev->prio, &fh->prio);	if (0 != err)		return err;	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;}static int saa7134_g_frequency(struct file *file, void *priv,					struct v4l2_frequency *f){	struct saa7134_fh *fh = priv;	struct saa7134_dev *dev = fh->dev;

⌨️ 快捷键说明

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