Commit d891f475 authored by Magnus Damm's avatar Magnus Damm Committed by Mauro Carvalho Chehab

V4L/DVB (9236): Teach vivi about multiple pixel formats

This patch contains the ground work to add support for multiple
pixel formats to vivi.c
Signed-off-by: default avatarMagnus Damm <damm@igel.co.jp>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 74d7c5af
...@@ -128,12 +128,31 @@ struct vivi_fmt { ...@@ -128,12 +128,31 @@ struct vivi_fmt {
int depth; int depth;
}; };
static struct vivi_fmt format = { static struct vivi_fmt formats[] = {
{
.name = "4:2:2, packed, YUYV", .name = "4:2:2, packed, YUYV",
.fourcc = V4L2_PIX_FMT_YUYV, .fourcc = V4L2_PIX_FMT_YUYV,
.depth = 16, .depth = 16,
},
}; };
static struct vivi_fmt *get_format(struct v4l2_format *f)
{
struct vivi_fmt *fmt;
unsigned int k;
for (k = 0; k < ARRAY_SIZE(formats); k++) {
fmt = &formats[k];
if (fmt->fourcc == f->fmt.pix.pixelformat)
break;
}
if (k == ARRAY_SIZE(formats))
return NULL;
return &formats[k];
}
struct sg_to_addr { struct sg_to_addr {
int pos; int pos;
struct scatterlist *sg; struct scatterlist *sg;
...@@ -248,6 +267,8 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) ...@@ -248,6 +267,8 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
for (color = 0; color < 4; color++) { for (color = 0; color < 4; color++) {
p = buf + color; p = buf + color;
switch (fh->fmt->fourcc) {
case V4L2_PIX_FMT_YUYV:
switch (color) { switch (color) {
case 0: case 0:
case 2: case 2:
...@@ -260,6 +281,8 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) ...@@ -260,6 +281,8 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
*p = b_v; *p = b_v;
break; break;
} }
break;
}
} }
} }
...@@ -622,11 +645,15 @@ static int vidioc_querycap(struct file *file, void *priv, ...@@ -622,11 +645,15 @@ static int vidioc_querycap(struct file *file, void *priv,
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f) struct v4l2_fmtdesc *f)
{ {
if (f->index > 0) struct vivi_fmt *fmt;
if (f->index >= ARRAY_SIZE(formats))
return -EINVAL; return -EINVAL;
strlcpy(f->description, format.name, sizeof(f->description)); fmt = &formats[f->index];
f->pixelformat = format.fourcc;
strlcpy(f->description, fmt->name, sizeof(f->description));
f->pixelformat = fmt->fourcc;
return 0; return 0;
} }
...@@ -656,13 +683,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, ...@@ -656,13 +683,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
enum v4l2_field field; enum v4l2_field field;
unsigned int maxw, maxh; unsigned int maxw, maxh;
if (format.fourcc != f->fmt.pix.pixelformat) { fmt = get_format(f);
dprintk(dev, 1, "Fourcc format (0x%08x) invalid. " if (!fmt) {
"Driver accepts only 0x%08x\n", dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n",
f->fmt.pix.pixelformat, format.fourcc); f->fmt.pix.pixelformat);
return -EINVAL; return -EINVAL;
} }
fmt = &format;
field = f->fmt.pix.field; field = f->fmt.pix.field;
...@@ -701,7 +727,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -701,7 +727,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct vivi_fh *fh = priv; struct vivi_fh *fh = priv;
struct videobuf_queue *q = &fh->vb_vidq; struct videobuf_queue *q = &fh->vb_vidq;
unsigned char r, g, b; unsigned char r, g, b;
int k; int k, is_yuv;
int ret = vidioc_try_fmt_vid_cap(file, fh, f); int ret = vidioc_try_fmt_vid_cap(file, fh, f);
if (ret < 0) if (ret < 0)
...@@ -715,7 +741,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -715,7 +741,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
goto out; goto out;
} }
fh->fmt = &format; fh->fmt = get_format(f);
fh->width = f->fmt.pix.width; fh->width = f->fmt.pix.width;
fh->height = f->fmt.pix.height; fh->height = f->fmt.pix.height;
fh->vb_vidq.field = f->fmt.pix.field; fh->vb_vidq.field = f->fmt.pix.field;
...@@ -726,10 +752,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -726,10 +752,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
r = bars[k][0]; r = bars[k][0];
g = bars[k][1]; g = bars[k][1];
b = bars[k][2]; b = bars[k][2];
is_yuv = 0;
switch (fh->fmt->fourcc) {
case V4L2_PIX_FMT_YUYV:
is_yuv = 1;
break;
}
if (is_yuv) {
fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ fh->bars[k][0] = TO_Y(r, g, b); /* Luma */
fh->bars[k][1] = TO_U(r, g, b); /* Cb */ fh->bars[k][1] = TO_U(r, g, b); /* Cb */
fh->bars[k][2] = TO_V(r, g, b); /* Cr */ fh->bars[k][2] = TO_V(r, g, b); /* Cr */
} else {
fh->bars[k][0] = r;
fh->bars[k][1] = g;
fh->bars[k][2] = b;
}
} }
ret = 0; ret = 0;
...@@ -885,8 +924,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, ...@@ -885,8 +924,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
File operations for the device File operations for the device
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
#define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8)
static int vivi_open(struct inode *inode, struct file *file) static int vivi_open(struct inode *inode, struct file *file)
{ {
int minor = iminor(inode); int minor = iminor(inode);
...@@ -935,7 +972,7 @@ unlock: ...@@ -935,7 +972,7 @@ unlock:
fh->dev = dev; fh->dev = dev;
fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fh->fmt = &format; fh->fmt = &formats[0];
fh->width = 640; fh->width = 640;
fh->height = 480; fh->height = 480;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment