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

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

#define ADC_DEVICE_NAME		DT_LABEL(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 *adc_dev = device_get_binding(ADC_DEVICE_NAME);

	zassert_not_null(adc_dev, "Cannot get ADC device");

	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. */
static void test_adc_emul_single_value(void)
{
	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 */
static void test_adc_emul_single_value_2ch(void)
{
	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. */
static void test_adc_emul_custom_function(void)
{
	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.
 */
static void test_adc_emul_custom_function_2ch(void)
{
	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.
 */
static void test_adc_emul_custom_function_and_value(void)
{
	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. */
static void test_adc_emul_gain(void)
{
	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().
 */
static void test_adc_emul_input_higher_than_ref(void)
{
	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.
 */
static void test_adc_emul_reference(void)
{
	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. */
static void test_adc_emul_ref_voltage_set(void)
{
	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 test_main(void)
{
	k_object_access_grant(get_adc_device(), k_current_get());

	ztest_test_suite(adc_basic_test,
			 ztest_user_unit_test(test_adc_emul_single_value),
			 ztest_user_unit_test(test_adc_emul_single_value_2ch),
			 ztest_user_unit_test(test_adc_emul_custom_function),
			 ztest_user_unit_test(test_adc_emul_custom_function_2ch),
			 ztest_user_unit_test(test_adc_emul_custom_function_and_value),
			 ztest_user_unit_test(test_adc_emul_gain),
			 ztest_user_unit_test(test_adc_emul_input_higher_than_ref),
			 ztest_user_unit_test(test_adc_emul_reference),
			 ztest_user_unit_test(test_adc_emul_ref_voltage_set));
	ztest_run_test_suite(adc_basic_test);
}
