media: v4l2-subdev: Add which field to struct v4l2_subdev_frame_interval

Due to a historical mishap, the v4l2_subdev_frame_interval structure
is the only part of the V4L2 subdev userspace API that doesn't contain a
'which' field. This prevents trying frame intervals using the subdev
'TRY' state mechanism.

Adding a 'which' field is simple as the structure has 8 reserved fields.
This would however break userspace as the field is currently set to 0,
corresponding to V4L2_SUBDEV_FORMAT_TRY, while the corresponding ioctls
currently operate on the 'ACTIVE' state. We thus need to add a new
subdev client cap, V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH, to
indicate that userspace is aware of this new field.

All drivers that implement the subdev .get_frame_interval() and
.set_frame_interval() operations are updated to return -EINVAL when
operating on the TRY state, preserving the current behaviour.

While at it, fix a bad copy&paste in the documentation of the struct
v4l2_subdev_frame_interval_enum 'which' field.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> # for imx-media
Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> # for tegra-video
Reviewed-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
Laurent Pinchart
2023-12-13 17:00:05 +02:00
committed by Hans Verkuil
parent 287fe16083
commit 805d4311a5
37 changed files with 425 additions and 18 deletions
@@ -71,6 +71,11 @@ is unknown to the kernel.
of 'stream' fields (referring to the stream number) with various of 'stream' fields (referring to the stream number) with various
ioctls. If this is not set (which is the default), the 'stream' fields ioctls. If this is not set (which is the default), the 'stream' fields
will be forced to 0 by the kernel. will be forced to 0 by the kernel.
* - ``V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH``
- The client is aware of the :c:type:`v4l2_subdev_frame_interval`
``which`` field. If this is not set (which is the default), the
``which`` field is forced to ``V4L2_SUBDEV_FORMAT_ACTIVE`` by the
kernel.
Return Value Return Value
============ ============
@@ -58,8 +58,9 @@ struct
contains the current frame interval as would be returned by a contains the current frame interval as would be returned by a
``VIDIOC_SUBDEV_G_FRAME_INTERVAL`` call. ``VIDIOC_SUBDEV_G_FRAME_INTERVAL`` call.
Calling ``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` on a subdev device node that has been If the subdev device node has been registered in read-only mode, calls to
registered in read-only mode is not allowed. An error is returned and the errno ``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` are only valid if the ``which`` field is set
to ``V4L2_SUBDEV_FORMAT_TRY``, otherwise an error is returned and the errno
variable is set to ``-EPERM``. variable is set to ``-EPERM``.
Drivers must not return an error solely because the requested interval Drivers must not return an error solely because the requested interval
@@ -93,7 +94,11 @@ the same sub-device is not defined.
- ``stream`` - ``stream``
- Stream identifier. - Stream identifier.
* - __u32 * - __u32
- ``reserved``\ [8] - ``which``
- Active or try frame interval, from enum
:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
* - __u32
- ``reserved``\ [7]
- Reserved for future extensions. Applications and drivers must set - Reserved for future extensions. Applications and drivers must set
the array to zero. the array to zero.
@@ -114,9 +119,9 @@ EBUSY
EINVAL EINVAL
The struct The struct
:c:type:`v4l2_subdev_frame_interval` :c:type:`v4l2_subdev_frame_interval`
``pad`` references a non-existing pad, or the pad doesn't support ``pad`` references a non-existing pad, the ``which`` field references a
frame intervals. non-existing frame interval, or the pad doesn't support frame intervals.
EPERM EPERM
The ``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` ioctl has been called on a read-only The ``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` ioctl has been called on a read-only
subdevice. subdevice and the ``which`` field is set to ``V4L2_SUBDEV_FORMAT_ACTIVE``.
+7
View File
@@ -469,6 +469,13 @@ static int adv7180_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct adv7180_state *state = to_state(sd); struct adv7180_state *state = to_state(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (state->curr_norm & V4L2_STD_525_60) { if (state->curr_norm & V4L2_STD_525_60) {
fi->interval.numerator = 1001; fi->interval.numerator = 1001;
fi->interval.denominator = 30000; fi->interval.denominator = 30000;
+14
View File
@@ -1654,6 +1654,13 @@ static int alvium_g_frame_interval(struct v4l2_subdev *sd,
{ {
struct alvium_dev *alvium = sd_to_alvium(sd); struct alvium_dev *alvium = sd_to_alvium(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fi->interval = alvium->frame_interval; fi->interval = alvium->frame_interval;
return 0; return 0;
@@ -1703,6 +1710,13 @@ static int alvium_s_frame_interval(struct v4l2_subdev *sd,
struct alvium_dev *alvium = sd_to_alvium(sd); struct alvium_dev *alvium = sd_to_alvium(sd);
int ret; int ret;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (alvium->streaming) if (alvium->streaming)
return -EBUSY; return -EBUSY;
+14
View File
@@ -1051,6 +1051,13 @@ static int et8ek8_get_frame_interval(struct v4l2_subdev *subdev,
{ {
struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev); struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
memset(fi, 0, sizeof(*fi)); memset(fi, 0, sizeof(*fi));
fi->interval = sensor->current_reglist->mode.timeperframe; fi->interval = sensor->current_reglist->mode.timeperframe;
@@ -1064,6 +1071,13 @@ static int et8ek8_set_frame_interval(struct v4l2_subdev *subdev,
struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev); struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
struct et8ek8_reglist *reglist; struct et8ek8_reglist *reglist;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
reglist = et8ek8_reglist_find_mode_ival(&meta_reglist, reglist = et8ek8_reglist_find_mode_ival(&meta_reglist,
sensor->current_reglist, sensor->current_reglist,
&fi->interval); &fi->interval);
+7
View File
@@ -905,6 +905,13 @@ static int imx214_get_frame_interval(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state, struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fival) struct v4l2_subdev_frame_interval *fival)
{ {
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fival->interval.numerator = 1; fival->interval.numerator = 1;
fival->interval.denominator = IMX214_FPS; fival->interval.denominator = IMX214_FPS;
+14
View File
@@ -1333,6 +1333,13 @@ static int imx274_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct stimx274 *imx274 = to_imx274(sd); struct stimx274 *imx274 = to_imx274(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fi->interval = imx274->frame_interval; fi->interval = imx274->frame_interval;
dev_dbg(&imx274->client->dev, "%s frame rate = %d / %d\n", dev_dbg(&imx274->client->dev, "%s frame rate = %d / %d\n",
__func__, imx274->frame_interval.numerator, __func__, imx274->frame_interval.numerator,
@@ -1350,6 +1357,13 @@ static int imx274_set_frame_interval(struct v4l2_subdev *sd,
int min, max, def; int min, max, def;
int ret; int ret;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
ret = pm_runtime_resume_and_get(&imx274->client->dev); ret = pm_runtime_resume_and_get(&imx274->client->dev);
if (ret < 0) if (ret < 0)
return ret; return ret;
+14
View File
@@ -874,6 +874,13 @@ static int max9286_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct max9286_priv *priv = sd_to_max9286(sd); struct max9286_priv *priv = sd_to_max9286(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (interval->pad != MAX9286_SRC_PAD) if (interval->pad != MAX9286_SRC_PAD)
return -EINVAL; return -EINVAL;
@@ -888,6 +895,13 @@ static int max9286_set_frame_interval(struct v4l2_subdev *sd,
{ {
struct max9286_priv *priv = sd_to_max9286(sd); struct max9286_priv *priv = sd_to_max9286(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (interval->pad != MAX9286_SRC_PAD) if (interval->pad != MAX9286_SRC_PAD)
return -EINVAL; return -EINVAL;
+14
View File
@@ -1051,6 +1051,13 @@ static int mt9m111_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fi->interval = mt9m111->frame_interval; fi->interval = mt9m111->frame_interval;
return 0; return 0;
@@ -1068,6 +1075,13 @@ static int mt9m111_set_frame_interval(struct v4l2_subdev *sd,
if (mt9m111->is_streaming) if (mt9m111->is_streaming)
return -EBUSY; return -EBUSY;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad != 0) if (fi->pad != 0)
return -EINVAL; return -EINVAL;
+14
View File
@@ -1592,6 +1592,13 @@ static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *ival = &interval->interval; struct v4l2_fract *ival = &interval->interval;
struct mt9m114 *sensor = ifp_to_mt9m114(sd); struct mt9m114 *sensor = ifp_to_mt9m114(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(sensor->ifp.hdl.lock); mutex_lock(sensor->ifp.hdl.lock);
ival->numerator = 1; ival->numerator = 1;
@@ -1610,6 +1617,13 @@ static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd,
struct mt9m114 *sensor = ifp_to_mt9m114(sd); struct mt9m114 *sensor = ifp_to_mt9m114(sd);
int ret = 0; int ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(sensor->ifp.hdl.lock); mutex_lock(sensor->ifp.hdl.lock);
if (ival->numerator != 0 && ival->denominator != 0) if (ival->numerator != 0 && ival->denominator != 0)
+14
View File
@@ -366,6 +366,13 @@ static int mt9v011_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state, struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *ival) struct v4l2_subdev_frame_interval *ival)
{ {
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
calc_fps(sd, calc_fps(sd,
&ival->interval.numerator, &ival->interval.numerator,
&ival->interval.denominator); &ival->interval.denominator);
@@ -380,6 +387,13 @@ static int mt9v011_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *tpf = &ival->interval; struct v4l2_fract *tpf = &ival->interval;
u16 speed; u16 speed;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
speed = calc_speed(sd, tpf->numerator, tpf->denominator); speed = calc_speed(sd, tpf->numerator, tpf->denominator);
mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed); mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed);
+14
View File
@@ -730,6 +730,13 @@ static int mt9v111_set_frame_interval(struct v4l2_subdev *sd,
tpf->denominator; tpf->denominator;
unsigned int max_fps; unsigned int max_fps;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (!tpf->numerator) if (!tpf->numerator)
tpf->numerator = 1; tpf->numerator = 1;
@@ -779,6 +786,13 @@ static int mt9v111_get_frame_interval(struct v4l2_subdev *sd,
struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd);
struct v4l2_fract *tpf = &ival->interval; struct v4l2_fract *tpf = &ival->interval;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&mt9v111->stream_mutex); mutex_lock(&mt9v111->stream_mutex);
tpf->numerator = 1; tpf->numerator = 1;
+7
View File
@@ -558,6 +558,13 @@ static int ov2680_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct ov2680_dev *sensor = to_ov2680_dev(sd); struct ov2680_dev *sensor = to_ov2680_dev(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&sensor->lock); mutex_lock(&sensor->lock);
fi->interval = sensor->mode.frame_interval; fi->interval = sensor->mode.frame_interval;
mutex_unlock(&sensor->lock); mutex_unlock(&sensor->lock);
+14
View File
@@ -3610,6 +3610,13 @@ static int ov5640_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct ov5640_dev *sensor = to_ov5640_dev(sd); struct ov5640_dev *sensor = to_ov5640_dev(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&sensor->lock); mutex_lock(&sensor->lock);
fi->interval = sensor->frame_interval; fi->interval = sensor->frame_interval;
mutex_unlock(&sensor->lock); mutex_unlock(&sensor->lock);
@@ -3625,6 +3632,13 @@ static int ov5640_set_frame_interval(struct v4l2_subdev *sd,
const struct ov5640_mode_info *mode; const struct ov5640_mode_info *mode;
int frame_rate, ret = 0; int frame_rate, ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad != 0) if (fi->pad != 0)
return -EINVAL; return -EINVAL;
+7
View File
@@ -2276,6 +2276,13 @@ static int ov5648_get_frame_interval(struct v4l2_subdev *subdev,
const struct ov5648_mode *mode; const struct ov5648_mode *mode;
int ret = 0; int ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&sensor->mutex); mutex_lock(&sensor->mutex);
mode = sensor->state.mode; mode = sensor->state.mode;
+7
View File
@@ -1013,6 +1013,13 @@ static int ov5693_get_frame_interval(struct v4l2_subdev *sd,
ov5693->ctrls.vblank->val); ov5693->ctrls.vblank->val);
unsigned int fps = DIV_ROUND_CLOSEST(OV5693_PIXEL_RATE, framesize); unsigned int fps = DIV_ROUND_CLOSEST(OV5693_PIXEL_RATE, framesize);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
interval->interval.numerator = 1; interval->interval.numerator = 1;
interval->interval.denominator = fps; interval->interval.denominator = fps;
+14
View File
@@ -806,6 +806,13 @@ static int ov6650_get_frame_interval(struct v4l2_subdev *sd,
struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client); struct ov6650 *priv = to_ov6650(client);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
ival->interval = priv->tpf; ival->interval = priv->tpf;
dev_dbg(&client->dev, "Frame interval: %u/%u s\n", dev_dbg(&client->dev, "Frame interval: %u/%u s\n",
@@ -823,6 +830,13 @@ static int ov6650_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *tpf = &ival->interval; struct v4l2_fract *tpf = &ival->interval;
int div, ret; int div, ret;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (tpf->numerator == 0 || tpf->denominator == 0) if (tpf->numerator == 0 || tpf->denominator == 0)
div = 1; /* Reset to full rate */ div = 1; /* Reset to full rate */
else else
+14
View File
@@ -1391,6 +1391,13 @@ static int ov7251_get_frame_interval(struct v4l2_subdev *subdev,
{ {
struct ov7251 *ov7251 = to_ov7251(subdev); struct ov7251 *ov7251 = to_ov7251(subdev);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&ov7251->lock); mutex_lock(&ov7251->lock);
fi->interval = ov7251->current_mode->timeperframe; fi->interval = ov7251->current_mode->timeperframe;
mutex_unlock(&ov7251->lock); mutex_unlock(&ov7251->lock);
@@ -1406,6 +1413,13 @@ static int ov7251_set_frame_interval(struct v4l2_subdev *subdev,
const struct ov7251_mode_info *new_mode; const struct ov7251_mode_info *new_mode;
int ret = 0; int ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&ov7251->lock); mutex_lock(&ov7251->lock);
new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval); new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval);
+12
View File
@@ -1160,6 +1160,12 @@ static int ov7670_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct ov7670_info *info = to_state(sd); struct ov7670_info *info = to_state(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
info->devtype->get_framerate(sd, &ival->interval); info->devtype->get_framerate(sd, &ival->interval);
@@ -1173,6 +1179,12 @@ static int ov7670_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *tpf = &ival->interval; struct v4l2_fract *tpf = &ival->interval;
struct ov7670_info *info = to_state(sd); struct ov7670_info *info = to_state(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
return info->devtype->set_framerate(sd, tpf); return info->devtype->set_framerate(sd, tpf);
} }
+14
View File
@@ -724,6 +724,13 @@ static int ov772x_get_frame_interval(struct v4l2_subdev *sd,
struct ov772x_priv *priv = to_ov772x(sd); struct ov772x_priv *priv = to_ov772x(sd);
struct v4l2_fract *tpf = &ival->interval; struct v4l2_fract *tpf = &ival->interval;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
tpf->numerator = 1; tpf->numerator = 1;
tpf->denominator = priv->fps; tpf->denominator = priv->fps;
@@ -739,6 +746,13 @@ static int ov772x_set_frame_interval(struct v4l2_subdev *sd,
unsigned int fps; unsigned int fps;
int ret = 0; int ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&priv->lock); mutex_lock(&priv->lock);
if (priv->streaming) { if (priv->streaming) {
+7
View File
@@ -2846,6 +2846,13 @@ static int ov8865_get_frame_interval(struct v4l2_subdev *subdev,
unsigned int framesize; unsigned int framesize;
unsigned int fps; unsigned int fps;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&sensor->mutex); mutex_lock(&sensor->mutex);
mode = sensor->state.mode; mode = sensor->state.mode;
+14
View File
@@ -1107,6 +1107,13 @@ static int ov965x_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct ov965x *ov965x = to_ov965x(sd); struct ov965x *ov965x = to_ov965x(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&ov965x->lock); mutex_lock(&ov965x->lock);
fi->interval = ov965x->fiv->interval; fi->interval = ov965x->fiv->interval;
mutex_unlock(&ov965x->lock); mutex_unlock(&ov965x->lock);
@@ -1156,6 +1163,13 @@ static int ov965x_set_frame_interval(struct v4l2_subdev *sd,
struct ov965x *ov965x = to_ov965x(sd); struct ov965x *ov965x = to_ov965x(sd);
int ret; int ret;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
v4l2_dbg(1, debug, sd, "Setting %d/%d frame interval\n", v4l2_dbg(1, debug, sd, "Setting %d/%d frame interval\n",
fi->interval.numerator, fi->interval.denominator); fi->interval.numerator, fi->interval.denominator);
+14
View File
@@ -872,6 +872,13 @@ static int s5c73m3_oif_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad != OIF_SOURCE_PAD) if (fi->pad != OIF_SOURCE_PAD)
return -EINVAL; return -EINVAL;
@@ -923,6 +930,13 @@ static int s5c73m3_oif_set_frame_interval(struct v4l2_subdev *sd,
struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
int ret; int ret;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad != OIF_SOURCE_PAD) if (fi->pad != OIF_SOURCE_PAD)
return -EINVAL; return -EINVAL;
+14
View File
@@ -1124,6 +1124,13 @@ static int s5k5baf_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct s5k5baf *state = to_s5k5baf(sd); struct s5k5baf *state = to_s5k5baf(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&state->lock); mutex_lock(&state->lock);
fi->interval.numerator = state->fiv; fi->interval.numerator = state->fiv;
fi->interval.denominator = 10000; fi->interval.denominator = 10000;
@@ -1162,6 +1169,13 @@ static int s5k5baf_set_frame_interval(struct v4l2_subdev *sd,
{ {
struct s5k5baf *state = to_s5k5baf(sd); struct s5k5baf *state = to_s5k5baf(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&state->lock); mutex_lock(&state->lock);
__s5k5baf_set_frame_interval(state, fi); __s5k5baf_set_frame_interval(state, fi);
mutex_unlock(&state->lock); mutex_unlock(&state->lock);
+14
View File
@@ -740,6 +740,13 @@ static int thp7312_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct thp7312_device *thp7312 = to_thp7312_dev(sd); struct thp7312_device *thp7312 = to_thp7312_dev(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fi->interval.numerator = 1; fi->interval.numerator = 1;
fi->interval.denominator = thp7312->current_rate->fps; fi->interval.denominator = thp7312->current_rate->fps;
@@ -757,6 +764,13 @@ static int thp7312_set_frame_interval(struct v4l2_subdev *sd,
unsigned int best_delta = UINT_MAX; unsigned int best_delta = UINT_MAX;
unsigned int fps; unsigned int fps;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
/* Avoid divisions by 0, pick the highest frame if the interval is 0. */ /* Avoid divisions by 0, pick the highest frame if the interval is 0. */
fps = fi->interval.numerator fps = fi->interval.numerator
? DIV_ROUND_CLOSEST(fi->interval.denominator, fi->interval.numerator) ? DIV_ROUND_CLOSEST(fi->interval.denominator, fi->interval.numerator)
+12
View File
@@ -746,6 +746,12 @@ tvp514x_get_frame_interval(struct v4l2_subdev *sd,
struct tvp514x_decoder *decoder = to_decoder(sd); struct tvp514x_decoder *decoder = to_decoder(sd);
enum tvp514x_std current_std; enum tvp514x_std current_std;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
/* get the current standard */ /* get the current standard */
current_std = decoder->current_std; current_std = decoder->current_std;
@@ -765,6 +771,12 @@ tvp514x_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *timeperframe; struct v4l2_fract *timeperframe;
enum tvp514x_std current_std; enum tvp514x_std current_std;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
timeperframe = &ival->interval; timeperframe = &ival->interval;
+16 -9
View File
@@ -291,9 +291,8 @@ static inline int check_frame_interval(struct v4l2_subdev *sd,
if (!fi) if (!fi)
return -EINVAL; return -EINVAL;
return check_pad(sd, fi->pad) ? : return check_which(fi->which) ? : check_pad(sd, fi->pad) ? :
check_state(sd, state, V4L2_SUBDEV_FORMAT_ACTIVE, fi->pad, check_state(sd, state, fi->which, fi->pad, fi->stream);
fi->stream);
} }
static int call_get_frame_interval(struct v4l2_subdev *sd, static int call_get_frame_interval(struct v4l2_subdev *sd,
@@ -537,9 +536,16 @@ subdev_ioctl_get_state(struct v4l2_subdev *sd, struct v4l2_subdev_fh *subdev_fh,
which = ((struct v4l2_subdev_selection *)arg)->which; which = ((struct v4l2_subdev_selection *)arg)->which;
break; break;
case VIDIOC_SUBDEV_G_FRAME_INTERVAL: case VIDIOC_SUBDEV_G_FRAME_INTERVAL:
case VIDIOC_SUBDEV_S_FRAME_INTERVAL: case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {
which = V4L2_SUBDEV_FORMAT_ACTIVE; struct v4l2_subdev_frame_interval *fi = arg;
if (!(subdev_fh->client_caps &
V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH))
fi->which = V4L2_SUBDEV_FORMAT_ACTIVE;
which = fi->which;
break; break;
}
case VIDIOC_SUBDEV_G_ROUTING: case VIDIOC_SUBDEV_G_ROUTING:
case VIDIOC_SUBDEV_S_ROUTING: case VIDIOC_SUBDEV_S_ROUTING:
which = ((struct v4l2_subdev_routing *)arg)->which; which = ((struct v4l2_subdev_routing *)arg)->which;
@@ -796,12 +802,12 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,
case VIDIOC_SUBDEV_S_FRAME_INTERVAL: { case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {
struct v4l2_subdev_frame_interval *fi = arg; struct v4l2_subdev_frame_interval *fi = arg;
if (ro_subdev)
return -EPERM;
if (!client_supports_streams) if (!client_supports_streams)
fi->stream = 0; fi->stream = 0;
if (fi->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
return -EPERM;
memset(fi->reserved, 0, sizeof(fi->reserved)); memset(fi->reserved, 0, sizeof(fi->reserved));
return v4l2_subdev_call(sd, pad, set_frame_interval, state, fi); return v4l2_subdev_call(sd, pad, set_frame_interval, state, fi);
} }
@@ -998,7 +1004,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,
client_cap->capabilities &= ~V4L2_SUBDEV_CLIENT_CAP_STREAMS; client_cap->capabilities &= ~V4L2_SUBDEV_CLIENT_CAP_STREAMS;
/* Filter out unsupported capabilities */ /* Filter out unsupported capabilities */
client_cap->capabilities &= V4L2_SUBDEV_CLIENT_CAP_STREAMS; client_cap->capabilities &= (V4L2_SUBDEV_CLIENT_CAP_STREAMS |
V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH);
subdev_fh->client_caps = client_cap->capabilities; subdev_fh->client_caps = client_cap->capabilities;
@@ -500,6 +500,13 @@ static int gc0310_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state, struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *interval) struct v4l2_subdev_frame_interval *interval)
{ {
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
interval->interval.numerator = 1; interval->interval.numerator = 1;
interval->interval.denominator = GC0310_FPS; interval->interval.denominator = GC0310_FPS;
@@ -704,6 +704,13 @@ static int gc2235_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct gc2235_device *dev = to_gc2235_sensor(sd); struct gc2235_device *dev = to_gc2235_sensor(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
interval->interval.numerator = 1; interval->interval.numerator = 1;
interval->interval.denominator = dev->res->fps; interval->interval.denominator = dev->res->fps;
@@ -1394,6 +1394,13 @@ static int mt9m114_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct mt9m114_device *dev = to_mt9m114_sensor(sd); struct mt9m114_device *dev = to_mt9m114_sensor(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
interval->interval.numerator = 1; interval->interval.numerator = 1;
interval->interval.denominator = mt9m114_res[dev->res].fps; interval->interval.denominator = mt9m114_res[dev->res].fps;
@@ -851,6 +851,13 @@ static int ov2722_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct ov2722_device *dev = to_ov2722_sensor(sd); struct ov2722_device *dev = to_ov2722_sensor(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
interval->interval.numerator = 1; interval->interval.numerator = 1;
interval->interval.denominator = dev->res->fps; interval->interval.denominator = dev->res->fps;
+14
View File
@@ -399,6 +399,13 @@ static int prp_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct prp_priv *priv = sd_to_priv(sd); struct prp_priv *priv = sd_to_priv(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad >= PRP_NUM_PADS) if (fi->pad >= PRP_NUM_PADS)
return -EINVAL; return -EINVAL;
@@ -415,6 +422,13 @@ static int prp_set_frame_interval(struct v4l2_subdev *sd,
{ {
struct prp_priv *priv = sd_to_priv(sd); struct prp_priv *priv = sd_to_priv(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad >= PRP_NUM_PADS) if (fi->pad >= PRP_NUM_PADS)
return -EINVAL; return -EINVAL;
@@ -1209,6 +1209,13 @@ static int prp_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct prp_priv *priv = sd_to_priv(sd); struct prp_priv *priv = sd_to_priv(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad >= PRPENCVF_NUM_PADS) if (fi->pad >= PRPENCVF_NUM_PADS)
return -EINVAL; return -EINVAL;
@@ -1225,6 +1232,13 @@ static int prp_set_frame_interval(struct v4l2_subdev *sd,
{ {
struct prp_priv *priv = sd_to_priv(sd); struct prp_priv *priv = sd_to_priv(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad >= PRPENCVF_NUM_PADS) if (fi->pad >= PRPENCVF_NUM_PADS)
return -EINVAL; return -EINVAL;
+14
View File
@@ -908,6 +908,13 @@ static int csi_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct csi_priv *priv = v4l2_get_subdevdata(sd); struct csi_priv *priv = v4l2_get_subdevdata(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad >= CSI_NUM_PADS) if (fi->pad >= CSI_NUM_PADS)
return -EINVAL; return -EINVAL;
@@ -928,6 +935,13 @@ static int csi_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *input_fi; struct v4l2_fract *input_fi;
int ret = 0; int ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&priv->lock); mutex_lock(&priv->lock);
input_fi = &priv->frame_interval[CSI_SINK_PAD]; input_fi = &priv->frame_interval[CSI_SINK_PAD];
@@ -786,6 +786,13 @@ static int vdic_get_frame_interval(struct v4l2_subdev *sd,
{ {
struct vdic_priv *priv = v4l2_get_subdevdata(sd); struct vdic_priv *priv = v4l2_get_subdevdata(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad >= VDIC_NUM_PADS) if (fi->pad >= VDIC_NUM_PADS)
return -EINVAL; return -EINVAL;
@@ -806,6 +813,13 @@ static int vdic_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *input_fi, *output_fi; struct v4l2_fract *input_fi, *output_fi;
int ret = 0; int ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(&priv->lock); mutex_lock(&priv->lock);
input_fi = &priv->frame_interval[priv->active_input_pad]; input_fi = &priv->frame_interval[priv->active_input_pad];
+7
View File
@@ -231,6 +231,13 @@ static int tegra_csi_get_frame_interval(struct v4l2_subdev *subdev,
if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)) if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (vfi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
vfi->interval.numerator = 1; vfi->interval.numerator = 1;
vfi->interval.denominator = csi_chan->framerate; vfi->interval.denominator = csi_chan->framerate;
+12 -3
View File
@@ -116,13 +116,15 @@ struct v4l2_subdev_frame_size_enum {
* @pad: pad number, as reported by the media API * @pad: pad number, as reported by the media API
* @interval: frame interval in seconds * @interval: frame interval in seconds
* @stream: stream number, defined in subdev routing * @stream: stream number, defined in subdev routing
* @which: interval type (from enum v4l2_subdev_format_whence)
* @reserved: drivers and applications must zero this array * @reserved: drivers and applications must zero this array
*/ */
struct v4l2_subdev_frame_interval { struct v4l2_subdev_frame_interval {
__u32 pad; __u32 pad;
struct v4l2_fract interval; struct v4l2_fract interval;
__u32 stream; __u32 stream;
__u32 reserved[8]; __u32 which;
__u32 reserved[7];
}; };
/** /**
@@ -133,7 +135,7 @@ struct v4l2_subdev_frame_interval {
* @width: frame width in pixels * @width: frame width in pixels
* @height: frame height in pixels * @height: frame height in pixels
* @interval: frame interval in seconds * @interval: frame interval in seconds
* @which: format type (from enum v4l2_subdev_format_whence) * @which: interval type (from enum v4l2_subdev_format_whence)
* @stream: stream number, defined in subdev routing * @stream: stream number, defined in subdev routing
* @reserved: drivers and applications must zero this array * @reserved: drivers and applications must zero this array
*/ */
@@ -239,7 +241,14 @@ struct v4l2_subdev_routing {
* set (which is the default), the 'stream' fields will be forced to 0 by the * set (which is the default), the 'stream' fields will be forced to 0 by the
* kernel. * kernel.
*/ */
#define V4L2_SUBDEV_CLIENT_CAP_STREAMS (1ULL << 0) #define V4L2_SUBDEV_CLIENT_CAP_STREAMS (1ULL << 0)
/*
* The client is aware of the struct v4l2_subdev_frame_interval which field. If
* this is not set (which is the default), the which field is forced to
* V4L2_SUBDEV_FORMAT_ACTIVE by the kernel.
*/
#define V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH (1ULL << 1)
/** /**
* struct v4l2_subdev_client_capability - Capabilities of the client accessing * struct v4l2_subdev_client_capability - Capabilities of the client accessing