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: Janusz Krzysztofik <jmkrzyszt@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
parent
985d2d7a48
commit
c748f10c21
@ -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)
|
||||
{
|
||||
@ -976,12 +1003,13 @@ 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,
|
||||
.get_selection = ov6650_get_selection,
|
||||
.set_selection = ov6650_set_selection,
|
||||
.get_fmt = ov6650_get_fmt,
|
||||
.set_fmt = ov6650_set_fmt,
|
||||
.get_mbus_config = ov6650_get_mbus_config,
|
||||
.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,
|
||||
.set_fmt = ov6650_set_fmt,
|
||||
.get_mbus_config = ov6650_get_mbus_config,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops ov6650_subdev_ops = {
|
||||
|
Loading…
Reference in New Issue
Block a user