Unverified Commit 61b23b6b authored by Mark Brown's avatar Mark Brown
Browse files

ADD legacy audio driver support for rembrandt

Merge series from V sujith kumar Reddy <Vsujithkumar.Reddy@amd.com>:

Add Generic driver to support multiple platform,
ADD HS control instance for Rembrandt platform.
Add nau8825,max98560 and rt5682s,rt1019 combination support for legacy
platform.
parents 3585da93 e8a33a94
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -40,6 +40,17 @@ config SND_AMD_ASOC_RENOIR
	help
	  This option enables Renoir I2S support on AMD platform.

config SND_AMD_ASOC_REMBRANDT
	tristate "AMD ACP ASOC Rembrandt Support"
	select SND_SOC_AMD_ACP_PCM
	select SND_SOC_AMD_ACP_I2S
	select SND_SOC_AMD_ACP_PDM
	depends on X86 && PCI
	help
	  This option enables Rembrandt I2S support on AMD platform.
	  Say Y if you want to enable AUDIO on Rembrandt
	  If unsure select "N".

config SND_SOC_AMD_MACH_COMMON
	tristate
	depends on X86 && PCI && I2C
+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ snd-acp-pci-objs := acp-pci.o

#platform specific driver
snd-acp-renoir-objs     := acp-renoir.o
snd-acp-rembrandt-objs  := acp-rembrandt.o

#machine specific driver
snd-acp-mach-objs     := acp-mach-common.o
@@ -24,6 +25,7 @@ obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o
obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o

obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o
obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o

obj-$(CONFIG_SND_SOC_AMD_MACH_COMMON) += snd-acp-mach.o
obj-$(CONFIG_SND_SOC_AMD_LEGACY_MACH) += snd-acp-legacy-mach.o
+155 −14
Original line number Diff line number Diff line
@@ -30,11 +30,14 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata;
	struct acp_resource *rsrc;
	u32 val;
	u32 xfer_resolution;
	u32 reg_val;
	u32 lrclk_div_val, bclk_div_val;

	adata = snd_soc_dai_get_drvdata(dai);
	rsrc = adata->rsrc;

	/* These values are as per Hardware Spec */
	switch (params_format(params)) {
@@ -63,6 +66,9 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
		case I2S_SP_INSTANCE:
			reg_val = ACP_I2STDM_ITER;
			break;
		case I2S_HS_INSTANCE:
			reg_val = ACP_HSTDM_ITER;
			break;
		default:
			dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
			return -EINVAL;
@@ -75,6 +81,9 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
		case I2S_SP_INSTANCE:
			reg_val = ACP_I2STDM_IRER;
			break;
		case I2S_HS_INSTANCE:
			reg_val = ACP_HSTDM_IRER;
			break;
		default:
			dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
			return -EINVAL;
@@ -86,6 +95,74 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
	val = val | (xfer_resolution  << 3);
	writel(val, adata->acp_base + reg_val);

	if (rsrc->soc_mclk) {
		switch (params_format(params)) {
		case SNDRV_PCM_FORMAT_S16_LE:
			switch (params_rate(params)) {
			case 8000:
				bclk_div_val = 768;
				break;
			case 16000:
				bclk_div_val = 384;
				break;
			case 24000:
				bclk_div_val = 256;
				break;
			case 32000:
				bclk_div_val = 192;
				break;
			case 44100:
			case 48000:
				bclk_div_val = 128;
				break;
			case 88200:
			case 96000:
				bclk_div_val = 64;
				break;
			case 192000:
				bclk_div_val = 32;
				break;
			default:
				return -EINVAL;
			}
			lrclk_div_val = 32;
			break;
		case SNDRV_PCM_FORMAT_S32_LE:
			switch (params_rate(params)) {
			case 8000:
				bclk_div_val = 384;
				break;
			case 16000:
				bclk_div_val = 192;
				break;
			case 24000:
				bclk_div_val = 128;
				break;
			case 32000:
				bclk_div_val = 96;
				break;
			case 44100:
			case 48000:
				bclk_div_val = 64;
				break;
			case 88200:
			case 96000:
				bclk_div_val = 32;
				break;
			case 192000:
				bclk_div_val = 16;
				break;
			default:
				return -EINVAL;
			}
			lrclk_div_val = 64;
			break;
		default:
			return -EINVAL;
		}
		adata->lrclk_div = lrclk_div_val;
		adata->bclk_div = bclk_div_val;
	}
	return 0;
}

@@ -94,6 +171,7 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
	struct acp_stream *stream = substream->runtime->private_data;
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_resource *rsrc = adata->rsrc;
	u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg;

	period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size);
@@ -118,6 +196,12 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
				ier_val = ACP_I2STDM_IER;
				buf_reg = ACP_I2S_TX_RINGBUFSIZE;
				break;
			case I2S_HS_INSTANCE:
				water_val = ACP_HS_TX_INTR_WATERMARK_SIZE;
				reg_val = ACP_HSTDM_ITER;
				ier_val = ACP_HSTDM_IER;
				buf_reg = ACP_HS_TX_RINGBUFSIZE;
				break;
			default:
				dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
				return -EINVAL;
@@ -136,6 +220,12 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
				ier_val = ACP_I2STDM_IER;
				buf_reg = ACP_I2S_RX_RINGBUFSIZE;
				break;
			case I2S_HS_INSTANCE:
				water_val = ACP_HS_RX_INTR_WATERMARK_SIZE;
				reg_val = ACP_HSTDM_IRER;
				ier_val = ACP_HSTDM_IER;
				buf_reg = ACP_HS_RX_RINGBUFSIZE;
				break;
			default:
				dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
				return -EINVAL;
@@ -147,6 +237,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
		val = val | BIT(0);
		writel(val, adata->acp_base + reg_val);
		writel(1, adata->acp_base + ier_val);
		if (rsrc->soc_mclk)
			acp_set_i2s_clk(adata, dai->driver->id);
		return 0;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -159,6 +251,9 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
			case I2S_SP_INSTANCE:
				reg_val = ACP_I2STDM_ITER;
				break;
			case I2S_HS_INSTANCE:
				reg_val = ACP_HSTDM_ITER;
				break;
			default:
				dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
				return -EINVAL;
@@ -172,6 +267,9 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
			case I2S_SP_INSTANCE:
				reg_val = ACP_I2STDM_IRER;
				break;
			case I2S_HS_INSTANCE:
				reg_val = ACP_HSTDM_IRER;
				break;
			default:
				dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
				return -EINVAL;
@@ -187,6 +285,9 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
		if (!(readl(adata->acp_base + ACP_I2STDM_ITER) & BIT(0)) &&
		    !(readl(adata->acp_base + ACP_I2STDM_IRER) & BIT(0)))
			writel(0, adata->acp_base + ACP_I2STDM_IER);
		if (!(readl(adata->acp_base + ACP_HSTDM_ITER) & BIT(0)) &&
		    !(readl(adata->acp_base + ACP_HSTDM_IRER) & BIT(0)))
			writel(0, adata->acp_base + ACP_HSTDM_IER);
		return 0;
	default:
		return -EINVAL;
@@ -199,6 +300,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_resource *rsrc = adata->rsrc;
	struct acp_stream *stream = substream->runtime->private_data;
	u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
	u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
@@ -208,7 +310,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
	case I2S_SP_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_I2S_TX_DMA_SIZE;
			acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
			acp_fifo_addr = rsrc->sram_pte_offset +
						SP_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr =	ACP_I2S_TX_FIFOADDR;
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
@@ -217,7 +319,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
		} else {
			reg_dma_size = ACP_I2S_RX_DMA_SIZE;
			acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
			acp_fifo_addr = rsrc->sram_pte_offset +
						SP_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
@@ -228,7 +330,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
	case I2S_BT_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_BT_TX_DMA_SIZE;
			acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
			acp_fifo_addr = rsrc->sram_pte_offset +
						BT_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_TX_FIFOADDR;
			reg_fifo_size = ACP_BT_TX_FIFOSIZE;
@@ -237,7 +339,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
		} else {
			reg_dma_size = ACP_BT_RX_DMA_SIZE;
			acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
			acp_fifo_addr = rsrc->sram_pte_offset +
						BT_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_RX_FIFOADDR;
			reg_fifo_size = ACP_BT_RX_FIFOSIZE;
@@ -246,6 +348,27 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
		}
		break;
	case I2S_HS_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_HS_TX_DMA_SIZE;
			acp_fifo_addr = rsrc->sram_pte_offset +
				HS_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_HS_TX_FIFOADDR;
			reg_fifo_size = ACP_HS_TX_FIFOSIZE;

			phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
		} else {
			reg_dma_size = ACP_HS_RX_DMA_SIZE;
			acp_fifo_addr = rsrc->sram_pte_offset +
					HS_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_HS_RX_FIFOADDR;
			reg_fifo_size = ACP_HS_RX_FIFOSIZE;

			phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
		}
		break;
	default:
		dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
		return -EINVAL;
@@ -255,11 +378,15 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
	writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
	writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);

	ext_int_ctrl = readl(adata->acp_base + ACP_EXTERNAL_INTR_CNTL);
	ext_int_ctrl |= BIT(I2S_RX_THRESHOLD) | BIT(BT_RX_THRESHOLD)
			| BIT(I2S_TX_THRESHOLD) | BIT(BT_TX_THRESHOLD);
	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
	ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
			BIT(BT_RX_THRESHOLD(rsrc->offset)) |
			BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
			BIT(BT_TX_THRESHOLD(rsrc->offset)) |
			BIT(HS_RX_THRESHOLD(rsrc->offset)) |
			BIT(HS_TX_THRESHOLD(rsrc->offset));

	writel(ext_int_ctrl, adata->acp_base + ACP_EXTERNAL_INTR_CNTL);
	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));

	return 0;
}
@@ -268,32 +395,45 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d
{
	struct acp_stream *stream = substream->runtime->private_data;
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_resource *rsrc = adata->rsrc;
	unsigned int dir = substream->stream;
	unsigned int irq_bit = 0;

	switch (dai->driver->id) {
	case I2S_SP_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			irq_bit = BIT(I2S_TX_THRESHOLD);
			irq_bit = BIT(I2S_TX_THRESHOLD(rsrc->offset));
			stream->pte_offset = ACP_SRAM_SP_PB_PTE_OFFSET;
			stream->fifo_offset = SP_PB_FIFO_ADDR_OFFSET;
		} else {
			irq_bit = BIT(I2S_RX_THRESHOLD);
			irq_bit = BIT(I2S_RX_THRESHOLD(rsrc->offset));
			stream->pte_offset = ACP_SRAM_SP_CP_PTE_OFFSET;
			stream->fifo_offset = SP_CAPT_FIFO_ADDR_OFFSET;
		}
		break;
	case I2S_BT_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			irq_bit = BIT(BT_TX_THRESHOLD);
			irq_bit = BIT(BT_TX_THRESHOLD(rsrc->offset));
			stream->pte_offset = ACP_SRAM_BT_PB_PTE_OFFSET;
			stream->fifo_offset = BT_PB_FIFO_ADDR_OFFSET;
		} else {
			irq_bit = BIT(BT_RX_THRESHOLD);
			irq_bit = BIT(BT_RX_THRESHOLD(rsrc->offset));
			stream->pte_offset = ACP_SRAM_BT_CP_PTE_OFFSET;
			stream->fifo_offset = BT_CAPT_FIFO_ADDR_OFFSET;
		}
		break;
	case I2S_HS_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			irq_bit = BIT(HS_TX_THRESHOLD(rsrc->offset));
			stream->pte_offset = ACP_SRAM_HS_PB_PTE_OFFSET;
			stream->fifo_offset = HS_PB_FIFO_ADDR_OFFSET;
		} else {
			irq_bit = BIT(HS_RX_THRESHOLD(rsrc->offset));
			stream->pte_offset = ACP_SRAM_HS_CP_PTE_OFFSET;
			stream->fifo_offset = HS_CAPT_FIFO_ADDR_OFFSET;
		}
		break;
	default:
		dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
		return -EINVAL;
@@ -319,6 +459,7 @@ int asoc_acp_i2s_probe(struct snd_soc_dai *dai)
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_resource *rsrc = adata->rsrc;
	unsigned int val;

	if (!adata->acp_base) {
@@ -326,8 +467,8 @@ int asoc_acp_i2s_probe(struct snd_soc_dai *dai)
		return -EINVAL;
	}

	val = readl(adata->acp_base + ACP_I2S_PIN_CONFIG);
	if (val != I2S_MODE) {
	val = readl(adata->acp_base + rsrc->i2s_pin_cfg_offset);
	if (val != rsrc->i2s_mode) {
		dev_err(dev, "I2S Mode not supported val %x\n", val);
		return -EINVAL;
	}
+32 −0
Original line number Diff line number Diff line
@@ -47,6 +47,28 @@ static struct acp_card_drvdata rt5682s_rt1019_data = {
	.dmic_codec_id = DMIC,
};

static struct acp_card_drvdata max_nau8825_data = {
	.hs_cpu_id = I2S_HS,
	.amp_cpu_id = I2S_HS,
	.dmic_cpu_id = DMIC,
	.hs_codec_id = NAU8825,
	.amp_codec_id = MAX98360A,
	.dmic_codec_id = DMIC,
	.soc_mclk = true,
	.platform = REMBRANDT,
};

static struct acp_card_drvdata rt5682s_rt1019_rmb_data = {
	.hs_cpu_id = I2S_HS,
	.amp_cpu_id = I2S_HS,
	.dmic_cpu_id = DMIC,
	.hs_codec_id = RT5682S,
	.amp_codec_id = RT1019,
	.dmic_codec_id = DMIC,
	.soc_mclk = true,
	.platform = REMBRANDT,
};

static const struct snd_kcontrol_new acp_controls[] = {
	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
	SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -112,6 +134,14 @@ static const struct platform_device_id board_ids[] = {
		.name = "acp3xalc5682s1019",
		.driver_data = (kernel_ulong_t)&rt5682s_rt1019_data,
	},
	{
		.name = "rmb-nau8825-max",
		.driver_data = (kernel_ulong_t)&max_nau8825_data,
	},
	{
		.name = "rmb-rt5682s-rt1019",
		.driver_data = (kernel_ulong_t)&rt5682s_rt1019_rmb_data,
	},
	{ }
};
static struct platform_driver acp_asoc_audio = {
@@ -130,4 +160,6 @@ MODULE_DESCRIPTION("ACP chrome audio support");
MODULE_ALIAS("platform:acp3xalc56821019");
MODULE_ALIAS("platform:acp3xalc5682sm98360");
MODULE_ALIAS("platform:acp3xalc5682s1019");
MODULE_ALIAS("platform:rmb-nau8825-max");
MODULE_ALIAS("platform:rmb-rt5682s-rt1019");
MODULE_LICENSE("GPL v2");
+84 −20
Original line number Diff line number Diff line
@@ -313,9 +313,6 @@ static const struct snd_soc_ops acp_card_dmic_ops = {
SND_SOC_DAILINK_DEF(rt1019,
	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
			  COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
SND_SOC_DAILINK_DEF(rt1019_1,
		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:02", "rt1019-aif"),
		    COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));

static const struct snd_soc_dapm_route rt1019_map_lr[] = {
	{ "Left Spk", NULL, "Left SPO" },
@@ -333,17 +330,6 @@ static struct snd_soc_codec_conf rt1019_conf[] = {
	},
};

static struct snd_soc_codec_conf rt1019_1_conf[] = {
	{
		.dlc = COMP_CODEC_CONF("i2c-10EC1019:02"),
		.name_prefix = "Left",
	},
	{
		.dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
		.name_prefix = "Right",
	},
};

static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_card *card = rtd->card;
@@ -559,6 +545,12 @@ static struct snd_soc_dai_link_component platform_component[] = {
	}
};

static struct snd_soc_dai_link_component platform_rmb_component[] = {
	{
		.name = "acp_asoc_rembrandt.0",
	}
};

static struct snd_soc_dai_link_component sof_component[] = {
	{
		 .name = "0000:04:00.5",
@@ -567,6 +559,8 @@ static struct snd_soc_dai_link_component sof_component[] = {

SND_SOC_DAILINK_DEF(i2s_sp,
	DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp")));
SND_SOC_DAILINK_DEF(i2s_hs,
		    DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));
SND_SOC_DAILINK_DEF(sof_sp,
	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
SND_SOC_DAILINK_DEF(sof_hs,
@@ -716,10 +710,6 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
			links[i].init = acp_card_rt1019_init;
			card->codec_conf = rt1019_conf;
			card->num_configs = ARRAY_SIZE(rt1019_conf);
			links[i].codecs = rt1019_1;
			links[i].num_codecs = ARRAY_SIZE(rt1019_1);
			card->codec_conf = rt1019_1_conf;
			card->num_configs = ARRAY_SIZE(rt1019_1_conf);
		}
		i++;
	}
@@ -792,6 +782,40 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card)
		i++;
	}

	if (drv_data->hs_cpu_id == I2S_HS) {
		links[i].name = "acp-headset-codec";
		links[i].id = HEADSET_BE_ID;
		links[i].cpus = i2s_hs;
		links[i].num_cpus = ARRAY_SIZE(i2s_hs);
		if (drv_data->platform == REMBRANDT) {
			links[i].platforms = platform_rmb_component;
			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
		} else {
			links[i].platforms = platform_component;
			links[i].num_platforms = ARRAY_SIZE(platform_component);
		}
		links[i].dpcm_playback = 1;
		links[i].dpcm_capture = 1;
		if (!drv_data->hs_codec_id) {
			/* Use dummy codec if codec id not specified */
			links[i].codecs = dummy_codec;
			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
		}
		if (drv_data->hs_codec_id == NAU8825) {
			links[i].codecs = nau8825;
			links[i].num_codecs = ARRAY_SIZE(nau8825);
			links[i].init = acp_card_nau8825_init;
			links[i].ops = &acp_card_nau8825_ops;
		}
		if (drv_data->hs_codec_id == RT5682S) {
			links[i].codecs = rt5682s;
			links[i].num_codecs = ARRAY_SIZE(rt5682s);
			links[i].init = acp_card_rt5682s_init;
			links[i].ops = &acp_card_rt5682s_ops;
		}
		i++;
	}

	if (drv_data->amp_cpu_id == I2S_SP) {
		links[i].name = "acp-amp-codec";
		links[i].id = AMP_BE_ID;
@@ -822,6 +846,41 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card)
		i++;
	}

	if (drv_data->amp_cpu_id == I2S_HS) {
		links[i].name = "acp-amp-codec";
		links[i].id = AMP_BE_ID;
		links[i].cpus = i2s_hs;
		links[i].num_cpus = ARRAY_SIZE(i2s_hs);
		if (drv_data->platform == REMBRANDT) {
			links[i].platforms = platform_rmb_component;
			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
		} else {
			links[i].platforms = platform_component;
			links[i].num_platforms = ARRAY_SIZE(platform_component);
		}
		links[i].dpcm_playback = 1;
		if (!drv_data->amp_codec_id) {
			/* Use dummy codec if codec id not specified */
			links[i].codecs = dummy_codec;
			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
		}
		if (drv_data->amp_codec_id == MAX98360A) {
			links[i].codecs = max98360a;
			links[i].num_codecs = ARRAY_SIZE(max98360a);
			links[i].ops = &acp_card_maxim_ops;
			links[i].init = acp_card_maxim_init;
		}
		if (drv_data->amp_codec_id == RT1019) {
			links[i].codecs = rt1019;
			links[i].num_codecs = ARRAY_SIZE(rt1019);
			links[i].ops = &acp_card_rt1019_ops;
			links[i].init = acp_card_rt1019_init;
			card->codec_conf = rt1019_conf;
			card->num_configs = ARRAY_SIZE(rt1019_conf);
		}
		i++;
	}

	if (drv_data->dmic_cpu_id == DMIC) {
		links[i].name = "acp-dmic-codec";
		links[i].id = DMIC_BE_ID;
@@ -835,8 +894,13 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card)
		}
		links[i].cpus = pdm_dmic;
		links[i].num_cpus = ARRAY_SIZE(pdm_dmic);
		if (drv_data->platform == REMBRANDT) {
			links[i].platforms = platform_rmb_component;
			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
		} else {
			links[i].platforms = platform_component;
			links[i].num_platforms = ARRAY_SIZE(platform_component);
		}
		links[i].ops = &acp_card_dmic_ops;
		links[i].dpcm_capture = 1;
	}
Loading