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
9struct dummy_dev {
10	struct video_device *vfd;
11};
12
13static 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
22static 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
31static 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
41static 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
60static const struct v4l2_ioctl_ops dummy_ioctl_ops = {
61	.vidioc_querycap = vidioc_querycap,
62};
63
64static 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
75static struct video_device *dummy_vfd = NULL;
76
77static 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
101static 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
111module_init(video_dummy_init);
112module_exit(video_dummy_exit);
113
114MODULE_DESCRIPTION("Dummy video module");
115MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
116MODULE_LICENSE("GPL");
117