diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2012-04-27 08:33:10 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-20 08:22:47 -0400 |
commit | 0f735f5236643cbbeb833fa0946bd52c20d00966 (patch) | |
tree | 6876c402947a40d1b35c19811e500246ccf19c61 /drivers/media/video/s5p-fimc/fimc-capture.c | |
parent | 2b511edb986fc11b8fa2b5e124c885a99aded257 (diff) |
[media] s5p-fimc: Rework the video pipeline control functions
There is getting more entities to manage within single video pipeline
in newer SoCs. To simplify code put subdevs' pointer into an array
rather than adding new member in struct fimc_pipeline for each subdev.
This allows to easier handle subdev operations in proper order.
Additionally walk graph in one direction only in fimc_pipeline_prepare()
function to make sure we properly gather only media entities that below
to single data pipeline. This avoids wrong initialization in case where,
for example there are multiple active links from s5p-mipi-csis subdev
output pad.
struct fimc_pipeline declaration is moved to the driver's public header
to allow other drivers to reuse the fimc-lite driver added in subsequent
patches.
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/video/s5p-fimc/fimc-capture.c')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 52a5fb469b45..7c884bb7104f 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -34,16 +34,17 @@ | |||
34 | static int fimc_init_capture(struct fimc_dev *fimc) | 34 | static int fimc_init_capture(struct fimc_dev *fimc) |
35 | { | 35 | { |
36 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; | 36 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
37 | struct fimc_pipeline *p = &fimc->pipeline; | ||
37 | struct fimc_sensor_info *sensor; | 38 | struct fimc_sensor_info *sensor; |
38 | unsigned long flags; | 39 | unsigned long flags; |
39 | int ret = 0; | 40 | int ret = 0; |
40 | 41 | ||
41 | if (fimc->pipeline.sensor == NULL || ctx == NULL) | 42 | if (p->subdevs[IDX_SENSOR] == NULL || ctx == NULL) |
42 | return -ENXIO; | 43 | return -ENXIO; |
43 | if (ctx->s_frame.fmt == NULL) | 44 | if (ctx->s_frame.fmt == NULL) |
44 | return -EINVAL; | 45 | return -EINVAL; |
45 | 46 | ||
46 | sensor = v4l2_get_subdev_hostdata(fimc->pipeline.sensor); | 47 | sensor = v4l2_get_subdev_hostdata(p->subdevs[IDX_SENSOR]); |
47 | 48 | ||
48 | spin_lock_irqsave(&fimc->slock, flags); | 49 | spin_lock_irqsave(&fimc->slock, flags); |
49 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); | 50 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); |
@@ -109,7 +110,7 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend) | |||
109 | spin_unlock_irqrestore(&fimc->slock, flags); | 110 | spin_unlock_irqrestore(&fimc->slock, flags); |
110 | 111 | ||
111 | if (streaming) | 112 | if (streaming) |
112 | return fimc_pipeline_s_stream(fimc, 0); | 113 | return fimc_pipeline_s_stream(&fimc->pipeline, 0); |
113 | else | 114 | else |
114 | return 0; | 115 | return 0; |
115 | } | 116 | } |
@@ -254,7 +255,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) | |||
254 | fimc_activate_capture(ctx); | 255 | fimc_activate_capture(ctx); |
255 | 256 | ||
256 | if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) | 257 | if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) |
257 | fimc_pipeline_s_stream(fimc, 1); | 258 | fimc_pipeline_s_stream(&fimc->pipeline, 1); |
258 | } | 259 | } |
259 | 260 | ||
260 | return 0; | 261 | return 0; |
@@ -281,7 +282,7 @@ int fimc_capture_suspend(struct fimc_dev *fimc) | |||
281 | int ret = fimc_stop_capture(fimc, suspend); | 282 | int ret = fimc_stop_capture(fimc, suspend); |
282 | if (ret) | 283 | if (ret) |
283 | return ret; | 284 | return ret; |
284 | return fimc_pipeline_shutdown(fimc); | 285 | return fimc_pipeline_shutdown(&fimc->pipeline); |
285 | } | 286 | } |
286 | 287 | ||
287 | static void buffer_queue(struct vb2_buffer *vb); | 288 | static void buffer_queue(struct vb2_buffer *vb); |
@@ -297,7 +298,7 @@ int fimc_capture_resume(struct fimc_dev *fimc) | |||
297 | 298 | ||
298 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); | 299 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); |
299 | vid_cap->buf_index = 0; | 300 | vid_cap->buf_index = 0; |
300 | fimc_pipeline_initialize(fimc, &fimc->vid_cap.vfd->entity, | 301 | fimc_pipeline_initialize(&fimc->pipeline, &vid_cap->vfd->entity, |
301 | false); | 302 | false); |
302 | fimc_init_capture(fimc); | 303 | fimc_init_capture(fimc); |
303 | 304 | ||
@@ -414,7 +415,7 @@ static void buffer_queue(struct vb2_buffer *vb) | |||
414 | spin_unlock_irqrestore(&fimc->slock, flags); | 415 | spin_unlock_irqrestore(&fimc->slock, flags); |
415 | 416 | ||
416 | if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) | 417 | if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) |
417 | fimc_pipeline_s_stream(fimc, 1); | 418 | fimc_pipeline_s_stream(&fimc->pipeline, 1); |
418 | return; | 419 | return; |
419 | } | 420 | } |
420 | spin_unlock_irqrestore(&fimc->slock, flags); | 421 | spin_unlock_irqrestore(&fimc->slock, flags); |
@@ -464,7 +465,7 @@ int fimc_capture_ctrls_create(struct fimc_dev *fimc) | |||
464 | return ret; | 465 | return ret; |
465 | 466 | ||
466 | return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrl_handler, | 467 | return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrl_handler, |
467 | fimc->pipeline.sensor->ctrl_handler); | 468 | fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler); |
468 | } | 469 | } |
469 | 470 | ||
470 | static int fimc_capture_set_default_format(struct fimc_dev *fimc); | 471 | static int fimc_capture_set_default_format(struct fimc_dev *fimc); |
@@ -487,7 +488,7 @@ static int fimc_capture_open(struct file *file) | |||
487 | pm_runtime_get_sync(&fimc->pdev->dev); | 488 | pm_runtime_get_sync(&fimc->pdev->dev); |
488 | 489 | ||
489 | if (++fimc->vid_cap.refcnt == 1) { | 490 | if (++fimc->vid_cap.refcnt == 1) { |
490 | ret = fimc_pipeline_initialize(fimc, | 491 | ret = fimc_pipeline_initialize(&fimc->pipeline, |
491 | &fimc->vid_cap.vfd->entity, true); | 492 | &fimc->vid_cap.vfd->entity, true); |
492 | if (ret < 0) { | 493 | if (ret < 0) { |
493 | dev_err(&fimc->pdev->dev, | 494 | dev_err(&fimc->pdev->dev, |
@@ -515,7 +516,7 @@ static int fimc_capture_close(struct file *file) | |||
515 | if (--fimc->vid_cap.refcnt == 0) { | 516 | if (--fimc->vid_cap.refcnt == 0) { |
516 | clear_bit(ST_CAPT_BUSY, &fimc->state); | 517 | clear_bit(ST_CAPT_BUSY, &fimc->state); |
517 | fimc_stop_capture(fimc, false); | 518 | fimc_stop_capture(fimc, false); |
518 | fimc_pipeline_shutdown(fimc); | 519 | fimc_pipeline_shutdown(&fimc->pipeline); |
519 | clear_bit(ST_CAPT_SUSPENDED, &fimc->state); | 520 | clear_bit(ST_CAPT_SUSPENDED, &fimc->state); |
520 | } | 521 | } |
521 | 522 | ||
@@ -736,8 +737,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
736 | bool set) | 737 | bool set) |
737 | { | 738 | { |
738 | struct fimc_dev *fimc = ctx->fimc_dev; | 739 | struct fimc_dev *fimc = ctx->fimc_dev; |
739 | struct v4l2_subdev *sd = fimc->pipeline.sensor; | 740 | struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR]; |
740 | struct v4l2_subdev *csis = fimc->pipeline.csis; | 741 | struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS]; |
741 | struct v4l2_subdev_format sfmt; | 742 | struct v4l2_subdev_format sfmt; |
742 | struct v4l2_mbus_framefmt *mf = &sfmt.format; | 743 | struct v4l2_mbus_framefmt *mf = &sfmt.format; |
743 | struct fimc_fmt *ffmt = NULL; | 744 | struct fimc_fmt *ffmt = NULL; |
@@ -945,7 +946,7 @@ static int fimc_cap_enum_input(struct file *file, void *priv, | |||
945 | struct v4l2_input *i) | 946 | struct v4l2_input *i) |
946 | { | 947 | { |
947 | struct fimc_dev *fimc = video_drvdata(file); | 948 | struct fimc_dev *fimc = video_drvdata(file); |
948 | struct v4l2_subdev *sd = fimc->pipeline.sensor; | 949 | struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR]; |
949 | 950 | ||
950 | if (i->index != 0) | 951 | if (i->index != 0) |
951 | return -EINVAL; | 952 | return -EINVAL; |
@@ -1037,7 +1038,8 @@ static int fimc_cap_streamon(struct file *file, void *priv, | |||
1037 | if (fimc_capture_active(fimc)) | 1038 | if (fimc_capture_active(fimc)) |
1038 | return -EBUSY; | 1039 | return -EBUSY; |
1039 | 1040 | ||
1040 | media_entity_pipeline_start(&p->sensor->entity, p->pipe); | 1041 | media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity, |
1042 | p->m_pipeline); | ||
1041 | 1043 | ||
1042 | if (fimc->vid_cap.user_subdev_api) { | 1044 | if (fimc->vid_cap.user_subdev_api) { |
1043 | ret = fimc_pipeline_validate(fimc); | 1045 | ret = fimc_pipeline_validate(fimc); |
@@ -1051,7 +1053,7 @@ static int fimc_cap_streamoff(struct file *file, void *priv, | |||
1051 | enum v4l2_buf_type type) | 1053 | enum v4l2_buf_type type) |
1052 | { | 1054 | { |
1053 | struct fimc_dev *fimc = video_drvdata(file); | 1055 | struct fimc_dev *fimc = video_drvdata(file); |
1054 | struct v4l2_subdev *sd = fimc->pipeline.sensor; | 1056 | struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR]; |
1055 | int ret; | 1057 | int ret; |
1056 | 1058 | ||
1057 | ret = vb2_streamoff(&fimc->vid_cap.vbq, type); | 1059 | ret = vb2_streamoff(&fimc->vid_cap.vbq, type); |