diff options
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-capture.c')
| -rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 354574591908..725812aa0c30 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
| @@ -350,7 +350,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, | |||
| 350 | if (pixm) | 350 | if (pixm) |
| 351 | sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); | 351 | sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); |
| 352 | else | 352 | else |
| 353 | sizes[i] = size; | 353 | sizes[i] = max_t(u32, size, frame->payload[i]); |
| 354 | |||
| 354 | allocators[i] = ctx->fimc_dev->alloc_ctx; | 355 | allocators[i] = ctx->fimc_dev->alloc_ctx; |
| 355 | } | 356 | } |
| 356 | 357 | ||
| @@ -479,37 +480,39 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc); | |||
| 479 | static int fimc_capture_open(struct file *file) | 480 | static int fimc_capture_open(struct file *file) |
| 480 | { | 481 | { |
| 481 | struct fimc_dev *fimc = video_drvdata(file); | 482 | struct fimc_dev *fimc = video_drvdata(file); |
| 482 | int ret = v4l2_fh_open(file); | 483 | int ret; |
| 483 | |||
| 484 | if (ret) | ||
| 485 | return ret; | ||
| 486 | 484 | ||
| 487 | dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); | 485 | dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); |
| 488 | 486 | ||
| 489 | /* Return if the corresponding video mem2mem node is already opened. */ | ||
| 490 | if (fimc_m2m_active(fimc)) | 487 | if (fimc_m2m_active(fimc)) |
| 491 | return -EBUSY; | 488 | return -EBUSY; |
| 492 | 489 | ||
| 493 | set_bit(ST_CAPT_BUSY, &fimc->state); | 490 | set_bit(ST_CAPT_BUSY, &fimc->state); |
| 494 | pm_runtime_get_sync(&fimc->pdev->dev); | 491 | ret = pm_runtime_get_sync(&fimc->pdev->dev); |
| 492 | if (ret < 0) | ||
| 493 | return ret; | ||
| 495 | 494 | ||
| 496 | if (++fimc->vid_cap.refcnt == 1) { | 495 | ret = v4l2_fh_open(file); |
| 497 | ret = fimc_pipeline_initialize(&fimc->pipeline, | 496 | if (ret) |
| 498 | &fimc->vid_cap.vfd->entity, true); | 497 | return ret; |
| 499 | if (ret < 0) { | ||
| 500 | dev_err(&fimc->pdev->dev, | ||
| 501 | "Video pipeline initialization failed\n"); | ||
| 502 | pm_runtime_put_sync(&fimc->pdev->dev); | ||
| 503 | fimc->vid_cap.refcnt--; | ||
| 504 | v4l2_fh_release(file); | ||
| 505 | clear_bit(ST_CAPT_BUSY, &fimc->state); | ||
| 506 | return ret; | ||
| 507 | } | ||
| 508 | ret = fimc_capture_ctrls_create(fimc); | ||
| 509 | 498 | ||
| 510 | if (!ret && !fimc->vid_cap.user_subdev_api) | 499 | if (++fimc->vid_cap.refcnt != 1) |
| 511 | ret = fimc_capture_set_default_format(fimc); | 500 | return 0; |
| 501 | |||
| 502 | ret = fimc_pipeline_initialize(&fimc->pipeline, | ||
| 503 | &fimc->vid_cap.vfd->entity, true); | ||
| 504 | if (ret < 0) { | ||
| 505 | clear_bit(ST_CAPT_BUSY, &fimc->state); | ||
| 506 | pm_runtime_put_sync(&fimc->pdev->dev); | ||
| 507 | fimc->vid_cap.refcnt--; | ||
| 508 | v4l2_fh_release(file); | ||
| 509 | return ret; | ||
| 512 | } | 510 | } |
| 511 | ret = fimc_capture_ctrls_create(fimc); | ||
| 512 | |||
| 513 | if (!ret && !fimc->vid_cap.user_subdev_api) | ||
| 514 | ret = fimc_capture_set_default_format(fimc); | ||
| 515 | |||
| 513 | return ret; | 516 | return ret; |
| 514 | } | 517 | } |
| 515 | 518 | ||
| @@ -818,9 +821,6 @@ static int fimc_cap_g_fmt_mplane(struct file *file, void *fh, | |||
| 818 | struct fimc_dev *fimc = video_drvdata(file); | 821 | struct fimc_dev *fimc = video_drvdata(file); |
| 819 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; | 822 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
| 820 | 823 | ||
| 821 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
| 822 | return -EINVAL; | ||
| 823 | |||
| 824 | return fimc_fill_format(&ctx->d_frame, f); | 824 | return fimc_fill_format(&ctx->d_frame, f); |
| 825 | } | 825 | } |
| 826 | 826 | ||
| @@ -833,9 +833,6 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh, | |||
| 833 | struct v4l2_mbus_framefmt mf; | 833 | struct v4l2_mbus_framefmt mf; |
| 834 | struct fimc_fmt *ffmt = NULL; | 834 | struct fimc_fmt *ffmt = NULL; |
| 835 | 835 | ||
| 836 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
| 837 | return -EINVAL; | ||
| 838 | |||
| 839 | if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { | 836 | if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { |
| 840 | fimc_capture_try_format(ctx, &pix->width, &pix->height, | 837 | fimc_capture_try_format(ctx, &pix->width, &pix->height, |
| 841 | NULL, &pix->pixelformat, | 838 | NULL, &pix->pixelformat, |
| @@ -887,8 +884,6 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) | |||
| 887 | struct fimc_fmt *s_fmt = NULL; | 884 | struct fimc_fmt *s_fmt = NULL; |
| 888 | int ret, i; | 885 | int ret, i; |
| 889 | 886 | ||
| 890 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
| 891 | return -EINVAL; | ||
| 892 | if (vb2_is_busy(&fimc->vid_cap.vbq)) | 887 | if (vb2_is_busy(&fimc->vid_cap.vbq)) |
| 893 | return -EBUSY; | 888 | return -EBUSY; |
| 894 | 889 | ||
| @@ -924,10 +919,10 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) | |||
| 924 | pix->width = mf->width; | 919 | pix->width = mf->width; |
| 925 | pix->height = mf->height; | 920 | pix->height = mf->height; |
| 926 | } | 921 | } |
| 922 | |||
| 927 | fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); | 923 | fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); |
| 928 | for (i = 0; i < ff->fmt->colplanes; i++) | 924 | for (i = 0; i < ff->fmt->colplanes; i++) |
| 929 | ff->payload[i] = | 925 | ff->payload[i] = pix->plane_fmt[i].sizeimage; |
| 930 | (pix->width * pix->height * ff->fmt->depth[i]) / 8; | ||
| 931 | 926 | ||
| 932 | set_frame_bounds(ff, pix->width, pix->height); | 927 | set_frame_bounds(ff, pix->width, pix->height); |
| 933 | /* Reset the composition rectangle if not yet configured */ | 928 | /* Reset the composition rectangle if not yet configured */ |
| @@ -1045,18 +1040,22 @@ static int fimc_cap_streamon(struct file *file, void *priv, | |||
| 1045 | { | 1040 | { |
| 1046 | struct fimc_dev *fimc = video_drvdata(file); | 1041 | struct fimc_dev *fimc = video_drvdata(file); |
| 1047 | struct fimc_pipeline *p = &fimc->pipeline; | 1042 | struct fimc_pipeline *p = &fimc->pipeline; |
| 1043 | struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR]; | ||
| 1048 | int ret; | 1044 | int ret; |
| 1049 | 1045 | ||
| 1050 | if (fimc_capture_active(fimc)) | 1046 | if (fimc_capture_active(fimc)) |
| 1051 | return -EBUSY; | 1047 | return -EBUSY; |
| 1052 | 1048 | ||
| 1053 | media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity, | 1049 | ret = media_entity_pipeline_start(&sd->entity, p->m_pipeline); |
| 1054 | p->m_pipeline); | 1050 | if (ret < 0) |
| 1051 | return ret; | ||
| 1055 | 1052 | ||
| 1056 | if (fimc->vid_cap.user_subdev_api) { | 1053 | if (fimc->vid_cap.user_subdev_api) { |
| 1057 | ret = fimc_pipeline_validate(fimc); | 1054 | ret = fimc_pipeline_validate(fimc); |
| 1058 | if (ret) | 1055 | if (ret < 0) { |
| 1056 | media_entity_pipeline_stop(&sd->entity); | ||
| 1059 | return ret; | 1057 | return ret; |
| 1058 | } | ||
| 1060 | } | 1059 | } |
| 1061 | return vb2_streamon(&fimc->vid_cap.vbq, type); | 1060 | return vb2_streamon(&fimc->vid_cap.vbq, type); |
| 1062 | } | 1061 | } |
