aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-06-20 09:57:47 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-28 14:30:18 -0400
commitb1d2dc5c4d39d4e6c405419ad1f444bf59874111 (patch)
tree4f9fc0f7e8313c3e992a57fa1cd01178003e36f4
parent038f5c4be7e8cc100c35a5aedb2557004c280cfa (diff)
[media] exynos4-is: Fix format propagation on FIMC-LITE.n subdevs
FIMC-LITE subdevs have one sink pad and two source pads on which the image formats are always same. This patch implements missing format propagation from the sink pad to the source pads, to allow user space to negotiate TRY format on whole media pipeline involving FIMC-LITE.n subdevs. The subdev try_fmt helper is simplified. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Jacek Anaszewski <j.anaszewski@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-lite.c92
1 files changed, 59 insertions, 33 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 07767c8b1c62..993bd798f3d2 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -560,37 +560,51 @@ static const struct v4l2_file_operations fimc_lite_fops = {
560 * Format and crop negotiation helpers 560 * Format and crop negotiation helpers
561 */ 561 */
562 562
563static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc, 563static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
564 u32 *width, u32 *height, 564 struct v4l2_subdev_fh *fh,
565 u32 *code, u32 *fourcc, int pad) 565 struct v4l2_subdev_format *format)
566{ 566{
567 struct flite_drvdata *dd = fimc->dd; 567 struct flite_drvdata *dd = fimc->dd;
568 const struct fimc_fmt *fmt; 568 struct v4l2_mbus_framefmt *mf = &format->format;
569 unsigned int flags = 0; 569 const struct fimc_fmt *fmt = NULL;
570
571 if (format->pad == FLITE_SD_PAD_SINK) {
572 v4l_bound_align_image(&mf->width, 8, dd->max_width,
573 ffs(dd->out_width_align) - 1,
574 &mf->height, 0, dd->max_height, 0, 0);
570 575
571 if (pad == FLITE_SD_PAD_SINK) { 576 fmt = fimc_lite_find_format(NULL, &mf->code, 0, 0);
572 v4l_bound_align_image(width, 8, dd->max_width, 577 if (WARN_ON(!fmt))
573 ffs(dd->out_width_align) - 1, 578 return NULL;
574 height, 0, dd->max_height, 0, 0); 579
580 mf->code = fmt->mbus_code;
575 } else { 581 } else {
576 v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width, 582 struct flite_frame *sink = &fimc->inp_frame;
577 ffs(dd->out_width_align) - 1, 583 struct v4l2_mbus_framefmt *sink_fmt;
578 height, 0, fimc->inp_frame.rect.height, 584 struct v4l2_rect *rect;
579 0, 0);
580 flags = fimc->inp_frame.fmt->flags;
581 }
582 585
583 fmt = fimc_lite_find_format(fourcc, code, flags, 0); 586 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
584 if (WARN_ON(!fmt)) 587 sink_fmt = v4l2_subdev_get_try_format(fh,
585 return NULL; 588 FLITE_SD_PAD_SINK);
586 589
587 if (code) 590 mf->code = sink_fmt->code;
588 *code = fmt->mbus_code; 591
589 if (fourcc) 592 rect = v4l2_subdev_get_try_crop(fh,
590 *fourcc = fmt->fourcc; 593 FLITE_SD_PAD_SINK);
594 } else {
595 mf->code = sink->fmt->mbus_code;
596 rect = &sink->rect;
597 }
598
599 /* Allow changing format only on sink pad */
600 mf->width = rect->width;
601 mf->height = rect->height;
602 }
591 603
592 v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n", 604 mf->field = V4L2_FIELD_NONE;
593 code ? *code : 0, *width, *height); 605
606 v4l2_dbg(1, debug, &fimc->subdev, "code: %#x (%d), %dx%d\n",
607 mf->code, mf->colorspace, mf->width, mf->height);
594 608
595 return fmt; 609 return fmt;
596} 610}
@@ -1035,6 +1049,15 @@ static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1035 return 0; 1049 return 0;
1036} 1050}
1037 1051
1052static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
1053 struct v4l2_subdev_fh *fh, unsigned int pad)
1054{
1055 if (pad != FLITE_SD_PAD_SINK)
1056 pad = FLITE_SD_PAD_SOURCE_DMA;
1057
1058 return v4l2_subdev_get_try_format(fh, pad);
1059}
1060
1038static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, 1061static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1039 struct v4l2_subdev_fh *fh, 1062 struct v4l2_subdev_fh *fh,
1040 struct v4l2_subdev_format *fmt) 1063 struct v4l2_subdev_format *fmt)
@@ -1044,7 +1067,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1044 struct flite_frame *f = &fimc->inp_frame; 1067 struct flite_frame *f = &fimc->inp_frame;
1045 1068
1046 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1069 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1047 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 1070 mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
1048 fmt->format = *mf; 1071 fmt->format = *mf;
1049 return 0; 1072 return 0;
1050 } 1073 }
@@ -1090,12 +1113,20 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1090 return -EBUSY; 1113 return -EBUSY;
1091 } 1114 }
1092 1115
1093 ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height, 1116 ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt);
1094 &mf->code, NULL, fmt->pad);
1095 1117
1096 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1118 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1097 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 1119 struct v4l2_mbus_framefmt *src_fmt;
1120
1121 mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
1098 *mf = fmt->format; 1122 *mf = fmt->format;
1123
1124 if (fmt->pad == FLITE_SD_PAD_SINK) {
1125 unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
1126 src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad);
1127 *src_fmt = *mf;
1128 }
1129
1099 mutex_unlock(&fimc->lock); 1130 mutex_unlock(&fimc->lock);
1100 return 0; 1131 return 0;
1101 } 1132 }
@@ -1113,11 +1144,6 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1113 source->rect = sink->rect; 1144 source->rect = sink->rect;
1114 source->f_width = mf->width; 1145 source->f_width = mf->width;
1115 source->f_height = mf->height; 1146 source->f_height = mf->height;
1116 } else {
1117 /* Allow changing format only on sink pad */
1118 mf->code = sink->fmt->mbus_code;
1119 mf->width = sink->rect.width;
1120 mf->height = sink->rect.height;
1121 } 1147 }
1122 1148
1123 mutex_unlock(&fimc->lock); 1149 mutex_unlock(&fimc->lock);