Add frame sync event for video capture device. Signed-off-by: Changhuang Liang <changhuang.liang@xxxxxxxxxxxxxxxx> --- .../staging/media/starfive/camss/stf-capture.c | 9 +++++++++ drivers/staging/media/starfive/camss/stf-video.c | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/staging/media/starfive/camss/stf-capture.c index 6a137a273c8a..d0be769da11b 100644 --- a/drivers/staging/media/starfive/camss/stf-capture.c +++ b/drivers/staging/media/starfive/camss/stf-capture.c @@ -7,6 +7,7 @@ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd. */ +#include <media/v4l2-event.h> #include "stf-camss.h" static const char * const stf_cap_names[] = { @@ -430,10 +431,15 @@ static void stf_buf_flush(struct stf_v_buf *output, enum vb2_buffer_state state) static void stf_buf_done(struct stf_v_buf *output) { + struct stf_capture *cap = container_of(output, struct stf_capture, + buffers); struct stfcamss_buffer *ready_buf; struct stfcamss *stfcamss = cap->video.stfcamss; u64 ts = ktime_get_ns(); unsigned long flags; + struct v4l2_event event = { + .type = V4L2_EVENT_FRAME_SYNC, + }; if (output->state == STF_OUTPUT_OFF || output->state == STF_OUTPUT_RESERVED) @@ -445,6 +451,9 @@ static void stf_buf_done(struct stf_v_buf *output) if (cap->type == STF_CAPTURE_SCD) stf_isp_fill_yhist(stfcamss, ready_buf->vaddr_sc); + event.u.frame_sync.frame_sequence = output->sequence; + v4l2_event_queue(&cap->video.vdev, &event); + ready_buf->vb.vb2_buf.timestamp = ts; ready_buf->vb.sequence = output->sequence++; diff --git a/drivers/staging/media/starfive/camss/stf-video.c b/drivers/staging/media/starfive/camss/stf-video.c index 54d855ba0b57..32381e9ad049 100644 --- a/drivers/staging/media/starfive/camss/stf-video.c +++ b/drivers/staging/media/starfive/camss/stf-video.c @@ -507,6 +507,17 @@ static int video_try_fmt(struct file *file, void *fh, struct v4l2_format *f) return __video_try_fmt(video, f); } +static int video_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_FRAME_SYNC: + return v4l2_event_subscribe(fh, sub, 0, NULL); + default: + return -EINVAL; + } +} + static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = { .vidioc_querycap = video_querycap, .vidioc_enum_fmt_vid_cap = video_enum_fmt, @@ -523,6 +534,8 @@ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = { .vidioc_prepare_buf = vb2_ioctl_prepare_buf, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_subscribe_event = video_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static int video_scd_g_fmt(struct file *file, void *fh, struct v4l2_format *f) @@ -554,6 +567,8 @@ static const struct v4l2_ioctl_ops stf_vid_scd_ioctl_ops = { .vidioc_prepare_buf = vb2_ioctl_prepare_buf, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_subscribe_event = video_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; /* ----------------------------------------------------------------------------- -- 2.25.1