linux/drivers/media/platform/renesas/rcar-vin/rcar-core.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for Renesas R-Car VIN
 *
 * Copyright (C) 2016 Renesas Electronics Corp.
 * Copyright (C) 2011-2013 Renesas Solutions Corp.
 * Copyright (C) 2013 Cogent Embedded, Inc., <[email protected]>
 * Copyright (C) 2008 Magnus Damm
 *
 * Based on the soc-camera rcar_vin driver
 */

#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>

#include <media/v4l2-async.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>

#include "rcar-vin.h"

/*
 * The companion CSI-2 receiver driver (rcar-csi2) is known
 * and we know it has one source pad (pad 0) and four sink
 * pads (pad 1-4). So to translate a pad on the remote
 * CSI-2 receiver to/from the VIN internal channel number simply
 * subtract/add one from the pad/channel number.
 */
#define rvin_group_csi_pad_to_channel(pad)
#define rvin_group_csi_channel_to_pad(channel)

/*
 * Not all VINs are created equal, master VINs control the
 * routing for other VIN's. We can figure out which VIN is
 * master by looking at a VINs id.
 */
#define rvin_group_id_to_master(vin)

#define v4l2_dev_to_vin(d)

/* -----------------------------------------------------------------------------
 * Gen3 Group Allocator
 */

/* FIXME:  This should if we find a system that supports more
 * than one group for the whole system be replaced with a linked
 * list of groups. And eventually all of this should be replaced
 * with a global device allocator API.
 *
 * But for now this works as on all supported systems there will
 * be only one group for all instances.
 */

static DEFINE_MUTEX(rvin_group_lock);
static struct rvin_group *rvin_group_data;

static void rvin_group_cleanup(struct rvin_group *group)
{}

static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin,
			   int (*link_setup)(struct rvin_dev *),
			   const struct media_device_ops *ops)
{}

static void rvin_group_release(struct kref *kref)
{}

static int rvin_group_get(struct rvin_dev *vin,
			  int (*link_setup)(struct rvin_dev *),
			  const struct media_device_ops *ops)
{}

static void rvin_group_put(struct rvin_dev *vin)
{}

/* group lock should be held when calling this function. */
static int rvin_group_entity_to_remote_id(struct rvin_group *group,
					  struct media_entity *entity)
{}

static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
{}

static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
				     struct v4l2_subdev *subdev,
				     struct v4l2_async_connection *asc)
{}

static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
				   struct v4l2_subdev *subdev,
				   struct v4l2_async_connection *asc)
{}

static const struct v4l2_async_notifier_operations rvin_group_notify_ops =;

static int rvin_group_parse_of(struct rvin_dev *vin, unsigned int port,
			       unsigned int id)
{}

static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
{}

static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port,
				    unsigned int max_id)
{}

/* -----------------------------------------------------------------------------
 * Controls
 */

static int rvin_s_ctrl(struct v4l2_ctrl *ctrl)
{}

static const struct v4l2_ctrl_ops rvin_ctrl_ops =;

static void rvin_free_controls(struct rvin_dev *vin)
{}

static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev)
{}

/* -----------------------------------------------------------------------------
 * Async notifier
 */

static int rvin_find_pad(struct v4l2_subdev *sd, int direction)
{}

/* -----------------------------------------------------------------------------
 * Parallel async notifier
 */

/* The vin lock should be held when calling the subdevice attach and detach */
static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
					  struct v4l2_subdev *subdev)
{}

static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
{}

static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
{}

static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier,
					struct v4l2_subdev *subdev,
					struct v4l2_async_connection *asc)
{}

static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier,
				      struct v4l2_subdev *subdev,
				      struct v4l2_async_connection *asc)
{}

static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops =;

static int rvin_parallel_parse_of(struct rvin_dev *vin)
{}

static void rvin_parallel_cleanup(struct rvin_dev *vin)
{}

static int rvin_parallel_init(struct rvin_dev *vin)
{}

/* -----------------------------------------------------------------------------
 * CSI-2
 */

/*
 * Link setup for the links between a VIN and a CSI-2 receiver is a bit
 * complex. The reason for this is that the register controlling routing
 * is not present in each VIN instance. There are special VINs which
 * control routing for themselves and other VINs. There are not many
 * different possible links combinations that can be enabled at the same
 * time, therefor all already enabled links which are controlled by a
 * master VIN need to be taken into account when making the decision
 * if a new link can be enabled or not.
 *
 * 1. Find out which VIN the link the user tries to enable is connected to.
 * 2. Lookup which master VIN controls the links for this VIN.
 * 3. Start with a bitmask with all bits set.
 * 4. For each previously enabled link from the master VIN bitwise AND its
 *    route mask (see documentation for mask in struct rvin_group_route)
 *    with the bitmask.
 * 5. Bitwise AND the mask for the link the user tries to enable to the bitmask.
 * 6. If the bitmask is not empty at this point the new link can be enabled
 *    while keeping all previous links enabled. Update the CHSEL value of the
 *    master VIN and inform the user that the link could be enabled.
 *
 * Please note that no link can be enabled if any VIN in the group is
 * currently open.
 */
static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
				 unsigned int notification)
{}

static const struct media_device_ops rvin_csi2_media_ops =;

static int rvin_csi2_create_link(struct rvin_group *group, unsigned int id,
				 const struct rvin_group_route *route)
{}

static int rvin_csi2_setup_links(struct rvin_dev *vin)
{}

static void rvin_csi2_cleanup(struct rvin_dev *vin)
{}

static int rvin_csi2_init(struct rvin_dev *vin)
{}

/* -----------------------------------------------------------------------------
 * ISP
 */

static int rvin_isp_setup_links(struct rvin_dev *vin)
{}

static void rvin_isp_cleanup(struct rvin_dev *vin)
{}

static int rvin_isp_init(struct rvin_dev *vin)
{}

/* -----------------------------------------------------------------------------
 * Suspend / Resume
 */

static int __maybe_unused rvin_suspend(struct device *dev)
{}

static int __maybe_unused rvin_resume(struct device *dev)
{}

/* -----------------------------------------------------------------------------
 * Platform Device Driver
 */

static const struct rvin_info rcar_info_h1 =;

static const struct rvin_info rcar_info_m1 =;

static const struct rvin_info rcar_info_gen2 =;

static const struct rvin_group_route rcar_info_r8a774e1_routes[] =;

static const struct rvin_info rcar_info_r8a774e1 =;

static const struct rvin_group_route rcar_info_r8a7795_routes[] =;

static const struct rvin_info rcar_info_r8a7795 =;

static const struct rvin_group_route rcar_info_r8a7796_routes[] =;

static const struct rvin_info rcar_info_r8a7796 =;

static const struct rvin_group_route rcar_info_r8a77965_routes[] =;

static const struct rvin_info rcar_info_r8a77965 =;

static const struct rvin_group_route rcar_info_r8a77970_routes[] =;

static const struct rvin_info rcar_info_r8a77970 =;

static const struct rvin_group_route rcar_info_r8a77980_routes[] =;

static const struct rvin_info rcar_info_r8a77980 =;

static const struct rvin_group_route rcar_info_r8a77990_routes[] =;

static const struct rvin_info rcar_info_r8a77990 =;

static const struct rvin_group_route rcar_info_r8a77995_routes[] =;

static const struct rvin_info rcar_info_r8a77995 =;

static const struct rvin_info rcar_info_gen4 =;

static const struct of_device_id rvin_of_id_table[] =;
MODULE_DEVICE_TABLE(of, rvin_of_id_table);

static int rcar_vin_probe(struct platform_device *pdev)
{}

static void rcar_vin_remove(struct platform_device *pdev)
{}

static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);

static struct platform_driver rcar_vin_driver =;

module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();