summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2017-03-30 12:30:22 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-03-26 12:15:05 +0000
commiteefc9055c55fe918f5365a9ac7cab6e808edbe7f (patch)
tree0469c405deb8e563f2be6f71ee88fa68baac4967
parent844d8671aecd92212763ce9e4bf660b5efb4d74b (diff)
media: staging/imx: add frame intervals back in
We need frame interval support present in every subdev to prevent media-ctl failing, for example: Enumerating pads and links Setting up format SRGGB8_1X8 816x616 on pad imx219 0-0010/0 Format set: SRGGB8_1X8 816x616 Setting up frame interval 1/25 on pad imx219 0-0010/0 Frame interval set: 1/25 Setting up format SRGGB8_1X8 816x616 on pad imx6-mipi-csi2/0 Format set: SRGGB8_1X8 816x616 Setting up frame interval 1/25 on pad imx6-mipi-csi2/0 Unable to set frame interval: Inappropriate ioctl for device (-25)Unable to setup formats: Inappropriate ioctl for device (25) This causes media-ctl to exit with a non-zero code, which is indistinguishable from (eg) a failure to set the format. This means setup scripts have no way to tell whether the failure was due to a real failure, or whether it's due to something not being supported. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/media/platform/video-mux.c32
-rw-r--r--drivers/staging/media/imx/imx6-mipi-csi2.c36
2 files changed, 68 insertions, 0 deletions
diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index 31e9e92e723e..a8ae8833264e 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -25,6 +25,7 @@ struct video_mux {
struct v4l2_async_notifier notifier;
struct media_pad *pads;
struct mux_control *mux;
+ struct v4l2_fract timeperframe;
struct mutex lock;
int active;
};
@@ -141,8 +142,35 @@ static int video_mux_s_stream(struct v4l2_subdev *sd, int enable)
return v4l2_subdev_call(upstream_sd, video, s_stream, enable);
}
+static int vidsw_g_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_frame_interval *fi)
+{
+ struct video_mux *vmux = v4l2_subdev_to_video_mux(sd);
+
+ fi->interval = vmux->timeperframe;
+
+ return 0;
+}
+
+static int vidsw_s_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_frame_interval *fi)
+{
+ struct video_mux *vmux = v4l2_subdev_to_video_mux(sd);
+ struct media_pad *pad = &vmux->pads[fi->pad];
+
+ /* Output pad mirrors active input pad, no limits on input pads */
+ if (pad->flags & MEDIA_PAD_FL_SOURCE)
+ fi->interval = vmux->timeperframe;
+
+ vmux->timeperframe = fi->interval;
+
+ return 0;
+}
+
static const struct v4l2_subdev_video_ops video_mux_subdev_video_ops = {
.s_stream = video_mux_s_stream,
+ .g_frame_interval = vidsw_g_frame_interval,
+ .s_frame_interval = vidsw_s_frame_interval,
};
static int video_mux_set_format(struct v4l2_subdev *sd,
@@ -408,6 +436,10 @@ static int video_mux_probe(struct platform_device *pdev)
vmux->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
vmux->subdev.dev = dev;
+ /* init default frame interval */
+ vmux->timeperframe.numerator = 1;
+ vmux->timeperframe.denominator = 30;
+
/*
* The largest numbered port is the output port. It determines
* total number of pads.
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 0d8b42061623..84e87a8fbd98 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -52,6 +52,7 @@ struct csi2_dev {
struct mutex lock;
struct v4l2_mbus_framefmt format_mbus;
+ struct v4l2_fract frame_interval;
int stream_count;
struct v4l2_subdev *src_sd;
@@ -554,6 +555,35 @@ out:
return ret;
}
+static int csi2_g_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_frame_interval *fi)
+{
+ struct csi2_dev *csi2 = sd_to_dev(sd);
+
+ mutex_lock(&csi2->lock);
+ fi->interval = csi2->frame_interval;
+ mutex_unlock(&csi2->lock);
+
+ return 0;
+}
+
+static int csi2_s_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_frame_interval *fi)
+{
+ struct csi2_dev *csi2 = sd_to_dev(sd);
+
+ mutex_lock(&csi2->lock);
+
+ /* Output pads mirror active input pad, no limits on input pads */
+ if (fi->pad != CSI2_SINK_PAD)
+ fi->interval = csi2->frame_interval;
+
+ csi2->frame_interval = fi->interval;
+
+ mutex_unlock(&csi2->lock);
+ return 0;
+}
+
static int csi2_registered(struct v4l2_subdev *sd)
{
struct csi2_dev *csi2 = sd_to_dev(sd);
@@ -616,6 +646,8 @@ static const struct media_entity_operations csi2_entity_ops = {
static const struct v4l2_subdev_video_ops csi2_video_ops = {
.s_stream = csi2_s_stream,
+ .g_frame_interval = csi2_g_frame_interval,
+ .s_frame_interval = csi2_s_frame_interval,
};
static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
@@ -739,6 +771,10 @@ static int csi2_probe(struct platform_device *pdev)
csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
csi2->sd.grp_id = IMX_MEDIA_GRP_ID_CSI2;
+ /* init default frame interval */
+ csi2->frame_interval.numerator = 1;
+ csi2->frame_interval.denominator = 30;
+
for (i = 0; i < CSI2_NUM_PADS; i++) {
csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;