drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c

Source file repositories/reference/linux-study-clean/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
Extension
.c
Size
19499 bytes
Lines
741
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

// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2021-2022 Bootlin
 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
 */

#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mc.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-v4l2.h>

#include "sun6i_isp.h"
#include "sun6i_isp_capture.h"
#include "sun6i_isp_proc.h"
#include "sun6i_isp_reg.h"

/* Helpers */

void sun6i_isp_capture_dimensions(struct sun6i_isp_device *isp_dev,
				  unsigned int *width, unsigned int *height)
{
	if (width)
		*width = isp_dev->capture.format.fmt.pix.width;
	if (height)
		*height = isp_dev->capture.format.fmt.pix.height;
}

void sun6i_isp_capture_format(struct sun6i_isp_device *isp_dev,
			      u32 *pixelformat)
{
	if (pixelformat)
		*pixelformat = isp_dev->capture.format.fmt.pix.pixelformat;
}

/* Format */

static const struct sun6i_isp_capture_format sun6i_isp_capture_formats[] = {
	{
		.pixelformat		= V4L2_PIX_FMT_NV12,
		.output_format		= SUN6I_ISP_OUTPUT_FMT_YUV420SP,
	},
	{
		.pixelformat		= V4L2_PIX_FMT_NV21,
		.output_format		= SUN6I_ISP_OUTPUT_FMT_YVU420SP,
	},
};

const struct sun6i_isp_capture_format *
sun6i_isp_capture_format_find(u32 pixelformat)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(sun6i_isp_capture_formats); i++)
		if (sun6i_isp_capture_formats[i].pixelformat == pixelformat)
			return &sun6i_isp_capture_formats[i];

	return NULL;
}

/* Capture */

static void
sun6i_isp_capture_buffer_configure(struct sun6i_isp_device *isp_dev,
				   struct sun6i_isp_buffer *isp_buffer)
{
	const struct v4l2_format_info *info;
	struct vb2_buffer *vb2_buffer;
	unsigned int width, height;
	unsigned int width_aligned;
	dma_addr_t address;
	u32 pixelformat;

	vb2_buffer = &isp_buffer->v4l2_buffer.vb2_buf;
	address = vb2_dma_contig_plane_dma_addr(vb2_buffer, 0);

	sun6i_isp_load_write(isp_dev, SUN6I_ISP_MCH_Y_ADDR0_REG,
			     SUN6I_ISP_ADDR_VALUE(address));

	sun6i_isp_capture_dimensions(isp_dev, &width, &height);
	sun6i_isp_capture_format(isp_dev, &pixelformat);

	info = v4l2_format_info(pixelformat);
	if (WARN_ON(!info))
		return;

	/* Stride needs to be aligned to 4. */
	width_aligned = ALIGN(width, 2);

Annotation

Implementation Notes