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

Commit a4965c59 authored by Lad, Prabhakar's avatar Lad, Prabhakar Committed by Mauro Carvalho Chehab
Browse files

[media] media: davinci: vpif_capture: fix v4l-compliance issues



This patch does the following:

1: sets initial default format during probe.
2: removes spurious messages.
3: optimize vpif_s/try_fmt_vid_out code.

Signed-off-by: default avatarLad, Prabhakar <prabhakar.csengg@gmail.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 4015bef6
Loading
Loading
Loading
Loading
+54 −137
Original line number Diff line number Diff line
@@ -498,10 +498,28 @@ static int vpif_update_std_info(struct channel_obj *ch)
	common->width = std_info->width;
	common->fmt.fmt.pix.height = std_info->height;
	common->height = std_info->height;
	common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
	common->fmt.fmt.pix.bytesperline = std_info->width;
	vpifparams->video_params.hpitch = std_info->width;
	vpifparams->video_params.storage_mode = std_info->frm_fmt;

	if (vid_ch->stdid)
		common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
	else
		common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;

	if (ch->vpifparams.std_info.frm_fmt)
		common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
	else
		common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

	if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
		common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
	else
		common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;

	common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	return 0;
}

@@ -577,24 +595,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
	ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
}

/**
 * vpif_config_format: configure default frame format in the device
 * ch : ptr to channel object
 */
static void vpif_config_format(struct channel_obj *ch)
{
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];

	vpif_dbg(2, debug, "vpif_config_format\n");

	common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
	if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
		common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
	else
		common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
	common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
}

/**
 * vpif_get_default_field() - Get default field type based on interface
 * @vpif_params - ptr to vpif params
@@ -606,112 +606,6 @@ static inline enum v4l2_field vpif_get_default_field(
						V4L2_FIELD_INTERLACED;
}

/**
 * vpif_check_format()  - check given pixel format for compatibility
 * @ch - channel  ptr
 * @pixfmt - Given pixel format
 * @update - update the values as per hardware requirement
 *
 * Check the application pixel format for S_FMT and update the input
 * values as per hardware limits for TRY_FMT. The default pixel and
 * field format is selected based on interface type.
 */
static int vpif_check_format(struct channel_obj *ch,
			     struct v4l2_pix_format *pixfmt,
			     int update)
{
	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
	struct vpif_params *vpif_params = &ch->vpifparams;
	enum v4l2_field field = pixfmt->field;
	u32 sizeimage, hpitch, vpitch;
	int ret = -EINVAL;

	vpif_dbg(2, debug, "vpif_check_format\n");
	/**
	 * first check for the pixel format. If if_type is Raw bayer,
	 * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
	 * V4L2_PIX_FMT_YUV422P is supported
	 */
	if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
		if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
			if (!update) {
				vpif_dbg(2, debug, "invalid pix format\n");
				goto exit;
			}
			pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
		}
	} else {
		if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
			if (!update) {
				vpif_dbg(2, debug, "invalid pixel format\n");
				goto exit;
			}
			pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
		}
	}

	if (!(VPIF_VALID_FIELD(field))) {
		if (!update) {
			vpif_dbg(2, debug, "invalid field format\n");
			goto exit;
		}
		/**
		 * By default use FIELD_NONE for RAW Bayer capture
		 * and FIELD_INTERLACED for other interfaces
		 */
		field = vpif_get_default_field(&vpif_params->iface);
	} else if (field == V4L2_FIELD_ANY)
		/* unsupported field. Use default */
		field = vpif_get_default_field(&vpif_params->iface);

	/* validate the hpitch */
	hpitch = pixfmt->bytesperline;
	if (hpitch < vpif_params->std_info.width) {
		if (!update) {
			vpif_dbg(2, debug, "invalid hpitch\n");
			goto exit;
		}
		hpitch = vpif_params->std_info.width;
	}

	sizeimage = pixfmt->sizeimage;

	vpitch = sizeimage / (hpitch * 2);

	/* validate the vpitch */
	if (vpitch < vpif_params->std_info.height) {
		if (!update) {
			vpif_dbg(2, debug, "Invalid vpitch\n");
			goto exit;
		}
		vpitch = vpif_params->std_info.height;
	}

	/* Check for 8 byte alignment */
	if (!ALIGN(hpitch, 8)) {
		if (!update) {
			vpif_dbg(2, debug, "invalid pitch alignment\n");
			goto exit;
		}
		/* adjust to next 8 byte boundary */
		hpitch = (((hpitch + 7) / 8) * 8);
	}
	/* if update is set, modify the bytesperline and sizeimage */
	if (update) {
		pixfmt->bytesperline = hpitch;
		pixfmt->sizeimage = hpitch * vpitch * 2;
	}
	/**
	 * Image width and height is always based on current standard width and
	 * height
	 */
	pixfmt->width = common->fmt.fmt.pix.width;
	pixfmt->height = common->fmt.fmt.pix.height;
	return 0;
exit:
	return ret;
}

/**
 * vpif_config_addr() - function to configure buffer address in vpif
 * @ch - channel ptr
@@ -922,9 +816,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
		return -EINVAL;
	}

	/* Configure the default format information */
	vpif_config_format(ch);

	/* set standard in the sub device */
	ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);
	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
@@ -951,10 +842,8 @@ static int vpif_enum_input(struct file *file, void *priv,

	chan_cfg = &config->chan_config[ch->channel_id];

	if (input->index >= chan_cfg->input_count) {
		vpif_dbg(1, debug, "Invalid input index\n");
	if (input->index >= chan_cfg->input_count)
		return -EINVAL;
	}

	memcpy(input, &chan_cfg->inputs[input->index].input,
		sizeof(*input));
@@ -1043,8 +932,34 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
	struct video_device *vdev = video_devdata(file);
	struct channel_obj *ch = video_get_drvdata(vdev);
	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
	struct vpif_params *vpif_params = &ch->vpifparams;

	return vpif_check_format(ch, pixfmt, 1);
	/*
	 * to supress v4l-compliance warnings silently correct
	 * the pixelformat
	 */
	if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
		if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8)
			pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
	} else {
		if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
			pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
	}

	common->fmt.fmt.pix.pixelformat = pixfmt->pixelformat;

	vpif_update_std_info(ch);

	pixfmt->field = common->fmt.fmt.pix.field;
	pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
	pixfmt->bytesperline = common->fmt.fmt.pix.width;
	pixfmt->width = common->fmt.fmt.pix.width;
	pixfmt->height = common->fmt.fmt.pix.height;
	pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
	pixfmt->priv = 0;

	return 0;
}


@@ -1082,20 +997,17 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
	struct video_device *vdev = video_devdata(file);
	struct channel_obj *ch = video_get_drvdata(vdev);
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct v4l2_pix_format *pixfmt;
	int ret = 0;
	int ret;

	vpif_dbg(2, debug, "%s\n", __func__);

	if (vb2_is_busy(&common->buffer_queue))
		return -EBUSY;

	pixfmt = &fmt->fmt.pix;
	/* Check for valid field format */
	ret = vpif_check_format(ch, pixfmt, 0);

	ret = vpif_try_fmt_vid_cap(file, priv, fmt);
	if (ret)
		return ret;

	/* store the format in the channel object */
	common->fmt = *fmt;
	return 0;
@@ -1443,6 +1355,11 @@ static int vpif_probe_complete(void)
		if (err)
			goto probe_out;

		/* set initial format */
		ch->video.stdid = V4L2_STD_525_60;
		memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
		vpif_update_std_info(ch);

		/* Initialize vb2 queue */
		q = &common->buffer_queue;
		q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;