Commit b35d6c02 authored by Ricardo Ribalda Delgado's avatar Ricardo Ribalda Delgado Committed by Mauro Carvalho Chehab

media: v4l2-core: Implement v4l2_ctrl_new_std_compound

Currently compound controls do not have a simple way of initializing its
values. This results in ofuscated code with type_ops init.

This patch introduces a new field on the control with the default value
for the compound control that can be set with the brand new
v4l2_ctrl_new_std_compound function
Suggested-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarRicardo Ribalda Delgado <ribalda@kernel.org>
[hverkuil@xs4all.nl: fix checkpatch warning]
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent d8b1ad7c
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#define call_op(master, op) \ #define call_op(master, op) \
(has_op(master, op) ? master->ops->op(master) : 0) (has_op(master, op) ? master->ops->op(master) : 0)
static const union v4l2_ctrl_ptr ptr_null;
/* Internal temporary helper struct, one for each v4l2_ext_control */ /* Internal temporary helper struct, one for each v4l2_ext_control */
struct v4l2_ctrl_helper { struct v4l2_ctrl_helper {
/* Pointer to the control reference of the master control */ /* Pointer to the control reference of the master control */
...@@ -1530,6 +1532,9 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, ...@@ -1530,6 +1532,9 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
void *p = ptr.p + idx * ctrl->elem_size; void *p = ptr.p + idx * ctrl->elem_size;
if (ctrl->p_def.p)
memcpy(p, ctrl->p_def.p, ctrl->elem_size);
else
memset(p, 0, ctrl->elem_size); memset(p, 0, ctrl->elem_size);
/* /*
...@@ -2354,7 +2359,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, ...@@ -2354,7 +2359,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
s64 min, s64 max, u64 step, s64 def, s64 min, s64 max, u64 step, s64 def,
const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size, const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size,
u32 flags, const char * const *qmenu, u32 flags, const char * const *qmenu,
const s64 *qmenu_int, void *priv) const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def,
void *priv)
{ {
struct v4l2_ctrl *ctrl; struct v4l2_ctrl *ctrl;
unsigned sz_extra; unsigned sz_extra;
...@@ -2460,6 +2466,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, ...@@ -2460,6 +2466,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
is_array) is_array)
sz_extra += 2 * tot_ctrl_size; sz_extra += 2 * tot_ctrl_size;
if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p)
sz_extra += elem_size;
ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL); ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL);
if (ctrl == NULL) { if (ctrl == NULL) {
handler_set_err(hdl, -ENOMEM); handler_set_err(hdl, -ENOMEM);
...@@ -2503,6 +2512,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, ...@@ -2503,6 +2512,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
ctrl->p_new.p = &ctrl->val; ctrl->p_new.p = &ctrl->val;
ctrl->p_cur.p = &ctrl->cur.val; ctrl->p_cur.p = &ctrl->cur.val;
} }
if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p) {
ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size;
memcpy(ctrl->p_def.p, p_def.p, elem_size);
}
for (idx = 0; idx < elems; idx++) { for (idx = 0; idx < elems; idx++) {
ctrl->type_ops->init(ctrl, idx, ctrl->p_cur); ctrl->type_ops->init(ctrl, idx, ctrl->p_cur);
ctrl->type_ops->init(ctrl, idx, ctrl->p_new); ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
...@@ -2554,7 +2569,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, ...@@ -2554,7 +2569,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
type, min, max, type, min, max,
is_menu ? cfg->menu_skip_mask : step, def, is_menu ? cfg->menu_skip_mask : step, def,
cfg->dims, cfg->elem_size, cfg->dims, cfg->elem_size,
flags, qmenu, qmenu_int, priv); flags, qmenu, qmenu_int, ptr_null, priv);
if (ctrl) if (ctrl)
ctrl->is_private = cfg->is_private; ctrl->is_private = cfg->is_private;
return ctrl; return ctrl;
...@@ -2579,7 +2594,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, ...@@ -2579,7 +2594,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
} }
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
min, max, step, def, NULL, 0, min, max, step, def, NULL, 0,
flags, NULL, NULL, NULL); flags, NULL, NULL, ptr_null, NULL);
} }
EXPORT_SYMBOL(v4l2_ctrl_new_std); EXPORT_SYMBOL(v4l2_ctrl_new_std);
...@@ -2612,7 +2627,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, ...@@ -2612,7 +2627,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
} }
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
0, max, mask, def, NULL, 0, 0, max, mask, def, NULL, 0,
flags, qmenu, qmenu_int, NULL); flags, qmenu, qmenu_int, ptr_null, NULL);
} }
EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
...@@ -2644,11 +2659,32 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, ...@@ -2644,11 +2659,32 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
} }
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
0, max, mask, def, NULL, 0, 0, max, mask, def, NULL, 0,
flags, qmenu, NULL, NULL); flags, qmenu, NULL, ptr_null, NULL);
} }
EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items);
/* Helper function for standard compound controls */
struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops, u32 id,
const union v4l2_ctrl_ptr p_def)
{
const char *name;
enum v4l2_ctrl_type type;
u32 flags;
s64 min, max, step, def;
v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
if (type < V4L2_CTRL_COMPOUND_TYPES) {
handler_set_err(hdl, -EINVAL);
return NULL;
}
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
min, max, step, def, NULL, 0,
flags, NULL, NULL, p_def, NULL);
}
EXPORT_SYMBOL(v4l2_ctrl_new_std_compound);
/* Helper function for standard integer menu controls */ /* Helper function for standard integer menu controls */
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops, const struct v4l2_ctrl_ops *ops,
...@@ -2669,7 +2705,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, ...@@ -2669,7 +2705,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
} }
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
0, max, 0, def, NULL, 0, 0, max, 0, def, NULL, 0,
flags, NULL, qmenu_int, NULL); flags, NULL, qmenu_int, ptr_null, NULL);
} }
EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
......
...@@ -200,6 +200,9 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv); ...@@ -200,6 +200,9 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
* not freed when the control is deleted. Should this be needed * not freed when the control is deleted. Should this be needed
* then a new internal bitfield can be added to tell the framework * then a new internal bitfield can be added to tell the framework
* to free this pointer. * to free this pointer.
* @p_def: The control's default value represented via a union which
* provides a standard way of accessing control types
* through a pointer (for compound controls only).
* @p_cur: The control's current value represented via a union which * @p_cur: The control's current value represented via a union which
* provides a standard way of accessing control types * provides a standard way of accessing control types
* through a pointer. * through a pointer.
...@@ -254,6 +257,7 @@ struct v4l2_ctrl { ...@@ -254,6 +257,7 @@ struct v4l2_ctrl {
s32 val; s32 val;
} cur; } cur;
union v4l2_ctrl_ptr p_def;
union v4l2_ctrl_ptr p_new; union v4l2_ctrl_ptr p_new;
union v4l2_ctrl_ptr p_cur; union v4l2_ctrl_ptr p_cur;
}; };
...@@ -646,6 +650,24 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, ...@@ -646,6 +650,24 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
u64 mask, u8 def, u64 mask, u8 def,
const char * const *qmenu); const char * const *qmenu);
/**
* v4l2_ctrl_new_std_compound() - Allocate and initialize a new standard V4L2
* compound control.
*
* @hdl: The control handler.
* @ops: The control ops.
* @id: The control ID.
* @p_def: The control's default value.
*
* Sames as v4l2_ctrl_new_std(), but with support to compound controls, thanks
* to the @p_def field.
*
*/
struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id,
const union v4l2_ctrl_ptr p_def);
/** /**
* v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control. * v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control.
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment