drivers/media/platform/ti/cal/cal-video.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/ti/cal/cal-video.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/ti/cal/cal-video.c
Extension
.c
Size
28529 bytes
Lines
1113
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 (idx == f->index) {
			f->pixelformat = cal_formats[i].fourcc;
			f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			return 0;
		}

		idx++;
	}

	return -EINVAL;
}

static void cal_mc_try_fmt(struct cal_ctx *ctx, struct v4l2_format *f,
			   const struct cal_format_info **info)
{
	struct v4l2_pix_format *format = &f->fmt.pix;
	const struct cal_format_info *fmtinfo;
	unsigned int bpp;

	/*
	 * Default to the first format if the requested pixel format code isn't
	 * supported.
	 */
	fmtinfo = cal_format_by_fourcc(f->fmt.pix.pixelformat);
	if (!fmtinfo || fmtinfo->meta)
		fmtinfo = &cal_formats[0];

	/*
	 * Clamp the size, update the pixel format. The field and colorspace are
	 * accepted as-is, except for V4L2_FIELD_ANY that is turned into
	 * V4L2_FIELD_NONE.
	 */
	bpp = ALIGN(fmtinfo->bpp, 8);

	format->width = clamp_t(unsigned int, format->width,
				CAL_MIN_WIDTH_BYTES * 8 / bpp,
				CAL_MAX_WIDTH_BYTES * 8 / bpp);
	format->height = clamp_t(unsigned int, format->height,
				 CAL_MIN_HEIGHT_LINES, CAL_MAX_HEIGHT_LINES);
	format->pixelformat = fmtinfo->fourcc;

	if (format->field == V4L2_FIELD_ANY)
		format->field = V4L2_FIELD_NONE;

	/*
	 * Calculate the number of bytes per line and the image size. The
	 * hardware stores the stride as a number of 16 bytes words, in a
	 * signed 15-bit value. Only 14 bits are thus usable.
	 */
	format->bytesperline = ALIGN(clamp(format->bytesperline,
					   format->width * bpp / 8,
					   ((1U << 14) - 1) * 16), 16);

	format->sizeimage = format->height * format->bytesperline;

	format->colorspace = ctx->v_fmt.fmt.pix.colorspace;

	if (info)
		*info = fmtinfo;

	ctx_dbg(3, ctx, "%s: %p4cc %ux%u (bytesperline %u sizeimage %u)\n",
		__func__, &format->pixelformat,
		format->width, format->height,
		format->bytesperline, format->sizeimage);
}

static int cal_mc_try_fmt_vid_cap(struct file *file, void *priv,
				  struct v4l2_format *f)
{
	struct cal_ctx *ctx = video_drvdata(file);

	cal_mc_try_fmt(ctx, f, NULL);
	return 0;
}

static int cal_mc_s_fmt_vid_cap(struct file *file, void *priv,
				struct v4l2_format *f)
{
	struct cal_ctx *ctx = video_drvdata(file);
	const struct cal_format_info *fmtinfo;

	if (vb2_is_busy(&ctx->vb_vidq)) {
		ctx_dbg(3, ctx, "%s device busy\n", __func__);
		return -EBUSY;
	}

	cal_mc_try_fmt(ctx, f, &fmtinfo);

	ctx->v_fmt = *f;
	ctx->fmtinfo = fmtinfo;

Annotation

Implementation Notes