diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2017-03-30 12:30:22 +0100 |
---|---|---|
committer | Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 2024-03-26 12:15:05 +0000 |
commit | eefc9055c55fe918f5365a9ac7cab6e808edbe7f (patch) | |
tree | 0469c405deb8e563f2be6f71ee88fa68baac4967 | |
parent | 844d8671aecd92212763ce9e4bf660b5efb4d74b (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.c | 32 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx6-mipi-csi2.c | 36 |
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; |