text: /*
   * 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 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);
  }
  