drivers/media/platform/raspberrypi/rp1-cfe/csi2.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/raspberrypi/rp1-cfe/csi2.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/raspberrypi/rp1-cfe/csi2.c
Extension
.c
Size
16671 bytes
Lines
587
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

if (!cfe_fmt) {
			cfe_fmt = find_format_by_code(MEDIA_BUS_FMT_SRGGB10_1X10);
			format->format.code = cfe_fmt->code;
		}

		struct v4l2_mbus_framefmt *fmt;

		fmt = v4l2_subdev_state_get_format(state, format->pad,
						   format->stream);
		if (!fmt)
			return -EINVAL;

		*fmt = format->format;

		fmt = v4l2_subdev_state_get_opposite_stream_format(state,
								   format->pad,
								   format->stream);
		if (!fmt)
			return -EINVAL;

		format->format.field = V4L2_FIELD_NONE;

		*fmt = format->format;
	} else {
		/* Only allow changing the source pad mbus code. */

		struct v4l2_mbus_framefmt *sink_fmt, *source_fmt;
		u32 sink_code;
		u32 code;

		sink_fmt = v4l2_subdev_state_get_opposite_stream_format(state,
									format->pad,
									format->stream);
		if (!sink_fmt)
			return -EINVAL;

		source_fmt = v4l2_subdev_state_get_format(state, format->pad,
							  format->stream);
		if (!source_fmt)
			return -EINVAL;

		sink_code = sink_fmt->code;
		code = format->format.code;

		/*
		 * Only allow changing the mbus code to:
		 * - The sink's mbus code
		 * - The 16-bit version of the sink's mbus code
		 * - The compressed version of the sink's mbus code
		 */
		if (code == sink_code ||
		    code == cfe_find_16bit_code(sink_code) ||
		    code == cfe_find_compressed_code(sink_code))
			source_fmt->code = code;

		format->format.code = source_fmt->code;
	}

	return 0;
}

static int csi2_set_routing(struct v4l2_subdev *sd,
			    struct v4l2_subdev_state *state,
			    enum v4l2_subdev_format_whence which,
			    struct v4l2_subdev_krouting *routing)
{
	int ret;

	ret = v4l2_subdev_routing_validate(sd, routing,
					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 |
					   V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING);
	if (ret)
		return ret;

	/* Only stream ID 0 allowed on source pads */
	for (unsigned int i = 0; i < routing->num_routes; ++i) {
		const struct v4l2_subdev_route *route = &routing->routes[i];

		if (route->source_stream != 0)
			return -ENXIO;
	}

	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing,
					       &cfe_default_format);
	if (ret)
		return ret;

	return 0;
}

Annotation

Implementation Notes