[PATCH] cafe_ccic: add support for VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS
Dan Williams
dcbw at redhat.com
Fri Jul 6 17:37:45 EDT 2007
Newer gstreamer v4l2 plugins require these ioctls to determine supported
frame sizes and rates. Unfortunately, the kernel v4l2 bits don't have
members in 'struct video_device' for these ioctls, so we have to
override the generic ioctl handler for these two functions. They report
only VGA size @ 30fps as being supported for now.
Signed-off-by: Dan Williams <dcbw at redhat.com>
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 4710044..41cdb69 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1716,6 +1716,63 @@ static int cafe_vidioc_s_parm(struct file *filp, void *priv,
return ret;
}
+static int cafe_vidioc_enum_framesizes(struct cafe_camera* cam,
+ void __user * arg)
+{
+ struct v4l2_frmsizeenum frmsize;
+
+ if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
+ return -EFAULT;
+
+ if (frmsize.index != 0)
+ return -EINVAL;
+
+ if (frmsize.pixel_format != V4L2_PIX_FMT_YUYV &&
+ frmsize.pixel_format != V4L2_PIX_FMT_RGB444 &&
+ frmsize.pixel_format != V4L2_PIX_FMT_RGB565)
+ return -EINVAL;
+
+ frmsize.type = V4L2_FRMSIZE_TYPE_DISCRETE;
+
+ frmsize.discrete.width = VGA_WIDTH;
+ frmsize.discrete.height = VGA_HEIGHT;
+ memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
+
+ if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int cafe_vidioc_enum_frameintervals(struct cafe_camera* cam,
+ void __user * arg)
+{
+ struct v4l2_frmivalenum frmival;
+
+ if (copy_from_user(&frmival, arg, sizeof(frmival)))
+ return -EFAULT;
+
+ if (frmival.index != 0)
+ return -EINVAL;
+
+ if (frmival.pixel_format != V4L2_PIX_FMT_YUYV &&
+ frmival.pixel_format != V4L2_PIX_FMT_RGB444 &&
+ frmival.pixel_format != V4L2_PIX_FMT_RGB565)
+ return -EINVAL;
+
+ if (frmival.width != VGA_WIDTH || frmival.height != VGA_HEIGHT)
+ return -EINVAL;
+
+ frmival.type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ frmival.discrete.numerator = 1;
+ frmival.discrete.denominator = 30;
+ memset(&frmival.reserved, 0, sizeof(frmival.reserved));
+
+ if (copy_to_user(arg, &frmival, sizeof(frmival)))
+ return -EFAULT;
+
+ return 0;
+}
static void cafe_v4l_dev_release(struct video_device *vd)
{
@@ -1724,6 +1781,23 @@ static void cafe_v4l_dev_release(struct video_device *vd)
kfree(cam);
}
+static int cafe_v4l_ioctl(struct inode* inode, struct file* filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct cafe_camera *cam = filp->private_data;
+
+ switch (cmd) {
+ case VIDIOC_ENUM_FRAMESIZES:
+ return cafe_vidioc_enum_framesizes(cam, (void __user *)arg);
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ return cafe_vidioc_enum_frameintervals(cam, (void __user *)arg);
+ default:
+ break;
+ }
+
+ return video_ioctl2(inode, filp, cmd, arg);
+}
+
/*
* This template device holds all of those v4l2 methods; we
@@ -1737,7 +1811,7 @@ static const struct file_operations cafe_v4l_fops = {
.read = cafe_v4l_read,
.poll = cafe_v4l_poll,
.mmap = cafe_v4l_mmap,
- .ioctl = video_ioctl2,
+ .ioctl = cafe_v4l_ioctl,
.llseek = no_llseek,
};
More information about the Devel
mailing list