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

📄 videodevx.c

📁 2440mmc-and-camera-linux-driver 2440mmc-and-camera-linux-driver
💻 C
📖 第 1 页 / 共 4 页
字号:
			 * has serious privacy issues.			 */			vfd->devfs_handle = 				devfs_register (NULL, name, DEVFS_FL_DEFAULT,						VIDEO_MAJOR, vfd->minor,						S_IFCHR | S_IRUSR | S_IWUSR,#if LINUX_VERSION_CODE >= 0x020300						vfd->fops ? vfd->fops :#endif						&video_fops, NULL);#endif#if (LINUX_VERSION_CODE >= 0x020300) && defined(CONFIG_PROC_FS)			sprintf (name, "%s%d", name_base, i - base);			videodev_proc_create_dev (vfd, name);#endif			return 0;		}	}	return -ENFILE;}/* *	Unregister an unused video for linux device */ void video_unregister_device(struct video_device *vfd){	if(video_device[vfd->minor]!=vfd)		panic("vfd: bad unregister");#if (LINUX_VERSION_CODE >= 0x020300) && defined(CONFIG_PROC_FS)	videodev_proc_destroy_dev (vfd);#endif#ifdef CONFIG_DEVFS_FS	devfs_unregister (vfd->devfs_handle);#endif	video_device[vfd->minor]=NULL;	MOD_DEC_USE_COUNT;}/* V4L2 stuff starts here *//* *	Active devices  */static struct v4l2_clock *masterclock;static struct v4l2_v4l_compat *v4l2_v4l_compat;/* *	D E V I C E   O P E R A T I O N S * *//* *	Open a video device. */static intv4l2_video_open(struct inode *inode, struct file *file){	unsigned int		minor = MINOR(inode->i_rdev);	struct v4l2_device	*vfl;	int			err;	if (minor >= V4L2_NUM_DEVICES)		return -ENODEV;	vfl = v4l2_device[minor];#ifdef CONFIG_KMOD	/*  KMOD code by Erik Walthinsen  */	if((vfl == NULL)&&(video_device[minor] == NULL))	{		char modname[20];		sprintf(modname, "char-major-%d-%d", v4l2_major, minor);		request_module(modname);		vfl = v4l2_device[minor];	}#endif	if (vfl == NULL)		return video_open(inode, file);	if (vfl->open == NULL)		return -ENODEV;	err = vfl->open(vfl, file->f_flags, &file->private_data);	if (err == 0 && file->private_data == NULL)	{		printk(KERN_ERR"V4L2: Device returned NULL open id\n");		err = -ENODEV;	}	if (err == 0)		++vfl->busy;	return err;}/* *	Last close of a struct file */	static intv4l2_video_release(struct inode *inode, struct file *file){	struct v4l2_device *vfl = v4l2_device[MINOR(inode->i_rdev)];		if(!vfl)		return video_release(inode, file);		if (vfl->close)		vfl->close(file->private_data);	file->private_data = NULL;	if (vfl->busy)		--vfl->busy;	return 0;}/* *	Read from a video device */static ssize_tv4l2_video_read(struct file *file,	   char *buf, size_t count, loff_t *ppos){	struct v4l2_device *vfl =		v4l2_device[MINOR(file->f_dentry->d_inode->i_rdev)];			if(!vfl)  		return video_read(file, buf, count, ppos);			if (vfl->read)		return vfl->read(file->private_data, buf, count,				 file->f_flags & O_NONBLOCK);	return -EINVAL;}/* *	Write to a video device */static ssize_tv4l2_video_write(struct file *file,	    const char *buf, size_t count, loff_t *ppos){	struct v4l2_device *vfl =		v4l2_device[MINOR(file->f_dentry->d_inode->i_rdev)];					if(!vfl)		return video_write(file, buf, count, ppos);			if (vfl->write)		return vfl->write(file->private_data, buf, count,				  file->f_flags & O_NONBLOCK);	return 0;}/* *	IO Control */static voidfill_ctrl_category(struct v4l2_queryctrl *qc);static intv4l2_video_ioctl(struct inode *inode, struct file *file,	    unsigned int cmd, unsigned long arg){	struct v4l2_device *vfl = v4l2_device[MINOR(inode->i_rdev)];	char	targ[V4L2_MAX_IOCTL_SIZE];	void	*parg	= (void *)arg;	int	err	= -EINVAL;		if (!vfl)		return video_ioctl(inode, file, cmd, arg);	if (vfl->ioctl == NULL)		return -EINVAL;	/*  Copy arguments into temp kernel buffer  */	switch (_IOC_DIR(cmd))	{	case _IOC_NONE:		parg = (void *)arg;		break;	case _IOC_WRITE:	case (_IOC_WRITE | _IOC_READ):	/* Some v4l ioctls that are read/write are flagged read-only  */	case _IOC_READ:		if (_IOC_SIZE(cmd) > sizeof(targ))		{			printk(KERN_ERR"V4L2: ioctl 0x%08x arguments are "			       "too big, > %d\n", cmd, sizeof(targ));			break;/*  Arguments are too big.  */		}		if (copy_from_user(targ, (void *)arg, _IOC_SIZE(cmd)))		{			printk(KERN_INFO"V4L2: Fault on write ioctl 0x%08x "			       "copying data from user buffer\n", cmd);			return -EFAULT;		}		parg = targ;		break;	}	/*  Fill in the category for pre-defined controls  */	if (cmd == VIDIOC_QUERYCTRL)		fill_ctrl_category((struct v4l2_queryctrl *)parg);	/*  Try passing it to the driver first  */	err = vfl->ioctl(file->private_data, cmd, parg);	/*  If the driver doesn't recognize it and it's an old ioctl,	    pass it through the translation layer.  */	if (err == -ENOIOCTLCMD && _IOC_TYPE(cmd) == 'v' &&		v4l2_v4l_compat != NULL)	{		err = v4l2_v4l_compat->translate_ioctl(				file, vfl, file->private_data, cmd, parg);	}	/*  Copy results into user buffer  */	switch (_IOC_DIR(cmd))	{	case _IOC_READ:	case (_IOC_WRITE | _IOC_READ):		if (parg == targ &&		    copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))		{			printk(KERN_INFO"V4L2: Fault on read ioctl 0x%08x "			       "copying results to user buffer\n", cmd);			return -EFAULT;		}		break;	}	if (err != -ENOIOCTLCMD)		return err;	/*  Handle ioctls not recognized by the driver  */	return -EINVAL;}/* *	Memory mapping */ static intv4l2_video_mmap(struct file *file, struct vm_area_struct *vma){	struct v4l2_device *vfl =		v4l2_device[MINOR(file->f_dentry->d_inode->i_rdev)];	int	err;		if(!vfl)		return video_mmap(file, vma);		if (vfl->mmap)	{		/*  For v4l compatibility. v4l apps typically pass zero	*/		/*  for the offset, needs fixup.			*/		if (v4l2_v4l_compat != NULL)			v4l2_v4l_compat->fix_offset(file, vfl, vma);		vma->vm_file = file;		err = vfl->mmap(file->private_data, vma);#if LINUX_VERSION_CODE < 0x020203		/* This is now done in the kernel, as it should be */ 		if (err == 0 && vma->vm_file != NULL)			++vma->vm_file->f_count;#endif		return err;	}	return -ENODEV;}/* *	Poll (select()) support */static unsigned intv4l2_video_poll(struct file *file, poll_table *table){	struct v4l2_device *vfl =		v4l2_device[MINOR(file->f_dentry->d_inode->i_rdev)];			if(!vfl)		return video_poll(file, table);			if (vfl->poll)		return vfl->poll(file->private_data, file, table);	return POLLERR;}/* *	Not used. */ static loff_tv4l2_video_llseek(struct file *file,	     loff_t offset, int origin){	return -ESPIPE;}/* *	CONTROL CATEGORIES */static voidfill_ctrl_category(struct v4l2_queryctrl *qc){	if ((qc->id >= V4L2_CID_BRIGHTNESS &&	     qc->id <= V4L2_CID_HUE) ||	    (qc->id >= V4L2_CID_BLACK_LEVEL &&	     qc->id <= V4L2_CID_LASTP1-1))	{		qc->category = V4L2_CTRL_CAT_VIDEO;		strcpy(qc->group, "Video");	} else	if ((qc->id >= V4L2_CID_AUDIO_VOLUME &&	     qc->id <= V4L2_CID_AUDIO_LOUDNESS))	{		qc->category = V4L2_CTRL_CAT_AUDIO;		strcpy(qc->group, "Audio");	} else	if ((qc->id >= V4L2_CID_EFFECT_BASE &&	     qc->id <= V4L2_CID_EFFECT_BASE + 10000))	{		qc->category = V4L2_CTRL_CAT_EFFECT;		strcpy(qc->group, "Effect");	} else	{		strcpy(qc->group, "Private");	}}#if defined(CONFIG_PROC_FS) || defined(CONFIG_DEVFS_FS)static char *device_types[] ={	"capture",	"codec",	"output",	"effects", 	"vbi",		"vtr",		"teletext",	"radio", 	"undef",	"undef",	"undef",	"undef",};#endif/* *	D E V I C E   R E G I S T R A T I O N * *	Video for Linux Two device drivers request registration here. */intv4l2_register_device(struct v4l2_device *vfl){	int	i	= 0;	int	err;#if (LINUX_VERSION_CODE >= 0x020300) && \    (defined(CONFIG_PROC_FS) || defined(CONFIG_DEVFS_FS))	char	*base_name;	char	name[32];#endif	if (vfl == NULL)	{		printk(KERN_ERR"V4L2: v4l2_register_device() passed"		       " a NULL pointer!\n");		return -1;	}	i = vfl->minor;	if (vfl->open == NULL)	{		printk(KERN_ERR "V4L2: Device %d has no open method\n", i);		return -1;	}	if (i < 0 || i >= V4L2_NUM_DEVICES)	{		printk(KERN_ERR"V4L2: Minor value %d is out of range\n", i);		return -1;	}	if (v4l2_device[i] != NULL)	{		printk(KERN_ERR"V4L2: %s and %s have both been assigned"		       " minor %d\n", v4l2_device[i]->name,		       vfl->name, i);		return 1;	}  	if (video_device[i] != NULL)	{		printk(KERN_ERR"V4L2: %s(v4l1) and %s(v4l2) have both been assigned"		       " minor %d\n", video_device[i]->name,		       vfl->name, i);		return 1;	}	v4l2_device[i] = vfl;	/* The init call may sleep so we book the slot out then call */	MOD_INC_USE_COUNT;	err = 0;	if (vfl->initialize)		err = vfl->initialize(vfl);	if (err < 0)	{		printk(KERN_ERR "V4L2: %s initialize method failed\n",		       vfl->name);		v4l2_device[i] = NULL;		MOD_DEC_USE_COUNT;		return err;	}	vfl->busy = 0;	vfl->name[sizeof(vfl->name) - 1] = 0;	printk(KERN_INFO"V4L2: Registered \"%s\" as char device %d, %d\n",		 vfl->name, v4l2_major, vfl->minor);#ifdef CONFIG_KMOD	/*  Try loading the v4l compatibility layer  */	if (v4l2_v4l_compat == NULL)		request_module("v4l_compat");#endif#if (LINUX_VERSION_CODE >= 0x020300) && \    defined(CONFIG_PROC_FS) || defined(CONFIG_DEVFS_FS)	if (vfl->type >= 0 &&	    vfl->type < sizeof(device_types)/sizeof(char*))		base_name = device_types[vfl->type];	else if (vfl->type >= V4L2_TYPE_PRIVATE)		base_name = "private";	else 		base_name = "undef";	#if defined(CONFIG_PROC_FS)	sprintf(name, "%s%i", base_name, i);	v4l2_proc_create_dev (vfl, name);#endif /* CONFIG_PROCFS */#endif#ifdef CONFIG_DEVFS_FS	/*	 * Start the device root only.  Anything else	 * has serious privacy issues.	 */	if (vfl->devfs_devname[0]==0)		sprintf (name, "v4l2/%s%d", base_name, i);	else		sprintf (name, "v4l2/%s", vfl->devfs_devname);	vfl->devfs_handle = 		devfs_register (NULL, name, DEVFS_FL_DEFAULT,				v4l2_major, vfl->minor,				S_IFCHR | S_IRUSR | S_IWUSR,				&v4l2_fops, NULL);#endif	memset(vfl->v4l2_reserved, 0, sizeof(vfl->v4l2_reserved));	vfl->v4l2_priv = NULL;	return 0;}/* *	Unregister an unused video for linux device */voidv4l2_unregister_device(struct v4l2_device *vfl){	if (vfl->minor < 0 || vfl->minor >= V4L2_NUM_DEVICES ||	    v4l2_device[vfl->minor] != vfl)	{		printk(KERN_ERR"V4L2: bad unregister\n");		return;	}#if (LINUX_VERSION_CODE >= 0x020300) && defined(CONFIG_PROC_FS)	/* Add the /proc entry */	v4l2_proc_destroy_dev (vfl);#endif#ifdef CONFIG_DEVFS_FS	devfs_unregister (vfl->devfs_handle);#endif	v4l2_device[vfl->minor] = NULL;	MOD_DEC_USE_COUNT;}/* *	Register/unregister v4l back compatibility layer */intv4l2_v4l_compat_register(struct v4l2_v4l_compat *v4l_c){	if (v4l_c == NULL)	{		printk(KERN_ERR"V4L2: v4l2_register_v4l_compat() passed"		       " a NULL pointer!\n");		return -1;	}	if (v4l2_v4l_compat != NULL)	{		printk(KERN_ERR"V4L2: Attempt to re-register v4l1 "		       "compatibility layer.\n");		return -1;	}	if (v4l_c->translate_ioctl == NULL)	{		printk(KERN_ERR "V4L2: v4l1 compatibility layer has no "		       "translate_ioctl() method\n");		return -1;	}	if (v4l_c->fix_offset == NULL)	{		printk(KERN_ERR "V4L2: v4l1 compatibility layer has no "		       "fix_offset() method\n");		return -1;	}	v4l2_v4l_compat = v4l_c;	printk(KERN_INFO"V4L2: v4l1 backward compatibility enabled.\n");	return 0;}voidv4l2_v4l_compat_unregister(struct v4l2_v4l_compat *v4l_c){	if (v4l2_v4l_compat != v4l_c)		return;	v4l2_v4l_compat = NULL;	printk(KERN_INFO"V4L2: v4l1 backward compatibility disabled.\n");}/* *	/ p r o c / v i d e o d e v   H A N D L E R */#ifdef CONFIG_PROC_FS/* The actual code is the same, it's the interface what changes */#if 0static intvideo_build_proc(char *buf, char **start, off_t offset, int len, void *data){	struct v4l2_device *vfl;	struct video_device *vfl1;	int	i;	char	*t;

⌨️ 快捷键说明

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