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

#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>

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

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

	ut_assertok(adc_channel_mask(dev, &channel_mask));
	ut_asserteq((1 << SANDBOX_ADC_CHANNELS) - 1, channel_mask);

	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@0", &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@0", &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@0", &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@0", &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@0", 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@0", 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);

static const int dm_test_adc_uV_data[SANDBOX_ADC_CHANNELS] = {
	((u64)SANDBOX_ADC_CHANNEL0_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
		SANDBOX_ADC_DATA_MASK,
	((u64)SANDBOX_ADC_CHANNEL1_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
		SANDBOX_ADC_DATA_MASK,
	((u64)SANDBOX_ADC_CHANNEL2_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
		SANDBOX_ADC_DATA_MASK,
	((u64)SANDBOX_ADC_CHANNEL3_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
		SANDBOX_ADC_DATA_MASK,
};

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

	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc@0", &dev));
	/* Test each ADC channel's value in microvolts */
	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_assertok(adc_raw_to_uV(dev, data, &uV));
		ut_asserteq(dm_test_adc_uV_data[i], uV);
	}

	return 0;
}
DM_TEST(dm_test_adc_raw_to_uV, DM_TESTF_SCAN_FDT);
