File Index
Files and directories
Sign in
FILE

acp-mach-common.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/amd/acp/acp-mach-common.c C
   1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
   2//
   3// This file is provided under a dual BSD/GPLv2 license. When using or
   4// redistributing this file, you may do so under either license.
   5//
   6// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc.
   7//
   8// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
   9//	    Vijendar Mukunda <Vijendar.Mukunda@amd.com>
  10//
  11
  12/*
  13 * Machine Driver Interface for ACP HW block
  14 */
  15
  16#include <sound/core.h>
  17#include <sound/jack.h>
  18#include <sound/pcm_params.h>
  19#include <sound/soc-dapm.h>
  20#include <sound/soc.h>
  21#include <linux/input.h>
  22#include <linux/module.h>
  23
  24#include "../../codecs/rt5682.h"
  25#include "../../codecs/rt1019.h"
  26#include "../../codecs/rt5682s.h"
  27#include "../../codecs/nau8825.h"
  28#include "../../codecs/nau8821.h"
  29#include "acp-mach.h"
  30
  31#define PCO_PLAT_CLK 48000000
  32#define RT5682_PLL_FREQ (48000 * 512)
  33#define DUAL_CHANNEL	2
  34#define FOUR_CHANNEL	4
  35#define NAU8821_CODEC_DAI	"nau8821-hifi"
  36#define NAU8821_BCLK		1536000
  37#define NAU8821_FREQ_OUT	12288000
  38#define MAX98388_CODEC_DAI	"max98388-aif1"
  39
  40#define TDM_MODE_ENABLE 1
  41
  42const struct dmi_system_id acp_quirk_table[] = {
  43	{
  44		/* Google skyrim proto-0 */
  45		.matches = {
  46			DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"),
  47		},
  48		.driver_data = (void *)TDM_MODE_ENABLE,
  49	},
  50	{}
  51};
  52EXPORT_SYMBOL_GPL(acp_quirk_table);
  53
  54static const unsigned int channels[] = {
  55	DUAL_CHANNEL,
  56};
  57
  58static const unsigned int rates[] = {
  59	48000,
  60};
  61
  62static const struct snd_pcm_hw_constraint_list constraints_rates = {
  63	.count = ARRAY_SIZE(rates),
  64	.list  = rates,
  65	.mask = 0,
  66};
  67
  68static const struct snd_pcm_hw_constraint_list constraints_channels = {
  69	.count = ARRAY_SIZE(channels),
  70	.list = channels,
  71	.mask = 0,
  72};
  73
  74static int acp_clk_enable(struct acp_card_drvdata *drvdata,
  75			  unsigned int srate, unsigned int bclk_ratio)
  76{
  77	clk_set_rate(drvdata->wclk, srate);
  78	clk_set_rate(drvdata->bclk, srate * bclk_ratio);
  79
  80	return clk_prepare_enable(drvdata->wclk);
  81}
  82
  83/* Declare RT5682 codec components */
  84SND_SOC_DAILINK_DEF(rt5682,
  85	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
  86
  87static struct snd_soc_jack rt5682_jack;
  88static struct snd_soc_jack_pin rt5682_jack_pins[] = {
  89	{
  90		.pin = "Headphone Jack",
  91		.mask = SND_JACK_HEADPHONE,
  92	},
  93	{
  94		.pin = "Headset Mic",
  95		.mask = SND_JACK_MICROPHONE,
  96	},
  97};
  98
  99static const struct snd_kcontrol_new rt5682_controls[] = {
 100	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
 101	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 102};
 103
 104static const struct snd_soc_dapm_widget rt5682_widgets[] = {
 105	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 106	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 107};
 108
 109static const struct snd_soc_dapm_route rt5682_map[] = {
 110	{ "Headphone Jack", NULL, "HPOL" },
 111	{ "Headphone Jack", NULL, "HPOR" },
 112	{ "IN1P", NULL, "Headset Mic" },
 113};
 114
 115/* Define card ops for RT5682 CODEC */
 116static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
 117{
 118	struct snd_soc_card *card = rtd->card;
 119	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 120	struct acp_card_drvdata *drvdata = card->drvdata;
 121	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 122	struct snd_soc_component *component = codec_dai->component;
 123	int ret;
 124
 125	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
 126
 127	if (drvdata->hs_codec_id != RT5682)
 128		return -EINVAL;
 129
 130	drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
 131	if (IS_ERR(drvdata->wclk))
 132		return PTR_ERR(drvdata->wclk);
 133
 134	drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
 135	if (IS_ERR(drvdata->bclk))
 136		return PTR_ERR(drvdata->bclk);
 137
 138	ret = snd_soc_dapm_new_controls(dapm, rt5682_widgets,
 139					ARRAY_SIZE(rt5682_widgets));
 140	if (ret) {
 141		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
 142		return ret;
 143	}
 144
 145	ret = snd_soc_add_card_controls(card, rt5682_controls,
 146					ARRAY_SIZE(rt5682_controls));
 147	if (ret) {
 148		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
 149		return ret;
 150	}
 151
 152	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
 153					 SND_JACK_HEADSET | SND_JACK_LINEOUT |
 154					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 155					 SND_JACK_BTN_2 | SND_JACK_BTN_3,
 156					 &rt5682_jack,
 157					 rt5682_jack_pins,
 158					 ARRAY_SIZE(rt5682_jack_pins));
 159	if (ret) {
 160		dev_err(card->dev, "HP jack creation failed %d\n", ret);
 161		return ret;
 162	}
 163
 164	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 165	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
 166	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
 167	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 168
 169	ret = snd_soc_component_set_jack(component, &rt5682_jack, NULL);
 170	if (ret) {
 171		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
 172		return ret;
 173	}
 174
 175	return snd_soc_dapm_add_routes(dapm, rt5682_map, ARRAY_SIZE(rt5682_map));
 176}
 177
 178static int acp_card_hs_startup(struct snd_pcm_substream *substream)
 179{
 180	struct snd_pcm_runtime *runtime = substream->runtime;
 181	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 182	struct snd_soc_card *card = rtd->card;
 183	struct acp_card_drvdata *drvdata = card->drvdata;
 184	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 185	int ret;
 186	unsigned int fmt;
 187
 188	if (drvdata->tdm_mode)
 189		fmt = SND_SOC_DAIFMT_DSP_A;
 190	else
 191		fmt = SND_SOC_DAIFMT_I2S;
 192
 193	if (drvdata->soc_mclk)
 194		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
 195	else
 196		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
 197
 198	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
 199	if (ret < 0) {
 200		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
 201		return ret;
 202	}
 203
 204	runtime->hw.channels_max = DUAL_CHANNEL;
 205	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 206				      &constraints_channels);
 207	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 208				      &constraints_rates);
 209
 210	return ret;
 211}
 212
 213static void acp_card_shutdown(struct snd_pcm_substream *substream)
 214{
 215	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 216	struct snd_soc_card *card = rtd->card;
 217	struct acp_card_drvdata *drvdata = card->drvdata;
 218
 219	if (!drvdata->soc_mclk)
 220		clk_disable_unprepare(drvdata->wclk);
 221}
 222
 223static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream,
 224				      struct snd_pcm_hw_params *params)
 225{
 226	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 227	struct snd_soc_card *card = rtd->card;
 228	struct acp_card_drvdata *drvdata = card->drvdata;
 229	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 230	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 231	int ret;
 232	unsigned int fmt, srate, ch, format;
 233
 234	srate = params_rate(params);
 235	ch = params_channels(params);
 236	format = params_physical_width(params);
 237
 238	if (drvdata->tdm_mode)
 239		fmt = SND_SOC_DAIFMT_DSP_A;
 240	else
 241		fmt = SND_SOC_DAIFMT_I2S;
 242
 243	if (drvdata->soc_mclk)
 244		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
 245	else
 246		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
 247
 248	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
 249	if (ret && ret != -ENOTSUPP) {
 250		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
 251		return ret;
 252	}
 253
 254	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
 255	if (ret < 0) {
 256		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
 257		return ret;
 258	}
 259
 260	if (drvdata->tdm_mode) {
 261		/**
 262		 * As codec supports slot 0 and slot 1 for playback and capture.
 263		 */
 264		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
 265		if (ret && ret != -ENOTSUPP) {
 266			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
 267			return ret;
 268		}
 269
 270		ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
 271		if (ret < 0) {
 272			dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
 273			return ret;
 274		}
 275	}
 276
 277	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
 278				  PCO_PLAT_CLK, RT5682_PLL_FREQ);
 279	if (ret < 0) {
 280		dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
 281		return ret;
 282	}
 283
 284	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
 285				     RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
 286	if (ret < 0) {
 287		dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
 288		return ret;
 289	}
 290
 291	if (drvdata->tdm_mode) {
 292		ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
 293					  6144000, 49152000);
 294		if (ret < 0) {
 295			dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
 296			return ret;
 297		}
 298
 299		ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,
 300					     49152000, SND_SOC_CLOCK_IN);
 301		if (ret < 0) {
 302			dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
 303			return ret;
 304		}
 305	}
 306
 307	/* Set tdm/i2s1 master bclk ratio */
 308	ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
 309	if (ret < 0) {
 310		dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
 311		return ret;
 312	}
 313
 314	if (!drvdata->soc_mclk) {
 315		ret = acp_clk_enable(drvdata, srate, ch * format);
 316		if (ret < 0) {
 317			dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
 318			return ret;
 319		}
 320	}
 321
 322	return 0;
 323}
 324
 325static const struct snd_soc_ops acp_card_rt5682_ops = {
 326	.startup = acp_card_hs_startup,
 327	.shutdown = acp_card_shutdown,
 328	.hw_params = acp_card_rt5682_hw_params,
 329};
 330
 331/* Define RT5682S CODEC component*/
 332SND_SOC_DAILINK_DEF(rt5682s,
 333		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));
 334
 335static struct snd_soc_jack rt5682s_jack;
 336static struct snd_soc_jack_pin rt5682s_jack_pins[] = {
 337	{
 338		.pin = "Headphone Jack",
 339		.mask = SND_JACK_HEADPHONE,
 340	},
 341	{
 342		.pin = "Headset Mic",
 343		.mask = SND_JACK_MICROPHONE,
 344	},
 345};
 346
 347static const struct snd_kcontrol_new rt5682s_controls[] = {
 348	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
 349	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 350};
 351
 352static const struct snd_soc_dapm_widget rt5682s_widgets[] = {
 353	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 354	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 355};
 356
 357static const struct snd_soc_dapm_route rt5682s_map[] = {
 358	{ "Headphone Jack", NULL, "HPOL" },
 359	{ "Headphone Jack", NULL, "HPOR" },
 360	{ "IN1P", NULL, "Headset Mic" },
 361};
 362
 363static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
 364{
 365	struct snd_soc_card *card = rtd->card;
 366	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 367	struct acp_card_drvdata *drvdata = card->drvdata;
 368	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 369	struct snd_soc_component *component = codec_dai->component;
 370	int ret;
 371
 372	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
 373
 374	if (drvdata->hs_codec_id != RT5682S)
 375		return -EINVAL;
 376
 377	if (!drvdata->soc_mclk) {
 378		drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
 379		if (IS_ERR(drvdata->wclk))
 380			return PTR_ERR(drvdata->wclk);
 381
 382		drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
 383		if (IS_ERR(drvdata->bclk))
 384			return PTR_ERR(drvdata->bclk);
 385	}
 386
 387	ret = snd_soc_dapm_new_controls(dapm, rt5682s_widgets,
 388					ARRAY_SIZE(rt5682s_widgets));
 389	if (ret) {
 390		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
 391		return ret;
 392	}
 393
 394	ret = snd_soc_add_card_controls(card, rt5682s_controls,
 395					ARRAY_SIZE(rt5682s_controls));
 396	if (ret) {
 397		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
 398		return ret;
 399	}
 400
 401	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
 402					 SND_JACK_HEADSET | SND_JACK_LINEOUT |
 403					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 404					 SND_JACK_BTN_2 | SND_JACK_BTN_3,
 405					 &rt5682s_jack,
 406					 rt5682s_jack_pins,
 407					 ARRAY_SIZE(rt5682s_jack_pins));
 408	if (ret) {
 409		dev_err(card->dev, "HP jack creation failed %d\n", ret);
 410		return ret;
 411	}
 412
 413	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 414	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
 415	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
 416	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 417
 418	ret = snd_soc_component_set_jack(component, &rt5682s_jack, NULL);
 419	if (ret) {
 420		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
 421		return ret;
 422	}
 423
 424	return snd_soc_dapm_add_routes(dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map));
 425}
 426
 427static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream,
 428				      struct snd_pcm_hw_params *params)
 429{
 430	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 431	struct snd_soc_card *card = rtd->card;
 432	struct acp_card_drvdata *drvdata = card->drvdata;
 433	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 434	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 435	int ret;
 436	unsigned int fmt, srate, ch, format;
 437
 438	srate = params_rate(params);
 439	ch = params_channels(params);
 440	format = params_physical_width(params);
 441
 442	if (drvdata->tdm_mode)
 443		fmt = SND_SOC_DAIFMT_DSP_A;
 444	else
 445		fmt = SND_SOC_DAIFMT_I2S;
 446
 447	if (drvdata->soc_mclk)
 448		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
 449	else
 450		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
 451
 452	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
 453	if (ret && ret != -ENOTSUPP) {
 454		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
 455		return ret;
 456	}
 457
 458	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
 459	if (ret < 0) {
 460		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
 461		return ret;
 462	}
 463
 464	if (drvdata->tdm_mode) {
 465		/**
 466		 * As codec supports slot 0 and slot 1 for playback and capture.
 467		 */
 468		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
 469		if (ret && ret != -ENOTSUPP) {
 470			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
 471			return ret;
 472		}
 473
 474		ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
 475		if (ret < 0) {
 476			dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
 477			return ret;
 478		}
 479	}
 480
 481	ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
 482				  PCO_PLAT_CLK, RT5682_PLL_FREQ);
 483	if (ret < 0) {
 484		dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
 485		return ret;
 486	}
 487
 488	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
 489				     RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
 490	if (ret < 0) {
 491		dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
 492		return ret;
 493	}
 494
 495	if (drvdata->tdm_mode) {
 496		ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
 497					  6144000, 49152000);
 498		if (ret < 0) {
 499			dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
 500			return ret;
 501		}
 502
 503		ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,
 504					     49152000, SND_SOC_CLOCK_IN);
 505		if (ret < 0) {
 506			dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
 507			return ret;
 508		}
 509	}
 510
 511	/* Set tdm/i2s1 master bclk ratio */
 512	ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
 513	if (ret < 0) {
 514		dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
 515		return ret;
 516	}
 517
 518	clk_set_rate(drvdata->wclk, srate);
 519	clk_set_rate(drvdata->bclk, srate * ch * format);
 520	if (!drvdata->soc_mclk) {
 521		ret = acp_clk_enable(drvdata, srate, ch * format);
 522		if (ret < 0) {
 523			dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
 524			return ret;
 525		}
 526	}
 527
 528	return 0;
 529}
 530
 531static const struct snd_soc_ops acp_card_rt5682s_ops = {
 532	.startup = acp_card_hs_startup,
 533	.hw_params = acp_card_rt5682s_hw_params,
 534};
 535
 536static const unsigned int dmic_channels[] = {
 537	DUAL_CHANNEL, FOUR_CHANNEL,
 538};
 539
 540static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = {
 541	.count = ARRAY_SIZE(dmic_channels),
 542	.list = dmic_channels,
 543	.mask = 0,
 544};
 545
 546static int acp_card_dmic_startup(struct snd_pcm_substream *substream)
 547{
 548	struct snd_pcm_runtime *runtime = substream->runtime;
 549
 550	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 551				   &dmic_constraints_channels);
 552	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 553				   &constraints_rates);
 554
 555	return 0;
 556}
 557
 558static const struct snd_soc_ops acp_card_dmic_ops = {
 559	.startup = acp_card_dmic_startup,
 560};
 561
 562/* Declare RT1019 codec components */
 563SND_SOC_DAILINK_DEF(rt1019,
 564	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
 565			  COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
 566
 567static const struct snd_kcontrol_new rt1019_controls[] = {
 568	SOC_DAPM_PIN_SWITCH("Left Spk"),
 569	SOC_DAPM_PIN_SWITCH("Right Spk"),
 570};
 571
 572static const struct snd_soc_dapm_widget rt1019_widgets[] = {
 573	SND_SOC_DAPM_SPK("Left Spk", NULL),
 574	SND_SOC_DAPM_SPK("Right Spk", NULL),
 575};
 576
 577static const struct snd_soc_dapm_route rt1019_map_lr[] = {
 578	{ "Left Spk", NULL, "Left SPO" },
 579	{ "Right Spk", NULL, "Right SPO" },
 580};
 581
 582static struct snd_soc_codec_conf rt1019_conf[] = {
 583	{
 584		 .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
 585		 .name_prefix = "Left",
 586	},
 587	{
 588		 .dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
 589		 .name_prefix = "Right",
 590	},
 591};
 592
 593static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)
 594{
 595	struct snd_soc_card *card = rtd->card;
 596	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 597	struct acp_card_drvdata *drvdata = card->drvdata;
 598	int ret;
 599
 600	if (drvdata->amp_codec_id != RT1019)
 601		return -EINVAL;
 602
 603	ret = snd_soc_dapm_new_controls(dapm, rt1019_widgets,
 604					ARRAY_SIZE(rt1019_widgets));
 605	if (ret) {
 606		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
 607		return ret;
 608	}
 609
 610	ret = snd_soc_add_card_controls(card, rt1019_controls,
 611					ARRAY_SIZE(rt1019_controls));
 612	if (ret) {
 613		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
 614		return ret;
 615	}
 616
 617	return snd_soc_dapm_add_routes(dapm, rt1019_map_lr,
 618				       ARRAY_SIZE(rt1019_map_lr));
 619}
 620
 621static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
 622				     struct snd_pcm_hw_params *params)
 623{
 624	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 625	struct snd_soc_card *card = rtd->card;
 626	struct acp_card_drvdata *drvdata = card->drvdata;
 627	struct snd_soc_dai *codec_dai;
 628	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 629	int i, ret = 0;
 630	unsigned int fmt, srate, ch, format;
 631
 632	srate = params_rate(params);
 633	ch = params_channels(params);
 634	format = params_physical_width(params);
 635
 636	if (drvdata->amp_codec_id != RT1019)
 637		return -EINVAL;
 638
 639	if (drvdata->tdm_mode)
 640		fmt = SND_SOC_DAIFMT_DSP_A;
 641	else
 642		fmt = SND_SOC_DAIFMT_I2S;
 643
 644	if (drvdata->soc_mclk)
 645		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
 646	else
 647		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
 648
 649	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
 650	if (ret && ret != -ENOTSUPP) {
 651		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
 652		return ret;
 653	}
 654
 655	if (drvdata->tdm_mode) {
 656		/**
 657		 * As codec supports slot 2 and slot 3 for playback.
 658		 */
 659		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
 660		if (ret && ret != -ENOTSUPP) {
 661			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
 662			return ret;
 663		}
 664	}
 665
 666	for_each_rtd_codec_dais(rtd, i, codec_dai) {
 667		if (strcmp(codec_dai->name, "rt1019-aif"))
 668			continue;
 669
 670		if (drvdata->tdm_mode)
 671			ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
 672						  TDM_CHANNELS * format * srate, 256 * srate);
 673		else
 674			ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
 675						  ch * format * srate, 256 * srate);
 676
 677		if (ret < 0)
 678			return ret;
 679
 680		ret = snd_soc_dai_set_sysclk(codec_dai, RT1019_SCLK_S_PLL,
 681					     256 * srate, SND_SOC_CLOCK_IN);
 682		if (ret < 0)
 683			return ret;
 684
 685		if (drvdata->tdm_mode) {
 686			ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
 687							| SND_SOC_DAIFMT_NB_NF);
 688			if (ret < 0) {
 689				dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
 690				return ret;
 691			}
 692
 693			/**
 694			 * As codec supports slot 2 for left channel playback.
 695			 */
 696			if (!strcmp(codec_dai->component->name, "i2c-10EC1019:00")) {
 697				ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x4, 8, 16);
 698				if (ret < 0)
 699					break;
 700			}
 701
 702			/**
 703			 * As codec supports slot 3 for right channel playback.
 704			 */
 705			if (!strcmp(codec_dai->component->name, "i2c-10EC1019:01")) {
 706				ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x8, 8, 16);
 707				if (ret < 0)
 708					break;
 709			}
 710		}
 711	}
 712
 713	if (!drvdata->soc_mclk) {
 714		ret = acp_clk_enable(drvdata, srate, ch * format);
 715		if (ret < 0) {
 716			dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
 717			return ret;
 718		}
 719	}
 720
 721	return 0;
 722}
 723
 724static int acp_card_amp_startup(struct snd_pcm_substream *substream)
 725{
 726	struct snd_pcm_runtime *runtime = substream->runtime;
 727
 728	runtime->hw.channels_max = DUAL_CHANNEL;
 729	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 730				      &constraints_channels);
 731	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 732				      &constraints_rates);
 733
 734	return 0;
 735}
 736
 737static const struct snd_soc_ops acp_card_rt1019_ops = {
 738	.startup = acp_card_amp_startup,
 739	.shutdown = acp_card_shutdown,
 740	.hw_params = acp_card_rt1019_hw_params,
 741};
 742
 743/* Declare Maxim codec components */
 744SND_SOC_DAILINK_DEF(max98360a,
 745	DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));
 746
 747static const struct snd_kcontrol_new max98360a_controls[] = {
 748	SOC_DAPM_PIN_SWITCH("Spk"),
 749};
 750
 751static const struct snd_soc_dapm_widget max98360a_widgets[] = {
 752	SND_SOC_DAPM_SPK("Spk", NULL),
 753};
 754
 755static const struct snd_soc_dapm_route max98360a_map[] = {
 756	{"Spk", NULL, "Speaker"},
 757};
 758
 759static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)
 760{
 761	struct snd_soc_card *card = rtd->card;
 762	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 763	struct acp_card_drvdata *drvdata = card->drvdata;
 764	int ret;
 765
 766	if (drvdata->amp_codec_id != MAX98360A)
 767		return -EINVAL;
 768
 769	ret = snd_soc_dapm_new_controls(dapm, max98360a_widgets,
 770					ARRAY_SIZE(max98360a_widgets));
 771	if (ret) {
 772		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
 773		return ret;
 774	}
 775
 776	ret = snd_soc_add_card_controls(card, max98360a_controls,
 777					ARRAY_SIZE(max98360a_controls));
 778	if (ret) {
 779		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
 780		return ret;
 781	}
 782
 783	return snd_soc_dapm_add_routes(dapm, max98360a_map,
 784				       ARRAY_SIZE(max98360a_map));
 785}
 786
 787static int acp_card_maxim_hw_params(struct snd_pcm_substream *substream,
 788				    struct snd_pcm_hw_params *params)
 789{
 790	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 791	struct snd_soc_card *card = rtd->card;
 792	struct acp_card_drvdata *drvdata = card->drvdata;
 793	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 794	unsigned int fmt, srate, ch, format;
 795	int ret;
 796
 797	srate = params_rate(params);
 798	ch = params_channels(params);
 799	format = params_physical_width(params);
 800
 801	if (drvdata->tdm_mode)
 802		fmt = SND_SOC_DAIFMT_DSP_A;
 803	else
 804		fmt = SND_SOC_DAIFMT_I2S;
 805
 806	if (drvdata->soc_mclk)
 807		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
 808	else
 809		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
 810
 811	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
 812	if (ret && ret != -ENOTSUPP) {
 813		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
 814		return ret;
 815	}
 816
 817	if (drvdata->tdm_mode) {
 818		/**
 819		 * As codec supports slot 2 and slot 3 for playback.
 820		 */
 821		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
 822		if (ret && ret != -ENOTSUPP) {
 823			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
 824			return ret;
 825		}
 826	}
 827
 828	if (!drvdata->soc_mclk) {
 829		ret = acp_clk_enable(drvdata, srate, ch * format);
 830		if (ret < 0) {
 831			dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
 832			return ret;
 833		}
 834	}
 835	return 0;
 836}
 837
 838static const struct snd_soc_ops acp_card_maxim_ops = {
 839	.startup = acp_card_amp_startup,
 840	.shutdown = acp_card_shutdown,
 841	.hw_params = acp_card_maxim_hw_params,
 842};
 843
 844SND_SOC_DAILINK_DEF(max98388,
 845		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", MAX98388_CODEC_DAI),
 846				       COMP_CODEC("i2c-ADS8388:01", MAX98388_CODEC_DAI)));
 847
 848static const struct snd_kcontrol_new max98388_controls[] = {
 849	SOC_DAPM_PIN_SWITCH("Left Spk"),
 850	SOC_DAPM_PIN_SWITCH("Right Spk"),
 851};
 852
 853static const struct snd_soc_dapm_widget max98388_widgets[] = {
 854	SND_SOC_DAPM_SPK("Left Spk", NULL),
 855	SND_SOC_DAPM_SPK("Right Spk", NULL),
 856};
 857
 858static const struct snd_soc_dapm_route max98388_map[] = {
 859	{ "Left Spk", NULL, "Left BE_OUT" },
 860	{ "Right Spk", NULL, "Right BE_OUT" },
 861};
 862
 863static struct snd_soc_codec_conf max98388_conf[] = {
 864	{
 865		.dlc = COMP_CODEC_CONF("i2c-ADS8388:00"),
 866		.name_prefix = "Left",
 867	},
 868	{
 869		.dlc = COMP_CODEC_CONF("i2c-ADS8388:01"),
 870		.name_prefix = "Right",
 871	},
 872};
 873
 874static const unsigned int max98388_format[] = {16};
 875
 876static struct snd_pcm_hw_constraint_list constraints_sample_bits_max = {
 877	.list = max98388_format,
 878	.count = ARRAY_SIZE(max98388_format),
 879};
 880
 881static int acp_card_max98388_startup(struct snd_pcm_substream *substream)
 882{
 883	struct snd_pcm_runtime *runtime = substream->runtime;
 884
 885	runtime->hw.channels_max = DUAL_CHANNEL;
 886	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 887				   &constraints_channels);
 888	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 889				   &constraints_rates);
 890	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
 891				   &constraints_sample_bits_max);
 892
 893	return 0;
 894}
 895
 896static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd)
 897{
 898	struct snd_soc_card *card = rtd->card;
 899	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 900	struct acp_card_drvdata *drvdata = card->drvdata;
 901	int ret;
 902
 903	if (drvdata->amp_codec_id != MAX98388)
 904		return -EINVAL;
 905
 906	ret = snd_soc_dapm_new_controls(dapm, max98388_widgets,
 907					ARRAY_SIZE(max98388_widgets));
 908
 909	if (ret) {
 910		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
 911		/* Don't need to add routes if widget addition failed */
 912		return ret;
 913	}
 914
 915	ret = snd_soc_add_card_controls(card, max98388_controls,
 916					ARRAY_SIZE(max98388_controls));
 917	if (ret) {
 918		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
 919		return ret;
 920	}
 921
 922	return snd_soc_dapm_add_routes(dapm, max98388_map,
 923				       ARRAY_SIZE(max98388_map));
 924}
 925
 926static int acp_max98388_hw_params(struct snd_pcm_substream *substream,
 927				  struct snd_pcm_hw_params *params)
 928{
 929	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 930	struct snd_soc_card *card = rtd->card;
 931	struct snd_soc_dai *codec_dai =
 932			snd_soc_card_get_codec_dai(card,
 933						   MAX98388_CODEC_DAI);
 934	int ret;
 935
 936	ret = snd_soc_dai_set_fmt(codec_dai,
 937				  SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_I2S |
 938				  SND_SOC_DAIFMT_NB_NF);
 939	if (ret < 0)
 940		return ret;
 941
 942	return ret;
 943}
 944
 945static const struct snd_soc_ops acp_max98388_ops = {
 946	.startup = acp_card_max98388_startup,
 947	.hw_params = acp_max98388_hw_params,
 948};
 949
 950/* Declare nau8825 codec components */
 951SND_SOC_DAILINK_DEF(nau8825,
 952		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));
 953
 954static struct snd_soc_jack nau8825_jack;
 955static struct snd_soc_jack_pin nau8825_jack_pins[] = {
 956	{
 957		.pin = "Headphone Jack",
 958		.mask = SND_JACK_HEADPHONE,
 959	},
 960	{
 961		.pin = "Headset Mic",
 962		.mask = SND_JACK_MICROPHONE,
 963	},
 964};
 965
 966static const struct snd_kcontrol_new nau8825_controls[] = {
 967	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
 968	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 969};
 970
 971static const struct snd_soc_dapm_widget nau8825_widgets[] = {
 972	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 973	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 974};
 975
 976static const struct snd_soc_dapm_route nau8825_map[] = {
 977	{ "Headphone Jack", NULL, "HPOL" },
 978	{ "Headphone Jack", NULL, "HPOR" },
 979};
 980
 981static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)
 982{
 983	struct snd_soc_card *card = rtd->card;
 984	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 985	struct acp_card_drvdata *drvdata = card->drvdata;
 986	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 987	struct snd_soc_component *component = codec_dai->component;
 988	int ret;
 989
 990	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
 991
 992	if (drvdata->hs_codec_id != NAU8825)
 993		return -EINVAL;
 994
 995	ret = snd_soc_dapm_new_controls(dapm, nau8825_widgets,
 996					ARRAY_SIZE(nau8825_widgets));
 997	if (ret) {
 998		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
 999		return ret;
1000	}
1001
1002	ret = snd_soc_add_card_controls(card, nau8825_controls,
1003					ARRAY_SIZE(nau8825_controls));
1004	if (ret) {
1005		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
1006		return ret;
1007	}
1008
1009	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
1010					 SND_JACK_HEADSET | SND_JACK_LINEOUT |
1011					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1012					 SND_JACK_BTN_2 | SND_JACK_BTN_3,
1013					 &nau8825_jack,
1014					 nau8825_jack_pins,
1015					 ARRAY_SIZE(nau8825_jack_pins));
1016	if (ret) {
1017		dev_err(card->dev, "HP jack creation failed %d\n", ret);
1018		return ret;
1019	}
1020
1021	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
1022	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
1023	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
1024	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
1025
1026	ret = snd_soc_component_set_jack(component, &nau8825_jack, NULL);
1027	if (ret) {
1028		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
1029		return ret;
1030	}
1031
1032	return snd_soc_dapm_add_routes(dapm, nau8825_map, ARRAY_SIZE(nau8825_map));
1033}
1034
1035static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,
1036				 struct snd_pcm_hw_params *params)
1037{
1038	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1039	struct snd_soc_card *card = rtd->card;
1040	struct acp_card_drvdata *drvdata = card->drvdata;
1041	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
1042	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
1043	int ret;
1044	unsigned int fmt;
1045
1046	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS,
1047				     (48000 * 256), SND_SOC_CLOCK_IN);
1048	if (ret < 0)
1049		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
1050
1051	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
1052				  params_rate(params) * 256);
1053	if (ret < 0) {
1054		dev_err(rtd->dev, "can't set FLL: %d\n", ret);
1055		return ret;
1056	}
1057
1058	if (drvdata->tdm_mode)
1059		fmt = SND_SOC_DAIFMT_DSP_A;
1060	else
1061		fmt = SND_SOC_DAIFMT_I2S;
1062
1063	if (drvdata->soc_mclk)
1064		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
1065	else
1066		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
1067
1068	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
1069	if (ret && ret != -ENOTSUPP) {
1070		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
1071		return ret;
1072	}
1073
1074	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
1075	if (ret < 0) {
1076		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
1077		return ret;
1078	}
1079
1080	if (drvdata->tdm_mode) {
1081		/**
1082		 * As codec supports slot 4 and slot 5 for playback and slot 6 for capture.
1083		 */
1084		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x30, 0xC0, 8, 16);
1085		if (ret && ret != -ENOTSUPP) {
1086			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
1087			return ret;
1088		}
1089
1090		ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x40, 0x30, 8, 16);
1091		if (ret < 0) {
1092			dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
1093			return ret;
1094		}
1095	}
1096	return ret;
1097}
1098
1099static int acp_nau8825_startup(struct snd_pcm_substream *substream)
1100{
1101	struct snd_pcm_runtime *runtime = substream->runtime;
1102
1103	runtime->hw.channels_max = 2;
1104	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1105				   &constraints_channels);
1106
1107	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
1108	snd_pcm_hw_constraint_list(runtime, 0,
1109				   SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
1110	return 0;
1111}
1112
1113static const struct snd_soc_ops acp_card_nau8825_ops = {
1114	.startup =  acp_nau8825_startup,
1115	.hw_params = acp_nau8825_hw_params,
1116};
1117
1118static int platform_clock_control(struct snd_soc_dapm_widget *w,
1119				  struct snd_kcontrol *k, int  event)
1120{
1121	struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm);
1122	struct snd_soc_dai *codec_dai;
1123	int ret = 0;
1124
1125	codec_dai = snd_soc_card_get_codec_dai(card, NAU8821_CODEC_DAI);
1126	if (!codec_dai) {
1127		dev_err(card->dev, "Codec dai not found\n");
1128		return -EIO;
1129	}
1130
1131	if (SND_SOC_DAPM_EVENT_OFF(event)) {
1132		ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL,
1133					     0, SND_SOC_CLOCK_IN);
1134		if (ret < 0) {
1135			dev_err(card->dev, "set sysclk err = %d\n", ret);
1136			return -EIO;
1137		}
1138	} else {
1139		ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
1140					     SND_SOC_CLOCK_IN);
1141		if (ret < 0)
1142			dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);
1143		ret = snd_soc_dai_set_pll(codec_dai, 0, 0, NAU8821_BCLK,
1144					  NAU8821_FREQ_OUT);
1145		if (ret < 0)
1146			dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
1147	}
1148	return ret;
1149}
1150
1151static struct snd_soc_jack nau8821_jack;
1152static struct snd_soc_jack_pin nau8821_jack_pins[] = {
1153	{
1154		.pin = "Headphone Jack",
1155		.mask = SND_JACK_HEADPHONE,
1156	},
1157	{
1158		.pin = "Headset Mic",
1159		.mask = SND_JACK_MICROPHONE,
1160	},
1161};
1162
1163static const struct snd_kcontrol_new nau8821_controls[] = {
1164	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
1165	SOC_DAPM_PIN_SWITCH("Headset Mic"),
1166};
1167
1168static const struct snd_soc_dapm_widget nau8821_widgets[] = {
1169	SND_SOC_DAPM_HP("Headphone Jack", NULL),
1170	SND_SOC_DAPM_MIC("Headset Mic", NULL),
1171	SND_SOC_DAPM_MIC("Int Mic", NULL),
1172	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
1173			    platform_clock_control, SND_SOC_DAPM_PRE_PMU |
1174			    SND_SOC_DAPM_POST_PMD),
1175};
1176
1177static const struct snd_soc_dapm_route nau8821_audio_route[] = {
1178	/* HP jack connectors - unknown if we have jack detection */
1179	{ "Headphone Jack", NULL, "HPOL" },
1180	{ "Headphone Jack", NULL, "HPOR" },
1181	{ "MICL", NULL, "Headset Mic" },
1182	{ "MICR", NULL, "Headset Mic" },
1183	{ "DMIC", NULL, "Int Mic" },
1184	{ "Headphone Jack", NULL, "Platform Clock" },
1185	{ "Headset Mic", NULL, "Platform Clock" },
1186	{ "Int Mic", NULL, "Platform Clock" },
1187};
1188
1189static const unsigned int nau8821_format[] = {16};
1190
1191static struct snd_pcm_hw_constraint_list constraints_sample_bits = {
1192	.list = nau8821_format,
1193	.count = ARRAY_SIZE(nau8821_format),
1194};
1195
1196static int acp_8821_init(struct snd_soc_pcm_runtime *rtd)
1197{
1198	struct snd_soc_card *card = rtd->card;
1199	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
1200	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
1201	struct snd_soc_component *component = codec_dai->component;
1202	int ret;
1203
1204	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
1205
1206	ret = snd_soc_dapm_new_controls(dapm, nau8821_widgets,
1207					ARRAY_SIZE(nau8821_widgets));
1208	if (ret) {
1209		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
1210		// Don't need to add routes if widget addition failed
1211		return ret;
1212	}
1213
1214	ret = snd_soc_add_card_controls(card, nau8821_controls,
1215					ARRAY_SIZE(nau8821_controls));
1216	if (ret) {
1217		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
1218		return ret;
1219	}
1220
1221	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
1222					 SND_JACK_HEADSET | SND_JACK_LINEOUT |
1223					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1224					 SND_JACK_BTN_2 | SND_JACK_BTN_3,
1225					 &nau8821_jack,
1226					 nau8821_jack_pins,
1227					 ARRAY_SIZE(nau8821_jack_pins));
1228	if (ret) {
1229		dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
1230		return ret;
1231	}
1232
1233	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
1234	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
1235	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
1236	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
1237
1238	nau8821_enable_jack_detect(component, &nau8821_jack);
1239
1240	return snd_soc_dapm_add_routes(dapm, nau8821_audio_route,
1241				       ARRAY_SIZE(nau8821_audio_route));
1242}
1243
1244static int acp_8821_startup(struct snd_pcm_substream *substream)
1245{
1246	struct snd_pcm_runtime *runtime = substream->runtime;
1247
1248	runtime->hw.channels_max = DUAL_CHANNEL;
1249	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1250				   &constraints_channels);
1251	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1252				   &constraints_rates);
1253	snd_pcm_hw_constraint_list(substream->runtime, 0,
1254				   SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1255				   &constraints_sample_bits);
1256	return 0;
1257}
1258
1259static int acp_nau8821_hw_params(struct snd_pcm_substream *substream,
1260				 struct snd_pcm_hw_params *params)
1261{
1262	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1263	struct snd_soc_card *card = rtd->card;
1264	struct acp_card_drvdata *drvdata = card->drvdata;
1265	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
1266	int ret;
1267	unsigned int fmt;
1268
1269	if (drvdata->soc_mclk)
1270		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
1271	else
1272		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
1273
1274	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
1275	if (ret < 0) {
1276		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
1277		return ret;
1278	}
1279
1280	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
1281				     SND_SOC_CLOCK_IN);
1282	if (ret < 0)
1283		dev_err(card->dev, "can't set FS clock %d\n", ret);
1284	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params),
1285				  params_rate(params) * 256);
1286	if (ret < 0)
1287		dev_err(card->dev, "can't set FLL: %d\n", ret);
1288
1289	return ret;
1290}
1291
1292static const struct snd_soc_ops acp_8821_ops = {
1293	.startup = acp_8821_startup,
1294	.hw_params = acp_nau8821_hw_params,
1295};
1296
1297SND_SOC_DAILINK_DEF(nau8821,
1298		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00",
1299						  NAU8821_CODEC_DAI)));
1300
1301/* Declare DMIC codec components */
1302SND_SOC_DAILINK_DEF(dmic_codec,
1303		DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
1304
1305/* Declare ACP CPU components */
1306static struct snd_soc_dai_link_component platform_component[] = {
1307	{
1308		 .name = "acp_asoc_renoir.0",
1309	}
1310};
1311
1312static struct snd_soc_dai_link_component platform_rmb_component[] = {
1313	{
1314		.name = "acp_asoc_rembrandt.0",
1315	}
1316};
1317
1318static struct snd_soc_dai_link_component platform_acp63_component[] = {
1319	{
1320		.name = "acp_asoc_acp63.0",
1321	}
1322};
1323
1324static struct snd_soc_dai_link_component platform_acp70_component[] = {
1325	{
1326		.name = "acp_asoc_acp70.0",
1327	}
1328};
1329
1330static struct snd_soc_dai_link_component sof_component[] = {
1331	{
1332		 .name = "0000:04:00.5",
1333	}
1334};
1335
1336SND_SOC_DAILINK_DEF(i2s_sp,
1337	DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp")));
1338SND_SOC_DAILINK_DEF(i2s_hs,
1339		    DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));
1340SND_SOC_DAILINK_DEF(sof_sp,
1341	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
1342SND_SOC_DAILINK_DEF(sof_sp_virtual,
1343	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp-virtual")));
1344SND_SOC_DAILINK_DEF(sof_hs,
1345		    DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));
1346SND_SOC_DAILINK_DEF(sof_hs_virtual,
1347	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual")));
1348SND_SOC_DAILINK_DEF(sof_bt,
1349		    DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-bt")));
1350SND_SOC_DAILINK_DEF(sof_dmic,
1351	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
1352SND_SOC_DAILINK_DEF(pdm_dmic,
1353	DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic")));
1354
1355static int acp_rtk_set_bias_level(struct snd_soc_card *card,
1356				  struct snd_soc_dapm_context *dapm,
1357				  enum snd_soc_bias_level level)
1358{
1359	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
1360	struct acp_card_drvdata *drvdata = card->drvdata;
1361	int ret = 0;
1362
1363	if (!component)
1364		return 0;
1365
1366	if (strncmp(component->name, "i2c-RTL5682", 11) &&
1367	    strncmp(component->name, "i2c-10EC1019", 12))
1368		return 0;
1369
1370	/*
1371	 * For Realtek's codec and amplifier components,
1372	 * the lrck and bclk must be enabled brfore their all dapms be powered on,
1373	 * and must be disabled after their all dapms be powered down
1374	 * to avoid any pop.
1375	 */
1376	switch (level) {
1377	case SND_SOC_BIAS_STANDBY:
1378		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
1379
1380			/* Increase bclk's enable_count */
1381			ret = clk_prepare_enable(drvdata->bclk);
1382			if (ret < 0)
1383				dev_err(component->dev, "Failed to enable bclk %d\n", ret);
1384		} else {
1385			/*
1386			 * Decrease bclk's enable_count.
1387			 * While the enable_count is 0, the bclk would be closed.
1388			 */
1389			clk_disable_unprepare(drvdata->bclk);
1390		}
1391		break;
1392	default:
1393		break;
1394	}
1395
1396	return ret;
1397}
1398
1399int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
1400{
1401	struct snd_soc_dai_link *links;
1402	struct device *dev = card->dev;
1403	struct acp_card_drvdata *drv_data = card->drvdata;
1404	int i = 0, num_links = 0;
1405
1406	if (drv_data->hs_cpu_id)
1407		num_links++;
1408	if (drv_data->bt_cpu_id)
1409		num_links++;
1410	if (drv_data->amp_cpu_id)
1411		num_links++;
1412	if (drv_data->dmic_cpu_id)
1413		num_links++;
1414
1415	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
1416	if (!links)
1417		return -ENOMEM;
1418
1419	if (drv_data->hs_cpu_id == I2S_SP) {
1420		links[i].name = "acp-headset-codec";
1421		links[i].id = HEADSET_BE_ID;
1422		links[i].cpus = sof_sp;
1423		links[i].num_cpus = ARRAY_SIZE(sof_sp);
1424		links[i].platforms = sof_component;
1425		links[i].num_platforms = ARRAY_SIZE(sof_component);
1426		links[i].nonatomic = true;
1427		links[i].no_pcm = 1;
1428		if (!drv_data->hs_codec_id) {
1429			/* Use dummy codec if codec id not specified */
1430			links[i].codecs = &snd_soc_dummy_dlc;
1431			links[i].num_codecs = 1;
1432		}
1433		if (drv_data->hs_codec_id == RT5682) {
1434			links[i].codecs = rt5682;
1435			links[i].num_codecs = ARRAY_SIZE(rt5682);
1436			links[i].init = acp_card_rt5682_init;
1437			links[i].ops = &acp_card_rt5682_ops;
1438		}
1439		if (drv_data->hs_codec_id == RT5682S) {
1440			links[i].codecs = rt5682s;
1441			links[i].num_codecs = ARRAY_SIZE(rt5682s);
1442			links[i].init = acp_card_rt5682s_init;
1443			links[i].ops = &acp_card_rt5682s_ops;
1444		}
1445		if (drv_data->hs_codec_id == NAU8821) {
1446			links[i].codecs = nau8821;
1447			links[i].num_codecs = ARRAY_SIZE(nau8821);
1448			links[i].init = acp_8821_init;
1449			links[i].ops = &acp_8821_ops;
1450		}
1451		i++;
1452	}
1453
1454	if (drv_data->hs_cpu_id == I2S_HS) {
1455		links[i].name = "acp-headset-codec";
1456		links[i].id = HEADSET_BE_ID;
1457		links[i].cpus = sof_hs;
1458		links[i].num_cpus = ARRAY_SIZE(sof_hs);
1459		links[i].platforms = sof_component;
1460		links[i].num_platforms = ARRAY_SIZE(sof_component);
1461		links[i].nonatomic = true;
1462		links[i].no_pcm = 1;
1463		if (!drv_data->hs_codec_id) {
1464			/* Use dummy codec if codec id not specified */
1465			links[i].codecs = &snd_soc_dummy_dlc;
1466			links[i].num_codecs = 1;
1467		}
1468		if (drv_data->hs_codec_id == NAU8825) {
1469			links[i].codecs = nau8825;
1470			links[i].num_codecs = ARRAY_SIZE(nau8825);
1471			links[i].init = acp_card_nau8825_init;
1472			links[i].ops = &acp_card_nau8825_ops;
1473		}
1474		if (drv_data->hs_codec_id == RT5682S) {
1475			links[i].codecs = rt5682s;
1476			links[i].num_codecs = ARRAY_SIZE(rt5682s);
1477			links[i].init = acp_card_rt5682s_init;
1478			links[i].ops = &acp_card_rt5682s_ops;
1479		}
1480		i++;
1481	}
1482
1483	if (drv_data->amp_cpu_id == I2S_SP) {
1484		links[i].name = "acp-amp-codec";
1485		links[i].id = AMP_BE_ID;
1486		if (drv_data->acp_rev == ACP_RN_PCI_ID) {
1487			links[i].cpus = sof_sp;
1488			links[i].num_cpus = ARRAY_SIZE(sof_sp);
1489		} else {
1490			links[i].cpus = sof_sp_virtual;
1491			links[i].num_cpus = ARRAY_SIZE(sof_sp_virtual);
1492		}
1493		links[i].platforms = sof_component;
1494		links[i].num_platforms = ARRAY_SIZE(sof_component);
1495		links[i].playback_only = 1;
1496		links[i].nonatomic = true;
1497		links[i].no_pcm = 1;
1498		if (!drv_data->amp_codec_id) {
1499			/* Use dummy codec if codec id not specified */
1500			links[i].codecs = &snd_soc_dummy_dlc;
1501			links[i].num_codecs = 1;
1502		}
1503		if (drv_data->amp_codec_id == RT1019) {
1504			links[i].codecs = rt1019;
1505			links[i].num_codecs = ARRAY_SIZE(rt1019);
1506			links[i].ops = &acp_card_rt1019_ops;
1507			links[i].init = acp_card_rt1019_init;
1508			card->codec_conf = rt1019_conf;
1509			card->num_configs = ARRAY_SIZE(rt1019_conf);
1510		}
1511		if (drv_data->amp_codec_id == MAX98360A) {
1512			links[i].codecs = max98360a;
1513			links[i].num_codecs = ARRAY_SIZE(max98360a);
1514			links[i].ops = &acp_card_maxim_ops;
1515			links[i].init = acp_card_maxim_init;
1516		}
1517		i++;
1518	}
1519
1520	if (drv_data->amp_cpu_id == I2S_HS) {
1521		links[i].name = "acp-amp-codec";
1522		links[i].id = AMP_BE_ID;
1523		links[i].cpus = sof_hs_virtual;
1524		links[i].num_cpus = ARRAY_SIZE(sof_hs_virtual);
1525		links[i].platforms = sof_component;
1526		links[i].num_platforms = ARRAY_SIZE(sof_component);
1527		links[i].playback_only = 1;
1528		links[i].nonatomic = true;
1529		links[i].no_pcm = 1;
1530		if (!drv_data->amp_codec_id) {
1531			/* Use dummy codec if codec id not specified */
1532			links[i].codecs = &snd_soc_dummy_dlc;
1533			links[i].num_codecs = 1;
1534		}
1535		if (drv_data->amp_codec_id == MAX98360A) {
1536			links[i].codecs = max98360a;
1537			links[i].num_codecs = ARRAY_SIZE(max98360a);
1538			links[i].ops = &acp_card_maxim_ops;
1539			links[i].init = acp_card_maxim_init;
1540		}
1541		if (drv_data->amp_codec_id == MAX98388) {
1542			links[i].playback_only = 0;
1543			links[i].codecs = max98388;
1544			links[i].num_codecs = ARRAY_SIZE(max98388);
1545			links[i].ops = &acp_max98388_ops;
1546			links[i].init = acp_card_max98388_init;
1547			card->codec_conf = max98388_conf;
1548			card->num_configs = ARRAY_SIZE(max98388_conf);
1549		}
1550		if (drv_data->amp_codec_id == RT1019) {
1551			links[i].codecs = rt1019;
1552			links[i].num_codecs = ARRAY_SIZE(rt1019);
1553			links[i].ops = &acp_card_rt1019_ops;
1554			links[i].init = acp_card_rt1019_init;
1555			card->codec_conf = rt1019_conf;
1556			card->num_configs = ARRAY_SIZE(rt1019_conf);
1557		}
1558		i++;
1559	}
1560
1561	if (drv_data->bt_cpu_id == I2S_BT) {
1562		links[i].name = "acp-bt-codec";
1563		links[i].id = BT_BE_ID;
1564		links[i].cpus = sof_bt;
1565		links[i].num_cpus = ARRAY_SIZE(sof_bt);
1566		links[i].platforms = sof_component;
1567		links[i].num_platforms = ARRAY_SIZE(sof_component);
1568		links[i].nonatomic = true;
1569		links[i].no_pcm = 1;
1570		if (!drv_data->bt_codec_id) {
1571			/* Use dummy codec if codec id not specified */
1572			links[i].codecs = &snd_soc_dummy_dlc;
1573			links[i].num_codecs = 1;
1574		}
1575		i++;
1576	}
1577
1578	if (drv_data->dmic_cpu_id == DMIC) {
1579		links[i].name = "acp-dmic-codec";
1580		links[i].id = DMIC_BE_ID;
1581		links[i].codecs = dmic_codec;
1582		links[i].num_codecs = ARRAY_SIZE(dmic_codec);
1583		links[i].cpus = sof_dmic;
1584		links[i].num_cpus = ARRAY_SIZE(sof_dmic);
1585		links[i].platforms = sof_component;
1586		links[i].num_platforms = ARRAY_SIZE(sof_component);
1587		links[i].capture_only = 1;
1588		links[i].nonatomic = true;
1589		links[i].no_pcm = 1;
1590	}
1591
1592	card->dai_link = links;
1593	card->num_links = num_links;
1594	card->set_bias_level = acp_rtk_set_bias_level;
1595
1596	return 0;
1597}
1598EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, "SND_SOC_AMD_MACH");
1599
1600int acp_legacy_dai_links_create(struct snd_soc_card *card)
1601{
1602	struct snd_soc_dai_link *links;
1603	struct device *dev = card->dev;
1604	struct acp_card_drvdata *drv_data = card->drvdata;
1605	int i = 0, num_links = 0;
1606	int rc;
1607
1608	if (drv_data->hs_cpu_id)
1609		num_links++;
1610	if (drv_data->amp_cpu_id)
1611		num_links++;
1612	if (drv_data->dmic_cpu_id)
1613		num_links++;
1614
1615	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
1616	if (!links)
1617		return -ENOMEM;
1618
1619	if (drv_data->hs_cpu_id == I2S_SP) {
1620		links[i].name = "acp-headset-codec";
1621		links[i].id = HEADSET_BE_ID;
1622		links[i].cpus = i2s_sp;
1623		links[i].num_cpus = ARRAY_SIZE(i2s_sp);
1624		links[i].platforms = platform_component;
1625		links[i].num_platforms = ARRAY_SIZE(platform_component);
1626		if (!drv_data->hs_codec_id) {
1627			/* Use dummy codec if codec id not specified */
1628			links[i].codecs = &snd_soc_dummy_dlc;
1629			links[i].num_codecs = 1;
1630		}
1631		if (drv_data->hs_codec_id == RT5682) {
1632			links[i].codecs = rt5682;
1633			links[i].num_codecs = ARRAY_SIZE(rt5682);
1634			links[i].init = acp_card_rt5682_init;
1635			links[i].ops = &acp_card_rt5682_ops;
1636		}
1637		if (drv_data->hs_codec_id == RT5682S) {
1638			links[i].codecs = rt5682s;
1639			links[i].num_codecs = ARRAY_SIZE(rt5682s);
1640			links[i].init = acp_card_rt5682s_init;
1641			links[i].ops = &acp_card_rt5682s_ops;
1642		}
1643		if (drv_data->hs_codec_id == ES83XX) {
1644			rc = acp_ops_configure_link(card, &links[i]);
1645			if (rc != 0) {
1646				dev_err(dev, "Failed to configure link for ES83XX: %d\n", rc);
1647				return rc;
1648			}
1649		}
1650		i++;
1651	}
1652
1653	if (drv_data->hs_cpu_id == I2S_HS) {
1654		links[i].name = "acp-headset-codec";
1655		links[i].id = HEADSET_BE_ID;
1656		links[i].cpus = i2s_hs;
1657		links[i].num_cpus = ARRAY_SIZE(i2s_hs);
1658		switch (drv_data->acp_rev) {
1659		case ACP_RMB_PCI_ID:
1660			links[i].platforms = platform_rmb_component;
1661			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
1662			break;
1663		case ACP63_PCI_ID:
1664			links[i].platforms = platform_acp63_component;
1665			links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);
1666			break;
1667		default:
1668			links[i].platforms = platform_component;
1669			links[i].num_platforms = ARRAY_SIZE(platform_component);
1670			break;
1671		}
1672
1673		if (!drv_data->hs_codec_id) {
1674			/* Use dummy codec if codec id not specified */
1675			links[i].codecs = &snd_soc_dummy_dlc;
1676			links[i].num_codecs = 1;
1677		}
1678		if (drv_data->hs_codec_id == NAU8825) {
1679			links[i].codecs = nau8825;
1680			links[i].num_codecs = ARRAY_SIZE(nau8825);
1681			links[i].init = acp_card_nau8825_init;
1682			links[i].ops = &acp_card_nau8825_ops;
1683		}
1684		if (drv_data->hs_codec_id == RT5682S) {
1685			links[i].codecs = rt5682s;
1686			links[i].num_codecs = ARRAY_SIZE(rt5682s);
1687			links[i].init = acp_card_rt5682s_init;
1688			links[i].ops = &acp_card_rt5682s_ops;
1689		}
1690		i++;
1691	}
1692
1693	if (drv_data->amp_cpu_id == I2S_SP) {
1694		links[i].name = "acp-amp-codec";
1695		links[i].id = AMP_BE_ID;
1696		links[i].cpus = i2s_sp;
1697		links[i].num_cpus = ARRAY_SIZE(i2s_sp);
1698		links[i].platforms = platform_component;
1699		links[i].num_platforms = ARRAY_SIZE(platform_component);
1700		links[i].playback_only = 1;
1701		if (!drv_data->amp_codec_id) {
1702			/* Use dummy codec if codec id not specified */
1703			links[i].codecs = &snd_soc_dummy_dlc;
1704			links[i].num_codecs = 1;
1705		}
1706		if (drv_data->amp_codec_id == RT1019) {
1707			links[i].codecs = rt1019;
1708			links[i].num_codecs = ARRAY_SIZE(rt1019);
1709			links[i].ops = &acp_card_rt1019_ops;
1710			links[i].init = acp_card_rt1019_init;
1711			card->codec_conf = rt1019_conf;
1712			card->num_configs = ARRAY_SIZE(rt1019_conf);
1713		}
1714		if (drv_data->amp_codec_id == MAX98360A) {
1715			links[i].codecs = max98360a;
1716			links[i].num_codecs = ARRAY_SIZE(max98360a);
1717			links[i].ops = &acp_card_maxim_ops;
1718			links[i].init = acp_card_maxim_init;
1719		}
1720		i++;
1721	}
1722
1723	if (drv_data->amp_cpu_id == I2S_HS) {
1724		links[i].name = "acp-amp-codec";
1725		links[i].id = AMP_BE_ID;
1726		links[i].cpus = i2s_hs;
1727		links[i].num_cpus = ARRAY_SIZE(i2s_hs);
1728		switch (drv_data->acp_rev) {
1729		case ACP_RMB_PCI_ID:
1730			links[i].platforms = platform_rmb_component;
1731			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
1732			break;
1733		case ACP63_PCI_ID:
1734			links[i].platforms = platform_acp63_component;
1735			links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);
1736			break;
1737		default:
1738			links[i].platforms = platform_component;
1739			links[i].num_platforms = ARRAY_SIZE(platform_component);
1740			break;
1741		}
1742
1743		links[i].playback_only = 1;
1744		if (!drv_data->amp_codec_id) {
1745			/* Use dummy codec if codec id not specified */
1746			links[i].codecs = &snd_soc_dummy_dlc;
1747			links[i].num_codecs = 1;
1748		}
1749		if (drv_data->amp_codec_id == MAX98360A) {
1750			links[i].codecs = max98360a;
1751			links[i].num_codecs = ARRAY_SIZE(max98360a);
1752			links[i].ops = &acp_card_maxim_ops;
1753			links[i].init = acp_card_maxim_init;
1754		}
1755		if (drv_data->amp_codec_id == RT1019) {
1756			links[i].codecs = rt1019;
1757			links[i].num_codecs = ARRAY_SIZE(rt1019);
1758			links[i].ops = &acp_card_rt1019_ops;
1759			links[i].init = acp_card_rt1019_init;
1760			card->codec_conf = rt1019_conf;
1761			card->num_configs = ARRAY_SIZE(rt1019_conf);
1762		}
1763		i++;
1764	}
1765
1766	if (drv_data->dmic_cpu_id == DMIC) {
1767		links[i].name = "acp-dmic-codec";
1768		links[i].stream_name = "DMIC capture";
1769		links[i].id = DMIC_BE_ID;
1770		if (drv_data->dmic_codec_id == DMIC) {
1771			links[i].codecs = dmic_codec;
1772			links[i].num_codecs = ARRAY_SIZE(dmic_codec);
1773		} else {
1774			/* Use dummy codec if codec id not specified */
1775			links[i].codecs = &snd_soc_dummy_dlc;
1776			links[i].num_codecs = 1;
1777		}
1778		links[i].cpus = pdm_dmic;
1779		links[i].num_cpus = ARRAY_SIZE(pdm_dmic);
1780		switch (drv_data->acp_rev) {
1781		case ACP_RMB_PCI_ID:
1782			links[i].platforms = platform_rmb_component;
1783			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
1784			break;
1785		case ACP63_PCI_ID:
1786			links[i].platforms = platform_acp63_component;
1787			links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);
1788			break;
1789		case ACP70_PCI_ID:
1790		case ACP71_PCI_ID:
1791		case ACP72_PCI_ID:
1792			links[i].platforms = platform_acp70_component;
1793			links[i].num_platforms = ARRAY_SIZE(platform_acp70_component);
1794			break;
1795		default:
1796			links[i].platforms = platform_component;
1797			links[i].num_platforms = ARRAY_SIZE(platform_component);
1798			break;
1799		}
1800		links[i].ops = &acp_card_dmic_ops;
1801		links[i].capture_only = 1;
1802	}
1803
1804	card->dai_link = links;
1805	card->num_links = num_links;
1806	card->set_bias_level = acp_rtk_set_bias_level;
1807
1808	return 0;
1809}
1810EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, "SND_SOC_AMD_MACH");
1811
1812MODULE_DESCRIPTION("AMD ACP Common Machine driver");
1813MODULE_LICENSE("GPL v2");
~/ Read-only file preview.