// SPDX-License-Identifier: GPL-2.0+
/*
 * I2C multiplexer using GPIO API
 *
 * Copyright 2017 NXP
 *
 * Peng Fan <peng.fan@nxp.com>
 */

#include <asm/global_data.h>
#include <asm/io.h>
#include <asm-generic/gpio.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
#include <dm/pinctrl.h>
#include <fdtdec.h>
#include <i2c.h>
#include <linux/errno.h>
#include <linux/libfdt.h>

DECLARE_GLOBAL_DATA_PTR;

/**
 * struct i2c_mux_gpio_priv - private data for i2c mux gpio
 *
 * @values: the reg value of each child node
 * @n_values: num of regs
 * @gpios: the mux-gpios array
 * @n_gpios: num of gpios in mux-gpios
 * @idle: the value of idle-state
 */
struct i2c_mux_gpio_priv {
	u32 *values;
	int n_values;
	struct gpio_desc *gpios;
	int n_gpios;
	u32 idle;
};

static int i2c_mux_gpio_select(struct udevice *dev, struct udevice *bus,
			       uint channel)
{
	struct i2c_mux_gpio_priv *priv = dev_get_priv(dev);
	int i, ret;

	for (i = 0; i < priv->n_gpios; i++) {
		ret = dm_gpio_set_value(&priv->gpios[i], (channel >> i) & 1);
		if (ret)
			return ret;
	}

	return 0;
}

static int i2c_mux_gpio_deselect(struct udevice *dev, struct udevice *bus,
				 uint channel)
{
	struct i2c_mux_gpio_priv *priv = dev_get_priv(dev);
	int i, ret;

	for (i = 0; i < priv->n_gpios; i++) {
		ret = dm_gpio_set_value(&priv->gpios[i], (priv->idle >> i) & 1);
		if (ret)
			return ret;
	}

	return 0;
}

static int i2c_mux_gpio_probe(struct udevice *dev)
{
	const void *fdt = gd->fdt_blob;
	int node = dev_of_offset(dev);
	struct i2c_mux_gpio_priv *mux = dev_get_priv(dev);
	struct gpio_desc *gpios;
	u32 *values;
	int i = 0, subnode, ret;

	mux->n_values = fdtdec_get_child_count(fdt, node);
	values = devm_kzalloc(dev, sizeof(*mux->values) * mux->n_values,
			      GFP_KERNEL);
	if (!values) {
		dev_err(dev, "Cannot alloc values array");
		return -ENOMEM;
	}

	fdt_for_each_subnode(subnode, fdt, node) {
		*(values + i) = fdtdec_get_uint(fdt, subnode, "reg", -1);
		i++;
	}

	mux->values = values;

	mux->idle = fdtdec_get_uint(fdt, node, "idle-state", -1);

	mux->n_gpios = gpio_get_list_count(dev, "mux-gpios");
	if (mux->n_gpios < 0) {
		dev_err(dev, "Missing mux-gpios property\n");
		return -EINVAL;
	}

	gpios = devm_kzalloc(dev, sizeof(struct gpio_desc) * mux->n_gpios,
			     GFP_KERNEL);
	if (!gpios) {
		dev_err(dev, "Cannot allocate gpios array\n");
		return -ENOMEM;
	}

	ret = gpio_request_list_by_name(dev, "mux-gpios", gpios, mux->n_gpios,
					GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
	if (ret <= 0) {
		dev_err(dev, "Failed to request mux-gpios\n");
		return ret;
	}

	mux->gpios = gpios;

	return 0;
}

static const struct i2c_mux_ops i2c_mux_gpio_ops = {
	.select = i2c_mux_gpio_select,
	.deselect = i2c_mux_gpio_deselect,
};

static const struct udevice_id i2c_mux_gpio_ids[] = {
	{ .compatible = "i2c-mux-gpio", },
	{}
};

U_BOOT_DRIVER(i2c_mux_gpio) = {
	.name = "i2c_mux_gpio",
	.id = UCLASS_I2C_MUX,
	.of_match = i2c_mux_gpio_ids,
	.ops = &i2c_mux_gpio_ops,
	.probe = i2c_mux_gpio_probe,
	.priv_auto	= sizeof(struct i2c_mux_gpio_priv),
};
