@@ -162,6 +162,8 @@
CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
CICR0_EOFM | CICR0_FOM)
+#define PIX_YUV422P_ALIGN 16 /* YUV422P pix size should be a multiple of 16 */
+
/*
* Structures
*/
@@ -241,11 +243,8 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
- /* planar capture requires Y, U and V buffers to be page aligned */
if (pcdev->channels == 3)
- *size = roundup(icd->width * icd->height, 8) /* Y pages */
- + roundup(icd->width * icd->height / 2, 8) /* U pages */
- + roundup(icd->width * icd->height / 2, 8); /* V pages */
+ *size = icd->width * icd->height * 2;
else
*size = roundup(icd->width * icd->height *
((icd->current_fmt->depth + 7) >> 3), 8);
@@ -1297,6 +1296,18 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
pix->width = 2048;
pix->width &= ~0x01;
+ /*
+ * YUV422P planar format requires images size to be a 16 bytes
+ * multiple. If not, zeros will be inserted between Y and U planes, and
+ * U and V planes, and YUV422P standard would be violated.
+ */
+ if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
+ if ((pix->width * pix->height) & PIX_YUV422P_ALIGN)
+ pix->height = ALIGN(pix->height, PIX_YUV422P_ALIGN / 2);
+ if ((pix->width * pix->height) & PIX_YUV422P_ALIGN)
+ pix->width = ALIGN(pix->width, PIX_YUV422P_ALIGN / 2);
+ }
+
pix->bytesperline = pix->width *
DIV_ROUND_UP(xlate->host_fmt->depth, 8);
pix->sizeimage = pix->height * pix->bytesperline;