/*
 * 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 {
	const char *i2c_bus;
	uint16_t i2c_addr;
	uint8_t resolution;
};

struct dacx3608_data {
	const struct device *i2c;
	uint8_t configured;
};

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

	if (i2c_burst_read(data->i2c, cfg->i2c_addr,
			   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)
{
	struct dacx3608_data *data = dev->data;
	const struct dacx3608_config *cfg = dev->config;
	uint8_t buf[3] = {reg, val >> 8, val & 0xFF};

	return i2c_write(data->i2c, buf, sizeof(buf), cfg->i2c_addr);
}

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;

	data->i2c = device_get_binding(config->i2c_bus);
	if (!data->i2c) {
		LOG_ERR("Could not find I2C device");
		return -EINVAL;
	}

	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 = { \
		.i2c_bus = DT_BUS_LABEL(INST_DT_DACX3608(n, t)), \
		.i2c_addr = DT_REG_ADDR(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_DACX3608_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) \
	UTIL_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);
