/*
 * 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 {
	struct device	*i2c_device;
	const char	*i2c_dev_name;
	u8_t		i2c_address;
	struct device	*gpio_device;
	const char	*gpio_dev_name;
	u32_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_info)
#define DEV_DATA(dev) \
	((struct codec_driver_data *const)(dev)->driver_data)

static void codec_write_reg(struct device *dev, struct reg_addr reg, u8_t val);
static void codec_read_reg(struct device *dev, struct reg_addr reg, u8_t *val);
static void codec_soft_reset(struct device *dev);
static int codec_configure_dai(struct device *dev, audio_dai_cfg_t *cfg);
static int codec_configure_clocks(struct device *dev,
		struct audio_codec_cfg *cfg);
static int codec_configure_filters(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(struct device *dev);
static int codec_set_output_volume(struct device *dev, int vol);

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

static int codec_initialize(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(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(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(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(struct device *dev)
{
	/* mute DAC channels */
	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_MUTE_DEFAULT);
}

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

static int codec_set_property(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(struct device *dev)
{
	/* nothing to do because there is nothing cached */
	return 0;
}

static void codec_write_reg(struct device *dev, struct reg_addr reg, u8_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(struct device *dev, struct reg_addr reg, u8_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(struct device *dev)
{
	/* soft reset the DAC */
	codec_write_reg(dev, SOFT_RESET_ADDR, SOFT_RESET_ASSERT);
}

static int codec_configure_dai(struct device *dev, audio_dai_cfg_t *cfg)
{
	u8_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(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,
			(u8_t)(NDAC_DIV(ndac) | NDAC_POWER_UP_MASK));
	codec_write_reg(dev, MDAC_DIV_ADDR,
			(u8_t)(MDAC_DIV(mdac) | MDAC_POWER_UP_MASK));
	codec_write_reg(dev, OSR_MSB_ADDR, (u8_t)((osr >> 8) & OSR_MSB_MASK));
	codec_write_reg(dev, OSR_LSB_ADDR, (u8_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(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(struct device *dev)
{
	u8_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(struct device *dev, int vol)
{
	u8_t vol_val;
	int vol_index;
	u8_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, ((u32_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 = (u8_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(struct device *dev)
{
	u8_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_AND_API_INIT(tlv320dac310x, DT_INST_LABEL(0), codec_initialize,
		&codec_device_data, &codec_device_config, POST_KERNEL,
		CONFIG_AUDIO_CODEC_INIT_PRIORITY, &codec_driver_api);
