V4L/DVB (13564): gspca - main: Implement vidioc_enum_frameintervals.
Antonio Ospite [Wed, 2 Dec 2009 09:18:46 +0000 (06:18 -0300)]
Some drivers support multiple frameintervals (framerates), make gspca able to
enumerate them.

Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/gspca.h

index 0a99a21..e6e8df4 100644 (file)
@@ -982,6 +982,34 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
        return -EINVAL;
 }
 
+static int vidioc_enum_frameintervals(struct file *filp, void *priv,
+                                     struct v4l2_frmivalenum *fival)
+{
+       struct gspca_dev *gspca_dev = priv;
+       int mode = wxh_to_mode(gspca_dev, fival->width, fival->height);
+       __u32 i;
+
+       if (gspca_dev->cam.mode_framerates == NULL ||
+                       gspca_dev->cam.mode_framerates[mode].nrates == 0)
+               return -EINVAL;
+
+       if (fival->pixel_format !=
+                       gspca_dev->cam.cam_mode[mode].pixelformat)
+               return -EINVAL;
+
+       for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) {
+               if (fival->index == i) {
+                       fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+                       fival->discrete.numerator = 1;
+                       fival->discrete.denominator =
+                               gspca_dev->cam.mode_framerates[mode].rates[i];
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
 static void gspca_release(struct video_device *vfd)
 {
        struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
@@ -1973,6 +2001,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
        .vidioc_g_parm          = vidioc_g_parm,
        .vidioc_s_parm          = vidioc_s_parm,
        .vidioc_enum_framesizes = vidioc_enum_framesizes,
+       .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .vidioc_g_register      = vidioc_g_register,
        .vidioc_s_register      = vidioc_s_register,
index 1816173..a55c0a0 100644 (file)
@@ -45,11 +45,20 @@ extern int gspca_debug;
 /* image transfers */
 #define MAX_NURBS 4            /* max number of URBs */
 
+
+/* used to list framerates supported by a camera mode (resolution) */
+struct framerates {
+       int *rates;
+       int nrates;
+};
+
 /* device information - set at probe time */
 struct cam {
        int bulk_size;          /* buffer size when image transfer by bulk */
        const struct v4l2_pix_format *cam_mode; /* size nmodes */
        char nmodes;
+       const struct framerates *mode_framerates; /* must have size nmode,
+                                                  * just like cam_mode */
        __u8 bulk_nurbs;        /* number of URBs in bulk mode
                                 * - cannot be > MAX_NURBS
                                 * - when 0 and bulk_size != 0 means