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

#include <drivers/adc.h>
#include <drivers/adc/adc_emul.h>
#include <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 milivolt 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 shoudn'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 shuldn'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);
}
