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 <[EMAIL PROTECTED]>

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,
 };
 


_______________________________________________
Devel mailing list
[email protected]
http://lists.laptop.org/listinfo/devel

Reply via email to