/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_tlv320dac

#include <errno.h>

#include <sys/util.h>

#include <device.h>
#include <drivers/i2c.h>
#include <drivers/gpio.h>

#include <audio/codec.h>
#include "tlv320dac310x.h"

#define LOG_LEVEL CONFIG_AUDIO_CODEC_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(tlv320dac310x);

#define CODEC_OUTPUT_VOLUME_MAX		0
#define CODEC_OUTPUT_VOLUME_MIN		(-78 * 2)

struct codec_driver_config {
	const struct device *i2c_device;
	const char	*i2c_dev_name;
	uint8_t		i2c_address;
	const struct device *gpio_device;
	const char	*gpio_dev_name;
	uint32_t		gpio_pin;
	int		gpio_flags;
};

struct codec_driver_data {
	struct reg_addr	reg_addr_cache;
};

static struct codec_driver_config codec_device_config = {
	.i2c_device	= NULL,
	.i2c_dev_name	= DT_INST_BUS_LABEL(0),
	.i2c_address	= DT_INST_REG_ADDR(0),
	.gpio_device	= NULL,
	.gpio_dev_name	= DT_INST_GPIO_LABEL(0, reset_gpios),
	.gpio_pin	= DT_INST_GPIO_PIN(0, reset_gpios),
	.gpio_flags	= DT_INST_GPIO_FLAGS(0, reset_gpios),
};

static struct codec_driver_data codec_device_data;

#define DEV_CFG(dev) \
	((struct codec_driver_config *const)(dev)->config)
#define DEV_DATA(dev) \
	((struct codec_driver_data *const)(dev)->data)

static void codec_write_reg(const struct device *dev, struct reg_addr reg,
			    uint8_t val);
static void codec_read_reg(const struct device *dev, struct reg_addr reg,
			   uint8_t *val);
static void codec_soft_reset(const struct device *dev);
static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg);
static int codec_configure_clocks(const struct device *dev,
				  struct audio_codec_cfg *cfg);
static int codec_configure_filters(const struct device *dev,
				   audio_dai_cfg_t *cfg);
static enum osr_multiple codec_get_osr_multiple(audio_dai_cfg_t *cfg);
static void codec_configure_output(const struct device *dev);
static int codec_set_output_volume(const struct device *dev, int vol);

#if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
static void codec_read_all_regs(const struct device *dev);
#define CODEC_DUMP_REGS(dev)	codec_read_all_regs((dev))
#else
#define CODEC_DUMP_REGS(dev)
#endif

static int codec_initialize(const struct device *dev)
{
	struct codec_driver_config *const dev_cfg = DEV_CFG(dev);

	/* bind I2C */
	dev_cfg->i2c_device = device_get_binding(dev_cfg->i2c_dev_name);

	if (dev_cfg->i2c_device == NULL) {
		LOG_ERR("I2C device binding error");
		return -ENXIO;
	}

	/* bind GPIO */
	dev_cfg->gpio_device = device_get_binding(dev_cfg->gpio_dev_name);

	if (dev_cfg->gpio_device == NULL) {
		LOG_ERR("GPIO device binding error");
		return -ENXIO;
	}

	return 0;
}

static int codec_configure(const struct device *dev,
			   struct audio_codec_cfg *cfg)
{
	struct codec_driver_config *const dev_cfg = DEV_CFG(dev);
	int ret;

	if (cfg->dai_type != AUDIO_DAI_TYPE_I2S) {
		LOG_ERR("dai_type must be AUDIO_DAI_TYPE_I2S");
		return -EINVAL;
	}

	/* Configure reset GPIO, and set the line to inactive, which will also
	 * de-assert the reset line and thus enable the codec.
	 */
	gpio_pin_configure(dev_cfg->gpio_device, dev_cfg->gpio_pin,
			   dev_cfg->gpio_flags | GPIO_OUTPUT_INACTIVE);

	codec_soft_reset(dev);

	ret = codec_configure_clocks(dev, cfg);
	if (ret == 0) {
		ret = codec_configure_dai(dev, &cfg->dai_cfg);
	}
	if (ret == 0) {
		ret = codec_configure_filters(dev, &cfg->dai_cfg);
	}
	codec_configure_output(dev);

	return ret;
}

static void codec_start_output(const struct device *dev)
{
	/* powerup DAC channels */
	codec_write_reg(dev, DATA_PATH_SETUP_ADDR, DAC_LR_POWERUP_DEFAULT);

	/* unmute DAC channels */
	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_UNMUTE_DEFAULT);

	CODEC_DUMP_REGS(dev);
}

static void codec_stop_output(const struct device *dev)
{
	/* mute DAC channels */
	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_MUTE_DEFAULT);

	/* powerdown DAC channels */
	codec_write_reg(dev, DATA_PATH_SETUP_ADDR, DAC_LR_POWERDN_DEFAULT);
}

static void codec_mute_output(const struct device *dev)
{
	/* mute DAC channels */
	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_MUTE_DEFAULT);
}

static void codec_unmute_output(const struct device *dev)
{
	/* unmute DAC channels */
	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_UNMUTE_DEFAULT);
}

static int codec_set_property(const struct device *dev,
			      audio_property_t property,
			      audio_channel_t channel,
			      audio_property_value_t val)
{
	/* individual channel control not currently supported */
	if (channel != AUDIO_CHANNEL_ALL) {
		LOG_ERR("channel %u invalid. must be AUDIO_CHANNEL_ALL",
			channel);
		return -EINVAL;
	}

	switch (property) {
	case AUDIO_PROPERTY_OUTPUT_VOLUME:
		return codec_set_output_volume(dev, val.vol);

	case AUDIO_PROPERTY_OUTPUT_MUTE:
		if (val.mute) {
			codec_mute_output(dev);
		} else {
			codec_unmute_output(dev);
		}
		return 0;

	default:
		break;
	}

	return -EINVAL;
}

static int codec_apply_properties(const struct device *dev)
{
	/* nothing to do because there is nothing cached */
	return 0;
}

static void codec_write_reg(const struct device *dev, struct reg_addr reg,
			    uint8_t val)
{
	struct codec_driver_data *const dev_data = DEV_DATA(dev);
	struct codec_driver_config *const dev_cfg = DEV_CFG(dev);

	/* set page if different */
	if (dev_data->reg_addr_cache.page != reg.page) {
		i2c_reg_write_byte(dev_cfg->i2c_device,
				dev_cfg->i2c_address, 0, reg.page);
		dev_data->reg_addr_cache.page = reg.page;
	}

	i2c_reg_write_byte(dev_cfg->i2c_device,
			dev_cfg->i2c_address, reg.reg_addr, val);
	LOG_DBG("WR PG:%u REG:%02u VAL:0x%02x",
			reg.page, reg.reg_addr, val);
}

static void codec_read_reg(const struct device *dev, struct reg_addr reg,
			   uint8_t *val)
{
	struct codec_driver_data *const dev_data = DEV_DATA(dev);
	struct codec_driver_config *const dev_cfg = DEV_CFG(dev);

	/* set page if different */
	if (dev_data->reg_addr_cache.page != reg.page) {
		i2c_reg_write_byte(dev_cfg->i2c_device,
				dev_cfg->i2c_address, 0, reg.page);
		dev_data->reg_addr_cache.page = reg.page;
	}

	i2c_reg_read_byte(dev_cfg->i2c_device,
			dev_cfg->i2c_address, reg.reg_addr, val);
	LOG_DBG("RD PG:%u REG:%02u VAL:0x%02x",
			reg.page, reg.reg_addr, *val);
}

static void codec_soft_reset(const struct device *dev)
{
	/* soft reset the DAC */
	codec_write_reg(dev, SOFT_RESET_ADDR, SOFT_RESET_ASSERT);
}

static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg)
{
	uint8_t val;

	/* configure I2S interface */
	val = IF_CTRL_IFTYPE(IF_CTRL_IFTYPE_I2S);
	if (cfg->i2s.options & I2S_OPT_BIT_CLK_MASTER) {
		val |= IF_CTRL_BCLK_OUT;
	}

	if (cfg->i2s.options & I2S_OPT_FRAME_CLK_MASTER) {
		val |= IF_CTRL_WCLK_OUT;
	}

	switch (cfg->i2s.word_size) {
	case AUDIO_PCM_WIDTH_16_BITS:
		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_16);
		break;
	case AUDIO_PCM_WIDTH_20_BITS:
		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_20);
		break;
	case AUDIO_PCM_WIDTH_24_BITS:
		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_24);
		break;
	case AUDIO_PCM_WIDTH_32_BITS:
		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_32);
		break;
	default:
		LOG_ERR("Unsupported PCM sample bit width %u",
				cfg->i2s.word_size);
		return -EINVAL;
	}

	codec_write_reg(dev, IF_CTRL1_ADDR, val);
	return 0;
}

static int codec_configure_clocks(const struct device *dev,
				  struct audio_codec_cfg *cfg)
{
	int dac_clk, mod_clk;
	struct i2s_config *i2s;
	int osr, osr_min, osr_max;
	enum osr_multiple osr_multiple;
	int mdac, ndac, bclk_div, mclk_div;

	i2s = &cfg->dai_cfg.i2s;
	LOG_DBG("MCLK %u Hz PCM Rate: %u Hz", cfg->mclk_freq,
			i2s->frame_clk_freq);

	if (cfg->mclk_freq <= DAC_PROC_CLK_FREQ_MAX) {
		/* use MCLK frequecy as the DAC processing clock */
		ndac = 1;
	} else {
		ndac = cfg->mclk_freq / DAC_PROC_CLK_FREQ_MAX;
	}

	dac_clk = cfg->mclk_freq / ndac;

	/* determine OSR Multiple based on PCM rate */
	osr_multiple = codec_get_osr_multiple(&cfg->dai_cfg);

	/*
	 * calculate MOD clock such that it is an integer multiple of
	 * cfg->i2s.frame_clk_freq and
	 * DAC_MOD_CLK_FREQ_MIN <= MOD clock <= DAC_MOD_CLK_FREQ_MAX
	 */
	osr_min = (DAC_MOD_CLK_FREQ_MIN + i2s->frame_clk_freq - 1) /
		i2s->frame_clk_freq;
	osr_max = DAC_MOD_CLK_FREQ_MAX / i2s->frame_clk_freq;

	/* round mix and max values to the required multiple */
	osr_max = (osr_max / osr_multiple) * osr_multiple;
	osr_min = (osr_min + osr_multiple - 1) / osr_multiple;

	osr = osr_max;
	while (osr >= osr_min) {
		mod_clk = i2s->frame_clk_freq * osr;

		/* calculate mdac */
		mdac = dac_clk / mod_clk;

		/* check if mdac is an integer */
		if ((mdac * mod_clk) == dac_clk) {
			/* found suitable dividers */
			break;
		}
		osr -= osr_multiple;
	}

	/* check if suitable value was found */
	if (osr < osr_min) {
		LOG_ERR("Unable to find suitable mdac and osr values");
		return -EINVAL;
	}

	LOG_DBG("Processing freq: %u Hz Modulator freq: %u Hz",
			dac_clk, mod_clk);
	LOG_DBG("NDAC: %u MDAC: %u OSR: %u", ndac, mdac, osr);

	if (i2s->options & I2S_OPT_BIT_CLK_MASTER) {
		bclk_div = osr * mdac / (i2s->word_size * 2U); /* stereo */
		if ((bclk_div * i2s->word_size * 2) != (osr * mdac)) {
			LOG_ERR("Unable to generate BCLK %u from MCLK %u",
				i2s->frame_clk_freq * i2s->word_size * 2U,
				cfg->mclk_freq);
			return -EINVAL;
		}
		LOG_DBG("I2S Master BCLKDIV: %u", bclk_div);
		codec_write_reg(dev, BCLK_DIV_ADDR,
				BCLK_DIV_POWER_UP | BCLK_DIV(bclk_div));
	}

	/* set NDAC, then MDAC, followed by OSR */
	codec_write_reg(dev, NDAC_DIV_ADDR,
			(uint8_t)(NDAC_DIV(ndac) | NDAC_POWER_UP_MASK));
	codec_write_reg(dev, MDAC_DIV_ADDR,
			(uint8_t)(MDAC_DIV(mdac) | MDAC_POWER_UP_MASK));
	codec_write_reg(dev, OSR_MSB_ADDR, (uint8_t)((osr >> 8) & OSR_MSB_MASK));
	codec_write_reg(dev, OSR_LSB_ADDR, (uint8_t)(osr & OSR_LSB_MASK));

	if (i2s->options & I2S_OPT_BIT_CLK_MASTER) {
		codec_write_reg(dev, BCLK_DIV_ADDR,
				BCLK_DIV(bclk_div) | BCLK_DIV_POWER_UP);
	}

	/* calculate MCLK divider to get ~1MHz */
	mclk_div = (cfg->mclk_freq + 1000000 - 1) / 1000000U;
	/* setup timer clock to be MCLK divided */
	codec_write_reg(dev, TIMER_MCLK_DIV_ADDR,
			TIMER_MCLK_DIV_EN_EXT | TIMER_MCLK_DIV_VAL(mclk_div));
	LOG_DBG("Timer MCLK Divider: %u", mclk_div);

	return 0;
}

static int codec_configure_filters(const struct device *dev,
				   audio_dai_cfg_t *cfg)
{
	enum proc_block proc_blk;

	/* determine decimation filter type */
	if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_192K) {
		proc_blk = PRB_P18_DECIMATION_C;
		LOG_INF("PCM Rate: %u Filter C PRB P18 selected",
				cfg->i2s.frame_clk_freq);
	} else if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_96K) {
		proc_blk = PRB_P10_DECIMATION_B;
		LOG_INF("PCM Rate: %u Filter B PRB P10 selected",
				cfg->i2s.frame_clk_freq);
	} else {
		proc_blk = PRB_P25_DECIMATION_A;
		LOG_INF("PCM Rate: %u Filter A PRB P25 selected",
				cfg->i2s.frame_clk_freq);
	}

	codec_write_reg(dev, PROC_BLK_SEL_ADDR, PROC_BLK_SEL(proc_blk));
	return 0;
}

static enum osr_multiple codec_get_osr_multiple(audio_dai_cfg_t *cfg)
{
	enum osr_multiple osr;

	if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_192K) {
		osr = OSR_MULTIPLE_2;
	} else if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_96K) {
		osr = OSR_MULTIPLE_4;
	} else {
		osr = OSR_MULTIPLE_8;
	}

	LOG_INF("PCM Rate: %u OSR Multiple: %u", cfg->i2s.frame_clk_freq,
			osr);
	return osr;
}

static void codec_configure_output(const struct device *dev)
{
	uint8_t val;

	/*
	 * set common mode voltage to 1.65V (half of AVDD)
	 * AVDD is typically 3.3V
	 */
	codec_read_reg(dev, HEADPHONE_DRV_ADDR, &val);
	val &= ~HEADPHONE_DRV_CM_MASK;
	val |= HEADPHONE_DRV_CM(CM_VOLTAGE_1P65) | HEADPHONE_DRV_RESERVED;
	codec_write_reg(dev, HEADPHONE_DRV_ADDR, val);

	/* enable pop removal on power down/up */
	codec_read_reg(dev, HP_OUT_POP_RM_ADDR, &val);
	codec_write_reg(dev, HP_OUT_POP_RM_ADDR, val | HP_OUT_POP_RM_ENABLE);

	/* route DAC output to Headphone */
	val = OUTPUT_ROUTING_HPL | OUTPUT_ROUTING_HPR;
	codec_write_reg(dev, OUTPUT_ROUTING_ADDR, val);

	/* enable volume control on Headphone out */
	codec_write_reg(dev, HPL_ANA_VOL_CTRL_ADDR,
			HPX_ANA_VOL(HPX_ANA_VOL_DEFAULT));
	codec_write_reg(dev, HPR_ANA_VOL_CTRL_ADDR,
			HPX_ANA_VOL(HPX_ANA_VOL_DEFAULT));

	/* set headphone outputs as line-out */
	codec_write_reg(dev, HEADPHONE_DRV_CTRL_ADDR, HEADPHONE_DRV_LINEOUT);

	/* unmute headphone drivers */
	codec_write_reg(dev, HPL_DRV_GAIN_CTRL_ADDR, HPX_DRV_UNMUTE);
	codec_write_reg(dev, HPR_DRV_GAIN_CTRL_ADDR, HPX_DRV_UNMUTE);

	/* power up headphone drivers */
	codec_read_reg(dev, HEADPHONE_DRV_ADDR, &val);
	val |= HEADPHONE_DRV_POWERUP | HEADPHONE_DRV_RESERVED;
	codec_write_reg(dev, HEADPHONE_DRV_ADDR, val);
}

static int codec_set_output_volume(const struct device *dev, int vol)
{
	uint8_t vol_val;
	int vol_index;
	uint8_t vol_array[] = {
		107, 108, 110, 113, 116, 120, 125, 128, 132, 138, 144
	};

	if ((vol > CODEC_OUTPUT_VOLUME_MAX) ||
			(vol < CODEC_OUTPUT_VOLUME_MIN)) {
		LOG_ERR("Invalid volume %d.%d dB",
				vol >> 1, ((uint32_t)vol & 1) ? 5 : 0);
		return -EINVAL;
	}

	/* remove sign */
	vol = -vol;

	/* if volume is near floor, set minimum */
	if (vol > HPX_ANA_VOL_FLOOR) {
		vol_val = HPX_ANA_VOL_FLOOR;
	} else if (vol > HPX_ANA_VOL_LOW_THRESH) {
		/* lookup low volume values */
		for (vol_index = 0; vol_index < ARRAY_SIZE(vol_array); vol_index++) {
			if (vol_array[vol_index] >= vol) {
				break;
			}
		}
		vol_val = HPX_ANA_VOL_LOW_THRESH + vol_index + 1;
	} else {
		vol_val = (uint8_t)vol;
	}

	codec_write_reg(dev, HPL_ANA_VOL_CTRL_ADDR, HPX_ANA_VOL(vol_val));
	codec_write_reg(dev, HPR_ANA_VOL_CTRL_ADDR, HPX_ANA_VOL(vol_val));
	return 0;
}

#if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
static void codec_read_all_regs(const struct device *dev)
{
	uint8_t val;

	codec_read_reg(dev, SOFT_RESET_ADDR, &val);
	codec_read_reg(dev, NDAC_DIV_ADDR, &val);
	codec_read_reg(dev, MDAC_DIV_ADDR, &val);
	codec_read_reg(dev, OSR_MSB_ADDR, &val);
	codec_read_reg(dev, OSR_LSB_ADDR, &val);
	codec_read_reg(dev, IF_CTRL1_ADDR, &val);
	codec_read_reg(dev, BCLK_DIV_ADDR, &val);
	codec_read_reg(dev, OVF_FLAG_ADDR, &val);
	codec_read_reg(dev, PROC_BLK_SEL_ADDR, &val);
	codec_read_reg(dev, DATA_PATH_SETUP_ADDR, &val);
	codec_read_reg(dev, VOL_CTRL_ADDR, &val);
	codec_read_reg(dev, L_DIG_VOL_CTRL_ADDR, &val);
	codec_read_reg(dev, DRC_CTRL1_ADDR, &val);
	codec_read_reg(dev, L_BEEP_GEN_ADDR, &val);
	codec_read_reg(dev, R_BEEP_GEN_ADDR, &val);
	codec_read_reg(dev, BEEP_LEN_MSB_ADDR, &val);
	codec_read_reg(dev, BEEP_LEN_MIB_ADDR, &val);
	codec_read_reg(dev, BEEP_LEN_LSB_ADDR, &val);

	codec_read_reg(dev, HEADPHONE_DRV_ADDR, &val);
	codec_read_reg(dev, HP_OUT_POP_RM_ADDR, &val);
	codec_read_reg(dev, OUTPUT_ROUTING_ADDR, &val);
	codec_read_reg(dev, HPL_ANA_VOL_CTRL_ADDR, &val);
	codec_read_reg(dev, HPR_ANA_VOL_CTRL_ADDR, &val);
	codec_read_reg(dev, HPL_DRV_GAIN_CTRL_ADDR, &val);
	codec_read_reg(dev, HPR_DRV_GAIN_CTRL_ADDR, &val);
	codec_read_reg(dev, HEADPHONE_DRV_CTRL_ADDR, &val);

	codec_read_reg(dev, TIMER_MCLK_DIV_ADDR, &val);
}
#endif

static const struct audio_codec_api codec_driver_api = {
	.configure		= codec_configure,
	.start_output		= codec_start_output,
	.stop_output		= codec_stop_output,
	.set_property		= codec_set_property,
	.apply_properties	= codec_apply_properties,
};

DEVICE_DT_INST_DEFINE(0, codec_initialize, NULL, &codec_device_data,
		&codec_device_config, POST_KERNEL,
		CONFIG_AUDIO_CODEC_INIT_PRIORITY, &codec_driver_api);
