aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-09-07 03:46:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-04 21:49:54 -0500
commit8ac7a9493a4380a8a886fbfe311ab00bc424ca0f (patch)
tree25f60268aad8cf9f45c44b1ef7e8a2f30e506952
parent20deebfe17b20ded00ba404adbcd014eb2b024c1 (diff)
[media] v4l2-ctrls: add a notify callback
Sometimes platform/bridge drivers need to be notified when a control from a sub-device changes value. In order to support this a notify callback was added. [dheitmueller@kernellabs.com: fix merge conflict in v4l2-ctrls.c] Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--Documentation/video4linux/v4l2-controls.txt22
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c18
-rw-r--r--include/media/v4l2-ctrls.h25
3 files changed, 57 insertions, 8 deletions
diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt
index cfe52c798d74..676f87366025 100644
--- a/Documentation/video4linux/v4l2-controls.txt
+++ b/Documentation/video4linux/v4l2-controls.txt
@@ -715,14 +715,20 @@ a control of this type whenever the first control belonging to a new control
715class is added. 715class is added.
716 716
717 717
718Proposals for Extensions 718Adding Notify Callbacks
719======================== 719=======================
720
721Sometimes the platform or bridge driver needs to be notified when a control
722from a sub-device driver changes. You can set a notify callback by calling
723this function:
720 724
721Some ideas for future extensions to the spec: 725void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl,
726 void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv);
722 727
7231) Add a V4L2_CTRL_FLAG_HEX to have values shown as hexadecimal instead of 728Whenever the give control changes value the notify callback will be called
724decimal. Useful for e.g. video_mute_yuv. 729with a pointer to the control and the priv pointer that was passed with
730v4l2_ctrl_notify. Note that the control's handler lock is held when the
731notify function is called.
725 732
7262) It is possible to mark in the controls array which controls have been 733There can be only one notify function per control handler. Any attempt
727successfully written and which failed by for example adding a bit to the 734to set another notify function will cause a WARN_ON.
728control ID. Not sure if it is worth the effort, though.
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index f6ee201d9347..fa02363e7db4 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1204,6 +1204,8 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
1204 send_event(fh, ctrl, 1204 send_event(fh, ctrl,
1205 (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | 1205 (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) |
1206 (update_inactive ? V4L2_EVENT_CTRL_CH_FLAGS : 0)); 1206 (update_inactive ? V4L2_EVENT_CTRL_CH_FLAGS : 0));
1207 if (ctrl->call_notify && changed && ctrl->handler->notify)
1208 ctrl->handler->notify(ctrl, ctrl->handler->notify_priv);
1207 } 1209 }
1208} 1210}
1209 1211
@@ -2725,6 +2727,22 @@ int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
2725} 2727}
2726EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64); 2728EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64);
2727 2729
2730void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
2731{
2732 if (ctrl == NULL)
2733 return;
2734 if (notify == NULL) {
2735 ctrl->call_notify = 0;
2736 return;
2737 }
2738 if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify))
2739 return;
2740 ctrl->handler->notify = notify;
2741 ctrl->handler->notify_priv = priv;
2742 ctrl->call_notify = 1;
2743}
2744EXPORT_SYMBOL(v4l2_ctrl_notify);
2745
2728static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) 2746static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
2729{ 2747{
2730 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); 2748 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 96509119f28f..c4cc04136074 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -53,6 +53,8 @@ struct v4l2_ctrl_ops {
53 int (*s_ctrl)(struct v4l2_ctrl *ctrl); 53 int (*s_ctrl)(struct v4l2_ctrl *ctrl);
54}; 54};
55 55
56typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
57
56/** struct v4l2_ctrl - The control structure. 58/** struct v4l2_ctrl - The control structure.
57 * @node: The list node. 59 * @node: The list node.
58 * @ev_subs: The list of control event subscriptions. 60 * @ev_subs: The list of control event subscriptions.
@@ -72,6 +74,8 @@ struct v4l2_ctrl_ops {
72 * set this flag directly. 74 * set this flag directly.
73 * @has_volatiles: If set, then one or more members of the cluster are volatile. 75 * @has_volatiles: If set, then one or more members of the cluster are volatile.
74 * Drivers should never touch this flag. 76 * Drivers should never touch this flag.
77 * @call_notify: If set, then call the handler's notify function whenever the
78 * control's value changes.
75 * @manual_mode_value: If the is_auto flag is set, then this is the value 79 * @manual_mode_value: If the is_auto flag is set, then this is the value
76 * of the auto control that determines if that control is in 80 * of the auto control that determines if that control is in
77 * manual mode. So if the value of the auto control equals this 81 * manual mode. So if the value of the auto control equals this
@@ -119,6 +123,7 @@ struct v4l2_ctrl {
119 unsigned int is_private:1; 123 unsigned int is_private:1;
120 unsigned int is_auto:1; 124 unsigned int is_auto:1;
121 unsigned int has_volatiles:1; 125 unsigned int has_volatiles:1;
126 unsigned int call_notify:1;
122 unsigned int manual_mode_value:8; 127 unsigned int manual_mode_value:8;
123 128
124 const struct v4l2_ctrl_ops *ops; 129 const struct v4l2_ctrl_ops *ops;
@@ -177,6 +182,10 @@ struct v4l2_ctrl_ref {
177 * control is needed multiple times, so this is a simple 182 * control is needed multiple times, so this is a simple
178 * optimization. 183 * optimization.
179 * @buckets: Buckets for the hashing. Allows for quick control lookup. 184 * @buckets: Buckets for the hashing. Allows for quick control lookup.
185 * @notify: A notify callback that is called whenever the control changes value.
186 * Note that the handler's lock is held when the notify function
187 * is called!
188 * @notify_priv: Passed as argument to the v4l2_ctrl notify callback.
180 * @nr_of_buckets: Total number of buckets in the array. 189 * @nr_of_buckets: Total number of buckets in the array.
181 * @error: The error code of the first failed control addition. 190 * @error: The error code of the first failed control addition.
182 */ 191 */
@@ -187,6 +196,8 @@ struct v4l2_ctrl_handler {
187 struct list_head ctrl_refs; 196 struct list_head ctrl_refs;
188 struct v4l2_ctrl_ref *cached; 197 struct v4l2_ctrl_ref *cached;
189 struct v4l2_ctrl_ref **buckets; 198 struct v4l2_ctrl_ref **buckets;
199 v4l2_ctrl_notify_fnc notify;
200 void *notify_priv;
190 u16 nr_of_buckets; 201 u16 nr_of_buckets;
191 int error; 202 int error;
192}; 203};
@@ -525,6 +536,20 @@ static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
525 mutex_unlock(ctrl->handler->lock); 536 mutex_unlock(ctrl->handler->lock);
526} 537}
527 538
539/** v4l2_ctrl_notify() - Function to set a notify callback for a control.
540 * @ctrl: The control.
541 * @notify: The callback function.
542 * @priv: The callback private handle, passed as argument to the callback.
543 *
544 * This function sets a callback function for the control. If @ctrl is NULL,
545 * then it will do nothing. If @notify is NULL, then the notify callback will
546 * be removed.
547 *
548 * There can be only one notify. If another already exists, then a WARN_ON
549 * will be issued and the function will do nothing.
550 */
551void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv);
552
528/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver. 553/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.
529 * @ctrl: The control. 554 * @ctrl: The control.
530 * 555 *