/*
 * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>

#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/st/regulator.h>
#include <libfdt.h>

#define MAX_PROPERTY_LEN 64

static struct rdev rdev_array[PLAT_NB_RDEVS];

#define for_each_rdev(rdev) \
	for (rdev = rdev_array; rdev < (rdev_array + PLAT_NB_RDEVS); rdev++)

#define for_each_registered_rdev(rdev) \
	for (rdev = rdev_array; \
	     (rdev < (rdev_array + PLAT_NB_RDEVS)) && (rdev->desc != NULL); rdev++)

static void lock_driver(const struct rdev *rdev)
{
	if (rdev->desc->ops->lock != NULL) {
		rdev->desc->ops->lock(rdev->desc);
	}
}

static void unlock_driver(const struct rdev *rdev)
{
	if (rdev->desc->ops->unlock != NULL) {
		rdev->desc->ops->unlock(rdev->desc);
	}
}

static struct rdev *regulator_get_by_phandle(int32_t phandle)
{
	struct rdev *rdev;

	for_each_registered_rdev(rdev) {
		if (rdev->phandle == phandle) {
			return rdev;
		}
	}

	WARN("%s: phandle %d not found\n", __func__, phandle);
	return NULL;
}

/*
 * Get a regulator from its node name
 *
 * @fdt - pointer to device tree memory
 * @node_name - name of the node "ldo1"
 * Return pointer to rdev if succeed, NULL else.
 */
struct rdev *regulator_get_by_name(const char *node_name)
{
	struct rdev *rdev;

	assert(node_name != NULL);
	VERBOSE("get %s\n", node_name);

	for_each_registered_rdev(rdev) {
		if (strcmp(rdev->desc->node_name, node_name) == 0) {
			return rdev;
		}
	}

	WARN("%s: %s not found\n", __func__, node_name);
	return NULL;
}

static int32_t get_supply_phandle(const void *fdt, int node, const char *name)
{
	const fdt32_t *cuint;
	int len __unused;
	int supply_phandle = -FDT_ERR_NOTFOUND;
	char prop_name[MAX_PROPERTY_LEN];

	len = snprintf(prop_name, MAX_PROPERTY_LEN - 1, "%s-supply", name);
	assert((len >= 0) && (len < MAX_PROPERTY_LEN - 1));

	cuint = fdt_getprop(fdt, node, prop_name, NULL);
	if (cuint != NULL) {
		supply_phandle = fdt32_to_cpu(*cuint);
		VERBOSE("%s: supplied by %d\n", name, supply_phandle);
	}

	return supply_phandle;
}

/*
 * Get a regulator from a supply name
 *
 * @fdt - pointer to device tree memory
 * @node - offset of the node that contains the supply description
 * @name - name of the supply "vdd" for "vdd-supply'
 * Return pointer to rdev if succeed, NULL else.
 */
struct rdev *regulator_get_by_supply_name(const void *fdt, int node, const char *name)
{
	const int p = get_supply_phandle(fdt, node, name);

	if (p < 0) {
		return NULL;
	}

	return regulator_get_by_phandle(p);
}

static int __regulator_set_state(struct rdev *rdev, bool state)
{
	if (rdev->desc->ops->set_state == NULL) {
		return -ENODEV;
	}

	return rdev->desc->ops->set_state(rdev->desc, state);
}

/*
 * Enable regulator
 *
 * @rdev - pointer to rdev struct
 * Return 0 if succeed, non 0 else.
 */
int regulator_enable(struct rdev *rdev)
{
	int ret;

	assert(rdev != NULL);

	ret = __regulator_set_state(rdev, STATE_ENABLE);

	udelay(rdev->enable_ramp_delay);

	return ret;
}

/*
 * Disable regulator
 *
 * @rdev - pointer to rdev struct
 * Return 0 if succeed, non 0 else.
 */
int regulator_disable(struct rdev *rdev)
{
	int ret;

	assert(rdev != NULL);

	ret = __regulator_set_state(rdev, STATE_DISABLE);

	udelay(rdev->enable_ramp_delay);

	return ret;
}

/*
 * Regulator enabled query
 *
 * @rdev - pointer to rdev struct
 * Return 0 if disabled, 1 if enabled, <0 else.
 */
int regulator_is_enabled(const struct rdev *rdev)
{
	int ret;

	assert(rdev != NULL);

	VERBOSE("%s: is en\n", rdev->desc->node_name);

	if (rdev->desc->ops->get_state == NULL) {
		return -ENODEV;
	}

	lock_driver(rdev);

	ret = rdev->desc->ops->get_state(rdev->desc);
	if (ret < 0) {
		ERROR("regul %s get state failed: err:%d\n",
		      rdev->desc->node_name, ret);
	}

	unlock_driver(rdev);

	return ret;
}

/*
 * Set regulator voltage
 *
 * @rdev - pointer to rdev struct
 * @mvolt - Target voltage level in millivolt
 * Return 0 if succeed, non 0 else.
 */
int regulator_set_voltage(struct rdev *rdev, uint16_t mvolt)
{
	int ret;

	assert(rdev != NULL);

	VERBOSE("%s: set mvolt\n", rdev->desc->node_name);

	if (rdev->desc->ops->set_voltage == NULL) {
		return -ENODEV;
	}

	if ((mvolt < rdev->min_mv) || (mvolt > rdev->max_mv)) {
		return -EPERM;
	}

	lock_driver(rdev);

	ret = rdev->desc->ops->set_voltage(rdev->desc, mvolt);
	if (ret < 0) {
		ERROR("regul %s set volt failed: err:%d\n",
		      rdev->desc->node_name, ret);
	}

	unlock_driver(rdev);

	return ret;
}

/*
 * Set regulator min voltage
 *
 * @rdev - pointer to rdev struct
 * Return 0 if succeed, non 0 else.
 */
int regulator_set_min_voltage(struct rdev *rdev)
{
	return regulator_set_voltage(rdev, rdev->min_mv);
}

/*
 * Get regulator voltage
 *
 * @rdev - pointer to rdev struct
 * Return milli volts if succeed, <0 else.
 */
int regulator_get_voltage(const struct rdev *rdev)
{
	int ret;

	assert(rdev != NULL);

	VERBOSE("%s: get volt\n", rdev->desc->node_name);

	if (rdev->desc->ops->get_voltage == NULL) {
		return rdev->min_mv;
	}

	lock_driver(rdev);

	ret = rdev->desc->ops->get_voltage(rdev->desc);
	if (ret < 0) {
		ERROR("regul %s get voltage failed: err:%d\n",
		      rdev->desc->node_name, ret);
	}

	unlock_driver(rdev);

	return ret;
}

/*
 * List regulator voltages
 *
 * @rdev - pointer to rdev struct
 * @levels - out: array of supported millitvolt levels from min to max value
 * @count - out: number of possible millivolt values
 * Return 0 if succeed, non 0 else.
 */
int regulator_list_voltages(const struct rdev *rdev, const uint16_t **levels, size_t *count)
{
	int ret;
	size_t n;

	assert(rdev != NULL);
	assert(levels != NULL);
	assert(count != NULL);

	VERBOSE("%s: list volt\n", rdev->desc->node_name);

	if (rdev->desc->ops->list_voltages == NULL) {
		return -ENODEV;
	}

	lock_driver(rdev);

	ret = rdev->desc->ops->list_voltages(rdev->desc, levels, count);

	unlock_driver(rdev);

	if (ret < 0) {
		ERROR("regul %s list_voltages failed: err: %d\n",
		      rdev->desc->node_name, ret);
		return ret;
	}

	/*
	 * Reduce the possible values depending on min and max from device-tree
	 */
	n = *count;
	while ((n > 1U) && ((*levels)[n - 1U] > rdev->max_mv)) {
		n--;
	}

	/* Verify that max val is a valid value */
	if (rdev->max_mv != (*levels)[n - 1]) {
		ERROR("regul %s: max value %u is invalid\n",
		      rdev->desc->node_name, rdev->max_mv);
		return -EINVAL;
	}

	while ((n > 1U) && ((*levels[0U]) < rdev->min_mv)) {
		(*levels)++;
		n--;
	}

	/* Verify that min is not too high */
	if (n == 0U) {
		ERROR("regul %s set min voltage is too high\n",
		      rdev->desc->node_name);
		return -EINVAL;
	}

	/* Verify that min val is a valid vlue */
	if (rdev->min_mv != (*levels)[0U]) {
		ERROR("regul %s: min value %u is invalid\n",
		      rdev->desc->node_name, rdev->min_mv);
		return -EINVAL;
	}

	*count = n;

	VERBOSE("rdev->min_mv=%u rdev->max_mv=%u\n", rdev->min_mv, rdev->max_mv);

	return 0;
}

/*
 * Get regulator voltages range
 *
 * @rdev - pointer to rdev struct
 * @min_mv - out: min possible millivolt value
 * @max_mv - out: max possible millivolt value
 * Return 0 if succeed, non 0 else.
 */
void regulator_get_range(const struct rdev *rdev, uint16_t *min_mv, uint16_t *max_mv)
{
	assert(rdev != NULL);

	if (min_mv != NULL) {
		*min_mv = rdev->min_mv;
	}
	if (max_mv != NULL) {
		*max_mv = rdev->max_mv;
	}
}

/*
 * Set regulator flag
 *
 * @rdev - pointer to rdev struct
 * @flag - flag value to set (eg: REGUL_OCP)
 * Return 0 if succeed, non 0 else.
 */
int regulator_set_flag(struct rdev *rdev, uint16_t flag)
{
	int ret;

	/* check that only one bit is set on flag */
	if (__builtin_popcount(flag) != 1) {
		return -EINVAL;
	}

	/* REGUL_ALWAYS_ON and REGUL_BOOT_ON are internal properties of the core */
	if ((flag == REGUL_ALWAYS_ON) || (flag == REGUL_BOOT_ON)) {
		rdev->flags |= flag;
		return 0;
	}

	if (rdev->desc->ops->set_flag == NULL) {
		ERROR("%s can not set any flag\n", rdev->desc->node_name);
		return -ENODEV;
	}

	lock_driver(rdev);

	ret = rdev->desc->ops->set_flag(rdev->desc, flag);

	unlock_driver(rdev);

	if (ret != 0) {
		ERROR("%s: could not set flag %d ret=%d\n",
		      rdev->desc->node_name, flag, ret);
		return ret;
	}

	rdev->flags |= flag;

	return 0;
}

/*
 * Parse the device-tree for a regulator
 *
 * Read min/max voltage from dt and check its validity
 * Read the properties, and call the driver to set flags
 * Read power supply phandle
 * Read and store low power mode states
 *
 * @rdev - pointer to rdev struct
 * @node - device-tree node offset of the regulator
 * Return 0 if disabled, 1 if enabled, <0 else.
 */
static int parse_dt(struct rdev *rdev, int node)
{
	void *fdt;
	const fdt32_t *cuint;
	const uint16_t *levels;
	size_t size;
	int ret;

	VERBOSE("%s: parse dt\n", rdev->desc->node_name);

	if (fdt_get_address(&fdt) == 0) {
		return -ENOENT;
	}

	rdev->phandle = fdt_get_phandle(fdt, node);

	cuint = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
	if (cuint != NULL) {
		uint16_t min_mv;

		min_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
		VERBOSE("%s: min_mv=%d\n", rdev->desc->node_name, (int)min_mv);
		if (min_mv <= rdev->max_mv) {
			rdev->min_mv = min_mv;
		} else {
			ERROR("%s: min_mv=%d is too high\n",
			      rdev->desc->node_name, (int)min_mv);
			return -EINVAL;
		}
	}

	cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
	if (cuint != NULL) {
		uint16_t max_mv;

		max_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
		VERBOSE("%s: max_mv=%d\n", rdev->desc->node_name, (int)max_mv);
		if (max_mv >= rdev->min_mv) {
			rdev->max_mv = max_mv;
		} else {
			ERROR("%s: max_mv=%d is too low\n",
			      rdev->desc->node_name, (int)max_mv);
			return -EINVAL;
		}
	}

	/* validate that min and max values can be used */
	ret = regulator_list_voltages(rdev, &levels, &size);
	if ((ret != 0) && (ret != -ENODEV)) {
		return ret;
	}

	return 0;
}

/*
 * Register a regulator driver in regulator framework.
 * Initialize voltage range from driver description
 *
 * @desc - pointer to the regulator description
 * @node - device-tree node offset of the regulator
 * Return 0 if succeed, non 0 else.
 */
int regulator_register(const struct regul_description *desc, int node)
{
	struct rdev *rdev;

	assert(desc != NULL);

	VERBOSE("register %s\n", desc->node_name);

	for_each_rdev(rdev) {
		if (rdev->desc == NULL) {
			break;
		}
	}

	if (rdev == rdev_array + PLAT_NB_RDEVS) {
		WARN("Not enough place for regulators, PLAT_NB_RDEVS should be increased.\n");
		return -ENOMEM;
	}

	rdev->desc = desc;
	rdev->enable_ramp_delay = rdev->desc->enable_ramp_delay;

	if (rdev->desc->ops->list_voltages != NULL) {
		int ret;
		const uint16_t *levels;
		size_t count;

		lock_driver(rdev);

		ret = rdev->desc->ops->list_voltages(rdev->desc, &levels, &count);

		unlock_driver(rdev);

		if (ret < 0) {
			ERROR("regul %s set state failed: err:%d\n",
			      rdev->desc->node_name, ret);
			return ret;
		}

		rdev->min_mv = levels[0];
		rdev->max_mv = levels[count - 1U];
	} else {
		rdev->max_mv = UINT16_MAX;
	}

	return parse_dt(rdev, node);
}
