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

Commit 988f7b80 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] cx25821: g/s/try/enum_fmt related fixes and cleanups



- fill in colorspace
- zero priv
- delete unsupported formats
- fix field handling
- s_std should update width/height
- proper mapping of width/height to valid resolutions

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 8d125c50
Loading
Loading
Loading
Loading
+32 −102
Original line number Original line Diff line number Diff line
@@ -54,11 +54,6 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");


static const struct cx25821_fmt formats[] = {
static const struct cx25821_fmt formats[] = {
	{
	{
		.name = "8 bpp, gray",
		.fourcc = V4L2_PIX_FMT_GREY,
		.depth = 8,
		.flags = FORMAT_FLAGS_PACKED,
	 }, {
		.name = "4:1:1, packed, Y41P",
		.name = "4:1:1, packed, Y41P",
		.fourcc = V4L2_PIX_FMT_Y41P,
		.fourcc = V4L2_PIX_FMT_Y41P,
		.depth = 12,
		.depth = 12,
@@ -68,16 +63,6 @@ static const struct cx25821_fmt formats[] = {
		.fourcc = V4L2_PIX_FMT_YUYV,
		.fourcc = V4L2_PIX_FMT_YUYV,
		.depth = 16,
		.depth = 16,
		.flags = FORMAT_FLAGS_PACKED,
		.flags = FORMAT_FLAGS_PACKED,
	}, {
		.name = "4:2:2, packed, UYVY",
		.fourcc = V4L2_PIX_FMT_UYVY,
		.depth = 16,
		.flags = FORMAT_FLAGS_PACKED,
	}, {
		.name = "4:2:0, YUV",
		.fourcc = V4L2_PIX_FMT_YUV420,
		.depth = 12,
		.flags = FORMAT_FLAGS_PACKED,
	},
	},
};
};


@@ -85,14 +70,9 @@ static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
{
{
	unsigned int i;
	unsigned int i;


	if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P)
		return formats + 1;

	for (i = 0; i < ARRAY_SIZE(formats); i++)
	for (i = 0; i < ARRAY_SIZE(formats); i++)
		if (formats[i].fourcc == fourcc)
		if (formats[i].fourcc == fourcc)
			return formats + i;
			return formats + i;

	pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);
	return NULL;
	return NULL;
}
}


@@ -381,8 +361,7 @@ static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buff
			bpl_local = buf->bpl;   /* Default */
			bpl_local = buf->bpl;   /* Default */


			if (chan->use_cif_resolution) {
			if (chan->use_cif_resolution) {
				if (dev->tvnorm & V4L2_STD_PAL_BG ||
				if (dev->tvnorm & V4L2_STD_625_50)
						dev->tvnorm & V4L2_STD_PAL_DK)
					bpl_local = 352 << 1;
					bpl_local = 352 << 1;
				else
				else
					bpl_local = chan->cif_width << 1;
					bpl_local = chan->cif_width << 1;
@@ -612,8 +591,10 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
	f->fmt.pix.height = chan->height;
	f->fmt.pix.height = chan->height;
	f->fmt.pix.field = chan->vidq.field;
	f->fmt.pix.field = chan->vidq.field;
	f->fmt.pix.pixelformat = chan->fmt->fourcc;
	f->fmt.pix.pixelformat = chan->fmt->fourcc;
	f->fmt.pix.bytesperline = (f->fmt.pix.width * chan->fmt->depth) >> 3;
	f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3;
	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
	f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline;
	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
	f->fmt.pix.priv = 0;


	return 0;
	return 0;
}
}
@@ -621,48 +602,39 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
				   struct v4l2_format *f)
				   struct v4l2_format *f)
{
{
	struct cx25821_channel *chan = video_drvdata(file);
	struct cx25821_dev *dev = chan->dev;
	const struct cx25821_fmt *fmt;
	const struct cx25821_fmt *fmt;
	enum v4l2_field field;
	enum v4l2_field field = f->fmt.pix.field;
	unsigned int maxw, maxh;
	unsigned int maxw, maxh;
	unsigned w;


	fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
	fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
	if (NULL == fmt)
	if (NULL == fmt)
		return -EINVAL;
		return -EINVAL;

	field = f->fmt.pix.field;
	maxw = 720;
	maxw = 720;
	maxh = 576;
	maxh = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;


	if (V4L2_FIELD_ANY == field) {
	w = f->fmt.pix.width;
		if (f->fmt.pix.height > maxh / 2)
	if (field != V4L2_FIELD_BOTTOM)
			field = V4L2_FIELD_INTERLACED;
		else
		field = V4L2_FIELD_TOP;
		field = V4L2_FIELD_TOP;
	if (w < 352) {
		w = 176;
		f->fmt.pix.height = maxh / 4;
	} else if (w < 720) {
		w = 352;
		f->fmt.pix.height = maxh / 2;
	} else {
		w = 720;
		f->fmt.pix.height = maxh;
		field = V4L2_FIELD_INTERLACED;
	}
	}

	switch (field) {
	case V4L2_FIELD_TOP:
	case V4L2_FIELD_BOTTOM:
		maxh = maxh / 2;
		break;
	case V4L2_FIELD_INTERLACED:
		break;
	default:
		return -EINVAL;
	}

	f->fmt.pix.field = field;
	f->fmt.pix.field = field;
	if (f->fmt.pix.height < 32)
	f->fmt.pix.width = w;
		f->fmt.pix.height = 32;
	if (f->fmt.pix.height > maxh)
		f->fmt.pix.height = maxh;
	if (f->fmt.pix.width < 48)
		f->fmt.pix.width = 48;
	if (f->fmt.pix.width > maxw)
		f->fmt.pix.width = maxw;
	f->fmt.pix.width &= ~0x03;
	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
	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.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
	f->fmt.pix.priv = 0;


	return 0;
	return 0;
}
}
@@ -696,43 +668,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
	return videobuf_streamoff(&chan->vidq);
	return videobuf_streamoff(&chan->vidq);
}
}


static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
{
	if (tvnorm == V4L2_STD_PAL_BG) {
		if (width == 352 || width == 720)
			return 1;
		else
			return 0;
	}

	if (tvnorm == V4L2_STD_NTSC_M) {
		if (width == 320 || width == 352 || width == 720)
			return 1;
		else
			return 0;
	}
	return 0;
}

static int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
{
	if (tvnorm == V4L2_STD_PAL_BG) {
		if (height == 576 || height == 288)
			return 1;
		else
			return 0;
	}

	if (tvnorm == V4L2_STD_NTSC_M) {
		if (height == 480 || height == 240)
			return 1;
		else
			return 0;
	}

	return 0;
}

static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
				struct v4l2_format *f)
				struct v4l2_format *f)
{
{
@@ -749,20 +684,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,


	chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
	chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
	chan->vidq.field = f->fmt.pix.field;
	chan->vidq.field = f->fmt.pix.field;

	/* check if width and height is valid based on set standard */
	if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm))
	chan->width = f->fmt.pix.width;
	chan->width = f->fmt.pix.width;

	if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm))
	chan->height = f->fmt.pix.height;
	chan->height = f->fmt.pix.height;


	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
		pix_format = PIXEL_FRMT_411;
		pix_format = PIXEL_FRMT_411;
	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
		pix_format = PIXEL_FRMT_422;
	else
	else
		return -EINVAL;
		pix_format = PIXEL_FRMT_422;


	cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
	cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);


@@ -879,6 +807,8 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
		return 0;
		return 0;


	cx25821_set_tvnorm(dev, tvnorms);
	cx25821_set_tvnorm(dev, tvnorms);
	chan->width = 720;
	chan->height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;


	medusa_set_videostandard(dev);
	medusa_set_videostandard(dev);