CHROMIUM: v4l2-ctrls: add function to apply a configuration store.

Drivers need to be able to select a specific store. Add a new function that can
be used to apply a given store.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>

BUG=chrome-os-partner:33728
TEST=build

Signed-off-by: Pawel Osciak <posciak@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/232585
Trybot-Ready: Tomasz Figa <tfiga@chromium.org>
Tested-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Wu-cheng Li <wuchengli@chromium.org>
Commit-Queue: Tomasz Figa <tfiga@chromium.org>

Change-Id: I3b80a31681765836a134812ebc56686324ca5194
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Signed-off-by: Yakir Yang <ykk@rock-chips.com>
This commit is contained in:
Hans Verkuil 2014-09-12 11:52:26 +02:00 committed by Huang, Tao
parent 3b670167f2
commit a2e9b787cf
2 changed files with 63 additions and 0 deletions

View File

@ -1616,6 +1616,17 @@ static void cur_to_new(struct v4l2_ctrl *ctrl)
ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
}
static void store_to_new(struct v4l2_ctrl *ctrl, unsigned store)
{
if (ctrl == NULL)
return;
if (store)
ptr_to_ptr(ctrl, ctrl->p_stores[store - 1], ctrl->p_new);
else
ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
ctrl->is_new = true;
}
/* Return non-zero if one or more of the controls in the cluster has a new
value that differs from the current value. */
static int cluster_changed(struct v4l2_ctrl *master)
@ -3381,6 +3392,56 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
}
EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
int v4l2_ctrl_apply_store(struct v4l2_ctrl_handler *hdl, unsigned store)
{
struct v4l2_ctrl_ref *ref;
bool found_store = false;
unsigned i;
if (hdl == NULL || store == 0)
return -EINVAL;
mutex_lock(hdl->lock);
list_for_each_entry(ref, &hdl->ctrl_refs, node) {
struct v4l2_ctrl *master;
if (store > ref->ctrl->nr_of_stores)
continue;
found_store = true;
master = ref->ctrl->cluster[0];
if (ref->ctrl != master)
continue;
if (master->handler != hdl)
v4l2_ctrl_lock(master);
for (i = 0; i < master->ncontrols; i++)
store_to_new(master->cluster[i], store);
/* For volatile autoclusters that are currently in auto mode
we need to discover if it will be set to manual mode.
If so, then we have to copy the current volatile values
first since those will become the new manual values (which
may be overwritten by explicit new values from this set
of controls). */
if (master->is_auto && master->has_volatiles &&
!is_cur_manual(master)) {
s32 new_auto_val = *master->p_stores[store - 1].p_s32;
/* If the new value == the manual value, then copy
the current volatile values. */
if (new_auto_val == master->manual_mode_value)
update_from_auto_cluster(master);
}
try_or_set_cluster(NULL, master, 0, true, 0);
if (master->handler != hdl)
v4l2_ctrl_unlock(master);
}
mutex_unlock(hdl->lock);
return found_store ? 0 : -EINVAL;
}
EXPORT_SYMBOL(v4l2_ctrl_apply_store);
void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
{
if (ctrl == NULL)

View File

@ -900,6 +900,8 @@ static inline void v4l2_ctrl_set_max_stores(struct v4l2_ctrl *ctrl, u16 max_stor
ctrl->max_stores = max_stores;
}
int v4l2_ctrl_apply_store(struct v4l2_ctrl_handler *hdl, unsigned store);
/* Internal helper functions that deal with control events. */
extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new);