1
2 #include <linux/module.h>
3 #include <linux/version.h>
4 #include <linux/fs.h>
5 #include <linux/videodev2.h>
6 #include <media/v4l2-ioctl.h>
7 #include <media/v4l2-dev.h>
8
9 struct dummy_dev {
10 struct video_device *vfd;
11 };
12
dummy_open(struct inode * inode,struct file * file)13 static int dummy_open(struct inode *inode, struct file *file)
14 {
15 int minor = iminor(inode);
16
17 printk(KERN_DEBUG "video_dummy: open called (minor=%d)\n", minor);
18
19 return 0;
20 }
21
dummy_close(struct inode * inode,struct file * file)22 static int dummy_close(struct inode *inode, struct file *file)
23 {
24 int minor = iminor(inode);
25
26 printk(KERN_DEBUG "video_dummy: close called (minor=%d)\n", minor);
27
28 return 0;
29 }
30
vidioc_querycap(struct file * file,void * priv,struct v4l2_capability * cap)31 static int vidioc_querycap(struct file *file, void *priv,
32 struct v4l2_capability *cap)
33 {
34 strcpy(cap->driver, "dummy");
35 strcpy(cap->card, "dummy");
36 cap->version = KERNEL_VERSION(0, 0, 1);
37 cap->capabilities = 0;
38 return 0;
39 }
40
41 static struct file_operations dummy_fops = {
42 .owner = THIS_MODULE,
43 .open = dummy_open,
44 .release = dummy_close,
45 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
46
47 #ifdef CONFIG_COMPAT
48 /*
49 * V4L/DVB (10139): v4l: rename v4l_compat_ioctl32 to v4l2_compat_ioctl32
50 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9bb7cde793f0637cfbdd21c04050ffcef33a5624
51 */
52 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
53 .compat_ioctl = v4l_compat_ioctl32,
54 #else
55 .compat_ioctl = v4l2_compat_ioctl32,
56 #endif
57 #endif
58 };
59
60 static const struct v4l2_ioctl_ops dummy_ioctl_ops = {
61 .vidioc_querycap = vidioc_querycap,
62 };
63
64 static const struct video_device dummy_template = {
65 .name = "dummy",
66 .fops = &dummy_fops,
67 .ioctl_ops = &dummy_ioctl_ops,
68 .minor = -1,
69 .release = video_device_release,
70
71 .tvnorms = V4L2_STD_525_60,
72 .current_norm = V4L2_STD_NTSC_M,
73 };
74
75 static struct video_device *dummy_vfd = NULL;
76
video_dummy_init(void)77 static int __init video_dummy_init(void)
78 {
79 int ret;
80
81 dummy_vfd = video_device_alloc();
82 if (!dummy_vfd)
83 return -ENOMEM;
84
85 *dummy_vfd = dummy_template;
86
87 ret = video_register_device(dummy_vfd, VFL_TYPE_GRABBER, -1);
88 if (ret < 0) {
89 video_device_release(dummy_vfd);
90 dummy_vfd = NULL;
91 return ret;
92 }
93
94 printk(KERN_INFO
95 "video_dummy: V4L2 device registered as /dev/video%d\n",
96 dummy_vfd->num);
97
98 return 0;
99 }
100
video_dummy_exit(void)101 static void __exit video_dummy_exit(void)
102 {
103
104 printk(KERN_INFO "video_dummy: removing /dev/video%d\n",
105 dummy_vfd->num);
106 video_unregister_device(dummy_vfd);
107 dummy_vfd = NULL;
108
109 }
110
111 module_init(video_dummy_init);
112 module_exit(video_dummy_exit);
113
114 MODULE_DESCRIPTION("Dummy video module");
115 MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
116 MODULE_LICENSE("GPL");
117