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

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

#define DT_DRV_COMPAT zephyr_adc_emul

#include <drivers/adc.h>
#include <drivers/adc/adc_emul.h>
#include <kernel.h>
#include <logging/log.h>
#include <sys/byteorder.h>
#include <sys/util.h>
#include <zephyr.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);
