/*
 * Qualcomm pm8916 pmic gpio driver - part of Qualcomm PM8916 PMIC
 *
 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <power/pmic.h>
#include <spmi/spmi.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/bitops.h>

DECLARE_GLOBAL_DATA_PTR;

/* Register offset for each gpio */
#define REG_OFFSET(x)          ((x) * 0x100)

/* Register maps */

/* Type and subtype are shared for all pm8916 peripherals */
#define REG_TYPE               0x4
#define REG_SUBTYPE            0x5

#define REG_STATUS             0x08
#define REG_STATUS_VAL_MASK    0x1

/* MODE_CTL */
#define REG_CTL           0x40
#define REG_CTL_MODE_MASK       0x70
#define REG_CTL_MODE_INPUT      0x00
#define REG_CTL_MODE_INOUT      0x20
#define REG_CTL_MODE_OUTPUT     0x10
#define REG_CTL_OUTPUT_MASK     0x0F

#define REG_DIG_VIN_CTL        0x41
#define REG_DIG_VIN_VIN0       0

#define REG_DIG_PULL_CTL       0x42
#define REG_DIG_PULL_NO_PU     0x5

#define REG_DIG_OUT_CTL        0x45
#define REG_DIG_OUT_CTL_CMOS   (0x0 << 4)
#define REG_DIG_OUT_CTL_DRIVE_L 0x1

#define REG_EN_CTL             0x46
#define REG_EN_CTL_ENABLE      (1 << 7)

struct pm8916_gpio_bank {
	uint32_t pid; /* Peripheral ID on SPMI bus */
};

static int pm8916_gpio_set_direction(struct udevice *dev, unsigned offset,
				     bool input, int value)
{
	struct pm8916_gpio_bank *priv = dev_get_priv(dev);
	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
	int ret;

	/* Disable the GPIO */
	ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL,
			      REG_EN_CTL_ENABLE, 0);
	if (ret < 0)
		return ret;

	/* Select the mode */
	if (input)
		ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL,
				     REG_CTL_MODE_INPUT);
	else
		ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL,
				     REG_CTL_MODE_INOUT | (value ? 1 : 0));
	if (ret < 0)
		return ret;

	/* Set the right pull (no pull) */
	ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL,
			     REG_DIG_PULL_NO_PU);
	if (ret < 0)
		return ret;

	/* Configure output pin drivers if needed */
	if (!input) {
		/* Select the VIN - VIN0, pin is input so it doesn't matter */
		ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL,
				     REG_DIG_VIN_VIN0);
		if (ret < 0)
			return ret;

		/* Set the right dig out control */
		ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL,
				     REG_DIG_OUT_CTL_CMOS |
				     REG_DIG_OUT_CTL_DRIVE_L);
		if (ret < 0)
			return ret;
	}

	/* Enable the GPIO */
	return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0,
			       REG_EN_CTL_ENABLE);
}

static int pm8916_gpio_direction_input(struct udevice *dev, unsigned offset)
{
	return pm8916_gpio_set_direction(dev, offset, true, 0);
}

static int pm8916_gpio_direction_output(struct udevice *dev, unsigned offset,
					int value)
{
	return pm8916_gpio_set_direction(dev, offset, false, value);
}

static int pm8916_gpio_get_function(struct udevice *dev, unsigned offset)
{
	struct pm8916_gpio_bank *priv = dev_get_priv(dev);
	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
	int reg;

	/* Set the output value of the gpio */
	reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL);
	if (reg < 0)
		return reg;

	switch (reg & REG_CTL_MODE_MASK) {
	case REG_CTL_MODE_INPUT:
		return GPIOF_INPUT;
	case REG_CTL_MODE_INOUT: /* Fallthrough */
	case REG_CTL_MODE_OUTPUT:
		return GPIOF_OUTPUT;
	default:
		return GPIOF_UNKNOWN;
	}
}

static int pm8916_gpio_get_value(struct udevice *dev, unsigned offset)
{
	struct pm8916_gpio_bank *priv = dev_get_priv(dev);
	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
	int reg;

	reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS);
	if (reg < 0)
		return reg;

	return !!(reg & REG_STATUS_VAL_MASK);
}

static int pm8916_gpio_set_value(struct udevice *dev, unsigned offset,
				 int value)
{
	struct pm8916_gpio_bank *priv = dev_get_priv(dev);
	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);

	/* Set the output value of the gpio */
	return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL,
			       REG_CTL_OUTPUT_MASK, !!value);
}

static const struct dm_gpio_ops pm8916_gpio_ops = {
	.direction_input	= pm8916_gpio_direction_input,
	.direction_output	= pm8916_gpio_direction_output,
	.get_value		= pm8916_gpio_get_value,
	.set_value		= pm8916_gpio_set_value,
	.get_function		= pm8916_gpio_get_function,
};

static int pm8916_gpio_probe(struct udevice *dev)
{
	struct pm8916_gpio_bank *priv = dev_get_priv(dev);
	int reg;

	priv->pid = dev_get_addr(dev);
	if (priv->pid == FDT_ADDR_T_NONE)
		return -EINVAL;

	/* Do a sanity check */
	reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
	if (reg != 0x10)
		return -ENODEV;

	reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
	if (reg != 0x5)
		return -ENODEV;

	return 0;
}

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

	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
					     "gpio-count", 0);
	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 = "pm8916";

	return 0;
}

static const struct udevice_id pm8916_gpio_ids[] = {
	{ .compatible = "qcom,pm8916-gpio" },
	{ }
};

U_BOOT_DRIVER(gpio_pm8916) = {
	.name	= "gpio_pm8916",
	.id	= UCLASS_GPIO,
	.of_match = pm8916_gpio_ids,
	.ofdata_to_platdata = pm8916_gpio_ofdata_to_platdata,
	.probe	= pm8916_gpio_probe,
	.ops	= &pm8916_gpio_ops,
	.priv_auto_alloc_size = sizeof(struct pm8916_gpio_bank),
};


/* Add pmic buttons as GPIO as well - there is no generic way for now */
#define PON_INT_RT_STS                        0x10
#define KPDPWR_ON_INT_BIT                     0
#define RESIN_ON_INT_BIT                      1

static int pm8941_pwrkey_get_function(struct udevice *dev, unsigned offset)
{
	return GPIOF_INPUT;
}

static int pm8941_pwrkey_get_value(struct udevice *dev, unsigned offset)
{
	struct pm8916_gpio_bank *priv = dev_get_priv(dev);

	int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS);

	if (reg < 0)
		return 0;

	switch (offset) {
	case 0: /* Power button */
		return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0;
		break;
	case 1: /* Reset button */
	default:
		return (reg & BIT(RESIN_ON_INT_BIT)) != 0;
		break;
	}
}

static const struct dm_gpio_ops pm8941_pwrkey_ops = {
	.get_value		= pm8941_pwrkey_get_value,
	.get_function		= pm8941_pwrkey_get_function,
};

static int pm8941_pwrkey_probe(struct udevice *dev)
{
	struct pm8916_gpio_bank *priv = dev_get_priv(dev);
	int reg;

	priv->pid = dev_get_addr(dev);
	if (priv->pid == FDT_ADDR_T_NONE)
		return -EINVAL;

	/* Do a sanity check */
	reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
	if (reg != 0x1)
		return -ENODEV;

	reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
	if (reg != 0x1)
		return -ENODEV;

	return 0;
}

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

	uc_priv->gpio_count = 2;
	if (uc_priv->bank_name == NULL)
		uc_priv->bank_name = "pm8916_key";

	return 0;
}

static const struct udevice_id pm8941_pwrkey_ids[] = {
	{ .compatible = "qcom,pm8916-pwrkey" },
	{ }
};

U_BOOT_DRIVER(pwrkey_pm8941) = {
	.name	= "pwrkey_pm8916",
	.id	= UCLASS_GPIO,
	.of_match = pm8941_pwrkey_ids,
	.ofdata_to_platdata = pm8941_pwrkey_ofdata_to_platdata,
	.probe	= pm8941_pwrkey_probe,
	.ops	= &pm8941_pwrkey_ops,
	.priv_auto_alloc_size = sizeof(struct pm8916_gpio_bank),
};
