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> | 2025-04-04 15:08:11 +0100 |
commit | 3c256bf00d059ecb597115c5ebbd830a8968df23 (patch) | |
tree | cb3eab1ba2ec2468ddac35d2395aea931894604e | |
parent | 987b18576f93c132353131758eb0756c2ba7950c (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 cba34893258a..38425568831c 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 dd8c7b3233bc..65c266afedbc 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; |