// SPDX-License-Identifier: GPL-2.0+
/*
 * Qualcomm GPIO driver
 *
 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
 */

#include <dm.h>
#include <errno.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <mach/gpio.h>

DECLARE_GLOBAL_DATA_PTR;

/* OE */
#define GPIO_OE_DISABLE  (0x0 << 9)
#define GPIO_OE_ENABLE   (0x1 << 9)
#define GPIO_OE_MASK     (0x1 << 9)

/* GPIO_IN_OUT register shifts. */
#define GPIO_IN          0
#define GPIO_OUT         1

struct msm_gpio_bank {
	phys_addr_t base;
	const struct msm_pin_data *pin_data;
};

#define GPIO_CONFIG_REG(dev, x) \
	(qcom_pin_offset(((struct msm_gpio_bank *)dev_get_priv(dev))->pin_data->pin_offsets, x))

#define GPIO_IN_OUT_REG(dev, x) \
	(GPIO_CONFIG_REG(dev, x) + 0x4)

static void msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
{
	struct msm_gpio_bank *priv = dev_get_priv(dev);

	/* Always NOP for special pins, assume they're in the correct state */
	if (qcom_is_special_pin(priv->pin_data, gpio))
		return;

	/* Disable OE bit */
	clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
			GPIO_OE_MASK, GPIO_OE_DISABLE);

	return;
}

static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
{
	struct msm_gpio_bank *priv = dev_get_priv(dev);

	/* Always NOP for special pins, assume they're in the correct state */
	if (qcom_is_special_pin(priv->pin_data, gpio))
		return 0;

	value = !!value;
	/* set value */
	writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));

	return 0;
}

static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
				     int value)
{
	struct msm_gpio_bank *priv = dev_get_priv(dev);

	/* Always NOP for special pins, assume they're in the correct state */
	if (qcom_is_special_pin(priv->pin_data, gpio))
		return 0;

	value = !!value;
	/* set value */
	writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
	/* switch direction */
	clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
			GPIO_OE_MASK, GPIO_OE_ENABLE);

	return 0;
}

static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags)
{
	if (flags & GPIOD_IS_OUT_ACTIVE) {
		return msm_gpio_direction_output(dev, gpio, 1);
	} else if (flags & GPIOD_IS_OUT) {
		return msm_gpio_direction_output(dev, gpio, 0);
	} else if (flags & GPIOD_IS_IN) {
		msm_gpio_direction_input(dev, gpio);
		if (flags & GPIOD_PULL_UP)
			return msm_gpio_set_value(dev, gpio, 1);
		else if (flags & GPIOD_PULL_DOWN)
			return msm_gpio_set_value(dev, gpio, 0);
	}

	return 0;
}

static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
{
	struct msm_gpio_bank *priv = dev_get_priv(dev);

	/* Always NOP for special pins, assume they're in the correct state */
	if (qcom_is_special_pin(priv->pin_data, gpio))
		return 0;

	return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
}

static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
{
	struct msm_gpio_bank *priv = dev_get_priv(dev);

	/* Always NOP for special pins, assume they're in the correct state */
	if (qcom_is_special_pin(priv->pin_data, gpio))
		return 0;

	if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
		return GPIOF_OUTPUT;

	return GPIOF_INPUT;
}

static const struct dm_gpio_ops gpio_msm_ops = {
	.set_flags		= msm_gpio_set_flags,
	.get_value		= msm_gpio_get_value,
	.get_function		= msm_gpio_get_function,
};

static int msm_gpio_probe(struct udevice *dev)
{
	struct msm_gpio_bank *priv = dev_get_priv(dev);

	priv->base = dev_read_addr(dev);
	priv->pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);

	return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
}

static int msm_gpio_of_to_plat(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	const struct msm_pin_data *pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);

	/* Get the pin count from the pinctrl driver */
	uc_priv->gpio_count = pin_data->pin_count;
	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
					 "gpio-bank-name", NULL);
	if (uc_priv->bank_name == NULL)
		uc_priv->bank_name = "soc";

	return 0;
}

U_BOOT_DRIVER(gpio_msm) = {
	.name	= "gpio_msm",
	.id	= UCLASS_GPIO,
	.of_to_plat = msm_gpio_of_to_plat,
	.probe	= msm_gpio_probe,
	.ops	= &gpio_msm_ops,
	.flags	= DM_UC_FLAG_SEQ_ALIAS,
	.priv_auto	= sizeof(struct msm_gpio_bank),
};
