drivers/media/platform/renesas/vsp1/vsp1_brx.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/renesas/vsp1/vsp1_brx.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/renesas/vsp1/vsp1_brx.c
Extension
.c
Size
11717 bytes
Lines
441
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

scoped_guard(mutex, &brx->entity.lock) {
			sel->r = *v4l2_subdev_state_get_compose(state, sel->pad);
		}

		return 0;

	default:
		return -EINVAL;
	}
}

static int brx_set_selection(struct v4l2_subdev *subdev,
			     struct v4l2_subdev_state *sd_state,
			     struct v4l2_subdev_selection *sel)
{
	struct vsp1_brx *brx = to_brx(subdev);
	struct v4l2_subdev_state *state;
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *compose;

	if (sel->pad == brx->entity.source_pad)
		return -EINVAL;

	if (sel->target != V4L2_SEL_TGT_COMPOSE)
		return -EINVAL;

	guard(mutex)(&brx->entity.lock);

	state = vsp1_entity_get_state(&brx->entity, sd_state, sel->which);
	if (!state)
		return -EINVAL;

	/*
	 * The compose rectangle top left corner must be inside the output
	 * frame.
	 */
	format = v4l2_subdev_state_get_format(state, brx->entity.source_pad);
	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);

	/*
	 * Scaling isn't supported, the compose rectangle size must be identical
	 * to the sink format size.
	 */
	format = v4l2_subdev_state_get_format(state, sel->pad);
	sel->r.width = format->width;
	sel->r.height = format->height;

	compose = v4l2_subdev_state_get_compose(state, sel->pad);
	*compose = sel->r;

	return 0;
}

static const struct v4l2_subdev_pad_ops brx_pad_ops = {
	.enum_mbus_code = vsp1_subdev_enum_mbus_code,
	.enum_frame_size = brx_enum_frame_size,
	.get_fmt = vsp1_subdev_get_pad_format,
	.set_fmt = brx_set_format,
	.get_selection = brx_get_selection,
	.set_selection = brx_set_selection,
};

static const struct v4l2_subdev_ops brx_ops = {
	.core	= &vsp1_entity_core_ops,
	.pad    = &brx_pad_ops,
};

/* -----------------------------------------------------------------------------
 * VSP1 Entity Operations
 */

static void brx_configure_stream(struct vsp1_entity *entity,
				 struct v4l2_subdev_state *state,
				 struct vsp1_pipeline *pipe,
				 struct vsp1_dl_list *dl,
				 struct vsp1_dl_body *dlb)
{
	struct vsp1_brx *brx = to_brx(&entity->subdev);
	struct v4l2_mbus_framefmt *format;
	unsigned int flags;
	unsigned int i;

	format = v4l2_subdev_state_get_format(state, brx->entity.source_pad);

	/*
	 * The hardware is extremely flexible but we have no userspace API to
	 * expose all the parameters, nor is it clear whether we would have use
	 * cases for all the supported modes. Let's just hardcode the parameters
	 * to sane default values for now.

Annotation

Implementation Notes