]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: rcar-vin: Generate FRAME_SYNC events
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Mon, 16 Jun 2025 18:57:22 +0000 (20:57 +0200)
committerHans Verkuil <hverkuil@xs4all.nl>
Wed, 18 Jun 2025 07:20:45 +0000 (09:20 +0200)
Enable the VSYNC Rising Edge Detection interrupt and generate a
FRAME_SYNC event form it. The interrupt is available on all supported
models of the VIN (Gen2, Gen3 and Gen4).

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Link: https://lore.kernel.org/r/20250616185722.980722-4-niklas.soderlund+renesas@ragnatech.se
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
drivers/media/platform/renesas/rcar-vin/rcar-dma.c
drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c

index 19ff190f0fb2058c14b7032a7196a10adaea022d..b619d1436a41512aeeb599b35091092faaa4d87c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 
+#include <media/v4l2-event.h>
 #include <media/videobuf2-dma-contig.h>
 
 #include "rcar-vin.h"
 #define VNFC_S_FRAME           (1 << 0)
 
 /* Video n Interrupt Enable Register bits */
+#define VNIE_VFE               BIT(17)
+#define VNIE_VRE               BIT(16)
 #define VNIE_FIE               BIT(4)
 #define VNIE_EFE               BIT(1)
 
 /* Video n Interrupt Status Register bits */
+#define VNINTS_VFS             BIT(17)
+#define VNINTS_VRS             BIT(16)
 #define VNINTS_FIS             BIT(4)
 #define VNINTS_EFS             BIT(1)
 
@@ -889,6 +894,8 @@ static int rvin_setup(struct rvin_dev *vin)
 
        /* Progressive or interlaced mode */
        interrupts = progressive ? VNIE_FIE : VNIE_EFE;
+       /* Enable VSYNC Rising Edge Detection. */
+       interrupts |= VNIE_VRE;
 
        /* Ack interrupts */
        rvin_write(vin, interrupts, VNINTS_REG);
@@ -1040,6 +1047,16 @@ static irqreturn_t rvin_irq(int irq, void *data)
        rvin_write(vin, status, VNINTS_REG);
        handled = 1;
 
+       /* Signal Start of Frame. */
+       if (status & VNINTS_VRS) {
+               struct v4l2_event event = {
+                       .type = V4L2_EVENT_FRAME_SYNC,
+                       .u.frame_sync.frame_sequence = vin->sequence,
+               };
+
+               v4l2_event_queue(&vin->vdev, &event);
+       }
+
        /* Nothing to do if nothing was captured. */
        capture = vin->format.field == V4L2_FIELD_NONE ||
                vin->format.field == V4L2_FIELD_ALTERNATE ?
index 9b1e3a9d3249b1af59a77ad5b63ecb78bce0cd51..62eddf3a35fc91434cb2e584a01819380a7a6dd8 100644 (file)
@@ -489,6 +489,8 @@ static int rvin_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, 2, NULL);
        case V4L2_EVENT_SOURCE_CHANGE:
                return v4l2_event_subscribe(fh, sub, 4, NULL);
        }