/**
 * @file
 *
 * @brief Emulated ADC driver
 */

/*
 * Copyright 2021 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT zephyr_adc_emul

#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/adc/adc_emul.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>

LOG_MODULE_REGISTER(adc_emul, CONFIG_ADC_LOG_LEVEL);

#define ADC_CONTEXT_USES_KERNEL_TIMER
#include "adc_context.h"

#define ADC_EMUL_MAX_RESOLUTION 16

typedef uint16_t adc_emul_res_t;

enum adc_emul_input_source {
	ADC_EMUL_CONST_VALUE,
	ADC_EMUL_CUSTOM_FUNC,
};

/**
 * @brief Channel of emulated ADC config
 *
 * This structure contains configuration of one channel of emulated ADC.
 */
struct adc_emul_chan_cfg {
	/** Pointer to function used to obtain input mV */
	adc_emul_value_func func;
	/** Pointer to data that are passed to @a func on call */
	void *func_data;
	/** Constant mV input value */
	uint32_t const_value;
	/** Gain used on output value */
	enum adc_gain gain;
	/** Reference source */
	enum adc_reference ref;
	/** Input source which is used to obtain input value */
	enum adc_emul_input_source input;
};

/**
 * @brief Emulated ADC config
 *
 * This structure contains constant data for given instance of emulated ADC.
 */
struct adc_emul_config {
	/** Number of supported channels */
	uint8_t num_channels;
};

/**
 * @brief Emulated ADC data
 *
 * This structure contains data structures used by a emulated ADC.
 */
struct adc_emul_data {
	/** Structure that handle state of ongoing read operation */
	struct adc_context ctx;
	/** Pointer to ADC emulator own device structure */
	const struct device *dev;
	/** Pointer to memory where next sample will be written */
	uint16_t *buf;
	/** Pointer to where will be data stored in case of repeated sampling */
	uint16_t *repeat_buf;
	/** Mask with channels that will be sampled */
	uint32_t channels;
	/** Mask created from requested resolution in read operation */
	uint16_t res_mask;
	/** Reference voltage for ADC_REF_VDD_1 source */
	uint16_t ref_vdd;
	/** Reference voltage for ADC_REF_EXTERNAL0 source */
	uint16_t ref_ext0;
	/** Reference voltage for ADC_REF_EXTERNAL1 source */
	uint16_t ref_ext1;
	/** Reference voltage for ADC_REF_INTERNAL source */
	uint16_t ref_int;
	/** Array of each channel configuration */
	struct adc_emul_chan_cfg *chan_cfg;
	/** Structure used for acquisition thread */
	struct k_thread thread;
	/** Semaphore used to control acquisition thread */
	struct k_sem sem;
	/** Mutex used to control access to channels config and ref voltages */
	struct k_mutex cfg_mtx;

	/** Stack for acquisition thread */
	K_KERNEL_STACK_MEMBER(stack,
			CONFIG_ADC_EMUL_ACQUISITION_THREAD_STACK_SIZE);
};

int adc_emul_const_value_set(const struct device *dev, unsigned int chan,
			     uint32_t value)
{
	const struct adc_emul_config *config = dev->config;
	struct adc_emul_data *data = dev->data;
	struct adc_emul_chan_cfg *chan_cfg;

	if (chan >= config->num_channels) {
		LOG_ERR("unsupported channel %d", chan);
		return -EINVAL;
	}

	chan_cfg = &data->chan_cfg[chan];

	k_mutex_lock(&data->cfg_mtx, K_FOREVER);

	chan_cfg->input = ADC_EMUL_CONST_VALUE;
	chan_cfg->const_value = value;

	k_mutex_unlock(&data->cfg_mtx);

	return 0;
}

int adc_emul_value_func_set(const struct device *dev, unsigned int chan,
			    adc_emul_value_func func, void *func_data)
{
	const struct adc_emul_config *config = dev->config;
	struct adc_emul_data *data = dev->data;
	struct adc_emul_chan_cfg *chan_cfg;

	if (chan >= config->num_channels) {
		LOG_ERR("unsupported channel %d", chan);
		return -EINVAL;
	}

	chan_cfg = &data->chan_cfg[chan];

	k_mutex_lock(&data->cfg_mtx, K_FOREVER);

	chan_cfg->func = func;
	chan_cfg->func_data = func_data;
	chan_cfg->input = ADC_EMUL_CUSTOM_FUNC;

	k_mutex_unlock(&data->cfg_mtx);

	return 0;
}

int adc_emul_ref_voltage_set(const struct device *dev, enum adc_reference ref,
			     uint16_t value)
{
	struct adc_driver_api *api = (struct adc_driver_api *)dev->api;
	struct adc_emul_data *data = dev->data;
	int err = 0;

	k_mutex_lock(&data->cfg_mtx, K_FOREVER);

	switch (ref) {
	case ADC_REF_VDD_1:
		data->ref_vdd = value;
		break;
	case ADC_REF_INTERNAL:
		data->ref_int = value;
		api->ref_internal = value;
		break;
	case ADC_REF_EXTERNAL0:
		data->ref_ext0 = value;
		break;
	case ADC_REF_EXTERNAL1:
		data->ref_ext1 = value;
		break;
	default:
		err = -EINVAL;
	}

	k_mutex_unlock(&data->cfg_mtx);

	return err;
}

/**
 * @brief Convert @p ref to reference voltage value in mV
 *
 * @param data Internal data of ADC emulator
 * @param ref Select which reference source should be used
 *
 * @return Reference voltage in mV
 * @return 0 on error
 */
static uint16_t adc_emul_get_ref_voltage(struct adc_emul_data *data,
					 enum adc_reference ref)
{
	uint16_t voltage;

	k_mutex_lock(&data->cfg_mtx, K_FOREVER);

	switch (ref) {
	case ADC_REF_VDD_1:
		voltage = data->ref_vdd;
		break;
	case ADC_REF_VDD_1_2:
		voltage = data->ref_vdd / 2;
		break;
	case ADC_REF_VDD_1_3:
		voltage = data->ref_vdd / 3;
		break;
	case ADC_REF_VDD_1_4:
		voltage = data->ref_vdd / 4;
		break;
	case ADC_REF_INTERNAL:
		voltage = data->ref_int;
		break;
	case ADC_REF_EXTERNAL0:
		voltage = data->ref_ext0;
		break;
	case ADC_REF_EXTERNAL1:
		voltage = data->ref_ext1;
		break;
	default:
		voltage = 0;
	}

	k_mutex_unlock(&data->cfg_mtx);

	return voltage;
}

static int adc_emul_channel_setup(const struct device *dev,
				  const struct adc_channel_cfg *channel_cfg)
{
	const struct adc_emul_config *config = dev->config;
	struct adc_emul_chan_cfg *emul_chan_cfg;
	struct adc_emul_data *data = dev->data;

	if (channel_cfg->channel_id >= config->num_channels) {
		LOG_ERR("unsupported channel id '%d'", channel_cfg->channel_id);
		return -ENOTSUP;
	}

	if (adc_emul_get_ref_voltage(data, channel_cfg->reference) == 0) {
		LOG_ERR("unsupported channel reference '%d'",
			channel_cfg->reference);
		return -ENOTSUP;
	}

	if (channel_cfg->differential) {
		LOG_ERR("unsupported differential mode");
		return -ENOTSUP;
	}

	emul_chan_cfg = &data->chan_cfg[channel_cfg->channel_id];

	k_mutex_lock(&data->cfg_mtx, K_FOREVER);

	emul_chan_cfg->gain = channel_cfg->gain;
	emul_chan_cfg->ref = channel_cfg->reference;

	k_mutex_unlock(&data->cfg_mtx);

	return 0;
}

/**
 * @brief Check if buffer in @p sequence is big enough to hold all ADC samples
 *
 * @param dev ADC emulator device
 * @param sequence ADC sequence description
 *
 * @return 0 on success
 * @return -ENOMEM if buffer is not big enough
 */
static int adc_emul_check_buffer_size(const struct device *dev,
					 const struct adc_sequence *sequence)
{
	const struct adc_emul_config *config = dev->config;
	uint8_t channels = 0;
	size_t needed;
	uint32_t mask;

	for (mask = BIT(config->num_channels - 1); mask != 0; mask >>= 1) {
		if (mask & sequence->channels) {
			channels++;
		}
	}

	needed = channels * sizeof(adc_emul_res_t);
	if (sequence->options) {
		needed *= (1 + sequence->options->extra_samplings);
	}

	if (sequence->buffer_size < needed) {
		return -ENOMEM;
	}

	return 0;
}

/**
 * @brief Start processing read request
 *
 * @param dev ADC emulator device
 * @param sequence ADC sequence description
 *
 * @return 0 on success
 * @return -ENOTSUP if requested resolution or channel is out side of supported
 *         range
 * @return -ENOMEM if buffer is not big enough
 *         (see @ref adc_emul_check_buffer_size)
 * @return other error code returned by adc_context_wait_for_completion
 */
static int adc_emul_start_read(const struct device *dev,
			       const struct adc_sequence *sequence)
{
	const struct adc_emul_config *config = dev->config;
	struct adc_emul_data *data = dev->data;
	int err;

	if (sequence->resolution > ADC_EMUL_MAX_RESOLUTION ||
	    sequence->resolution == 0) {
		LOG_ERR("unsupported resolution %d", sequence->resolution);
		return -ENOTSUP;
	}

	if (find_msb_set(sequence->channels) > config->num_channels) {
		LOG_ERR("unsupported channels in mask: 0x%08x",
			sequence->channels);
		return -ENOTSUP;
	}

	err = adc_emul_check_buffer_size(dev, sequence);
	if (err) {
		LOG_ERR("buffer size too small");
		return err;
	}

	data->res_mask = BIT_MASK(sequence->resolution);
	data->buf = sequence->buffer;
	adc_context_start_read(&data->ctx, sequence);

	return adc_context_wait_for_completion(&data->ctx);
}

static int adc_emul_read_async(const struct device *dev,
			       const struct adc_sequence *sequence,
			       struct k_poll_signal *async)
{
	struct adc_emul_data *data = dev->data;
	int err;

	adc_context_lock(&data->ctx, async ? true : false, async);
	err = adc_emul_start_read(dev, sequence);
	adc_context_release(&data->ctx, err);

	return err;
}

static int adc_emul_read(const struct device *dev,
			 const struct adc_sequence *sequence)
{
	return adc_emul_read_async(dev, sequence, NULL);
}

static void adc_context_start_sampling(struct adc_context *ctx)
{
	struct adc_emul_data *data = CONTAINER_OF(ctx, struct adc_emul_data,
						  ctx);

	data->channels = ctx->sequence.channels;
	data->repeat_buf = data->buf;

	k_sem_give(&data->sem);
}

static void adc_context_update_buffer_pointer(struct adc_context *ctx,
					      bool repeat_sampling)
{
	struct adc_emul_data *data = CONTAINER_OF(ctx, struct adc_emul_data,
						  ctx);

	if (repeat_sampling) {
		data->buf = data->repeat_buf;
	}
}

/**
 * @brief Convert input voltage of ADC @p chan to raw output value
 *
 * @param data Internal data of ADC emulator
 * @param chan ADC channel to sample
 * @param result Raw output value
 *
 * @return 0 on success
 * @return -EINVAL if failed to get reference voltage or unknown input is
 *         selected
 * @return other error code returned by custom function
 */
static int adc_emul_get_chan_value(struct adc_emul_data *data,
				   unsigned int chan,
				   adc_emul_res_t *result)
{
	struct adc_emul_chan_cfg *chan_cfg = &data->chan_cfg[chan];
	uint32_t input_mV;
	uint32_t ref_v;
	uint64_t temp; /* Temporary 64 bit value prevent overflows */
	int err = 0;

	k_mutex_lock(&data->cfg_mtx, K_FOREVER);

	/* Get input voltage */
	switch (chan_cfg->input) {
	case ADC_EMUL_CONST_VALUE:
		input_mV = chan_cfg->const_value;
		break;

	case ADC_EMUL_CUSTOM_FUNC:
		err = chan_cfg->func(data->dev, chan, chan_cfg->func_data,
				     &input_mV);
		if (err) {
			LOG_ERR("failed to read channel %d (err %d)",
				chan, err);
			goto out;
		}
		break;

	default:
		LOG_ERR("unknown input source %d", chan_cfg->input);
		err = -EINVAL;
		goto out;
	}

	/* Get reference voltage and apply inverted gain */
	ref_v = adc_emul_get_ref_voltage(data, chan_cfg->ref);
	err = adc_gain_invert(chan_cfg->gain, &ref_v);
	if (ref_v == 0 || err) {
		LOG_ERR("failed to get ref voltage (channel %d)", chan);
		err = -EINVAL;
		goto out;
	}

	/* Calculate output value */
	temp = (uint64_t)input_mV * data->res_mask / ref_v;

	/* If output value is greater than resolution, it has to be trimmed */
	if (temp > data->res_mask) {
		temp = data->res_mask;
	}

	*result = temp;

out:
	k_mutex_unlock(&data->cfg_mtx);

	return err;
}

/**
 * @brief Main function of thread which is used to collect samples from
 *        emulated ADC. When adc_context_start_sampling give semaphore,
 *        for each requested channel value function is called. Returned
 *        mV value is converted to output using reference voltage, gain
 *        and requested resolution.
 *
 * @param data Internal data of ADC emulator
 *
 * @return This thread should not end
 */
static void adc_emul_acquisition_thread(struct adc_emul_data *data)
{
	int err;

	while (true) {
		k_sem_take(&data->sem, K_FOREVER);

		err = 0;

		while (data->channels) {
			adc_emul_res_t result = 0;
			unsigned int chan = find_lsb_set(data->channels) - 1;

			LOG_DBG("reading channel %d", chan);

			err = adc_emul_get_chan_value(data, chan, &result);
			if (err) {
				adc_context_complete(&data->ctx, err);
				break;
			}

			LOG_DBG("read channel %d, result = %d", chan, result);

			*data->buf++ = result;
			WRITE_BIT(data->channels, chan, 0);
		}

		if (!err) {
			adc_context_on_sampling_done(&data->ctx, data->dev);
		}
	}
}

/**
 * @brief Function called on init for each ADC emulator device. It setups all
 *        channels to return constant 0 mV and create acquisition thread.
 *
 * @param dev ADC emulator device
 *
 * @return 0 on success
 */
static int adc_emul_init(const struct device *dev)
{
	const struct adc_emul_config *config = dev->config;
	struct adc_emul_data *data = dev->data;
	int chan;

	data->dev = dev;

	k_sem_init(&data->sem, 0, 1);
	k_mutex_init(&data->cfg_mtx);

	for (chan = 0; chan < config->num_channels; chan++) {
		struct adc_emul_chan_cfg *chan_cfg = &data->chan_cfg[chan];

		chan_cfg->func = NULL;
		chan_cfg->func_data = NULL;
		chan_cfg->input = ADC_EMUL_CONST_VALUE;
		chan_cfg->const_value = 0;
	}

	k_thread_create(&data->thread, data->stack,
			CONFIG_ADC_EMUL_ACQUISITION_THREAD_STACK_SIZE,
			(k_thread_entry_t)adc_emul_acquisition_thread,
			data, NULL, NULL,
			CONFIG_ADC_EMUL_ACQUISITION_THREAD_PRIO,
			0, K_NO_WAIT);

	adc_context_unlock_unconditionally(&data->ctx);

	return 0;
}

#define ADC_EMUL_INIT(_num)						\
	static struct adc_driver_api adc_emul_api_##_num = {		\
		.channel_setup = adc_emul_channel_setup,		\
		.read = adc_emul_read,					\
		.ref_internal = DT_INST_PROP(_num, ref_internal_mv),	\
		IF_ENABLED(CONFIG_ADC_ASYNC,				\
			(.read_async = adc_emul_read_async,))		\
	};								\
									\
	static struct adc_emul_chan_cfg					\
		adc_emul_ch_cfg_##_num[DT_INST_PROP(_num, nchannels)];	\
									\
	static const struct adc_emul_config adc_emul_config_##_num = {	\
		.num_channels = DT_INST_PROP(_num, nchannels),		\
	};								\
									\
	static struct adc_emul_data adc_emul_data_##_num = {		\
		ADC_CONTEXT_INIT_TIMER(adc_emul_data_##_num, ctx),	\
		ADC_CONTEXT_INIT_LOCK(adc_emul_data_##_num, ctx),	\
		ADC_CONTEXT_INIT_SYNC(adc_emul_data_##_num, ctx),	\
		.chan_cfg = adc_emul_ch_cfg_##_num,			\
		.ref_vdd = DT_INST_PROP(_num, ref_vdd_mv),		\
		.ref_ext0 = DT_INST_PROP(_num, ref_external0_mv),	\
		.ref_ext1 = DT_INST_PROP(_num, ref_external1_mv),	\
		.ref_int = DT_INST_PROP(_num, ref_internal_mv),		\
	};								\
									\
	DEVICE_DT_INST_DEFINE(_num, adc_emul_init, NULL,		\
			      &adc_emul_data_##_num,			\
			      &adc_emul_config_##_num, POST_KERNEL,	\
			      CONFIG_ADC_INIT_PRIORITY,			\
			      &adc_emul_api_##_num)

DT_INST_FOREACH_STATUS_OKAY(ADC_EMUL_INIT);
