diff options
Diffstat (limited to 'drivers/media/video/omap3isp/ispvideo.c')
-rw-r--r-- | drivers/media/video/omap3isp/ispvideo.c | 79 |
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 | ||
955 | static 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) |