drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
Extension
.c
Size
22934 bytes
Lines
862
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mxc_isi_m2m_buffer {
	struct v4l2_m2m_buffer buf;
	dma_addr_t dma_addrs[3];
};

struct mxc_isi_m2m_ctx_queue_data {
	struct v4l2_pix_format_mplane format;
	const struct mxc_isi_format_info *info;
	u32 sequence;
};

struct mxc_isi_m2m_ctx {
	struct v4l2_fh fh;
	struct mxc_isi_m2m *m2m;

	/* Protects the m2m vb2 queues */
	struct mutex vb2_lock;

	struct {
		struct mxc_isi_m2m_ctx_queue_data out;
		struct mxc_isi_m2m_ctx_queue_data cap;
	} queues;

	struct {
		struct v4l2_ctrl_handler handler;
		unsigned int alpha;
		bool hflip;
		bool vflip;
	} ctrls;

	bool chained;
};

static inline struct mxc_isi_m2m_buffer *
to_isi_m2m_buffer(struct vb2_v4l2_buffer *buf)
{
	return container_of(buf, struct mxc_isi_m2m_buffer, buf.vb);
}

static inline struct mxc_isi_m2m_ctx *file_to_isi_m2m_ctx(struct file *filp)
{
	return container_of(file_to_v4l2_fh(filp), struct mxc_isi_m2m_ctx, fh);
}

static inline struct mxc_isi_m2m_ctx_queue_data *
mxc_isi_m2m_ctx_qdata(struct mxc_isi_m2m_ctx *ctx, enum v4l2_buf_type type)
{
	if (V4L2_TYPE_IS_OUTPUT(type))
		return &ctx->queues.out;
	else
		return &ctx->queues.cap;
}

/* -----------------------------------------------------------------------------
 * V4L2 M2M device operations
 */

static void mxc_isi_m2m_frame_write_done(struct mxc_isi_pipe *pipe, u32 status)
{
	struct mxc_isi_m2m *m2m = &pipe->isi->m2m;
	struct vb2_v4l2_buffer *src_vbuf, *dst_vbuf;
	struct mxc_isi_m2m_ctx *ctx;

	ctx = v4l2_m2m_get_curr_priv(m2m->m2m_dev);
	if (!ctx) {
		dev_err(m2m->isi->dev,
			"Instance released before the end of transaction\n");
		return;
	}

	src_vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
	dst_vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);

	v4l2_m2m_buf_copy_metadata(src_vbuf, dst_vbuf);

	src_vbuf->sequence = ctx->queues.out.sequence++;
	dst_vbuf->sequence = ctx->queues.cap.sequence++;

	v4l2_m2m_buf_done(src_vbuf, VB2_BUF_STATE_DONE);
	v4l2_m2m_buf_done(dst_vbuf, VB2_BUF_STATE_DONE);

	v4l2_m2m_job_finish(m2m->m2m_dev, ctx->fh.m2m_ctx);
}

static void mxc_isi_m2m_device_run(void *priv)
{
	struct mxc_isi_m2m_ctx *ctx = priv;
	struct mxc_isi_m2m *m2m = ctx->m2m;
	struct vb2_v4l2_buffer *src_vbuf, *dst_vbuf;
	struct mxc_isi_m2m_buffer *src_buf, *dst_buf;

Annotation

Implementation Notes