media: v4l2-common: create v4l2_g/s_parm_cap helpers
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 22 Jan 2018 08:58:36 +0000 (03:58 -0500)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Thu, 22 Feb 2018 17:25:33 +0000 (12:25 -0500)
Create helpers to handle VIDIOC_G/S_PARM by querying the
g/s_frame_interval v4l2_subdev ops.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/v4l2-core/v4l2-common.c
include/media/v4l2-common.h

index 8650ad92b64de8757ea80b43bf285deb2385b283..96c1b31de9e380d1b3c1ef2049f112a1b62265d4 100644 (file)
@@ -392,3 +392,51 @@ void v4l2_get_timestamp(struct timeval *tv)
        tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 }
 EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
+
+int v4l2_g_parm_cap(struct video_device *vdev,
+                   struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+       struct v4l2_subdev_frame_interval ival = { 0 };
+       int ret;
+
+       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+           a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               return -EINVAL;
+
+       if (vdev->device_caps & V4L2_CAP_READWRITE)
+               a->parm.capture.readbuffers = 2;
+       if (v4l2_subdev_has_op(sd, video, g_frame_interval))
+               a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+       ret = v4l2_subdev_call(sd, video, g_frame_interval, &ival);
+       if (!ret)
+               a->parm.capture.timeperframe = ival.interval;
+       return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_g_parm_cap);
+
+int v4l2_s_parm_cap(struct video_device *vdev,
+                   struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+       struct v4l2_subdev_frame_interval ival = {
+               .interval = a->parm.capture.timeperframe
+       };
+       int ret;
+
+       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+           a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               return -EINVAL;
+
+       memset(&a->parm, 0, sizeof(a->parm));
+       if (vdev->device_caps & V4L2_CAP_READWRITE)
+               a->parm.capture.readbuffers = 2;
+       else
+               a->parm.capture.readbuffers = 0;
+
+       if (v4l2_subdev_has_op(sd, video, g_frame_interval))
+               a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+       ret = v4l2_subdev_call(sd, video, s_frame_interval, &ival);
+       if (!ret)
+               a->parm.capture.timeperframe = ival.interval;
+       return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
index e0d95a7c5d48fd96e29897577611d8e214894886..f3aa1d728c0bcb76876ecf7302fb978ed1b523e2 100644 (file)
@@ -341,4 +341,30 @@ v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
  */
 void v4l2_get_timestamp(struct timeval *tv);
 
+/**
+ * v4l2_g_parm_cap - helper routine for vidioc_g_parm to fill this in by
+ *      calling the g_frame_interval op of the given subdev. It only works
+ *      for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the
+ *      function name.
+ *
+ * @vdev: the struct video_device pointer. Used to determine the device caps.
+ * @sd: the sub-device pointer.
+ * @a: the VIDIOC_G_PARM argument.
+ */
+int v4l2_g_parm_cap(struct video_device *vdev,
+                   struct v4l2_subdev *sd, struct v4l2_streamparm *a);
+
+/**
+ * v4l2_s_parm_cap - helper routine for vidioc_s_parm to fill this in by
+ *      calling the s_frame_interval op of the given subdev. It only works
+ *      for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the
+ *      function name.
+ *
+ * @vdev: the struct video_device pointer. Used to determine the device caps.
+ * @sd: the sub-device pointer.
+ * @a: the VIDIOC_S_PARM argument.
+ */
+int v4l2_s_parm_cap(struct video_device *vdev,
+                   struct v4l2_subdev *sd, struct v4l2_streamparm *a);
+
 #endif /* V4L2_COMMON_H_ */