aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-06-18 12:42:30 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-28 14:32:17 -0400
commit5cfaad64d88a1bb52a6f779be02a69a2d50860fb (patch)
treebe220c34b541f9437e0df8e3c0ede48e10450302 /drivers/media/platform
parenta055d97037ad09ad9b87f6a6e74a65a44b942102 (diff)
[media] exynos4-is: Fix format propagation on FIMC-IS-ISP subdev
Ensure TRY formats are propagated from the sink pad to the source pads of the FIMC-IS-ISP subdev and the TRY and ACTIVE formats are separated. [mchehab@redhat.com: Whitespace cleanup] Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.c92
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.h3
2 files changed, 66 insertions, 29 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index ecb82a9517f3..f859b3cdd409 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -128,31 +128,28 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
128 struct v4l2_subdev_format *fmt) 128 struct v4l2_subdev_format *fmt)
129{ 129{
130 struct fimc_isp *isp = v4l2_get_subdevdata(sd); 130 struct fimc_isp *isp = v4l2_get_subdevdata(sd);
131 struct fimc_is *is = fimc_isp_to_is(isp);
132 struct v4l2_mbus_framefmt *mf = &fmt->format; 131 struct v4l2_mbus_framefmt *mf = &fmt->format;
133 struct v4l2_mbus_framefmt cur_fmt;
134 132
135 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 133 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
136 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 134 *mf = *v4l2_subdev_get_try_format(fh, fmt->pad);
137 fmt->format = *mf;
138 return 0; 135 return 0;
139 } 136 }
140 137
141 mf->colorspace = V4L2_COLORSPACE_SRGB; 138 mf->colorspace = V4L2_COLORSPACE_SRGB;
142 139
143 mutex_lock(&isp->subdev_lock); 140 mutex_lock(&isp->subdev_lock);
144 __is_get_frame_size(is, &cur_fmt);
145 141
146 if (fmt->pad == FIMC_ISP_SD_PAD_SINK) { 142 if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
147 /* full camera input frame size */ 143 /* ISP OTF input image format */
148 mf->width = cur_fmt.width + FIMC_ISP_CAC_MARGIN_WIDTH; 144 *mf = isp->sink_fmt;
149 mf->height = cur_fmt.height + FIMC_ISP_CAC_MARGIN_HEIGHT;
150 mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
151 } else { 145 } else {
152 /* crop size */ 146 /* ISP OTF output image format */
153 mf->width = cur_fmt.width; 147 *mf = isp->src_fmt;
154 mf->height = cur_fmt.height; 148
155 mf->code = V4L2_MBUS_FMT_YUV10_1X30; 149 if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
150 mf->colorspace = V4L2_COLORSPACE_JPEG;
151 mf->code = V4L2_MBUS_FMT_YUV10_1X30;
152 }
156 } 153 }
157 154
158 mutex_unlock(&isp->subdev_lock); 155 mutex_unlock(&isp->subdev_lock);
@@ -164,21 +161,37 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
164} 161}
165 162
166static void __isp_subdev_try_format(struct fimc_isp *isp, 163static void __isp_subdev_try_format(struct fimc_isp *isp,
167 struct v4l2_subdev_format *fmt) 164 struct v4l2_subdev_fh *fh,
165 struct v4l2_subdev_format *fmt)
168{ 166{
169 struct v4l2_mbus_framefmt *mf = &fmt->format; 167 struct v4l2_mbus_framefmt *mf = &fmt->format;
168 struct v4l2_mbus_framefmt *format;
169
170 mf->colorspace = V4L2_COLORSPACE_SRGB;
170 171
171 if (fmt->pad == FIMC_ISP_SD_PAD_SINK) { 172 if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
172 v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN, 173 v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
173 FIMC_ISP_SINK_WIDTH_MAX, 0, 174 FIMC_ISP_SINK_WIDTH_MAX, 0,
174 &mf->height, FIMC_ISP_SINK_HEIGHT_MIN, 175 &mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
175 FIMC_ISP_SINK_HEIGHT_MAX, 0, 0); 176 FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
176 isp->subdev_fmt = *mf; 177 mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
177 } else { 178 } else {
179 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
180 format = v4l2_subdev_get_try_format(fh,
181 FIMC_ISP_SD_PAD_SINK);
182 else
183 format = &isp->sink_fmt;
184
178 /* Allow changing format only on sink pad */ 185 /* Allow changing format only on sink pad */
179 mf->width = isp->subdev_fmt.width - FIMC_ISP_CAC_MARGIN_WIDTH; 186 mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
180 mf->height = isp->subdev_fmt.height - FIMC_ISP_CAC_MARGIN_HEIGHT; 187 mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
181 mf->code = isp->subdev_fmt.code; 188
189 if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
190 mf->code = V4L2_MBUS_FMT_YUV10_1X30;
191 mf->colorspace = V4L2_COLORSPACE_JPEG;
192 } else {
193 mf->code = format->code;
194 }
182 } 195 }
183} 196}
184 197
@@ -194,24 +207,47 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
194 isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n", 207 isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
195 __func__, fmt->pad, mf->code, mf->width, mf->height); 208 __func__, fmt->pad, mf->code, mf->width, mf->height);
196 209
197 mf->colorspace = V4L2_COLORSPACE_SRGB;
198
199 mutex_lock(&isp->subdev_lock); 210 mutex_lock(&isp->subdev_lock);
200 __isp_subdev_try_format(isp, fmt); 211 __isp_subdev_try_format(isp, fh, fmt);
201 212
202 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 213 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
203 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 214 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
204 *mf = fmt->format; 215 *mf = fmt->format;
205 mutex_unlock(&isp->subdev_lock); 216
206 return 0; 217 /* Propagate format to the source pads */
218 if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
219 struct v4l2_subdev_format format = *fmt;
220 unsigned int pad;
221
222 for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
223 pad < FIMC_ISP_SD_PADS_NUM; pad++) {
224 format.pad = pad;
225 __isp_subdev_try_format(isp, fh, &format);
226 mf = v4l2_subdev_get_try_format(fh, pad);
227 *mf = format.format;
228 }
229 }
230 } else {
231 if (sd->entity.stream_count == 0) {
232 if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
233 struct v4l2_subdev_format format = *fmt;
234
235 isp->sink_fmt = *mf;
236
237 format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
238 __isp_subdev_try_format(isp, fh, &format);
239
240 isp->src_fmt = format.format;
241 __is_set_frame_size(is, &isp->src_fmt);
242 } else {
243 isp->src_fmt = *mf;
244 }
245 } else {
246 ret = -EBUSY;
247 }
207 } 248 }
208 249
209 if (sd->entity.stream_count == 0)
210 __is_set_frame_size(is, mf);
211 else
212 ret = -EBUSY;
213 mutex_unlock(&isp->subdev_lock); 250 mutex_unlock(&isp->subdev_lock);
214
215 return ret; 251 return ret;
216} 252}
217 253
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
index 756063e77fb8..03bf95ab017b 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.h
+++ b/drivers/media/platform/exynos4-is/fimc-isp.h
@@ -145,7 +145,8 @@ struct fimc_isp {
145 struct vb2_alloc_ctx *alloc_ctx; 145 struct vb2_alloc_ctx *alloc_ctx;
146 struct v4l2_subdev subdev; 146 struct v4l2_subdev subdev;
147 struct media_pad subdev_pads[FIMC_ISP_SD_PADS_NUM]; 147 struct media_pad subdev_pads[FIMC_ISP_SD_PADS_NUM];
148 struct v4l2_mbus_framefmt subdev_fmt; 148 struct v4l2_mbus_framefmt src_fmt;
149 struct v4l2_mbus_framefmt sink_fmt;
149 struct v4l2_ctrl *test_pattern; 150 struct v4l2_ctrl *test_pattern;
150 struct fimc_isp_ctrls ctrls; 151 struct fimc_isp_ctrls ctrls;
151 152