/* adc-ti-adc108s102.c - TI's ADC 108s102 driver implementation */

/*
 * Copyright (c) 2015 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>

#include <kernel.h>
#include <misc/util.h>
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_ADC_LEVEL
#include <logging/sys_log.h>
#include <string.h>
#include <init.h>

#include "adc_ti_adc108s102.h"

static inline int _ti_adc108s102_sampling(struct device *dev)
{
	struct ti_adc108s102_data *adc = dev->driver_data;

	SYS_LOG_DBG("Sampling!");

	/* SPI deals with u8_t buffers so multiplying by 2 the length */
	return spi_transceive(adc->spi, adc->cmd_buffer,
			      adc->cmd_buf_len * 2,
			      adc->sampling_buffer,
			      adc->sampling_buf_len * 2);
}

static inline void _ti_adc108s102_handle_result(struct device *dev)
{
	struct ti_adc108s102_data *adc = dev->driver_data;
	struct adc_seq_table *seq_table = adc->seq_table;
	struct ti_adc108s102_chan *chan;
	struct adc_seq_entry *entry;
	u32_t s_i, i;

	SYS_LOG_DBG("_ti_adc108s102_handle_result()");

	for (i = 0, s_i = 1; i < seq_table->num_entries; i++, s_i++) {
		entry = &seq_table->entries[i];
		chan = &adc->chans[entry->channel_id];

		if (entry->buffer_length - chan->buf_idx == 0) {
			continue;
		}

		*((u16_t *)(entry->buffer+chan->buf_idx)) =
				ADC108S102_RESULT(adc->sampling_buffer[s_i]);

		chan->buf_idx += 2;
	}
}

static inline s32_t _ti_adc108s102_prepare(struct device *dev)
{
	struct ti_adc108s102_data *adc = dev->driver_data;
	struct adc_seq_table *seq_table = adc->seq_table;
	struct ti_adc108s102_chan *chan;
	s32_t sampling_delay = 0;
	u32_t i;

	adc->cmd_buf_len = 0;
	adc->sampling_buf_len = 1; /* Counting the dummy byte */

	for (i = 0; i < seq_table->num_entries; i++) {
		struct adc_seq_entry *entry = &seq_table->entries[i];

		/* No more space in the buffer? */
		chan = &adc->chans[entry->channel_id];
		if (entry->buffer_length - chan->buf_idx == 0) {
			continue;
		}

		SYS_LOG_DBG("Requesting channel %d", entry->channel_id);
		adc->cmd_buffer[adc->cmd_buf_len] =
				ADC108S102_CHANNEL_CMD(entry->channel_id);

		adc->cmd_buf_len++;
		adc->sampling_buf_len++;

		sampling_delay = entry->sampling_delay;
	}

	if (adc->cmd_buf_len == 0) {
		return ADC108S102_DONE;
	}

	/* dummy cmd byte */
	adc->cmd_buffer[adc->cmd_buf_len] = 0;
	adc->cmd_buf_len++;

	SYS_LOG_DBG("ADC108S102 is prepared...");

	return sampling_delay;
}

static void ti_adc108s102_enable(struct device *dev)
{
	ARG_UNUSED(dev);

	/*
	 * There is nothing to be done. If there is no sampling going on,
	 * the chip will put itself on power-saving mode (that is because
	 * SPI will release CS)
	 */
}

static void ti_adc108s102_disable(struct device *dev)
{
	ARG_UNUSED(dev);

	/* Same issue as with ti_adc108s102_enable() */
}

static inline int _verify_entries(struct adc_seq_table *seq_table)
{
	struct adc_seq_entry *entry;
	u32_t chans_set = 0;
	int i;

	for (i = 0; i < seq_table->num_entries; i++) {
		entry = &seq_table->entries[i];

		if (entry->sampling_delay <= 0 ||
		    entry->channel_id > ADC108S102_CHANNELS) {
			return 0;
		}

		if (!entry->buffer_length) {
			continue;
		}

		chans_set++;
	}

	return chans_set;
}

static int ti_adc108s102_read(struct device *dev,
					struct adc_seq_table *seq_table)
{
	const struct ti_adc108s102_config *config = dev->config->config_info;
	struct ti_adc108s102_data *adc = dev->driver_data;
	struct spi_config spi_conf;
	int ret = 0;
	s32_t delay;

	spi_conf.config = config->spi_config_flags;
	spi_conf.max_sys_freq = config->spi_freq;

	if (spi_configure(adc->spi, &spi_conf)) {
		return -EIO;
	}

	if (spi_slave_select(adc->spi, config->spi_slave)) {
		return -EIO;
	}

	/* Resetting all internal channel data */
	memset(adc->chans, 0, ADC108S102_CHANNELS_SIZE);

	if (_verify_entries(seq_table) == 0) {
		return -EINVAL;
	}

	adc->seq_table = seq_table;

	/* Sampling */
	while (1) {
		delay = _ti_adc108s102_prepare(dev);
		if (delay == ADC108S102_DONE) {
			break;
		}

		/* convert to milliseconds */
		delay = (s32_t)((MSEC_PER_SEC * (u64_t)delay) /
			sys_clock_ticks_per_sec);

		k_sleep(delay);

		ret = _ti_adc108s102_sampling(dev);
		if (ret != 0) {
			break;
		}

		_ti_adc108s102_handle_result(dev);
	}

	return ret;
}

static const struct adc_driver_api ti_adc108s102_api = {
	.enable = ti_adc108s102_enable,
	.disable = ti_adc108s102_disable,
	.read = ti_adc108s102_read,
};

static int ti_adc108s102_init(struct device *dev)
{
	const struct ti_adc108s102_config *config = dev->config->config_info;
	struct ti_adc108s102_data *adc = dev->driver_data;

	adc->spi = device_get_binding((char *)config->spi_port);
	if (!adc->spi) {
		return -EPERM;
	}

	SYS_LOG_DBG("ADC108s102 initialized");

	dev->driver_api = &ti_adc108s102_api;

	return 0;
}

#ifdef CONFIG_ADC_TI_ADC108S102

static struct ti_adc108s102_data adc108s102_data;

static const struct ti_adc108s102_config adc108s102_config = {
	.spi_port = CONFIG_ADC_TI_ADC108S102_SPI_PORT_NAME,
	.spi_config_flags = CONFIG_ADC_TI_ADC108S102_SPI_CONFIGURATION,
	.spi_freq = CONFIG_ADC_TI_ADC108S102_SPI_MAX_FREQ,
	.spi_slave = CONFIG_ADC_TI_ADC108S102_SPI_SLAVE,
};

DEVICE_INIT(adc108s102, CONFIG_ADC_0_NAME,
			ti_adc108s102_init,
			&adc108s102_data, &adc108s102_config,
			POST_KERNEL, CONFIG_ADC_INIT_PRIORITY);

#endif /* CONFIG_ADC_TI_ADC108S102 */
