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

📄 usbvision-video.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;	memset(vfd->reserved, 0, sizeof(vfd->reserved));	return 0;}static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,					struct v4l2_format *vf){	struct usb_usbvision *usbvision = video_drvdata(file);	vf->fmt.pix.width = usbvision->curwidth;	vf->fmt.pix.height = usbvision->curheight;	vf->fmt.pix.pixelformat = usbvision->palette.format;	vf->fmt.pix.bytesperline =		usbvision->curwidth*usbvision->palette.bytes_per_pixel;	vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*usbvision->curheight;	vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;	vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */	return 0;}static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,			       struct v4l2_format *vf){	struct usb_usbvision *usbvision = video_drvdata(file);	int formatIdx;	/* Find requested format in available ones */	for(formatIdx=0;formatIdx<USBVISION_SUPPORTED_PALETTES;formatIdx++) {		if(vf->fmt.pix.pixelformat ==		   usbvision_v4l2_format[formatIdx].format) {			usbvision->palette = usbvision_v4l2_format[formatIdx];			break;		}	}	/* robustness */	if(formatIdx == USBVISION_SUPPORTED_PALETTES) {		return -EINVAL;	}	RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);	RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);	vf->fmt.pix.bytesperline = vf->fmt.pix.width*		usbvision->palette.bytes_per_pixel;	vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*vf->fmt.pix.height;	return 0;}static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,			       struct v4l2_format *vf){	struct usb_usbvision *usbvision = video_drvdata(file);	int ret;	if( 0 != (ret=vidioc_try_fmt_vid_cap (file, priv, vf)) ) {		return ret;	}	/* stop io in case it is already in progress */	if(usbvision->streaming == Stream_On) {		if ((ret = usbvision_stream_interrupt(usbvision)))			return ret;	}	usbvision_frames_free(usbvision);	usbvision_empty_framequeues(usbvision);	usbvision->curFrame = NULL;	/* by now we are committed to the new data... */	mutex_lock(&usbvision->lock);	usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height);	mutex_unlock(&usbvision->lock);	return 0;}static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,		      size_t count, loff_t *ppos){	struct usb_usbvision *usbvision = video_drvdata(file);	int noblock = file->f_flags & O_NONBLOCK;	unsigned long lock_flags;	int ret,i;	struct usbvision_frame *frame;	PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __func__,	       (unsigned long)count, noblock);	if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL))		return -EFAULT;	/* This entry point is compatible with the mmap routines	   so that a user can do either VIDIOC_QBUF/VIDIOC_DQBUF	   to get frames or call read on the device. */	if(!usbvision->num_frames) {		/* First, allocate some frames to work with		   if this has not been done with VIDIOC_REQBUF */		usbvision_frames_free(usbvision);		usbvision_empty_framequeues(usbvision);		usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES);	}	if(usbvision->streaming != Stream_On) {		/* no stream is running, make it running ! */		usbvision->streaming = Stream_On;		call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL);	}	/* Then, enqueue as many frames as possible	   (like a user of VIDIOC_QBUF would do) */	for(i=0;i<usbvision->num_frames;i++) {		frame = &usbvision->frame[i];		if(frame->grabstate == FrameState_Unused) {			/* Mark it as ready and enqueue frame */			frame->grabstate = FrameState_Ready;			frame->scanstate = ScanState_Scanning;			/* Accumulated in usbvision_parse_data() */			frame->scanlength = 0;			/* set v4l2_format index */			frame->v4l2_format = usbvision->palette;			spin_lock_irqsave(&usbvision->queue_lock, lock_flags);			list_add_tail(&frame->frame, &usbvision->inqueue);			spin_unlock_irqrestore(&usbvision->queue_lock,					       lock_flags);		}	}	/* Then try to steal a frame (like a VIDIOC_DQBUF would do) */	if (list_empty(&(usbvision->outqueue))) {		if(noblock)			return -EAGAIN;		ret = wait_event_interruptible			(usbvision->wait_frame,			 !list_empty(&(usbvision->outqueue)));		if (ret)			return ret;	}	spin_lock_irqsave(&usbvision->queue_lock, lock_flags);	frame = list_entry(usbvision->outqueue.next,			   struct usbvision_frame, frame);	list_del(usbvision->outqueue.next);	spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);	/* An error returns an empty frame */	if (frame->grabstate == FrameState_Error) {		frame->bytes_read = 0;		return 0;	}	PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld",	       __func__,	       frame->index, frame->bytes_read, frame->scanlength);	/* copy bytes to user space; we allow for partials reads */	if ((count + frame->bytes_read) > (unsigned long)frame->scanlength)		count = frame->scanlength - frame->bytes_read;	if (copy_to_user(buf, frame->data + frame->bytes_read, count)) {		return -EFAULT;	}	frame->bytes_read += count;	PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld",	       __func__,	       (unsigned long)count, frame->bytes_read);	/* For now, forget the frame if it has not been read in one shot. *//* 	if (frame->bytes_read >= frame->scanlength) {// All data has been read */		frame->bytes_read = 0;		/* Mark it as available to be used again. */		frame->grabstate = FrameState_Unused;/* 	} */	return count;}static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma){	unsigned long size = vma->vm_end - vma->vm_start,		start = vma->vm_start;	void *pos;	u32 i;	struct usb_usbvision *usbvision = video_drvdata(file);	PDEBUG(DBG_MMAP, "mmap");	mutex_lock(&usbvision->lock);	if (!USBVISION_IS_OPERATIONAL(usbvision)) {		mutex_unlock(&usbvision->lock);		return -EFAULT;	}	if (!(vma->vm_flags & VM_WRITE) ||	    size != PAGE_ALIGN(usbvision->max_frame_size)) {		mutex_unlock(&usbvision->lock);		return -EINVAL;	}	for (i = 0; i < usbvision->num_frames; i++) {		if (((PAGE_ALIGN(usbvision->max_frame_size)*i) >> PAGE_SHIFT) ==		    vma->vm_pgoff)			break;	}	if (i == usbvision->num_frames) {		PDEBUG(DBG_MMAP,		       "mmap: user supplied mapping address is out of range");		mutex_unlock(&usbvision->lock);		return -EINVAL;	}	/* VM_IO is eventually going to replace PageReserved altogether */	vma->vm_flags |= VM_IO;	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */	pos = usbvision->frame[i].data;	while (size > 0) {		if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {			PDEBUG(DBG_MMAP, "mmap: vm_insert_page failed");			mutex_unlock(&usbvision->lock);			return -EAGAIN;		}		start += PAGE_SIZE;		pos += PAGE_SIZE;		size -= PAGE_SIZE;	}	mutex_unlock(&usbvision->lock);	return 0;}/* * Here comes the stuff for radio on usbvision based devices * */static int usbvision_radio_open(struct inode *inode, struct file *file){	struct usb_usbvision *usbvision = video_drvdata(file);	int errCode = 0;	PDEBUG(DBG_IO, "%s:", __func__);	mutex_lock(&usbvision->lock);	if (usbvision->user) {		err("%s: Someone tried to open an already opened USBVision Radio!", __func__);		errCode = -EBUSY;	}	else {		if(PowerOnAtOpen) {			usbvision_reset_powerOffTimer(usbvision);			if (usbvision->power == 0) {				usbvision_power_on(usbvision);				usbvision_i2c_register(usbvision);			}		}		/* Alternate interface 1 is is the biggest frame size */		errCode = usbvision_set_alternate(usbvision);		if (errCode < 0) {			usbvision->last_error = errCode;			errCode = -EBUSY;			goto out;		}		// If so far no errors then we shall start the radio		usbvision->radio = 1;		call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);		usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);		usbvision->user++;	}	if (errCode) {		if (PowerOnAtOpen) {			usbvision_i2c_unregister(usbvision);			usbvision_power_off(usbvision);			usbvision->initialized = 0;		}	}out:	mutex_unlock(&usbvision->lock);	return errCode;}static int usbvision_radio_close(struct inode *inode, struct file *file){	struct usb_usbvision *usbvision = video_drvdata(file);	int errCode = 0;	PDEBUG(DBG_IO, "");	mutex_lock(&usbvision->lock);	/* Set packet size to 0 */	usbvision->ifaceAlt=0;	errCode = usb_set_interface(usbvision->dev, usbvision->iface,				    usbvision->ifaceAlt);	usbvision_audio_off(usbvision);	usbvision->radio=0;	usbvision->user--;	if (PowerOnAtOpen) {		usbvision_set_powerOffTimer(usbvision);		usbvision->initialized = 0;	}	mutex_unlock(&usbvision->lock);	if (usbvision->remove_pending) {		printk(KERN_INFO "%s: Final disconnect\n", __func__);		usbvision_release(usbvision);	}	PDEBUG(DBG_IO, "success");	return errCode;}/* * Here comes the stuff for vbi on usbvision based devices * */static int usbvision_vbi_open(struct inode *inode, struct file *file){	/* TODO */	return -ENODEV;}static int usbvision_vbi_close(struct inode *inode, struct file *file){	/* TODO */	return -ENODEV;}static int usbvision_do_vbi_ioctl(struct inode *inode, struct file *file,				 unsigned int cmd, void *arg){	/* TODO */	return -ENOIOCTLCMD;}static int usbvision_vbi_ioctl(struct inode *inode, struct file *file,		       unsigned int cmd, unsigned long arg){	return video_usercopy(inode, file, cmd, arg, usbvision_do_vbi_ioctl);}//// Video registration stuff//// Video templatestatic const struct file_operations usbvision_fops = {	.owner             = THIS_MODULE,	.open		= usbvision_v4l2_open,	.release	= usbvision_v4l2_close,	.read		= usbvision_v4l2_read,	.mmap		= usbvision_v4l2_mmap,	.ioctl		= video_ioctl2,	.llseek		= no_llseek,/* 	.poll          = video_poll, */	.compat_ioctl  = v4l_compat_ioctl32,};static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {	.vidioc_querycap      = vidioc_querycap,	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,	.vidioc_reqbufs       = vidioc_reqbufs,	.vidioc_querybuf      = vidioc_querybuf,	.vidioc_qbuf          = vidioc_qbuf,	.vidioc_dqbuf         = vidioc_dqbuf,	.vidioc_s_std         = vidioc_s_std,	.vidioc_enum_input    = vidioc_enum_input,	.vidioc_g_input       = vidioc_g_input,	.vidioc_s_input       = vidioc_s_input,	.vidioc_queryctrl     = vidioc_queryctrl,	.vidioc_g_audio       = vidioc_g_audio,	.vidioc_s_audio       = vidioc_s_audio,	.vidioc_g_ctrl        = vidioc_g_ctrl,	.vidioc_s_ctrl        = vidioc_s_ctrl,	.vidioc_streamon      = vidioc_streamon,	.vidioc_streamoff     = vidioc_streamoff,#ifdef CONFIG_VIDEO_V4L1_COMPAT/*  	.vidiocgmbuf          = vidiocgmbuf, */#endif	.vidioc_g_tuner       = vidioc_g_tuner,	.vidioc_s_tuner       = vidioc_s_tuner,	.vidioc_g_frequency   = vidioc_g_frequency,	.vidioc_s_frequency   = vidioc_s_frequency,#ifdef CONFIG_VIDEO_ADV_DEBUG	.vidioc_g_register    = vidioc_g_register,	.vidioc_s_register    = vidioc_s_register,#endif};static struct video_device usbvision_video_template = {	.fops		= &usbvision_fops,	.ioctl_ops 	= &usbvision_ioctl_ops,	.name           = "usbvision-video",	.release	= video_device_release,	.minor		= -1,	.tvnorms              = USBVISION_NORMS,	.current_norm         = V4L2_STD_PAL};// Radio templatestatic const struct file_operations usbvision_radio_fops = {	.owner             = THIS_MODULE,	.open		= usbvision_radio_open,	.release	= usbvision_radio_close,	.ioctl		= video_ioctl2,	.llseek		= no_llseek,	.compat_ioctl  = v4l_compat_ioctl32,};static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {	.vidioc_querycap      = vidioc_querycap,	.vidioc_enum_input    = vidioc_enum_input,	.vidioc_g_input       = vidioc_g_input,	.vidioc_s_input       = vidioc_s_input,	.vidioc_queryctrl     = vidioc_queryctrl,	.vidioc_g_audio       = vidioc_g_audio,	.vidioc_s_audio       = vidioc_s_audio,	.vidioc_g_ctrl        = vidioc_g_ctrl,	.vidioc_s_ctrl        = vidioc_s_ctrl,	.vidioc_g_tuner       = vidioc_g_tuner,	.vidioc_s_tuner       = vidioc_s_tuner,	.vidioc_g_frequency   = vidioc_g_frequency,	.vidioc_s_frequency   = vidioc_s_frequency,};static struct video_device usbvision_radio_template = {	.fops		= &usbvision_radio_fops,	.name           = "usbvision-radio",	.release	= video_device_release,	.minor		= -1,	.ioctl_ops 	= &usbvision_radio_ioctl_ops,	.tvnorms              = USBVISION_NORMS,	.current_norm         = V4L2_STD_PAL};// vbi templatestatic const struct file_operations usbvision_vbi_fops = {	.owner             = THIS_MODULE,	.open		= usbvision_vbi_open,	.release	= usbvision_vbi_close,	.ioctl		= usbvision_vbi_ioctl,	.llseek		= no_llseek,	.compat_ioctl  = v4l_compat_ioctl32,};static struct video_device usbvision_vbi_template=

⌨️ 快捷键说明

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