drivers/media/platform/samsung/exynos4-is/fimc-isp.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/samsung/exynos4-is/fimc-isp.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/samsung/exynos4-is/fimc-isp.c
Extension
.c
Size
20401 bytes
Lines
788
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 (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
			mf->colorspace = V4L2_COLORSPACE_JPEG;
			mf->code = MEDIA_BUS_FMT_YUV10_1X30;
		}
	}

	mutex_unlock(&isp->subdev_lock);

	isp_dbg(1, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n", __func__,
		fmt->pad, mf->code, mf->width, mf->height);

	return 0;
}

static void __isp_subdev_try_format(struct fimc_isp *isp,
				    struct v4l2_subdev_state *sd_state,
				    struct v4l2_subdev_format *fmt)
{
	struct v4l2_mbus_framefmt *mf = &fmt->format;
	struct v4l2_mbus_framefmt *format;

	mf->colorspace = V4L2_COLORSPACE_SRGB;

	if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
		v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
				FIMC_ISP_SINK_WIDTH_MAX, 0,
				&mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
				FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
		mf->code = MEDIA_BUS_FMT_SGRBG10_1X10;
	} else {
		if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
			format = v4l2_subdev_state_get_format(sd_state,
							      FIMC_ISP_SD_PAD_SINK);
		else
			format = &isp->sink_fmt;

		/* Allow changing format only on sink pad */
		mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
		mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;

		if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
			mf->code = MEDIA_BUS_FMT_YUV10_1X30;
			mf->colorspace = V4L2_COLORSPACE_JPEG;
		} else {
			mf->code = format->code;
		}
	}
}

static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *sd_state,
				   struct v4l2_subdev_format *fmt)
{
	struct fimc_isp *isp = v4l2_get_subdevdata(sd);
	struct fimc_is *is = fimc_isp_to_is(isp);
	struct v4l2_mbus_framefmt *mf = &fmt->format;
	int ret = 0;

	isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
		 __func__, fmt->pad, mf->code, mf->width, mf->height);

	mutex_lock(&isp->subdev_lock);
	__isp_subdev_try_format(isp, sd_state, fmt);

	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
		mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
		*mf = fmt->format;

		/* Propagate format to the source pads */
		if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
			struct v4l2_subdev_format format = *fmt;
			unsigned int pad;

			for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
					pad < FIMC_ISP_SD_PADS_NUM; pad++) {
				format.pad = pad;
				__isp_subdev_try_format(isp, sd_state,
							&format);
				mf = v4l2_subdev_state_get_format(sd_state,
								  pad);
				*mf = format.format;
			}
		}
	} else {
		if (!media_entity_is_streaming(&sd->entity)) {
			if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
				struct v4l2_subdev_format format = *fmt;

				isp->sink_fmt = *mf;

Annotation

Implementation Notes