aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap3isp/ispvideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/omap3isp/ispvideo.c')
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
index 3f5065ac9ad9..ffad91e93b6e 100644
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -952,6 +952,81 @@ isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
952 file->f_flags & O_NONBLOCK); 952 file->f_flags & O_NONBLOCK);
953} 953}
954 954
955static int isp_video_check_external_subdevs(struct isp_video *video,
956 struct isp_pipeline *pipe)
957{
958 struct isp_device *isp = video->isp;
959 struct media_entity *ents[] = {
960 &isp->isp_csi2a.subdev.entity,
961 &isp->isp_csi2c.subdev.entity,
962 &isp->isp_ccp2.subdev.entity,
963 &isp->isp_ccdc.subdev.entity
964 };
965 struct media_pad *source_pad;
966 struct media_entity *source = NULL;
967 struct media_entity *sink;
968 struct v4l2_subdev_format fmt;
969 struct v4l2_ext_controls ctrls;
970 struct v4l2_ext_control ctrl;
971 unsigned int i;
972 int ret = 0;
973
974 for (i = 0; i < ARRAY_SIZE(ents); i++) {
975 /* Is the entity part of the pipeline? */
976 if (!(pipe->entities & (1 << ents[i]->id)))
977 continue;
978
979 /* ISP entities have always sink pad == 0. Find source. */
980 source_pad = media_entity_remote_source(&ents[i]->pads[0]);
981 if (source_pad == NULL)
982 continue;
983
984 source = source_pad->entity;
985 sink = ents[i];
986 break;
987 }
988
989 if (!source) {
990 dev_warn(isp->dev, "can't find source, failing now\n");
991 return ret;
992 }
993
994 if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
995 return 0;
996
997 pipe->external = media_entity_to_v4l2_subdev(source);
998
999 fmt.pad = source_pad->index;
1000 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1001 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
1002 pad, get_fmt, NULL, &fmt);
1003 if (unlikely(ret < 0)) {
1004 dev_warn(isp->dev, "get_fmt returned null!\n");
1005 return ret;
1006 }
1007
1008 pipe->external_bpp = omap3isp_video_format_info(fmt.format.code)->bpp;
1009
1010 memset(&ctrls, 0, sizeof(ctrls));
1011 memset(&ctrl, 0, sizeof(ctrl));
1012
1013 ctrl.id = V4L2_CID_PIXEL_RATE;
1014
1015 ctrls.count = 1;
1016 ctrls.controls = &ctrl;
1017
1018 ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
1019 if (ret < 0) {
1020 dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
1021 pipe->external->name);
1022 return ret;
1023 }
1024
1025 pipe->external_rate = ctrl.value64;
1026
1027 return 0;
1028}
1029
955/* 1030/*
956 * Stream management 1031 * Stream management
957 * 1032 *
@@ -1039,6 +1114,10 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1039 else 1114 else
1040 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT; 1115 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
1041 1116
1117 ret = isp_video_check_external_subdevs(video, pipe);
1118 if (ret < 0)
1119 goto err_check_format;
1120
1042 /* Validate the pipeline and update its state. */ 1121 /* Validate the pipeline and update its state. */
1043 ret = isp_video_validate_pipeline(pipe); 1122 ret = isp_video_validate_pipeline(pipe);
1044 if (ret < 0) 1123 if (ret < 0)