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

#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/adc/adc_emul.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

#define ADC_DEVICE_NODE		DT_INST(0, zephyr_adc_emul)
#define ADC_REF_INTERNAL_MV	DT_PROP(DT_INST(0, zephyr_adc_emul), ref_internal_mv)
#define ADC_REF_EXTERNAL1_MV	DT_PROP(DT_INST(0, zephyr_adc_emul), ref_external1_mv)
#define ADC_RESOLUTION		14
#define ADC_ACQUISITION_TIME	ADC_ACQ_TIME_DEFAULT
#define ADC_1ST_CHANNEL_ID	0
#define ADC_2ND_CHANNEL_ID	1

#define INVALID_ADC_VALUE	SHRT_MIN
/* Raw to millivolt conversion doesn't handle rounding */
#define MV_OUTPUT_EPS		2
#define SEQUENCE_STEP		100

#define BUFFER_SIZE  6
static ZTEST_BMEM int16_t m_sample_buffer[BUFFER_SIZE];

/**
 * @brief Get ADC emulated device
 *
 * @return pointer to ADC device
 */
const struct device *get_adc_device(void)
{
	const struct device *const adc_dev = DEVICE_DT_GET(ADC_DEVICE_NODE);

	zassert_true(device_is_ready(adc_dev), "ADC device is not ready");

	return adc_dev;
}

/**
 * @brief Setup channel with specific reference and gain
 *
 * @param adc_dev Pointer to ADC device
 * @param ref ADC reference voltage source
 * @param gain Gain applied to ADC @p channel
 * @param channel ADC channel which is being setup
 *
 * @return none
 */
static void channel_setup(const struct device *adc_dev, enum adc_reference ref,
			  enum adc_gain gain, int channel)
{
	int ret;
	struct adc_channel_cfg channel_cfg = {
		.gain             = gain,
		.reference        = ref,
		.acquisition_time = ADC_ACQUISITION_TIME,
		.channel_id       = channel,
	};

	ret = adc_channel_setup(adc_dev, &channel_cfg);
	zassert_ok(ret, "Setting up of the %d channel failed with code %d",
		   channel, ret);
}

/**
 * @brief Check if samples for specific channel are correct. It can check
 *        samples with arithmetic sequence with common difference.
 *
 * @param expected_count Number of samples that are expected to be set
 * @param start_mv_value Voltage in mV that was set on input at the beginning
 *                       of sampling
 * @param step Common difference in arithmetic sequence which describes how
 *             samples were generated
 * @param num_channels Number of channels that were sampled
 * @param channel_id ADC channel from which samples are checked
 * @param ref_mv Reference voltage in mV
 * @param gain Gain applied to ADC @p channel_id
 *
 * @return none
 */
static void check_samples(int expected_count, int32_t start_mv_value, int step,
			  int num_channels, int channel_id, int32_t ref_mv,
			  enum adc_gain gain)
{
	int32_t output, expected;
	int i, ret;

	for (i = channel_id; i < expected_count; i += num_channels) {
		expected = start_mv_value + i / num_channels * step;
		output = m_sample_buffer[i];
		ret = adc_raw_to_millivolts(ref_mv, gain, ADC_RESOLUTION,
					    &output);
		zassert_ok(ret, "adc_raw_to_millivolts() failed with code %d",
			   ret);
		zassert_within(expected, output, MV_OUTPUT_EPS,
			       "%u != %u [%u] should has set value",
			       expected, output, i);
	}

}

/**
 * @brief Check if any values in buffer were set after expected samples.
 *
 * @param expected_count Number of samples that are expected to be set
 *
 * @return none
 */
static void check_empty_samples(int expected_count)
{
	int i;

	for (i = expected_count; i < BUFFER_SIZE; i++) {
		zassert_equal(INVALID_ADC_VALUE, m_sample_buffer[i],
			      "[%u] should be empty", i);
	}
}

/**
 * @brief Run adc_read for given channels and collect specified number of
 *        samples.
 *
 * @param adc_dev Pointer to ADC device
 * @param channel_mask Mask of channels that will be sampled
 * @param samples Number of requested samples for each channel
 *
 * @return none
 */
static void start_adc_read(const struct device *adc_dev, uint32_t channel_mask,
			   int samples)
{
	int ret;
	const struct adc_sequence_options *options_ptr;

	const struct adc_sequence_options options = {
		.extra_samplings = samples - 1,
	};

	if (samples > 1) {
		options_ptr = &options;
	} else {
		options_ptr = NULL;
	}

	const struct adc_sequence sequence = {
		.options     = options_ptr,
		.channels    = channel_mask,
		.buffer      = m_sample_buffer,
		.buffer_size = sizeof(m_sample_buffer),
		.resolution  = ADC_RESOLUTION,
	};

	ret = adc_read(adc_dev, &sequence);
	zassert_ok(ret, "adc_read() failed with code %d", ret);
}

/** @brief Data for handle_seq function */
struct handle_seq_params {
	/** Current input value in mV */
	unsigned int value;
};

/**
 * @brief Simple custom function to set as value input function for emulated
 *        ADC channel. It returns arithmetic sequence with SEQUENCE_STEP
 *        as common difference, starting from param value.
 *
 * @param dev Pointer to ADC device
 * @param channel ADC channel for which input value is requested
 * @param data Pointer to function parameters. It has to be
 *             struct handle_seq_params type
 * @param result Pointer where input value should be stored
 *
 * @return 0 on success
 * @return -EINVAL when current input value equals 0
 */
static int handle_seq(const struct device *dev, unsigned int channel,
		      void *data, uint32_t *result)
{
	struct handle_seq_params *param = data;

	if (param->value == 0) {
		return -EINVAL;
	}

	*result = param->value;
	param->value += SEQUENCE_STEP;

	return 0;
}

/** @brief Test setting one channel with constant output. */
ZTEST_USER(adc_emul, test_adc_emul_single_value)
{
	const uint16_t input_mv = 1500;
	const int samples = 4;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);

	/* ADC emulator-specific setup */
	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples, input_mv, 0 /* step */, 1 /* channels */,
		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1);

	check_empty_samples(samples);
}

/** @brief Test setting two channels with different constant output */
ZTEST_USER(adc_emul, test_adc_emul_single_value_2ch)
{
	const uint16_t input1_mv = 3000;
	const uint16_t input2_mv = 2000;
	const int samples = 3;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);
	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_2ND_CHANNEL_ID);

	/* ADC emulator-specific setup */
	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
			BIT(ADC_2ND_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1);
	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1);

	check_empty_samples(samples * 2);
}

/** @brief Test setting one channel with custom function. */
ZTEST_USER(adc_emul, test_adc_emul_custom_function)
{
	struct handle_seq_params channel1_param;
	const uint16_t input_mv = 1500;
	const int samples = 4;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);

	/* ADC emulator-specific setup */
	channel1_param.value = input_mv;

	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
				      handle_seq, &channel1_param);
	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples, input_mv, SEQUENCE_STEP, 1 /* channels */,
		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1);

	check_empty_samples(samples);
}

/**
 * @brief Test setting two channels with custom function and different
 *        params.
 */
ZTEST_USER(adc_emul, test_adc_emul_custom_function_2ch)
{
	struct handle_seq_params channel1_param;
	struct handle_seq_params channel2_param;
	const uint16_t input1_mv = 1500;
	const uint16_t input2_mv = 1000;
	const int samples = 3;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);
	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_2ND_CHANNEL_ID);

	/* ADC emulator-specific setup */
	channel1_param.value = input1_mv;
	channel2_param.value = input2_mv;

	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
				      handle_seq, &channel1_param);
	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);

	ret = adc_emul_value_func_set(adc_dev, ADC_2ND_CHANNEL_ID,
				      handle_seq, &channel2_param);
	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
			BIT(ADC_2ND_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples * 2, input1_mv, SEQUENCE_STEP,
		      2 /* channels */, 0 /* first channel data */,
		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
	check_samples(samples * 2, input2_mv, SEQUENCE_STEP,
		      2 /* channels */, 1 /* first channel data */,
		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);

	check_empty_samples(samples * 2);
}

/**
 * @brief Test setting two channels, one with custom function and
 *        one with constant value.
 */
ZTEST_USER(adc_emul, test_adc_emul_custom_function_and_value)
{
	struct handle_seq_params channel1_param;
	const uint16_t input1_mv = 1500;
	const uint16_t input2_mv = 1000;
	const int samples = 3;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);
	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_2ND_CHANNEL_ID);

	/* ADC emulator-specific setup */
	channel1_param.value = input1_mv;

	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
				      handle_seq, &channel1_param);
	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);

	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
			BIT(ADC_2ND_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples * 2, input1_mv, SEQUENCE_STEP,
		      2 /* channels */, 0 /* first channel data */,
		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1);

	check_empty_samples(samples * 2);
}

/** @brief Test few different settings of gain argument. */
ZTEST_USER(adc_emul, test_adc_emul_gain)
{
	const uint16_t input_mv = 1000;
	uint32_t channel_mask;
	const int samples = 3;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1_6,
		      ADC_1ST_CHANNEL_ID);
	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_3,
		      ADC_2ND_CHANNEL_ID);

	/* ADC emulator-specific setup */
	channel_mask = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID);

	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, channel_mask, samples);

	/* Check samples */
	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1_6);
	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_3);

	check_empty_samples(samples * 2);

	/* Change gain and re-run test */
	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1_4,
		      ADC_1ST_CHANNEL_ID);
	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_2_3,
		      ADC_2ND_CHANNEL_ID);

	/* Test sampling */
	start_adc_read(adc_dev, channel_mask, samples);

	/* Check samples */
	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1_4);
	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_2_3);

	check_empty_samples(samples * 2);
}

/**
 * @brief Test behaviour on input higher than reference. Return value should be
 *        cropped to reference value and cannot exceed resolution requested in
 *        adc_read().
 */
ZTEST_USER(adc_emul, test_adc_emul_input_higher_than_ref)
{
	const uint16_t input_mv = ADC_REF_INTERNAL_MV + 100;
	const int samples = 4;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);

	/* ADC emulator-specific setup */
	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);

	/*
	 * Check samples - returned value should max out on reference value.
	 * Raw value shouldn't exceed resolution.
	 */
	check_samples(samples, ADC_REF_INTERNAL_MV, 0 /* step */,
		      1 /* channels */, 0 /* first channel data */,
		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);

	check_empty_samples(samples);

	for (i = 0; i < samples; i++) {
		zassert_equal(BIT_MASK(ADC_RESOLUTION), m_sample_buffer[i],
			      "[%u] raw value isn't max value", i);
	}
}

/**
 * @brief Test different reference sources and if error is reported when
 *        unconfigured reference source is requested.
 */
ZTEST_USER(adc_emul, test_adc_emul_reference)
{
	const uint16_t input1_mv = 4000;
	const uint16_t input2_mv = 2000;
	const int samples = 3;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_EXTERNAL1, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);

	struct adc_channel_cfg channel_cfg = {
		.gain             = ADC_GAIN_1,
		/* Reference value not setup in DTS */
		.reference        = ADC_REF_EXTERNAL0,
		.acquisition_time = ADC_ACQUISITION_TIME,
		.channel_id       = ADC_2ND_CHANNEL_ID,
	};

	ret = adc_channel_setup(adc_dev, &channel_cfg);
	zassert_not_equal(ret, 0,
			  "Setting up of the %d channel shouldn't succeeded",
			  ADC_2ND_CHANNEL_ID);

	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_2ND_CHANNEL_ID);

	/* ADC emulator-specific setup */
	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
			BIT(ADC_2ND_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
		      0 /* first channel data */, ADC_REF_EXTERNAL1_MV,
		      ADC_GAIN_1);
	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1);

	check_empty_samples(samples * 2);
}

/** @brief Test setting reference value. */
ZTEST_USER(adc_emul, test_adc_emul_ref_voltage_set)
{
	const uint16_t input1_mv = 4000;
	const uint16_t input2_mv = 2000;
	const uint16_t ref1_mv = 6000;
	const uint16_t ref2_mv = 9000;
	const int samples = 3;
	int ret, i;

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
	}

	/* Generic ADC setup */
	const struct device *adc_dev = get_adc_device();

	channel_setup(adc_dev, ADC_REF_EXTERNAL1, ADC_GAIN_1,
		      ADC_1ST_CHANNEL_ID);
	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
		      ADC_2ND_CHANNEL_ID);

	/* ADC emulator-specific setup */
	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);

	/* Change reference voltage */
	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_EXTERNAL1, ref1_mv);
	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);

	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_INTERNAL, ref2_mv);
	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
			BIT(ADC_2ND_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
		      0 /* first channel data */, ref1_mv, ADC_GAIN_1);
	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
		      1 /* first channel data */, ref2_mv, ADC_GAIN_1);

	check_empty_samples(samples * 2);

	/* Set previous reference voltage value */
	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_EXTERNAL1,
				       ADC_REF_EXTERNAL1_MV);
	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);

	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_INTERNAL,
				       ADC_REF_INTERNAL_MV);
	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);

	/* Test sampling */
	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
			BIT(ADC_2ND_CHANNEL_ID), samples);

	/* Check samples */
	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
		      0 /* first channel data */, ADC_REF_EXTERNAL1_MV,
		      ADC_GAIN_1);
	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
		      ADC_GAIN_1);

	check_empty_samples(samples * 2);
}

void *adc_emul_setup(void)
{
	k_object_access_grant(get_adc_device(), k_current_get());

	return NULL;
}

ZTEST_SUITE(adc_emul, NULL, adc_emul_setup, NULL, NULL, NULL);
