[v2,09/16] v4l2-ctrls: add v4l2_ctrl_s_ctrl_ptr()

Message ID 20190403221501.32814-10-dafna3@gmail.com (mailing list archive)
State TODO, archived
Delegated to: Hans Verkuil
Headers

Commit Message

Dafna Hirschfeld April 3, 2019, 10:14 p.m. UTC
  From: Hans Verkuil <hverkuil@xs4all.nl>

Add a function to set a compound control by passing a pointer to the
new data.

Functions to set other control types already existed, but not for this.

This is needed for stateless encoders.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 11 ++++++++
 include/media/v4l2-ctrls.h           | 42 ++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)
  

Patch

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index b1ae2e555c68..c6e8f5838b65 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -3855,6 +3855,17 @@  int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
 }
 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
 
+int __v4l2_ctrl_s_ctrl_ptr(struct v4l2_ctrl *ctrl, const void *ptr)
+{
+	lockdep_assert_held(ctrl->handler->lock);
+
+	/* It's a driver bug if this happens. */
+	WARN_ON(!ctrl->is_ptr);
+	memcpy(ctrl->p_new.p, ptr, ctrl->elems * ctrl->elem_size);
+	return set_ctrl(NULL, ctrl, 0);
+}
+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_ptr);
+
 void v4l2_ctrl_request_complete(struct media_request *req,
 				struct v4l2_ctrl_handler *main_hdl)
 {
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index bd621cec65a5..87c4ade17e22 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -1060,6 +1060,48 @@  static inline int v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
 	return rval;
 }
 
+/**
+ * __v4l2_ctrl_s_ctrl_ptr() - Unlocked variant of v4l2_ctrl_s_ctrl_ptr().
+ *
+ * @ctrl:	The control.
+ * @ptr:	Pointer to the new control contents.
+ *
+ * This sets the control's new content safely by going through the control
+ * framework. This function assumes the control's handler is already locked,
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for pointer type controls only and will memcpy()
+ * @ctrl->elems * @ctrl->elem_size bytes from @ptr to the internal
+ * control data.
+ */
+int __v4l2_ctrl_s_ctrl_ptr(struct v4l2_ctrl *ctrl, const void *ptr);
+
+/**
+ * v4l2_ctrl_s_ctrl_ptr() - Helper function to set a control's string value
+ *	 from within a driver.
+ *
+ * @ctrl:	The control.
+ * @ptr:	Pointer to the new control contents.
+ *
+ * This sets the control's new content 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 pointer type controls only and will memcpy()
+ * @ctrl->elems * @ctrl->elem_size bytes from @ptr to the internal
+ * control data.
+ */
+static inline int v4l2_ctrl_s_ctrl_ptr(struct v4l2_ctrl *ctrl, const void *ptr)
+{
+	int rval;
+
+	v4l2_ctrl_lock(ctrl);
+	rval = __v4l2_ctrl_s_ctrl_ptr(ctrl, ptr);
+	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;