Commit c748f10c authored by Janusz Krzysztofik's avatar Janusz Krzysztofik Committed by Mauro Carvalho Chehab
Browse files

media: ov6650: Fix missing frame interval enumeration support



According to v4l2-compliance utility, a video device which supports
V4L2_CAP_TIMEPERFRAME via .vidioc_s_parm() operation should also
support .vidioc_enum_frameintervals().  If the former is implemented
via a call to v4l2_s_parm_cap() which in turn calls a subdevice
.s_frame_interval() pad operation, the video device may want to
implement the latter by passing frame interval enumeration requests to
the subdevice .enum_frame_intervals() video operation.  If that
operation is not supported by the subdevice and failure is returned by
the video device, the compliance test issues a warning.

Implement the missing pad operation.  Enumerate frame intervals
possible to be set via pixel clock adjustment, as implemented by
.s_frame_interval(), but not exceeding a reasonable maximum of 1
second.

[Sakari Ailus: Rebased on mbus config pad op patches]

Signed-off-by: default avatarJanusz Krzysztofik <jmkrzyszt@gmail.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 985d2d7a
Loading
Loading
Loading
Loading
+34 −6
Original line number Diff line number Diff line
@@ -764,6 +764,33 @@ static int ov6650_enum_mbus_code(struct v4l2_subdev *sd,
	return 0;
}

static int ov6650_enum_frame_interval(struct v4l2_subdev *sd,
				    struct v4l2_subdev_state *sd_state,
				    struct v4l2_subdev_frame_interval_enum *fie)
{
	int i;

	/* enumerate supported frame intervals not exceeding 1 second */
	if (fie->index > CLKRC_DIV_MASK ||
	    GET_CLKRC_DIV(fie->index) > FRAME_RATE_MAX)
		return -EINVAL;

	for (i = 0; i < ARRAY_SIZE(ov6650_codes); i++)
		if (fie->code == ov6650_codes[i])
			break;
	if (i == ARRAY_SIZE(ov6650_codes))
		return -EINVAL;

	if (!fie->width || fie->width > W_CIF ||
	    !fie->height || fie->height > H_CIF)
		return -EINVAL;

	fie->interval.numerator = GET_CLKRC_DIV(fie->index);
	fie->interval.denominator = FRAME_RATE_MAX;

	return 0;
}

static int ov6650_g_frame_interval(struct v4l2_subdev *sd,
				   struct v4l2_subdev_frame_interval *ival)
{
@@ -977,6 +1004,7 @@ static const struct v4l2_subdev_video_ops ov6650_video_ops = {

static const struct v4l2_subdev_pad_ops ov6650_pad_ops = {
	.enum_mbus_code		= ov6650_enum_mbus_code,
	.enum_frame_interval	= ov6650_enum_frame_interval,
	.get_selection		= ov6650_get_selection,
	.set_selection		= ov6650_set_selection,
	.get_fmt		= ov6650_get_fmt,