// SPDX-License-Identifier: GPL-2.0
/*
 * Code to build software firmware node graph for atomisp2 connected sensors
 * from ACPI tables.
 *
 * Copyright (C) 2023 Hans de Goede <hdegoede@redhat.com>
 *
 * Based on drivers/media/pci/intel/ipu3/cio2-bridge.c written by:
 * Dan Scally <djrscally@gmail.com>
 */

#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/property.h>

#include <media/ipu-bridge.h>
#include <media/v4l2-fwnode.h>

#include "atomisp_cmd.h"
#include "atomisp_csi2.h"
#include "atomisp_internal.h"

#define PMC_CLK_RATE_19_2MHZ			19200000

/*
 * 79234640-9e10-4fea-a5c1-b5aa8b19756f
 * This _DSM GUID returns information about the GPIO lines mapped to a sensor.
 * Function number 1 returns a count of the GPIO lines that are mapped.
 * Subsequent functions return 32 bit ints encoding information about the GPIO.
 */
static const guid_t intel_sensor_gpio_info_guid =
	GUID_INIT(0x79234640, 0x9e10, 0x4fea,
		  0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);

#define INTEL_GPIO_DSM_TYPE_SHIFT			0
#define INTEL_GPIO_DSM_TYPE_MASK			GENMASK(7, 0)
#define INTEL_GPIO_DSM_PIN_SHIFT			8
#define INTEL_GPIO_DSM_PIN_MASK				GENMASK(15, 8)
#define INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT		24
#define INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK		GENMASK(31, 24)

#define INTEL_GPIO_DSM_TYPE(x) \
	(((x) & INTEL_GPIO_DSM_TYPE_MASK) >> INTEL_GPIO_DSM_TYPE_SHIFT)
#define INTEL_GPIO_DSM_PIN(x) \
	(((x) & INTEL_GPIO_DSM_PIN_MASK) >> INTEL_GPIO_DSM_PIN_SHIFT)
#define INTEL_GPIO_DSM_SENSOR_ON_VAL(x) \
	(((x) & INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK) >> INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT)

/*
 * 822ace8f-2814-4174-a56b-5f029fe079ee
 * This _DSM GUID returns a string from the sensor device, which acts as a
 * module identifier.
 */
static const guid_t intel_sensor_module_guid =
	GUID_INIT(0x822ace8f, 0x2814, 0x4174,
		  0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);

/*
 * dc2f6c4f-045b-4f1d-97b9-882a6860a4be
 * This _DSM GUID returns a package with n*2 strings, with each set of 2 strings
 * forming a key, value pair for settings like e.g. "CsiLanes" = "1".
 */
static const guid_t atomisp_dsm_guid =
	GUID_INIT(0xdc2f6c4f, 0x045b, 0x4f1d,
		  0x97, 0xb9, 0x88, 0x2a, 0x68, 0x60, 0xa4, 0xbe);

/*
 * 75c9a639-5c8a-4a00-9f48-a9c3b5da789f
 * This _DSM GUID returns a string giving the VCM type e.g. "AD5823".
 */
static const guid_t vcm_dsm_guid =
	GUID_INIT(0x75c9a639, 0x5c8a, 0x4a00,
		  0x9f, 0x48, 0xa9, 0xc3, 0xb5, 0xda, 0x78, 0x9f);

struct atomisp_sensor_config {
	int lanes;
	bool vcm;
};

#define ATOMISP_SENSOR_CONFIG(_HID, _LANES, _VCM)			\
{									\
	.id = _HID,							\
	.driver_data = (long)&((const struct atomisp_sensor_config) {	\
		.lanes = _LANES,					\
		.vcm = _VCM,						\
	})								\
}

/*
 * gmin_cfg parsing code. This is a cleaned up version of the gmin_cfg parsing
 * code from atomisp_gmin_platform.c.
 * Once all sensors are moved to v4l2-async probing atomisp_gmin_platform.c can
 * be removed and the duplication of this code goes away.
 */
struct gmin_cfg_var {
	const char *acpi_dev_name;
	const char *key;
	const char *val;
};

static struct gmin_cfg_var lenovo_ideapad_miix_310_vars[] = {
	/* _DSM contains the wrong CsiPort! */
	{ "OVTI2680:01", "CsiPort", "0" },
	{}
};

static const struct dmi_system_id gmin_cfg_dmi_overrides[] = {
	{
		/* Lenovo Ideapad Miix 310 */
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10"),
		},
		.driver_data = lenovo_ideapad_miix_310_vars,
	},
	{}
};

static char *gmin_cfg_get_dsm(struct acpi_device *adev, const char *key)
{
	union acpi_object *obj, *key_el, *val_el;
	char *val = NULL;
	int i;

	obj = acpi_evaluate_dsm_typed(adev->handle, &atomisp_dsm_guid, 0, 0,
				      NULL, ACPI_TYPE_PACKAGE);
	if (!obj)
		return NULL;

	for (i = 0; i < obj->package.count - 1; i += 2) {
		key_el = &obj->package.elements[i + 0];
		val_el = &obj->package.elements[i + 1];

		if (key_el->type != ACPI_TYPE_STRING || val_el->type != ACPI_TYPE_STRING)
			break;

		if (!strcmp(key_el->string.pointer, key)) {
			val = kstrdup(val_el->string.pointer, GFP_KERNEL);
			if (!val)
				break;

			acpi_handle_info(adev->handle, "%s: Using DSM entry %s=%s\n",
					 dev_name(&adev->dev), key, val);
			break;
		}
	}

	ACPI_FREE(obj);
	return val;
}

static char *gmin_cfg_get_dmi_override(struct acpi_device *adev, const char *key)
{
	const struct dmi_system_id *id;
	struct gmin_cfg_var *gv;

	id = dmi_first_match(gmin_cfg_dmi_overrides);
	if (!id)
		return NULL;

	for (gv = id->driver_data; gv->acpi_dev_name; gv++) {
		if (strcmp(gv->acpi_dev_name, acpi_dev_name(adev)))
			continue;

		if (strcmp(key, gv->key))
			continue;

		acpi_handle_info(adev->handle, "%s: Using DMI entry %s=%s\n",
				 dev_name(&adev->dev), key, gv->val);
		return kstrdup(gv->val, GFP_KERNEL);
	}

	return NULL;
}

static char *gmin_cfg_get(struct acpi_device *adev, const char *key)
{
	char *val;

	val = gmin_cfg_get_dmi_override(adev, key);
	if (val)
		return val;

	return gmin_cfg_get_dsm(adev, key);
}

static int gmin_cfg_get_int(struct acpi_device *adev, const char *key, int default_val)
{
	char *str_val;
	long int_val;
	int ret;

	str_val = gmin_cfg_get(adev, key);
	if (!str_val)
		goto out_use_default;

	ret = kstrtoul(str_val, 0, &int_val);
	kfree(str_val);
	if (ret)
		goto out_use_default;

	return int_val;

out_use_default:
	acpi_handle_info(adev->handle, "%s: Using default %s=%d\n",
			 dev_name(&adev->dev), key, default_val);
	return default_val;
}

static int atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(struct acpi_device *adev)
{
	/* ACPI_PATH_SEGMENT_LENGTH is guaranteed to be big enough for name + 0 term. */
	char name[ACPI_PATH_SEGMENT_LENGTH];
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer b_name = { sizeof(name), name };
	union acpi_object *package, *element;
	int i, ret = -ENOENT;
	acpi_handle rhandle;
	acpi_status status;
	u8 clock_num;

	status = acpi_evaluate_object_typed(adev->handle, "_PR0", NULL, &buffer, ACPI_TYPE_PACKAGE);
	if (ACPI_FAILURE(status))
		return -ENOENT;

	package = buffer.pointer;
	for (i = 0; i < package->package.count; i++) {
		element = &package->package.elements[i];

		if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
			continue;

		rhandle = element->reference.handle;
		if (!rhandle)
			continue;

		acpi_get_name(rhandle, ACPI_SINGLE_NAME, &b_name);

		if (str_has_prefix(name, "CLK") && !kstrtou8(&name[3], 10, &clock_num) &&
		    clock_num <= 4) {
			ret = clock_num;
			break;
		}
	}

	ACPI_FREE(buffer.pointer);

	if (ret < 0)
		acpi_handle_warn(adev->handle, "%s: Could not find PMC clk in _PR0\n",
				 dev_name(&adev->dev));

	return ret;
}

static int atomisp_csi2_set_pmc_clk_freq(struct acpi_device *adev, int clock_num)
{
	struct clk *clk;
	char name[14];
	int ret;

	if (clock_num < 0)
		return 0;

	snprintf(name, sizeof(name), "pmc_plt_clk_%d", clock_num);

	clk = clk_get(NULL, name);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		acpi_handle_err(adev->handle, "%s: Error getting clk %s: %d\n",
				dev_name(&adev->dev), name, ret);
		return ret;
	}

	/*
	 * The firmware might enable the clock at boot, to change
	 * the rate we must ensure the clock is disabled.
	 */
	ret = clk_prepare_enable(clk);
	if (!ret)
		clk_disable_unprepare(clk);
	if (!ret)
		ret = clk_set_rate(clk, PMC_CLK_RATE_19_2MHZ);
	if (ret)
		acpi_handle_err(adev->handle, "%s: Error setting clk-rate for %s: %d\n",
				dev_name(&adev->dev), name, ret);

	clk_put(clk);
	return ret;
}

static int atomisp_csi2_get_port(struct acpi_device *adev, int clock_num)
{
	int port;

	/*
	 * Compare clock-number to the PMC-clock used for CsiPort 1
	 * in the CHT/BYT reference designs.
	 */
	if (IS_ISP2401)
		port = clock_num == 4 ? 1 : 0;
	else
		port = clock_num == 0 ? 1 : 0;

	/* Intel DSM or DMI quirk overrides _PR0 CLK derived default */
	return gmin_cfg_get_int(adev, "CsiPort", port);
}

/* Note this always returns 1 to continue looping so that res_count is accurate */
static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_data)
{
	struct atomisp_csi2_acpi_gpio_parsing_data *data = _data;
	struct acpi_resource_gpio *agpio;
	const char *name;
	bool active_low;
	unsigned int i;
	u32 settings = 0;
	u16 pin;

	if (!acpi_gpio_get_io_resource(ares, &agpio))
		return 1; /* Not a GPIO, continue the loop */

	data->res_count++;

	pin = agpio->pin_table[0];
	for (i = 0; i < data->settings_count; i++) {
		if (INTEL_GPIO_DSM_PIN(data->settings[i]) == pin) {
			settings = data->settings[i];
			break;
		}
	}

	if (i == data->settings_count) {
		acpi_handle_warn(data->adev->handle,
				 "%s: Could not find DSM GPIO settings for pin %u\n",
				 dev_name(&data->adev->dev), pin);
		return 1;
	}

	switch (INTEL_GPIO_DSM_TYPE(settings)) {
	case 0:
		name = "reset-gpios";
		break;
	case 1:
		name = "powerdown-gpios";
		break;
	default:
		acpi_handle_warn(data->adev->handle, "%s: Unknown GPIO type 0x%02lx for pin %u\n",
				 dev_name(&data->adev->dev),
				 INTEL_GPIO_DSM_TYPE(settings), pin);
		return 1;
	}

	/*
	 * Both reset and power-down need to be logical false when the sensor
	 * is on (sensor should not be in reset and not be powered-down). So
	 * when the sensor-on-value (which is the physical pin value) is high,
	 * then the signal is active-low.
	 */
	active_low = INTEL_GPIO_DSM_SENSOR_ON_VAL(settings);

	i = data->map_count;
	if (i == CSI2_MAX_ACPI_GPIOS)
		return 1;

	/* res_count is already incremented */
	data->map->params[i].crs_entry_index = data->res_count - 1;
	data->map->params[i].active_low = active_low;
	data->map->mapping[i].name = name;
	data->map->mapping[i].data = &data->map->params[i];
	data->map->mapping[i].size = 1;
	data->map_count++;

	acpi_handle_info(data->adev->handle, "%s: %s crs %d %s pin %u active-%s\n",
			 dev_name(&data->adev->dev), name,
			 data->res_count - 1, agpio->resource_source.string_ptr,
			 pin, active_low ? "low" : "high");

	return 1;
}

/*
 * Helper function to create an ACPI GPIO lookup table for sensor reset and
 * powerdown signals on Intel Bay Trail (BYT) and Cherry Trail (CHT) devices,
 * including setting the correct polarity for the GPIO.
 *
 * This uses the "79234640-9e10-4fea-a5c1-b5aa8b19756f" DSM method directly
 * on the sensor device's ACPI node. This is different from later Intel
 * hardware which has a separate INT3472 acpi_device with this info.
 *
 * This function must be called before creating the sw-noded describing
 * the fwnode graph endpoint. And sensor drivers used on these devices
 * must return -EPROBE_DEFER when there is no endpoint description yet.
 * Together this guarantees that the GPIO lookups are in place before
 * the sensor driver tries to get GPIOs with gpiod_get().
 *
 * Note this code uses the same DSM GUID as the int3472_gpio_guid in
 * the INT3472 discrete.c code and there is some overlap, but there are
 * enough differences that it is difficult to share the code.
 */
static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev)
{
	struct atomisp_csi2_acpi_gpio_parsing_data data = { };
	LIST_HEAD(resource_list);
	union acpi_object *obj;
	unsigned int i, j;
	int ret;

	obj = acpi_evaluate_dsm_typed(adev->handle, &intel_sensor_module_guid,
				      0x00, 1, NULL, ACPI_TYPE_STRING);
	if (obj) {
		acpi_handle_info(adev->handle, "%s: Sensor module id: '%s'\n",
				 dev_name(&adev->dev), obj->string.pointer);
		ACPI_FREE(obj);
	}

	/*
	 * First get the GPIO-settings count and then get count GPIO-settings
	 * values. Note the order of these may differ from the order in which
	 * the GPIOs are listed on the ACPI resources! So we first store them all
	 * and then enumerate the ACPI resources and match them up by pin number.
	 */
	obj = acpi_evaluate_dsm_typed(adev->handle,
				      &intel_sensor_gpio_info_guid, 0x00, 1,
				      NULL, ACPI_TYPE_INTEGER);
	if (!obj) {
		acpi_handle_err(adev->handle, "%s: No _DSM entry for GPIO pin count\n",
				dev_name(&adev->dev));
		return -EIO;
	}

	data.settings_count = obj->integer.value;
	ACPI_FREE(obj);

	if (data.settings_count > CSI2_MAX_ACPI_GPIOS) {
		acpi_handle_err(adev->handle, "%s: Too many GPIOs %u > %u\n",
				dev_name(&adev->dev), data.settings_count,
				CSI2_MAX_ACPI_GPIOS);
		return -EOVERFLOW;
	}

	for (i = 0; i < data.settings_count; i++) {
		/*
		 * i + 2 because the index of this _DSM function is 1-based
		 * and the first function is just a count.
		 */
		obj = acpi_evaluate_dsm_typed(adev->handle,
					      &intel_sensor_gpio_info_guid,
					      0x00, i + 2,
					      NULL, ACPI_TYPE_INTEGER);
		if (!obj) {
			acpi_handle_err(adev->handle, "%s: No _DSM entry for pin %u\n",
					dev_name(&adev->dev), i);
			return -EIO;
		}

		data.settings[i] = obj->integer.value;
		ACPI_FREE(obj);
	}

	/* Since we match up by pin-number the pin-numbers must be unique */
	for (i = 0; i < data.settings_count; i++) {
		for (j = i + 1; j < data.settings_count; j++) {
			if (INTEL_GPIO_DSM_PIN(data.settings[i]) !=
			    INTEL_GPIO_DSM_PIN(data.settings[j]))
				continue;

			acpi_handle_err(adev->handle, "%s: Duplicate pin number %lu\n",
					dev_name(&adev->dev),
					INTEL_GPIO_DSM_PIN(data.settings[i]));
			return -EIO;
		}
	}

	data.map = kzalloc(sizeof(*data.map), GFP_KERNEL);
	if (!data.map)
		return -ENOMEM;

	/* Now parse the ACPI resources and build the lookup table */
	data.adev = adev;
	ret = acpi_dev_get_resources(adev, &resource_list,
				     atomisp_csi2_handle_acpi_gpio_res, &data);
	if (ret < 0)
		return ret;

	acpi_dev_free_resource_list(&resource_list);

	if (data.map_count != data.settings_count ||
	    data.res_count != data.settings_count)
		acpi_handle_warn(adev->handle, "%s: ACPI GPIO resources vs DSM GPIO-info count mismatch (dsm: %d res: %d map %d\n",
				 dev_name(&adev->dev), data.settings_count,
				 data.res_count, data.map_count);

	ret = acpi_dev_add_driver_gpios(adev, data.map->mapping);
	if (ret)
		acpi_handle_err(adev->handle, "%s: Error adding driver GPIOs: %d\n",
				dev_name(&adev->dev), ret);

	return ret;
}

static char *atomisp_csi2_get_vcm_type(struct acpi_device *adev)
{
	union acpi_object *obj;
	char *vcm_type;

	obj = acpi_evaluate_dsm_typed(adev->handle, &vcm_dsm_guid, 0, 0,
				      NULL, ACPI_TYPE_STRING);
	if (!obj)
		return NULL;

	vcm_type = kstrdup(obj->string.pointer, GFP_KERNEL);
	ACPI_FREE(obj);

	if (!vcm_type)
		return NULL;

	string_lower(vcm_type, vcm_type);
	return vcm_type;
}

static const struct acpi_device_id atomisp_sensor_configs[] = {
	/*
	 * FIXME ov5693 modules have a VCM, but for unknown reasons
	 * the sensor fails to start streaming when instantiating
	 * an i2c-client for the VCM, so it is disabled for now.
	 */
	ATOMISP_SENSOR_CONFIG("INT33BE", 2, false),	/* OV5693 */
	{}
};

static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev,
					    struct ipu_sensor *sensor)
{
	const struct acpi_device_id *id;
	int ret, clock_num;
	bool vcm = false;
	int lanes = 1;

	id = acpi_match_acpi_device(atomisp_sensor_configs, adev);
	if (id) {
		struct atomisp_sensor_config *cfg =
			(struct atomisp_sensor_config *)id->driver_data;

		lanes = cfg->lanes;
		vcm = cfg->vcm;
	}

	/*
	 * ACPI takes care of turning the PMC clock on and off, but on BYT
	 * the clock defaults to 25 MHz instead of the expected 19.2 MHz.
	 * Get the PMC-clock number from ACPI PR0 method and set it to 19.2 MHz.
	 * The PMC-clock number is also used to determine the default CSI port.
	 */
	clock_num = atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(adev);

	ret = atomisp_csi2_set_pmc_clk_freq(adev, clock_num);
	if (ret)
		return ret;

	sensor->link = atomisp_csi2_get_port(adev, clock_num);
	if (sensor->link >= ATOMISP_CAMERA_NR_PORTS) {
		acpi_handle_err(adev->handle, "%s: Invalid port: %u\n",
				dev_name(&adev->dev), sensor->link);
		return -EINVAL;
	}

	sensor->lanes = gmin_cfg_get_int(adev, "CsiLanes", lanes);
	if (sensor->lanes > IPU_MAX_LANES) {
		acpi_handle_err(adev->handle, "%s: Invalid lane-count: %d\n",
				dev_name(&adev->dev), sensor->lanes);
		return -EINVAL;
	}

	ret = atomisp_csi2_add_gpio_mappings(adev);
	if (ret)
		return ret;

	sensor->mclkspeed = PMC_CLK_RATE_19_2MHZ;
	sensor->rotation = 0;
	sensor->orientation = (sensor->link == 1) ?
		V4L2_FWNODE_ORIENTATION_BACK : V4L2_FWNODE_ORIENTATION_FRONT;

	if (vcm)
		sensor->vcm_type = atomisp_csi2_get_vcm_type(adev);

	return 0;
}

int atomisp_csi2_bridge_init(struct atomisp_device *isp)
{
	struct device *dev = isp->dev;
	struct fwnode_handle *fwnode;

	/*
	 * This function is intended to run only once and then leave
	 * the created nodes attached even after a rmmod, therefore:
	 * 1. The bridge memory is leaked deliberately on success
	 * 2. If a secondary fwnode is already set exit early.
	 */
	fwnode = dev_fwnode(dev);
	if (fwnode && fwnode->secondary)
		return 0;

	return ipu_bridge_init(dev, atomisp_csi2_parse_sensor_fwnode);
}

/******* V4L2 sub-device asynchronous registration callbacks***********/

struct sensor_async_subdev {
	struct v4l2_async_connection asd;
	int port;
};

#define to_sensor_asd(a)	container_of(a, struct sensor_async_subdev, asd)
#define notifier_to_atomisp(n)	container_of(n, struct atomisp_device, notifier)

/* .bound() notifier callback when a match is found */
static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier,
				  struct v4l2_subdev *sd,
				  struct v4l2_async_connection *asd)
{
	struct atomisp_device *isp = notifier_to_atomisp(notifier);
	struct sensor_async_subdev *s_asd = to_sensor_asd(asd);
	int ret;

	if (s_asd->port >= ATOMISP_CAMERA_NR_PORTS) {
		dev_err(isp->dev, "port %d not supported\n", s_asd->port);
		return -EINVAL;
	}

	if (isp->sensor_subdevs[s_asd->port]) {
		dev_err(isp->dev, "port %d already has a sensor attached\n", s_asd->port);
		return -EBUSY;
	}

	ret = ipu_bridge_instantiate_vcm(sd->dev);
	if (ret)
		return ret;

	isp->sensor_subdevs[s_asd->port] = sd;
	return 0;
}

/* The .unbind callback */
static void atomisp_notifier_unbind(struct v4l2_async_notifier *notifier,
				    struct v4l2_subdev *sd,
				    struct v4l2_async_connection *asd)
{
	struct atomisp_device *isp = notifier_to_atomisp(notifier);
	struct sensor_async_subdev *s_asd = to_sensor_asd(asd);

	isp->sensor_subdevs[s_asd->port] = NULL;
}

/* .complete() is called after all subdevices have been located */
static int atomisp_notifier_complete(struct v4l2_async_notifier *notifier)
{
	struct atomisp_device *isp = notifier_to_atomisp(notifier);

	return atomisp_register_device_nodes(isp);
}

static const struct v4l2_async_notifier_operations atomisp_async_ops = {
	.bound = atomisp_notifier_bound,
	.unbind = atomisp_notifier_unbind,
	.complete = atomisp_notifier_complete,
};

int atomisp_csi2_bridge_parse_firmware(struct atomisp_device *isp)
{
	int i, mipi_port, ret;

	v4l2_async_nf_init(&isp->notifier, &isp->v4l2_dev);
	isp->notifier.ops = &atomisp_async_ops;

	for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
		struct v4l2_fwnode_endpoint vep = {
			.bus_type = V4L2_MBUS_CSI2_DPHY,
		};
		struct sensor_async_subdev *s_asd;
		struct fwnode_handle *ep;

		ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(isp->dev), i, 0,
						     FWNODE_GRAPH_ENDPOINT_NEXT);
		if (!ep)
			continue;

		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
		if (ret)
			goto err_parse;

		if (vep.base.port >= ATOMISP_CAMERA_NR_PORTS) {
			dev_err(isp->dev, "port %d not supported\n", vep.base.port);
			ret = -EINVAL;
			goto err_parse;
		}

		mipi_port = atomisp_port_to_mipi_port(isp, vep.base.port);
		isp->sensor_lanes[mipi_port] = vep.bus.mipi_csi2.num_data_lanes;

		s_asd = v4l2_async_nf_add_fwnode_remote(&isp->notifier, ep,
							struct sensor_async_subdev);
		if (IS_ERR(s_asd)) {
			ret = PTR_ERR(s_asd);
			goto err_parse;
		}

		s_asd->port = vep.base.port;

		fwnode_handle_put(ep);
		continue;

err_parse:
		fwnode_handle_put(ep);
		return ret;
	}

	return 0;
}
