/*
 * Copyright 2022 Nordic Semiconductor ASA
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/drivers/regulator.h>

static void regulator_delay(uint32_t delay_us)
{
	if (delay_us > 0U) {
#ifdef CONFIG_MULTITHREADING
		k_sleep(K_USEC(delay_us));
#else
		k_busy_wait(delay_us);
#endif
	}
}

void regulator_common_data_init(const struct device *dev)
{
	struct regulator_common_data *data = dev->data;

#ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
	(void)k_mutex_init(&data->lock);
#endif
	data->refcnt = 0;
}

int regulator_common_init(const struct device *dev, bool is_enabled)
{
	const struct regulator_driver_api *api = dev->api;
	const struct regulator_common_config *config = dev->config;
	struct regulator_common_data *data = dev->data;
	int32_t current_uv;
	int ret;

	if (config->initial_mode != REGULATOR_INITIAL_MODE_UNKNOWN) {
		ret = regulator_set_mode(dev, config->initial_mode);
		if (ret < 0) {
			return ret;
		}
	}

	if (config->init_uv > INT32_MIN) {
		ret = regulator_set_voltage(dev, config->init_uv, config->init_uv);
		if (ret < 0) {
			return ret;
		}
	}

	/* If we have valid range values, we try to match them before enabling */
	if ((config->min_uv > INT32_MIN) || (config->max_uv < INT32_MAX)) {

		ret = regulator_get_voltage(dev, &current_uv);
		if (ret < 0) {
			return ret;
		}

		/* Snap to closest interval value if out of range */
		if (current_uv < config->min_uv) {
			ret = regulator_set_voltage(dev, config->min_uv, config->min_uv);
			if (ret < 0) {
				return ret;
			}
		} else if (current_uv > config->max_uv) {
			ret = regulator_set_voltage(dev, config->max_uv, config->max_uv);
			if (ret < 0) {
				return ret;
			}
		}
	}

	if (is_enabled) {
		data->refcnt++;
	} else if ((config->flags & REGULATOR_INIT_ENABLED) != 0U) {
		ret = api->enable(dev);
		if (ret < 0) {
			return ret;
		}

		regulator_delay(config->startup_delay_us);
		data->refcnt++;
	}

	return 0;
}

int regulator_enable(const struct device *dev)
{
	const struct regulator_driver_api *api = dev->api;
	const struct regulator_common_config *config = dev->config;
	struct regulator_common_data *data = dev->data;
	int ret = 0;

	/* enable not supported (always on) */
	if (api->enable == NULL) {
		return 0;
	}

	/* regulator must stay always on */
	if  ((config->flags & REGULATOR_ALWAYS_ON) != 0U) {
		return 0;
	}

#ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
	(void)k_mutex_lock(&data->lock, K_FOREVER);
#endif

	data->refcnt++;

	if (data->refcnt == 1) {
		ret = api->enable(dev);
		if (ret < 0) {
			data->refcnt--;
		} else {
			regulator_delay(config->off_on_delay_us);
		}
	}

#ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
	k_mutex_unlock(&data->lock);
#endif

	return ret;
}

bool regulator_is_enabled(const struct device *dev)
{
	const struct regulator_common_config *config = dev->config;
	struct regulator_common_data *data = dev->data;
	bool enabled;

	if ((config->flags & REGULATOR_ALWAYS_ON) != 0U) {
		enabled = true;
	} else {
#ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
		(void)k_mutex_lock(&data->lock, K_FOREVER);
#endif
		enabled = data->refcnt != 0;
#ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
		k_mutex_unlock(&data->lock);
#endif
	}

	return enabled;
}

int regulator_disable(const struct device *dev)
{
	const struct regulator_driver_api *api = dev->api;
	const struct regulator_common_config *config = dev->config;
	struct regulator_common_data *data = dev->data;
	int ret = 0;

	/* disable not supported (always on) */
	if (api->disable == NULL) {
		return 0;
	}

	/* regulator must stay always on */
	if  ((config->flags & REGULATOR_ALWAYS_ON) != 0U) {
		return 0;
	}

#ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
	(void)k_mutex_lock(&data->lock, K_FOREVER);
#endif

	data->refcnt--;

	if (data->refcnt == 0) {
		ret = api->disable(dev);
		if (ret < 0) {
			data->refcnt++;
		}
	}

#ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
	k_mutex_unlock(&data->lock);
#endif

	return ret;
}

bool regulator_is_supported_voltage(const struct device *dev, int32_t min_uv,
				    int32_t max_uv)
{
	const struct regulator_common_config *config = dev->config;
	unsigned int volt_cnt;

	/* voltage may not be allowed, even if supported */
	if ((min_uv > config->max_uv) || (max_uv < config->min_uv)) {
		return false;
	}

	volt_cnt = regulator_count_voltages(dev);

	for (unsigned int idx = 0U; idx < volt_cnt; idx++) {
		int32_t volt_uv;

		(void)regulator_list_voltage(dev, idx, &volt_uv);

		if ((volt_uv >= min_uv) && (volt_uv <= max_uv)) {
			return true;
		}
	}

	return false;
}

int regulator_set_voltage(const struct device *dev, int32_t min_uv,
			  int32_t max_uv)
{
	const struct regulator_common_config *config = dev->config;
	const struct regulator_driver_api *api = dev->api;

	if (api->set_voltage == NULL) {
		return -ENOSYS;
	}

	/* voltage may not be allowed, even if supported */
	if ((min_uv > config->max_uv) || (max_uv < config->min_uv)) {
		return -EINVAL;
	}

	return api->set_voltage(dev, min_uv, max_uv);
}

int regulator_set_current_limit(const struct device *dev, int32_t min_ua,
				int32_t max_ua)
{
	const struct regulator_common_config *config = dev->config;
	const struct regulator_driver_api *api = dev->api;

	if (api->set_current_limit == NULL) {
		return -ENOSYS;
	}

	/* current limit may not be allowed, even if supported */
	if ((min_ua > config->max_ua) || (max_ua < config->min_ua)) {
		return -EINVAL;
	}

	return api->set_current_limit(dev, min_ua, max_ua);
}

int regulator_set_mode(const struct device *dev, regulator_mode_t mode)
{
	const struct regulator_common_config *config = dev->config;
	const struct regulator_driver_api *api = dev->api;

	if (api->set_mode == NULL) {
		return -ENOSYS;
	}

	/* no mode restrictions */
	if (config->allowed_modes_cnt == 0U) {
		return api->set_mode(dev, mode);
	}

	/* check if mode is allowed, apply if it is */
	for (uint8_t i = 0U; i < config->allowed_modes_cnt; i++) {
		if (mode == config->allowed_modes[i]) {
			return api->set_mode(dev, mode);
		}
	}

	return -ENOTSUP;
}
