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

#include <errno.h>

#define SYS_LOG_DOMAIN "dev/codec"
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_AUDIO_CODEC_LEVEL
#include <logging/sys_log.h>

#include <misc/util.h>

#include <device.h>
#include <i2c.h>

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

#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 codec_driver_data {
	struct reg_addr	reg_addr_cache;
};

static struct codec_driver_config codec_device_config = {
	.i2c_device	= NULL,
	.i2c_dev_name	= CONFIG_CODEC_I2C_BUS_NAME,
	.i2c_address	= CONFIG_CODEC_I2C_BUS_ADDR,
};

static struct codec_driver_data codec_device_data;

#define DEV_CFG(dev) \
	((struct codec_driver_config *const)(dev)->config->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 (SYS_LOG_LEVEL >= SYS_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) {
		SYS_LOG_ERR("I2C device binding error");
		return -ENXIO;
	}
	return 0;
}

static int codec_configure(struct device *dev,
		struct audio_codec_cfg *cfg)
{
	int ret;

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

	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) {
		SYS_LOG_ERR("channel %u invalid. must be AUDIO_CHANNEL_ALL");
		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,
				DAC_I2C_DEV_ADDR, 0, reg.page);
		dev_data->reg_addr_cache.page = reg.page;
	}

	i2c_reg_write_byte(dev_cfg->i2c_device,
			DAC_I2C_DEV_ADDR, reg.reg_addr, val);
	SYS_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,
				DAC_I2C_DEV_ADDR, 0, reg.page);
		dev_data->reg_addr_cache.page = reg.page;
	}

	i2c_reg_read_byte(dev_cfg->i2c_device,
			DAC_I2C_DEV_ADDR, reg.reg_addr, val);
	SYS_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:
		SYS_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;
	SYS_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) {
		SYS_LOG_ERR("Unable to find suitable mdac and osr values");
		return -EINVAL;
	}

	SYS_LOG_DBG("Processing freq: %u Hz Modulator freq: %u Hz",
			dac_clk, mod_clk);
	SYS_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 * 2); /* stereo */
		if ((bclk_div * i2s->word_size * 2) != (osr * mdac)) {
			SYS_LOG_ERR("Unable to generate BCLK %u from MCLK %u",
				i2s->frame_clk_freq * i2s->word_size * 2,
				cfg->mclk_freq);
			return -EINVAL;
		}
		SYS_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) / 1000000;
	/* 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));
	SYS_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;
		SYS_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;
		SYS_LOG_INF("PCM Rate: %u Filter B PRB P10 selected",
				cfg->i2s.frame_clk_freq);
	} else {
		proc_blk = PRB_P25_DECIMATION_A;
		SYS_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;
	}

	SYS_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, vol_count;
	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)) {
		SYS_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 */
		vol_count = sizeof(vol_array)/sizeof(u8_t);
		for (vol_index = 0; vol_index < vol_count; 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 (SYS_LOG_LEVEL >= SYS_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, CONFIG_CODEC_NAME, codec_initialize,
		&codec_device_data, &codec_device_config, POST_KERNEL,
		CONFIG_AUDIO_CODEC_INIT_PRIORITY, &codec_driver_api);
