drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
Extension
.c
Size
10203 bytes
Lines
440
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

// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2011-2018 Magewell Electronics Co., Ltd. (Nanjing)
 * Author: Yong Deng <yong.deng@magewell.com>
 * Copyright 2021-2022 Bootlin
 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mc.h>

#include "sun6i_csi.h"
#include "sun6i_csi_bridge.h"
#include "sun6i_csi_capture.h"
#include "sun6i_csi_reg.h"

/* ISP */

int sun6i_csi_isp_complete(struct sun6i_csi_device *csi_dev,
			   struct v4l2_device *v4l2_dev)
{
	if (csi_dev->v4l2_dev && csi_dev->v4l2_dev != v4l2_dev)
		return -EINVAL;

	csi_dev->v4l2_dev = v4l2_dev;
	csi_dev->media_dev = v4l2_dev->mdev;

	return sun6i_csi_capture_setup(csi_dev);
}

static int sun6i_csi_isp_detect(struct sun6i_csi_device *csi_dev)
{
	struct device *dev = csi_dev->dev;
	struct fwnode_handle *handle;

	/*
	 * ISP is not available if not connected via fwnode graph.
	 * This will also check that the remote parent node is available.
	 */
	handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
						 SUN6I_CSI_PORT_ISP, 0,
						 FWNODE_GRAPH_ENDPOINT_NEXT);
	if (!handle)
		return 0;

	fwnode_handle_put(handle);

	if (!IS_ENABLED(CONFIG_VIDEO_SUN6I_ISP)) {
		dev_warn(dev,
			 "ISP link is detected but not enabled in kernel config!");
		return 0;
	}

	csi_dev->isp_available = true;

	return 0;
}

/* Media */

static const struct media_device_ops sun6i_csi_media_ops = {
	.link_notify = v4l2_pipeline_link_notify,
};

/* V4L2 */

static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev)
{
	struct sun6i_csi_v4l2 *v4l2 = &csi_dev->v4l2;
	struct media_device *media_dev = &v4l2->media_dev;
	struct v4l2_device *v4l2_dev = &v4l2->v4l2_dev;
	struct device *dev = csi_dev->dev;
	int ret;

	/* Media Device */

	strscpy(media_dev->model, SUN6I_CSI_DESCRIPTION,
		sizeof(media_dev->model));
	media_dev->hw_revision = 0;
	media_dev->ops = &sun6i_csi_media_ops;
	media_dev->dev = dev;

Annotation

Implementation Notes