[media] media: imx: capture: add frame sizes/interval enumeration
authorRussell King <rmk+kernel@armlinux.org.uk>
Wed, 7 Jun 2017 18:34:10 +0000 (15:34 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Tue, 20 Jun 2017 11:02:56 +0000 (08:02 -0300)
Add support for enumerating frame sizes and frame intervals from the
first subdev via the V4L2 interfaces.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/staging/media/imx/imx-media-capture.c

index f07ed9ae1a923f136af5d77438b8de85860a2d56..ddab4c249da25a8ad5b01776fcde6366f82d315a 100644 (file)
@@ -81,6 +81,76 @@ static int vidioc_querycap(struct file *file, void *fh,
        return 0;
 }
 
+static int capture_enum_framesizes(struct file *file, void *fh,
+                                  struct v4l2_frmsizeenum *fsize)
+{
+       struct capture_priv *priv = video_drvdata(file);
+       const struct imx_media_pixfmt *cc;
+       struct v4l2_subdev_frame_size_enum fse = {
+               .index = fsize->index,
+               .pad = priv->src_sd_pad,
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+       };
+       int ret;
+
+       cc = imx_media_find_format(fsize->pixel_format, CS_SEL_ANY, true);
+       if (!cc)
+               return -EINVAL;
+
+       fse.code = cc->codes[0];
+
+       ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_size, NULL, &fse);
+       if (ret)
+               return ret;
+
+       if (fse.min_width == fse.max_width &&
+           fse.min_height == fse.max_height) {
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+               fsize->discrete.width = fse.min_width;
+               fsize->discrete.height = fse.min_height;
+       } else {
+               fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
+               fsize->stepwise.min_width = fse.min_width;
+               fsize->stepwise.max_width = fse.max_width;
+               fsize->stepwise.min_height = fse.min_height;
+               fsize->stepwise.max_height = fse.max_height;
+               fsize->stepwise.step_width = 1;
+               fsize->stepwise.step_height = 1;
+       }
+
+       return 0;
+}
+
+static int capture_enum_frameintervals(struct file *file, void *fh,
+                                      struct v4l2_frmivalenum *fival)
+{
+       struct capture_priv *priv = video_drvdata(file);
+       const struct imx_media_pixfmt *cc;
+       struct v4l2_subdev_frame_interval_enum fie = {
+               .index = fival->index,
+               .pad = priv->src_sd_pad,
+               .width = fival->width,
+               .height = fival->height,
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+       };
+       int ret;
+
+       cc = imx_media_find_format(fival->pixel_format, CS_SEL_ANY, true);
+       if (!cc)
+               return -EINVAL;
+
+       fie.code = cc->codes[0];
+
+       ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_interval, NULL, &fie);
+       if (ret)
+               return ret;
+
+       fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+       fival->discrete = fie.interval;
+
+       return 0;
+}
+
 static int capture_enum_fmt_vid_cap(struct file *file, void *fh,
                                    struct v4l2_fmtdesc *f)
 {
@@ -269,6 +339,9 @@ static int capture_s_parm(struct file *file, void *fh,
 static const struct v4l2_ioctl_ops capture_ioctl_ops = {
        .vidioc_querycap        = vidioc_querycap,
 
+       .vidioc_enum_framesizes = capture_enum_framesizes,
+       .vidioc_enum_frameintervals = capture_enum_frameintervals,
+
        .vidioc_enum_fmt_vid_cap        = capture_enum_fmt_vid_cap,
        .vidioc_g_fmt_vid_cap           = capture_g_fmt_vid_cap,
        .vidioc_try_fmt_vid_cap         = capture_try_fmt_vid_cap,