/*
 * Copyright (c) 2020 Matija Tudan
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <kernel.h>
#include <drivers/i2c.h>
#include <drivers/dac.h>
#include <sys/util.h>
#include <sys/byteorder.h>
#include <sys/__assert.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(dac_dacx3608, CONFIG_DAC_LOG_LEVEL);

/* Register addresses */
#define DACX3608_REG_DEVICE_CONFIG  0x01U
#define DACX3608_REG_STATUS_TRIGGER 0x02U
#define DACX3608_REG_BRDCAST        0x03U
#define DACX3608_REG_DACA_DATA      0x08U

#define DAC43608_DEVICE_ID      0x500	/* STATUS_TRIGGER[DEVICE_ID] */
#define DAC53608_DEVICE_ID      0x300	/* STATUS_TRIGGER[DEVICE_ID] */
#define DACX3608_SW_RST         0x0A	/* STATUS_TRIGGER[SW_RST] */
#define DACX3608_POR_DELAY      5
#define DACX3608_MAX_CHANNEL    8

struct dacx3608_config {
	struct i2c_dt_spec bus;
	uint8_t resolution;
};

struct dacx3608_data {
	uint8_t configured;
};

static int dacx3608_reg_read(const struct device *dev, uint8_t reg,
			      uint16_t *val)
{
	const struct dacx3608_config *cfg = dev->config;

	if (i2c_burst_read_dt(&cfg->bus, reg, (uint8_t *) val, 2) < 0) {
		LOG_ERR("I2C read failed");
		return -EIO;
	}

	*val = sys_be16_to_cpu(*val);

	return 0;
}

static int dacx3608_reg_write(const struct device *dev, uint8_t reg,
			       uint16_t val)
{
	const struct dacx3608_config *cfg = dev->config;
	uint8_t buf[3] = {reg, val >> 8, val & 0xFF};

	return i2c_write_dt(&cfg->bus, buf, sizeof(buf));
}

int dacx3608_reg_update(const struct device *dev, uint8_t reg,
			 uint16_t mask, bool setting)
{
	uint16_t regval;
	int ret;

	ret = dacx3608_reg_read(dev, reg, &regval);
	if (ret) {
		return -EIO;
	}

	if (setting) {
		regval |= mask;
	} else {
		regval &= ~mask;
	}

	ret = dacx3608_reg_write(dev, reg, regval);
	if (ret) {
		return ret;
	}

	return 0;
}

static int dacx3608_channel_setup(const struct device *dev,
				   const struct dac_channel_cfg *channel_cfg)
{
	const struct dacx3608_config *config = dev->config;
	struct dacx3608_data *data = dev->data;
	bool setting = false;
	int ret;

	if (channel_cfg->channel_id > DACX3608_MAX_CHANNEL - 1) {
		LOG_ERR("Unsupported channel %d", channel_cfg->channel_id);
		return -ENOTSUP;
	}

	if (channel_cfg->resolution != config->resolution) {
		LOG_ERR("Unsupported resolution %d", channel_cfg->resolution);
		return -ENOTSUP;
	}

	if (data->configured & BIT(channel_cfg->channel_id)) {
		LOG_DBG("Channel %d already configured", channel_cfg->channel_id);
		return 0;
	}

	/* Clear PDNn bit */
	ret = dacx3608_reg_update(dev, DACX3608_REG_DEVICE_CONFIG,
				BIT(channel_cfg->channel_id), setting);
	if (ret) {
		LOG_ERR("Unable to update DEVICE_CONFIG register");
		return -EIO;
	}

	data->configured |= BIT(channel_cfg->channel_id);

	LOG_DBG("Channel %d initialized", channel_cfg->channel_id);

	return 0;
}

static int dacx3608_write_value(const struct device *dev, uint8_t channel,
				uint32_t value)
{
	const struct dacx3608_config *config = dev->config;
	struct dacx3608_data *data = dev->data;
	uint16_t regval;
	int ret;

	if (channel > DACX3608_MAX_CHANNEL - 1) {
		LOG_ERR("Unsupported channel %d", channel);
		return -ENOTSUP;
	}

	if (!(data->configured & BIT(channel))) {
		LOG_ERR("Channel %d not initialized", channel);
		return -EINVAL;
	}

	if (value >= (1 << (config->resolution))) {
		LOG_ERR("Value %d out of range", value);
		return -EINVAL;
	}

	/*
	 * Shift passed value two times left because first two bits are Don't Care
	 *
	 * DACn_DATA register format:
	 *
	 * | 15 14 13 12 |      11 10 9 8 7 6 5 4 3 2      |    1 0     |
	 * |-------------|---------------------------------|------------|
	 * | Don't Care  |  DAC53608[9:0] / DAC43608[7:0]  | Don't Care |
	 */
	regval = value << 2;
	regval &= 0xFFFF;

	ret = dacx3608_reg_write(dev, DACX3608_REG_DACA_DATA + channel, regval);
	if (ret) {
		LOG_ERR("Unable to set value %d on channel %d", value, channel);
		return -EIO;
	}

	return 0;
}

static int dacx3608_soft_reset(const struct device *dev)
{
	uint16_t regval = DACX3608_SW_RST;
	int ret;

	ret = dacx3608_reg_write(dev, DACX3608_REG_STATUS_TRIGGER, regval);
	if (ret) {
		return -EIO;
	}
	k_msleep(DACX3608_POR_DELAY);

	return 0;
}

static int dacx3608_device_id_check(const struct device *dev)
{
	uint16_t dev_id;
	int ret;

	ret = dacx3608_reg_read(dev, DACX3608_REG_STATUS_TRIGGER, &dev_id);
	if (ret) {
		LOG_ERR("Unable to read device ID");
		return -EIO;
	}

	switch (dev_id) {
	case DAC43608_DEVICE_ID:
	case DAC53608_DEVICE_ID:
		LOG_DBG("Device ID %#4x", dev_id);
		break;
	default:
		LOG_ERR("Unknown Device ID %#4x", dev_id);
		return -EIO;
	}

	return 0;
}

static int dacx3608_init(const struct device *dev)
{
	const struct dacx3608_config *config = dev->config;
	struct dacx3608_data *data = dev->data;
	int ret;

	if (!device_is_ready(config->bus.bus)) {
		LOG_ERR("I2C device not ready");
		return -ENODEV;
	}

	ret = dacx3608_soft_reset(dev);
	if (ret) {
		LOG_ERR("Soft-reset failed");
		return ret;
	}

	ret = dacx3608_device_id_check(dev);
	if (ret) {
		return ret;
	}

	data->configured = 0;

	LOG_DBG("Init complete");

	return 0;
}

static const struct dac_driver_api dacx3608_driver_api = {
	.channel_setup = dacx3608_channel_setup,
	.write_value = dacx3608_write_value,
};

#define INST_DT_DACX3608(inst, t) DT_INST(inst, ti_dac##t)

#define DACX3608_DEVICE(t, n, res) \
	static struct dacx3608_data dac##t##_data_##n; \
	static const struct dacx3608_config dac##t##_config_##n = { \
		.bus = I2C_DT_SPEC_GET(INST_DT_DACX3608(n, t)), \
		.resolution = res, \
	}; \
	DEVICE_DT_DEFINE(INST_DT_DACX3608(n, t), \
				&dacx3608_init, NULL, \
				&dac##t##_data_##n, \
				&dac##t##_config_##n, POST_KERNEL, \
				CONFIG_DAC_INIT_PRIORITY, \
				&dacx3608_driver_api)

/*
 * DAC43608: 8-bit
 */
#define DAC43608_DEVICE(n) DACX3608_DEVICE(43608, n, 8)

/*
 * DAC53608: 10-bit
 */
#define DAC53608_DEVICE(n) DACX3608_DEVICE(53608, n, 10)

#define CALL_WITH_ARG(arg, expr) expr(arg)

#define INST_DT_DACX3608_FOREACH(t, inst_expr) \
	LISTIFY(DT_NUM_INST_STATUS_OKAY(ti_dac##t), \
		     CALL_WITH_ARG, (), inst_expr)

INST_DT_DACX3608_FOREACH(43608, DAC43608_DEVICE);
INST_DT_DACX3608_FOREACH(53608, DAC53608_DEVICE);
