/*
 * Copyright 2023 NXP
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_vref

#include <errno.h>

#include <zephyr/drivers/regulator.h>
#include <zephyr/dt-bindings/regulator/nxp_vref.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/linear_range.h>
#include <zephyr/sys/util.h>

#include <fsl_device_registers.h>

static const struct linear_range utrim_range = LINEAR_RANGE_INIT(1000000, 100000U, 0x0U, 0xBU);

struct regulator_nxp_vref_data {
	struct regulator_common_data common;
};

struct regulator_nxp_vref_config {
	struct regulator_common_config common;
	VREF_Type *base;
	uint8_t gnd_sel;
	uint16_t buf_start_delay;
	uint16_t bg_start_time;
};

static int regulator_nxp_vref_enable(const struct device *dev)
{
	const struct regulator_nxp_vref_config *config = dev->config;
	VREF_Type *const base = config->base;

	volatile uint32_t *const csr = &base->CSR;

	*csr |= VREF_CSR_LPBGEN_MASK | VREF_CSR_LPBG_BUF_EN_MASK;
	/* Wait for bandgap startup */
	k_busy_wait(config->bg_start_time);

	/* Enable high accuracy bandgap */
	*csr |= VREF_CSR_HCBGEN_MASK;

	/* Monitor until stable */
	while (!(*csr & VREF_CSR_VREFST_MASK))
		;

	/* Enable output buffer */
	*csr |= VREF_CSR_BUF21EN_MASK;

	return 0;
}

static int regulator_nxp_vref_disable(const struct device *dev)
{
	const struct regulator_nxp_vref_config *config = dev->config;
	VREF_Type *const base = config->base;

	/*
	 * Disable HC Bandgap, LP Bandgap, and Buf21
	 * to achieve "Off" mode of VREF
	 */
	base->CSR &= ~(VREF_CSR_BUF21EN_MASK | VREF_CSR_HCBGEN_MASK | VREF_CSR_LPBGEN_MASK);

	return 0;
}

static int regulator_nxp_vref_set_mode(const struct device *dev, regulator_mode_t mode)
{
	const struct regulator_nxp_vref_config *config = dev->config;
	VREF_Type *const base = config->base;
	uint32_t csr = base->CSR;

	if (mode == NXP_VREF_MODE_STANDBY) {
		csr &= ~VREF_CSR_REGEN_MASK &
			~VREF_CSR_CHOPEN_MASK &
			~VREF_CSR_HI_PWR_LV_MASK &
			~VREF_CSR_BUF21EN_MASK;
	} else if (mode == NXP_VREF_MODE_LOW_POWER) {
		csr &= ~VREF_CSR_REGEN_MASK &
			~VREF_CSR_CHOPEN_MASK &
			~VREF_CSR_HI_PWR_LV_MASK;
		csr |= VREF_CSR_BUF21EN_MASK;
	} else if (mode == NXP_VREF_MODE_HIGH_POWER) {
		csr &= ~VREF_CSR_REGEN_MASK &
			~VREF_CSR_CHOPEN_MASK;
		csr |= VREF_CSR_HI_PWR_LV_MASK &
			VREF_CSR_BUF21EN_MASK;
	} else if (mode == NXP_VREF_MODE_INTERNAL_REGULATOR) {
		csr |= VREF_CSR_REGEN_MASK &
			VREF_CSR_CHOPEN_MASK &
			VREF_CSR_HI_PWR_LV_MASK &
			VREF_CSR_BUF21EN_MASK;
	} else {
		return -EINVAL;
	}

	base->CSR = csr;

	k_busy_wait(config->buf_start_delay);

	return 0;
}

static int regulator_nxp_vref_get_mode(const struct device *dev, regulator_mode_t *mode)
{
	const struct regulator_nxp_vref_config *config = dev->config;
	VREF_Type *const base = config->base;
	uint32_t csr = base->CSR;

	/* Check bits to determine mode */
	if (csr & VREF_CSR_REGEN_MASK) {
		*mode = NXP_VREF_MODE_INTERNAL_REGULATOR;
	} else if (csr & VREF_CSR_HI_PWR_LV_MASK) {
		*mode = NXP_VREF_MODE_HIGH_POWER;
	} else if (csr & VREF_CSR_BUF21EN_MASK) {
		*mode = NXP_VREF_MODE_LOW_POWER;
	} else {
		*mode = NXP_VREF_MODE_STANDBY;
	}

	return 0;
}

static inline unsigned int regulator_nxp_vref_count_voltages(const struct device *dev)
{
	return linear_range_values_count(&utrim_range);
}

static int regulator_nxp_vref_list_voltage(const struct device *dev,
						unsigned int idx, int32_t *volt_uv)
{
	return linear_range_get_value(&utrim_range, idx, volt_uv);
}

static int regulator_nxp_vref_set_voltage(const struct device *dev,
					int32_t min_uv, int32_t max_uv)
{
	const struct regulator_nxp_vref_config *config = dev->config;
	VREF_Type *const base = config->base;
	uint16_t idx;
	int ret;

	ret = linear_range_get_win_index(&utrim_range, min_uv, max_uv, &idx);
	if (ret < 0) {
		return ret;
	}

	base->UTRIM &= ~VREF_UTRIM_TRIM2V1_MASK;
	base->UTRIM |= VREF_UTRIM_TRIM2V1_MASK & idx;

	return 0;
}

static int regulator_nxp_vref_get_voltage(const struct device *dev,
						int32_t *volt_uv)
{
	const struct regulator_nxp_vref_config *config = dev->config;
	VREF_Type *const base = config->base;
	uint16_t idx;
	int ret;

	/* Linear range index is the register value */
	idx = (base->UTRIM & VREF_UTRIM_TRIM2V1_MASK) >> VREF_UTRIM_TRIM2V1_SHIFT;

	ret = linear_range_get_value(&utrim_range, base->UTRIM, volt_uv);

	return ret;
}

static const struct regulator_driver_api api = {
	.enable = regulator_nxp_vref_enable,
	.disable = regulator_nxp_vref_disable,
	.set_mode = regulator_nxp_vref_set_mode,
	.get_mode = regulator_nxp_vref_get_mode,
	.set_voltage = regulator_nxp_vref_set_voltage,
	.get_voltage = regulator_nxp_vref_get_voltage,
	.list_voltage = regulator_nxp_vref_list_voltage,
	.count_voltages = regulator_nxp_vref_count_voltages,
};

static int regulator_nxp_vref_init(const struct device *dev)
{
	const struct regulator_nxp_vref_config *config = dev->config;
	VREF_Type *base = config->base;
	int ret;

	regulator_common_data_init(dev);

	/* Select ground */
	base->CSR &= ~VREF_CSR_REFL_GRD_SEL_MASK;
	base->CSR |= config->gnd_sel;

	ret = regulator_nxp_vref_disable(dev);
	if (ret < 0) {
		return ret;
	}

	return regulator_common_init(dev, false);
}

#define REGULATOR_NXP_VREF_DEFINE(inst)						\
	static struct regulator_nxp_vref_data data_##inst;			\
										\
	static const struct regulator_nxp_vref_config config_##inst = {		\
		.common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst),		\
		.base = (VREF_Type *) DT_INST_REG_ADDR(inst),			\
		.gnd_sel = DT_INST_ENUM_IDX_OR(inst, nxp_ground_select, 0),	\
		.buf_start_delay = DT_INST_PROP(inst,				\
				nxp_buffer_startup_delay_us),			\
		.bg_start_time = DT_INST_PROP(inst,				\
				nxp_bandgap_startup_time_us),			\
	};									\
										\
	DEVICE_DT_INST_DEFINE(inst, regulator_nxp_vref_init, NULL, &data_##inst,\
				&config_##inst, POST_KERNEL,			\
				CONFIG_REGULATOR_NXP_VREF_INIT_PRIORITY, &api);	\

DT_INST_FOREACH_STATUS_OKAY(REGULATOR_NXP_VREF_DEFINE)
