diff options
Diffstat (limited to 'drivers/media/video/mx3_camera.c')
-rw-r--r-- | drivers/media/video/mx3_camera.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 93c35ef5f0ad..02d54a057b60 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -199,8 +199,6 @@ static int mx3_videobuf_setup(struct vb2_queue *vq, | |||
199 | struct soc_camera_device *icd = soc_camera_from_vb2q(vq); | 199 | struct soc_camera_device *icd = soc_camera_from_vb2q(vq); |
200 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 200 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
201 | struct mx3_camera_dev *mx3_cam = ici->priv; | 201 | struct mx3_camera_dev *mx3_cam = ici->priv; |
202 | int bytes_per_line; | ||
203 | unsigned int height; | ||
204 | 202 | ||
205 | if (!mx3_cam->idmac_channel[0]) | 203 | if (!mx3_cam->idmac_channel[0]) |
206 | return -EINVAL; | 204 | return -EINVAL; |
@@ -208,21 +206,29 @@ static int mx3_videobuf_setup(struct vb2_queue *vq, | |||
208 | if (fmt) { | 206 | if (fmt) { |
209 | const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd, | 207 | const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd, |
210 | fmt->fmt.pix.pixelformat); | 208 | fmt->fmt.pix.pixelformat); |
209 | unsigned int bytes_per_line; | ||
210 | int ret; | ||
211 | |||
211 | if (!xlate) | 212 | if (!xlate) |
212 | return -EINVAL; | 213 | return -EINVAL; |
213 | bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width, | 214 | |
214 | xlate->host_fmt); | 215 | ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width, |
215 | height = fmt->fmt.pix.height; | 216 | xlate->host_fmt); |
217 | if (ret < 0) | ||
218 | return ret; | ||
219 | |||
220 | bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret); | ||
221 | |||
222 | ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line, | ||
223 | fmt->fmt.pix.height); | ||
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | |||
227 | sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret); | ||
216 | } else { | 228 | } else { |
217 | /* Called from VIDIOC_REQBUFS or in compatibility mode */ | 229 | /* Called from VIDIOC_REQBUFS or in compatibility mode */ |
218 | bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | 230 | sizes[0] = icd->sizeimage; |
219 | icd->current_fmt->host_fmt); | ||
220 | height = icd->user_height; | ||
221 | } | 231 | } |
222 | if (bytes_per_line < 0) | ||
223 | return bytes_per_line; | ||
224 | |||
225 | sizes[0] = bytes_per_line * height; | ||
226 | 232 | ||
227 | alloc_ctxs[0] = mx3_cam->alloc_ctx; | 233 | alloc_ctxs[0] = mx3_cam->alloc_ctx; |
228 | 234 | ||
@@ -267,14 +273,11 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
267 | struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; | 273 | struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; |
268 | struct idmac_video_param *video = &ichan->params.video; | 274 | struct idmac_video_param *video = &ichan->params.video; |
269 | const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt; | 275 | const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt; |
270 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, host_fmt); | ||
271 | unsigned long flags; | 276 | unsigned long flags; |
272 | dma_cookie_t cookie; | 277 | dma_cookie_t cookie; |
273 | size_t new_size; | 278 | size_t new_size; |
274 | 279 | ||
275 | BUG_ON(bytes_per_line <= 0); | 280 | new_size = icd->sizeimage; |
276 | |||
277 | new_size = bytes_per_line * icd->user_height; | ||
278 | 281 | ||
279 | if (vb2_plane_size(vb, 0) < new_size) { | 282 | if (vb2_plane_size(vb, 0) < new_size) { |
280 | dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n", | 283 | dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n", |
@@ -314,9 +317,9 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
314 | * horizontal parameters in this case are expressed in bytes, | 317 | * horizontal parameters in this case are expressed in bytes, |
315 | * not in pixels. | 318 | * not in pixels. |
316 | */ | 319 | */ |
317 | video->out_width = bytes_per_line; | 320 | video->out_width = icd->bytesperline; |
318 | video->out_height = icd->user_height; | 321 | video->out_height = icd->user_height; |
319 | video->out_stride = bytes_per_line; | 322 | video->out_stride = icd->bytesperline; |
320 | } else { | 323 | } else { |
321 | /* | 324 | /* |
322 | * For IPU known formats the pixel unit will be managed | 325 | * For IPU known formats the pixel unit will be managed |
@@ -642,12 +645,14 @@ static const struct soc_mbus_pixelfmt mx3_camera_formats[] = { | |||
642 | .bits_per_sample = 8, | 645 | .bits_per_sample = 8, |
643 | .packing = SOC_MBUS_PACKING_NONE, | 646 | .packing = SOC_MBUS_PACKING_NONE, |
644 | .order = SOC_MBUS_ORDER_LE, | 647 | .order = SOC_MBUS_ORDER_LE, |
648 | .layout = SOC_MBUS_LAYOUT_PACKED, | ||
645 | }, { | 649 | }, { |
646 | .fourcc = V4L2_PIX_FMT_GREY, | 650 | .fourcc = V4L2_PIX_FMT_GREY, |
647 | .name = "Monochrome 8 bit", | 651 | .name = "Monochrome 8 bit", |
648 | .bits_per_sample = 8, | 652 | .bits_per_sample = 8, |
649 | .packing = SOC_MBUS_PACKING_NONE, | 653 | .packing = SOC_MBUS_PACKING_NONE, |
650 | .order = SOC_MBUS_ORDER_LE, | 654 | .order = SOC_MBUS_ORDER_LE, |
655 | .layout = SOC_MBUS_LAYOUT_PACKED, | ||
651 | }, | 656 | }, |
652 | }; | 657 | }; |
653 | 658 | ||