diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-09-07 03:46:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-01-04 21:49:54 -0500 |
commit | 8ac7a9493a4380a8a886fbfe311ab00bc424ca0f (patch) | |
tree | 25f60268aad8cf9f45c44b1ef7e8a2f30e506952 | |
parent | 20deebfe17b20ded00ba404adbcd014eb2b024c1 (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.txt | 22 | ||||
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ctrls.c | 18 | ||||
-rw-r--r-- | include/media/v4l2-ctrls.h | 25 |
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 | |||
715 | class is added. | 715 | class is added. |
716 | 716 | ||
717 | 717 | ||
718 | Proposals for Extensions | 718 | Adding Notify Callbacks |
719 | ======================== | 719 | ======================= |
720 | |||
721 | Sometimes the platform or bridge driver needs to be notified when a control | ||
722 | from a sub-device driver changes. You can set a notify callback by calling | ||
723 | this function: | ||
720 | 724 | ||
721 | Some ideas for future extensions to the spec: | 725 | void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, |
726 | void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv); | ||
722 | 727 | ||
723 | 1) Add a V4L2_CTRL_FLAG_HEX to have values shown as hexadecimal instead of | 728 | Whenever the give control changes value the notify callback will be called |
724 | decimal. Useful for e.g. video_mute_yuv. | 729 | with a pointer to the control and the priv pointer that was passed with |
730 | v4l2_ctrl_notify. Note that the control's handler lock is held when the | ||
731 | notify function is called. | ||
725 | 732 | ||
726 | 2) It is possible to mark in the controls array which controls have been | 733 | There can be only one notify function per control handler. Any attempt |
727 | successfully written and which failed by for example adding a bit to the | 734 | to set another notify function will cause a WARN_ON. |
728 | control 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 | } |
2726 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64); | 2728 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64); |
2727 | 2729 | ||
2730 | void 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 | } | ||
2744 | EXPORT_SYMBOL(v4l2_ctrl_notify); | ||
2745 | |||
2728 | static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) | 2746 | static 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 | ||
56 | typedef 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 | */ | ||
551 | void 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 | * |