Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d0360a4 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] v4l2-ctrls: add support for setting string controls



Rather than always having to use a v4l2_ext_control struct to set
a control value from within a driver, switch to just setting the
new value. This is faster and it makes it possible to set more
complex types such as a string control as is added by this
patch.

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 592d1349
Loading
Loading
Loading
Loading
+20 −27
Original line number Diff line number Diff line
@@ -3121,26 +3121,22 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
	struct v4l2_ctrl *master = ctrl->cluster[0];
	int i;

	/* Compound controls are not supported. The user_to_new() and
	 * cur_to_user() calls below would need to be modified not to access
	 * userspace memory when called from set_ctrl().
	 */
	if (ctrl->is_ptr)
		return -EINVAL;

	/* Reset the 'is_new' flags of the cluster */
	for (i = 0; i < master->ncontrols; i++)
		if (master->cluster[i])
			master->cluster[i]->is_new = 0;

	if (c)
		user_to_new(c, ctrl);

	/* For autoclusters with volatiles that are switched from auto to
	   manual mode we have to update the current volatile values since
	   those will become the initial manual values after such a switch. */
	if (master->is_auto && master->has_volatiles && ctrl == master &&
	    !is_cur_manual(master) && c->value == master->manual_mode_value)
	    !is_cur_manual(master) && ctrl->val == master->manual_mode_value)
		update_from_auto_cluster(master);

	user_to_new(c, ctrl);
	ctrl->is_new = 1;
	return try_or_set_cluster(fh, master, true, ch_flags);
}

@@ -3188,40 +3184,37 @@ EXPORT_SYMBOL(v4l2_subdev_s_ctrl);

int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
{
	struct v4l2_ext_control c;
	int rval;

	lockdep_assert_held(ctrl->handler->lock);

	/* It's a driver bug if this happens. */
	WARN_ON(!ctrl->is_int);
	c.value = val;
	rval = set_ctrl(NULL, ctrl, &c, 0);
	if (!rval)
		cur_to_user(&c, ctrl);

	return rval;
	ctrl->val = val;
	return set_ctrl(NULL, ctrl, NULL, 0);
}
EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl);

int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
{
	struct v4l2_ext_control c;
	int rval;

	lockdep_assert_held(ctrl->handler->lock);

	/* It's a driver bug if this happens. */
	WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
	c.value64 = val;
	rval = set_ctrl(NULL, ctrl, &c, 0);
	if (!rval)
		cur_to_user(&c, ctrl);

	return rval;
	*ctrl->p_new.p_s64 = val;
	return set_ctrl(NULL, ctrl, NULL, 0);
}
EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64);

int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
{
	lockdep_assert_held(ctrl->handler->lock);

	/* It's a driver bug if this happens. */
	WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING);
	strlcpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);
	return set_ctrl(NULL, ctrl, NULL, 0);
}
EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);

void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
{
	if (ctrl == NULL)
+24 −0
Original line number Diff line number Diff line
@@ -737,6 +737,30 @@ static inline int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
	return rval;
}

/** __v4l2_ctrl_s_ctrl_string() - Unlocked variant of v4l2_ctrl_s_ctrl_string(). */
int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s);

/** v4l2_ctrl_s_ctrl_string() - Helper function to set a control's string value from within a driver.
  * @ctrl:	The control.
  * @s:		The new string.
  *
  * This set the control's new string safely by going through the control
  * framework. This function will lock the control's handler, so it cannot be
  * used from within the &v4l2_ctrl_ops functions.
  *
  * This function is for string type controls only.
  */
static inline int v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
{
	int rval;

	v4l2_ctrl_lock(ctrl);
	rval = __v4l2_ctrl_s_ctrl_string(ctrl, s);
	v4l2_ctrl_unlock(ctrl);

	return rval;
}

/* 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);