Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
8ac7a949 20deebfe

+57 -8
+14 -8
Documentation/video4linux/v4l2-controls.txt
··· 715 715 class is added. 716 716 717 717 718 - Proposals for Extensions 719 - ======================== 718 + Adding Notify Callbacks 719 + ======================= 720 720 721 - Some ideas for future extensions to the spec: 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: 722 724 723 - 1) Add a V4L2_CTRL_FLAG_HEX to have values shown as hexadecimal instead of 724 - decimal. Useful for e.g. video_mute_yuv. 725 + void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, 726 + void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv); 725 727 726 - 2) It is possible to mark in the controls array which controls have been 727 - successfully written and which failed by for example adding a bit to the 728 - control ID. Not sure if it is worth the effort, though. 728 + Whenever the give control changes value the notify callback will be called 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. 732 + 733 + There can be only one notify function per control handler. Any attempt 734 + to set another notify function will cause a WARN_ON.
+18
drivers/media/v4l2-core/v4l2-ctrls.c
··· 1204 1204 send_event(fh, ctrl, 1205 1205 (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | 1206 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 ··· 2726 2724 return set_ctrl(NULL, ctrl, &c); 2727 2725 } 2728 2726 EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64); 2727 + 2728 + void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv) 2729 + { 2730 + if (ctrl == NULL) 2731 + return; 2732 + if (notify == NULL) { 2733 + ctrl->call_notify = 0; 2734 + return; 2735 + } 2736 + if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify)) 2737 + return; 2738 + ctrl->handler->notify = notify; 2739 + ctrl->handler->notify_priv = priv; 2740 + ctrl->call_notify = 1; 2741 + } 2742 + EXPORT_SYMBOL(v4l2_ctrl_notify); 2729 2743 2730 2744 static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) 2731 2745 {
+25
include/media/v4l2-ctrls.h
··· 53 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 58 /** struct v4l2_ctrl - The control structure. 57 59 * @node: The list node. 58 60 * @ev_subs: The list of control event subscriptions. ··· 74 72 * set this flag directly. 75 73 * @has_volatiles: If set, then one or more members of the cluster are volatile. 76 74 * Drivers should never touch this flag. 75 + * @call_notify: If set, then call the handler's notify function whenever the 76 + * control's value changes. 77 77 * @manual_mode_value: If the is_auto flag is set, then this is the value 78 78 * of the auto control that determines if that control is in 79 79 * manual mode. So if the value of the auto control equals this ··· 123 119 unsigned int is_private:1; 124 120 unsigned int is_auto:1; 125 121 unsigned int has_volatiles:1; 122 + unsigned int call_notify:1; 126 123 unsigned int manual_mode_value:8; 127 124 128 125 const struct v4l2_ctrl_ops *ops; ··· 182 177 * control is needed multiple times, so this is a simple 183 178 * optimization. 184 179 * @buckets: Buckets for the hashing. Allows for quick control lookup. 180 + * @notify: A notify callback that is called whenever the control changes value. 181 + * Note that the handler's lock is held when the notify function 182 + * is called! 183 + * @notify_priv: Passed as argument to the v4l2_ctrl notify callback. 185 184 * @nr_of_buckets: Total number of buckets in the array. 186 185 * @error: The error code of the first failed control addition. 187 186 */ ··· 196 187 struct list_head ctrl_refs; 197 188 struct v4l2_ctrl_ref *cached; 198 189 struct v4l2_ctrl_ref **buckets; 190 + v4l2_ctrl_notify_fnc notify; 191 + void *notify_priv; 199 192 u16 nr_of_buckets; 200 193 int error; 201 194 }; ··· 535 524 { 536 525 mutex_unlock(ctrl->handler->lock); 537 526 } 527 + 528 + /** v4l2_ctrl_notify() - Function to set a notify callback for a control. 529 + * @ctrl: The control. 530 + * @notify: The callback function. 531 + * @priv: The callback private handle, passed as argument to the callback. 532 + * 533 + * This function sets a callback function for the control. If @ctrl is NULL, 534 + * then it will do nothing. If @notify is NULL, then the notify callback will 535 + * be removed. 536 + * 537 + * There can be only one notify. If another already exists, then a WARN_ON 538 + * will be issued and the function will do nothing. 539 + */ 540 + void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv); 538 541 539 542 /** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver. 540 543 * @ctrl: The control.