/*
 * 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, device_pm_control_nop, \
				&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);
