/*
 * Copyright 2021 Grinn
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_mcp4728

#include <zephyr/zephyr.h>
#include <zephyr/drivers/dac.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(dac_mcp4728, CONFIG_DAC_LOG_LEVEL);

#define MCP4728_MAX_CHANNEL			4U
#define MCP4728_RESOLUTION			0xC
#define MCP4728_DAC_MAX_VAL			((1U << MCP4728_RESOLUTION) - 1U)
#define MCP4728_MULTI_WRITE_CMD_VAL		8U
#define MCP4728_MULTI_WRITE_CMD_POS		3U
#define MCP4728_MULTI_WRITE_CHANNEL_POS		1U
#define MCP4728_MULTI_WRITE_REFERENCE_POS	7U
#define MCP4728_MULTI_WRITE_POWER_DOWN_POS	5U
#define MCP4728_MULTI_WRITE_POWER_DOWN_MASK	0X3
#define MCP4728_MULTI_WRITE_GAIN_POS		4U
#define MCP4728_MULTI_WRITE_DAC_UPPER_VAL_POS	8U
#define MCP4728_MULTI_WRITE_DAC_UPPER_VAL_MASK	0xF
#define MCP4728_MULTI_WRITE_DAC_LOWER_VAL_MASK	0xFF

struct mcp4728_config {
	struct i2c_dt_spec bus;
	uint8_t power_down[MCP4728_MAX_CHANNEL];
	uint8_t voltage_reference[MCP4728_MAX_CHANNEL];
	uint8_t gain[MCP4728_MAX_CHANNEL];
};

static int mcp4728_channel_setup(const struct device *dev,
				const struct dac_channel_cfg *channel_cfg)
{
	if (channel_cfg->channel_id >= MCP4728_MAX_CHANNEL) {
		return -ENOTSUP;
	}

	if (channel_cfg->resolution != MCP4728_RESOLUTION) {
		return -ENOTSUP;
	}

	return 0;
}

static int mcp4728_write_value(const struct device *dev, uint8_t channel, uint32_t value)
{
	const struct mcp4728_config *config = (struct mcp4728_config *)dev->config;
	uint8_t tx_data[3];
	int ret;

	if (channel >= MCP4728_MAX_CHANNEL) {
		return -ENOTSUP;
	}

	if (value > MCP4728_DAC_MAX_VAL) {
		return -ENOTSUP;
	}

	/* Multi-Write Command: Write Multiple DAC Input Registers. */
	tx_data[0] = (MCP4728_MULTI_WRITE_CMD_VAL << MCP4728_MULTI_WRITE_CMD_POS) |
			(channel << MCP4728_MULTI_WRITE_CHANNEL_POS);
	tx_data[1] = (config->voltage_reference[channel] << MCP4728_MULTI_WRITE_REFERENCE_POS) |
			((config->power_down[channel] & MCP4728_MULTI_WRITE_POWER_DOWN_MASK)
			<< MCP4728_MULTI_WRITE_POWER_DOWN_POS) |
			((config->gain[channel] << MCP4728_MULTI_WRITE_GAIN_POS)) |
			((value >> MCP4728_MULTI_WRITE_DAC_UPPER_VAL_POS) &
			MCP4728_MULTI_WRITE_DAC_UPPER_VAL_MASK);
	tx_data[2] = (value & MCP4728_MULTI_WRITE_DAC_LOWER_VAL_MASK);
	ret = i2c_write_dt(&config->bus, tx_data, sizeof(tx_data));

	return ret;
}

static int dac_mcp4728_init(const struct device *dev)
{
	const struct mcp4728_config *config = dev->config;

	if (!device_is_ready(config->bus.bus)) {
		LOG_ERR("%s device not found", config->bus.bus->name);
		return -ENODEV;
	}
	return 0;
}

static const struct dac_driver_api mcp4728_driver_api = {
	.channel_setup = mcp4728_channel_setup,
	.write_value = mcp4728_write_value,
};

#define INST_DT_MCP4728(index)							\
	static const struct mcp4728_config mcp4728_config_##index = {		\
		.bus = I2C_DT_SPEC_INST_GET(index),				\
		.power_down = DT_INST_PROP(index, power_down_mode),		\
		.voltage_reference = DT_INST_PROP(index, voltage_reference),	\
		.gain = DT_INST_PROP_OR(index, gain, {0}),			\
	};									\
										\
	DEVICE_DT_INST_DEFINE(index, dac_mcp4728_init, NULL, NULL,		\
				&mcp4728_config_##index,			\
				POST_KERNEL,					\
				CONFIG_DAC_INIT_PRIORITY,			\
				&mcp4728_driver_api);

DT_INST_FOREACH_STATUS_OKAY(INST_DT_MCP4728);
