/*
 * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
 * Keerthy <j-keerthy@ti.com>
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <i2c.h>
#include <asm/gpio.h>
#include <power/pmic.h>
#include <power/regulator.h>

#define GPIO_REGULATOR_MAX_STATES	2

DECLARE_GLOBAL_DATA_PTR;

struct gpio_regulator_platdata {
	struct gpio_desc gpio; /* GPIO for regulator voltage control */
	int states[GPIO_REGULATOR_MAX_STATES];
	int voltages[GPIO_REGULATOR_MAX_STATES];
};

static int gpio_regulator_ofdata_to_platdata(struct udevice *dev)
{
	struct dm_regulator_uclass_platdata *uc_pdata;
	struct gpio_regulator_platdata *dev_pdata;
	struct gpio_desc *gpio;
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	int ret, count, i, j;
	u32 states_array[8];

	dev_pdata = dev_get_platdata(dev);
	uc_pdata = dev_get_uclass_platdata(dev);
	if (!uc_pdata)
		return -ENXIO;

	/* Set type to gpio */
	uc_pdata->type = REGULATOR_TYPE_GPIO;

	/*
	 * Get gpio regulator gpio desc
	 * Assuming one GPIO per regulator.
	 * Can be extended later to multiple GPIOs
	 * per gpio-regulator. As of now no instance with multiple
	 * gpios is presnt
	 */
	gpio = &dev_pdata->gpio;
	ret = gpio_request_by_name(dev, "gpios", 0, gpio, GPIOD_IS_OUT);
	if (ret)
		debug("regulator gpio - not found! Error: %d", ret);

	count = fdtdec_get_int_array_count(blob, node, "states",
					   states_array, 8);

	if (!count)
		return -EINVAL;

	for (i = 0, j = 0; i < count; i += 2) {
		dev_pdata->voltages[j] = states_array[i];
		dev_pdata->states[j] = states_array[i + 1];
		j++;
	}

	return 0;
}

static int gpio_regulator_get_value(struct udevice *dev)
{
	struct dm_regulator_uclass_platdata *uc_pdata;
	struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
	int enable;

	if (!dev_pdata->gpio.dev)
		return -ENOSYS;

	uc_pdata = dev_get_uclass_platdata(dev);
	if (uc_pdata->min_uV > uc_pdata->max_uV) {
		debug("Invalid constraints for: %s\n", uc_pdata->name);
		return -EINVAL;
	}

	enable = dm_gpio_get_value(&dev_pdata->gpio);
	if (enable == dev_pdata->states[0])
		return dev_pdata->voltages[0];
	else
		return dev_pdata->voltages[1];
}

static int gpio_regulator_set_value(struct udevice *dev, int uV)
{
	struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
	int ret;
	bool enable;

	if (!dev_pdata->gpio.dev)
		return -ENOSYS;

	if (uV == dev_pdata->voltages[0])
		enable = dev_pdata->states[0];
	else if (uV == dev_pdata->voltages[1])
		enable = dev_pdata->states[1];
	else
		return -EINVAL;

	ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
	if (ret) {
		error("Can't set regulator : %s gpio to: %d\n", dev->name,
		      enable);
		return ret;
	}

	return 0;
}

static const struct dm_regulator_ops gpio_regulator_ops = {
	.get_value	= gpio_regulator_get_value,
	.set_value	= gpio_regulator_set_value,
};

static const struct udevice_id gpio_regulator_ids[] = {
	{ .compatible = "regulator-gpio" },
	{ },
};

U_BOOT_DRIVER(gpio_regulator) = {
	.name = "gpio regulator",
	.id = UCLASS_REGULATOR,
	.ops = &gpio_regulator_ops,
	.of_match = gpio_regulator_ids,
	.ofdata_to_platdata = gpio_regulator_ofdata_to_platdata,
	.platdata_auto_alloc_size = sizeof(struct gpio_regulator_platdata),
};
