]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - include/media/v4l2-ctrls.h
[media] v4l2-ctrls: make manual_mode_value 8 bits and check against control range
[mirror_ubuntu-zesty-kernel.git] / include / media / v4l2-ctrls.h
index 97d063837b61fb48b315d04da9096375480772f8..8f08c6edf5093bf061444e657e0c8307acb467ee 100644 (file)
@@ -30,6 +30,8 @@ struct v4l2_ctrl_handler;
 struct v4l2_ctrl;
 struct video_device;
 struct v4l2_subdev;
+struct v4l2_event_subscription;
+struct v4l2_fh;
 
 /** struct v4l2_ctrl_ops - The control operations that the driver has to provide.
   * @g_volatile_ctrl: Get a new value for this control. Generally only relevant
@@ -65,6 +67,15 @@ struct v4l2_ctrl_ops {
   *            control's current value cannot be cached and needs to be
   *            retrieved through the g_volatile_ctrl op. Drivers can set
   *            this flag.
+  * @is_auto:   If set, then this control selects whether the other cluster
+  *            members are in 'automatic' mode or 'manual' mode. This is
+  *            used for autogain/gain type clusters. Drivers should never
+  *            set this flag directly.
+  * @manual_mode_value: If the is_auto flag is set, then this is the value
+  *            of the auto control that determines if that control is in
+  *            manual mode. So if the value of the auto control equals this
+  *            value, then the whole cluster is in manual mode. Drivers should
+  *            never set this flag directly.
   * @ops:      The control ops.
   * @id:       The control ID.
   * @name:     The control name.
@@ -97,6 +108,7 @@ struct v4l2_ctrl_ops {
 struct v4l2_ctrl {
        /* Administrative fields */
        struct list_head node;
+       struct list_head fhs;
        struct v4l2_ctrl_handler *handler;
        struct v4l2_ctrl **cluster;
        unsigned ncontrols;
@@ -105,6 +117,8 @@ struct v4l2_ctrl {
        unsigned int is_new:1;
        unsigned int is_private:1;
        unsigned int is_volatile:1;
+       unsigned int is_auto:1;
+       unsigned int manual_mode_value:8;
 
        const struct v4l2_ctrl_ops *ops;
        u32 id;
@@ -155,6 +169,7 @@ struct v4l2_ctrl_ref {
   *            control is needed multiple times, so this is a simple
   *            optimization.
   * @buckets:  Buckets for the hashing. Allows for quick control lookup.
+  * @nr_of_refs: Total number of control references in the list.
   * @nr_of_buckets: Total number of buckets in the array.
   * @error:    The error code of the first failed control addition.
   */
@@ -164,10 +179,16 @@ struct v4l2_ctrl_handler {
        struct list_head ctrl_refs;
        struct v4l2_ctrl_ref *cached;
        struct v4l2_ctrl_ref **buckets;
+       u16 nr_of_refs;
        u16 nr_of_buckets;
        int error;
 };
 
+struct v4l2_ctrl_fh {
+       struct list_head node;
+       struct v4l2_fh *fh;
+};
+
 /** struct v4l2_ctrl_config - Control configuration structure.
   * @ops:      The control ops.
   * @id:       The control ID.
@@ -363,6 +384,40 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
 void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls);
 
 
+/** v4l2_ctrl_auto_cluster() - Mark all controls in the cluster as belonging to
+  * that cluster and set it up for autofoo/foo-type handling.
+  * @ncontrols:        The number of controls in this cluster.
+  * @controls: The cluster control array of size @ncontrols. The first control
+  *            must be the 'auto' control (e.g. autogain, autoexposure, etc.)
+  * @manual_val: The value for the first control in the cluster that equals the
+  *            manual setting.
+  * @set_volatile: If true, then all controls except the first auto control will
+  *            have is_volatile set to true. If false, then is_volatile will not
+  *            be touched.
+  *
+  * Use for control groups where one control selects some automatic feature and
+  * the other controls are only active whenever the automatic feature is turned
+  * off (manual mode). Typical examples: autogain vs gain, auto-whitebalance vs
+  * red and blue balance, etc.
+  *
+  * The behavior of such controls is as follows:
+  *
+  * When the autofoo control is set to automatic, then any manual controls
+  * are set to inactive and any reads will call g_volatile_ctrl (if the control
+  * was marked volatile).
+  *
+  * When the autofoo control is set to manual, then any manual controls will
+  * be marked active, and any reads will just return the current value without
+  * going through g_volatile_ctrl.
+  *
+  * In addition, this function will set the V4L2_CTRL_FLAG_UPDATE flag
+  * on the autofoo control and V4L2_CTRL_FLAG_INACTIVE on the foo control(s)
+  * if autofoo is in auto mode.
+  */
+void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
+                       u8 manual_val, bool set_volatile);
+
+
 /** v4l2_ctrl_find() - Find a control with the given ID.
   * @hdl:      The control handler.
   * @id:       The control ID to find.
@@ -379,9 +434,9 @@ struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id);
   * This sets or clears the V4L2_CTRL_FLAG_INACTIVE flag atomically.
   * Does nothing if @ctrl == NULL.
   * This will usually be called from within the s_ctrl op.
+  * The V4L2_EVENT_CTRL event will be generated afterwards.
   *
-  * This function can be called regardless of whether the control handler
-  * is locked or not.
+  * This function assumes that the control handler is locked.
   */
 void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
 
@@ -391,11 +446,12 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
   *
   * This sets or clears the V4L2_CTRL_FLAG_GRABBED flag atomically.
   * Does nothing if @ctrl == NULL.
+  * The V4L2_EVENT_CTRL event will be generated afterwards.
   * This will usually be called when starting or stopping streaming in the
   * driver.
   *
-  * This function can be called regardless of whether the control handler
-  * is locked or not.
+  * This function assumes that the control handler is not locked and will
+  * take the lock itself.
   */
 void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
 
@@ -440,15 +496,39 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
   */
 int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
 
+/* Internal helper functions that deal with control events. */
+void v4l2_ctrl_add_fh(struct v4l2_ctrl_handler *hdl,
+               struct v4l2_ctrl_fh *ctrl_fh,
+               struct v4l2_event_subscription *sub);
+void v4l2_ctrl_del_fh(struct v4l2_ctrl *ctrl, struct v4l2_fh *fh);
+
+/** v4l2_ctrl_subscribe_fh() - Helper function that subscribes a control event.
+  * @fh:       The file handler that subscribed the control event.
+  * @sub:      The event to subscribe (type must be V4L2_EVENT_CTRL).
+  * @n:                How many events should be allocated? (Passed to v4l2_event_alloc).
+  *            Recommended to set to twice the number of controls plus whatever
+  *            is needed for other events. This function will set n to
+  *            max(n, 2 * fh->ctrl_handler->nr_of_refs).
+  *
+  * A helper function that initializes the fh for events, allocates the
+  * list of events and subscribes the control event.
+  *
+  * Typically called in the handler of VIDIOC_SUBSCRIBE_EVENT in the
+  * V4L2_EVENT_CTRL case.
+  */
+int v4l2_ctrl_subscribe_fh(struct v4l2_fh *fh,
+                       struct v4l2_event_subscription *sub, unsigned n);
 
 /* Helpers for ioctl_ops. If hdl == NULL then they will all return -EINVAL. */
 int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc);
 int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm);
 int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl);
-int v4l2_s_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl);
+int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+                                               struct v4l2_control *ctrl);
 int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
 int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
-int v4l2_s_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
+int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+                                               struct v4l2_ext_controls *c);
 
 /* Helpers for subdevices. If the associated ctrl_handler == NULL then they
    will all return -EINVAL. */