MLK-16692-2: mipi_csi: Add S_PARM and G_PARM ioctl
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Thu, 2 Nov 2017 01:33:14 +0000 (09:33 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:39:09 +0000 (15:39 -0500)
Add VIDIOC_S_PARM and VIDIOC_G_PARM ioctl to support
to get and set camera parameters

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

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

index c45077d..57a9b07 100644 (file)
@@ -49,6 +49,11 @@ struct reg_value {
        unsigned int delay_ms;
 };
 
+enum ov10635_frame_rate {
+       OV10635_15_FPS,
+       OV10635_30_FPS,
+};
+
 static struct reg_value ov10635_init_data[] = {
        { 0x0103, 0x01, 0 },
        { 0x300c, 0x61, 0 },
@@ -2467,6 +2472,7 @@ static int max9286_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
        switch (a->type) {
        /* This is the only case currently handled. */
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                memset(a, 0, sizeof(*a));
                a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                cparm->capability = max9286_data->streamcap.capability;
@@ -2504,11 +2510,53 @@ static int max9286_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
  */
 static int max9286_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
 {
+       struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
+       struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+       enum ov10635_frame_rate frame_rate;
+       u32 tgt_fps;
        int ret = 0;
 
        switch (a->type) {
        /* This is the only case currently handled. */
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+               /* Check that the new frame rate is allowed. */
+               if ((timeperframe->numerator == 0) ||
+                   (timeperframe->denominator == 0)) {
+                       timeperframe->denominator = DEFAULT_FPS;
+                       timeperframe->numerator = 1;
+               }
+
+               tgt_fps = timeperframe->denominator /
+                         timeperframe->numerator;
+
+               if (tgt_fps > MAX_FPS) {
+                       timeperframe->denominator = MAX_FPS;
+                       timeperframe->numerator = 1;
+               } else if (tgt_fps < MIN_FPS) {
+                       timeperframe->denominator = MIN_FPS;
+                       timeperframe->numerator = 1;
+               }
+
+               /* Actual frame rate we use */
+               tgt_fps = timeperframe->denominator /
+                         timeperframe->numerator;
+
+               if (tgt_fps == 15)
+                       frame_rate = OV10635_15_FPS;
+               else if (tgt_fps == 30)
+                       frame_rate = OV10635_30_FPS;
+               else {
+                       pr_err(" The camera frame rate is not supported!\n");
+                       return -EINVAL;
+               }
+
+                /* TODO Reserved to extension */
+
+               max9286_data->streamcap.timeperframe = *timeperframe;
+               max9286_data->streamcap.capturemode = a->parm.capture.capturemode;
+
+
                break;
 
        /* These are all the possible cases. */
index f80f4a7..4b75add 100644 (file)
 #define MIPI_CSI2_SENS_VC3_PAD_SOURCE  3
 #define MIPI_CSI2_SENS_VCX_PADS_NUM            4
 
+#define MAX_FPS                30
+#define MIN_FPS                15
+#define DEFAULT_FPS            30
+
 /*!
  * Maintains the information on the current state of the sesor.
  */
index 49757cc..760a577 100644 (file)
@@ -944,6 +944,36 @@ static int mxc_isi_cap_g_chip_ident(struct file *file, void *fb,
        return 0;
 }
 
+static int mxc_isi_cap_g_parm(struct file *file, void *fh,
+                       struct v4l2_streamparm *a)
+{
+       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;
+
+       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;
+       }
+       return v4l2_subdev_call(sd, video, g_parm, a);
+}
+
+static int mxc_isi_cap_s_parm(struct file *file, void *fh,
+                       struct v4l2_streamparm *a)
+{
+       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;
+
+       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;
+       }
+       return v4l2_subdev_call(sd, video, s_parm, a);
+}
+
 static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = {
        .vidioc_querycap                = mxc_isi_cap_querycap,
 
@@ -966,6 +996,9 @@ static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = {
        .vidioc_g_selection             = mxc_isi_cap_g_selection,
        .vidioc_s_selection             = mxc_isi_cap_s_selection,
        .vidioc_g_chip_ident    = mxc_isi_cap_g_chip_ident,
+
+       .vidioc_g_parm                  = mxc_isi_cap_g_parm,
+       .vidioc_s_parm                  = mxc_isi_cap_s_parm,
 };
 
 /* Capture subdev media entity operations */