drivers/staging/media/ipu7/ipu7-isys-video.c

Source file repositories/reference/linux-study-clean/drivers/staging/media/ipu7/ipu7-isys-video.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/media/ipu7/ipu7-isys-video.c
Extension
.c
Size
29341 bytes
Lines
1079
Domain
Driver Families
Bucket
drivers/staging
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 (num_found < f->index) {
			num_found++;
			continue;
		}

		f->flags = 0;
		f->pixelformat = ipu7_isys_pfmts[i].pixelformat;

		return 0;
	}

	return -EINVAL;
}

static int ipu7_isys_vidioc_enum_framesizes(struct file *file, void *fh,
					    struct v4l2_frmsizeenum *fsize)
{
	unsigned int i;

	if (fsize->index > 0)
		return -EINVAL;

	for (i = 0; i < ARRAY_SIZE(ipu7_isys_pfmts); i++) {
		if (fsize->pixel_format != ipu7_isys_pfmts[i].pixelformat)
			continue;

		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
		fsize->stepwise.min_width = IPU_ISYS_MIN_WIDTH;
		fsize->stepwise.max_width = IPU_ISYS_MAX_WIDTH;
		fsize->stepwise.min_height = IPU_ISYS_MIN_HEIGHT;
		fsize->stepwise.max_height = IPU_ISYS_MAX_HEIGHT;
		fsize->stepwise.step_width = 2;
		fsize->stepwise.step_height = 2;

		return 0;
	}

	return -EINVAL;
}

static int ipu7_isys_vidioc_g_fmt_vid_cap(struct file *file, void *fh,
					  struct v4l2_format *f)
{
	struct ipu7_isys_video *av = video_drvdata(file);

	f->fmt.pix = av->pix_fmt;

	return 0;
}

static void ipu7_isys_try_fmt_cap(struct ipu7_isys_video *av, u32 type,
				  u32 *format, u32 *width, u32 *height,
				  u32 *bytesperline, u32 *sizeimage)
{
	const struct ipu7_isys_pixelformat *pfmt =
		ipu7_isys_get_isys_format(*format);

	*format = pfmt->pixelformat;
	*width = clamp(*width, IPU_ISYS_MIN_WIDTH, IPU_ISYS_MAX_WIDTH);
	*height = clamp(*height, IPU_ISYS_MIN_HEIGHT, IPU_ISYS_MAX_HEIGHT);

	if (pfmt->bpp != pfmt->bpp_packed)
		*bytesperline = *width * DIV_ROUND_UP(pfmt->bpp, BITS_PER_BYTE);
	else
		*bytesperline = DIV_ROUND_UP(*width * pfmt->bpp, BITS_PER_BYTE);

	*bytesperline = ALIGN(*bytesperline, 64U);

	/*
	 * (height + 1) * bytesperline due to a hardware issue: the DMA unit
	 * is a power of two, and a line should be transferred as few units
	 * as possible. The result is that up to line length more data than
	 * the image size may be transferred to memory after the image.
	 * Another limitation is the GDA allocation unit size. For low
	 * resolution it gives a bigger number. Use larger one to avoid
	 * memory corruption.
	 */
	*sizeimage = *bytesperline * *height +
		max(*bytesperline,
		    av->isys->pdata->ipdata->isys_dma_overshoot);
}

static void __ipu_isys_vidioc_try_fmt_vid_cap(struct ipu7_isys_video *av,
					      struct v4l2_format *f)
{
	ipu7_isys_try_fmt_cap(av, f->type, &f->fmt.pix.pixelformat,
			      &f->fmt.pix.width, &f->fmt.pix.height,
			      &f->fmt.pix.bytesperline, &f->fmt.pix.sizeimage);

	f->fmt.pix.field = V4L2_FIELD_NONE;

Annotation

Implementation Notes