/*
 * Copyright (c) 2020 Vestas Wind Systems A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_kinetis_temperature

#include <device.h>
#include <drivers/sensor.h>
#include <drivers/adc.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(temp_kinetis, CONFIG_SENSOR_LOG_LEVEL);

/*
 * Driver assumptions:
 * - ADC samples are in uint16_t format
 * - Both ADC channels (sensor and bandgap) are on the same ADC instance
 *
 * See NXP Application Note AN3031 for details on calculations.
 */

/* Two ADC samples required for each reading, sensor value and bandgap value */
#define TEMP_KINETIS_ADC_SAMPLES 2

struct temp_kinetis_config {
	const struct device *adc;
	uint8_t sensor_adc_ch;
	uint8_t bandgap_adc_ch;
	int bandgap_mv;
	int vtemp25_mv;
	int slope_cold_uv;
	int slope_hot_uv;
	struct adc_sequence adc_seq;
};

struct temp_kinetis_data {
	uint16_t buffer[TEMP_KINETIS_ADC_SAMPLES];
};

static int temp_kinetis_sample_fetch(const struct device *dev,
				     enum sensor_channel chan)
{
	const struct temp_kinetis_config *config = dev->config;
	struct temp_kinetis_data *data = dev->data;
#ifdef CONFIG_TEMP_KINETIS_FILTER
	uint16_t previous[TEMP_KINETIS_ADC_SAMPLES];
	int i;
#endif /* CONFIG_TEMP_KINETIS_FILTER */
	int err;

	/* Always read both sensor and bandgap voltage in one go */
	if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP &&
	    chan != SENSOR_CHAN_VOLTAGE) {
		return -ENOTSUP;
	}

#ifdef CONFIG_TEMP_KINETIS_FILTER
	memcpy(previous, data->buffer, sizeof(previous));
#endif /* CONFIG_TEMP_KINETIS_FILTER */

	err = adc_read(config->adc, &config->adc_seq);
	if (err) {
		LOG_ERR("failed to read ADC channels (err %d)", err);
		return err;
	}

	LOG_DBG("sensor = %d, bandgap = %d", data->buffer[0], data->buffer[1]);

#ifdef CONFIG_TEMP_KINETIS_FILTER
	if (previous[0] != 0 && previous[1] != 0) {
		for (i = 0; i < ARRAY_SIZE(previous); i++) {
			data->buffer[i] = (data->buffer[i] >> 1) +
				(previous[i] >> 1);
		}

		LOG_DBG("sensor = %d, bandgap = %d (filtered)", data->buffer[0],
			data->buffer[1]);
	}
#endif /* CONFIG_TEMP_KINETIS_FILTER */

	return 0;
}

static int temp_kinetis_channel_get(const struct device *dev,
				    enum sensor_channel chan,
				    struct sensor_value *val)
{
	const struct temp_kinetis_config *config = dev->config;
	struct temp_kinetis_data *data = dev->data;
	uint16_t adcr_vdd = BIT_MASK(config->adc_seq.resolution);
	uint16_t adcr_temp25;
	int32_t temp_cc;
	int32_t vdd_mv;
	int slope_uv;
	uint16_t adcr_100m;

	if (chan != SENSOR_CHAN_VOLTAGE && chan != SENSOR_CHAN_DIE_TEMP) {
		return -ENOTSUP;
	}

	/* VDD (or VREF, but AN3031 calls it VDD) in millivolts */
	vdd_mv = (adcr_vdd * config->bandgap_mv) / data->buffer[1];

	if (chan == SENSOR_CHAN_VOLTAGE) {
		val->val1 = vdd_mv / 1000;
		val->val2 = (vdd_mv % 1000) * 1000;
		return 0;
	}

	/* ADC result for temperature = 25 degrees Celsius */
	adcr_temp25 = (adcr_vdd * config->vtemp25_mv) / vdd_mv;

	/* Determine which slope to use */
	if (data->buffer[0] > adcr_temp25) {
		slope_uv = config->slope_cold_uv;
	} else {
		slope_uv = config->slope_hot_uv;
	}

	adcr_100m = (adcr_vdd * slope_uv) / (vdd_mv * 10);

	/* Temperature in centi degrees Celsius */
	temp_cc = 2500 -
		(((data->buffer[0] - adcr_temp25) * 10000) / adcr_100m);

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

	return 0;
}

static const struct sensor_driver_api temp_kinetis_driver_api = {
	.sample_fetch = temp_kinetis_sample_fetch,
	.channel_get = temp_kinetis_channel_get,
};

static int temp_kinetis_init(const struct device *dev)
{
	const struct temp_kinetis_config *config = dev->config;
	struct temp_kinetis_data *data = dev->data;
	int err;
	int i;
	const struct adc_channel_cfg ch_cfg[] = {
		{
			.gain = ADC_GAIN_1,
			.reference = ADC_REF_INTERNAL,
			.acquisition_time = ADC_ACQ_TIME_DEFAULT,
			.channel_id = config->sensor_adc_ch,
			.differential = 0,
		},
		{
			.gain = ADC_GAIN_1,
			.reference = ADC_REF_INTERNAL,
			.acquisition_time = ADC_ACQ_TIME_DEFAULT,
			.channel_id = config->bandgap_adc_ch,
			.differential = 0,
		},
	};

	memset(&data->buffer, 0, ARRAY_SIZE(data->buffer));

	if (!device_is_ready(config->adc)) {
		LOG_ERR("ADC device is not ready");
		return -EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(ch_cfg); i++) {
		err = adc_channel_setup(config->adc, &ch_cfg[i]);
		if (err) {
			LOG_ERR("failed to configure ADC channel (err %d)",
				err);
			return err;
		}
	}

	return 0;
}

BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1,
	     "unsupported temp instance");

#define TEMP_KINETIS_INIT(inst)						\
	BUILD_ASSERT(DT_INST_IO_CHANNELS_INPUT_BY_NAME(inst, sensor) <	\
		     DT_INST_IO_CHANNELS_INPUT_BY_NAME(inst, bandgap),	\
		     "This driver assumes sensor ADC channel to come before "\
		     "bandgap ADC channel");				\
									\
	static struct temp_kinetis_data temp_kinetis_data_0;		\
									\
	static const struct temp_kinetis_config temp_kinetis_config_0 = {\
		.adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(inst)),\
		.sensor_adc_ch =					\
			DT_INST_IO_CHANNELS_INPUT_BY_NAME(inst, sensor),\
		.bandgap_adc_ch =					\
			DT_INST_IO_CHANNELS_INPUT_BY_NAME(inst, bandgap),\
		.bandgap_mv = DT_INST_PROP(0, bandgap_voltage) / 1000,	\
		.vtemp25_mv = DT_INST_PROP(0, vtemp25) / 1000,		\
		.slope_cold_uv = DT_INST_PROP(0, sensor_slope_cold),	\
		.slope_hot_uv = DT_INST_PROP(0, sensor_slope_hot),	\
		.adc_seq = {						\
			.options = NULL,				\
			.channels =					\
		BIT(DT_INST_IO_CHANNELS_INPUT_BY_NAME(inst, sensor)) |	\
		BIT(DT_INST_IO_CHANNELS_INPUT_BY_NAME(inst, bandgap)),	\
			.buffer = &temp_kinetis_data_0.buffer,		\
			.buffer_size = sizeof(temp_kinetis_data_0.buffer),\
			.resolution = CONFIG_TEMP_KINETIS_RESOLUTION,	\
			.oversampling = CONFIG_TEMP_KINETIS_OVERSAMPLING,\
			.calibrate = false,				\
		},							\
	};								\
									\
	DEVICE_DT_INST_DEFINE(inst, temp_kinetis_init,			\
			    NULL,					\
			    &temp_kinetis_data_0,			\
			    &temp_kinetis_config_0, POST_KERNEL,	\
			    CONFIG_SENSOR_INIT_PRIORITY,		\
			    &temp_kinetis_driver_api);

DT_INST_FOREACH_STATUS_OKAY(TEMP_KINETIS_INIT)
