// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2013 Google, Inc
 */

#define LOG_CATEGORY	UCLASS_GPIO

#include <dm.h>
#include <dt-structs.h>
#include <log.h>
#include <dm/devres.h>
#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
#include <dt-bindings/gpio/gpio.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
#include <acpi/acpi_device.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <dm/device_compat.h>
#include <linux/bug.h>
#include <linux/ctype.h>
#include <linux/delay.h>

DECLARE_GLOBAL_DATA_PTR;

#define GPIO_ALLOC_BITS	32

/**
 * gpio_desc_init() - Initialize the GPIO descriptor
 *
 * @desc:	GPIO descriptor to initialize
 * @dev:	GPIO device
 * @offset:	Offset of device GPIO
 */
static void gpio_desc_init(struct gpio_desc *desc,
			   struct udevice *dev,
			   uint offset)
{
	desc->dev = dev;
	desc->offset = offset;
	desc->flags = 0;
}

/**
 * gpio_to_device() - Convert global GPIO number to device, number
 *
 * Convert the GPIO number to an entry in the list of GPIOs
 * or GPIO blocks registered with the GPIO controller. Returns
 * entry on success, NULL on error.
 *
 * @gpio:	The numeric representation of the GPIO
 * @desc:	Returns description (desc->flags will always be 0)
 * Return: 0 if found, -ENOENT if not found
 */
static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
{
	struct gpio_dev_priv *uc_priv;
	struct udevice *dev;

	for (uclass_first_device(UCLASS_GPIO, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		uc_priv = dev_get_uclass_priv(dev);
		if (gpio >= uc_priv->gpio_base &&
		    gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
			gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
			return 0;
		}
	}

	/* No such GPIO */
	return -ENOENT;
}

/**
 * gpio_is_claimed() - Test whether GPIO is claimed by consumer
 *
 * Test whether GPIO is claimed by consumer already.
 *
 * @uc_priv:	gpio_dev_priv pointer.
 * @offset:	gpio offset within the device
 * @return:	true if claimed, false if not claimed
 */
static bool gpio_is_claimed(struct gpio_dev_priv *uc_priv, unsigned int offset)
{
	return !!(uc_priv->claimed[offset / GPIO_ALLOC_BITS] & BIT(offset % GPIO_ALLOC_BITS));
}

/**
 * gpio_set_claim() - Set GPIO claimed by consumer
 *
 * Set a bit which indicate the GPIO is claimed by consumer
 *
 * @uc_priv:	gpio_dev_priv pointer.
 * @offset:	gpio offset within the device
 */
static void gpio_set_claim(struct gpio_dev_priv *uc_priv, unsigned int offset)
{
	uc_priv->claimed[offset / GPIO_ALLOC_BITS] |= BIT(offset % GPIO_ALLOC_BITS);
}

/**
 * gpio_clear_claim() - Clear GPIO claimed by consumer
 *
 * Clear a bit which indicate the GPIO is claimed by consumer
 *
 * @uc_priv:	gpio_dev_priv pointer.
 * @offset:	gpio offset within the device
 */
static void gpio_clear_claim(struct gpio_dev_priv *uc_priv, unsigned int offset)
{
	uc_priv->claimed[offset / GPIO_ALLOC_BITS] &= ~BIT(offset % GPIO_ALLOC_BITS);
}

#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
/**
 * dm_gpio_lookup_label() - look for name in gpio device
 *
 * search in uc_priv, if there is a gpio with labelname same
 * as name.
 *
 * @name:	name which is searched
 * @uc_priv:	gpio_dev_priv pointer.
 * @offset:	gpio offset within the device
 * @return:	0 if found, -ENOENT if not.
 */
static int dm_gpio_lookup_label(const char *name,
				struct gpio_dev_priv *uc_priv, ulong *offset)
{
	int i;

	*offset = -1;
	for (i = 0; i < uc_priv->gpio_count; i++) {
		if (!gpio_is_claimed(uc_priv, i))
			continue;
		if (!strcmp(name, uc_priv->name[i])) {
			*offset = i;
			return 0;
		}
	}
	return -ENOENT;
}
#else
static int
dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
		     ulong *offset)
{
	return -ENOENT;
}
#endif

int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
{
	struct gpio_dev_priv *uc_priv = NULL;
	struct udevice *dev;
	ulong offset;
	int numeric;

	numeric = isdigit(*name) ? dectoul(name, NULL) : -1;
	for (uclass_first_device(UCLASS_GPIO, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		int len;

		uc_priv = dev_get_uclass_priv(dev);
		if (numeric != -1) {
			offset = numeric - uc_priv->gpio_base;
			/* Allow GPIOs to be numbered from 0 */
			if (offset < uc_priv->gpio_count)
				break;
		}

		len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;

		if (!strncasecmp(name, uc_priv->bank_name, len)) {
			if (!strict_strtoul(name + len, 10, &offset))
				if (offset < uc_priv->gpio_count)
					break;
		}

		/*
		 * if we did not found a gpio through its bank
		 * name, we search for a valid gpio label.
		 */
		if (!dm_gpio_lookup_label(name, uc_priv, &offset))
			break;
	}

	if (!dev)
		return -EINVAL;

	gpio_desc_init(desc, dev, offset);

	return 0;
}

int gpio_lookup_name(const char *name, struct udevice **devp,
		     unsigned int *offsetp, unsigned int *gpiop)
{
	struct gpio_desc desc;
	int ret;

	if (devp)
		*devp = NULL;
	ret = dm_gpio_lookup_name(name, &desc);
	if (ret)
		return ret;

	if (devp)
		*devp = desc.dev;
	if (offsetp)
		*offsetp = desc.offset;
	if (gpiop) {
		struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);

		*gpiop = uc_priv->gpio_base + desc.offset;
	}

	return 0;
}

unsigned long gpio_flags_xlate(uint32_t arg)
{
	unsigned long flags = 0;

	if (arg & GPIO_ACTIVE_LOW)
		flags |= GPIOD_ACTIVE_LOW;

	/*
	 * need to test 2 bits for gpio output binding:
	 * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
	 * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
	 */
	if (arg & GPIO_SINGLE_ENDED) {
		if (arg & GPIO_LINE_OPEN_DRAIN)
			flags |= GPIOD_OPEN_DRAIN;
		else
			flags |= GPIOD_OPEN_SOURCE;
	}

	if (arg & GPIO_PULL_UP)
		flags |= GPIOD_PULL_UP;

	if (arg & GPIO_PULL_DOWN)
		flags |= GPIOD_PULL_DOWN;

	return flags;
}

int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
			  struct ofnode_phandle_args *args)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	if (args->args_count < 1)
		return -EINVAL;

	desc->offset = args->args[0];
	if (desc->offset >= uc_priv->gpio_count)
		return -EINVAL;

	if (args->args_count < 2)
		return 0;

	desc->flags = gpio_flags_xlate(args->args[1]);

	return 0;
}

static int gpio_find_and_xlate(struct gpio_desc *desc,
			       struct ofnode_phandle_args *args)
{
	const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);

	if (ops->xlate)
		return ops->xlate(desc->dev, desc, args);
	else
		return gpio_xlate_offs_flags(desc->dev, desc, args);
}

#if CONFIG_IS_ENABLED(GPIO_HOG)

struct gpio_hog_priv {
	struct gpio_desc gpiod;
};

struct gpio_hog_data {
	int gpiod_flags;
	int value;
	u32 val[2];
};

static int gpio_hog_of_to_plat(struct udevice *dev)
{
	struct gpio_hog_data *plat = dev_get_plat(dev);
	const char *nodename;
	int ret;

	plat->value = 0;
	if (dev_read_bool(dev, "input")) {
		plat->gpiod_flags = GPIOD_IS_IN;
	} else if (dev_read_bool(dev, "output-high")) {
		plat->value = 1;
		plat->gpiod_flags = GPIOD_IS_OUT;
	} else if (dev_read_bool(dev, "output-low")) {
		plat->gpiod_flags = GPIOD_IS_OUT;
	} else {
		printf("%s: missing gpio-hog state.\n", __func__);
		return -EINVAL;
	}
	ret = dev_read_u32_array(dev, "gpios", plat->val, 2);
	if (ret) {
		printf("%s: wrong gpios property, 2 values needed %d\n",
		       __func__, ret);
		return ret;
	}
	nodename = dev_read_string(dev, "line-name");
	if (nodename)
		device_set_name(dev, nodename);

	return 0;
}

static int gpio_hog_probe(struct udevice *dev)
{
	struct gpio_hog_data *plat = dev_get_plat(dev);
	struct gpio_hog_priv *priv = dev_get_priv(dev);
	int ret;

	ret = gpio_dev_request_index(dev->parent, dev->name, "gpio-hog",
				     plat->val[0], plat->gpiod_flags,
				     plat->val[1], &priv->gpiod);
	if (ret < 0) {
		debug("%s: node %s could not get gpio.\n", __func__,
		      dev->name);
		return ret;
	}

	if (plat->gpiod_flags == GPIOD_IS_OUT) {
		ret = dm_gpio_set_value(&priv->gpiod, plat->value);
		if (ret < 0) {
			debug("%s: node %s could not set gpio.\n", __func__,
			      dev->name);
			return ret;
		}
	}

	return 0;
}

int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
{
	struct udevice *dev;

	*desc = NULL;
	if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
		struct gpio_hog_priv *priv = dev_get_priv(dev);

		*desc = &priv->gpiod;
		return 0;
	}

	return -ENODEV;
}

U_BOOT_DRIVER(gpio_hog) = {
	.name	= "gpio_hog",
	.id	= UCLASS_NOP,
	.of_to_plat = gpio_hog_of_to_plat,
	.probe = gpio_hog_probe,
	.priv_auto	= sizeof(struct gpio_hog_priv),
	.plat_auto	= sizeof(struct gpio_hog_data),
};
#else
int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
{
	return 0;
}
#endif

int dm_gpio_request(struct gpio_desc *desc, const char *label)
{
	const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
	struct udevice *dev = desc->dev;
	struct gpio_dev_priv *uc_priv;
	char *str;
	int ret;

	uc_priv = dev_get_uclass_priv(dev);
	if (gpio_is_claimed(uc_priv, desc->offset))
		return -EBUSY;
	str = strdup(label);
	if (!str)
		return -ENOMEM;
	if (ops->request) {
		ret = ops->request(dev, desc->offset, label);
		if (ret) {
			free(str);
			return ret;
		}
	}

	gpio_set_claim(uc_priv, desc->offset);
	uc_priv->name[desc->offset] = str;

	return 0;
}

static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
{
#if !defined(CONFIG_XPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
	va_list args;
	char buf[40];

	va_start(args, fmt);
	vscnprintf(buf, sizeof(buf), fmt, args);
	va_end(args);
	return dm_gpio_request(desc, buf);
#else
	return dm_gpio_request(desc, fmt);
#endif
}

/**
 * gpio_request() - [COMPAT] Request GPIO
 * gpio:	GPIO number
 * label:	Name for the requested GPIO
 *
 * The label is copied and allocated so the caller does not need to keep
 * the pointer around.
 *
 * This function implements the API that's compatible with current
 * GPIO API used in U-Boot. The request is forwarded to particular
 * GPIO driver. Returns 0 on success, negative value on error.
 */
int gpio_request(unsigned gpio, const char *label)
{
	struct gpio_desc desc;
	int ret;

	ret = gpio_to_device(gpio, &desc);
	if (ret)
		return ret;

	return dm_gpio_request(&desc, label);
}

/**
 * gpio_requestf() - [COMPAT] Request GPIO
 * @gpio:	GPIO number
 * @fmt:	Format string for the requested GPIO
 * @...:	Arguments for the printf() format string
 *
 * This function implements the API that's compatible with current
 * GPIO API used in U-Boot. The request is forwarded to particular
 * GPIO driver. Returns 0 on success, negative value on error.
 */
int gpio_requestf(unsigned gpio, const char *fmt, ...)
{
#if !defined(CONFIG_XPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
	va_list args;
	char buf[40];

	va_start(args, fmt);
	vscnprintf(buf, sizeof(buf), fmt, args);
	va_end(args);
	return gpio_request(gpio, buf);
#else
	return gpio_request(gpio, fmt);
#endif
}

int _dm_gpio_free(struct udevice *dev, uint offset)
{
	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
	struct gpio_dev_priv *uc_priv;
	int ret;

	uc_priv = dev_get_uclass_priv(dev);
	if (!gpio_is_claimed(uc_priv, offset))
		return -ENXIO;
	if (ops->rfree) {
		ret = ops->rfree(dev, offset);
		if (ret)
			return ret;
	}

	gpio_clear_claim(uc_priv, offset);
	free(uc_priv->name[offset]);
	uc_priv->name[offset] = NULL;

	return 0;
}

/**
 * gpio_free() - [COMPAT] Relinquish GPIO
 * gpio:	GPIO number
 *
 * This function implements the API that's compatible with current
 * GPIO API used in U-Boot. The request is forwarded to particular
 * GPIO driver. Returns 0 on success, negative value on error.
 */
int gpio_free(unsigned gpio)
{
	struct gpio_desc desc;
	int ret;

	ret = gpio_to_device(gpio, &desc);
	if (ret)
		return ret;

	return _dm_gpio_free(desc.dev, desc.offset);
}

static int check_reserved(const struct gpio_desc *desc, const char *func)
{
	struct gpio_dev_priv *uc_priv;

	if (!dm_gpio_is_valid(desc))
		return -ENOENT;

	uc_priv = dev_get_uclass_priv(desc->dev);
	if (!gpio_is_claimed(uc_priv, desc->offset)) {
		printf("%s: %s: error: gpio %s%d not reserved\n",
		       desc->dev->name, func,
		       uc_priv->bank_name ? uc_priv->bank_name : "",
		       desc->offset);
		return -EBUSY;
	}

	return 0;
}

/**
 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
 * gpio:	GPIO number
 *
 * This function implements the API that's compatible with current
 * GPIO API used in U-Boot. The request is forwarded to particular
 * GPIO driver. Returns 0 on success, negative value on error.
 */
int gpio_direction_input(unsigned gpio)
{
	struct gpio_desc desc;
	int ret;

	ret = gpio_to_device(gpio, &desc);
	if (ret)
		return ret;

	return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN);
}

/**
 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
 * gpio:	GPIO number
 * value:	Logical value to be set on the GPIO pin
 *
 * This function implements the API that's compatible with current
 * GPIO API used in U-Boot. The request is forwarded to particular
 * GPIO driver. Returns 0 on success, negative value on error.
 */
int gpio_direction_output(unsigned gpio, int value)
{
	struct gpio_desc desc;
	ulong flags;
	int ret;

	ret = gpio_to_device(gpio, &desc);
	if (ret)
		return ret;

	flags = GPIOD_IS_OUT;
	if (value)
		flags |= GPIOD_IS_OUT_ACTIVE;
	return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, flags);
}

static int _gpio_get_value(const struct gpio_desc *desc)
{
	const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
	int value;

	value = ops->get_value(desc->dev, desc->offset);

	return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
}

int dm_gpio_get_value(const struct gpio_desc *desc)
{
	int ret;

	ret = check_reserved(desc, "get_value");
	if (ret)
		return ret;

	return _gpio_get_value(desc);
}

int dm_gpio_set_value(const struct gpio_desc *desc, int value)
{
	const struct dm_gpio_ops *ops;
	int ret;

	ret = check_reserved(desc, "set_value");
	if (ret)
		return ret;

	if (desc->flags & GPIOD_ACTIVE_LOW)
		value = !value;

	/* GPIOD_ are directly managed by driver in set_flags */
	ops = gpio_get_ops(desc->dev);
	if (ops->set_flags) {
		ulong flags = desc->flags;

		if (value)
			flags |= GPIOD_IS_OUT_ACTIVE;
		else
			flags &= ~GPIOD_IS_OUT_ACTIVE;
		return ops->set_flags(desc->dev, desc->offset, flags);
	}

	/*
	 * Emulate open drain by not actively driving the line high or
	 * Emulate open source by not actively driving the line low
	 */
	if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
	    (desc->flags & GPIOD_OPEN_SOURCE && !value))
		return ops->direction_input(desc->dev, desc->offset);
	else if (desc->flags & GPIOD_OPEN_DRAIN ||
		 desc->flags & GPIOD_OPEN_SOURCE)
		return ops->direction_output(desc->dev, desc->offset, value);

	ret = ops->set_value(desc->dev, desc->offset, value);
	if (ret)
		return ret;

	return 0;
}

/* check dir flags invalid configuration */
static int check_dir_flags(ulong flags)
{
	if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
		log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
			  __func__, flags);
		return -EINVAL;
	}

	if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
		log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
			  __func__, flags);
		return -EINVAL;
	}

	if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
		log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
			  __func__, flags);
		return -EINVAL;
	}

	return 0;
}

/**
 * _dm_gpio_set_flags() - Send flags to the driver
 *
 * This uses the best available method to send the given flags to the driver.
 * Note that if flags & GPIOD_ACTIVE_LOW, the driver sees the opposite value
 * of GPIOD_IS_OUT_ACTIVE.
 *
 * @desc:	GPIO description
 * @flags:	flags value to set
 * Return: 0 if OK, -ve on error
 */
static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
{
	struct udevice *dev = desc->dev;
	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	int ret = 0;

	ret = check_dir_flags(flags);
	if (ret) {
		dev_dbg(dev,
			"%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
			desc->dev->name,
			uc_priv->bank_name ? uc_priv->bank_name : "",
			desc->offset, flags);

		return ret;
	}

	/* If active low, invert the output state */
	if ((flags & (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW)) ==
		(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW))
		flags ^= GPIOD_IS_OUT_ACTIVE;

	/* GPIOD_ are directly managed by driver in set_flags */
	if (ops->set_flags) {
		ret = ops->set_flags(dev, desc->offset, flags);
	} else {
		if (flags & GPIOD_IS_OUT) {
			bool value = flags & GPIOD_IS_OUT_ACTIVE;

			ret = ops->direction_output(dev, desc->offset, value);
		} else if (flags & GPIOD_IS_IN) {
			ret = ops->direction_input(dev, desc->offset);
		}
	}

	return ret;
}

int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set)
{
	ulong flags;
	int ret;

	ret = check_reserved(desc, "set_dir_flags");
	if (ret)
		return ret;

	flags = (desc->flags & ~clr) | set;

	ret = _dm_gpio_set_flags(desc, flags);
	if (ret)
		return ret;

	/* save the flags also in descriptor */
	desc->flags = flags;

	return 0;
}

int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
{
	/* combine the requested flags (for IN/OUT) and the descriptor flags */
	return dm_gpio_clrset_flags(desc, GPIOD_MASK_DIR, flags);
}

int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
			  ulong set)
{
	int ret;
	int i;

	for (i = 0; i < count; i++) {
		ret = dm_gpio_clrset_flags(&desc[i], clr, set);
		if (ret)
			return log_ret(ret);
	}

	return 0;
}

int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
{
	struct udevice *dev = desc->dev;
	int ret, value;
	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
	ulong flags;

	ret = check_reserved(desc, "get_flags");
	if (ret)
		return ret;

	/* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
	if (ops->get_flags) {
		ret = ops->get_flags(dev, desc->offset, &flags);
		if (ret)
			return ret;

		/* GPIOD_ACTIVE_LOW is saved in desc->flags */
		value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
		if (desc->flags & GPIOD_ACTIVE_LOW)
			value = !value;
		flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
		flags |= (desc->flags & GPIOD_ACTIVE_LOW);
		if (value)
			flags |= GPIOD_IS_OUT_ACTIVE;
	} else {
		flags = desc->flags;
		/* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
		flags &= ~GPIOD_IS_OUT_ACTIVE;
		if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
			flags |= GPIOD_IS_OUT_ACTIVE;
	}
	*flagsp = flags;

	return 0;
}

/**
 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
 * gpio:	GPIO number
 *
 * This function implements the API that's compatible with current
 * GPIO API used in U-Boot. The request is forwarded to particular
 * GPIO driver. Returns the value of the GPIO pin, or negative value
 * on error.
 */
int gpio_get_value(unsigned gpio)
{
	int ret;

	struct gpio_desc desc;

	ret = gpio_to_device(gpio, &desc);
	if (ret)
		return ret;
	return dm_gpio_get_value(&desc);
}

/**
 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
 * gpio:	GPIO number
 * value:	Logical value to be set on the GPIO pin.
 *
 * This function implements the API that's compatible with current
 * GPIO API used in U-Boot. The request is forwarded to particular
 * GPIO driver. Returns 0 on success, negative value on error.
 */
int gpio_set_value(unsigned gpio, int value)
{
	struct gpio_desc desc;
	int ret;

	ret = gpio_to_device(gpio, &desc);
	if (ret)
		return ret;
	return dm_gpio_set_value(&desc, value);
}

const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
{
	struct gpio_dev_priv *priv;

	/* Must be called on an active device */
	priv = dev_get_uclass_priv(dev);
	assert(priv);

	*bit_count = priv->gpio_count;
	return priv->bank_name;
}

static const char * const gpio_function[GPIOF_COUNT] = {
	"input",
	"output",
	"unused",
	"unknown",
	"func",
};

static int get_function(struct udevice *dev, int offset, bool skip_unused,
			const char **namep)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	const struct dm_gpio_ops *ops = gpio_get_ops(dev);

	BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
	if (!device_active(dev))
		return -ENODEV;
	if (offset < 0 || offset >= uc_priv->gpio_count)
		return -EINVAL;
	if (namep)
		*namep = uc_priv->name[offset];
	if (skip_unused && !gpio_is_claimed(uc_priv, offset))
		return GPIOF_UNUSED;
	if (ops->get_function) {
		int ret;

		ret = ops->get_function(dev, offset);
		if (ret < 0)
			return ret;
		if (ret >= ARRAY_SIZE(gpio_function))
			return -ENODATA;
		return ret;
	}

	return GPIOF_UNKNOWN;
}

int gpio_get_function(struct udevice *dev, int offset, const char **namep)
{
	return get_function(dev, offset, true, namep);
}

int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
{
	return get_function(dev, offset, false, namep);
}

int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
{
	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
	struct gpio_dev_priv *priv;
	char *str = buf;
	const char *label;
	int func;
	int ret;
	int len;
	bool used;

	BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));

	*buf = 0;
	priv = dev_get_uclass_priv(dev);
	ret = gpio_get_raw_function(dev, offset, &label);
	if (ret < 0)
		return ret;
	func = ret;
	len = snprintf(str, buffsize, "%s%d: %s",
		       priv->bank_name ? priv->bank_name : "",
		       offset, gpio_function[func]);

	switch (func) {
	case GPIOF_FUNC:
		snprintf(str + len, buffsize - len, " %s", label ? label : "");
		break;
	case GPIOF_INPUT:
	case GPIOF_OUTPUT:
	case GPIOF_UNUSED:
		ret = ops->get_value(dev, offset);
		if (ret < 0)
			return ret;
		used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
		snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
			 ret,
			 used ? 'x' : ' ',
			 label ? " " : "",
			 label ? label : "");
		break;
	}

	return 0;
}

#if CONFIG_IS_ENABLED(ACPIGEN)
int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
{
	const struct dm_gpio_ops *ops;

	memset(gpio, '\0', sizeof(*gpio));
	if (!dm_gpio_is_valid(desc)) {
		/* Indicate that the GPIO is not valid */
		gpio->pin_count = 0;
		gpio->pins[0] = 0;
		return -EINVAL;
	}

	ops = gpio_get_ops(desc->dev);
	if (!ops->get_acpi)
		return -ENOSYS;

	return ops->get_acpi(desc, gpio);
}
#endif

int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
{
	int i, ret;
	int gpio;

	for (i = 0; i < 32; i++) {
		gpio = gpio_num_array[i];
		if (gpio == -1)
			break;
		ret = gpio_requestf(gpio, fmt, i);
		if (ret)
			goto err;
		ret = gpio_direction_input(gpio);
		if (ret) {
			gpio_free(gpio);
			goto err;
		}
	}

	return 0;
err:
	for (i--; i >= 0; i--)
		gpio_free(gpio_num_array[i]);

	return ret;
}

/*
 * get a number comprised of multiple GPIO values. gpio_num_array points to
 * the array of gpio pin numbers to scan, terminated by -1.
 */
int gpio_get_values_as_int(const int *gpio_list)
{
	int gpio;
	unsigned bitmask = 1;
	unsigned vector = 0;
	int ret;

	while (bitmask &&
	       ((gpio = *gpio_list++) != -1)) {
		ret = gpio_get_value(gpio);
		if (ret < 0)
			return ret;
		else if (ret)
			vector |= bitmask;
		bitmask <<= 1;
	}

	return vector;
}

int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
{
	unsigned bitmask = 1;
	unsigned vector = 0;
	int ret, i;

	for (i = 0; i < count; i++) {
		ret = dm_gpio_get_value(&desc_list[i]);
		if (ret < 0)
			return ret;
		else if (ret)
			vector |= bitmask;
		bitmask <<= 1;
	}

	return vector;
}

int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
				    int count)
{
	static const char tristate[] = "01z";
	enum {
		PULLUP,
		PULLDOWN,

		NUM_OPTIONS,
	};
	int vals[NUM_OPTIONS];
	uint mask;
	uint vector = 0;
	int ret, i;

	/*
	 * Limit to 19 digits which should be plenty. This avoids overflow of a
	 * 32-bit int
	 */
	assert(count < 20);

	for (i = 0; i < NUM_OPTIONS; i++) {
		uint flags = GPIOD_IS_IN;

		flags |= (i == PULLDOWN) ? GPIOD_PULL_DOWN : GPIOD_PULL_UP;
		ret = dm_gpios_clrset_flags(desc_list, count, GPIOD_MASK_PULL,
					    flags);
		if (ret)
			return log_msg_ret("pu", ret);

		/* Give the lines time to settle */
		udelay(10);

		ret = dm_gpio_get_values_as_int(desc_list, count);
		if (ret < 0)
			return log_msg_ret("get1", ret);
		vals[i] = ret;
	}

	log_debug("values: %x %x, count = %d\n", vals[0], vals[1], count);
	for (i = count - 1, mask = 1 << i; i >= 0; i--, mask >>= 1) {
		uint pd = vals[PULLDOWN] & mask ? 1 : 0;
		uint pu = vals[PULLUP] & mask ? 1 : 0;
		uint digit;

		/*
		 * Get value with internal pulldown active. If this is 1 then
		 * there is a stronger external pullup, which we call 1. If not
		 * then call it 0.
		 *
		 * If the values differ then the pin is floating so we call
		 * this a 2.
		 */
		if (pu == pd)
			digit = pd;
		else
			digit = 2;
		log_debug("%c ", tristate[digit]);
		vector = 3 * vector + digit;
	}
	log_debug("vector=%d\n", vector);

	return vector;
}

/**
 * gpio_request_tail: common work for requesting a gpio.
 *
 * ret:		return value from previous work in function which calls
 *		this function.
 *		This seems bogus (why calling this function instead not
 *		calling it and end caller function instead?).
 *		Because on error in caller function we want to set some
 *		default values in gpio desc and have a common error
 *		debug message, which provides this function.
 * nodename:	Name of node for which gpio gets requested
 *		used for gpio label name.
 * args:	pointer to output arguments structure
 * list_name:	Name of GPIO list
 *		used for gpio label name.
 * index:	gpio index in gpio list
 *		used for gpio label name.
 * desc:	pointer to gpio descriptor, filled from this
 *		function.
 * flags:	gpio flags to use.
 * add_index:	should index added to gpio label name
 * gpio_dev:	pointer to gpio device from which the gpio
 *		will be requested. If NULL try to get the
 *		gpio device with uclass_get_device_by_ofnode()
 *
 * return:	In error case this function sets default values in
 *		gpio descriptor, also emmits a debug message.
 *		On success it returns 0 else the error code from
 *		function calls, or the error code passed through
 *		ret to this function.
 *
 */
static int gpio_request_tail(int ret, const char *nodename,
			     struct ofnode_phandle_args *args,
			     const char *list_name, int index,
			     struct gpio_desc *desc, int flags,
			     bool add_index, struct udevice *gpio_dev)
{
	gpio_desc_init(desc, gpio_dev, 0);
	if (ret)
		goto err;

	if (!desc->dev) {
		ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
						  &desc->dev);
		if (ret) {
#if CONFIG_IS_ENABLED(MAX77663_GPIO) || CONFIG_IS_ENABLED(PALMAS_GPIO)
			struct udevice *pmic;
			ret = uclass_get_device_by_ofnode(UCLASS_PMIC, args->node,
							  &pmic);
			if (ret) {
				log_debug("%s: PMIC device get failed, err %d\n",
					  __func__, ret);
				goto err;
			}

			device_foreach_child(desc->dev, pmic) {
				if (device_get_uclass_id(desc->dev) == UCLASS_GPIO)
					break;
			}

			/* if loop exits without GPIO device return error */
			if (device_get_uclass_id(desc->dev) != UCLASS_GPIO)
				goto err;
#else
			debug("%s: uclass_get_device_by_ofnode failed\n",
			      __func__);
			goto err;
#endif
		}
	}
	ret = gpio_find_and_xlate(desc, args);
	if (ret) {
		debug("%s: gpio_find_and_xlate failed\n", __func__);
		goto err;
	}
	ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
			       nodename, list_name, index);
	if (ret) {
		debug("%s: dm_gpio_requestf failed\n", __func__);
		goto err;
	}

	/* Keep any direction flags provided by the devicetree */
	ret = dm_gpio_set_dir_flags(desc,
				    flags | (desc->flags & GPIOD_MASK_DIR));
	if (ret) {
		debug("%s: dm_gpio_set_dir failed\n", __func__);
		goto err;
	}

	return 0;
err:
	debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
	      __func__, nodename, list_name, index, ret);
	return ret;
}

#if CONFIG_IS_ENABLED(OF_REAL)
static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
				       int index, struct gpio_desc *desc,
				       int flags, bool add_index)
{
	struct ofnode_phandle_args args;
	int ret;

	ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
					     index, &args);

	return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
				 index, desc, flags, add_index, NULL);
}

int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
			       struct gpio_desc *desc, int flags)
{
	return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
					   index > 0);
}

int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
			 struct gpio_desc *desc, int flags)
{
	struct ofnode_phandle_args args;
	ofnode node;
	int ret;

	ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
					 index, &args);
	node = dev_ofnode(dev);
	return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
				 index, desc, flags, index > 0, NULL);
}

int gpio_request_by_line_name(struct udevice *dev, const char *line_name,
			      struct gpio_desc *desc, int flags)
{
	int ret;

	if (!dev) {
		uclass_foreach_dev_probe(UCLASS_GPIO, dev)
			if (!gpio_request_by_line_name(dev, line_name, desc, flags))
				return 0;
		return -ENOENT;
	}

	ret = dev_read_stringlist_search(dev, "gpio-line-names", line_name);
	if (ret < 0)
		return ret;

	desc->dev = dev;
	desc->offset = ret;
	desc->flags = 0;

	ret = dm_gpio_request(desc, line_name);
	if (ret) {
		debug("%s: dm_gpio_requestf failed\n", __func__);
		return ret;
	}

	ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
	if (ret)
		debug("%s: dm_gpio_set_dir failed\n", __func__);

	return ret;
}

int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
				    struct gpio_desc *desc, int max_count,
				    int flags)
{
	int count;
	int ret;

	for (count = 0; count < max_count; count++) {
		ret = _gpio_request_by_name_nodev(node, list_name, count,
						  &desc[count], flags, true);
		if (ret == -ENOENT)
			break;
		else if (ret)
			goto err;
	}

	/* We ran out of GPIOs in the list */
	return count;

err:
	gpio_free_list_nodev(desc, count);

	return ret;
}

int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
			      struct gpio_desc *desc, int max_count,
			      int flags)
{
	/*
	 * This isn't ideal since we don't use dev->name in the debug()
	 * calls in gpio_request_by_name(), but we can do this until
	 * gpio_request_list_by_name_nodev() can be dropped.
	 */
	return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
					       max_count, flags);
}

int gpio_get_list_count(struct udevice *dev, const char *list_name)
{
	int ret;

	ret = dev_count_phandle_with_args(dev, list_name, "#gpio-cells",
					  -ENOENT);
	if (ret < 0) {
		debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
		      __func__, dev->name, list_name, ret);
	}

	return ret;
}
#endif /* OF_PLATDATA */

#if CONFIG_IS_ENABLED(OF_PLATDATA)
int gpio_request_by_phandle(struct udevice *dev,
			    const struct phandle_2_arg *cells,
			    struct gpio_desc *desc, int flags)
{
	struct ofnode_phandle_args args;
	struct udevice *gpio_dev;
	const int index = 0;
	int ret;

	ret = device_get_by_ofplat_idx(cells->idx, &gpio_dev);
	if (ret)
		return ret;
	args.args[0] = cells->arg[0];
	args.args[1] = cells->arg[1];

	return gpio_request_tail(ret, NULL, &args, NULL, index, desc, flags,
				 index > 0, gpio_dev);
}
#endif

int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
{
	/* For now, we don't do any checking of dev */
	return _dm_gpio_free(desc->dev, desc->offset);
}

int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
{
	int i;

	/* For now, we don't do any checking of dev */
	for (i = 0; i < count; i++)
		dm_gpio_free(dev, &desc[i]);

	return 0;
}

int gpio_free_list_nodev(struct gpio_desc *desc, int count)
{
	return gpio_free_list(NULL, desc, count);
}

/* We need to renumber the GPIOs when any driver is probed/removed */
static int gpio_renumber(struct udevice *removed_dev)
{
	struct gpio_dev_priv *uc_priv;
	struct udevice *dev;
	struct uclass *uc;
	unsigned base;
	int ret;

	ret = uclass_get(UCLASS_GPIO, &uc);
	if (ret)
		return ret;

	/* Ensure that we have a base for each bank */
	base = 0;
	uclass_foreach_dev(dev, uc) {
		if (device_active(dev) && dev != removed_dev) {
			uc_priv = dev_get_uclass_priv(dev);
			uc_priv->gpio_base = base;
			base += uc_priv->gpio_count;
		}
	}

	return 0;
}

int gpio_get_number(const struct gpio_desc *desc)
{
	struct udevice *dev = desc->dev;
	struct gpio_dev_priv *uc_priv;

	if (!dev)
		return -1;
	uc_priv = dev_get_uclass_priv(dev);

	return uc_priv->gpio_base + desc->offset;
}

static int gpio_post_probe(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
	if (!uc_priv->name)
		return -ENOMEM;

	uc_priv->claimed = calloc(DIV_ROUND_UP(uc_priv->gpio_count,
					       GPIO_ALLOC_BITS),
				  GPIO_ALLOC_BITS / 8);
	if (!uc_priv->claimed) {
		free(uc_priv->name);
		return -ENOMEM;
	}

	return gpio_renumber(NULL);
}

static int gpio_pre_remove(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	int i;

	for (i = 0; i < uc_priv->gpio_count; i++) {
		if (uc_priv->name[i])
			free(uc_priv->name[i]);
	}
	free(uc_priv->claimed);
	free(uc_priv->name);

	return gpio_renumber(dev);
}

int gpio_dev_request_index(struct udevice *dev, const char *nodename,
			   char *list_name, int index, int flags,
			   int dtflags, struct gpio_desc *desc)
{
	struct ofnode_phandle_args args;

	args.node =  ofnode_null();
	args.args_count = 2;
	args.args[0] = index;
	args.args[1] = dtflags;

	return gpio_request_tail(0, nodename, &args, list_name, index, desc,
				 flags, 0, dev);
}

static void devm_gpiod_release(struct udevice *dev, void *res)
{
	dm_gpio_free(dev, res);
}

static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
{
	return res == data;
}

struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
				       unsigned int index, int flags)
{
	int rc;
	struct gpio_desc *desc;
	char *propname;
	static const char suffix[] = "-gpios";

	propname = malloc(strlen(id) + sizeof(suffix));
	if (!propname) {
		rc = -ENOMEM;
		goto end;
	}

	strcpy(propname, id);
	strcat(propname, suffix);

	desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
			    __GFP_ZERO);
	if (unlikely(!desc)) {
		rc = -ENOMEM;
		goto end;
	}

	rc = gpio_request_by_name(dev, propname, index, desc, flags);

end:
	if (propname)
		free(propname);

	if (rc)
		return ERR_PTR(rc);

	devres_add(dev, desc);

	return desc;
}

struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
						const char *id,
						unsigned int index,
						int flags)
{
	struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);

	if (IS_ERR(desc))
		return NULL;

	return desc;
}

void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
{
	int rc;

	rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
	WARN_ON(rc);
}

static int gpio_post_bind(struct udevice *dev)
{
	if (CONFIG_IS_ENABLED(GPIO_HOG) && dev_has_ofnode(dev)) {
		struct udevice *child;
		ofnode node;

		dev_for_each_subnode(node, dev) {
			if (ofnode_read_bool(node, "gpio-hog")) {
				const char *name = ofnode_get_name(node);
				int ret;

				ret = device_bind_driver_to_node(dev,
								 "gpio_hog",
								 name, node,
								 &child);
				if (ret)
					return ret;

				/*
				 * Make sure gpio-hogs are probed after bind
				 * since hogs can be essential to the hardware
				 * system.
				 */
				dev_or_flags(child, DM_FLAG_PROBE_AFTER_BIND);
			}
		}
	}

	return 0;
}

UCLASS_DRIVER(gpio) = {
	.id		= UCLASS_GPIO,
	.name		= "gpio",
	.flags		= DM_UC_FLAG_SEQ_ALIAS,
	.post_probe	= gpio_post_probe,
	.post_bind	= gpio_post_bind,
	.pre_remove	= gpio_pre_remove,
	.per_device_auto	= sizeof(struct gpio_dev_priv),
};
