/**
 * @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 emualted 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 acquisiton 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_KERNEL_INIT_PRIORITY_DEVICE,	\
			      &adc_emul_api_##_num)

DT_INST_FOREACH_STATUS_OKAY(ADC_EMUL_INIT);
