/*
 * Tests for the driver model ADC API
 *
 * Copyright (c) 2015 Samsung Electronics
 * Przemyslaw Marczak <p.marczak@samsung.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <adc.h>
#include <dm.h>
#include <dm/root.h>
#include <dm/util.h>
#include <dm/test.h>
#include <errno.h>
#include <fdtdec.h>
#include <power/regulator.h>
#include <power/sandbox_pmic.h>
#include <sandbox-adc.h>
#include <test/ut.h>

DECLARE_GLOBAL_DATA_PTR;

static int dm_test_adc_bind(struct unit_test_state *uts)
{
	struct udevice *dev;

	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
	ut_asserteq_str(SANDBOX_ADC_DEVNAME, dev->name);

	return 0;
}
DM_TEST(dm_test_adc_bind, DM_TESTF_SCAN_FDT);

static int dm_test_adc_wrong_channel_selection(struct unit_test_state *uts)
{
	struct udevice *dev;

	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
	ut_asserteq(-EINVAL, adc_start_channel(dev, SANDBOX_ADC_CHANNELS));

	return 0;
}
DM_TEST(dm_test_adc_wrong_channel_selection, DM_TESTF_SCAN_FDT);

static int dm_test_adc_supply(struct unit_test_state *uts)
{
	struct udevice *supply;
	struct udevice *dev;
	int uV;

	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));

	/* Test Vss value - predefined 0 uV */
	ut_assertok(adc_vss_value(dev, &uV));
	ut_asserteq(SANDBOX_ADC_VSS_VALUE, uV);

	/* Test Vdd initial value - buck2 */
	ut_assertok(adc_vdd_value(dev, &uV));
	ut_asserteq(SANDBOX_BUCK2_INITIAL_EXPECTED_UV, uV);

	/* Change Vdd value - buck2 manual preset */
	ut_assertok(regulator_get_by_devname(SANDBOX_BUCK2_DEVNAME, &supply));
	ut_assertok(regulator_set_value(supply, SANDBOX_BUCK2_SET_UV));
	ut_asserteq(SANDBOX_BUCK2_SET_UV, regulator_get_value(supply));

	/* Update ADC platdata and get new Vdd value */
	ut_assertok(adc_vdd_value(dev, &uV));
	ut_asserteq(SANDBOX_BUCK2_SET_UV, uV);

	/* Disable buck2 and test ADC supply enable function */
	ut_assertok(regulator_set_enable(supply, false));
	ut_asserteq(false, regulator_get_enable(supply));
	/* adc_start_channel() should enable the supply regulator */
	ut_assertok(adc_start_channel(dev, 0));
	ut_asserteq(true, regulator_get_enable(supply));

	return 0;
}
DM_TEST(dm_test_adc_supply, DM_TESTF_SCAN_FDT);

struct adc_channel adc_channel_test_data[] = {
	{ 0, SANDBOX_ADC_CHANNEL0_DATA },
	{ 1, SANDBOX_ADC_CHANNEL1_DATA },
	{ 2, SANDBOX_ADC_CHANNEL2_DATA },
	{ 3, SANDBOX_ADC_CHANNEL3_DATA },
};

static int dm_test_adc_single_channel_conversion(struct unit_test_state *uts)
{
	struct adc_channel *tdata = adc_channel_test_data;
	unsigned int i, data;
	struct udevice *dev;

	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
	/* Test each ADC channel's value */
	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++) {
		ut_assertok(adc_start_channel(dev, tdata->id));
		ut_assertok(adc_channel_data(dev, tdata->id, &data));
		ut_asserteq(tdata->data, data);
	}

	return 0;
}
DM_TEST(dm_test_adc_single_channel_conversion, DM_TESTF_SCAN_FDT);

static int dm_test_adc_multi_channel_conversion(struct unit_test_state *uts)
{
	struct adc_channel channels[SANDBOX_ADC_CHANNELS];
	struct udevice *dev;
	struct adc_channel *tdata = adc_channel_test_data;
	unsigned int i, channel_mask;

	channel_mask = ADC_CHANNEL(0) | ADC_CHANNEL(1) |
		       ADC_CHANNEL(2) | ADC_CHANNEL(3);

	/* Start multi channel conversion */
	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
	ut_assertok(adc_start_channels(dev, channel_mask));
	ut_assertok(adc_channels_data(dev, channel_mask, channels));

	/* Compare the expected and returned conversion data. */
	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++)
		ut_asserteq(tdata->data, channels[i].data);

	return 0;
}
DM_TEST(dm_test_adc_multi_channel_conversion, DM_TESTF_SCAN_FDT);

static int dm_test_adc_single_channel_shot(struct unit_test_state *uts)
{
	struct adc_channel *tdata = adc_channel_test_data;
	unsigned int i, data;

	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++) {
		/* Start single channel conversion */
		ut_assertok(adc_channel_single_shot("adc", tdata->id, &data));
		/* Compare the expected and returned conversion data. */
		ut_asserteq(tdata->data, data);
	}

	return 0;
}
DM_TEST(dm_test_adc_single_channel_shot, DM_TESTF_SCAN_FDT);

static int dm_test_adc_multi_channel_shot(struct unit_test_state *uts)
{
	struct adc_channel channels[SANDBOX_ADC_CHANNELS];
	struct adc_channel *tdata = adc_channel_test_data;
	unsigned int i, channel_mask;

	channel_mask = ADC_CHANNEL(0) | ADC_CHANNEL(1) |
		       ADC_CHANNEL(2) | ADC_CHANNEL(3);

	/* Start single call and multi channel conversion */
	ut_assertok(adc_channels_single_shot("adc", channel_mask, channels));

	/* Compare the expected and returned conversion data. */
	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++)
		ut_asserteq(tdata->data, channels[i].data);

	return 0;
}
DM_TEST(dm_test_adc_multi_channel_shot, DM_TESTF_SCAN_FDT);
