isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon time. isp_video_check_external_subdevs() is called after pipeline validation. Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxx> --- drivers/media/video/omap3isp/ispvideo.c | 74 +++++++++++++++++++++++++++++++ 1 files changed, 74 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index f2621bc..4ec781a 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c @@ -934,6 +934,77 @@ isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) file->f_flags & O_NONBLOCK); } +static int isp_video_check_external_subdevs(struct isp_pipeline *pipe) +{ + struct isp_device *isp = + container_of(pipe, struct isp_video, pipe)->isp; + struct media_entity *ents[] = { + &isp->isp_csi2a.subdev.entity, + &isp->isp_csi2c.subdev.entity, + &isp->isp_ccp2.subdev.entity, + &isp->isp_ccdc.subdev.entity + }; + struct media_pad *source_pad; + struct media_entity *source = NULL; + struct media_entity *sink; + struct v4l2_subdev_format fmt; + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + int i; + int ret = 0; + + for (i = 0; i < ARRAY_SIZE(ents); i++) { + /* Is the entity part of the pipeline? */ + if (!(pipe->pipe.entities & (1 << ents[i]->id))) + continue; + + /* ISP entities have always sink pad == 0. Find source. */ + source_pad = media_entity_remote_source(&ents[i]->pads[0]); + + if (source_pad == NULL) + continue; + + source = source_pad->entity; + sink = ents[i]; + break; + } + + if (!source || media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV) + return 0; + + pipe->external = media_entity_to_v4l2_subdev(source); + + fmt.pad = source_pad->index; + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink), + pad, get_fmt, NULL, &fmt); + BUG_ON(ret < 0); + + pipe->external_bpp = omap3isp_video_format_info( + fmt.format.code)->bpp; + + memset(&ctrls, 0, sizeof(ctrls)); + memset(&ctrl, 0, sizeof(ctrl)); + + ctrl.id = V4L2_CID_PIXEL_RATE; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(ctrl.id); + ctrls.count = 1; + ctrls.controls = &ctrl; + + ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls); + if (ret < 0) { + dev_warn(isp->dev, + "no pixel rate control in subdev %s\n", + pipe->external->name); + return ret; + } + + pipe->external_rate = ctrl.value64; + + return 0; +} + /* * Stream management * @@ -1000,6 +1071,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe); if (ret < 0) goto err_media_entity_pipeline_start; + ret = isp_video_check_external_subdevs(pipe); + if (ret < 0) + goto err_isp_video_check_format; /* Verify that the currently configured format matches the output of * the connected subdev. -- 1.7.2.5 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html