// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
// Copyright(c) 2015-17 Intel Corporation.

#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <sound/sdca.h>
#include "bus.h"
#include "sysfs_local.h"

static void sdw_slave_release(struct device *dev)
{
	struct sdw_slave *slave = dev_to_sdw_dev(dev);

	of_node_put(slave->dev.of_node);
	mutex_destroy(&slave->sdw_dev_lock);
	kfree(slave);
}

const struct device_type sdw_slave_type = {
	.name =		"sdw_slave",
	.release =	sdw_slave_release,
	.uevent =	sdw_slave_uevent,
};

int sdw_slave_add(struct sdw_bus *bus,
		  struct sdw_slave_id *id, struct fwnode_handle *fwnode)
{
	struct sdw_slave *slave;
	int ret;
	int i;

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

	/* Initialize data structure */
	memcpy(&slave->id, id, sizeof(*id));
	slave->dev.parent = bus->dev;
	slave->dev.fwnode = fwnode;

	if (id->unique_id == SDW_IGNORED_UNIQUE_ID) {
		/* name shall be sdw:ctrl:link:mfg:part:class */
		dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x",
			     bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
			     id->class_id);
	} else {
		/* name shall be sdw:ctrl:link:mfg:part:class:unique */
		dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x:%01x",
			     bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
			     id->class_id, id->unique_id);
	}

	slave->dev.bus = &sdw_bus_type;
	slave->dev.of_node = of_node_get(to_of_node(fwnode));
	slave->dev.type = &sdw_slave_type;
	slave->dev.groups = sdw_slave_status_attr_groups;
	slave->bus = bus;
	slave->status = SDW_SLAVE_UNATTACHED;
	init_completion(&slave->enumeration_complete);
	init_completion(&slave->initialization_complete);
	slave->dev_num = 0;
	slave->probed = false;
	slave->first_interrupt_done = false;
	mutex_init(&slave->sdw_dev_lock);

	for (i = 0; i < SDW_MAX_PORTS; i++)
		init_completion(&slave->port_ready[i]);

	mutex_lock(&bus->bus_lock);
	list_add_tail(&slave->node, &bus->slaves);
	mutex_unlock(&bus->bus_lock);

	/*
	 * The Soundwire driver probe may optionally register SDCA
	 * sub-devices, one per Function. This means the information
	 * on the SDCA revision and the number/type of Functions need
	 * to be extracted from platform firmware before the SoundWire
	 * driver probe, and as a consequence before the SoundWire
	 * device_register() below.
	 */
	sdca_lookup_interface_revision(slave);
	sdca_lookup_functions(slave);

	ret = device_register(&slave->dev);
	if (ret) {
		dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);

		/*
		 * On err, don't free but drop ref as this will be freed
		 * when release method is invoked.
		 */
		mutex_lock(&bus->bus_lock);
		list_del(&slave->node);
		mutex_unlock(&bus->bus_lock);
		put_device(&slave->dev);

		return ret;
	}
	sdw_slave_debugfs_init(slave);

	return ret;
}
EXPORT_SYMBOL(sdw_slave_add);

#if IS_ENABLED(CONFIG_ACPI)

static bool find_slave(struct sdw_bus *bus,
		       struct acpi_device *adev,
		       struct sdw_slave_id *id)
{
	unsigned int link_id;
	u64 addr;
	int ret;

	ret = acpi_get_local_u64_address(adev->handle, &addr);
	if (ret < 0)
		return false;

	if (bus->ops->override_adr)
		addr = bus->ops->override_adr(bus, addr);

	if (!addr)
		return false;

	/* Extract link id from ADR, Bit 51 to 48 (included) */
	link_id = SDW_DISCO_LINK_ID(addr);

	/* Check for link_id match */
	if (link_id != bus->link_id)
		return false;

	sdw_extract_slave_id(bus, addr, id);

	return true;
}

struct sdw_acpi_child_walk_data {
	struct sdw_bus *bus;
	struct acpi_device *adev;
	struct sdw_slave_id id;
	bool ignore_unique_id;
};

static int sdw_acpi_check_duplicate(struct acpi_device *adev, void *data)
{
	struct sdw_acpi_child_walk_data *cwd = data;
	struct sdw_bus *bus = cwd->bus;
	struct sdw_slave_id id;

	if (adev == cwd->adev)
		return 0;

	if (!find_slave(bus, adev, &id))
		return 0;

	if (cwd->id.sdw_version != id.sdw_version || cwd->id.mfg_id != id.mfg_id ||
	    cwd->id.part_id != id.part_id || cwd->id.class_id != id.class_id)
		return 0;

	if (cwd->id.unique_id != id.unique_id) {
		dev_dbg(bus->dev,
			"Valid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n",
			cwd->id.unique_id, id.unique_id, cwd->id.mfg_id,
			cwd->id.part_id);
		cwd->ignore_unique_id = false;
		return 0;
	}

	dev_err(bus->dev,
		"Invalid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n",
		cwd->id.unique_id, id.unique_id, cwd->id.mfg_id, cwd->id.part_id);
	return -ENODEV;
}

static int sdw_acpi_find_one(struct acpi_device *adev, void *data)
{
	struct sdw_bus *bus = data;
	struct sdw_acpi_child_walk_data cwd = {
		.bus = bus,
		.adev = adev,
		.ignore_unique_id = true,
	};
	int ret;

	if (!find_slave(bus, adev, &cwd.id))
		return 0;

	/* Brute-force O(N^2) search for duplicates. */
	ret = acpi_dev_for_each_child(ACPI_COMPANION(bus->dev),
				      sdw_acpi_check_duplicate, &cwd);
	if (ret)
		return ret;

	if (cwd.ignore_unique_id)
		cwd.id.unique_id = SDW_IGNORED_UNIQUE_ID;

	/* Ignore errors and continue. */
	sdw_slave_add(bus, &cwd.id, acpi_fwnode_handle(adev));
	return 0;
}

/*
 * sdw_acpi_find_slaves() - Find Slave devices in Master ACPI node
 * @bus: SDW bus instance
 *
 * Scans Master ACPI node for SDW child Slave devices and registers it.
 */
int sdw_acpi_find_slaves(struct sdw_bus *bus)
{
	struct acpi_device *parent;

	parent = ACPI_COMPANION(bus->dev);
	if (!parent) {
		dev_err(bus->dev, "Can't find parent for acpi bind\n");
		return -ENODEV;
	}

	return acpi_dev_for_each_child(parent, sdw_acpi_find_one, bus);
}

#endif

/*
 * sdw_of_find_slaves() - Find Slave devices in master device tree node
 * @bus: SDW bus instance
 *
 * Scans Master DT node for SDW child Slave devices and registers it.
 */
int sdw_of_find_slaves(struct sdw_bus *bus)
{
	struct device *dev = bus->dev;
	struct device_node *node;

	for_each_child_of_node(bus->dev->of_node, node) {
		int link_id, ret, len;
		unsigned int sdw_version;
		const char *compat = NULL;
		struct sdw_slave_id id;
		const __be32 *addr;

		compat = of_get_property(node, "compatible", NULL);
		if (!compat)
			continue;

		ret = sscanf(compat, "sdw%01x%04hx%04hx%02hhx", &sdw_version,
			     &id.mfg_id, &id.part_id, &id.class_id);

		if (ret != 4) {
			dev_err(dev, "Invalid compatible string found %s\n",
				compat);
			continue;
		}

		addr = of_get_property(node, "reg", &len);
		if (!addr || (len < 2 * sizeof(u32))) {
			dev_err(dev, "Invalid Link and Instance ID\n");
			continue;
		}

		link_id = be32_to_cpup(addr++);
		id.unique_id = be32_to_cpup(addr);
		id.sdw_version = sdw_version;

		/* Check for link_id match */
		if (link_id != bus->link_id)
			continue;

		sdw_slave_add(bus, &id, of_fwnode_handle(node));
	}

	return 0;
}

struct device *of_sdw_find_device_by_node(struct device_node *np)
{
	return bus_find_device_by_of_node(&sdw_bus_type, np);
}
EXPORT_SYMBOL_GPL(of_sdw_find_device_by_node);

MODULE_IMPORT_NS("SND_SOC_SDCA");
