From c6a814ab51ef8d6a3ac05d768e588d2fe4d0acd4 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 17 Jan 2012 12:29:38 -0300 Subject: [PATCH] --- yaml --- r: 306286 b: refs/heads/master c: ccddd916dcde141a6fb5612da622a8ae060c12b8 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/media/video/omap3isp/ispvideo.c | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index bc039b279c14..a84dbf42569b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 80b37e7fab78ad849f6a5c1b581d6b8b54e76b45 +refs/heads/master: ccddd916dcde141a6fb5612da622a8ae060c12b8 diff --git a/trunk/drivers/media/video/omap3isp/ispvideo.c b/trunk/drivers/media/video/omap3isp/ispvideo.c index 3f5065ac9ad9..ffad91e93b6e 100644 --- a/trunk/drivers/media/video/omap3isp/ispvideo.c +++ b/trunk/drivers/media/video/omap3isp/ispvideo.c @@ -952,6 +952,81 @@ 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_video *video, + struct isp_pipeline *pipe) +{ + struct isp_device *isp = video->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; + unsigned int i; + int ret = 0; + + for (i = 0; i < ARRAY_SIZE(ents); i++) { + /* Is the entity part of the pipeline? */ + if (!(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) { + dev_warn(isp->dev, "can't find source, failing now\n"); + return ret; + } + + if (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); + if (unlikely(ret < 0)) { + dev_warn(isp->dev, "get_fmt returned null!\n"); + return ret; + } + + 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.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 * @@ -1039,6 +1114,10 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) else state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT; + ret = isp_video_check_external_subdevs(video, pipe); + if (ret < 0) + goto err_check_format; + /* Validate the pipeline and update its state. */ ret = isp_video_validate_pipeline(pipe); if (ret < 0)