This event is triggered whenever the 'flags' field changes.
Signed-off-by: Hans Verkuil <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html