diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-05-31 10:37:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-06-12 20:57:59 -0400 |
commit | 403dfbec45419c1838e0ea3be16625986ec17cfd (patch) | |
tree | 5098d4c6538bcb6e8044761efb18e81598080e9f | |
parent | 4bd728a16ee8212e3e468dabb737fe9ef5cea83d (diff) |
[media] exynos4-is: Use common exynos_media_pipeline data structure
This enumeration is now private to exynos4-is and the exynos5 camera
subsystem driver may have the subdevs handling designed differently.
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>
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-capture.c | 67 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-core.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.c | 29 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/media-dev.c | 110 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/media-dev.h | 38 | ||||
-rw-r--r-- | include/media/s5p_fimc.h | 53 |
7 files changed, 187 insertions, 114 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index b2f9581f1a8a..33c6a2f0ad74 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c | |||
@@ -120,8 +120,7 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend) | |||
120 | spin_unlock_irqrestore(&fimc->slock, flags); | 120 | spin_unlock_irqrestore(&fimc->slock, flags); |
121 | 121 | ||
122 | if (streaming) | 122 | if (streaming) |
123 | return fimc_pipeline_call(fimc, set_stream, | 123 | return fimc_pipeline_call(&cap->ve, set_stream, 0); |
124 | &fimc->pipeline, 0); | ||
125 | else | 124 | else |
126 | return 0; | 125 | return 0; |
127 | } | 126 | } |
@@ -179,8 +178,9 @@ static int fimc_capture_config_update(struct fimc_ctx *ctx) | |||
179 | 178 | ||
180 | void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf) | 179 | void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf) |
181 | { | 180 | { |
182 | struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS]; | ||
183 | struct fimc_vid_cap *cap = &fimc->vid_cap; | 181 | struct fimc_vid_cap *cap = &fimc->vid_cap; |
182 | struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe); | ||
183 | struct v4l2_subdev *csis = p->subdevs[IDX_CSIS]; | ||
184 | struct fimc_frame *f = &cap->ctx->d_frame; | 184 | struct fimc_frame *f = &cap->ctx->d_frame; |
185 | struct fimc_vid_buffer *v_buf; | 185 | struct fimc_vid_buffer *v_buf; |
186 | struct timeval *tv; | 186 | struct timeval *tv; |
@@ -288,8 +288,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) | |||
288 | fimc_activate_capture(ctx); | 288 | fimc_activate_capture(ctx); |
289 | 289 | ||
290 | if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) | 290 | if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) |
291 | return fimc_pipeline_call(fimc, set_stream, | 291 | return fimc_pipeline_call(&vid_cap->ve, set_stream, 1); |
292 | &fimc->pipeline, 1); | ||
293 | } | 292 | } |
294 | 293 | ||
295 | return 0; | 294 | return 0; |
@@ -313,7 +312,7 @@ int fimc_capture_suspend(struct fimc_dev *fimc) | |||
313 | int ret = fimc_stop_capture(fimc, suspend); | 312 | int ret = fimc_stop_capture(fimc, suspend); |
314 | if (ret) | 313 | if (ret) |
315 | return ret; | 314 | return ret; |
316 | return fimc_pipeline_call(fimc, close, &fimc->pipeline); | 315 | return fimc_pipeline_call(&fimc->vid_cap.ve, close); |
317 | } | 316 | } |
318 | 317 | ||
319 | static void buffer_queue(struct vb2_buffer *vb); | 318 | static void buffer_queue(struct vb2_buffer *vb); |
@@ -330,8 +329,7 @@ int fimc_capture_resume(struct fimc_dev *fimc) | |||
330 | 329 | ||
331 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); | 330 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); |
332 | vid_cap->buf_index = 0; | 331 | vid_cap->buf_index = 0; |
333 | fimc_pipeline_call(fimc, open, &fimc->pipeline, | 332 | fimc_pipeline_call(ve, open, &ve->vdev.entity, false); |
334 | &ve->vdev.entity, false); | ||
335 | fimc_capture_hw_init(fimc); | 333 | fimc_capture_hw_init(fimc); |
336 | 334 | ||
337 | clear_bit(ST_CAPT_SUSPENDED, &fimc->state); | 335 | clear_bit(ST_CAPT_SUSPENDED, &fimc->state); |
@@ -455,7 +453,7 @@ static void buffer_queue(struct vb2_buffer *vb) | |||
455 | if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) | 453 | if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) |
456 | return; | 454 | return; |
457 | 455 | ||
458 | ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1); | 456 | ret = fimc_pipeline_call(ve, set_stream, 1); |
459 | if (ret < 0) | 457 | if (ret < 0) |
460 | v4l2_err(&ve->vdev, "stream on failed: %d\n", ret); | 458 | v4l2_err(&ve->vdev, "stream on failed: %d\n", ret); |
461 | return; | 459 | return; |
@@ -503,8 +501,8 @@ static int fimc_capture_open(struct file *file) | |||
503 | if (v4l2_fh_is_singular_file(file)) { | 501 | if (v4l2_fh_is_singular_file(file)) { |
504 | fimc_md_graph_lock(ve); | 502 | fimc_md_graph_lock(ve); |
505 | 503 | ||
506 | ret = fimc_pipeline_call(fimc, open, &fimc->pipeline, | 504 | ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true); |
507 | &fimc->vid_cap.ve.vdev.entity, true); | 505 | |
508 | if (ret == 0) | 506 | if (ret == 0) |
509 | ret = fimc_capture_set_default_format(fimc); | 507 | ret = fimc_capture_set_default_format(fimc); |
510 | 508 | ||
@@ -555,8 +553,7 @@ static int fimc_capture_release(struct file *file) | |||
555 | 553 | ||
556 | if (close) { | 554 | if (close) { |
557 | clear_bit(ST_CAPT_BUSY, &fimc->state); | 555 | clear_bit(ST_CAPT_BUSY, &fimc->state); |
558 | fimc_stop_capture(fimc, false); | 556 | fimc_pipeline_call(&vc->ve, close); |
559 | fimc_pipeline_call(fimc, close, &fimc->pipeline); | ||
560 | clear_bit(ST_CAPT_SUSPENDED, &fimc->state); | 557 | clear_bit(ST_CAPT_SUSPENDED, &fimc->state); |
561 | 558 | ||
562 | fimc_md_graph_lock(&vc->ve); | 559 | fimc_md_graph_lock(&vc->ve); |
@@ -786,7 +783,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
786 | bool set) | 783 | bool set) |
787 | { | 784 | { |
788 | struct fimc_dev *fimc = ctx->fimc_dev; | 785 | struct fimc_dev *fimc = ctx->fimc_dev; |
789 | struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR]; | 786 | struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe); |
787 | struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR]; | ||
790 | struct v4l2_subdev_format sfmt; | 788 | struct v4l2_subdev_format sfmt; |
791 | struct v4l2_mbus_framefmt *mf = &sfmt.format; | 789 | struct v4l2_mbus_framefmt *mf = &sfmt.format; |
792 | struct media_entity *me; | 790 | struct media_entity *me; |
@@ -926,6 +924,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh, | |||
926 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; | 924 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
927 | struct exynos_video_entity *ve = &fimc->vid_cap.ve; | 925 | struct exynos_video_entity *ve = &fimc->vid_cap.ve; |
928 | struct v4l2_mbus_framefmt mf; | 926 | struct v4l2_mbus_framefmt mf; |
927 | struct v4l2_subdev *sensor; | ||
929 | struct fimc_fmt *ffmt = NULL; | 928 | struct fimc_fmt *ffmt = NULL; |
930 | int ret = 0; | 929 | int ret = 0; |
931 | 930 | ||
@@ -959,9 +958,18 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh, | |||
959 | 958 | ||
960 | fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix); | 959 | fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix); |
961 | 960 | ||
962 | if (ffmt->flags & FMT_FLAGS_COMPRESSED) | 961 | if (ffmt->flags & FMT_FLAGS_COMPRESSED) { |
963 | fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR], | 962 | fimc_md_graph_lock(ve); |
964 | pix->plane_fmt, ffmt->memplanes, true); | 963 | |
964 | sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR); | ||
965 | if (sensor) | ||
966 | fimc_get_sensor_frame_desc(sensor, pix->plane_fmt, | ||
967 | ffmt->memplanes, true); | ||
968 | else | ||
969 | ret = -EPIPE; | ||
970 | |||
971 | fimc_md_graph_unlock(ve); | ||
972 | } | ||
965 | 973 | ||
966 | return ret; | 974 | return ret; |
967 | } | 975 | } |
@@ -986,6 +994,7 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc, | |||
986 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; | 994 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
987 | struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; | 995 | struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; |
988 | struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt; | 996 | struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt; |
997 | struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe); | ||
989 | struct fimc_frame *ff = &ctx->d_frame; | 998 | struct fimc_frame *ff = &ctx->d_frame; |
990 | struct fimc_fmt *s_fmt = NULL; | 999 | struct fimc_fmt *s_fmt = NULL; |
991 | int ret, i; | 1000 | int ret, i; |
@@ -1027,7 +1036,7 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc, | |||
1027 | fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); | 1036 | fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); |
1028 | 1037 | ||
1029 | if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) { | 1038 | if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) { |
1030 | ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR], | 1039 | ret = fimc_get_sensor_frame_desc(p->subdevs[IDX_SENSOR], |
1031 | pix->plane_fmt, ff->fmt->memplanes, | 1040 | pix->plane_fmt, ff->fmt->memplanes, |
1032 | true); | 1041 | true); |
1033 | if (ret < 0) | 1042 | if (ret < 0) |
@@ -1078,14 +1087,20 @@ static int fimc_cap_enum_input(struct file *file, void *priv, | |||
1078 | struct v4l2_input *i) | 1087 | struct v4l2_input *i) |
1079 | { | 1088 | { |
1080 | struct fimc_dev *fimc = video_drvdata(file); | 1089 | struct fimc_dev *fimc = video_drvdata(file); |
1081 | struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR]; | 1090 | struct exynos_video_entity *ve = &fimc->vid_cap.ve; |
1091 | struct v4l2_subdev *sd; | ||
1082 | 1092 | ||
1083 | if (i->index != 0) | 1093 | if (i->index != 0) |
1084 | return -EINVAL; | 1094 | return -EINVAL; |
1085 | 1095 | ||
1086 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1096 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1097 | fimc_md_graph_lock(ve); | ||
1098 | sd = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR); | ||
1099 | fimc_md_graph_unlock(ve); | ||
1100 | |||
1087 | if (sd) | 1101 | if (sd) |
1088 | strlcpy(i->name, sd->name, sizeof(i->name)); | 1102 | strlcpy(i->name, sd->name, sizeof(i->name)); |
1103 | |||
1089 | return 0; | 1104 | return 0; |
1090 | } | 1105 | } |
1091 | 1106 | ||
@@ -1111,6 +1126,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) | |||
1111 | struct v4l2_subdev_format sink_fmt, src_fmt; | 1126 | struct v4l2_subdev_format sink_fmt, src_fmt; |
1112 | struct fimc_vid_cap *vc = &fimc->vid_cap; | 1127 | struct fimc_vid_cap *vc = &fimc->vid_cap; |
1113 | struct v4l2_subdev *sd = &vc->subdev; | 1128 | struct v4l2_subdev *sd = &vc->subdev; |
1129 | struct fimc_pipeline *p = to_fimc_pipeline(vc->ve.pipe); | ||
1114 | struct media_pad *sink_pad, *src_pad; | 1130 | struct media_pad *sink_pad, *src_pad; |
1115 | int i, ret; | 1131 | int i, ret; |
1116 | 1132 | ||
@@ -1164,7 +1180,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) | |||
1164 | src_fmt.format.code != sink_fmt.format.code) | 1180 | src_fmt.format.code != sink_fmt.format.code) |
1165 | return -EPIPE; | 1181 | return -EPIPE; |
1166 | 1182 | ||
1167 | if (sd == fimc->pipeline.subdevs[IDX_SENSOR] && | 1183 | if (sd == p->subdevs[IDX_SENSOR] && |
1168 | fimc_user_defined_mbus_fmt(src_fmt.format.code)) { | 1184 | fimc_user_defined_mbus_fmt(src_fmt.format.code)) { |
1169 | struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES]; | 1185 | struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES]; |
1170 | struct fimc_frame *frame = &vc->ctx->d_frame; | 1186 | struct fimc_frame *frame = &vc->ctx->d_frame; |
@@ -1188,7 +1204,6 @@ static int fimc_cap_streamon(struct file *file, void *priv, | |||
1188 | enum v4l2_buf_type type) | 1204 | enum v4l2_buf_type type) |
1189 | { | 1205 | { |
1190 | struct fimc_dev *fimc = video_drvdata(file); | 1206 | struct fimc_dev *fimc = video_drvdata(file); |
1191 | struct fimc_pipeline *p = &fimc->pipeline; | ||
1192 | struct fimc_vid_cap *vc = &fimc->vid_cap; | 1207 | struct fimc_vid_cap *vc = &fimc->vid_cap; |
1193 | struct media_entity *entity = &vc->ve.vdev.entity; | 1208 | struct media_entity *entity = &vc->ve.vdev.entity; |
1194 | struct fimc_source_info *si = NULL; | 1209 | struct fimc_source_info *si = NULL; |
@@ -1198,11 +1213,11 @@ static int fimc_cap_streamon(struct file *file, void *priv, | |||
1198 | if (fimc_capture_active(fimc)) | 1213 | if (fimc_capture_active(fimc)) |
1199 | return -EBUSY; | 1214 | return -EBUSY; |
1200 | 1215 | ||
1201 | ret = media_entity_pipeline_start(entity, p->m_pipeline); | 1216 | ret = media_entity_pipeline_start(entity, &vc->ve.pipe->mp); |
1202 | if (ret < 0) | 1217 | if (ret < 0) |
1203 | return ret; | 1218 | return ret; |
1204 | 1219 | ||
1205 | sd = p->subdevs[IDX_SENSOR]; | 1220 | sd = __fimc_md_get_subdev(vc->ve.pipe, IDX_SENSOR); |
1206 | if (sd) | 1221 | if (sd) |
1207 | si = v4l2_get_subdev_hostdata(sd); | 1222 | si = v4l2_get_subdev_hostdata(sd); |
1208 | 1223 | ||
@@ -1821,12 +1836,12 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd) | |||
1821 | if (ret) | 1836 | if (ret) |
1822 | return ret; | 1837 | return ret; |
1823 | 1838 | ||
1824 | fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); | 1839 | fimc->vid_cap.ve.pipe = v4l2_get_subdev_hostdata(sd); |
1825 | 1840 | ||
1826 | ret = fimc_register_capture_device(fimc, sd->v4l2_dev); | 1841 | ret = fimc_register_capture_device(fimc, sd->v4l2_dev); |
1827 | if (ret) { | 1842 | if (ret) { |
1828 | fimc_unregister_m2m_device(fimc); | 1843 | fimc_unregister_m2m_device(fimc); |
1829 | fimc->pipeline_ops = NULL; | 1844 | fimc->vid_cap.ve.pipe = NULL; |
1830 | } | 1845 | } |
1831 | 1846 | ||
1832 | return ret; | 1847 | return ret; |
@@ -1847,7 +1862,7 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) | |||
1847 | video_unregister_device(vdev); | 1862 | video_unregister_device(vdev); |
1848 | media_entity_cleanup(&vdev->entity); | 1863 | media_entity_cleanup(&vdev->entity); |
1849 | fimc_ctrls_delete(fimc->vid_cap.ctx); | 1864 | fimc_ctrls_delete(fimc->vid_cap.ctx); |
1850 | fimc->pipeline_ops = NULL; | 1865 | fimc->vid_cap.ve.pipe = NULL; |
1851 | } | 1866 | } |
1852 | kfree(fimc->vid_cap.ctx); | 1867 | kfree(fimc->vid_cap.ctx); |
1853 | fimc->vid_cap.ctx = NULL; | 1868 | fimc->vid_cap.ctx = NULL; |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h index e3da4ffd7a5e..c48a79254d83 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.h +++ b/drivers/media/platform/exynos4-is/fimc-core.h | |||
@@ -435,8 +435,6 @@ struct fimc_dev { | |||
435 | struct fimc_vid_cap vid_cap; | 435 | struct fimc_vid_cap vid_cap; |
436 | unsigned long state; | 436 | unsigned long state; |
437 | struct vb2_alloc_ctx *alloc_ctx; | 437 | struct vb2_alloc_ctx *alloc_ctx; |
438 | struct fimc_pipeline pipeline; | ||
439 | const struct fimc_pipeline_ops *pipeline_ops; | ||
440 | }; | 438 | }; |
441 | 439 | ||
442 | /** | 440 | /** |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 0f372bfffaf0..24e2a0f8797a 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
@@ -210,7 +210,7 @@ static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend) | |||
210 | if (!streaming) | 210 | if (!streaming) |
211 | return 0; | 211 | return 0; |
212 | 212 | ||
213 | return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0); | 213 | return fimc_pipeline_call(&fimc->ve, set_stream, 0); |
214 | } | 214 | } |
215 | 215 | ||
216 | static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend) | 216 | static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend) |
@@ -324,8 +324,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) | |||
324 | flite_hw_capture_start(fimc); | 324 | flite_hw_capture_start(fimc); |
325 | 325 | ||
326 | if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) | 326 | if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) |
327 | fimc_pipeline_call(fimc, set_stream, | 327 | fimc_pipeline_call(&fimc->ve, set_stream, 1); |
328 | &fimc->pipeline, 1); | ||
329 | } | 328 | } |
330 | if (debug > 0) | 329 | if (debug > 0) |
331 | flite_hw_dump_regs(fimc, __func__); | 330 | flite_hw_dump_regs(fimc, __func__); |
@@ -429,8 +428,7 @@ static void buffer_queue(struct vb2_buffer *vb) | |||
429 | spin_unlock_irqrestore(&fimc->slock, flags); | 428 | spin_unlock_irqrestore(&fimc->slock, flags); |
430 | 429 | ||
431 | if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) | 430 | if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) |
432 | fimc_pipeline_call(fimc, set_stream, | 431 | fimc_pipeline_call(&fimc->ve, set_stream, 1); |
433 | &fimc->pipeline, 1); | ||
434 | return; | 432 | return; |
435 | } | 433 | } |
436 | spin_unlock_irqrestore(&fimc->slock, flags); | 434 | spin_unlock_irqrestore(&fimc->slock, flags); |
@@ -482,8 +480,7 @@ static int fimc_lite_open(struct file *file) | |||
482 | 480 | ||
483 | mutex_lock(&me->parent->graph_mutex); | 481 | mutex_lock(&me->parent->graph_mutex); |
484 | 482 | ||
485 | ret = fimc_pipeline_call(fimc, open, &fimc->pipeline, | 483 | ret = fimc_pipeline_call(&fimc->ve, open, me, true); |
486 | me, true); | ||
487 | 484 | ||
488 | /* Mark video pipeline ending at this video node as in use. */ | 485 | /* Mark video pipeline ending at this video node as in use. */ |
489 | if (ret == 0) | 486 | if (ret == 0) |
@@ -518,9 +515,10 @@ static int fimc_lite_release(struct file *file) | |||
518 | media_entity_pipeline_stop(entity); | 515 | media_entity_pipeline_stop(entity); |
519 | fimc->streaming = false; | 516 | fimc->streaming = false; |
520 | } | 517 | } |
521 | clear_bit(ST_FLITE_IN_USE, &fimc->state); | ||
522 | fimc_lite_stop_capture(fimc, false); | 518 | fimc_lite_stop_capture(fimc, false); |
523 | fimc_pipeline_call(fimc, close, &fimc->pipeline); | 519 | fimc_pipeline_call(&fimc->ve, close); |
520 | clear_bit(ST_FLITE_IN_USE, &fimc->state); | ||
521 | |||
524 | mutex_lock(&entity->parent->graph_mutex); | 522 | mutex_lock(&entity->parent->graph_mutex); |
525 | entity->use_count--; | 523 | entity->use_count--; |
526 | mutex_unlock(&entity->parent->graph_mutex); | 524 | mutex_unlock(&entity->parent->graph_mutex); |
@@ -801,13 +799,12 @@ static int fimc_lite_streamon(struct file *file, void *priv, | |||
801 | { | 799 | { |
802 | struct fimc_lite *fimc = video_drvdata(file); | 800 | struct fimc_lite *fimc = video_drvdata(file); |
803 | struct media_entity *entity = &fimc->ve.vdev.entity; | 801 | struct media_entity *entity = &fimc->ve.vdev.entity; |
804 | struct fimc_pipeline *p = &fimc->pipeline; | ||
805 | int ret; | 802 | int ret; |
806 | 803 | ||
807 | if (fimc_lite_active(fimc)) | 804 | if (fimc_lite_active(fimc)) |
808 | return -EBUSY; | 805 | return -EBUSY; |
809 | 806 | ||
810 | ret = media_entity_pipeline_start(entity, p->m_pipeline); | 807 | ret = media_entity_pipeline_start(entity, &fimc->ve.pipe->mp); |
811 | if (ret < 0) | 808 | if (ret < 0) |
812 | return ret; | 809 | return ret; |
813 | 810 | ||
@@ -1282,12 +1279,12 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) | |||
1282 | return ret; | 1279 | return ret; |
1283 | 1280 | ||
1284 | video_set_drvdata(vfd, fimc); | 1281 | video_set_drvdata(vfd, fimc); |
1285 | fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); | 1282 | fimc->ve.pipe = v4l2_get_subdev_hostdata(sd); |
1286 | 1283 | ||
1287 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); | 1284 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
1288 | if (ret < 0) { | 1285 | if (ret < 0) { |
1289 | media_entity_cleanup(&vfd->entity); | 1286 | media_entity_cleanup(&vfd->entity); |
1290 | fimc->pipeline_ops = NULL; | 1287 | fimc->ve.pipe = NULL; |
1291 | return ret; | 1288 | return ret; |
1292 | } | 1289 | } |
1293 | 1290 | ||
@@ -1306,7 +1303,7 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd) | |||
1306 | if (video_is_registered(&fimc->ve.vdev)) { | 1303 | if (video_is_registered(&fimc->ve.vdev)) { |
1307 | video_unregister_device(&fimc->ve.vdev); | 1304 | video_unregister_device(&fimc->ve.vdev); |
1308 | media_entity_cleanup(&fimc->ve.vdev.entity); | 1305 | media_entity_cleanup(&fimc->ve.vdev.entity); |
1309 | fimc->pipeline_ops = NULL; | 1306 | fimc->ve.pipe = NULL; |
1310 | } | 1307 | } |
1311 | } | 1308 | } |
1312 | 1309 | ||
@@ -1552,7 +1549,7 @@ static int fimc_lite_resume(struct device *dev) | |||
1552 | return 0; | 1549 | return 0; |
1553 | 1550 | ||
1554 | INIT_LIST_HEAD(&fimc->active_buf_q); | 1551 | INIT_LIST_HEAD(&fimc->active_buf_q); |
1555 | fimc_pipeline_call(fimc, open, &fimc->pipeline, | 1552 | fimc_pipeline_call(&fimc->ve, open, |
1556 | &fimc->ve.vdev.entity, false); | 1553 | &fimc->ve.vdev.entity, false); |
1557 | fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP); | 1554 | fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP); |
1558 | clear_bit(ST_FLITE_SUSPENDED, &fimc->state); | 1555 | clear_bit(ST_FLITE_SUSPENDED, &fimc->state); |
@@ -1579,7 +1576,7 @@ static int fimc_lite_suspend(struct device *dev) | |||
1579 | if (ret < 0 || !fimc_lite_active(fimc)) | 1576 | if (ret < 0 || !fimc_lite_active(fimc)) |
1580 | return ret; | 1577 | return ret; |
1581 | 1578 | ||
1582 | return fimc_pipeline_call(fimc, close, &fimc->pipeline); | 1579 | return fimc_pipeline_call(&fimc->ve, close); |
1583 | } | 1580 | } |
1584 | #endif /* CONFIG_PM_SLEEP */ | 1581 | #endif /* CONFIG_PM_SLEEP */ |
1585 | 1582 | ||
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h index 25abba98d7e9..c7aa08477830 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.h +++ b/drivers/media/platform/exynos4-is/fimc-lite.h | |||
@@ -140,8 +140,6 @@ struct fimc_lite { | |||
140 | struct v4l2_ctrl_handler ctrl_handler; | 140 | struct v4l2_ctrl_handler ctrl_handler; |
141 | struct v4l2_ctrl *test_pattern; | 141 | struct v4l2_ctrl *test_pattern; |
142 | int index; | 142 | int index; |
143 | struct fimc_pipeline pipeline; | ||
144 | const struct fimc_pipeline_ops *pipeline_ops; | ||
145 | 143 | ||
146 | struct mutex lock; | 144 | struct mutex lock; |
147 | spinlock_t slock; | 145 | spinlock_t slock; |
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 1b4bb25d0a55..2020e44f63b1 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c | |||
@@ -46,7 +46,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, | |||
46 | * Caller holds the graph mutex. | 46 | * Caller holds the graph mutex. |
47 | */ | 47 | */ |
48 | static void fimc_pipeline_prepare(struct fimc_pipeline *p, | 48 | static void fimc_pipeline_prepare(struct fimc_pipeline *p, |
49 | struct media_entity *me) | 49 | struct media_entity *me) |
50 | { | 50 | { |
51 | struct v4l2_subdev *sd; | 51 | struct v4l2_subdev *sd; |
52 | int i; | 52 | int i; |
@@ -168,10 +168,11 @@ error: | |||
168 | * | 168 | * |
169 | * Called with the graph mutex held. | 169 | * Called with the graph mutex held. |
170 | */ | 170 | */ |
171 | static int __fimc_pipeline_open(struct fimc_pipeline *p, | 171 | static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, |
172 | struct media_entity *me, bool prepare) | 172 | struct media_entity *me, bool prepare) |
173 | { | 173 | { |
174 | struct fimc_md *fmd = entity_to_fimc_mdev(me); | 174 | struct fimc_md *fmd = entity_to_fimc_mdev(me); |
175 | struct fimc_pipeline *p = to_fimc_pipeline(ep); | ||
175 | struct v4l2_subdev *sd; | 176 | struct v4l2_subdev *sd; |
176 | int ret; | 177 | int ret; |
177 | 178 | ||
@@ -214,8 +215,9 @@ err_wbclk: | |||
214 | * | 215 | * |
215 | * Disable power of all subdevs and turn the external sensor clock off. | 216 | * Disable power of all subdevs and turn the external sensor clock off. |
216 | */ | 217 | */ |
217 | static int __fimc_pipeline_close(struct fimc_pipeline *p) | 218 | static int __fimc_pipeline_close(struct exynos_media_pipeline *ep) |
218 | { | 219 | { |
220 | struct fimc_pipeline *p = to_fimc_pipeline(ep); | ||
219 | struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL; | 221 | struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL; |
220 | struct fimc_md *fmd; | 222 | struct fimc_md *fmd; |
221 | int ret = 0; | 223 | int ret = 0; |
@@ -242,12 +244,13 @@ static int __fimc_pipeline_close(struct fimc_pipeline *p) | |||
242 | * @pipeline: video pipeline structure | 244 | * @pipeline: video pipeline structure |
243 | * @on: passed as the s_stream() callback argument | 245 | * @on: passed as the s_stream() callback argument |
244 | */ | 246 | */ |
245 | static int __fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on) | 247 | static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on) |
246 | { | 248 | { |
247 | static const u8 seq[2][IDX_MAX] = { | 249 | static const u8 seq[2][IDX_MAX] = { |
248 | { IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE }, | 250 | { IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE }, |
249 | { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP }, | 251 | { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP }, |
250 | }; | 252 | }; |
253 | struct fimc_pipeline *p = to_fimc_pipeline(ep); | ||
251 | int i, ret = 0; | 254 | int i, ret = 0; |
252 | 255 | ||
253 | if (p->subdevs[IDX_SENSOR] == NULL) | 256 | if (p->subdevs[IDX_SENSOR] == NULL) |
@@ -271,12 +274,38 @@ error: | |||
271 | } | 274 | } |
272 | 275 | ||
273 | /* Media pipeline operations for the FIMC/FIMC-LITE video device driver */ | 276 | /* Media pipeline operations for the FIMC/FIMC-LITE video device driver */ |
274 | static const struct fimc_pipeline_ops fimc_pipeline_ops = { | 277 | static const struct exynos_media_pipeline_ops fimc_pipeline_ops = { |
275 | .open = __fimc_pipeline_open, | 278 | .open = __fimc_pipeline_open, |
276 | .close = __fimc_pipeline_close, | 279 | .close = __fimc_pipeline_close, |
277 | .set_stream = __fimc_pipeline_s_stream, | 280 | .set_stream = __fimc_pipeline_s_stream, |
278 | }; | 281 | }; |
279 | 282 | ||
283 | static struct exynos_media_pipeline *fimc_md_pipeline_create( | ||
284 | struct fimc_md *fmd) | ||
285 | { | ||
286 | struct fimc_pipeline *p; | ||
287 | |||
288 | p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
289 | if (!p) | ||
290 | return NULL; | ||
291 | |||
292 | list_add_tail(&p->list, &fmd->pipelines); | ||
293 | |||
294 | p->ep.ops = &fimc_pipeline_ops; | ||
295 | return &p->ep; | ||
296 | } | ||
297 | |||
298 | static void fimc_md_pipelines_free(struct fimc_md *fmd) | ||
299 | { | ||
300 | while (!list_empty(&fmd->pipelines)) { | ||
301 | struct fimc_pipeline *p; | ||
302 | |||
303 | p = list_entry(fmd->pipelines.next, typeof(*p), list); | ||
304 | list_del(&p->list); | ||
305 | kfree(p); | ||
306 | } | ||
307 | } | ||
308 | |||
280 | /* | 309 | /* |
281 | * Sensor subdevice helper functions | 310 | * Sensor subdevice helper functions |
282 | */ | 311 | */ |
@@ -592,6 +621,7 @@ static int register_fimc_lite_entity(struct fimc_md *fmd, | |||
592 | struct fimc_lite *fimc_lite) | 621 | struct fimc_lite *fimc_lite) |
593 | { | 622 | { |
594 | struct v4l2_subdev *sd; | 623 | struct v4l2_subdev *sd; |
624 | struct exynos_media_pipeline *ep; | ||
595 | int ret; | 625 | int ret; |
596 | 626 | ||
597 | if (WARN_ON(fimc_lite->index >= FIMC_LITE_MAX_DEVS || | 627 | if (WARN_ON(fimc_lite->index >= FIMC_LITE_MAX_DEVS || |
@@ -600,7 +630,12 @@ static int register_fimc_lite_entity(struct fimc_md *fmd, | |||
600 | 630 | ||
601 | sd = &fimc_lite->subdev; | 631 | sd = &fimc_lite->subdev; |
602 | sd->grp_id = GRP_ID_FLITE; | 632 | sd->grp_id = GRP_ID_FLITE; |
603 | v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops); | 633 | |
634 | ep = fimc_md_pipeline_create(fmd); | ||
635 | if (!ep) | ||
636 | return -ENOMEM; | ||
637 | |||
638 | v4l2_set_subdev_hostdata(sd, ep); | ||
604 | 639 | ||
605 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); | 640 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); |
606 | if (!ret) | 641 | if (!ret) |
@@ -614,6 +649,7 @@ static int register_fimc_lite_entity(struct fimc_md *fmd, | |||
614 | static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc) | 649 | static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc) |
615 | { | 650 | { |
616 | struct v4l2_subdev *sd; | 651 | struct v4l2_subdev *sd; |
652 | struct exynos_media_pipeline *ep; | ||
617 | int ret; | 653 | int ret; |
618 | 654 | ||
619 | if (WARN_ON(fimc->id >= FIMC_MAX_DEVS || fmd->fimc[fimc->id])) | 655 | if (WARN_ON(fimc->id >= FIMC_MAX_DEVS || fmd->fimc[fimc->id])) |
@@ -621,7 +657,12 @@ static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc) | |||
621 | 657 | ||
622 | sd = &fimc->vid_cap.subdev; | 658 | sd = &fimc->vid_cap.subdev; |
623 | sd->grp_id = GRP_ID_FIMC; | 659 | sd->grp_id = GRP_ID_FIMC; |
624 | v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops); | 660 | |
661 | ep = fimc_md_pipeline_create(fmd); | ||
662 | if (!ep) | ||
663 | return -ENOMEM; | ||
664 | |||
665 | v4l2_set_subdev_hostdata(sd, ep); | ||
625 | 666 | ||
626 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); | 667 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); |
627 | if (!ret) { | 668 | if (!ret) { |
@@ -797,17 +838,19 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) | |||
797 | int i; | 838 | int i; |
798 | 839 | ||
799 | for (i = 0; i < FIMC_MAX_DEVS; i++) { | 840 | for (i = 0; i < FIMC_MAX_DEVS; i++) { |
800 | if (fmd->fimc[i] == NULL) | 841 | struct fimc_dev *dev = fmd->fimc[i]; |
842 | if (dev == NULL) | ||
801 | continue; | 843 | continue; |
802 | v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev); | 844 | v4l2_device_unregister_subdev(&dev->vid_cap.subdev); |
803 | fmd->fimc[i]->pipeline_ops = NULL; | 845 | dev->vid_cap.ve.pipe = NULL; |
804 | fmd->fimc[i] = NULL; | 846 | fmd->fimc[i] = NULL; |
805 | } | 847 | } |
806 | for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) { | 848 | for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) { |
807 | if (fmd->fimc_lite[i] == NULL) | 849 | struct fimc_lite *dev = fmd->fimc_lite[i]; |
850 | if (dev == NULL) | ||
808 | continue; | 851 | continue; |
809 | v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev); | 852 | v4l2_device_unregister_subdev(&dev->subdev); |
810 | fmd->fimc_lite[i]->pipeline_ops = NULL; | 853 | dev->ve.pipe = NULL; |
811 | fmd->fimc_lite[i] = NULL; | 854 | fmd->fimc_lite[i] = NULL; |
812 | } | 855 | } |
813 | for (i = 0; i < CSIS_MAX_ENTITIES; i++) { | 856 | for (i = 0; i < CSIS_MAX_ENTITIES; i++) { |
@@ -1234,38 +1277,22 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) | |||
1234 | static int fimc_md_link_notify(struct media_pad *source, | 1277 | static int fimc_md_link_notify(struct media_pad *source, |
1235 | struct media_pad *sink, u32 flags) | 1278 | struct media_pad *sink, u32 flags) |
1236 | { | 1279 | { |
1237 | struct fimc_lite *fimc_lite = NULL; | 1280 | struct exynos_video_entity *ve; |
1238 | struct fimc_dev *fimc = NULL; | 1281 | struct video_device *vdev; |
1239 | struct fimc_pipeline *pipeline; | 1282 | struct fimc_pipeline *pipeline; |
1240 | struct v4l2_subdev *sd; | ||
1241 | int i, ret = 0; | 1283 | int i, ret = 0; |
1242 | 1284 | ||
1243 | if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV) | 1285 | if (media_entity_type(sink->entity) != MEDIA_ENT_T_DEVNODE_V4L) |
1244 | return 0; | 1286 | return 0; |
1245 | 1287 | ||
1246 | sd = media_entity_to_v4l2_subdev(sink->entity); | 1288 | vdev = media_entity_to_video_device(sink->entity); |
1247 | 1289 | ve = vdev_to_exynos_video_entity(vdev); | |
1248 | switch (sd->grp_id) { | 1290 | pipeline = to_fimc_pipeline(ve->pipe); |
1249 | case GRP_ID_FLITE: | 1291 | |
1250 | fimc_lite = v4l2_get_subdevdata(sd); | 1292 | if (!(flags & MEDIA_LNK_FL_ENABLED) && pipeline->subdevs[IDX_SENSOR]) { |
1251 | if (WARN_ON(fimc_lite == NULL)) | 1293 | if (sink->entity->use_count > 0) |
1252 | return 0; | 1294 | ret = __fimc_pipeline_close(ve->pipe); |
1253 | pipeline = &fimc_lite->pipeline; | ||
1254 | break; | ||
1255 | case GRP_ID_FIMC: | ||
1256 | fimc = v4l2_get_subdevdata(sd); | ||
1257 | if (WARN_ON(fimc == NULL)) | ||
1258 | return 0; | ||
1259 | pipeline = &fimc->pipeline; | ||
1260 | break; | ||
1261 | default: | ||
1262 | return 0; | ||
1263 | } | ||
1264 | 1295 | ||
1265 | if (!(flags & MEDIA_LNK_FL_ENABLED)) { | ||
1266 | if (sink->entity->use_count > 0) { | ||
1267 | ret = __fimc_pipeline_close(pipeline); | ||
1268 | } | ||
1269 | for (i = 0; i < IDX_MAX; i++) | 1296 | for (i = 0; i < IDX_MAX; i++) |
1270 | pipeline->subdevs[i] = NULL; | 1297 | pipeline->subdevs[i] = NULL; |
1271 | } else if (sink->entity->use_count > 0) { | 1298 | } else if (sink->entity->use_count > 0) { |
@@ -1274,8 +1301,7 @@ static int fimc_md_link_notify(struct media_pad *source, | |||
1274 | * the pipeline is already in use, i.e. its video node is open. | 1301 | * the pipeline is already in use, i.e. its video node is open. |
1275 | * Recreate the controls destroyed during the link deactivation. | 1302 | * Recreate the controls destroyed during the link deactivation. |
1276 | */ | 1303 | */ |
1277 | ret = __fimc_pipeline_open(pipeline, | 1304 | ret = __fimc_pipeline_open(ve->pipe, sink->entity, true); |
1278 | source->entity, true); | ||
1279 | } | 1305 | } |
1280 | 1306 | ||
1281 | return ret ? -EPIPE : ret; | 1307 | return ret ? -EPIPE : ret; |
@@ -1358,6 +1384,7 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
1358 | 1384 | ||
1359 | spin_lock_init(&fmd->slock); | 1385 | spin_lock_init(&fmd->slock); |
1360 | fmd->pdev = pdev; | 1386 | fmd->pdev = pdev; |
1387 | INIT_LIST_HEAD(&fmd->pipelines); | ||
1361 | 1388 | ||
1362 | strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", | 1389 | strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", |
1363 | sizeof(fmd->media_dev.model)); | 1390 | sizeof(fmd->media_dev.model)); |
@@ -1445,6 +1472,7 @@ static int fimc_md_remove(struct platform_device *pdev) | |||
1445 | return 0; | 1472 | return 0; |
1446 | device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); | 1473 | device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); |
1447 | fimc_md_unregister_entities(fmd); | 1474 | fimc_md_unregister_entities(fmd); |
1475 | fimc_md_pipelines_free(fmd); | ||
1448 | media_device_unregister(&fmd->media_dev); | 1476 | media_device_unregister(&fmd->media_dev); |
1449 | fimc_md_put_clocks(fmd); | 1477 | fimc_md_put_clocks(fmd); |
1450 | return 0; | 1478 | return 0; |
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h index 3e9680c9de8b..a704eea2cfbd 100644 --- a/drivers/media/platform/exynos4-is/media-dev.h +++ b/drivers/media/platform/exynos4-is/media-dev.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <media/media-entity.h> | 18 | #include <media/media-entity.h> |
19 | #include <media/v4l2-device.h> | 19 | #include <media/v4l2-device.h> |
20 | #include <media/v4l2-subdev.h> | 20 | #include <media/v4l2-subdev.h> |
21 | #include <media/s5p_fimc.h> | ||
21 | 22 | ||
22 | #include "fimc-core.h" | 23 | #include "fimc-core.h" |
23 | #include "fimc-lite.h" | 24 | #include "fimc-lite.h" |
@@ -40,6 +41,29 @@ enum { | |||
40 | FIMC_MAX_WBCLKS | 41 | FIMC_MAX_WBCLKS |
41 | }; | 42 | }; |
42 | 43 | ||
44 | enum fimc_subdev_index { | ||
45 | IDX_SENSOR, | ||
46 | IDX_CSIS, | ||
47 | IDX_FLITE, | ||
48 | IDX_IS_ISP, | ||
49 | IDX_FIMC, | ||
50 | IDX_MAX, | ||
51 | }; | ||
52 | |||
53 | /* | ||
54 | * This structure represents a chain of media entities, including a data | ||
55 | * source entity (e.g. an image sensor subdevice), a data capture entity | ||
56 | * - a video capture device node and any remaining entities. | ||
57 | */ | ||
58 | struct fimc_pipeline { | ||
59 | struct exynos_media_pipeline ep; | ||
60 | struct list_head list; | ||
61 | struct media_entity *vdev_entity; | ||
62 | struct v4l2_subdev *subdevs[IDX_MAX]; | ||
63 | }; | ||
64 | |||
65 | #define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep) | ||
66 | |||
43 | struct fimc_csis_info { | 67 | struct fimc_csis_info { |
44 | struct v4l2_subdev *sd; | 68 | struct v4l2_subdev *sd; |
45 | int id; | 69 | int id; |
@@ -104,7 +128,9 @@ struct fimc_md { | |||
104 | struct pinctrl_state *state_idle; | 128 | struct pinctrl_state *state_idle; |
105 | } pinctl; | 129 | } pinctl; |
106 | bool user_subdev_api; | 130 | bool user_subdev_api; |
131 | |||
107 | spinlock_t slock; | 132 | spinlock_t slock; |
133 | struct list_head pipelines; | ||
108 | }; | 134 | }; |
109 | 135 | ||
110 | #define is_subdev_pad(pad) (pad == NULL || \ | 136 | #define is_subdev_pad(pad) (pad == NULL || \ |
@@ -149,4 +175,16 @@ static inline bool fimc_md_is_isp_available(struct device_node *node) | |||
149 | #define fimc_md_is_isp_available(node) (false) | 175 | #define fimc_md_is_isp_available(node) (false) |
150 | #endif /* CONFIG_OF */ | 176 | #endif /* CONFIG_OF */ |
151 | 177 | ||
178 | static inline struct v4l2_subdev *__fimc_md_get_subdev( | ||
179 | struct exynos_media_pipeline *ep, | ||
180 | unsigned int index) | ||
181 | { | ||
182 | struct fimc_pipeline *p = to_fimc_pipeline(ep); | ||
183 | |||
184 | if (!p || index >= IDX_MAX) | ||
185 | return NULL; | ||
186 | else | ||
187 | return p->subdevs[index]; | ||
188 | } | ||
189 | |||
152 | #endif | 190 | #endif |
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h index f5313b402eb7..0afadb663bbd 100644 --- a/include/media/s5p_fimc.h +++ b/include/media/s5p_fimc.h | |||
@@ -141,41 +141,40 @@ struct fimc_fmt { | |||
141 | #define FMT_FLAGS_YUV (1 << 7) | 141 | #define FMT_FLAGS_YUV (1 << 7) |
142 | }; | 142 | }; |
143 | 143 | ||
144 | enum fimc_subdev_index { | 144 | struct exynos_media_pipeline; |
145 | IDX_SENSOR, | ||
146 | IDX_CSIS, | ||
147 | IDX_FLITE, | ||
148 | IDX_IS_ISP, | ||
149 | IDX_FIMC, | ||
150 | IDX_MAX, | ||
151 | }; | ||
152 | |||
153 | struct media_pipeline; | ||
154 | struct v4l2_subdev; | ||
155 | 145 | ||
156 | struct fimc_pipeline { | 146 | /* |
157 | struct v4l2_subdev *subdevs[IDX_MAX]; | 147 | * Media pipeline operations to be called from within a video node, i.e. the |
158 | struct media_pipeline *m_pipeline; | 148 | * last entity within the pipeline. Implemented by related media device driver. |
149 | */ | ||
150 | struct exynos_media_pipeline_ops { | ||
151 | int (*prepare)(struct exynos_media_pipeline *p, | ||
152 | struct media_entity *me); | ||
153 | int (*unprepare)(struct exynos_media_pipeline *p); | ||
154 | int (*open)(struct exynos_media_pipeline *p, struct media_entity *me, | ||
155 | bool resume); | ||
156 | int (*close)(struct exynos_media_pipeline *p); | ||
157 | int (*set_stream)(struct exynos_media_pipeline *p, bool state); | ||
159 | }; | 158 | }; |
160 | 159 | ||
161 | struct exynos_video_entity { | 160 | struct exynos_video_entity { |
162 | struct video_device vdev; | 161 | struct video_device vdev; |
162 | struct exynos_media_pipeline *pipe; | ||
163 | }; | 163 | }; |
164 | 164 | ||
165 | /* | 165 | struct exynos_media_pipeline { |
166 | * Media pipeline operations to be called from within the fimc(-lite) | 166 | struct media_pipeline mp; |
167 | * video node when it is the last entity of the pipeline. Implemented | 167 | const struct exynos_media_pipeline_ops *ops; |
168 | * by corresponding media device driver. | ||
169 | */ | ||
170 | struct fimc_pipeline_ops { | ||
171 | int (*open)(struct fimc_pipeline *p, struct media_entity *me, | ||
172 | bool resume); | ||
173 | int (*close)(struct fimc_pipeline *p); | ||
174 | int (*set_stream)(struct fimc_pipeline *p, bool state); | ||
175 | }; | 168 | }; |
176 | 169 | ||
177 | #define fimc_pipeline_call(f, op, p, args...) \ | 170 | static inline struct exynos_video_entity *vdev_to_exynos_video_entity( |
178 | (!(f) ? -ENODEV : (((f)->pipeline_ops && (f)->pipeline_ops->op) ? \ | 171 | struct video_device *vdev) |
179 | (f)->pipeline_ops->op((p), ##args) : -ENOIOCTLCMD)) | 172 | { |
173 | return container_of(vdev, struct exynos_video_entity, vdev); | ||
174 | } | ||
175 | |||
176 | #define fimc_pipeline_call(ent, op, args...) \ | ||
177 | (!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \ | ||
178 | (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD)) \ | ||
180 | 179 | ||
181 | #endif /* S5P_FIMC_H_ */ | 180 | #endif /* S5P_FIMC_H_ */ |