Commit bda8f2f1 authored by Hans Verkuil's avatar Hans Verkuil
Browse files

Merge tag 'tags/media-next-imx-20240419' of...

Merge tag 'tags/media-next-imx-20240419' of git://git.kernel.org/pub/scm/linux/kernel/git/pinchartl/linux.git

 into media_stage

NXP media drivers improvements.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.linuxtv.org/project/linux-media/patch/20240419103822.GA6868@pendragon.ideasonboard.com/
parents 836e2548 459a5cb1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ allOf:
          properties:
            port@0:
              description: MIPI CSI-2 RX
            port@1: false
          required:
            - port@0

+33 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#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>
@@ -742,6 +743,18 @@ static void mipi_csis_stop_stream(struct mipi_csis_device *csis)
	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;
@@ -765,6 +778,10 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *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);
@@ -1154,8 +1171,23 @@ static int mipi_csis_log_status(struct v4l2_subdev *sd)
	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 = {
@@ -1358,7 +1390,7 @@ static int mipi_csis_subdev_init(struct mipi_csis_device *csis)
	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;