drivers/media/common/v4l2-tpg/v4l2-tpg-core.c

Source file repositories/reference/linux-study-clean/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c

File Facts

System
Linux kernel
Corpus path
drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
Extension
.c
Size
77811 bytes
Lines
2733
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 tpg_draw_params {
	/* common data */
	bool is_tv;
	bool is_60hz;
	unsigned twopixsize;
	unsigned img_width;
	unsigned stride;
	unsigned hmax;
	unsigned frame_line;
	unsigned frame_line_next;

	/* test pattern */
	unsigned mv_hor_old;
	unsigned mv_hor_new;
	unsigned mv_vert_old;
	unsigned mv_vert_new;

	/* extras */
	unsigned wss_width;
	unsigned wss_random_offset;
	unsigned sav_eav_f;
	unsigned left_pillar_width;
	unsigned right_pillar_start;
};

static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
				    struct tpg_draw_params *params)
{
	params->mv_hor_old =
		tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
	params->mv_hor_new =
		tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
			       tpg->src_width);
	params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
	params->mv_vert_new =
		(tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
}

static void tpg_fill_params_extras(const struct tpg_data *tpg,
				   unsigned p,
				   struct tpg_draw_params *params)
{
	unsigned left_pillar_width = 0;
	unsigned right_pillar_start = params->img_width;

	params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
		tpg->src_width / 2 - tpg->crop.left : 0;
	if (params->wss_width > tpg->crop.width)
		params->wss_width = tpg->crop.width;
	params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
	params->wss_random_offset =
		params->twopixsize * get_random_u32_below(tpg->src_width / 2);

	if (tpg->crop.left < tpg->border.left) {
		left_pillar_width = tpg->border.left - tpg->crop.left;
		if (left_pillar_width > tpg->crop.width)
			left_pillar_width = tpg->crop.width;
		left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
	}
	params->left_pillar_width = left_pillar_width;

	if (tpg->crop.left + tpg->crop.width >
	    tpg->border.left + tpg->border.width) {
		right_pillar_start =
			tpg->border.left + tpg->border.width - tpg->crop.left;
		right_pillar_start =
			tpg_hscale_div(tpg, p, right_pillar_start);
		if (right_pillar_start > params->img_width)
			right_pillar_start = params->img_width;
	}
	params->right_pillar_start = right_pillar_start;

	params->sav_eav_f = tpg->field ==
			(params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
}

static void tpg_fill_plane_extras(const struct tpg_data *tpg,
				  const struct tpg_draw_params *params,
				  unsigned p, unsigned h, u8 *vbuf)
{
	unsigned twopixsize = params->twopixsize;
	unsigned img_width = params->img_width;
	unsigned frame_line = params->frame_line;
	const struct v4l2_rect *sq = &tpg->square;
	const struct v4l2_rect *b = &tpg->border;
	const struct v4l2_rect *c = &tpg->crop;

	if (params->is_tv && !params->is_60hz &&
	    frame_line == 0 && params->wss_width) {
		/*

Annotation

Implementation Notes