#include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
        mipi_csis_system_enable(csis, false);
 }
 
+static void mipi_csis_queue_event_sof(struct mipi_csis_device *csis)
+{
+       struct v4l2_event event = {
+               .type = V4L2_EVENT_FRAME_SYNC,
+       };
+       u32 frame;
+
+       frame = mipi_csis_read(csis, MIPI_CSIS_FRAME_COUNTER_CH(0));
+       event.u.frame_sync.frame_sequence = frame;
+       v4l2_event_queue(csis->sd.devnode, &event);
+}
+
 static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id)
 {
        struct mipi_csis_device *csis = dev_id;
                                event->counter++;
                }
        }
+
+       if (status & MIPI_CSIS_INT_SRC_FRAME_START)
+               mipi_csis_queue_event_sof(csis);
+
        spin_unlock_irqrestore(&csis->slock, flags);
 
        mipi_csis_write(csis, MIPI_CSIS_INT_SRC, status);
        return 0;
 }
 
+static int mipi_csis_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+                                    struct v4l2_event_subscription *sub)
+{
+       if (sub->type != V4L2_EVENT_FRAME_SYNC)
+               return -EINVAL;
+
+       /* V4L2_EVENT_FRAME_SYNC doesn't require an id, so zero should be set */
+       if (sub->id != 0)
+               return -EINVAL;
+
+       return v4l2_event_subscribe(fh, sub, 0, NULL);
+}
+
 static const struct v4l2_subdev_core_ops mipi_csis_core_ops = {
        .log_status     = mipi_csis_log_status,
+       .subscribe_event =  mipi_csis_subscribe_event,
+       .unsubscribe_event = v4l2_event_subdev_unsubscribe,
 };
 
 static const struct v4l2_subdev_video_ops mipi_csis_video_ops = {
        snprintf(sd->name, sizeof(sd->name), "csis-%s",
                 dev_name(csis->dev));
 
-       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
        sd->ctrl_handler = NULL;
 
        sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;