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

📄 videodevx.c

📁 2440mmc-and-camera-linux-driver 2440mmc-and-camera-linux-driver
💻 C
📖 第 1 页 / 共 4 页
字号:
	len = 0;	len += sprintf(buf, "Video for Linux Two (V%d.%d alpha)."		       " Major device: %d\n",		       V4L2_MAJOR_VERSION, V4L2_MINOR_VERSION,		       v4l2_major);	//len += sprintf(buf+len,"minor: type      busy name\n");	for (i = 0; i < V4L2_NUM_DEVICES; i++)	{		vfl = v4l2_device[i];		if (vfl == NULL)			continue;		if  (len > (PAGE_SIZE - 80))			return len;		if (vfl->type >= 0 &&		    vfl->type < sizeof(device_types)/sizeof(char*))			t = device_types[vfl->type];		else if (vfl->type >= V4L2_TYPE_PRIVATE)			t = "private";		else 			t = "undef";		len += sprintf(buf+len, "%5d: %-9s %3d  %s\n",			       vfl->minor, t, vfl->busy, vfl->name);	}	len += sprintf(buf+len, "Video for Linux One\n");	for (i = 0; i < VIDEO_NUM_DEVICES; i++)	{		vfl1 = video_device[i];		if (vfl1 == NULL)			continue;		if  (len > (PAGE_SIZE - 80))			return len;		len += sprintf(buf+len, "%5d: v4l1 capture device %3d  %s\n",			       vfl1->minor, vfl1->busy, vfl1->name);	}	return len;}#endif#if LINUX_VERSION_CODE < 0x020300/*  Original /proc file code from Erik Walthinsen  */static intvideo_read_proc(char *buf, char **start, off_t offset, int len, int unused){	return video_build_proc(buf, start, offset, len, NULL);}/* proc file for /proc/videodev */static struct proc_dir_entry video_proc_entry ={	0, 8, "videodev", S_IFREG | S_IRUGO, 1, 0, 0, 0, NULL,	&video_read_proc};#else /* 2.3 */#if defined(CONFIG_PROC_FS)struct videodev_proc_data {	struct list_head proc_list;	char name[16];	struct video_device *vdev;	struct v4l2_device *v2dev;	struct proc_dir_entry *proc_entry;};static struct proc_dir_entry *video_dev_proc_entry = NULL;struct proc_dir_entry *video_proc_entry = NULL;EXPORT_SYMBOL(video_proc_entry);LIST_HEAD(videodev_proc_list);static int videodev_proc_read(char *page, char **start, off_t off,			       int count, int *eof, void *data){	int len = 0;	struct videodev_proc_data *d = 0;	struct list_head *tmp;	list_for_each (tmp, &videodev_proc_list) {		d = list_entry(tmp, struct videodev_proc_data, proc_list);		if ((data == d->vdev) || (data == d->v2dev))			break;	}	/* not found */	if (tmp == &videodev_proc_list)		return 0;#if 1/* Check whether we are opening a V4L1 or V4L2 device */	if (d->vdev)		len = sprintf(page,			"Video4Linux1 device:\n"			"  Name:\td->vdev->name\n"			"  Minor:\td->vdev->minor\n");	else if (d->v2dev)		len = sprintf(page,			"Video4Linux2 device:\n"			"  Name: \t%s\n"			"  Minor:\t%d\n"			"  Type: \t%s\n", d->v2dev->name, d->v2dev->minor, 				(d->v2dev->type > V4L2_TYPE_PRIVATE) ? "undef" :				device_types[d->v2dev->type]);	else		panic("vdev proc: none of V4L1 or V4L2");#else	len = video_build_proc(page, start, off, count, data);#endif	/* fix the read count. Not so important, since usually we only	 do cat /proc.. */	len -= off;	if (len < count) {		*eof = 1;		if (len <= 0)			return 0;	}	else		len = count;	*start = page + off;	return len;}static void videodev_proc_create(void){	video_proc_entry = create_proc_entry("video", S_IFDIR, &proc_root);	if (video_proc_entry == NULL) {		printk("video_dev: unable to initialise /proc/video\n");		return;	}	video_proc_entry->owner = THIS_MODULE;	video_dev_proc_entry = create_proc_entry("dev", S_IFDIR, video_proc_entry);	if (video_dev_proc_entry == NULL) {		printk("video_dev: unable to initialise /proc/video/dev\n");		return;	}	video_dev_proc_entry->owner = THIS_MODULE;}#ifdef MODULE#if defined(CONFIG_PROC_FS)static void videodev_proc_destroy(void){	if (video_dev_proc_entry != NULL)		remove_proc_entry("dev", video_proc_entry);	if (video_proc_entry != NULL)		remove_proc_entry("video", &proc_root);}#endif#endifstatic void videodev_proc_create_dev (struct video_device *vfd, char *name){	struct videodev_proc_data *d;	struct proc_dir_entry *p;	if (video_dev_proc_entry == NULL)		return;	d = kmalloc (sizeof (struct videodev_proc_data), GFP_KERNEL);	if (!d)		return;	p = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, video_dev_proc_entry);	p->data = vfd;	p->read_proc = videodev_proc_read;	d->proc_entry = p;	d->vdev = vfd;	d->v2dev = NULL; /* not a V4L2 device */	strcpy (d->name, name);	list_add (&d->proc_list, &videodev_proc_list);}static void videodev_proc_destroy_dev (struct video_device *vfd){	struct list_head *tmp;	struct videodev_proc_data *d;	list_for_each (tmp, &videodev_proc_list) {		d = list_entry(tmp, struct videodev_proc_data, proc_list);		if (vfd == d->vdev) {			remove_proc_entry(d->name, video_dev_proc_entry);			list_del (&d->proc_list);			kfree (d);			break;		}	}}static void v4l2_proc_create_dev (struct v4l2_device *vfd, char *name){	struct videodev_proc_data *d;	struct proc_dir_entry *p;	if (video_dev_proc_entry == NULL)		return;	d = kmalloc (sizeof (struct videodev_proc_data), GFP_KERNEL);	if (!d)		return;	p = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, video_dev_proc_entry);	p->data = vfd;	p->read_proc = videodev_proc_read;	d->proc_entry = p;	d->vdev = NULL; /* not a V4L device */	d->v2dev = vfd;	strcpy (d->name, name);	list_add (&d->proc_list, &videodev_proc_list);}static void v4l2_proc_destroy_dev (struct v4l2_device *vfd){	struct list_head *tmp;	struct videodev_proc_data *d;	list_for_each (tmp, &videodev_proc_list) {		d = list_entry(tmp, struct videodev_proc_data, proc_list);		if (vfd == d->v2dev) {			remove_proc_entry(d->name, video_dev_proc_entry);			list_del (&d->proc_list);			kfree (d);			break;		}	}}#endif#endif#endif/* *	V I D E O   F O R   L I N U X   T W O   I N I T I A L I Z A T I O N */static struct file_operations video_fops ={#if LINUX_VERSION_CODE >= 0x020403	owner:		THIS_MODULE,#endif	llseek:		v4l2_video_llseek,	read:		video_read,	write:		video_write,	poll:		video_poll,	ioctl:		video_ioctl,	mmap:		video_mmap,	open:		video_open,	release:	video_release};static struct file_operations v4l2_fops ={	llseek:		v4l2_video_llseek,	read:		v4l2_video_read,	write:		v4l2_video_write,	poll:		v4l2_video_poll,	ioctl:		v4l2_video_ioctl,	mmap:		v4l2_video_mmap,	open:		v4l2_video_open,	release:	v4l2_video_release};/* *	Initialize Video for Linux Two */	#ifdef CONFIG_DEVFS_FS#define REGISTER_CHRDEV devfs_register_chrdev#define UNREGISTER_CHRDEV devfs_unregister_chrdev#else#define REGISTER_CHRDEV register_chrdev#define UNREGISTER_CHRDEV unregister_chrdev#endifstatic intvideodev_register_chrdev(int interface /* 1 or 2 */){	int			major[3];	char			*name;	struct file_operations	*fops;	major[1] = VIDEO_MAJOR;	major[2] = v4l2_major;	name = (interface == 1) ? "v4l1" : "v4l2";	fops = (interface == 1) ? &video_fops : &v4l2_fops;	if (interface == 1)		printk(KERN_INFO"Video for Linux One (2.2.16)."		       " Major device: %d\n", major[1]);	if (interface == 2)		printk(KERN_INFO"Video for Linux Two (V%d.%d)."		       " Major device: %d\n",		       V4L2_MAJOR_VERSION, V4L2_MINOR_VERSION, major[2]);	if (major[1] == major[2])	{		if (interface == 2)			return 0;		name = "v4l1/2";		fops = &v4l2_fops;	}	if (REGISTER_CHRDEV(major[interface], name, fops))	{		printk("Unable to get major %d for %s\n",		       major[interface], name);		return -EIO;	}	return 0;}static intvideodev_unregister_chrdev(int interface /* 1 or 2 */){	int	major[3];	char	*name;	major[1] = VIDEO_MAJOR;	major[2] = v4l2_major;	name = (interface == 1) ? "v4l1" : "v4l2";	if (major[1] == major[2])	{		if (interface == 2)			return 0;		name = "v4l1/2";	}	UNREGISTER_CHRDEV(major[interface], name);	return 0;}int videodev_init(void){	int	i;	struct video_init *vfli = video_init_list;	i = videodev_register_chrdev(1);	if (i == 0)		i = videodev_register_chrdev(2);	if (i)		return i;	/* make sure there's a way to tell if a device is not there */	for (i = 0; i < V4L2_NUM_DEVICES; i++)		v4l2_device[i] = NULL;	for (i = 0; i < VIDEO_NUM_DEVICES; i++)		video_device[i] = NULL;#ifdef CONFIG_PROC_FS#if  LINUX_VERSION_CODE < 0x020300	proc_register(&proc_root, &video_proc_entry);#else /* 2.3 */	videodev_proc_create ();#endif#endif	masterclock = NULL;	while(vfli->init!=NULL)	{		vfli->init(vfli);		vfli++;	}	return 0;}#ifdef MODULE		int init_module(void){	return videodev_init();}void cleanup_module(void){#ifdef CONFIG_PROC_FS#if  LINUX_VERSION_CODE < 0x020300	proc_unregister(&proc_root, video_proc_entry.low_ino);#else /* 2.3 */	videodev_proc_destroy ();#endif#endif /* CONFIG_PROC_FS */	videodev_unregister_chrdev(1);	videodev_unregister_chrdev(2);}#endif/* * *	V 4 L 2   D R I V E R   H E L P E R   A P I * */voidv4l2_version(int *major, int *minor){	*major = V4L2_MAJOR_VERSION;	*minor = V4L2_MINOR_VERSION;}intv4l2_major_number(void){	return v4l2_major;}struct v4l2_device *v4l2_device_from_minor(int minor){	if (minor < 0 || minor >= V4L2_NUM_DEVICES)		return NULL;	return v4l2_device[minor];}struct v4l2_device *v4l2_device_from_file(struct file *file){	if (file == NULL)		return NULL;	return v4l2_device_from_minor(MINOR(file->f_dentry->d_inode->i_rdev));}void *v4l2_openid_from_file(struct file *file){	if (file == NULL)		return NULL;	return file->private_data;}#if  LINUX_VERSION_CODE >= 0x020300struct page *kvirt_to_pa(unsigned long adr){	struct page *ret = NULL;	pmd_t *pmd;	pte_t *pte;	pgd_t *pgd;	pgd = pgd_offset_k(adr);	if (!pgd_none(*pgd)) {		pmd = pmd_offset(pgd, adr);		if (!pmd_none(*pmd)) {			pte = pte_offset(pmd, adr);			if (pte_present(*pte)) {				ret = pte_page(*pte);			}		}	}	return ret;}/*  Useful for using vmalloc()ed memory as DMA target  */unsigned long v4l2_vmalloc_to_bus(void *virt){	struct page *page;	unsigned long kva, ret;	page = kvirt_to_pa((unsigned long) virt);	kva = ((unsigned long)page_address(page)) | (((unsigned long) virt) & (PAGE_SIZE - 1));	ret = virt_to_bus((void *) kva);	return ret;}/*  Useful for a nopage handler when mmap()ing vmalloc()ed memory  */struct page *v4l2_vmalloc_to_page(void *virt){	struct page *page;	page = kvirt_to_pa((unsigned long) virt);	return page;}#else /* 2.2 */static struct mm_struct *find_init_mm(void){	static struct mm_struct	*mm;	struct task_struct	*p;	if (mm)		return mm;	for (p = current; p && (p = p->next_task) != current; )		if (p->pid == 0)			break;	mm = (p) ? p->mm : NULL;	return mm;}/*  Useful for using vmalloc()ed memory as DMA target  */unsigned longv4l2_vmalloc_to_bus(void *virt){	pgd_t		*pgd;	pmd_t		*pmd;	pte_t		*pte;	unsigned long	a = (unsigned long)virt;	struct mm_struct *mm = find_init_mm();	if (mm == NULL ||	    pgd_none(*(pgd = pgd_offset(mm,  a))) ||	    pmd_none(*(pmd = pmd_offset(pgd, a))) ||	    pte_none(*(pte = pte_offset(pmd, a))))		return 0;	return virt_to_bus((void *)pte_page(*pte))		+ (a & (PAGE_SIZE - 1));}/*  Useful for a nopage handler when mmap()ing vmalloc()ed memory  */unsigned longv4l2_vmalloc_to_page(void *virt){	pgd_t		*pgd;	pmd_t		*pmd;	pte_t		*pte;	unsigned long	a = (unsigned long)virt;	struct mm_struct *mm = find_init_mm();	if (mm == NULL ||	    pgd_none(*(pgd = pgd_offset(current->mm, a))) ||	    pmd_none(*(pmd = pmd_offset(pgd,         a))) ||	    pte_none(*(pte = pte_offset(pmd,         a))))		return 0;	return pte_page(*pte);}#endif /* 2.2 *//* *  Simple queue management */static rwlock_t rw_lock_unlocked = RW_LOCK_UNLOCKED;void

⌨️ 快捷键说明

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