[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250818155809.469479-5-mirela.rabulea@nxp.com>
Date: Mon, 18 Aug 2025 18:58:08 +0300
From: Mirela Rabulea <mirela.rabulea@....com>
To: mchehab@...nel.org,
sakari.ailus@...ux.intel.com,
hverkuil-cisco@...all.nl,
laurent.pinchart+renesas@...asonboard.com,
ribalda@...omium.org,
jai.luthra@...asonboard.com,
laurentiu.palcu@....com
Cc: linux-media@...r.kernel.org,
linux-kernel@...r.kernel.org,
LnxRevLi@....com,
julien.vuillaumier@....com,
celine.laurencin@....com
Subject: [RFC v2 4/5] media: v4l2-ctrls: Use the single-capture control helpers in v4l2 core
Use the following v4l2 helpers to support backward compatibility
with single-capture controls, such that new drivers that only
implement explicitly the multi-capture control won't have to
worry about keeping them in sync with old single capture controls:
__v4l2_get_multi_ctrl
Used by the v2l2 core in try_or_set_cluster and
__v4l2_ctrl_handler_setup to redirect s_ctrl towards the multi controls
instead of single controls, so that the new sensor drivers do not need
to implement the single-capture controls in s_ctrl.
__v4l2_get_single_ctrl
Used by the v2l2 core in __v4l2_ctrl_modify_range, to modify also the
range of single-capture control when multi-capture control range
changes, so drivers won't have to worry about it.
__v4l2_s_ctrl_multi_to_single
Used by the v2l2 core in __v4l2_ctrl_s_ctrl_compound, to transparently
keep the value of single-capture control in sync with the value of the
multi-capture control, so drivers won't have to worry about it. The
__v4l2_ctrl_s_ctrl_compound() and __v4l2_ctrl_modify_range() are
usually called during sensor mode change to update the exposure
according to the current mode, the sensor driver only needs to update
the multi-controls, and the v4l2-core will update the single-controls.
Signed-off-by: Mirela Rabulea <mirela.rabulea@....com>
---
Changes in v2:
New patch
We need to choose either this patch (do as much as we can in the v4l2 core
for backward compatibility for old userspace apps using single-capture controls)
or patch #5 (let the new drivers still implement s_ctrl for single-capture controls,
but using the helpers, also driver needs to take care to keep ranges and values
in sync)
drivers/media/v4l2-core/v4l2-ctrls-api.c | 28 ++++++++++++++++++++---
drivers/media/v4l2-core/v4l2-ctrls-core.c | 23 +++++++++++++++++--
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c
index 49a5c7538a09..4f4cb53b8fb0 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -947,6 +947,8 @@ EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl,
enum v4l2_ctrl_type type, const void *p)
{
+ int ret;
+
lockdep_assert_held(ctrl->handler->lock);
/* It's a driver bug if this happens. */
@@ -956,7 +958,14 @@ int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl,
if (WARN_ON(ctrl->is_dyn_array))
return -EINVAL;
memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size);
- return set_ctrl(NULL, ctrl, 0);
+ ret = set_ctrl(NULL, ctrl, 0);
+ if (!ret)
+ return ret;
+ /*
+ * this can be removed when backward compatibility with legacy
+ * single exposure and gain controls is no longer needed
+ */
+ return __v4l2_s_ctrl_multi_to_single(ctrl);
}
EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_compound);
@@ -968,6 +977,7 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
{
bool value_changed;
bool range_changed = false;
+ struct v4l2_ctrl *ctrl_single = NULL;
int ret;
lockdep_assert_held(ctrl->handler->lock);
@@ -982,8 +992,11 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
case V4L2_CTRL_TYPE_U8:
case V4L2_CTRL_TYPE_U16:
case V4L2_CTRL_TYPE_U32:
- if (ctrl->is_array)
- return -EINVAL;
+ if (ctrl->is_array) {
+ ctrl_single = __v4l2_get_single_ctrl(ctrl);
+ if (!ctrl_single)
+ return -EINVAL;
+ }
ret = check_range(ctrl->type, min, max, step, def);
if (ret)
return ret;
@@ -1015,6 +1028,15 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
else if (range_changed)
send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
+ if (ret)
+ return ret;
+ /*
+ * this can be removed when backward compatibility with legacy
+ * single exposure and gain controls is no longer needed
+ */
+ if (ctrl_single)
+ ret = __v4l2_ctrl_modify_range(ctrl_single, min, max, step, def);
+
return ret;
}
EXPORT_SYMBOL(__v4l2_ctrl_modify_range);
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 41f307e3afa6..8d706070c041 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -2478,6 +2478,7 @@ int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master,
bool update_flag;
int ret;
int i;
+ struct v4l2_ctrl *master_multi = NULL;
/*
* Go through the cluster and either validate the new value or
@@ -2508,7 +2509,16 @@ int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master,
/* Don't set if there is no change */
if (ret || !set || !cluster_changed(master))
return ret;
- ret = call_op(master, s_ctrl);
+
+ /*
+ * for sensor drivers that no longer handle single-capture controls in
+ * s_ctrl, set the corresponding multi-capture control instead
+ */
+ master_multi = __v4l2_get_multi_ctrl(master);
+ if (master_multi)
+ ret = call_op(master_multi, s_ctrl);
+ else
+ ret = call_op(master, s_ctrl);
if (ret)
return ret;
@@ -2590,6 +2600,7 @@ int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
list_for_each_entry(ctrl, &hdl->ctrls, node) {
struct v4l2_ctrl *master = ctrl->cluster[0];
+ struct v4l2_ctrl *master_multi = __v4l2_get_multi_ctrl(master);
int i;
/* Skip if this control was already handled by a cluster. */
@@ -2605,7 +2616,15 @@ int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
master->cluster[i]->done = true;
}
}
- ret = call_op(master, s_ctrl);
+ /*
+ * for sensor drivers that no longer handle single-capture
+ * controls in s_ctrl, set the corresponding multi-capture
+ * control instead
+ */
+ if (master_multi)
+ ret = call_op(master_multi, s_ctrl);
+ else
+ ret = call_op(master, s_ctrl);
if (ret)
break;
}
--
2.43.0
Powered by blists - more mailing lists