#include <linux/videodev2.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
static int init(void);
static void shutdown(void);
static int open(struct file *file);
static int close(struct file *file);
static ssize_t read(struct file *file, char *ubuf, size_t bufsz, loff_t *offs);
+//static unsigned int poll(struct file *file, struct poll_table_struct *ptab);
static int ioctl_querycap(struct file *file, void *fh, struct v4l2_capability *cap);
static int ioctl_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *fdesc);
static int ioctl_get_fmt(struct file *file, void *fh, struct v4l2_format *fmt);
static int ioctl_set_fmt(struct file *file, void *fh, struct v4l2_format *fmt);
+static int ioctl_get_parm(struct file *file, void *fh, struct v4l2_streamparm *fmt);
+static int ioctl_set_parm(struct file *file, void *fh, struct v4l2_streamparm *fmt);
static int ioctl_queryctl(struct file *file, void *fh, struct v4l2_queryctrl *ctl);
static int update_frame(int xsz, int ysz);
MODULE_AUTHOR("John Tsiombikas");
MODULE_DESCRIPTION("v4l2 test module");
-#define DEVNAME "video42"
-
-struct video_device *vdev;
+static struct video_device *vdev;
+static struct v4l2_device v4l2_dev;
static struct v4l2_file_operations fops;
static struct v4l2_ioctl_ops iops;
static int width, height;
{
int res;
+ strcpy(v4l2_dev.name, "vdummy");
+ if((res = v4l2_device_register(0, &v4l2_dev)) != 0) {
+ return res;
+ }
+
if(!(vdev = video_device_alloc())) {
return -ENOMEM;
}
vdev->release = video_device_release;
- strcpy(vdev->name, "video test");
+ strcpy(vdev->name, KBUILD_MODNAME);
vdev->fops = &fops;
vdev->ioctl_ops = &iops;
vdev->vfl_type = VFL_TYPE_GRABBER;
+ vdev->v4l2_dev = &v4l2_dev;
+ fops.owner = THIS_MODULE;
fops.open = open;
fops.release = close;
fops.read = read;
+ //fops.poll = poll;
fops.unlocked_ioctl = video_ioctl2;
iops.vidioc_querycap = ioctl_querycap;
iops.vidioc_enum_fmt_vid_cap = ioctl_enum_fmt;
iops.vidioc_g_fmt_vid_cap = ioctl_get_fmt;
iops.vidioc_s_fmt_vid_cap = ioctl_set_fmt;
+ iops.vidioc_g_parm = ioctl_get_parm;
+ iops.vidioc_s_parm = ioctl_set_parm;
iops.vidioc_queryctrl = ioctl_queryctl;
if((res = video_register_device(vdev, VFL_TYPE_GRABBER, -1)) != 0) {
return res;
}
+ printk(KERN_INFO "vdummy device initialized\n");
return 0;
}
static void shutdown(void)
{
video_unregister_device(vdev);
+ v4l2_device_unregister(&v4l2_dev);
kfree(frame);
}
return sz;
}
+/*
+static unsigned int poll(struct file *file, struct poll_table_struct *ptab)
+{
+}
+*/
+
static int ioctl_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
{
- strcpy(cap->driver, "vidtest");
- strcpy(cap->card, "fake");
+ strcpy(cap->driver, KBUILD_MODNAME);
+ strcpy(cap->card, "dummy v4l2 dev");
strcpy(cap->bus_info, "nobus");
- cap->version = 0;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
{
int res;
+ printk(KERN_INFO "ioctl_set_fmt called\n");
+
if(fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
return -EINVAL;
}
return ioctl_get_fmt(file, fh, fmt);
}
+static int ioctl_get_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+ if(parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ return -EINVAL;
+ }
+ parm->parm.capture.capability = 0;
+ parm->parm.capture.capturemode = 0;
+ parm->parm.capture.timeperframe.numerator = 1;
+ parm->parm.capture.timeperframe.denominator = 30;
+ parm->parm.capture.extendedmode = 0;
+ parm->parm.capture.readbuffers = 1;
+ return 0;
+}
+
+static int ioctl_set_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+ if(parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ return -EINVAL;
+ }
+ return ioctl_get_parm(file, fh, parm);
+}
+
static int ioctl_queryctl(struct file *file, void *fh, struct v4l2_queryctrl *ctl)
{
return -EINVAL;
{
unsigned char *tmp;
int i, j;
- int new_fsz = xsz * ysz;
+ int new_fsz = xsz * ysz * 3;
+
+ printk(KERN_INFO "update_frame(%d, %d)\n", xsz, ysz);
if(xsz == width && ysz == height) {
return 0;