summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2023-12-13 18:00:05 +0300
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2023-12-13 18:52:35 +0300
commit805d4311a54a25d7347684fdf778c6239b190864 (patch)
treeb95e9c7fb047331923522741aa4a4b5f7353faf6 /drivers/media
parent287fe160834acdf9c44e5b73676180c6dbdedf76 (diff)
downloadlinux-805d4311a54a25d7347684fdf778c6239b190864.tar.xz
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>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/i2c/adv7180.c7
-rw-r--r--drivers/media/i2c/alvium-csi2.c14
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_driver.c14
-rw-r--r--drivers/media/i2c/imx214.c7
-rw-r--r--drivers/media/i2c/imx274.c14
-rw-r--r--drivers/media/i2c/max9286.c14
-rw-r--r--drivers/media/i2c/mt9m111.c14
-rw-r--r--drivers/media/i2c/mt9m114.c14
-rw-r--r--drivers/media/i2c/mt9v011.c14
-rw-r--r--drivers/media/i2c/mt9v111.c14
-rw-r--r--drivers/media/i2c/ov2680.c7
-rw-r--r--drivers/media/i2c/ov5640.c14
-rw-r--r--drivers/media/i2c/ov5648.c7
-rw-r--r--drivers/media/i2c/ov5693.c7
-rw-r--r--drivers/media/i2c/ov6650.c14
-rw-r--r--drivers/media/i2c/ov7251.c14
-rw-r--r--drivers/media/i2c/ov7670.c12
-rw-r--r--drivers/media/i2c/ov772x.c14
-rw-r--r--drivers/media/i2c/ov8865.c7
-rw-r--r--drivers/media/i2c/ov9650.c14
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c14
-rw-r--r--drivers/media/i2c/s5k5baf.c14
-rw-r--r--drivers/media/i2c/thp7312.c14
-rw-r--r--drivers/media/i2c/tvp514x.c12
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c25
25 files changed, 306 insertions, 9 deletions
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 7ed86030fb5c..409b9a37f018 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -469,6 +469,13 @@ static int adv7180_get_frame_interval(struct v4l2_subdev *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) {
fi->interval.numerator = 1001;
fi->interval.denominator = 30000;
diff --git a/drivers/media/i2c/alvium-csi2.c b/drivers/media/i2c/alvium-csi2.c
index a173abb0509f..34ff7fad3877 100644
--- a/drivers/media/i2c/alvium-csi2.c
+++ b/drivers/media/i2c/alvium-csi2.c
@@ -1654,6 +1654,13 @@ static int alvium_g_frame_interval(struct v4l2_subdev *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;
return 0;
@@ -1703,6 +1710,13 @@ static int alvium_s_frame_interval(struct v4l2_subdev *sd,
struct alvium_dev *alvium = sd_to_alvium(sd);
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)
return -EBUSY;
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index 71fb5aebd3df..f548b1bb75fb 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -1051,6 +1051,13 @@ static int et8ek8_get_frame_interval(struct v4l2_subdev *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));
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_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,
sensor->current_reglist,
&fi->interval);
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
index 8e832a4e3544..b148b1bd2bc3 100644
--- a/drivers/media/i2c/imx214.c
+++ b/drivers/media/i2c/imx214.c
@@ -905,6 +905,13 @@ static int imx214_get_frame_interval(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state,
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.denominator = IMX214_FPS;
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index 4040c642a36f..352da68b8b41 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -1333,6 +1333,13 @@ static int imx274_get_frame_interval(struct v4l2_subdev *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;
dev_dbg(&imx274->client->dev, "%s frame rate = %d / %d\n",
__func__, imx274->frame_interval.numerator,
@@ -1350,6 +1357,13 @@ static int imx274_set_frame_interval(struct v4l2_subdev *sd,
int min, max, def;
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);
if (ret < 0)
return ret;
diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 7e8cb53d31c3..d685d445cf23 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -874,6 +874,13 @@ static int max9286_get_frame_interval(struct v4l2_subdev *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)
return -EINVAL;
@@ -888,6 +895,13 @@ static int max9286_set_frame_interval(struct v4l2_subdev *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)
return -EINVAL;
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index 602954650f2e..ceeeb94c38d5 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -1051,6 +1051,13 @@ static int mt9m111_get_frame_interval(struct v4l2_subdev *sd,
{
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;
return 0;
@@ -1068,6 +1075,13 @@ static int mt9m111_set_frame_interval(struct v4l2_subdev *sd,
if (mt9m111->is_streaming)
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)
return -EINVAL;
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index dcd94299787c..427eae13ce26 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -1592,6 +1592,13 @@ static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *ival = &interval->interval;
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);
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);
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);
if (ival->numerator != 0 && ival->denominator != 0)
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 3485761428ba..8834ff8786e5 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -366,6 +366,13 @@ static int mt9v011_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
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,
&ival->interval.numerator,
&ival->interval.denominator);
@@ -380,6 +387,13 @@ static int mt9v011_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *tpf = &ival->interval;
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);
mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed);
diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c
index 496be67c971b..b0b98ed3c150 100644
--- a/drivers/media/i2c/mt9v111.c
+++ b/drivers/media/i2c/mt9v111.c
@@ -730,6 +730,13 @@ static int mt9v111_set_frame_interval(struct v4l2_subdev *sd,
tpf->denominator;
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)
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 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);
tpf->numerator = 1;
diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
index e3ff64a9e6ca..39d321e2b7f9 100644
--- a/drivers/media/i2c/ov2680.c
+++ b/drivers/media/i2c/ov2680.c
@@ -558,6 +558,13 @@ static int ov2680_get_frame_interval(struct v4l2_subdev *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);
fi->interval = sensor->mode.frame_interval;
mutex_unlock(&sensor->lock);
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 336bfd1ffd32..5162d45fe73b 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -3610,6 +3610,13 @@ static int ov5640_get_frame_interval(struct v4l2_subdev *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);
fi->interval = sensor->frame_interval;
mutex_unlock(&sensor->lock);
@@ -3625,6 +3632,13 @@ static int ov5640_set_frame_interval(struct v4l2_subdev *sd,
const struct ov5640_mode_info *mode;
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)
return -EINVAL;
diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c
index d0d7e9968f48..4b86d2631bd1 100644
--- a/drivers/media/i2c/ov5648.c
+++ b/drivers/media/i2c/ov5648.c
@@ -2276,6 +2276,13 @@ static int ov5648_get_frame_interval(struct v4l2_subdev *subdev,
const struct ov5648_mode *mode;
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);
mode = sensor->state.mode;
diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
index a65645811fbc..8deb28b55983 100644
--- a/drivers/media/i2c/ov5693.c
+++ b/drivers/media/i2c/ov5693.c
@@ -1013,6 +1013,13 @@ static int ov5693_get_frame_interval(struct v4l2_subdev *sd,
ov5693->ctrls.vblank->val);
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.denominator = fps;
diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c
index a4dc45bdf3d7..b65befb22a79 100644
--- a/drivers/media/i2c/ov6650.c
+++ b/drivers/media/i2c/ov6650.c
@@ -806,6 +806,13 @@ static int ov6650_get_frame_interval(struct v4l2_subdev *sd,
struct i2c_client *client = v4l2_get_subdevdata(sd);
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;
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;
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)
div = 1; /* Reset to full rate */
else
diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c
index 10d6b5deed83..30f61e04ecaf 100644
--- a/drivers/media/i2c/ov7251.c
+++ b/drivers/media/i2c/ov7251.c
@@ -1391,6 +1391,13 @@ static int ov7251_get_frame_interval(struct v4l2_subdev *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);
fi->interval = ov7251->current_mode->timeperframe;
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;
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);
new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval);
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 463f20ece36e..0cb96b6c9990 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -1160,6 +1160,12 @@ static int ov7670_get_frame_interval(struct v4l2_subdev *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);
@@ -1173,6 +1179,12 @@ static int ov7670_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *tpf = &ival->interval;
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);
}
diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
index a14a25946c5b..3e36a55274ef 100644
--- a/drivers/media/i2c/ov772x.c
+++ b/drivers/media/i2c/ov772x.c
@@ -724,6 +724,13 @@ static int ov772x_get_frame_interval(struct v4l2_subdev *sd,
struct ov772x_priv *priv = to_ov772x(sd);
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->denominator = priv->fps;
@@ -739,6 +746,13 @@ static int ov772x_set_frame_interval(struct v4l2_subdev *sd,
unsigned int fps;
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);
if (priv->streaming) {
diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 02a595281c49..95ffe7536aa6 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2846,6 +2846,13 @@ static int ov8865_get_frame_interval(struct v4l2_subdev *subdev,
unsigned int framesize;
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);
mode = sensor->state.mode;
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index f528892c893f..66cd0e9ddc9a 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -1107,6 +1107,13 @@ static int ov965x_get_frame_interval(struct v4l2_subdev *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);
fi->interval = ov965x->fiv->interval;
mutex_unlock(&ov965x->lock);
@@ -1156,6 +1163,13 @@ static int ov965x_set_frame_interval(struct v4l2_subdev *sd,
struct ov965x *ov965x = to_ov965x(sd);
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",
fi->interval.numerator, fi->interval.denominator);
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 73ca50f49812..af8d01f78c32 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -872,6 +872,13 @@ static int s5c73m3_oif_get_frame_interval(struct v4l2_subdev *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)
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);
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)
return -EINVAL;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 2fd1ecfeb086..de079d2c9282 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1124,6 +1124,13 @@ static int s5k5baf_get_frame_interval(struct v4l2_subdev *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);
fi->interval.numerator = state->fiv;
fi->interval.denominator = 10000;
@@ -1162,6 +1169,13 @@ static int s5k5baf_set_frame_interval(struct v4l2_subdev *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);
__s5k5baf_set_frame_interval(state, fi);
mutex_unlock(&state->lock);
diff --git a/drivers/media/i2c/thp7312.c b/drivers/media/i2c/thp7312.c
index d4975b180704..ad4f2b794e1a 100644
--- a/drivers/media/i2c/thp7312.c
+++ b/drivers/media/i2c/thp7312.c
@@ -740,6 +740,13 @@ static int thp7312_get_frame_interval(struct v4l2_subdev *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.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 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. */
fps = fi->interval.numerator
? DIV_ROUND_CLOSEST(fi->interval.denominator, fi->interval.numerator)
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index dee0cf992379..5a561e5bf659 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -746,6 +746,12 @@ tvp514x_get_frame_interval(struct v4l2_subdev *sd,
struct tvp514x_decoder *decoder = to_decoder(sd);
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 */
current_std = decoder->current_std;
@@ -765,6 +771,12 @@ tvp514x_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_fract *timeperframe;
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;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 405a4a2fa565..30131a37f2d5 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -291,9 +291,8 @@ static inline int check_frame_interval(struct v4l2_subdev *sd,
if (!fi)
return -EINVAL;
- return check_pad(sd, fi->pad) ? :
- check_state(sd, state, V4L2_SUBDEV_FORMAT_ACTIVE, fi->pad,
- fi->stream);
+ return check_which(fi->which) ? : check_pad(sd, fi->pad) ? :
+ check_state(sd, state, fi->which, fi->pad, fi->stream);
}
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;
break;
case VIDIOC_SUBDEV_G_FRAME_INTERVAL:
- case VIDIOC_SUBDEV_S_FRAME_INTERVAL:
- which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {
+ 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;
+ }
case VIDIOC_SUBDEV_G_ROUTING:
case VIDIOC_SUBDEV_S_ROUTING:
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: {
struct v4l2_subdev_frame_interval *fi = arg;
- if (ro_subdev)
- return -EPERM;
-
if (!client_supports_streams)
fi->stream = 0;
+ if (fi->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
+ return -EPERM;
+
memset(fi->reserved, 0, sizeof(fi->reserved));
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;
/* 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;