Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+67 −30
Original line number Original line Diff line number Diff line
@@ -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)
	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)
				*p = b_v;
				*p = b_v;
				break;
				break;
			}
			}
			break;
		}
	}
	}
}
}


@@ -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,
	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,
	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,
		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,
		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,
	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 @@ static int vivi_open(struct inode *inode, struct file *file)
	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;