drivers/staging/media/imx/imx-media-csc-scaler.c

Source file repositories/reference/linux-study-clean/drivers/staging/media/imx/imx-media-csc-scaler.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/media/imx/imx-media-csc-scaler.c
Extension
.c
Size
24127 bytes
Lines
926
Domain
Driver Families
Bucket
drivers/staging
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 ipu_csc_scaler_priv {
	struct imx_media_video_dev	vdev;

	struct v4l2_m2m_dev		*m2m_dev;
	struct device			*dev;

	struct imx_media_dev		*md;

	struct mutex			mutex;	/* mem2mem device mutex */
};

#define vdev_to_priv(v) container_of(v, struct ipu_csc_scaler_priv, vdev)

/* Per-queue, driver-specific private data */
struct ipu_csc_scaler_q_data {
	struct v4l2_pix_format		cur_fmt;
	struct v4l2_rect		rect;
};

struct ipu_csc_scaler_ctx {
	struct ipu_csc_scaler_priv	*priv;

	struct v4l2_fh			fh;
	struct ipu_csc_scaler_q_data	q_data[2];
	struct ipu_image_convert_ctx	*icc;

	struct v4l2_ctrl_handler	ctrl_hdlr;
	int				rotate;
	bool				hflip;
	bool				vflip;
	enum ipu_rotate_mode		rot_mode;
	unsigned int			sequence;
};

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

static struct ipu_csc_scaler_q_data *get_q_data(struct ipu_csc_scaler_ctx *ctx,
						enum v4l2_buf_type type)
{
	if (V4L2_TYPE_IS_OUTPUT(type))
		return &ctx->q_data[V4L2_M2M_SRC];
	else
		return &ctx->q_data[V4L2_M2M_DST];
}

/*
 * mem2mem callbacks
 */

static void job_abort(void *_ctx)
{
	struct ipu_csc_scaler_ctx *ctx = _ctx;

	if (ctx->icc)
		ipu_image_convert_abort(ctx->icc);
}

static void ipu_ic_pp_complete(struct ipu_image_convert_run *run, void *_ctx)
{
	struct ipu_csc_scaler_ctx *ctx = _ctx;
	struct ipu_csc_scaler_priv *priv = ctx->priv;
	struct vb2_v4l2_buffer *src_buf, *dst_buf;

	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);

	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);

	src_buf->sequence = ctx->sequence++;
	dst_buf->sequence = src_buf->sequence;

	v4l2_m2m_buf_done(src_buf, run->status ? VB2_BUF_STATE_ERROR :
						 VB2_BUF_STATE_DONE);
	v4l2_m2m_buf_done(dst_buf, run->status ? VB2_BUF_STATE_ERROR :
						 VB2_BUF_STATE_DONE);

	v4l2_m2m_job_finish(priv->m2m_dev, ctx->fh.m2m_ctx);
	kfree(run);
}

static void device_run(void *_ctx)
{
	struct ipu_csc_scaler_ctx *ctx = _ctx;
	struct ipu_csc_scaler_priv *priv = ctx->priv;
	struct vb2_v4l2_buffer *src_buf, *dst_buf;
	struct ipu_image_convert_run *run;
	int ret;

Annotation

Implementation Notes