diff --git a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml
index 89891adb928a..820f86e8744b 100644
--- a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml
@@ -242,6 +242,22 @@
+
+ struct v4l2_event_src_change
+
+ &cs-str;
+
+
+ __u32
+ changes
+
+ A bitmask that tells what has changed. See .
+
+
+
+
+
+
Changes
@@ -270,6 +286,23 @@
+
+
+ Source Changes
+
+ &cs-def;
+
+
+ V4L2_EVENT_SRC_CH_RESOLUTION
+ 0x0001
+ This event gets triggered when a resolution change is
+ detected at an input. This can come from an input connector or
+ from a video decoder.
+
+
+
+
+
&return-value;
diff --git a/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml b/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
index 5c70b616d818..f016254377aa 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
@@ -154,6 +154,26 @@
frame interval in between them.
+
+ V4L2_EVENT_SOURCE_CHANGE
+ 5
+
+ This event is triggered when a source parameter change is
+ detected during runtime by the video device. It can be a
+ runtime resolution change triggered by a video decoder or the
+ format change happening on an input connector.
+ This event requires that the id
+ matches the input index (when used with a video device node)
+ or the pad index (when used with a subdevice node) from which
+ you want to receive events.
+
+ This event has a &v4l2-event-source-change; associated
+ with it. The changes bitfield denotes
+ what has changed for the subscribed pad. If multiple events
+ occurred before application could dequeue them, then the changes
+ will have the ORed value of all the events generated.
+
+
V4L2_EVENT_PRIVATE_START
0x08000000
diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c
index 86dcb5483c42..8761aab99de9 100644
--- a/drivers/media/v4l2-core/v4l2-event.c
+++ b/drivers/media/v4l2-core/v4l2-event.c
@@ -318,3 +318,39 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh,
return v4l2_event_unsubscribe(fh, sub);
}
EXPORT_SYMBOL_GPL(v4l2_event_subdev_unsubscribe);
+
+static void v4l2_event_src_replace(struct v4l2_event *old,
+ const struct v4l2_event *new)
+{
+ u32 old_changes = old->u.src_change.changes;
+
+ old->u.src_change = new->u.src_change;
+ old->u.src_change.changes |= old_changes;
+}
+
+static void v4l2_event_src_merge(const struct v4l2_event *old,
+ struct v4l2_event *new)
+{
+ new->u.src_change.changes |= old->u.src_change.changes;
+}
+
+static const struct v4l2_subscribed_event_ops v4l2_event_src_ch_ops = {
+ .replace = v4l2_event_src_replace,
+ .merge = v4l2_event_src_merge,
+};
+
+int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
+ return v4l2_event_subscribe(fh, sub, 0, &v4l2_event_src_ch_ops);
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(v4l2_src_change_event_subscribe);
+
+int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
+ struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
+{
+ return v4l2_src_change_event_subscribe(fh, sub);
+}
+EXPORT_SYMBOL_GPL(v4l2_src_change_event_subdev_subscribe);
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
index be05d019de25..1ab9045e52e3 100644
--- a/include/media/v4l2-event.h
+++ b/include/media/v4l2-event.h
@@ -132,4 +132,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
void v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh,
struct v4l2_event_subscription *sub);
+int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub);
+int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
+ struct v4l2_fh *fh, struct v4l2_event_subscription *sub);
#endif /* V4L2_EVENT_H */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index db4aebd8baba..00259d2baa10 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1764,6 +1764,7 @@ struct v4l2_streamparm {
#define V4L2_EVENT_EOS 2
#define V4L2_EVENT_CTRL 3
#define V4L2_EVENT_FRAME_SYNC 4
+#define V4L2_EVENT_SOURCE_CHANGE 5
#define V4L2_EVENT_PRIVATE_START 0x08000000
/* Payload for V4L2_EVENT_VSYNC */
@@ -1795,12 +1796,19 @@ struct v4l2_event_frame_sync {
__u32 frame_sequence;
};
+#define V4L2_EVENT_SRC_CH_RESOLUTION (1 << 0)
+
+struct v4l2_event_src_change {
+ __u32 changes;
+};
+
struct v4l2_event {
__u32 type;
union {
struct v4l2_event_vsync vsync;
struct v4l2_event_ctrl ctrl;
struct v4l2_event_frame_sync frame_sync;
+ struct v4l2_event_src_change src_change;
__u8 data[64];
} u;
__u32 pending;