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

#define DT_DRV_COMPAT ti_ina237

#include <logging/log.h>
#include <drivers/sensor.h>
#include "ina237.h"
#include "ina23x_common.h"

LOG_MODULE_REGISTER(INA237, CONFIG_SENSOR_LOG_LEVEL);

/**
 * @brief Internal fixed value of INA237 that is used to ensure
 *	  scaling is properly maintained.
 *
 */
#define INA237_INTERNAL_FIXED_SCALING_VALUE 8192

/**
 * @brief The LSB value for the bus voltage register.
 *
 */
#define INA237_BUS_VOLTAGE_LSB 3125

/**
 * @brief The LSB value for the power register.
 *
 */
#define INA237_POWER_VALUE_LSB 2

/**
 * @brief sensor value get
 *
 * @retval 0 for success
 * @retval -ENOTSUP for unsupported channels
 */
static int ina237_channel_get(const struct device *dev,
			      enum sensor_channel chan,
			      struct sensor_value *val)
{
	struct ina237_data *data = dev->data;
	const struct ina237_config *config = dev->config;

	switch (chan) {
	case SENSOR_CHAN_VOLTAGE:
		if (config->current_lsb == INA23X_CURRENT_LSB_1MA) {
			uint32_t bus_mv = ((data->bus_voltage *
					 INA237_BUS_VOLTAGE_LSB) / 1000);

			val->val1 = bus_mv / 1000U;
			val->val2 = (bus_mv % 1000) * 1000;
		} else {
			val->val1 = data->bus_voltage;
			val->val2 = 0;
		}
		break;

	case SENSOR_CHAN_CURRENT:
		if (config->current_lsb == INA23X_CURRENT_LSB_1MA) {
			/**
			 * If current is negative, convert it to a
			 * magnitude and return the negative of that
			 * magnitude.
			 */
			if (data->current & INA23X_CURRENT_SIGN_BIT) {
				uint16_t current_mag = (~data->current + 1);

				val->val1 = -(current_mag / 10000U);
				val->val2 = -(current_mag % 10000) * 100;

			} else {
				val->val1 = data->current / 10000U;
				val->val2 = (data->current % 10000) * 100;
			}
		} else {
			val->val1 = data->current;
			val->val2 = 0;
		}
		break;

	case SENSOR_CHAN_POWER:
		if (config->current_lsb == INA23X_CURRENT_LSB_1MA) {
			uint32_t power_mw = ((data->power *
					 config->current_lsb *
					 INA237_POWER_VALUE_LSB) / 10);

			val->val1 = power_mw / 10000U;
			val->val2 = (power_mw % 10000) * 100;
		} else {
			val->val1 = data->power;
			val->val2 = 0;
		}
		break;

	default:
		return -ENOTSUP;
	}

	return 0;
}

/**
 * @brief sensor sample fetch
 *
 * @retval 0 for success
 * @retval -ENOTSUP for unsupported channels
 */
static int ina237_sample_fetch(const struct device *dev,
			       enum sensor_channel chan)
{
	struct ina237_data *data = dev->data;
	const struct ina237_config *config = dev->config;
	int ret;

	if (chan != SENSOR_CHAN_ALL &&
	    chan != SENSOR_CHAN_VOLTAGE &&
	    chan != SENSOR_CHAN_CURRENT &&
	    chan != SENSOR_CHAN_POWER) {
		return -ENOTSUP;
	}

	if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_VOLTAGE)) {
		ret = ina23x_reg_read_16(&config->bus, INA237_REG_BUS_VOLT, &data->bus_voltage);
		if (ret < 0) {
			LOG_ERR("Failed to read bus voltage");
			return ret;
		}
	}

	if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_CURRENT)) {
		ret = ina23x_reg_read_16(&config->bus, INA237_REG_CURRENT, &data->current);
		if (ret < 0) {
			LOG_ERR("Failed to read current");
			return ret;
		}
	}

	if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_POWER)) {
		ret = ina23x_reg_read_24(&config->bus, INA237_REG_POWER, &data->power);
		if (ret < 0) {
			LOG_ERR("Failed to read power");
			return ret;
		}
	}

	return 0;
}

/**
 * @brief sensor attribute set
 *
 * @retval 0 for success
 * @retval -ENOTSUP for unsupported channels
 * @retval -EIO for i2c write failure
 */
static int ina237_attr_set(const struct device *dev, enum sensor_channel chan,
			   enum sensor_attribute attr,
			   const struct sensor_value *val)
{
	const struct ina237_config *config = dev->config;
	uint16_t data = val->val1;

	switch (attr) {
	case SENSOR_ATTR_CONFIGURATION:
		return ina23x_reg_write(&config->bus, INA237_REG_CONFIG, data);
	case SENSOR_ATTR_CALIBRATION:
		return ina23x_reg_write(&config->bus, INA237_REG_CALIB, data);
	default:
		LOG_ERR("INA237 attribute not supported.");
		return -ENOTSUP;
	}
}

/**
 * @brief sensor attribute get
 *
 * @retval 0 for success
 * @retval -ENOTSUP for unsupported channels
 * @retval -EIO for i2c read failure
 */
static int ina237_attr_get(const struct device *dev, enum sensor_channel chan,
			   enum sensor_attribute attr,
			   struct sensor_value *val)
{
	const struct ina237_config *config = dev->config;
	uint16_t data;
	int ret;

	switch (attr) {
	case SENSOR_ATTR_CONFIGURATION:
		ret = ina23x_reg_read_16(&config->bus, INA237_REG_CONFIG, &data);
		if (ret < 0) {
			return ret;
		}
		break;
	case SENSOR_ATTR_CALIBRATION:
		ret = ina23x_reg_read_16(&config->bus, INA237_REG_CALIB, &data);
		if (ret < 0) {
			return ret;
		}
		break;
	default:
		LOG_ERR("INA237 attribute not supported.");
		return -ENOTSUP;
	}

	val->val1 = data;
	val->val2 = 0;

	return 0;
}

/**
 * @brief sensor calibrate
 *
 * @retval 0 for success
 * @retval -EIO for i2c write failure
 */
static int ina237_calibrate(const struct device *dev)
{
	const struct ina237_config *config = dev->config;
	uint16_t val;
	int ret;

	val = ((INA237_INTERNAL_FIXED_SCALING_VALUE * config->current_lsb * config->rshunt) / 100);

	ret = ina23x_reg_write(&config->bus, INA237_REG_CALIB, val);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

/**
 * @brief Initialize the INA237
 *
 * @retval 0 for success
 * @retval -EINVAL on error
 */
static int ina237_init(const struct device *dev)
{
	const struct ina237_config *config = dev->config;
	uint16_t id;
	int ret;

	if (!device_is_ready(config->bus.bus)) {
		LOG_ERR("I2C bus %s is not ready", config->bus.bus->name);
		return -ENODEV;
	}

	ret = ina23x_reg_read_16(&config->bus, INA237_REG_MANUFACTURER_ID, &id);
	if (ret < 0) {
		LOG_ERR("Failed to read manufacturer register!");
		return ret;
	}

	if (id != INA237_MANUFACTURER_ID) {
		LOG_ERR("Manufacturer ID doesn't match!");
		return -ENODEV;
	}

	ret = ina23x_reg_write(&config->bus, INA237_REG_ADC_CONFIG, config->adc_config);
	if (ret < 0) {
		LOG_ERR("Failed to write ADC configuration register!");
		return ret;
	}

	ret = ina23x_reg_write(&config->bus, INA237_REG_CONFIG, config->config);
	if (ret < 0) {
		LOG_ERR("Failed to write configuration register!");
		return ret;
	}

	ret = ina237_calibrate(dev);
	if (ret < 0) {
		LOG_ERR("Failed to write calibration register!");
		return ret;
	}

	return 0;
}

static const struct sensor_driver_api ina237_driver_api = {
	.attr_set = ina237_attr_set,
	.attr_get = ina237_attr_get,
	.sample_fetch = ina237_sample_fetch,
	.channel_get = ina237_channel_get,
};

BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 0,
	     "No compatible ina237 instances found");

#define INA237_DRIVER_INIT(inst)				    \
	static struct ina237_data ina237_data_##inst;		    \
	static const struct ina237_config ina237_config_##inst = {  \
		.bus = I2C_DT_SPEC_INST_GET(inst),		    \
		.config = DT_INST_PROP(inst, config),		    \
		.adc_config = DT_INST_PROP(inst, adc_config),	    \
		.current_lsb = DT_INST_PROP(inst, current_lsb),	    \
		.rshunt = DT_INST_PROP(inst, rshunt),		    \
	};							    \
	DEVICE_DT_INST_DEFINE(inst,				    \
			      &ina237_init,			    \
			      NULL,				    \
			      &ina237_data_##inst,		    \
			      &ina237_config_##inst,		    \
			      POST_KERNEL,			    \
			      CONFIG_SENSOR_INIT_PRIORITY,	    \
			      &ina237_driver_api);

DT_INST_FOREACH_STATUS_OKAY(INA237_DRIVER_INIT)
