// 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,
};
EXPORT_SYMBOL_GPL(sdw_slave_type);

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_obj(*slave);
	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");
