// SPDX-License-Identifier: GPL-2.0-only
/*
 * V4L2 fwnode binding parsing library
 *
 * The origins of the V4L2 fwnode library are in V4L2 OF library that
 * formerly was located in v4l2-of.c.
 *
 * Copyright (c) 2016 Intel Corporation.
 * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
 *
 * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
 *
 * Copyright (C) 2012 Renesas Electronics Corp.
 * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 */
#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>

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

static const struct v4l2_fwnode_bus_conv {
	enum v4l2_fwnode_bus_type fwnode_bus_type;
	enum v4l2_mbus_type mbus_type;
	const char *name;
} buses[] = {
	{
		V4L2_FWNODE_BUS_TYPE_GUESS,
		V4L2_MBUS_UNKNOWN,
		"not specified",
	}, {
		V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
		V4L2_MBUS_CSI2_CPHY,
		"MIPI CSI-2 C-PHY",
	}, {
		V4L2_FWNODE_BUS_TYPE_CSI1,
		V4L2_MBUS_CSI1,
		"MIPI CSI-1",
	}, {
		V4L2_FWNODE_BUS_TYPE_CCP2,
		V4L2_MBUS_CCP2,
		"compact camera port 2",
	}, {
		V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
		V4L2_MBUS_CSI2_DPHY,
		"MIPI CSI-2 D-PHY",
	}, {
		V4L2_FWNODE_BUS_TYPE_PARALLEL,
		V4L2_MBUS_PARALLEL,
		"parallel",
	}, {
		V4L2_FWNODE_BUS_TYPE_BT656,
		V4L2_MBUS_BT656,
		"Bt.656",
	}, {
		V4L2_FWNODE_BUS_TYPE_DPI,
		V4L2_MBUS_DPI,
		"DPI",
	}
};

static const struct v4l2_fwnode_bus_conv *
get_v4l2_fwnode_bus_conv_by_fwnode_bus(enum v4l2_fwnode_bus_type type)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(buses); i++)
		if (buses[i].fwnode_bus_type == type)
			return &buses[i];

	return NULL;
}

static enum v4l2_mbus_type
v4l2_fwnode_bus_type_to_mbus(enum v4l2_fwnode_bus_type type)
{
	const struct v4l2_fwnode_bus_conv *conv =
		get_v4l2_fwnode_bus_conv_by_fwnode_bus(type);

	return conv ? conv->mbus_type : V4L2_MBUS_INVALID;
}

static const char *
v4l2_fwnode_bus_type_to_string(enum v4l2_fwnode_bus_type type)
{
	const struct v4l2_fwnode_bus_conv *conv =
		get_v4l2_fwnode_bus_conv_by_fwnode_bus(type);

	return conv ? conv->name : "not found";
}

static const struct v4l2_fwnode_bus_conv *
get_v4l2_fwnode_bus_conv_by_mbus(enum v4l2_mbus_type type)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(buses); i++)
		if (buses[i].mbus_type == type)
			return &buses[i];

	return NULL;
}

static const char *
v4l2_fwnode_mbus_type_to_string(enum v4l2_mbus_type type)
{
	const struct v4l2_fwnode_bus_conv *conv =
		get_v4l2_fwnode_bus_conv_by_mbus(type);

	return conv ? conv->name : "not found";
}

static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
					       struct v4l2_fwnode_endpoint *vep,
					       enum v4l2_mbus_type bus_type)
{
	struct v4l2_mbus_config_mipi_csi2 *bus = &vep->bus.mipi_csi2;
	bool have_clk_lane = false, have_data_lanes = false,
		have_lane_polarities = false;
	unsigned int flags = 0, lanes_used = 0;
	u32 array[1 + V4L2_MBUS_CSI2_MAX_DATA_LANES];
	u32 clock_lane = 0;
	unsigned int num_data_lanes = 0;
	bool use_default_lane_mapping = false;
	unsigned int i;
	u32 v;
	int rval;

	if (bus_type == V4L2_MBUS_CSI2_DPHY ||
	    bus_type == V4L2_MBUS_CSI2_CPHY) {
		use_default_lane_mapping = true;

		num_data_lanes = min_t(u32, bus->num_data_lanes,
				       V4L2_MBUS_CSI2_MAX_DATA_LANES);

		clock_lane = bus->clock_lane;
		if (clock_lane)
			use_default_lane_mapping = false;

		for (i = 0; i < num_data_lanes; i++) {
			array[i] = bus->data_lanes[i];
			if (array[i])
				use_default_lane_mapping = false;
		}

		if (use_default_lane_mapping)
			pr_debug("no lane mapping given, using defaults\n");
	}

	rval = fwnode_property_count_u32(fwnode, "data-lanes");
	if (rval > 0) {
		num_data_lanes =
			min_t(int, V4L2_MBUS_CSI2_MAX_DATA_LANES, rval);

		fwnode_property_read_u32_array(fwnode, "data-lanes", array,
					       num_data_lanes);

		have_data_lanes = true;
		if (use_default_lane_mapping) {
			pr_debug("data-lanes property exists; disabling default mapping\n");
			use_default_lane_mapping = false;
		}
	}

	for (i = 0; i < num_data_lanes; i++) {
		if (lanes_used & BIT(array[i])) {
			if (have_data_lanes || !use_default_lane_mapping)
				pr_warn("duplicated lane %u in data-lanes, using defaults\n",
					array[i]);
			use_default_lane_mapping = true;
		}
		lanes_used |= BIT(array[i]);

		if (have_data_lanes)
			pr_debug("lane %u position %u\n", i, array[i]);
	}

	rval = fwnode_property_count_u32(fwnode, "lane-polarities");
	if (rval > 0) {
		if (rval != 1 + num_data_lanes /* clock+data */) {
			pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
				1 + num_data_lanes, rval);
			return -EINVAL;
		}

		have_lane_polarities = true;
	}

	if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
		clock_lane = v;
		pr_debug("clock lane position %u\n", v);
		have_clk_lane = true;
	}

	if (have_clk_lane && lanes_used & BIT(clock_lane) &&
	    !use_default_lane_mapping) {
		pr_warn("duplicated lane %u in clock-lanes, using defaults\n",
			v);
		use_default_lane_mapping = true;
	}

	if (fwnode_property_present(fwnode, "clock-noncontinuous")) {
		flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
		pr_debug("non-continuous clock\n");
	}

	if (bus_type == V4L2_MBUS_CSI2_DPHY ||
	    bus_type == V4L2_MBUS_CSI2_CPHY ||
	    lanes_used || have_clk_lane || flags) {
		/* Only D-PHY has a clock lane. */
		unsigned int dfl_data_lane_index =
			bus_type == V4L2_MBUS_CSI2_DPHY;

		bus->flags = flags;
		if (bus_type == V4L2_MBUS_UNKNOWN)
			vep->bus_type = V4L2_MBUS_CSI2_DPHY;
		bus->num_data_lanes = num_data_lanes;

		if (use_default_lane_mapping) {
			bus->clock_lane = 0;
			for (i = 0; i < num_data_lanes; i++)
				bus->data_lanes[i] = dfl_data_lane_index + i;
		} else {
			bus->clock_lane = clock_lane;
			for (i = 0; i < num_data_lanes; i++)
				bus->data_lanes[i] = array[i];
		}

		if (have_lane_polarities) {
			fwnode_property_read_u32_array(fwnode,
						       "lane-polarities", array,
						       1 + num_data_lanes);

			for (i = 0; i < 1 + num_data_lanes; i++) {
				bus->lane_polarities[i] = array[i];
				pr_debug("lane %u polarity %sinverted",
					 i, array[i] ? "" : "not ");
			}
		} else {
			pr_debug("no lane polarities defined, assuming not inverted\n");
		}
	}

	return 0;
}

#define PARALLEL_MBUS_FLAGS (V4L2_MBUS_HSYNC_ACTIVE_HIGH |	\
			     V4L2_MBUS_HSYNC_ACTIVE_LOW |	\
			     V4L2_MBUS_VSYNC_ACTIVE_HIGH |	\
			     V4L2_MBUS_VSYNC_ACTIVE_LOW |	\
			     V4L2_MBUS_FIELD_EVEN_HIGH |	\
			     V4L2_MBUS_FIELD_EVEN_LOW)

static void
v4l2_fwnode_endpoint_parse_parallel_bus(struct fwnode_handle *fwnode,
					struct v4l2_fwnode_endpoint *vep,
					enum v4l2_mbus_type bus_type)
{
	struct v4l2_mbus_config_parallel *bus = &vep->bus.parallel;
	unsigned int flags = 0;
	u32 v;

	if (bus_type == V4L2_MBUS_PARALLEL || bus_type == V4L2_MBUS_BT656)
		flags = bus->flags;

	if (!fwnode_property_read_u32(fwnode, "hsync-active", &v)) {
		flags &= ~(V4L2_MBUS_HSYNC_ACTIVE_HIGH |
			   V4L2_MBUS_HSYNC_ACTIVE_LOW);
		flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
			V4L2_MBUS_HSYNC_ACTIVE_LOW;
		pr_debug("hsync-active %s\n", v ? "high" : "low");
	}

	if (!fwnode_property_read_u32(fwnode, "vsync-active", &v)) {
		flags &= ~(V4L2_MBUS_VSYNC_ACTIVE_HIGH |
			   V4L2_MBUS_VSYNC_ACTIVE_LOW);
		flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
			V4L2_MBUS_VSYNC_ACTIVE_LOW;
		pr_debug("vsync-active %s\n", v ? "high" : "low");
	}

	if (!fwnode_property_read_u32(fwnode, "field-even-active", &v)) {
		flags &= ~(V4L2_MBUS_FIELD_EVEN_HIGH |
			   V4L2_MBUS_FIELD_EVEN_LOW);
		flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
			V4L2_MBUS_FIELD_EVEN_LOW;
		pr_debug("field-even-active %s\n", v ? "high" : "low");
	}

	if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) {
		flags &= ~(V4L2_MBUS_PCLK_SAMPLE_RISING |
			   V4L2_MBUS_PCLK_SAMPLE_FALLING);
		flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
			V4L2_MBUS_PCLK_SAMPLE_FALLING;
		pr_debug("pclk-sample %s\n", v ? "high" : "low");
	}

	if (!fwnode_property_read_u32(fwnode, "data-active", &v)) {
		flags &= ~(V4L2_MBUS_DATA_ACTIVE_HIGH |
			   V4L2_MBUS_DATA_ACTIVE_LOW);
		flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
			V4L2_MBUS_DATA_ACTIVE_LOW;
		pr_debug("data-active %s\n", v ? "high" : "low");
	}

	if (fwnode_property_present(fwnode, "slave-mode")) {
		pr_debug("slave mode\n");
		flags &= ~V4L2_MBUS_MASTER;
		flags |= V4L2_MBUS_SLAVE;
	} else {
		flags &= ~V4L2_MBUS_SLAVE;
		flags |= V4L2_MBUS_MASTER;
	}

	if (!fwnode_property_read_u32(fwnode, "bus-width", &v)) {
		bus->bus_width = v;
		pr_debug("bus-width %u\n", v);
	}

	if (!fwnode_property_read_u32(fwnode, "data-shift", &v)) {
		bus->data_shift = v;
		pr_debug("data-shift %u\n", v);
	}

	if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v)) {
		flags &= ~(V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH |
			   V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW);
		flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
			V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
		pr_debug("sync-on-green-active %s\n", v ? "high" : "low");
	}

	if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v)) {
		flags &= ~(V4L2_MBUS_DATA_ENABLE_HIGH |
			   V4L2_MBUS_DATA_ENABLE_LOW);
		flags |= v ? V4L2_MBUS_DATA_ENABLE_HIGH :
			V4L2_MBUS_DATA_ENABLE_LOW;
		pr_debug("data-enable-active %s\n", v ? "high" : "low");
	}

	switch (bus_type) {
	default:
		bus->flags = flags;
		if (flags & PARALLEL_MBUS_FLAGS)
			vep->bus_type = V4L2_MBUS_PARALLEL;
		else
			vep->bus_type = V4L2_MBUS_BT656;
		break;
	case V4L2_MBUS_PARALLEL:
		vep->bus_type = V4L2_MBUS_PARALLEL;
		bus->flags = flags;
		break;
	case V4L2_MBUS_BT656:
		vep->bus_type = V4L2_MBUS_BT656;
		bus->flags = flags & ~PARALLEL_MBUS_FLAGS;
		break;
	}
}

static void
v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode,
				    struct v4l2_fwnode_endpoint *vep,
				    enum v4l2_mbus_type bus_type)
{
	struct v4l2_mbus_config_mipi_csi1 *bus = &vep->bus.mipi_csi1;
	u32 v;

	if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) {
		bus->clock_inv = v;
		pr_debug("clock-inv %u\n", v);
	}

	if (!fwnode_property_read_u32(fwnode, "strobe", &v)) {
		bus->strobe = v;
		pr_debug("strobe %u\n", v);
	}

	if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) {
		bus->data_lane = v;
		pr_debug("data-lanes %u\n", v);
	}

	if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
		bus->clock_lane = v;
		pr_debug("clock-lanes %u\n", v);
	}

	if (bus_type == V4L2_MBUS_CCP2)
		vep->bus_type = V4L2_MBUS_CCP2;
	else
		vep->bus_type = V4L2_MBUS_CSI1;
}

static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
					struct v4l2_fwnode_endpoint *vep)
{
	u32 bus_type = V4L2_FWNODE_BUS_TYPE_GUESS;
	enum v4l2_mbus_type mbus_type;
	int rval;

	pr_debug("===== begin parsing endpoint %pfw\n", fwnode);

	fwnode_property_read_u32(fwnode, "bus-type", &bus_type);
	pr_debug("fwnode video bus type %s (%u), mbus type %s (%u)\n",
		 v4l2_fwnode_bus_type_to_string(bus_type), bus_type,
		 v4l2_fwnode_mbus_type_to_string(vep->bus_type),
		 vep->bus_type);
	mbus_type = v4l2_fwnode_bus_type_to_mbus(bus_type);
	if (mbus_type == V4L2_MBUS_INVALID) {
		pr_debug("unsupported bus type %u\n", bus_type);
		return -EINVAL;
	}

	if (vep->bus_type != V4L2_MBUS_UNKNOWN) {
		if (mbus_type != V4L2_MBUS_UNKNOWN &&
		    vep->bus_type != mbus_type) {
			pr_debug("expecting bus type %s\n",
				 v4l2_fwnode_mbus_type_to_string(vep->bus_type));
			return -ENXIO;
		}
	} else {
		vep->bus_type = mbus_type;
	}

	switch (vep->bus_type) {
	case V4L2_MBUS_UNKNOWN:
		rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
							   V4L2_MBUS_UNKNOWN);
		if (rval)
			return rval;

		if (vep->bus_type == V4L2_MBUS_UNKNOWN)
			v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep,
								V4L2_MBUS_UNKNOWN);

		pr_debug("assuming media bus type %s (%u)\n",
			 v4l2_fwnode_mbus_type_to_string(vep->bus_type),
			 vep->bus_type);

		break;
	case V4L2_MBUS_CCP2:
	case V4L2_MBUS_CSI1:
		v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, vep->bus_type);

		break;
	case V4L2_MBUS_CSI2_DPHY:
	case V4L2_MBUS_CSI2_CPHY:
		rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
							   vep->bus_type);
		if (rval)
			return rval;

		break;
	case V4L2_MBUS_PARALLEL:
	case V4L2_MBUS_BT656:
		v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep,
							vep->bus_type);

		break;
	default:
		pr_warn("unsupported bus type %u\n", mbus_type);
		return -EINVAL;
	}

	fwnode_graph_parse_endpoint(fwnode, &vep->base);

	return 0;
}

int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
			       struct v4l2_fwnode_endpoint *vep)
{
	int ret;

	ret = __v4l2_fwnode_endpoint_parse(fwnode, vep);

	pr_debug("===== end parsing endpoint %pfw\n", fwnode);

	return ret;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse);

void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
{
	if (IS_ERR_OR_NULL(vep))
		return;

	kfree(vep->link_frequencies);
	vep->link_frequencies = NULL;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free);

int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode,
				     struct v4l2_fwnode_endpoint *vep)
{
	int rval;

	rval = __v4l2_fwnode_endpoint_parse(fwnode, vep);
	if (rval < 0)
		return rval;

	rval = fwnode_property_count_u64(fwnode, "link-frequencies");
	if (rval > 0) {
		unsigned int i;

		vep->link_frequencies =
			kmalloc_array(rval, sizeof(*vep->link_frequencies),
				      GFP_KERNEL);
		if (!vep->link_frequencies)
			return -ENOMEM;

		vep->nr_of_link_frequencies = rval;

		rval = fwnode_property_read_u64_array(fwnode,
						      "link-frequencies",
						      vep->link_frequencies,
						      vep->nr_of_link_frequencies);
		if (rval < 0) {
			v4l2_fwnode_endpoint_free(vep);
			return rval;
		}

		for (i = 0; i < vep->nr_of_link_frequencies; i++)
			pr_debug("link-frequencies %u value %llu\n", i,
				 vep->link_frequencies[i]);
	}

	pr_debug("===== end parsing endpoint %pfw\n", fwnode);

	return 0;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);

int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
			   struct v4l2_fwnode_link *link)
{
	struct fwnode_endpoint fwep;

	memset(link, 0, sizeof(*link));

	fwnode_graph_parse_endpoint(fwnode, &fwep);
	link->local_id = fwep.id;
	link->local_port = fwep.port;
	link->local_node = fwnode_graph_get_port_parent(fwnode);

	fwnode = fwnode_graph_get_remote_endpoint(fwnode);
	if (!fwnode) {
		fwnode_handle_put(fwnode);
		return -ENOLINK;
	}

	fwnode_graph_parse_endpoint(fwnode, &fwep);
	link->remote_id = fwep.id;
	link->remote_port = fwep.port;
	link->remote_node = fwnode_graph_get_port_parent(fwnode);

	return 0;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link);

void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
{
	fwnode_handle_put(link->local_node);
	fwnode_handle_put(link->remote_node);
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);

static const struct v4l2_fwnode_connector_conv {
	enum v4l2_connector_type type;
	const char *compatible;
} connectors[] = {
	{
		.type = V4L2_CONN_COMPOSITE,
		.compatible = "composite-video-connector",
	}, {
		.type = V4L2_CONN_SVIDEO,
		.compatible = "svideo-connector",
	},
};

static enum v4l2_connector_type
v4l2_fwnode_string_to_connector_type(const char *con_str)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(connectors); i++)
		if (!strcmp(con_str, connectors[i].compatible))
			return connectors[i].type;

	return V4L2_CONN_UNKNOWN;
}

static void
v4l2_fwnode_connector_parse_analog(struct fwnode_handle *fwnode,
				   struct v4l2_fwnode_connector *vc)
{
	u32 stds;
	int ret;

	ret = fwnode_property_read_u32(fwnode, "sdtv-standards", &stds);

	/* The property is optional. */
	vc->connector.analog.sdtv_stds = ret ? V4L2_STD_ALL : stds;
}

void v4l2_fwnode_connector_free(struct v4l2_fwnode_connector *connector)
{
	struct v4l2_connector_link *link, *tmp;

	if (IS_ERR_OR_NULL(connector) || connector->type == V4L2_CONN_UNKNOWN)
		return;

	list_for_each_entry_safe(link, tmp, &connector->links, head) {
		v4l2_fwnode_put_link(&link->fwnode_link);
		list_del(&link->head);
		kfree(link);
	}

	kfree(connector->label);
	connector->label = NULL;
	connector->type = V4L2_CONN_UNKNOWN;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_connector_free);

static enum v4l2_connector_type
v4l2_fwnode_get_connector_type(struct fwnode_handle *fwnode)
{
	const char *type_name;
	int err;

	if (!fwnode)
		return V4L2_CONN_UNKNOWN;

	/* The connector-type is stored within the compatible string. */
	err = fwnode_property_read_string(fwnode, "compatible", &type_name);
	if (err)
		return V4L2_CONN_UNKNOWN;

	return v4l2_fwnode_string_to_connector_type(type_name);
}

int v4l2_fwnode_connector_parse(struct fwnode_handle *fwnode,
				struct v4l2_fwnode_connector *connector)
{
	struct fwnode_handle *connector_node;
	enum v4l2_connector_type connector_type;
	const char *label;
	int err;

	if (!fwnode)
		return -EINVAL;

	memset(connector, 0, sizeof(*connector));

	INIT_LIST_HEAD(&connector->links);

	connector_node = fwnode_graph_get_port_parent(fwnode);
	connector_type = v4l2_fwnode_get_connector_type(connector_node);
	if (connector_type == V4L2_CONN_UNKNOWN) {
		fwnode_handle_put(connector_node);
		connector_node = fwnode_graph_get_remote_port_parent(fwnode);
		connector_type = v4l2_fwnode_get_connector_type(connector_node);
	}

	if (connector_type == V4L2_CONN_UNKNOWN) {
		pr_err("Unknown connector type\n");
		err = -ENOTCONN;
		goto out;
	}

	connector->type = connector_type;
	connector->name = fwnode_get_name(connector_node);
	err = fwnode_property_read_string(connector_node, "label", &label);
	connector->label = err ? NULL : kstrdup_const(label, GFP_KERNEL);

	/* Parse the connector specific properties. */
	switch (connector->type) {
	case V4L2_CONN_COMPOSITE:
	case V4L2_CONN_SVIDEO:
		v4l2_fwnode_connector_parse_analog(connector_node, connector);
		break;
	/* Avoid compiler warnings */
	case V4L2_CONN_UNKNOWN:
		break;
	}

out:
	fwnode_handle_put(connector_node);

	return err;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_connector_parse);

int v4l2_fwnode_connector_add_link(struct fwnode_handle *fwnode,
				   struct v4l2_fwnode_connector *connector)
{
	struct fwnode_handle *connector_ep;
	struct v4l2_connector_link *link;
	int err;

	if (!fwnode || !connector || connector->type == V4L2_CONN_UNKNOWN)
		return -EINVAL;

	connector_ep = fwnode_graph_get_remote_endpoint(fwnode);
	if (!connector_ep)
		return -ENOTCONN;

	link = kzalloc(sizeof(*link), GFP_KERNEL);
	if (!link) {
		err = -ENOMEM;
		goto err;
	}

	err = v4l2_fwnode_parse_link(connector_ep, &link->fwnode_link);
	if (err)
		goto err;

	fwnode_handle_put(connector_ep);

	list_add(&link->head, &connector->links);
	connector->nr_of_links++;

	return 0;

err:
	kfree(link);
	fwnode_handle_put(connector_ep);

	return err;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_connector_add_link);

int v4l2_fwnode_device_parse(struct device *dev,
			     struct v4l2_fwnode_device_properties *props)
{
	struct fwnode_handle *fwnode = dev_fwnode(dev);
	u32 val;
	int ret;

	memset(props, 0, sizeof(*props));

	props->orientation = V4L2_FWNODE_PROPERTY_UNSET;
	ret = fwnode_property_read_u32(fwnode, "orientation", &val);
	if (!ret) {
		switch (val) {
		case V4L2_FWNODE_ORIENTATION_FRONT:
		case V4L2_FWNODE_ORIENTATION_BACK:
		case V4L2_FWNODE_ORIENTATION_EXTERNAL:
			break;
		default:
			dev_warn(dev, "Unsupported device orientation: %u\n", val);
			return -EINVAL;
		}

		props->orientation = val;
		dev_dbg(dev, "device orientation: %u\n", val);
	}

	props->rotation = V4L2_FWNODE_PROPERTY_UNSET;
	ret = fwnode_property_read_u32(fwnode, "rotation", &val);
	if (!ret) {
		if (val >= 360) {
			dev_warn(dev, "Unsupported device rotation: %u\n", val);
			return -EINVAL;
		}

		props->rotation = val;
		dev_dbg(dev, "device rotation: %u\n", val);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_device_parse);

static int
v4l2_async_nf_fwnode_parse_endpoint(struct device *dev,
				    struct v4l2_async_notifier *notifier,
				    struct fwnode_handle *endpoint,
				    unsigned int asd_struct_size,
				    parse_endpoint_func parse_endpoint)
{
	struct v4l2_fwnode_endpoint vep = { .bus_type = 0 };
	struct v4l2_async_subdev *asd;
	int ret;

	asd = kzalloc(asd_struct_size, GFP_KERNEL);
	if (!asd)
		return -ENOMEM;

	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
	asd->match.fwnode =
		fwnode_graph_get_remote_port_parent(endpoint);
	if (!asd->match.fwnode) {
		dev_dbg(dev, "no remote endpoint found\n");
		ret = -ENOTCONN;
		goto out_err;
	}

	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &vep);
	if (ret) {
		dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n",
			 ret);
		goto out_err;
	}

	ret = parse_endpoint ? parse_endpoint(dev, &vep, asd) : 0;
	if (ret == -ENOTCONN)
		dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep.base.port,
			vep.base.id);
	else if (ret < 0)
		dev_warn(dev,
			 "driver could not parse port@%u/endpoint@%u (%d)\n",
			 vep.base.port, vep.base.id, ret);
	v4l2_fwnode_endpoint_free(&vep);
	if (ret < 0)
		goto out_err;

	ret = __v4l2_async_nf_add_subdev(notifier, asd);
	if (ret < 0) {
		/* not an error if asd already exists */
		if (ret == -EEXIST)
			ret = 0;
		goto out_err;
	}

	return 0;

out_err:
	fwnode_handle_put(asd->match.fwnode);
	kfree(asd);

	return ret == -ENOTCONN ? 0 : ret;
}

int
v4l2_async_nf_parse_fwnode_endpoints(struct device *dev,
				     struct v4l2_async_notifier *notifier,
				     size_t asd_struct_size,
				     parse_endpoint_func parse_endpoint)
{
	struct fwnode_handle *fwnode;
	int ret = 0;

	if (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))
		return -EINVAL;

	fwnode_graph_for_each_endpoint(dev_fwnode(dev), fwnode) {
		struct fwnode_handle *dev_fwnode;
		bool is_available;

		dev_fwnode = fwnode_graph_get_port_parent(fwnode);
		is_available = fwnode_device_is_available(dev_fwnode);
		fwnode_handle_put(dev_fwnode);
		if (!is_available)
			continue;


		ret = v4l2_async_nf_fwnode_parse_endpoint(dev, notifier,
							  fwnode,
							  asd_struct_size,
							  parse_endpoint);
		if (ret < 0)
			break;
	}

	fwnode_handle_put(fwnode);

	return ret;
}
EXPORT_SYMBOL_GPL(v4l2_async_nf_parse_fwnode_endpoints);

/*
 * v4l2_fwnode_reference_parse - parse references for async sub-devices
 * @dev: the device node the properties of which are parsed for references
 * @notifier: the async notifier where the async subdevs will be added
 * @prop: the name of the property
 *
 * Return: 0 on success
 *	   -ENOENT if no entries were found
 *	   -ENOMEM if memory allocation failed
 *	   -EINVAL if property parsing failed
 */
static int v4l2_fwnode_reference_parse(struct device *dev,
				       struct v4l2_async_notifier *notifier,
				       const char *prop)
{
	struct fwnode_reference_args args;
	unsigned int index;
	int ret;

	for (index = 0;
	     !(ret = fwnode_property_get_reference_args(dev_fwnode(dev), prop,
							NULL, 0, index, &args));
	     index++) {
		struct v4l2_async_subdev *asd;

		asd = v4l2_async_nf_add_fwnode(notifier, args.fwnode,
					       struct v4l2_async_subdev);
		fwnode_handle_put(args.fwnode);
		if (IS_ERR(asd)) {
			/* not an error if asd already exists */
			if (PTR_ERR(asd) == -EEXIST)
				continue;

			return PTR_ERR(asd);
		}
	}

	/* -ENOENT here means successful parsing */
	if (ret != -ENOENT)
		return ret;

	/* Return -ENOENT if no references were found */
	return index ? 0 : -ENOENT;
}

/*
 * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
 *					arguments
 * @fwnode: fwnode to read @prop from
 * @notifier: notifier for @dev
 * @prop: the name of the property
 * @index: the index of the reference to get
 * @props: the array of integer property names
 * @nprops: the number of integer property names in @nprops
 *
 * First find an fwnode referred to by the reference at @index in @prop.
 *
 * Then under that fwnode, @nprops times, for each property in @props,
 * iteratively follow child nodes starting from fwnode such that they have the
 * property in @props array at the index of the child node distance from the
 * root node and the value of that property matching with the integer argument
 * of the reference, at the same index.
 *
 * The child fwnode reached at the end of the iteration is then returned to the
 * caller.
 *
 * The core reason for this is that you cannot refer to just any node in ACPI.
 * So to refer to an endpoint (easy in DT) you need to refer to a device, then
 * provide a list of (property name, property value) tuples where each tuple
 * uniquely identifies a child node. The first tuple identifies a child directly
 * underneath the device fwnode, the next tuple identifies a child node
 * underneath the fwnode identified by the previous tuple, etc. until you
 * reached the fwnode you need.
 *
 * THIS EXAMPLE EXISTS MERELY TO DOCUMENT THIS FUNCTION. DO NOT USE IT AS A
 * REFERENCE IN HOW ACPI TABLES SHOULD BE WRITTEN!! See documentation under
 * Documentation/firmware-guide/acpi/dsd/ instead and especially graph.txt,
 * data-node-references.txt and leds.txt .
 *
 *	Scope (\_SB.PCI0.I2C2)
 *	{
 *		Device (CAM0)
 *		{
 *			Name (_DSD, Package () {
 *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 *				Package () {
 *					Package () {
 *						"compatible",
 *						Package () { "nokia,smia" }
 *					},
 *				},
 *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
 *				Package () {
 *					Package () { "port0", "PRT0" },
 *				}
 *			})
 *			Name (PRT0, Package() {
 *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 *				Package () {
 *					Package () { "port", 0 },
 *				},
 *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
 *				Package () {
 *					Package () { "endpoint0", "EP00" },
 *				}
 *			})
 *			Name (EP00, Package() {
 *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 *				Package () {
 *					Package () { "endpoint", 0 },
 *					Package () {
 *						"remote-endpoint",
 *						Package() {
 *							\_SB.PCI0.ISP, 4, 0
 *						}
 *					},
 *				}
 *			})
 *		}
 *	}
 *
 *	Scope (\_SB.PCI0)
 *	{
 *		Device (ISP)
 *		{
 *			Name (_DSD, Package () {
 *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
 *				Package () {
 *					Package () { "port4", "PRT4" },
 *				}
 *			})
 *
 *			Name (PRT4, Package() {
 *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 *				Package () {
 *					Package () { "port", 4 },
 *				},
 *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
 *				Package () {
 *					Package () { "endpoint0", "EP40" },
 *				}
 *			})
 *
 *			Name (EP40, Package() {
 *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 *				Package () {
 *					Package () { "endpoint", 0 },
 *					Package () {
 *						"remote-endpoint",
 *						Package () {
 *							\_SB.PCI0.I2C2.CAM0,
 *							0, 0
 *						}
 *					},
 *				}
 *			})
 *		}
 *	}
 *
 * From the EP40 node under ISP device, you could parse the graph remote
 * endpoint using v4l2_fwnode_reference_get_int_prop with these arguments:
 *
 *  @fwnode: fwnode referring to EP40 under ISP.
 *  @prop: "remote-endpoint"
 *  @index: 0
 *  @props: "port", "endpoint"
 *  @nprops: 2
 *
 * And you'd get back fwnode referring to EP00 under CAM0.
 *
 * The same works the other way around: if you use EP00 under CAM0 as the
 * fwnode, you'll get fwnode referring to EP40 under ISP.
 *
 * The same example in DT syntax would look like this:
 *
 * cam: cam0 {
 *	compatible = "nokia,smia";
 *
 *	port {
 *		port = <0>;
 *		endpoint {
 *			endpoint = <0>;
 *			remote-endpoint = <&isp 4 0>;
 *		};
 *	};
 * };
 *
 * isp: isp {
 *	ports {
 *		port@4 {
 *			port = <4>;
 *			endpoint {
 *				endpoint = <0>;
 *				remote-endpoint = <&cam 0 0>;
 *			};
 *		};
 *	};
 * };
 *
 * Return: 0 on success
 *	   -ENOENT if no entries (or the property itself) were found
 *	   -EINVAL if property parsing otherwise failed
 *	   -ENOMEM if memory allocation failed
 */
static struct fwnode_handle *
v4l2_fwnode_reference_get_int_prop(struct fwnode_handle *fwnode,
				   const char *prop,
				   unsigned int index,
				   const char * const *props,
				   unsigned int nprops)
{
	struct fwnode_reference_args fwnode_args;
	u64 *args = fwnode_args.args;
	struct fwnode_handle *child;
	int ret;

	/*
	 * Obtain remote fwnode as well as the integer arguments.
	 *
	 * Note that right now both -ENODATA and -ENOENT may signal
	 * out-of-bounds access. Return -ENOENT in that case.
	 */
	ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,
						 index, &fwnode_args);
	if (ret)
		return ERR_PTR(ret == -ENODATA ? -ENOENT : ret);

	/*
	 * Find a node in the tree under the referred fwnode corresponding to
	 * the integer arguments.
	 */
	fwnode = fwnode_args.fwnode;
	while (nprops--) {
		u32 val;

		/* Loop over all child nodes under fwnode. */
		fwnode_for_each_child_node(fwnode, child) {
			if (fwnode_property_read_u32(child, *props, &val))
				continue;

			/* Found property, see if its value matches. */
			if (val == *args)
				break;
		}

		fwnode_handle_put(fwnode);

		/* No property found; return an error here. */
		if (!child) {
			fwnode = ERR_PTR(-ENOENT);
			break;
		}

		props++;
		args++;
		fwnode = child;
	}

	return fwnode;
}

struct v4l2_fwnode_int_props {
	const char *name;
	const char * const *props;
	unsigned int nprops;
};

/*
 * v4l2_fwnode_reference_parse_int_props - parse references for async
 *					   sub-devices
 * @dev: struct device pointer
 * @notifier: notifier for @dev
 * @prop: the name of the property
 * @props: the array of integer property names
 * @nprops: the number of integer properties
 *
 * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in
 * property @prop with integer arguments with child nodes matching in properties
 * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
 * accordingly.
 *
 * While it is technically possible to use this function on DT, it is only
 * meaningful on ACPI. On Device tree you can refer to any node in the tree but
 * on ACPI the references are limited to devices.
 *
 * Return: 0 on success
 *	   -ENOENT if no entries (or the property itself) were found
 *	   -EINVAL if property parsing otherwisefailed
 *	   -ENOMEM if memory allocation failed
 */
static int
v4l2_fwnode_reference_parse_int_props(struct device *dev,
				      struct v4l2_async_notifier *notifier,
				      const struct v4l2_fwnode_int_props *p)
{
	struct fwnode_handle *fwnode;
	unsigned int index;
	int ret;
	const char *prop = p->name;
	const char * const *props = p->props;
	unsigned int nprops = p->nprops;

	index = 0;
	do {
		fwnode = v4l2_fwnode_reference_get_int_prop(dev_fwnode(dev),
							    prop, index,
							    props, nprops);
		if (IS_ERR(fwnode)) {
			/*
			 * Note that right now both -ENODATA and -ENOENT may
			 * signal out-of-bounds access. Return the error in
			 * cases other than that.
			 */
			if (PTR_ERR(fwnode) != -ENOENT &&
			    PTR_ERR(fwnode) != -ENODATA)
				return PTR_ERR(fwnode);
			break;
		}
		fwnode_handle_put(fwnode);
		index++;
	} while (1);

	for (index = 0;
	     !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(dev_fwnode(dev),
								  prop, index,
								  props,
								  nprops)));
	     index++) {
		struct v4l2_async_subdev *asd;

		asd = v4l2_async_nf_add_fwnode(notifier, fwnode,
					       struct v4l2_async_subdev);
		fwnode_handle_put(fwnode);
		if (IS_ERR(asd)) {
			ret = PTR_ERR(asd);
			/* not an error if asd already exists */
			if (ret == -EEXIST)
				continue;

			return PTR_ERR(asd);
		}
	}

	return !fwnode || PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);
}

/**
 * v4l2_async_nf_parse_fwnode_sensor - parse common references on
 *					     sensors for async sub-devices
 * @dev: the device node the properties of which are parsed for references
 * @notifier: the async notifier where the async subdevs will be added
 *
 * Parse common sensor properties for remote devices related to the
 * sensor and set up async sub-devices for them.
 *
 * Any notifier populated using this function must be released with a call to
 * v4l2_async_nf_release() after it has been unregistered and the async
 * sub-devices are no longer in use, even in the case the function returned an
 * error.
 *
 * Return: 0 on success
 *	   -ENOMEM if memory allocation failed
 *	   -EINVAL if property parsing failed
 */
static int
v4l2_async_nf_parse_fwnode_sensor(struct device *dev,
				  struct v4l2_async_notifier *notifier)
{
	static const char * const led_props[] = { "led" };
	static const struct v4l2_fwnode_int_props props[] = {
		{ "flash-leds", led_props, ARRAY_SIZE(led_props) },
		{ "lens-focus", NULL, 0 },
	};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(props); i++) {
		int ret;

		if (props[i].props && is_acpi_node(dev_fwnode(dev)))
			ret = v4l2_fwnode_reference_parse_int_props(dev,
								    notifier,
								    &props[i]);
		else
			ret = v4l2_fwnode_reference_parse(dev, notifier,
							  props[i].name);
		if (ret && ret != -ENOENT) {
			dev_warn(dev, "parsing property \"%s\" failed (%d)\n",
				 props[i].name, ret);
			return ret;
		}
	}

	return 0;
}

int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd)
{
	struct v4l2_async_notifier *notifier;
	int ret;

	if (WARN_ON(!sd->dev))
		return -ENODEV;

	notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
	if (!notifier)
		return -ENOMEM;

	v4l2_async_nf_init(notifier);

	ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier);
	if (ret < 0)
		goto out_cleanup;

	ret = v4l2_async_subdev_nf_register(sd, notifier);
	if (ret < 0)
		goto out_cleanup;

	ret = v4l2_async_register_subdev(sd);
	if (ret < 0)
		goto out_unregister;

	sd->subdev_notifier = notifier;

	return 0;

out_unregister:
	v4l2_async_nf_unregister(notifier);

out_cleanup:
	v4l2_async_nf_cleanup(notifier);
	kfree(notifier);

	return ret;
}
EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
