// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
 *
 * lpass-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS
 */

#include <dt-bindings/sound/qcom,lpass.h>
#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
#include "lpass-lpaif-reg.h"
#include "lpass.h"

#define LPASS_CPU_MAX_MI2S_LINES	4
#define LPASS_CPU_I2S_SD0_MASK		BIT(0)
#define LPASS_CPU_I2S_SD1_MASK		BIT(1)
#define LPASS_CPU_I2S_SD2_MASK		BIT(2)
#define LPASS_CPU_I2S_SD3_MASK		BIT(3)
#define LPASS_CPU_I2S_SD0_1_MASK	GENMASK(1, 0)
#define LPASS_CPU_I2S_SD2_3_MASK	GENMASK(3, 2)
#define LPASS_CPU_I2S_SD0_1_2_MASK	GENMASK(2, 0)
#define LPASS_CPU_I2S_SD0_1_2_3_MASK	GENMASK(3, 0)
#define LPASS_REG_READ 1
#define LPASS_REG_WRITE 0

/*
 * Channel maps for Quad channel playbacks on MI2S Secondary
 */
static struct snd_pcm_chmap_elem lpass_quad_chmaps[] = {
		{ .channels = 4,
		  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_RL,
				SNDRV_CHMAP_FR, SNDRV_CHMAP_RR } },
		{ }
};
static int lpass_cpu_init_i2sctl_bitfields(struct device *dev,
			struct lpaif_i2sctl *i2sctl, struct regmap *map)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;

	i2sctl->loopback = devm_regmap_field_alloc(dev, map, v->loopback);
	i2sctl->spken = devm_regmap_field_alloc(dev, map, v->spken);
	i2sctl->spkmode = devm_regmap_field_alloc(dev, map, v->spkmode);
	i2sctl->spkmono = devm_regmap_field_alloc(dev, map, v->spkmono);
	i2sctl->micen = devm_regmap_field_alloc(dev, map, v->micen);
	i2sctl->micmode = devm_regmap_field_alloc(dev, map, v->micmode);
	i2sctl->micmono = devm_regmap_field_alloc(dev, map, v->micmono);
	i2sctl->wssrc = devm_regmap_field_alloc(dev, map, v->wssrc);
	i2sctl->bitwidth = devm_regmap_field_alloc(dev, map, v->bitwidth);

	if (IS_ERR(i2sctl->loopback) || IS_ERR(i2sctl->spken) ||
	    IS_ERR(i2sctl->spkmode) || IS_ERR(i2sctl->spkmono) ||
	    IS_ERR(i2sctl->micen) || IS_ERR(i2sctl->micmode) ||
	    IS_ERR(i2sctl->micmono) || IS_ERR(i2sctl->wssrc) ||
	    IS_ERR(i2sctl->bitwidth))
		return -EINVAL;

	return 0;
}

static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id,
		unsigned int freq, int dir)
{
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
	int ret;

	ret = clk_set_rate(drvdata->mi2s_osr_clk[dai->driver->id], freq);
	if (ret)
		dev_err(dai->dev, "error setting mi2s osrclk to %u: %d\n",
			freq, ret);

	return ret;
}

static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
	int ret;

	ret = clk_prepare_enable(drvdata->mi2s_osr_clk[dai->driver->id]);
	if (ret) {
		dev_err(dai->dev, "error in enabling mi2s osr clk: %d\n", ret);
		return ret;
	}
	ret = clk_prepare(drvdata->mi2s_bit_clk[dai->driver->id]);
	if (ret) {
		dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
		clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
		return ret;
	}
	return 0;
}

static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
	struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
	unsigned int id = dai->driver->id;

	clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
	/*
	 * Ensure LRCLK is disabled even in device node validation.
	 * Will not impact if disabled in lpass_cpu_daiops_trigger()
	 * suspend.
	 */
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_DISABLE);
	else
		regmap_fields_write(i2sctl->micen, id, LPAIF_I2SCTL_MICEN_DISABLE);

	/*
	 * BCLK may not be enabled if lpass_cpu_daiops_prepare is called before
	 * lpass_cpu_daiops_shutdown. It's paired with the clk_enable in
	 * lpass_cpu_daiops_prepare.
	 */
	if (drvdata->mi2s_was_prepared[dai->driver->id]) {
		drvdata->mi2s_was_prepared[dai->driver->id] = false;
		clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
	}

	clk_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]);
}

static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
	struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
	unsigned int id = dai->driver->id;
	snd_pcm_format_t format = params_format(params);
	unsigned int channels = params_channels(params);
	unsigned int rate = params_rate(params);
	unsigned int mode;
	unsigned int regval;
	int bitwidth, ret;

	bitwidth = snd_pcm_format_width(format);
	if (bitwidth < 0) {
		dev_err(dai->dev, "invalid bit width given: %d\n", bitwidth);
		return bitwidth;
	}

	ret = regmap_fields_write(i2sctl->loopback, id,
				 LPAIF_I2SCTL_LOOPBACK_DISABLE);
	if (ret) {
		dev_err(dai->dev, "error updating loopback field: %d\n", ret);
		return ret;
	}

	ret = regmap_fields_write(i2sctl->wssrc, id,
				 LPAIF_I2SCTL_WSSRC_INTERNAL);
	if (ret) {
		dev_err(dai->dev, "error updating wssrc field: %d\n", ret);
		return ret;
	}

	switch (bitwidth) {
	case 16:
		regval = LPAIF_I2SCTL_BITWIDTH_16;
		break;
	case 24:
		regval = LPAIF_I2SCTL_BITWIDTH_24;
		break;
	case 32:
		regval = LPAIF_I2SCTL_BITWIDTH_32;
		break;
	default:
		dev_err(dai->dev, "invalid bitwidth given: %d\n", bitwidth);
		return -EINVAL;
	}

	ret = regmap_fields_write(i2sctl->bitwidth, id, regval);
	if (ret) {
		dev_err(dai->dev, "error updating bitwidth field: %d\n", ret);
		return ret;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		mode = drvdata->mi2s_playback_sd_mode[id];
	else
		mode = drvdata->mi2s_capture_sd_mode[id];

	if (!mode) {
		dev_err(dai->dev, "no line is assigned\n");
		return -EINVAL;
	}

	switch (channels) {
	case 1:
	case 2:
		switch (mode) {
		case LPAIF_I2SCTL_MODE_QUAD01:
		case LPAIF_I2SCTL_MODE_6CH:
		case LPAIF_I2SCTL_MODE_8CH:
			mode = LPAIF_I2SCTL_MODE_SD0;
			break;
		case LPAIF_I2SCTL_MODE_QUAD23:
			mode = LPAIF_I2SCTL_MODE_SD2;
			break;
		}

		break;
	case 4:
		if (mode < LPAIF_I2SCTL_MODE_QUAD01) {
			dev_err(dai->dev, "cannot configure 4 channels with mode %d\n",
				mode);
			return -EINVAL;
		}

		switch (mode) {
		case LPAIF_I2SCTL_MODE_6CH:
		case LPAIF_I2SCTL_MODE_8CH:
			mode = LPAIF_I2SCTL_MODE_QUAD01;
			break;
		}
		break;
	case 6:
		if (mode < LPAIF_I2SCTL_MODE_6CH) {
			dev_err(dai->dev, "cannot configure 6 channels with mode %d\n",
				mode);
			return -EINVAL;
		}

		switch (mode) {
		case LPAIF_I2SCTL_MODE_8CH:
			mode = LPAIF_I2SCTL_MODE_6CH;
			break;
		}
		break;
	case 8:
		if (mode < LPAIF_I2SCTL_MODE_8CH) {
			dev_err(dai->dev, "cannot configure 8 channels with mode %d\n",
				mode);
			return -EINVAL;
		}
		break;
	default:
		dev_err(dai->dev, "invalid channels given: %u\n", channels);
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		ret = regmap_fields_write(i2sctl->spkmode, id,
					 LPAIF_I2SCTL_SPKMODE(mode));
		if (ret) {
			dev_err(dai->dev, "error writing to i2sctl spkr mode: %d\n",
				ret);
			return ret;
		}
		if (channels >= 2)
			ret = regmap_fields_write(i2sctl->spkmono, id,
						 LPAIF_I2SCTL_SPKMONO_STEREO);
		else
			ret = regmap_fields_write(i2sctl->spkmono, id,
						 LPAIF_I2SCTL_SPKMONO_MONO);
	} else {
		ret = regmap_fields_write(i2sctl->micmode, id,
					 LPAIF_I2SCTL_MICMODE(mode));
		if (ret) {
			dev_err(dai->dev, "error writing to i2sctl mic mode: %d\n",
				ret);
			return ret;
		}
		if (channels >= 2)
			ret = regmap_fields_write(i2sctl->micmono, id,
						 LPAIF_I2SCTL_MICMONO_STEREO);
		else
			ret = regmap_fields_write(i2sctl->micmono, id,
						 LPAIF_I2SCTL_MICMONO_MONO);
	}

	if (ret) {
		dev_err(dai->dev, "error writing to i2sctl channels mode: %d\n",
			ret);
		return ret;
	}

	ret = clk_set_rate(drvdata->mi2s_bit_clk[id],
			   rate * bitwidth * 2);
	if (ret) {
		dev_err(dai->dev, "error setting mi2s bitclk to %u: %d\n",
			rate * bitwidth * 2, ret);
		return ret;
	}

	return 0;
}

static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
		int cmd, struct snd_soc_dai *dai)
{
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
	struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
	unsigned int id = dai->driver->id;
	int ret = -EINVAL;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		/*
		 * Ensure lpass BCLK/LRCLK is enabled during
		 * device resume as lpass_cpu_daiops_prepare() is not called
		 * after the device resumes. We don't check mi2s_was_prepared before
		 * enable/disable BCLK in trigger events because:
		 *  1. These trigger events are paired, so the BCLK
		 *     enable_count is balanced.
		 *  2. the BCLK can be shared (ex: headset and headset mic),
		 *     we need to increase the enable_count so that we don't
		 *     turn off the shared BCLK while other devices are using
		 *     it.
		 */
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			ret = regmap_fields_write(i2sctl->spken, id,
						 LPAIF_I2SCTL_SPKEN_ENABLE);
		} else  {
			ret = regmap_fields_write(i2sctl->micen, id,
						 LPAIF_I2SCTL_MICEN_ENABLE);
		}
		if (ret)
			dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
				ret);

		ret = clk_enable(drvdata->mi2s_bit_clk[id]);
		if (ret) {
			dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
			clk_disable(drvdata->mi2s_osr_clk[id]);
			return ret;
		}
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		/*
		 * To ensure lpass BCLK/LRCLK is disabled during
		 * device suspend.
		 */
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			ret = regmap_fields_write(i2sctl->spken, id,
						 LPAIF_I2SCTL_SPKEN_DISABLE);
		} else  {
			ret = regmap_fields_write(i2sctl->micen, id,
						 LPAIF_I2SCTL_MICEN_DISABLE);
		}
		if (ret)
			dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
				ret);

		clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);

		break;
	}

	return ret;
}

static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
	struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
	unsigned int id = dai->driver->id;
	int ret;

	/*
	 * Ensure lpass BCLK/LRCLK is enabled bit before playback/capture
	 * data flow starts. This allows other codec to have some delay before
	 * the data flow.
	 * (ex: to drop start up pop noise before capture starts).
	 */
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		ret = regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_ENABLE);
	else
		ret = regmap_fields_write(i2sctl->micen, id, LPAIF_I2SCTL_MICEN_ENABLE);

	if (ret) {
		dev_err(dai->dev, "error writing to i2sctl reg: %d\n", ret);
		return ret;
	}

	/*
	 * Check mi2s_was_prepared before enabling BCLK as lpass_cpu_daiops_prepare can
	 * be called multiple times. It's paired with the clk_disable in
	 * lpass_cpu_daiops_shutdown.
	 */
	if (!drvdata->mi2s_was_prepared[dai->driver->id]) {
		ret = clk_enable(drvdata->mi2s_bit_clk[id]);
		if (ret) {
			dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
			return ret;
		}
		drvdata->mi2s_was_prepared[dai->driver->id] = true;
	}
	return 0;
}

static int lpass_cpu_daiops_pcm_new(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
	int ret;
	struct snd_soc_dai_driver *drv = dai->driver;
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);

	if (drvdata->mi2s_playback_sd_mode[dai->id] == LPAIF_I2SCTL_MODE_QUAD01) {
		ret =  snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
				lpass_quad_chmaps, drv->playback.channels_max, 0,
				NULL);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int lpass_cpu_daiops_probe(struct snd_soc_dai *dai)
{
	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
	int ret;

	/* ensure audio hardware is disabled */
	ret = regmap_write(drvdata->lpaif_map,
			LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), 0);
	if (ret)
		dev_err(dai->dev, "error writing to i2sctl reg: %d\n", ret);

	return ret;
}

const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = {
	.probe		= lpass_cpu_daiops_probe,
	.set_sysclk	= lpass_cpu_daiops_set_sysclk,
	.startup	= lpass_cpu_daiops_startup,
	.shutdown	= lpass_cpu_daiops_shutdown,
	.hw_params	= lpass_cpu_daiops_hw_params,
	.trigger	= lpass_cpu_daiops_trigger,
	.prepare	= lpass_cpu_daiops_prepare,
};
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops);

const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops2 = {
	.pcm_new	= lpass_cpu_daiops_pcm_new,
	.probe		= lpass_cpu_daiops_probe,
	.set_sysclk	= lpass_cpu_daiops_set_sysclk,
	.startup	= lpass_cpu_daiops_startup,
	.shutdown	= lpass_cpu_daiops_shutdown,
	.hw_params	= lpass_cpu_daiops_hw_params,
	.trigger	= lpass_cpu_daiops_trigger,
	.prepare	= lpass_cpu_daiops_prepare,
};
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops2);

static int asoc_qcom_of_xlate_dai_name(struct snd_soc_component *component,
				   const struct of_phandle_args *args,
				   const char **dai_name)
{
	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
	const struct lpass_variant *variant = drvdata->variant;
	int id = args->args[0];
	int ret = -EINVAL;
	int i;

	for (i = 0; i  < variant->num_dai; i++) {
		if (variant->dai_driver[i].id == id) {
			*dai_name = variant->dai_driver[i].name;
			ret = 0;
			break;
		}
	}

	return ret;
}

static const struct snd_soc_component_driver lpass_cpu_comp_driver = {
	.name = "lpass-cpu",
	.of_xlate_dai_name = asoc_qcom_of_xlate_dai_name,
	.legacy_dai_naming = 1,
};

static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	for (i = 0; i < v->i2s_ports; ++i)
		if (reg == LPAIF_I2SCTL_REG(v, i))
			return true;

	for (i = 0; i < v->irq_ports; ++i) {
		if (reg == LPAIF_IRQEN_REG(v, i))
			return true;
		if (reg == LPAIF_IRQCLEAR_REG(v, i))
			return true;
	}

	for (i = 0; i < v->rdma_channels; ++i) {
		if (reg == LPAIF_RDMACTL_REG(v, i))
			return true;
		if (reg == LPAIF_RDMABASE_REG(v, i))
			return true;
		if (reg == LPAIF_RDMABUFF_REG(v, i))
			return true;
		if (reg == LPAIF_RDMAPER_REG(v, i))
			return true;
	}

	for (i = 0; i < v->wrdma_channels; ++i) {
		if (reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
			return true;
		if (reg == LPAIF_WRDMABASE_REG(v, i + v->wrdma_channel_start))
			return true;
		if (reg == LPAIF_WRDMABUFF_REG(v, i + v->wrdma_channel_start))
			return true;
		if (reg == LPAIF_WRDMAPER_REG(v, i + v->wrdma_channel_start))
			return true;
	}

	return false;
}

static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	for (i = 0; i < v->i2s_ports; ++i)
		if (reg == LPAIF_I2SCTL_REG(v, i))
			return true;

	for (i = 0; i < v->irq_ports; ++i) {
		if (reg == LPAIF_IRQCLEAR_REG(v, i))
			return true;
		if (reg == LPAIF_IRQEN_REG(v, i))
			return true;
		if (reg == LPAIF_IRQSTAT_REG(v, i))
			return true;
	}

	for (i = 0; i < v->rdma_channels; ++i) {
		if (reg == LPAIF_RDMACTL_REG(v, i))
			return true;
		if (reg == LPAIF_RDMABASE_REG(v, i))
			return true;
		if (reg == LPAIF_RDMABUFF_REG(v, i))
			return true;
		if (reg == LPAIF_RDMACURR_REG(v, i))
			return true;
		if (reg == LPAIF_RDMAPER_REG(v, i))
			return true;
	}

	for (i = 0; i < v->wrdma_channels; ++i) {
		if (reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
			return true;
		if (reg == LPAIF_WRDMABASE_REG(v, i + v->wrdma_channel_start))
			return true;
		if (reg == LPAIF_WRDMABUFF_REG(v, i + v->wrdma_channel_start))
			return true;
		if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
			return true;
		if (reg == LPAIF_WRDMAPER_REG(v, i + v->wrdma_channel_start))
			return true;
	}

	return false;
}

static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	for (i = 0; i < v->irq_ports; ++i) {
		if (reg == LPAIF_IRQCLEAR_REG(v, i))
			return true;
		if (reg == LPAIF_IRQSTAT_REG(v, i))
			return true;
	}

	for (i = 0; i < v->rdma_channels; ++i)
		if (reg == LPAIF_RDMACURR_REG(v, i))
			return true;

	for (i = 0; i < v->wrdma_channels; ++i)
		if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
			return true;

	return false;
}

static struct regmap_config lpass_cpu_regmap_config = {
	.name = "lpass_cpu",
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.writeable_reg = lpass_cpu_regmap_writeable,
	.readable_reg = lpass_cpu_regmap_readable,
	.volatile_reg = lpass_cpu_regmap_volatile,
	.cache_type = REGCACHE_FLAT,
};

static int lpass_hdmi_init_bitfields(struct device *dev, struct regmap *map)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	unsigned int i;
	struct lpass_hdmi_tx_ctl *tx_ctl;
	struct regmap_field *legacy_en;
	struct lpass_vbit_ctrl *vbit_ctl;
	struct regmap_field *tx_parity;
	struct lpass_dp_metadata_ctl *meta_ctl;
	struct lpass_sstream_ctl *sstream_ctl;
	struct regmap_field *ch_msb;
	struct regmap_field *ch_lsb;
	struct lpass_hdmitx_dmactl *tx_dmactl;
	int rval;

	tx_ctl = devm_kzalloc(dev, sizeof(*tx_ctl), GFP_KERNEL);
	if (!tx_ctl)
		return -ENOMEM;

	QCOM_REGMAP_FIELD_ALLOC(dev, map, v->soft_reset, tx_ctl->soft_reset);
	QCOM_REGMAP_FIELD_ALLOC(dev, map, v->force_reset, tx_ctl->force_reset);
	drvdata->tx_ctl = tx_ctl;

	QCOM_REGMAP_FIELD_ALLOC(dev, map, v->legacy_en, legacy_en);
	drvdata->hdmitx_legacy_en = legacy_en;

	vbit_ctl = devm_kzalloc(dev, sizeof(*vbit_ctl), GFP_KERNEL);
	if (!vbit_ctl)
		return -ENOMEM;

	QCOM_REGMAP_FIELD_ALLOC(dev, map, v->replace_vbit, vbit_ctl->replace_vbit);
	QCOM_REGMAP_FIELD_ALLOC(dev, map, v->vbit_stream, vbit_ctl->vbit_stream);
	drvdata->vbit_ctl = vbit_ctl;


	QCOM_REGMAP_FIELD_ALLOC(dev, map, v->calc_en, tx_parity);
	drvdata->hdmitx_parity_calc_en = tx_parity;

	meta_ctl = devm_kzalloc(dev, sizeof(*meta_ctl), GFP_KERNEL);
	if (!meta_ctl)
		return -ENOMEM;

	rval = devm_regmap_field_bulk_alloc(dev, map, &meta_ctl->mute, &v->mute, 7);
	if (rval)
		return rval;
	drvdata->meta_ctl = meta_ctl;

	sstream_ctl = devm_kzalloc(dev, sizeof(*sstream_ctl), GFP_KERNEL);
	if (!sstream_ctl)
		return -ENOMEM;

	rval = devm_regmap_field_bulk_alloc(dev, map, &sstream_ctl->sstream_en, &v->sstream_en, 9);
	if (rval)
		return rval;

	drvdata->sstream_ctl = sstream_ctl;

	for (i = 0; i < LPASS_MAX_HDMI_DMA_CHANNELS; i++) {
		QCOM_REGMAP_FIELD_ALLOC(dev, map, v->msb_bits, ch_msb);
		drvdata->hdmitx_ch_msb[i] = ch_msb;

		QCOM_REGMAP_FIELD_ALLOC(dev, map, v->lsb_bits, ch_lsb);
		drvdata->hdmitx_ch_lsb[i] = ch_lsb;

		tx_dmactl = devm_kzalloc(dev, sizeof(*tx_dmactl), GFP_KERNEL);
		if (!tx_dmactl)
			return -ENOMEM;

		QCOM_REGMAP_FIELD_ALLOC(dev, map, v->use_hw_chs, tx_dmactl->use_hw_chs);
		QCOM_REGMAP_FIELD_ALLOC(dev, map, v->use_hw_usr, tx_dmactl->use_hw_usr);
		QCOM_REGMAP_FIELD_ALLOC(dev, map, v->hw_chs_sel, tx_dmactl->hw_chs_sel);
		QCOM_REGMAP_FIELD_ALLOC(dev, map, v->hw_usr_sel, tx_dmactl->hw_usr_sel);
		drvdata->hdmi_tx_dmactl[i] = tx_dmactl;
	}
	return 0;
}

static bool lpass_hdmi_regmap_writeable(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	if (reg == LPASS_HDMI_TX_CTL_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_DP_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_SSTREAM_ADDR(v))
		return true;
	if (reg == LPASS_HDMITX_APP_IRQEN_REG(v))
		return true;
	if (reg == LPASS_HDMITX_APP_IRQCLEAR_REG(v))
		return true;

	for (i = 0; i < v->hdmi_rdma_channels; i++) {
		if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
			return true;
		if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
			return true;
		if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
			return true;
	}

	for (i = 0; i < v->hdmi_rdma_channels; ++i) {
		if (reg == LPAIF_HDMI_RDMACTL_REG(v, i))
			return true;
		if (reg == LPAIF_HDMI_RDMABASE_REG(v, i))
			return true;
		if (reg == LPAIF_HDMI_RDMABUFF_REG(v, i))
			return true;
		if (reg == LPAIF_HDMI_RDMAPER_REG(v, i))
			return true;
	}
	return false;
}

static bool lpass_hdmi_regmap_readable(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	if (reg == LPASS_HDMI_TX_CTL_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
		return true;

	for (i = 0; i < v->hdmi_rdma_channels; i++) {
		if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
			return true;
		if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
			return true;
		if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
			return true;
	}

	if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_DP_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_SSTREAM_ADDR(v))
		return true;
	if (reg == LPASS_HDMITX_APP_IRQEN_REG(v))
		return true;
	if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v))
		return true;

	for (i = 0; i < v->hdmi_rdma_channels; ++i) {
		if (reg == LPAIF_HDMI_RDMACTL_REG(v, i))
			return true;
		if (reg == LPAIF_HDMI_RDMABASE_REG(v, i))
			return true;
		if (reg == LPAIF_HDMI_RDMABUFF_REG(v, i))
			return true;
		if (reg == LPAIF_HDMI_RDMAPER_REG(v, i))
			return true;
		if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
			return true;
	}

	return false;
}

static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v))
		return true;
	if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
		return true;
	if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
		return true;

	for (i = 0; i < v->hdmi_rdma_channels; ++i) {
		if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
			return true;
		if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
			return true;
		if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
			return true;
		if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
			return true;
	}
	return false;
}

static struct regmap_config lpass_hdmi_regmap_config = {
	.name = "lpass_hdmi",
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.writeable_reg = lpass_hdmi_regmap_writeable,
	.readable_reg = lpass_hdmi_regmap_readable,
	.volatile_reg = lpass_hdmi_regmap_volatile,
	.cache_type = REGCACHE_FLAT,
};

static bool __lpass_rxtx_regmap_accessible(struct device *dev, unsigned int reg, bool rw)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	for (i = 0; i < v->rxtx_irq_ports; ++i) {
		if (reg == LPAIF_RXTX_IRQCLEAR_REG(v, i))
			return true;
		if (reg == LPAIF_RXTX_IRQEN_REG(v, i))
			return true;
		if (reg == LPAIF_RXTX_IRQSTAT_REG(v, i))
			return true;
	}

	for (i = 0; i < v->rxtx_rdma_channels; ++i) {
		if (reg == LPAIF_CDC_RXTX_RDMACTL_REG(v, i, LPASS_CDC_DMA_RX0))
			return true;
		if (reg == LPAIF_CDC_RXTX_RDMABASE_REG(v, i, LPASS_CDC_DMA_RX0))
			return true;
		if (reg == LPAIF_CDC_RXTX_RDMABUFF_REG(v, i, LPASS_CDC_DMA_RX0))
			return true;
		if (rw == LPASS_REG_READ) {
			if (reg == LPAIF_CDC_RXTX_RDMACURR_REG(v, i, LPASS_CDC_DMA_RX0))
				return true;
		}
		if (reg == LPAIF_CDC_RXTX_RDMAPER_REG(v, i, LPASS_CDC_DMA_RX0))
			return true;
		if (reg == LPAIF_CDC_RXTX_RDMA_INTF_REG(v, i, LPASS_CDC_DMA_RX0))
			return true;
	}

	for (i = 0; i < v->rxtx_wrdma_channels; ++i) {
		if (reg == LPAIF_CDC_RXTX_WRDMACTL_REG(v, i + v->rxtx_wrdma_channel_start,
							LPASS_CDC_DMA_TX3))
			return true;
		if (reg == LPAIF_CDC_RXTX_WRDMABASE_REG(v, i + v->rxtx_wrdma_channel_start,
							LPASS_CDC_DMA_TX3))
			return true;
		if (reg == LPAIF_CDC_RXTX_WRDMABUFF_REG(v, i + v->rxtx_wrdma_channel_start,
							LPASS_CDC_DMA_TX3))
			return true;
		if (rw == LPASS_REG_READ) {
			if (reg == LPAIF_CDC_RXTX_WRDMACURR_REG(v, i, LPASS_CDC_DMA_RX0))
				return true;
		}
		if (reg == LPAIF_CDC_RXTX_WRDMAPER_REG(v, i + v->rxtx_wrdma_channel_start,
							LPASS_CDC_DMA_TX3))
			return true;
		if (reg == LPAIF_CDC_RXTX_WRDMA_INTF_REG(v, i + v->rxtx_wrdma_channel_start,
							LPASS_CDC_DMA_TX3))
			return true;
	}
	return false;
}

static bool lpass_rxtx_regmap_writeable(struct device *dev, unsigned int reg)
{
	return __lpass_rxtx_regmap_accessible(dev, reg, LPASS_REG_WRITE);
}

static bool lpass_rxtx_regmap_readable(struct device *dev, unsigned int reg)
{
	return __lpass_rxtx_regmap_accessible(dev, reg, LPASS_REG_READ);
}

static bool lpass_rxtx_regmap_volatile(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	for (i = 0; i < v->rxtx_irq_ports; ++i) {
		if (reg == LPAIF_RXTX_IRQCLEAR_REG(v, i))
			return true;
		if (reg == LPAIF_RXTX_IRQSTAT_REG(v, i))
			return true;
	}

	for (i = 0; i < v->rxtx_rdma_channels; ++i)
		if (reg == LPAIF_CDC_RXTX_RDMACURR_REG(v, i, LPASS_CDC_DMA_RX0))
			return true;

	for (i = 0; i < v->rxtx_wrdma_channels; ++i)
		if (reg == LPAIF_CDC_RXTX_WRDMACURR_REG(v, i + v->rxtx_wrdma_channel_start,
							LPASS_CDC_DMA_TX3))
			return true;

	return false;
}

static bool __lpass_va_regmap_accessible(struct device *dev, unsigned int reg, bool rw)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	for (i = 0; i < v->va_irq_ports; ++i) {
		if (reg == LPAIF_VA_IRQCLEAR_REG(v, i))
			return true;
		if (reg == LPAIF_VA_IRQEN_REG(v, i))
			return true;
		if (reg == LPAIF_VA_IRQSTAT_REG(v, i))
			return true;
	}

	for (i = 0; i < v->va_wrdma_channels; ++i) {
		if (reg == LPAIF_CDC_VA_WRDMACTL_REG(v, i + v->va_wrdma_channel_start,
							LPASS_CDC_DMA_VA_TX0))
			return true;
		if (reg == LPAIF_CDC_VA_WRDMABASE_REG(v, i + v->va_wrdma_channel_start,
							LPASS_CDC_DMA_VA_TX0))
			return true;
		if (reg == LPAIF_CDC_VA_WRDMABUFF_REG(v, i + v->va_wrdma_channel_start,
							LPASS_CDC_DMA_VA_TX0))
			return true;
		if (rw == LPASS_REG_READ) {
			if (reg == LPAIF_CDC_VA_WRDMACURR_REG(v, i + v->va_wrdma_channel_start,
							LPASS_CDC_DMA_VA_TX0))
				return true;
		}
		if (reg == LPAIF_CDC_VA_WRDMAPER_REG(v, i + v->va_wrdma_channel_start,
							LPASS_CDC_DMA_VA_TX0))
			return true;
		if (reg == LPAIF_CDC_VA_WRDMA_INTF_REG(v, i + v->va_wrdma_channel_start,
							LPASS_CDC_DMA_VA_TX0))
			return true;
	}
	return false;
}

static bool lpass_va_regmap_writeable(struct device *dev, unsigned int reg)
{
	return __lpass_va_regmap_accessible(dev, reg, LPASS_REG_WRITE);
}

static bool lpass_va_regmap_readable(struct device *dev, unsigned int reg)
{
	return __lpass_va_regmap_accessible(dev, reg, LPASS_REG_READ);
}

static bool lpass_va_regmap_volatile(struct device *dev, unsigned int reg)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);
	const struct lpass_variant *v = drvdata->variant;
	int i;

	for (i = 0; i < v->va_irq_ports; ++i) {
		if (reg == LPAIF_VA_IRQCLEAR_REG(v, i))
			return true;
		if (reg == LPAIF_VA_IRQSTAT_REG(v, i))
			return true;
	}

	for (i = 0; i < v->va_wrdma_channels; ++i) {
		if (reg == LPAIF_CDC_VA_WRDMACURR_REG(v, i + v->va_wrdma_channel_start,
							LPASS_CDC_DMA_VA_TX0))
			return true;
	}

	return false;
}

static struct regmap_config lpass_rxtx_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.writeable_reg = lpass_rxtx_regmap_writeable,
	.readable_reg = lpass_rxtx_regmap_readable,
	.volatile_reg = lpass_rxtx_regmap_volatile,
	.cache_type = REGCACHE_FLAT,
};

static struct regmap_config lpass_va_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.writeable_reg = lpass_va_regmap_writeable,
	.readable_reg = lpass_va_regmap_readable,
	.volatile_reg = lpass_va_regmap_volatile,
	.cache_type = REGCACHE_FLAT,
};

static unsigned int of_lpass_cpu_parse_sd_lines(struct device *dev,
						struct device_node *node,
						const char *name)
{
	unsigned int lines[LPASS_CPU_MAX_MI2S_LINES];
	unsigned int sd_line_mask = 0;
	int num_lines, i;

	num_lines = of_property_read_variable_u32_array(node, name, lines, 0,
							LPASS_CPU_MAX_MI2S_LINES);
	if (num_lines < 0)
		return LPAIF_I2SCTL_MODE_NONE;

	for (i = 0; i < num_lines; i++)
		sd_line_mask |= BIT(lines[i]);

	switch (sd_line_mask) {
	case LPASS_CPU_I2S_SD0_MASK:
		return LPAIF_I2SCTL_MODE_SD0;
	case LPASS_CPU_I2S_SD1_MASK:
		return LPAIF_I2SCTL_MODE_SD1;
	case LPASS_CPU_I2S_SD2_MASK:
		return LPAIF_I2SCTL_MODE_SD2;
	case LPASS_CPU_I2S_SD3_MASK:
		return LPAIF_I2SCTL_MODE_SD3;
	case LPASS_CPU_I2S_SD0_1_MASK:
		return LPAIF_I2SCTL_MODE_QUAD01;
	case LPASS_CPU_I2S_SD2_3_MASK:
		return LPAIF_I2SCTL_MODE_QUAD23;
	case LPASS_CPU_I2S_SD0_1_2_MASK:
		return LPAIF_I2SCTL_MODE_6CH;
	case LPASS_CPU_I2S_SD0_1_2_3_MASK:
		return LPAIF_I2SCTL_MODE_8CH;
	default:
		dev_err(dev, "Unsupported SD line mask: %#x\n", sd_line_mask);
		return LPAIF_I2SCTL_MODE_NONE;
	}
}

static void of_lpass_cpu_parse_dai_data(struct device *dev,
					struct lpass_data *data)
{
	struct device_node *node;
	int ret, i, id;

	/* Allow all channels by default for backwards compatibility */
	for (i = 0; i < data->variant->num_dai; i++) {
		id = data->variant->dai_driver[i].id;
		data->mi2s_playback_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH;
		data->mi2s_capture_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH;
	}

	for_each_child_of_node(dev->of_node, node) {
		ret = of_property_read_u32(node, "reg", &id);
		if (ret || id < 0) {
			dev_err(dev, "valid dai id not found: %d\n", ret);
			continue;
		}
		if (id == LPASS_DP_RX) {
			data->hdmi_port_enable = 1;
		} else if (is_cdc_dma_port(id)) {
			data->codec_dma_enable = 1;
		} else {
			data->mi2s_playback_sd_mode[id] =
				of_lpass_cpu_parse_sd_lines(dev, node,
							    "qcom,playback-sd-lines");
			data->mi2s_capture_sd_mode[id] =
				of_lpass_cpu_parse_sd_lines(dev, node,
						    "qcom,capture-sd-lines");
		}
	}
}

static int of_lpass_cdc_dma_clks_parse(struct device *dev,
					struct lpass_data *data)
{
	data->codec_mem0 = devm_clk_get(dev, "audio_cc_codec_mem0");
	if (IS_ERR(data->codec_mem0))
		return PTR_ERR(data->codec_mem0);

	data->codec_mem1 = devm_clk_get(dev, "audio_cc_codec_mem1");
	if (IS_ERR(data->codec_mem1))
		return PTR_ERR(data->codec_mem1);

	data->codec_mem2 = devm_clk_get(dev, "audio_cc_codec_mem2");
	if (IS_ERR(data->codec_mem2))
		return PTR_ERR(data->codec_mem2);

	data->va_mem0 = devm_clk_get(dev, "aon_cc_va_mem0");
	if (IS_ERR(data->va_mem0))
		return PTR_ERR(data->va_mem0);

	return 0;
}

int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
{
	struct lpass_data *drvdata;
	struct device_node *dsp_of_node;
	struct resource *res;
	const struct lpass_variant *variant;
	struct device *dev = &pdev->dev;
	int ret, i, dai_id;

	dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
	if (dsp_of_node) {
		dev_err(dev, "DSP exists and holds audio resources\n");
		of_node_put(dsp_of_node);
		return -EBUSY;
	}

	drvdata = devm_kzalloc(dev, sizeof(struct lpass_data), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;
	platform_set_drvdata(pdev, drvdata);

	variant = device_get_match_data(dev);
	if (!variant)
		return -EINVAL;

	if (of_device_is_compatible(dev->of_node, "qcom,lpass-cpu-apq8016"))
		dev_warn(dev, "qcom,lpass-cpu-apq8016 compatible is deprecated\n");

	drvdata->variant = variant;

	of_lpass_cpu_parse_dai_data(dev, drvdata);

	if (drvdata->codec_dma_enable) {
		drvdata->rxtx_lpaif =
				devm_platform_ioremap_resource_byname(pdev, "lpass-rxtx-lpaif");
		if (IS_ERR(drvdata->rxtx_lpaif))
			return PTR_ERR(drvdata->rxtx_lpaif);

		drvdata->va_lpaif = devm_platform_ioremap_resource_byname(pdev, "lpass-va-lpaif");
		if (IS_ERR(drvdata->va_lpaif))
			return PTR_ERR(drvdata->va_lpaif);

		lpass_rxtx_regmap_config.max_register = LPAIF_CDC_RXTX_WRDMAPER_REG(variant,
					variant->rxtx_wrdma_channels +
					variant->rxtx_wrdma_channel_start, LPASS_CDC_DMA_TX3);

		drvdata->rxtx_lpaif_map = devm_regmap_init_mmio(dev, drvdata->rxtx_lpaif,
					&lpass_rxtx_regmap_config);
		if (IS_ERR(drvdata->rxtx_lpaif_map))
			return PTR_ERR(drvdata->rxtx_lpaif_map);

		lpass_va_regmap_config.max_register = LPAIF_CDC_VA_WRDMAPER_REG(variant,
					variant->va_wrdma_channels +
					variant->va_wrdma_channel_start, LPASS_CDC_DMA_VA_TX0);

		drvdata->va_lpaif_map = devm_regmap_init_mmio(dev, drvdata->va_lpaif,
					&lpass_va_regmap_config);
		if (IS_ERR(drvdata->va_lpaif_map))
			return PTR_ERR(drvdata->va_lpaif_map);

		ret = of_lpass_cdc_dma_clks_parse(dev, drvdata);
		if (ret) {
			dev_err(dev, "failed to get cdc dma clocks %d\n", ret);
			return ret;
		}

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-rxtx-cdc-dma-lpm");
		drvdata->rxtx_cdc_dma_lpm_buf = res->start;

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-va-cdc-dma-lpm");
		drvdata->va_cdc_dma_lpm_buf = res->start;
	}

	drvdata->lpaif = devm_platform_ioremap_resource_byname(pdev, "lpass-lpaif");
	if (IS_ERR(drvdata->lpaif))
		return PTR_ERR(drvdata->lpaif);

	lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant,
						variant->wrdma_channels +
						variant->wrdma_channel_start);

	drvdata->lpaif_map = devm_regmap_init_mmio(dev, drvdata->lpaif,
			&lpass_cpu_regmap_config);
	if (IS_ERR(drvdata->lpaif_map)) {
		dev_err(dev, "error initializing regmap: %ld\n",
			PTR_ERR(drvdata->lpaif_map));
		return PTR_ERR(drvdata->lpaif_map);
	}

	if (drvdata->hdmi_port_enable) {
		drvdata->hdmiif = devm_platform_ioremap_resource_byname(pdev, "lpass-hdmiif");
		if (IS_ERR(drvdata->hdmiif))
			return PTR_ERR(drvdata->hdmiif);

		lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant,
					variant->hdmi_rdma_channels - 1);
		drvdata->hdmiif_map = devm_regmap_init_mmio(dev, drvdata->hdmiif,
					&lpass_hdmi_regmap_config);
		if (IS_ERR(drvdata->hdmiif_map)) {
			dev_err(dev, "error initializing regmap: %ld\n",
			PTR_ERR(drvdata->hdmiif_map));
			return PTR_ERR(drvdata->hdmiif_map);
		}
	}

	if (variant->init) {
		ret = variant->init(pdev);
		if (ret) {
			dev_err(dev, "error initializing variant: %d\n", ret);
			return ret;
		}
	}

	for (i = 0; i < variant->num_dai; i++) {
		dai_id = variant->dai_driver[i].id;
		if (dai_id == LPASS_DP_RX || is_cdc_dma_port(dai_id))
			continue;

		drvdata->mi2s_osr_clk[dai_id] = devm_clk_get_optional(dev,
					     variant->dai_osr_clk_names[i]);
		drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(dev,
						variant->dai_bit_clk_names[i]);
		if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
			dev_err(dev,
				"error getting %s: %ld\n",
				variant->dai_bit_clk_names[i],
				PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
			return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
		}
		if (drvdata->mi2s_playback_sd_mode[dai_id] ==
			LPAIF_I2SCTL_MODE_QUAD01) {
			variant->dai_driver[dai_id].playback.channels_min = 4;
			variant->dai_driver[dai_id].playback.channels_max = 4;
		}
	}

	/* Allocation for i2sctl regmap fields */
	drvdata->i2sctl = devm_kzalloc(&pdev->dev, sizeof(struct lpaif_i2sctl),
					GFP_KERNEL);

	/* Initialize bitfields for dai I2SCTL register */
	ret = lpass_cpu_init_i2sctl_bitfields(dev, drvdata->i2sctl,
						drvdata->lpaif_map);
	if (ret) {
		dev_err(dev, "error init i2sctl field: %d\n", ret);
		return ret;
	}

	if (drvdata->hdmi_port_enable) {
		ret = lpass_hdmi_init_bitfields(dev, drvdata->hdmiif_map);
		if (ret) {
			dev_err(dev, "%s error  hdmi init failed\n", __func__);
			return ret;
		}
	}
	ret = devm_snd_soc_register_component(dev,
					      &lpass_cpu_comp_driver,
					      variant->dai_driver,
					      variant->num_dai);
	if (ret) {
		dev_err(dev, "error registering cpu driver: %d\n", ret);
		goto err;
	}

	ret = asoc_qcom_lpass_platform_register(pdev);
	if (ret) {
		dev_err(dev, "error registering platform driver: %d\n", ret);
		goto err;
	}

err:
	return ret;
}
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_probe);

void asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev)
{
	struct lpass_data *drvdata = platform_get_drvdata(pdev);

	if (drvdata->variant->exit)
		drvdata->variant->exit(pdev);
}
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_remove);

void asoc_qcom_lpass_cpu_platform_shutdown(struct platform_device *pdev)
{
	struct lpass_data *drvdata = platform_get_drvdata(pdev);

	if (drvdata->variant->exit)
		drvdata->variant->exit(pdev);

}
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_shutdown);

MODULE_DESCRIPTION("QTi LPASS CPU Driver");
MODULE_LICENSE("GPL");
