// SPDX-License-Identifier: GPL-2.0-only
/*
 * I2C multiplexer using GPIO API
 *
 * Peter Korsgaard <peter.korsgaard@barco.com>
 */

#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/platform_data/i2c-mux-gpio.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/bits.h>
#include <linux/gpio/consumer.h>
/* FIXME: stop poking around inside gpiolib */
#include "../../gpio/gpiolib.h"

struct gpiomux {
	struct i2c_mux_gpio_platform_data data;
	int ngpios;
	struct gpio_desc **gpios;
};

static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
{
	DECLARE_BITMAP(values, BITS_PER_TYPE(val));

	values[0] = val;

	gpiod_set_array_value_cansleep(mux->ngpios, mux->gpios, NULL, values);
}

static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
{
	struct gpiomux *mux = i2c_mux_priv(muxc);

	i2c_mux_gpio_set(mux, chan);

	return 0;
}

static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan)
{
	struct gpiomux *mux = i2c_mux_priv(muxc);

	i2c_mux_gpio_set(mux, mux->data.idle);

	return 0;
}

#ifdef CONFIG_ACPI

static int i2c_mux_gpio_get_acpi_adr(struct device *dev,
				     struct fwnode_handle *fwdev,
				     unsigned int *adr)

{
	unsigned long long adr64;
	acpi_status status;

	status = acpi_evaluate_integer(ACPI_HANDLE_FWNODE(fwdev),
				       METHOD_NAME__ADR,
				       NULL, &adr64);

	if (!ACPI_SUCCESS(status)) {
		dev_err(dev, "Cannot get address\n");
		return -EINVAL;
	}

	*adr = adr64;
	if (*adr != adr64) {
		dev_err(dev, "Address out of range\n");
		return -ERANGE;
	}

	return 0;
}

#else

static int i2c_mux_gpio_get_acpi_adr(struct device *dev,
				     struct fwnode_handle *fwdev,
				     unsigned int *adr)
{
	return -EINVAL;
}

#endif

static int i2c_mux_gpio_probe_fw(struct gpiomux *mux,
				 struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *adapter_np;
	struct i2c_adapter *adapter = NULL;
	struct fwnode_handle *child;
	unsigned *values;
	int rc, i = 0;

	if (is_of_node(dev->fwnode)) {
		if (!np)
			return -ENODEV;

		adapter_np = of_parse_phandle(np, "i2c-parent", 0);
		if (!adapter_np) {
			dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
			return -ENODEV;
		}
		adapter = of_find_i2c_adapter_by_node(adapter_np);
		of_node_put(adapter_np);

	} else if (is_acpi_node(dev->fwnode)) {
		/*
		 * In ACPI land the mux should be a direct child of the i2c
		 * bus it muxes.
		 */
		acpi_handle dev_handle = ACPI_HANDLE(dev->parent);

		adapter = i2c_acpi_find_adapter_by_handle(dev_handle);
	}

	if (!adapter)
		return -EPROBE_DEFER;

	mux->data.parent = i2c_adapter_id(adapter);
	put_device(&adapter->dev);

	mux->data.n_values = device_get_child_node_count(dev);
	values = devm_kcalloc(dev,
			      mux->data.n_values, sizeof(*mux->data.values),
			      GFP_KERNEL);
	if (!values) {
		dev_err(dev, "Cannot allocate values array");
		return -ENOMEM;
	}

	device_for_each_child_node(dev, child) {
		if (is_of_node(child)) {
			fwnode_property_read_u32(child, "reg", values + i);

		} else if (is_acpi_node(child)) {
			rc = i2c_mux_gpio_get_acpi_adr(dev, child, values + i);
			if (rc)
				return rc;
		}

		i++;
	}
	mux->data.values = values;

	if (fwnode_property_read_u32(dev->fwnode, "idle-state", &mux->data.idle))
		mux->data.idle = I2C_MUX_GPIO_NO_IDLE;

	return 0;
}

static int i2c_mux_gpio_probe(struct platform_device *pdev)
{
	struct i2c_mux_core *muxc;
	struct gpiomux *mux;
	struct i2c_adapter *parent;
	struct i2c_adapter *root;
	unsigned initial_state;
	int i, ngpios, ret;

	mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
	if (!mux)
		return -ENOMEM;

	if (!dev_get_platdata(&pdev->dev)) {
		ret = i2c_mux_gpio_probe_fw(mux, pdev);
		if (ret < 0)
			return ret;
	} else {
		memcpy(&mux->data, dev_get_platdata(&pdev->dev),
			sizeof(mux->data));
	}

	ngpios = gpiod_count(&pdev->dev, "mux");
	if (ngpios <= 0) {
		dev_err(&pdev->dev, "no valid gpios provided\n");
		return ngpios ?: -EINVAL;
	}
	mux->ngpios = ngpios;

	parent = i2c_get_adapter(mux->data.parent);
	if (!parent)
		return -EPROBE_DEFER;

	muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values,
			     ngpios * sizeof(*mux->gpios), 0,
			     i2c_mux_gpio_select, NULL);
	if (!muxc) {
		ret = -ENOMEM;
		goto alloc_failed;
	}
	mux->gpios = muxc->priv;
	muxc->priv = mux;

	platform_set_drvdata(pdev, muxc);

	root = i2c_root_adapter(&parent->dev);

	muxc->mux_locked = true;

	if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) {
		initial_state = mux->data.idle;
		muxc->deselect = i2c_mux_gpio_deselect;
	} else {
		initial_state = mux->data.values[0];
	}

	for (i = 0; i < ngpios; i++) {
		struct device *gpio_dev;
		struct gpio_desc *gpiod;
		enum gpiod_flags flag;

		if (initial_state & BIT(i))
			flag = GPIOD_OUT_HIGH;
		else
			flag = GPIOD_OUT_LOW;
		gpiod = devm_gpiod_get_index(&pdev->dev, "mux", i, flag);
		if (IS_ERR(gpiod)) {
			ret = PTR_ERR(gpiod);
			goto alloc_failed;
		}

		mux->gpios[i] = gpiod;

		if (!muxc->mux_locked)
			continue;

		/* FIXME: find a proper way to access the GPIO device */
		gpio_dev = &gpiod->gdev->dev;
		muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
	}

	if (muxc->mux_locked)
		dev_info(&pdev->dev, "mux-locked i2c mux\n");

	for (i = 0; i < mux->data.n_values; i++) {
		u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
		unsigned int class = mux->data.classes ? mux->data.classes[i] : 0;

		ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class);
		if (ret)
			goto add_adapter_failed;
	}

	dev_info(&pdev->dev, "%d port mux on %s adapter\n",
		 mux->data.n_values, parent->name);

	return 0;

add_adapter_failed:
	i2c_mux_del_adapters(muxc);
alloc_failed:
	i2c_put_adapter(parent);

	return ret;
}

static int i2c_mux_gpio_remove(struct platform_device *pdev)
{
	struct i2c_mux_core *muxc = platform_get_drvdata(pdev);

	i2c_mux_del_adapters(muxc);
	i2c_put_adapter(muxc->parent);

	return 0;
}

static const struct of_device_id i2c_mux_gpio_of_match[] = {
	{ .compatible = "i2c-mux-gpio", },
	{},
};
MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match);

static struct platform_driver i2c_mux_gpio_driver = {
	.probe	= i2c_mux_gpio_probe,
	.remove	= i2c_mux_gpio_remove,
	.driver	= {
		.name	= "i2c-mux-gpio",
		.of_match_table = i2c_mux_gpio_of_match,
	},
};

module_platform_driver(i2c_mux_gpio_driver);

MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver");
MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:i2c-mux-gpio");
