media: starfive: Fix v4l2 compliance test issues
authormason.huo <mason.huo@starfivetech.com>
Mon, 27 Jun 2022 08:33:18 +0000 (16:33 +0800)
committermason.huo <mason.huo@starfivetech.com>
Thu, 21 Jul 2022 08:58:26 +0000 (16:58 +0800)
To get the v4l2 compliance test passed:
Add some v4l2 operations which are needed.
Improve the ioctl operations of sensor too.

Signed-off-by: mason.huo <mason.huo@starfivetech.com>
drivers/media/platform/starfive/v4l2_driver/imx219_mipi.c
drivers/media/platform/starfive/v4l2_driver/ov4689_mipi.c
drivers/media/platform/starfive/v4l2_driver/sc2235.c
drivers/media/platform/starfive/v4l2_driver/stf_video.c
drivers/media/platform/starfive/v4l2_driver/stf_video.h
drivers/media/platform/starfive/v4l2_driver/stf_vin.c

index 40ae5b4..bf7f9e4 100644 (file)
@@ -869,7 +869,7 @@ static int imx219_enum_frame_interval(struct v4l2_subdev *sd,
        u32 code;
        int ret;
 
-       if (fie->index >= ARRAY_SIZE(supported_modes) || fie->index)
+       if (fie->index >= ARRAY_SIZE(supported_modes))
                return -EINVAL;
 
        mutex_lock(&imx219->mutex);
index 73ba903..fa0ff14 100644 (file)
@@ -2662,7 +2662,7 @@ static int ov4689_enum_frame_interval(
 {
        //struct ov4689_dev *sensor = to_ov4689_dev(sd);
        struct v4l2_fract tpf;
-       //int ret;
+       int i = 0;
 
        if (fie->pad != 0)
                return -EINVAL;
@@ -2677,7 +2677,18 @@ static int ov4689_enum_frame_interval(
        // if (ret < 0)
        //      return -EINVAL;
 
+       pr_debug("fie->width = %d, fie->height = %d\n", fie->width, fie->height);
+       for (i = 0; i < OV4689_NUM_MODES; i++) {
+               if (fie->width == ov4689_mode_data[i].hact &&
+                       fie->height == ov4689_mode_data[i].vact)
+                       break;
+       }
+       if (i == OV4689_NUM_MODES)
+               return -ENOTTY;
+
        fie->interval = tpf;
+       fie->width = ov4689_mode_data[i].hact;
+       fie->height = ov4689_mode_data[i].vact;
 
        return 0;
 }
index bf50ccf..c1a77f8 100644 (file)
@@ -1576,15 +1576,25 @@ static int sc2235_enum_frame_interval(
        struct v4l2_subdev_frame_interval_enum *fie)
 {
        struct v4l2_fract tpf;
+       int i;
 
        if (fie->pad != 0)
                return -EINVAL;
+
        if (fie->index >= SC2235_NUM_FRAMERATES)
                return -EINVAL;
 
        tpf.numerator = 1;
        tpf.denominator = sc2235_framerates[fie->index];
 
+       for (i = 0; i < SC2235_NUM_MODES; i++) {
+               if (fie->width == sc2235_mode_data[i].hact &&
+                       fie->height == sc2235_mode_data[i].vact)
+                       break;
+       }
+       if (i == SC2235_NUM_MODES)
+               return -ENOTTY;
+
        fie->interval = tpf;
        return 0;
 }
index 6e5578a..489f440 100644 (file)
@@ -5,6 +5,7 @@
 #include "stfcamss.h"
 #include "stf_video.h"
 #include <media/media-entity.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-mc.h>
 #include <media/videobuf2-dma-sg.h>
 #include <media/videobuf2-vmalloc.h>
@@ -741,8 +742,8 @@ static struct v4l2_subdev *get_senname(struct file *file, const char *name)
                        break;
                entity = pad->entity;
        }
-       if (!strncmp(vin_name, entity->name, 13)) {
-               st_err(ST_VIDEO, "===== [%s] Please configure pipeline first =====\n", name);
+       if (!strncmp(vin_name, entity->name, STFCAMSS_MAX_ENTITY_NAME_LEN)) {
+               st_err(ST_VIDEO, " [%s] Please configure pipeline first!\n", name);
                return NULL;
        }
        subdev = media_entity_to_v4l2_subdev(entity);
@@ -842,7 +843,7 @@ static int video_enum_frameintervals(struct file *file, void *fh,
 
        sensor = stfcamss_find_sensor(entity);
        if (!sensor)
-               return -EINVAL;
+               return -ENOTTY;
        fie.index = fival->index;
        fie.width = fival->width;
        fie.height = fival->height;
@@ -852,6 +853,12 @@ static int video_enum_frameintervals(struct file *file, void *fh,
        code.index = 0;
        code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
 
+       /* Don't care about the code, just find by pixelformat */
+       ret = video_find_format(0, fival->pixel_format,
+                               video->formats, video->nformats);
+       if (ret < 0)
+               return -EINVAL;
+
        ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code);
        if (ret < 0)
                return -EINVAL;
@@ -995,7 +1002,7 @@ static int video_pipeline_s_fmt(struct stfcamss_video *video,
                }
        } else {
                st_err(ST_VIDEO, "Can't find sensor\n");
-               return -EINVAL;
+               return -ENOTTY;
        }
        /*
         * Starting from sensor subdevice, walk within
@@ -1344,7 +1351,6 @@ static int video_s_ctrl(struct file *file, void *fh,
        return ret;
 }
 
-#ifdef UNUSED_CODE
 static int video_query_ext_ctrl(struct file *file, void *fh,
                                    struct v4l2_query_ext_ctrl *qec)
 {
@@ -1359,7 +1365,6 @@ static int video_query_ext_ctrl(struct file *file, void *fh,
 
        return ret;
 }
-#endif
 
 static int video_g_ext_ctrls(struct file *file, void *fh,
                                 struct v4l2_ext_controls *ctrls)
@@ -1367,12 +1372,17 @@ static int video_g_ext_ctrls(struct file *file, void *fh,
        struct stfcamss_video *video = video_drvdata(file);
        struct video_device *vdev = &video->vdev;
        struct v4l2_subdev *subdev;
+       struct v4l2_fh *vfh;
        int ret;
 
        subdev = get_senname(file, (char *)__func__);
        if (!subdev)
                return -EINVAL;
 
+       vfh = container_of(&subdev->ctrl_handler, struct v4l2_fh, ctrl_handler);
+       if (!vfh->ctrl_handler)
+               return -ENOTTY;
+
        ret = v4l2_g_ext_ctrls(subdev->ctrl_handler,
                                                vdev, subdev->v4l2_dev->mdev, ctrls);
 
@@ -1395,7 +1405,7 @@ static int video_queryctrl(struct file *file, void *fh,
                ret = v4l2_queryctrl(subdev->ctrl_handler, qc);
        } else {
        //      st_err(ST_VIDEO, "== [%s] Please configure pipeline first ==\n", __func__);
-               return -EINVAL;
+               return -ENOTTY;
        }
 
        return ret;
@@ -1446,7 +1456,6 @@ static int video_try_ext_ctrls(struct file *file, void *fh,
 }
 
 
-#ifdef UNUSED_CODE
 static int video_querymenu(struct file *file, void *fh,
                               struct v4l2_querymenu *qm)
 {
@@ -1461,7 +1470,42 @@ static int video_querymenu(struct file *file, void *fh,
 
        return ret;
 }
-#endif
+
+static int video_subscribe_event(struct v4l2_fh *fh,
+                             const struct v4l2_event_subscription *sub)
+{
+       struct v4l2_subdev *subdev = NULL;
+       struct media_entity *entity = &fh->vdev->entity;
+       struct media_entity *sensor;
+
+       sensor = stfcamss_find_sensor(entity);
+       if (sensor)
+               subdev = media_entity_to_v4l2_subdev(sensor);
+
+       if (!subdev)
+               return -ENOTTY;
+
+       fh->ctrl_handler = subdev->ctrl_handler;
+       return v4l2_ctrl_subscribe_event(fh, sub);
+}
+
+static int video_unsubscribe_event(struct v4l2_fh *fh,
+                             const struct v4l2_event_subscription *sub)
+{
+       struct v4l2_subdev *subdev = NULL;
+       struct media_entity *entity = &fh->vdev->entity;
+       struct media_entity *sensor;
+
+       sensor = stfcamss_find_sensor(entity);
+       if (sensor)
+               subdev = media_entity_to_v4l2_subdev(sensor);
+
+       if (!subdev)
+               return -ENOTTY;
+
+       fh->ctrl_handler = subdev->ctrl_handler;
+       return v4l2_event_unsubscribe(fh, sub);
+}
 
 static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = {
        .vidioc_querycap                = video_querycap,
@@ -1491,8 +1535,12 @@ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = {
        .vidioc_s_ctrl                  = video_s_ctrl,
        .vidioc_g_ext_ctrls             = video_g_ext_ctrls,
        .vidioc_queryctrl               = video_queryctrl,
+       .vidioc_query_ext_ctrl          = video_query_ext_ctrl,
        .vidioc_s_ext_ctrls             = video_s_ext_ctrls,
        .vidioc_try_ext_ctrls           = video_try_ext_ctrls,
+       .vidioc_querymenu               = video_querymenu,
+       .vidioc_subscribe_event         = video_subscribe_event,
+       .vidioc_unsubscribe_event       = video_unsubscribe_event,
 };
 
 static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_mp = {
@@ -1523,8 +1571,13 @@ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_mp = {
        .vidioc_s_ctrl                  = video_s_ctrl,
        .vidioc_g_ext_ctrls             = video_g_ext_ctrls,
        .vidioc_queryctrl               = video_queryctrl,
+       .vidioc_query_ext_ctrl          = video_query_ext_ctrl,
        .vidioc_s_ext_ctrls             = video_s_ext_ctrls,
        .vidioc_try_ext_ctrls           = video_try_ext_ctrls,
+       .vidioc_querymenu               = video_querymenu,
+       .vidioc_subscribe_event         = video_subscribe_event,
+       .vidioc_unsubscribe_event       = video_unsubscribe_event,
+
 };
 
 static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_out = {
index 3f87db2..d134ee6 100644 (file)
 #include <media/v4l2-fh.h>
 #include <media/v4l2-ioctl.h>
 
-#define STFCAMSS_FRAME_MIN_WIDTH           64
-#define STFCAMSS_FRAME_MAX_WIDTH           1920
-#define STFCAMSS_FRAME_MIN_HEIGHT          64
-#define STFCAMSS_FRAME_MAX_HEIGHT          1080
-#define STFCAMSS_FRAME_WIDTH_ALIGN_8       8
-#define STFCAMSS_FRAME_WIDTH_ALIGN_128     128
-#define STFCAMSS_MIN_BUFFERS               2
+#define STFCAMSS_FRAME_MIN_WIDTH               64
+#define STFCAMSS_FRAME_MAX_WIDTH               1920
+#define STFCAMSS_FRAME_MIN_HEIGHT              64
+#define STFCAMSS_FRAME_MAX_HEIGHT              1080
+#define STFCAMSS_FRAME_WIDTH_ALIGN_8           8
+#define STFCAMSS_FRAME_WIDTH_ALIGN_128         128
+#define STFCAMSS_MIN_BUFFERS                   2
+
+#define STFCAMSS_MAX_ENTITY_NAME_LEN           27
 
 struct stfcamss_buffer {
        struct vb2_v4l2_buffer vb;
index f84f54f..96782dd 100644 (file)
@@ -134,9 +134,9 @@ static enum isp_line_id stf_vin_map_isp_line(enum vin_line_id line)
        enum isp_line_id line_id;
 
        if ((line > VIN_LINE_WR) && (line < VIN_LINE_MAX)) {
-               line_id = line % STF_ISP_LINE_SRC_SCD_Y;
+               line_id = line % STF_ISP_LINE_MAX;
                if (line_id == 0)
-                       line_id = line_id ? line_id : STF_ISP_LINE_SRC_SCD_Y;
+                       line_id = STF_ISP_LINE_SRC_SCD_Y;
        } else
                line_id = STF_ISP_LINE_INVALID;