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

#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/dac.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/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_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) \
	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);
