summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-02-28 09:25:50 +0300
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-03-01 19:06:49 +0300
commitc8af44e1e791c5d6e38c464603ae8d9a7b0468b1 (patch)
treed947363a3f1870a151aad10d6ab379c4306432d3 /drivers/media
parent9c9c396ce6c7f32a411bfe2fbce848d2045769c5 (diff)
downloadlinux-c8af44e1e791c5d6e38c464603ae8d9a7b0468b1.tar.xz
media: vim2m: use different framesizes for bayer formats
The only real restriction at vim2m is that width should be multiple of two, as the copy routine always copy two pixels each time. However, Bayer formats are defined as having a 2x2 matrix. So, odd vertical numbers would cause color distortions at the last line. So, it makes sense to use step 2 for vertical alignment on Bayer. With this patch, the reported formats for video capture will be: [0]: 'RGBP' (16-bit RGB 5-6-5) Size: Stepwise 32x32 - 640x480 with step 2/1 [1]: 'RGBR' (16-bit RGB 5-6-5 BE) Size: Stepwise 32x32 - 640x480 with step 2/1 [2]: 'RGB3' (24-bit RGB 8-8-8) Size: Stepwise 32x32 - 640x480 with step 2/1 [3]: 'BGR3' (24-bit BGR 8-8-8) Size: Stepwise 32x32 - 640x480 with step 2/1 [4]: 'YUYV' (YUYV 4:2:2) Size: Stepwise 32x32 - 640x480 with step 2/1 [5]: 'BA81' (8-bit Bayer BGBG/GRGR) Size: Stepwise 32x32 - 640x480 with step 2/2 [6]: 'GBRG' (8-bit Bayer GBGB/RGRG) Size: Stepwise 32x32 - 640x480 with step 2/2 [7]: 'GRBG' (8-bit Bayer GRGR/BGBG) Size: Stepwise 32x32 - 640x480 with step 2/2 [8]: 'RGGB' (8-bit Bayer RGRG/GBGB) Size: Stepwise 32x32 - 640x480 with step 2/2 Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/vim2m.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index 620f064ff12a..12f0f3e433da 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -50,7 +50,14 @@ MODULE_PARM_DESC(default_transtime, "default transaction time in ms");
#define MIN_H 32
#define MAX_W 640
#define MAX_H 480
-#define WIDTH_ALIGN 2 /* 2-byte alignment */
+
+/* Pixel alignment for non-bayer formats */
+#define WIDTH_ALIGN 2
+#define HEIGHT_ALIGN 1
+
+/* Pixel alignment for bayer formats */
+#define BAYER_WIDTH_ALIGN 2
+#define BAYER_HEIGHT_ALIGN 2
/* Flags that indicate a format can be used for capture/output */
#define MEM2MEM_CAPTURE (1 << 0)
@@ -162,6 +169,24 @@ static struct vim2m_fmt *find_format(u32 fourcc)
return &formats[k];
}
+static void get_alignment(u32 fourcc,
+ unsigned int *walign, unsigned int *halign)
+{
+ switch (fourcc) {
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SGBRG8:
+ case V4L2_PIX_FMT_SGRBG8:
+ case V4L2_PIX_FMT_SRGGB8:
+ *walign = BAYER_WIDTH_ALIGN;
+ *halign = BAYER_HEIGHT_ALIGN;
+ return;
+ default:
+ *walign = WIDTH_ALIGN;
+ *halign = HEIGHT_ALIGN;
+ return;
+ }
+}
+
struct vim2m_dev {
struct v4l2_device v4l2_dev;
struct video_device vfd;
@@ -691,8 +716,10 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
fsize->stepwise.min_height = MIN_H;
fsize->stepwise.max_width = MAX_W;
fsize->stepwise.max_height = MAX_H;
- fsize->stepwise.step_width = WIDTH_ALIGN;
- fsize->stepwise.step_height = 1;
+
+ get_alignment(fsize->pixel_format,
+ &fsize->stepwise.step_width,
+ &fsize->stepwise.step_height);
return 0;
}
@@ -735,6 +762,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt)
{
+ int walign, halign;
/* V4L2 specification suggests the driver corrects the format struct
* if any of the dimensions is unsupported */
if (f->fmt.pix.height < MIN_H)
@@ -747,7 +775,9 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt)
else if (f->fmt.pix.width > MAX_W)
f->fmt.pix.width = MAX_W;
- f->fmt.pix.width &= ~(WIDTH_ALIGN - 1);
+ get_alignment(f->fmt.pix.pixelformat, &walign, &halign);
+ f->fmt.pix.width &= ~(walign - 1);
+ f->fmt.pix.height &= ~(halign - 1);
f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.field = V4L2_FIELD_NONE;