/*
 * Copyright 2021 NXP
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * Based on regulator-fixed test and adc driver sample, with are
 * copyright Peter Bigot Consulting, LLC and Libre Solar Technologies GmbH,
 * respectively.
 */

#include <zephyr/zephyr.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/regulator.h>
#include <zephyr/drivers/regulator/consumer.h>
#include <ztest.h>

#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
	!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif

#define ADC_NODE		DT_PHANDLE(DT_PATH(zephyr_user), io_channels)

/* Common settings supported by most ADCs */
#define ADC_RESOLUTION		12
#define ADC_GAIN		ADC_GAIN_1
#define ADC_REFERENCE		ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME	ADC_ACQ_TIME_DEFAULT

static int16_t sample_buffer[1];

#define CHANNEL_ID DT_IO_CHANNELS_INPUT_BY_IDX(DT_PATH(zephyr_user), 0)

struct adc_channel_cfg channel_cfg = {
	.gain = ADC_GAIN,
	.reference = ADC_REFERENCE,
	.acquisition_time = ADC_ACQUISITION_TIME,
	.channel_id = CHANNEL_ID,
	.differential = 0
};

struct adc_sequence sequence = {
	/* individual channels will be added below */
	.channels    = BIT(CHANNEL_ID),
	.buffer      = sample_buffer,
	/* buffer size in bytes, not number of samples */
	.buffer_size = sizeof(sample_buffer),
	.resolution  = ADC_RESOLUTION,
};

static struct onoff_client cli;
static struct onoff_manager *callback_srv;
static struct onoff_client *callback_cli;
static uint32_t callback_state;
static int callback_res;
static onoff_client_callback callback_fn;

static void callback(struct onoff_manager *srv,
		     struct onoff_client *cli,
		     uint32_t state,
		     int res)
{
	onoff_client_callback cb = callback_fn;

	callback_srv = srv;
	callback_cli = cli;
	callback_state = state;
	callback_res = res;
	callback_fn = NULL;

	if (cb != NULL) {
		cb(srv, cli, state, res);
	}
}

static void reset_callback(void)
{
	callback_srv = NULL;
	callback_cli = NULL;
	callback_state = INT_MIN;
	callback_res = 0;
	callback_fn = NULL;
}

static void reset_client(void)
{
	cli = (struct onoff_client){};
	reset_callback();
	sys_notify_init_callback(&cli.notify, callback);
}

/* Returns voltage level of ADC in mV, or negative value on error */
static int adc_get_reading(const struct device *adc_dev)
{
	int rc, adc_vref, mv_value;

	adc_vref = adc_ref_internal(adc_dev);

	rc = adc_read(adc_dev, &sequence);
	if (rc) {
		return rc;
	}
	mv_value = sample_buffer[0];
	if (adc_vref > 0) {
		adc_raw_to_millivolts(adc_vref, ADC_GAIN, ADC_RESOLUTION, &mv_value);
	}
	TC_PRINT("ADC read %d mV\n", mv_value);
	return mv_value;
}

static void test_basic(void)
{
	const struct device *reg_dev, *adc_dev;
	int rc, adc_reading;

	adc_dev = device_get_binding(DT_LABEL(ADC_NODE));
	reg_dev = device_get_binding(CONFIG_TEST_PMIC_REGULATOR_NAME);
	zassert_not_null(adc_dev,
					"ADC device to check regulator output not defined");
	zassert_not_null(reg_dev,
					"Could not get regulator device binding");

	/* Configure ADC */
	adc_channel_setup(adc_dev, &channel_cfg);


	reset_client();

	/* Turn regulator on */
	rc = regulator_enable(reg_dev, &cli);
	zassert_true(rc >= 0,
		     "first enable failed: %d", rc);

	/* Wait for regulator to start */
	while (sys_notify_fetch_result(&cli.notify, &rc) == -EAGAIN) {
		k_yield();
	}
	rc = sys_notify_fetch_result(&cli.notify, &rc);
	zassert_true(rc == 0, "Could not fetch regulator enable result");

	zassert_equal(callback_cli, &cli,
		      "callback not invoked");
	zassert_equal(callback_res, 0,
		      "callback res: %d", callback_res);
	zassert_equal(callback_state, ONOFF_STATE_ON,
		      "callback state: 0x%x", callback_res);

	/* Read adc to ensure regulator actually booted */
	adc_reading = adc_get_reading(adc_dev);
	zassert_true(adc_reading > 200, /* Assume regulator provides at least 200mV */
		      "Regulator did not supply power, ADC read %d mV",
			  adc_reading);

	/* Turn it on again (another client) */

	reset_client();
	rc = regulator_enable(reg_dev, &cli);
	zassert_true(rc >= 0,
		     "second enable failed: %d", rc);

	zassert_equal(callback_cli, &cli,
		      "callback not invoked");
	zassert_true(callback_res >= 0,
		      "callback res: %d", callback_res);
	zassert_equal(callback_state, ONOFF_STATE_ON,
		      "callback state: 0x%x", callback_res);

	/* Make sure it's still on */

	adc_reading = adc_get_reading(adc_dev);
	zassert_true(adc_reading >= 200,
		      "Second on attempt failed, ADC read %d mV", adc_reading);

	/* Turn it off once (still has a client) */

	rc = regulator_disable(reg_dev);
	zassert_true(rc >= 0,
		     "first disable failed: %d", rc);

	/* Make sure it's still on */

	adc_reading = adc_get_reading(adc_dev);
	zassert_true(adc_reading >= 200,
		      "Regulator still has client, but ADC read %d mV", adc_reading);

	/* Turn it off again (no more clients) */

	rc = regulator_disable(reg_dev);
	zassert_true(rc >= 0,
		     "second disable failed: %d", rc);

	/* Verify the regulator is off */
	adc_reading = adc_get_reading(adc_dev);
	zassert_true(adc_reading <= 200,
		      "Regulator is on with no clients, ADC read %d mV", adc_reading);
}

void test_main(void)
{
	ztest_test_suite(regulator_test,
			 ztest_unit_test(test_basic)
			 );
	ztest_run_test_suite(regulator_test);
}
