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

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

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/samsung/exynos4-is/fimc-reg.c
Extension
.c
Size
22912 bytes
Lines
847
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

struct mbus_pixfmt_desc {
	u32 pixelcode;
	u32 cisrcfmt;
	u16 bus_width;
};

static const struct mbus_pixfmt_desc pix_desc[] = {
	{ MEDIA_BUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 },
	{ MEDIA_BUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 },
	{ MEDIA_BUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 },
	{ MEDIA_BUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 },
};

int fimc_hw_set_camera_source(struct fimc_dev *fimc,
			      struct fimc_source_info *source)
{
	const struct fimc_vid_cap *vc = &fimc->vid_cap;
	const struct fimc_frame *f = &vc->ctx->s_frame;
	u32 bus_width, cfg = 0;
	int i;

	switch (source->fimc_bus_type) {
	case FIMC_BUS_TYPE_ITU_601:
	case FIMC_BUS_TYPE_ITU_656:
		if (fimc_fmt_is_user_defined(f->fmt->color)) {
			cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
			break;
		}

		for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
			if (vc->ci_fmt.code == pix_desc[i].pixelcode) {
				cfg = pix_desc[i].cisrcfmt;
				bus_width = pix_desc[i].bus_width;
				break;
			}
		}

		if (i == ARRAY_SIZE(pix_desc)) {
			v4l2_err(&vc->ve.vdev,
				 "Camera color format not supported: %d\n",
				 vc->ci_fmt.code);
			return -EINVAL;
		}

		if (source->fimc_bus_type == FIMC_BUS_TYPE_ITU_601) {
			if (bus_width == 8)
				cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
			else if (bus_width == 16)
				cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
		} /* else defaults to ITU-R BT.656 8-bit */
		break;
	case FIMC_BUS_TYPE_MIPI_CSI2:
		if (fimc_fmt_is_user_defined(f->fmt->color))
			cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
		break;
	default:
	case FIMC_BUS_TYPE_ISP_WRITEBACK:
		/* Anything to do here ? */
		break;
	}

	cfg |= (f->o_width << 16) | f->o_height;
	writel(cfg, fimc->regs + FIMC_REG_CISRCFMT);
	return 0;
}

void fimc_hw_set_camera_offset(struct fimc_dev *fimc, const struct fimc_frame *f)
{
	u32 hoff2, voff2;

	u32 cfg = readl(fimc->regs + FIMC_REG_CIWDOFST);

	cfg &= ~(FIMC_REG_CIWDOFST_HOROFF_MASK | FIMC_REG_CIWDOFST_VEROFF_MASK);
	cfg |=  FIMC_REG_CIWDOFST_OFF_EN |
		(f->offs_h << 16) | f->offs_v;

	writel(cfg, fimc->regs + FIMC_REG_CIWDOFST);

	/* See CIWDOFSTn register description in the datasheet for details. */
	hoff2 = f->o_width - f->width - f->offs_h;
	voff2 = f->o_height - f->height - f->offs_v;
	cfg = (hoff2 << 16) | voff2;
	writel(cfg, fimc->regs + FIMC_REG_CIWDOFST2);
}

int fimc_hw_set_camera_type(struct fimc_dev *fimc,
			    const struct fimc_source_info *source)
{
	const struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
	u32 csis_data_alignment = 32;

Annotation

Implementation Notes