/*
 * Copyright 2022 The Chromium OS Authors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT zephyr_usb_c_vbus_adc

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usbc_vbus_adc, CONFIG_USBC_LOG_LEVEL);

#include <zephyr/device.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/usb_c/usbc_pd.h>
#include <zephyr/drivers/usb_c/usbc_vbus.h>
#include <soc.h>
#include <stddef.h>

#include "usbc_vbus_adc_priv.h"

/**
 * @brief Reads and returns VBUS measured in mV
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int adc_vbus_measure(const struct device *dev, int *meas)
{
	const struct usbc_vbus_config *const config = dev->config;
	struct usbc_vbus_data *data = dev->data;
	int value;
	int ret;

	__ASSERT(meas != NULL, "ADC VBUS meas must not be NULL");

	ret = adc_read(config->adc_channel.dev, &data->sequence);
	if (ret != 0) {
		LOG_INF("ADC reading failed with error %d.", ret);
		return ret;
	}

	value = data->sample;
	ret = adc_raw_to_millivolts_dt(&config->adc_channel, &value);
	if (ret != 0) {
		LOG_INF("Scaling ADC failed with error %d.", ret);
		return ret;
	}

	if (config->full_ohm > 0) {
		/* VBUS is scaled down though a voltage divider */
		value = (value * 1000) / ((config->output_ohm * 1000) / config->full_ohm);
	}
	*meas = value;

	return 0;
}

/**
 * @brief Checks if VBUS is at a particular level
 *
 * @retval true if VBUS is at the level voltage, else false
 */
static bool adc_vbus_check_level(const struct device *dev,
				 enum tc_vbus_level level)
{
	int meas;
	int ret;

	ret = adc_vbus_measure(dev, &meas);
	if (ret) {
		return false;
	}

	switch (level) {
	case TC_VBUS_SAFE0V:
		return (meas < PD_V_SAFE_0V_MAX_MV);
	case TC_VBUS_PRESENT:
		return (meas >= PD_V_SAFE_5V_MIN_MV);
	case TC_VBUS_REMOVED:
		return (meas < TC_V_SINK_DISCONNECT_MAX_MV);
	}

	return false;
}

/**
 * @brief Sets pin to discharge VBUS
 *
 * @retval 0 on success
 * @retval -EIO on failure
 * @retval -ENOENT if enable pin isn't defined
 */
static int adc_vbus_discharge(const struct device *dev,
			      bool enable)
{
	const struct usbc_vbus_config *const config = dev->config;
	const struct gpio_dt_spec *gcd = &config->discharge_gpios;
	int ret = -ENOENT;

	if (gcd->port) {
		ret = gpio_pin_set_dt(gcd, enable);
	}
	return ret;
}

/**
 * @brief Sets pin to enable VBUS measurments
 *
 * @retval 0 on success
 * @retval -EIO on failure
 * @retval -ENOENT if enable pin isn't defined
 */
static int adc_vbus_enable(const struct device *dev,
			   bool enable)
{
	const struct usbc_vbus_config *const config = dev->config;
	const struct gpio_dt_spec *gcp = &config->power_gpios;
	int ret = -ENOENT;

	if (gcp->port) {
		ret = gpio_pin_set_dt(gcp, enable);
	}
	return ret;
}

/**
 * @brief Initializes the ADC VBUS Driver
 *
 * @retval 0 on success
 * @retval -EIO on failure
 */
static int adc_vbus_init(const struct device *dev)
{
	const struct usbc_vbus_config *const config = dev->config;
	struct usbc_vbus_data *data = dev->data;
	const struct gpio_dt_spec *gcp = &config->power_gpios;
	const struct gpio_dt_spec *gcd = &config->discharge_gpios;
	int ret;

	/* Configure VBUS Measurement enable pin if defined */
	if (gcp->port) {
		ret = device_is_ready(gcp->port);
		if (ret < 0) {
			LOG_ERR("%s: device not ready", gcp->port->name);
			return ret;
		}
		ret = gpio_pin_configure_dt(gcp, GPIO_OUTPUT_INACTIVE);
		if (ret < 0) {
			LOG_ERR("Failed to control feed %s.%u: %d",
				gcp->port->name, gcp->pin, ret);
			return ret;
		}
	}

	/* Configure VBUS Discharge pin if defined */
	if (gcd->port) {
		ret = device_is_ready(gcd->port);
		if (ret == false) {
			LOG_ERR("%s: device not ready", gcd->port->name);
			return ret;
		}
		ret = gpio_pin_configure_dt(gcd, GPIO_OUTPUT_INACTIVE);
		if (ret < 0) {
			LOG_ERR("Failed to control feed %s.%u: %d",
				gcd->port->name, gcd->pin, ret);
			return ret;
		}

	}

	data->sequence.buffer = &data->sample;
	data->sequence.buffer_size = sizeof(data->sample);

	ret = adc_channel_setup_dt(&config->adc_channel);
	if (ret < 0) {
		LOG_INF("Could not setup channel (%d)\n", ret);
		return ret;
	}

	ret = adc_sequence_init_dt(&config->adc_channel, &data->sequence);
	if (ret < 0) {
		LOG_INF("Could not init sequence (%d)\n", ret);
		return ret;
	}

	return 0;
}

static const struct usbc_vbus_driver_api driver_api = {
	.measure = adc_vbus_measure,
	.check_level = adc_vbus_check_level,
	.discharge = adc_vbus_discharge,
	.enable = adc_vbus_enable
};

BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 0,
	     "No compatible USB-C VBUS Measurement instance found");

#define DRIVER_INIT(inst)								\
	static struct usbc_vbus_data drv_data_##inst;					\
	static const struct usbc_vbus_config drv_config_##inst = {			\
		.output_ohm = DT_INST_PROP(inst, output_ohms),				\
		.full_ohm = DT_INST_PROP_OR(inst, full_ohms, 0),			\
		.adc_channel = ADC_DT_SPEC_INST_GET(inst),				\
		.discharge_gpios = GPIO_DT_SPEC_INST_GET_OR(inst, discharge_gpios, {}), \
		.power_gpios = GPIO_DT_SPEC_INST_GET_OR(inst, power_gpios, {}),		\
	};										\
	DEVICE_DT_INST_DEFINE(inst,							\
			      &adc_vbus_init,						\
			      NULL,							\
			      &drv_data_##inst,						\
			      &drv_config_##inst,					\
			      POST_KERNEL,						\
			      CONFIG_USBC_INIT_PRIORITY,				\
			      &driver_api);

DT_INST_FOREACH_STATUS_OKAY(DRIVER_INIT)
