diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-04-08 12:17:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-14 14:47:44 -0400 |
commit | 756e6e14484b3249dad9663ed1398711b62676a3 (patch) | |
tree | 1914d4f3d997fde771e5433aff3ad06283f29ca0 /drivers/media/platform/exynos4-is/fimc-lite.c | |
parent | 488f29d00e819b178f9060fa08028b73d5f8d916 (diff) |
[media] exynos4-is: Make fimc-lite independent of the pipeline->subdevs array
Get the sensor subdev by walking media graph in both cases: when the
device is used as a subdev only and through video node. This allows
to not dereference the pipeline->subdevs[] array and makes the module
more generic and easier to re-use in other media driver.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform/exynos4-is/fimc-lite.c')
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.c | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index cb196b85a858..3ea4fc7beaf7 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
@@ -130,23 +130,43 @@ static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat, | |||
130 | return def_fmt; | 130 | return def_fmt; |
131 | } | 131 | } |
132 | 132 | ||
133 | /* Called with the media graph mutex held or @me stream_count > 0. */ | ||
134 | static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me) | ||
135 | { | ||
136 | struct media_pad *pad = &me->pads[0]; | ||
137 | struct v4l2_subdev *sd; | ||
138 | |||
139 | while (pad->flags & MEDIA_PAD_FL_SINK) { | ||
140 | /* source pad */ | ||
141 | pad = media_entity_remote_source(pad); | ||
142 | if (pad == NULL || | ||
143 | media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) | ||
144 | break; | ||
145 | |||
146 | sd = media_entity_to_v4l2_subdev(pad->entity); | ||
147 | |||
148 | if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR || | ||
149 | sd->grp_id == GRP_ID_SENSOR) | ||
150 | return sd; | ||
151 | /* sink pad */ | ||
152 | pad = &sd->entity.pads[0]; | ||
153 | } | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
133 | static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output) | 157 | static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output) |
134 | { | 158 | { |
135 | struct fimc_pipeline *pipeline = &fimc->pipeline; | ||
136 | struct v4l2_subdev *sensor; | ||
137 | struct fimc_sensor_info *si; | 159 | struct fimc_sensor_info *si; |
138 | unsigned long flags; | 160 | unsigned long flags; |
139 | 161 | ||
140 | sensor = isp_output ? fimc->sensor : pipeline->subdevs[IDX_SENSOR]; | 162 | if (fimc->sensor == NULL) |
141 | |||
142 | if (sensor == NULL) | ||
143 | return -ENXIO; | 163 | return -ENXIO; |
144 | 164 | ||
145 | if (fimc->inp_frame.fmt == NULL || fimc->out_frame.fmt == NULL) | 165 | if (fimc->inp_frame.fmt == NULL || fimc->out_frame.fmt == NULL) |
146 | return -EINVAL; | 166 | return -EINVAL; |
147 | 167 | ||
148 | /* Get sensor configuration data from the sensor subdev */ | 168 | /* Get sensor configuration data from the sensor subdev */ |
149 | si = v4l2_get_subdev_hostdata(sensor); | 169 | si = v4l2_get_subdev_hostdata(fimc->sensor); |
150 | spin_lock_irqsave(&fimc->slock, flags); | 170 | spin_lock_irqsave(&fimc->slock, flags); |
151 | 171 | ||
152 | flite_hw_set_camera_bus(fimc, &si->pdata); | 172 | flite_hw_set_camera_bus(fimc, &si->pdata); |
@@ -801,6 +821,8 @@ static int fimc_lite_streamon(struct file *file, void *priv, | |||
801 | if (ret < 0) | 821 | if (ret < 0) |
802 | goto err_p_stop; | 822 | goto err_p_stop; |
803 | 823 | ||
824 | fimc->sensor = __find_remote_sensor(&fimc->subdev.entity); | ||
825 | |||
804 | ret = vb2_ioctl_streamon(file, priv, type); | 826 | ret = vb2_ioctl_streamon(file, priv, type); |
805 | if (!ret) { | 827 | if (!ret) { |
806 | fimc->streaming = true; | 828 | fimc->streaming = true; |
@@ -929,29 +951,6 @@ static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = { | |||
929 | .vidioc_streamoff = fimc_lite_streamoff, | 951 | .vidioc_streamoff = fimc_lite_streamoff, |
930 | }; | 952 | }; |
931 | 953 | ||
932 | /* Called with the media graph mutex held */ | ||
933 | static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me) | ||
934 | { | ||
935 | struct media_pad *pad = &me->pads[0]; | ||
936 | struct v4l2_subdev *sd; | ||
937 | |||
938 | while (pad->flags & MEDIA_PAD_FL_SINK) { | ||
939 | /* source pad */ | ||
940 | pad = media_entity_remote_source(pad); | ||
941 | if (pad == NULL || | ||
942 | media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) | ||
943 | break; | ||
944 | |||
945 | sd = media_entity_to_v4l2_subdev(pad->entity); | ||
946 | |||
947 | if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR) | ||
948 | return sd; | ||
949 | /* sink pad */ | ||
950 | pad = &sd->entity.pads[0]; | ||
951 | } | ||
952 | return NULL; | ||
953 | } | ||
954 | |||
955 | /* Capture subdev media entity operations */ | 954 | /* Capture subdev media entity operations */ |
956 | static int fimc_lite_link_setup(struct media_entity *entity, | 955 | static int fimc_lite_link_setup(struct media_entity *entity, |
957 | const struct media_pad *local, | 956 | const struct media_pad *local, |