This event is triggered whenever the 'flags' field changes.

Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>
---
 drivers/media/video/cx2341x.c    |   58 +++++++++++++++++++++++--------------
 drivers/media/video/saa7115.c    |    3 +-
 drivers/media/video/v4l2-ctrls.c |   38 ++++++++----------------
 include/linux/videodev2.h        |    8 +++++
 include/media/v4l2-ctrls.h       |   36 +++++++++++------------
 5 files changed, 76 insertions(+), 67 deletions(-)

diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 103ef6b..2781889 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -1307,6 +1307,12 @@ static int cx2341x_try_ctrl(struct v4l2_ctrl *ctrl)
        return 0;
 }
 
+static void cx2341x_activate(struct v4l2_ctrl *ctrl, bool activate)
+{
+       v4l2_ctrl_flags(ctrl, V4L2_CTRL_FLAG_INACTIVE,
+                       activate ? 0 : V4L2_CTRL_FLAG_INACTIVE);
+}
+
 static int cx2341x_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        static const int mpeg_stream_type[] = {
@@ -1380,10 +1386,10 @@ static int cx2341x_s_ctrl(struct v4l2_ctrl *ctrl)
                        int is_ac3 = hdl->audio_encoding->val ==
                                                V4L2_MPEG_AUDIO_ENCODING_AC3;
 
-                       v4l2_ctrl_activate(hdl->audio_ac3_bitrate, is_ac3);
-                       v4l2_ctrl_activate(hdl->audio_l2_bitrate, !is_ac3);
+                       cx2341x_activate(hdl->audio_ac3_bitrate, is_ac3);
+                       cx2341x_activate(hdl->audio_l2_bitrate, !is_ac3);
                }
-               v4l2_ctrl_activate(hdl->audio_mode_extension,
+               cx2341x_activate(hdl->audio_mode_extension,
                        hdl->audio_mode->val == 
V4L2_MPEG_AUDIO_MODE_JOINT_STEREO);
                if (cx2341x_neq(hdl->audio_sampling_freq) &&
                    hdl->ops && hdl->ops->s_audio_sampling_freq)
@@ -1413,9 +1419,9 @@ static int cx2341x_s_ctrl(struct v4l2_ctrl *ctrl)
                if (err)
                        return err;
 
-               v4l2_ctrl_activate(hdl->video_bitrate_mode,
+               cx2341x_activate(hdl->video_bitrate_mode,
                        hdl->video_encoding->val != 
V4L2_MPEG_VIDEO_ENCODING_MPEG_1);
-               v4l2_ctrl_activate(hdl->video_bitrate_peak,
+               cx2341x_activate(hdl->video_bitrate_peak,
                        hdl->video_bitrate_mode->val != 
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
                if (cx2341x_neq(hdl->video_encoding) &&
                    hdl->ops && hdl->ops->s_video_encoding)
@@ -1441,18 +1447,18 @@ static int cx2341x_s_ctrl(struct v4l2_ctrl *ctrl)
 
                active_filter = hdl->video_spatial_filter_mode->val !=
                                
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO;
-               v4l2_ctrl_activate(hdl->video_spatial_filter, active_filter);
-               v4l2_ctrl_activate(hdl->video_luma_spatial_filter_type, 
active_filter);
-               v4l2_ctrl_activate(hdl->video_chroma_spatial_filter_type, 
active_filter);
+               cx2341x_activate(hdl->video_spatial_filter, active_filter);
+               cx2341x_activate(hdl->video_luma_spatial_filter_type, 
active_filter);
+               cx2341x_activate(hdl->video_chroma_spatial_filter_type, 
active_filter);
                active_filter = hdl->video_temporal_filter_mode->val !=
                                
V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO;
-               v4l2_ctrl_activate(hdl->video_temporal_filter, active_filter);
+               cx2341x_activate(hdl->video_temporal_filter, active_filter);
                active_filter = hdl->video_median_filter_type->val !=
                                V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF;
-               v4l2_ctrl_activate(hdl->video_luma_median_filter_bottom, 
active_filter);
-               v4l2_ctrl_activate(hdl->video_luma_median_filter_top, 
active_filter);
-               v4l2_ctrl_activate(hdl->video_chroma_median_filter_bottom, 
active_filter);
-               v4l2_ctrl_activate(hdl->video_chroma_median_filter_top, 
active_filter);
+               cx2341x_activate(hdl->video_luma_median_filter_bottom, 
active_filter);
+               cx2341x_activate(hdl->video_luma_median_filter_top, 
active_filter);
+               cx2341x_activate(hdl->video_chroma_median_filter_bottom, 
active_filter);
+               cx2341x_activate(hdl->video_chroma_median_filter_top, 
active_filter);
                return 0;
        }
 
@@ -1711,16 +1717,24 @@ int cx2341x_handler_setup(struct cx2341x_handler *cxhdl)
 }
 EXPORT_SYMBOL(cx2341x_handler_setup);
 
+static void cx2341x_grab(struct v4l2_ctrl *ctrl, bool busy)
+{
+       v4l2_ctrl_flags(ctrl, V4L2_CTRL_FLAG_GRABBED,
+                       busy ? V4L2_CTRL_FLAG_GRABBED : 0);
+}
+
 void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy)
 {
-       v4l2_ctrl_grab(cxhdl->audio_sampling_freq, busy);
-       v4l2_ctrl_grab(cxhdl->audio_encoding, busy);
-       v4l2_ctrl_grab(cxhdl->audio_l2_bitrate, busy);
-       v4l2_ctrl_grab(cxhdl->audio_ac3_bitrate, busy);
-       v4l2_ctrl_grab(cxhdl->stream_vbi_fmt, busy);
-       v4l2_ctrl_grab(cxhdl->stream_type, busy);
-       v4l2_ctrl_grab(cxhdl->video_bitrate_mode, busy);
-       v4l2_ctrl_grab(cxhdl->video_bitrate, busy);
-       v4l2_ctrl_grab(cxhdl->video_bitrate_peak, busy);
+       mutex_lock(&cxhdl->hdl.lock);
+       cx2341x_grab(cxhdl->audio_sampling_freq, busy);
+       cx2341x_grab(cxhdl->audio_encoding, busy);
+       cx2341x_grab(cxhdl->audio_l2_bitrate, busy);
+       cx2341x_grab(cxhdl->audio_ac3_bitrate, busy);
+       cx2341x_grab(cxhdl->stream_vbi_fmt, busy);
+       cx2341x_grab(cxhdl->stream_type, busy);
+       cx2341x_grab(cxhdl->video_bitrate_mode, busy);
+       cx2341x_grab(cxhdl->video_bitrate, busy);
+       cx2341x_grab(cxhdl->video_bitrate_peak, busy);
+       mutex_unlock(&cxhdl->hdl.lock);
 }
 EXPORT_SYMBOL(cx2341x_handler_set_busy);
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 0db9092..ae4b299 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -793,7 +793,8 @@ static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
                        saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, 
state->gain->val);
                else
                        saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, 
state->gain->val | 0x80);
-               v4l2_ctrl_activate(state->gain, !state->agc->val);
+               v4l2_ctrl_flags(state->gain, V4L2_CTRL_FLAG_INACTIVE,
+                               state->agc->val ? V4L2_CTRL_FLAG_INACTIVE : 0);
                break;
 
        default:
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 163f412..122c6da 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -1205,40 +1205,28 @@ void v4l2_ctrl_cluster(unsigned ncontrols, struct 
v4l2_ctrl **controls)
 }
 EXPORT_SYMBOL(v4l2_ctrl_cluster);
 
-/* Activate/deactivate a control. */
-void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active)
+void v4l2_ctrl_flags(struct v4l2_ctrl *ctrl, u32 clear_flags, u32 set_flags)
 {
+       struct v4l2_event ev;
+
        if (ctrl == NULL)
                return;
-
-       if (!active)
-               /* set V4L2_CTRL_FLAG_INACTIVE */
-               set_bit(4, &ctrl->flags);
-       else
-               /* clear V4L2_CTRL_FLAG_INACTIVE */
-               clear_bit(4, &ctrl->flags);
+       ctrl->flags = (ctrl->flags & ~clear_flags) | set_flags;
+       ev.u.ctrl_ch_state.flags = ctrl->flags;
+       ev.type = V4L2_EVENT_CTRL_CH_STATE;
+       send_event(ctrl, &ev);
 }
-EXPORT_SYMBOL(v4l2_ctrl_activate);
-
-/* Grab/ungrab a control.
-   Typically used when streaming starts and you want to grab controls,
-   preventing the user from changing them.
+EXPORT_SYMBOL(v4l2_ctrl_flags);
 
-   Just call this and the framework will block any attempts to change
-   these controls. */
-void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
+void v4l2_ctrl_flags_lock(struct v4l2_ctrl *ctrl, u32 clear_flags, u32 
set_flags)
 {
        if (ctrl == NULL)
                return;
-
-       if (grabbed)
-               /* set V4L2_CTRL_FLAG_GRABBED */
-               set_bit(1, &ctrl->flags);
-       else
-               /* clear V4L2_CTRL_FLAG_GRABBED */
-               clear_bit(1, &ctrl->flags);
+       v4l2_ctrl_lock(ctrl);
+       v4l2_ctrl_flags(ctrl, clear_flags, set_flags);
+       v4l2_ctrl_unlock(ctrl);
 }
-EXPORT_SYMBOL(v4l2_ctrl_grab);
+EXPORT_SYMBOL(v4l2_ctrl_flags_lock);
 
 /* Log the control name and value */
 static void log_ctrl(const struct v4l2_ctrl *ctrl,
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index f7238c1..eb56685 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1788,6 +1788,7 @@ struct v4l2_streamparm {
 #define V4L2_EVENT_VSYNC                       1
 #define V4L2_EVENT_EOS                         2
 #define V4L2_EVENT_CTRL_CH_VALUE               3
+#define V4L2_EVENT_CTRL_CH_STATE               4
 #define V4L2_EVENT_PRIVATE_START               0x08000000
 
 /* Payload for V4L2_EVENT_VSYNC */
@@ -1805,11 +1806,18 @@ struct v4l2_event_ctrl_ch_value {
        };
 } __attribute__ ((packed));
 
+/* Payload for V4L2_EVENT_CTRL_CH_STATE */
+struct v4l2_event_ctrl_ch_state {
+       __u32 type;
+       __u32 flags;
+} __attribute__ ((packed));
+
 struct v4l2_event {
        __u32                           type;
        union {
                struct v4l2_event_vsync vsync;
                struct v4l2_event_ctrl_ch_value ctrl_ch_value;
+               struct v4l2_event_ctrl_ch_state ctrl_ch_state;
                __u8                    data[64];
        } u;
        __u32                           pending;
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 7ca45a5..e6917f4 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -379,32 +379,30 @@ void v4l2_ctrl_cluster(unsigned ncontrols, struct 
v4l2_ctrl **controls);
   */
 struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id);
 
-/** v4l2_ctrl_activate() - Make the control active or inactive.
-  * @ctrl:     The control to (de)activate.
-  * @active:   True if the control should become active.
+/** v4l2_ctrl_flags() - Clear and set flags for a control.
+  * @ctrl:     The control whose flags should be changed.
+  * @clear_flags:      Mask out these flags.
+  * @set_flags:        Set these flags.
   *
-  * 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.
+  * This clears and sets flags. Does nothing if @ctrl == NULL.
+  * The V4L2_EVENT_CTRL_CH_STATE event will be generated afterwards.
   *
-  * This function can be called regardless of whether the control handler
-  * is locked or not.
+  * This function expects that the control handler is locked.
   */
-void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
+void v4l2_ctrl_flags(struct v4l2_ctrl *ctrl, u32 clear_flags, u32 set_flags);
 
-/** v4l2_ctrl_grab() - Mark the control as grabbed or not grabbed.
-  * @ctrl:     The control to (de)activate.
-  * @grabbed:  True if the control should become grabbed.
+/** v4l2_ctrl_flags_lock() - Clear and set flags for a control.
+  * @ctrl:     The control whose flags should be changed.
+  * @clear_flags:      Mask out these flags.
+  * @set_flags:        Set these flags.
   *
-  * This sets or clears the V4L2_CTRL_FLAG_GRABBED flag atomically.
-  * Does nothing if @ctrl == NULL.
-  * This will usually be called when starting or stopping streaming in the
-  * driver.
+  * This clears and sets flags. Does nothing if @ctrl == NULL.
+  * The V4L2_EVENT_CTRL_CH_STATE event will be generated afterwards.
   *
-  * This function can be called regardless of whether the control handler
-  * is locked or not.
+  * This function expects that the control handler is unlocked and will lock
+  * it before changing flags.
   */
-void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
+void v4l2_ctrl_flags_lock(struct v4l2_ctrl *ctrl, u32 clear_flags, u32 
set_flags);
 
 /** v4l2_ctrl_lock() - Helper function to lock the handler
   * associated with the control.
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to