MLK-16693-1: mipi_csi: Add enum framesize ioctl
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Thu, 2 Nov 2017 03:18:08 +0000 (11:18 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:39:09 +0000 (15:39 -0500)
Enum framesize include VIDIOC_ENUM_FRAMESIZES and
VIDIOC_ENUM_FRAMEINTERVALS cmd.

Reviewed-by: Robby Cai <robby.cai@nxp.com>
Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
(cherry picked from commit 78c5a9e1c44770ea10db3d1e3b7508662c9ac88b)

drivers/media/platform/imx8/max9286.c
drivers/media/platform/imx8/mxc-isi-cap.c

index 57a9b07..a1acc96 100644 (file)
@@ -2615,6 +2615,26 @@ static int max9286_enum_framesizes(struct v4l2_subdev *sd,
        fse->min_height = fse->max_height;
        return 0;
 }
+static int max9286_enum_frame_interval(struct v4l2_subdev *sd,
+                                  struct v4l2_subdev_pad_config *cfg,
+                                  struct v4l2_subdev_frame_interval_enum *fie)
+{
+       if (fie->index < 0 || fie->index > 8)
+               return -EINVAL;
+
+       if (fie->width == 0 || fie->height == 0 ||
+           fie->code == 0) {
+               pr_warning("Please assign pixel format, width and height.\n");
+               return -EINVAL;
+       }
+
+       fie->interval.numerator = 1;
+
+        /* TODO Reserved to extension */
+
+       fie->interval.denominator = 30;
+       return 0;
+}
 
 static int max9286_get_fmt(struct v4l2_subdev *sd,
                           struct v4l2_subdev_pad_config *cfg,
@@ -2694,6 +2714,7 @@ static int max9286_link_setup(struct media_entity *entity,
 static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
        .enum_mbus_code         = max9286_enum_mbus_code,
        .enum_frame_size        = max9286_enum_framesizes,
+       .enum_frame_interval    = max9286_enum_frame_interval,
        .get_fmt                = max9286_get_fmt,
        .set_fmt                = max9286_set_fmt,
        .get_frame_desc         = max9286_get_frame_desc,
index 760a577..6dd6768 100644 (file)
@@ -137,8 +137,8 @@ struct mxc_isi_fmt *mxc_isi_get_format(unsigned int index)
 /**
  * mxc_isi_find_format - lookup mxc_isi color format by fourcc or media bus format
  */
-struct mxc_isi_fmt *mxc_isi_find_format(const u32 *pixelformat, const u32 *mbus_code,
-                                 unsigned int mask, int index)
+struct mxc_isi_fmt *mxc_isi_find_format(const u32 *pixelformat,
+                                               const u32 *mbus_code, int index)
 {
        struct mxc_isi_fmt *fmt, *def_fmt = NULL;
        unsigned int i;
@@ -149,8 +149,6 @@ struct mxc_isi_fmt *mxc_isi_find_format(const u32 *pixelformat, const u32 *mbus_
 
        for (i = 0; i < ARRAY_SIZE(mxc_isi_out_formats); i++) {
                fmt = &mxc_isi_out_formats[i];
-               if (!(fmt->flags & mask))
-                       continue;
                if (pixelformat && fmt->fourcc == *pixelformat)
                        return fmt;
                if (mbus_code && fmt->mbus_code == *mbus_code)
@@ -974,6 +972,89 @@ static int mxc_isi_cap_s_parm(struct file *file, void *fh,
        return v4l2_subdev_call(sd, video, s_parm, a);
 }
 
+static int mxc_isi_cap_enum_framesizes(struct file *file, void *priv,
+                                        struct v4l2_frmsizeenum *fsize)
+{
+       struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+       struct v4l2_device *v4l2_dev = mxc_isi->isi_cap.sd.v4l2_dev;
+       struct v4l2_subdev *sd;
+       struct mxc_isi_fmt *fmt;
+       struct v4l2_subdev_frame_size_enum fse = {
+               .index = fsize->index,
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+       };
+       int ret;
+
+       fmt = mxc_isi_find_format(&fsize->pixel_format, NULL, 0);
+       if (!fmt || fmt->fourcc != fsize->pixel_format)
+               return -EINVAL;
+       fse.code = fmt->mbus_code;
+
+       sd = mxc_isi_get_subdev_by_name(v4l2_dev, "max9286_mipi");
+       if (sd == NULL) {
+               v4l2_err(&mxc_isi->isi_cap.sd, "Can't find subdev\n");
+               return -ENODEV;
+       }
+
+       ret = v4l2_subdev_call(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;
+               return 0;
+       }
+
+       fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+       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 mxc_isi_cap_enum_frameintervals(struct file *file, void *fh,
+                                         struct v4l2_frmivalenum *interval)
+{
+       struct mxc_isi_dev *mxc_isi = video_drvdata(file);
+       struct v4l2_device *v4l2_dev = mxc_isi->isi_cap.sd.v4l2_dev;
+       struct v4l2_subdev *sd;
+       struct mxc_isi_fmt *fmt;
+       struct v4l2_subdev_frame_interval_enum fie = {
+               .index = interval->index,
+               .width = interval->width,
+               .height = interval->height,
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+       };
+       int ret;
+
+       fmt = mxc_isi_find_format(&interval->pixel_format, NULL, 0);
+       if (!fmt || fmt->fourcc != interval->pixel_format)
+               return -EINVAL;
+       fie.code = fmt->mbus_code;
+
+       sd = mxc_isi_get_subdev_by_name(v4l2_dev, "max9286_mipi");
+       if (sd == NULL) {
+               v4l2_err(&mxc_isi->isi_cap.sd, "Can't find subdev\n");
+               return -ENODEV;
+       }
+
+       ret = v4l2_subdev_call(sd, pad, enum_frame_interval, NULL, &fie);
+       if (ret)
+               return ret;
+
+       interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+       interval->discrete = fie.interval;
+
+       return 0;
+}
+
 static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = {
        .vidioc_querycap                = mxc_isi_cap_querycap,
 
@@ -999,6 +1080,9 @@ static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = {
 
        .vidioc_g_parm                  = mxc_isi_cap_g_parm,
        .vidioc_s_parm                  = mxc_isi_cap_s_parm,
+
+       .vidioc_enum_framesizes = mxc_isi_cap_enum_framesizes,
+       .vidioc_enum_frameintervals = mxc_isi_cap_enum_frameintervals,
 };
 
 /* Capture subdev media entity operations */