0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <sound/core.h>
0017 #include <sound/jack.h>
0018 #include <sound/pcm_params.h>
0019 #include <sound/soc-dapm.h>
0020 #include <sound/soc.h>
0021 #include <linux/input.h>
0022 #include <linux/module.h>
0023
0024 #include "../../codecs/rt5682.h"
0025 #include "../../codecs/rt1019.h"
0026 #include "../../codecs/rt5682s.h"
0027 #include "../../codecs/nau8825.h"
0028 #include "acp-mach.h"
0029
0030 #define PCO_PLAT_CLK 48000000
0031 #define RT5682_PLL_FREQ (48000 * 512)
0032 #define DUAL_CHANNEL 2
0033 #define FOUR_CHANNEL 4
0034
0035 static struct snd_soc_jack pco_jack;
0036
0037 static const unsigned int channels[] = {
0038 DUAL_CHANNEL,
0039 };
0040
0041 static const unsigned int rates[] = {
0042 48000,
0043 };
0044
0045 static const struct snd_pcm_hw_constraint_list constraints_rates = {
0046 .count = ARRAY_SIZE(rates),
0047 .list = rates,
0048 .mask = 0,
0049 };
0050
0051 static const struct snd_pcm_hw_constraint_list constraints_channels = {
0052 .count = ARRAY_SIZE(channels),
0053 .list = channels,
0054 .mask = 0,
0055 };
0056
0057 static int acp_clk_enable(struct acp_card_drvdata *drvdata)
0058 {
0059 clk_set_rate(drvdata->wclk, 48000);
0060 clk_set_rate(drvdata->bclk, 48000 * 64);
0061
0062 return clk_prepare_enable(drvdata->wclk);
0063 }
0064
0065
0066 SND_SOC_DAILINK_DEF(rt5682,
0067 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
0068
0069 static const struct snd_soc_dapm_route rt5682_map[] = {
0070 { "Headphone Jack", NULL, "HPOL" },
0071 { "Headphone Jack", NULL, "HPOR" },
0072 { "IN1P", NULL, "Headset Mic" },
0073 };
0074
0075
0076 static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
0077 {
0078 struct snd_soc_card *card = rtd->card;
0079 struct acp_card_drvdata *drvdata = card->drvdata;
0080 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0081 struct snd_soc_component *component = codec_dai->component;
0082 int ret;
0083
0084 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
0085
0086 if (drvdata->hs_codec_id != RT5682)
0087 return -EINVAL;
0088
0089 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0090 | SND_SOC_DAIFMT_CBP_CFP);
0091 if (ret < 0) {
0092 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
0093 return ret;
0094 }
0095
0096 ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
0097 PCO_PLAT_CLK, RT5682_PLL_FREQ);
0098 if (ret < 0) {
0099 dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
0100 return ret;
0101 }
0102
0103 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
0104 RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
0105 if (ret < 0) {
0106 dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
0107 return ret;
0108 }
0109
0110
0111 ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
0112 if (ret < 0) {
0113 dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
0114 return ret;
0115 }
0116
0117 drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
0118 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
0119
0120 ret = snd_soc_card_jack_new(card, "Headset Jack",
0121 SND_JACK_HEADSET | SND_JACK_LINEOUT |
0122 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0123 SND_JACK_BTN_2 | SND_JACK_BTN_3,
0124 &pco_jack);
0125 if (ret) {
0126 dev_err(card->dev, "HP jack creation failed %d\n", ret);
0127 return ret;
0128 }
0129
0130 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0131 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0132 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0133 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0134
0135 ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
0136 if (ret) {
0137 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
0138 return ret;
0139 }
0140
0141 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682_map, ARRAY_SIZE(rt5682_map));
0142 }
0143
0144 static int acp_card_hs_startup(struct snd_pcm_substream *substream)
0145 {
0146 struct snd_pcm_runtime *runtime = substream->runtime;
0147 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0148 struct snd_soc_card *card = rtd->card;
0149 struct acp_card_drvdata *drvdata = card->drvdata;
0150 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0151 int ret;
0152 unsigned int fmt;
0153
0154 if (drvdata->soc_mclk)
0155 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
0156 else
0157 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
0158
0159 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
0160 if (ret < 0) {
0161 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
0162 return ret;
0163 }
0164
0165 runtime->hw.channels_max = DUAL_CHANNEL;
0166 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0167 &constraints_channels);
0168 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0169 &constraints_rates);
0170 if (!drvdata->soc_mclk) {
0171 ret = acp_clk_enable(drvdata);
0172 if (ret < 0) {
0173 dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
0174 return ret;
0175 }
0176 }
0177
0178 return ret;
0179 }
0180
0181 static void acp_card_shutdown(struct snd_pcm_substream *substream)
0182 {
0183 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0184 struct snd_soc_card *card = rtd->card;
0185 struct acp_card_drvdata *drvdata = card->drvdata;
0186
0187 if (!drvdata->soc_mclk)
0188 clk_disable_unprepare(drvdata->wclk);
0189 }
0190
0191 static const struct snd_soc_ops acp_card_rt5682_ops = {
0192 .startup = acp_card_hs_startup,
0193 .shutdown = acp_card_shutdown,
0194 };
0195
0196
0197 SND_SOC_DAILINK_DEF(rt5682s,
0198 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));
0199
0200 static const struct snd_soc_dapm_route rt5682s_map[] = {
0201 { "Headphone Jack", NULL, "HPOL" },
0202 { "Headphone Jack", NULL, "HPOR" },
0203 { "IN1P", NULL, "Headset Mic" },
0204 };
0205
0206 static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
0207 {
0208 struct snd_soc_card *card = rtd->card;
0209 struct acp_card_drvdata *drvdata = card->drvdata;
0210 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0211 struct snd_soc_component *component = codec_dai->component;
0212 unsigned int fmt;
0213 int ret;
0214
0215 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
0216
0217 if (drvdata->hs_codec_id != RT5682S)
0218 return -EINVAL;
0219
0220 if (drvdata->soc_mclk)
0221 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
0222 else
0223 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
0224
0225 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
0226 if (ret < 0) {
0227 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
0228 return ret;
0229 }
0230
0231 ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
0232 PCO_PLAT_CLK, RT5682_PLL_FREQ);
0233 if (ret < 0) {
0234 dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
0235 return ret;
0236 }
0237
0238 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
0239 RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
0240 if (ret < 0) {
0241 dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
0242 return ret;
0243 }
0244
0245
0246 ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
0247 if (ret < 0) {
0248 dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
0249 return ret;
0250 }
0251
0252 if (!drvdata->soc_mclk) {
0253 drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
0254 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
0255 }
0256
0257 ret = snd_soc_card_jack_new(card, "Headset Jack",
0258 SND_JACK_HEADSET | SND_JACK_LINEOUT |
0259 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0260 SND_JACK_BTN_2 | SND_JACK_BTN_3,
0261 &pco_jack);
0262 if (ret) {
0263 dev_err(card->dev, "HP jack creation failed %d\n", ret);
0264 return ret;
0265 }
0266
0267 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0268 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0269 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0270 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0271
0272 ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
0273 if (ret) {
0274 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
0275 return ret;
0276 }
0277
0278 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map));
0279 }
0280
0281 static const struct snd_soc_ops acp_card_rt5682s_ops = {
0282 .startup = acp_card_hs_startup,
0283 .shutdown = acp_card_shutdown,
0284 };
0285
0286 static const unsigned int dmic_channels[] = {
0287 DUAL_CHANNEL, FOUR_CHANNEL,
0288 };
0289
0290 static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = {
0291 .count = ARRAY_SIZE(dmic_channels),
0292 .list = dmic_channels,
0293 .mask = 0,
0294 };
0295
0296 static int acp_card_dmic_startup(struct snd_pcm_substream *substream)
0297 {
0298 struct snd_pcm_runtime *runtime = substream->runtime;
0299
0300 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0301 &dmic_constraints_channels);
0302 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0303 &constraints_rates);
0304
0305 return 0;
0306 }
0307
0308 static const struct snd_soc_ops acp_card_dmic_ops = {
0309 .startup = acp_card_dmic_startup,
0310 };
0311
0312
0313 SND_SOC_DAILINK_DEF(rt1019,
0314 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
0315 COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
0316
0317 static const struct snd_soc_dapm_route rt1019_map_lr[] = {
0318 { "Left Spk", NULL, "Left SPO" },
0319 { "Right Spk", NULL, "Right SPO" },
0320 };
0321
0322 static struct snd_soc_codec_conf rt1019_conf[] = {
0323 {
0324 .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
0325 .name_prefix = "Left",
0326 },
0327 {
0328 .dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
0329 .name_prefix = "Right",
0330 },
0331 };
0332
0333 static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)
0334 {
0335 struct snd_soc_card *card = rtd->card;
0336 struct acp_card_drvdata *drvdata = card->drvdata;
0337
0338 if (drvdata->amp_codec_id != RT1019)
0339 return -EINVAL;
0340
0341 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr,
0342 ARRAY_SIZE(rt1019_map_lr));
0343 }
0344
0345 static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
0346 struct snd_pcm_hw_params *params)
0347 {
0348 struct snd_soc_pcm_runtime *rtd = substream->private_data;
0349 struct snd_soc_card *card = rtd->card;
0350 struct acp_card_drvdata *drvdata = card->drvdata;
0351 struct snd_soc_dai *codec_dai;
0352 int srate, i, ret = 0;
0353
0354 srate = params_rate(params);
0355
0356 if (drvdata->amp_codec_id != RT1019)
0357 return -EINVAL;
0358
0359 for_each_rtd_codec_dais(rtd, i, codec_dai) {
0360 if (strcmp(codec_dai->name, "rt1019-aif"))
0361 continue;
0362
0363 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
0364 64 * srate, 256 * srate);
0365 if (ret < 0)
0366 return ret;
0367
0368 ret = snd_soc_dai_set_sysclk(codec_dai, RT1019_SCLK_S_PLL,
0369 256 * srate, SND_SOC_CLOCK_IN);
0370 if (ret < 0)
0371 return ret;
0372 }
0373
0374 return 0;
0375 }
0376
0377 static int acp_card_amp_startup(struct snd_pcm_substream *substream)
0378 {
0379 struct snd_pcm_runtime *runtime = substream->runtime;
0380 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0381 struct snd_soc_card *card = rtd->card;
0382 struct acp_card_drvdata *drvdata = card->drvdata;
0383 int ret = 0;
0384
0385 runtime->hw.channels_max = DUAL_CHANNEL;
0386 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0387 &constraints_channels);
0388 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0389 &constraints_rates);
0390
0391 if (!drvdata->soc_mclk) {
0392 ret = acp_clk_enable(drvdata);
0393 if (ret < 0) {
0394 dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
0395 return ret;
0396 }
0397 }
0398 return ret;
0399 }
0400
0401 static const struct snd_soc_ops acp_card_rt1019_ops = {
0402 .startup = acp_card_amp_startup,
0403 .shutdown = acp_card_shutdown,
0404 .hw_params = acp_card_rt1019_hw_params,
0405 };
0406
0407
0408 SND_SOC_DAILINK_DEF(max98360a,
0409 DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));
0410
0411 static const struct snd_soc_dapm_route max98360a_map[] = {
0412 {"Spk", NULL, "Speaker"},
0413 };
0414
0415 static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)
0416 {
0417 struct snd_soc_card *card = rtd->card;
0418 struct acp_card_drvdata *drvdata = card->drvdata;
0419
0420 if (drvdata->amp_codec_id != MAX98360A)
0421 return -EINVAL;
0422
0423 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map,
0424 ARRAY_SIZE(max98360a_map));
0425 }
0426
0427 static const struct snd_soc_ops acp_card_maxim_ops = {
0428 .startup = acp_card_amp_startup,
0429 .shutdown = acp_card_shutdown,
0430 };
0431
0432
0433 SND_SOC_DAILINK_DEF(nau8825,
0434 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));
0435
0436 static const struct snd_soc_dapm_route nau8825_map[] = {
0437 { "Headphone Jack", NULL, "HPOL" },
0438 { "Headphone Jack", NULL, "HPOR" },
0439 };
0440
0441 static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)
0442 {
0443 struct snd_soc_card *card = rtd->card;
0444 struct acp_card_drvdata *drvdata = card->drvdata;
0445 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0446 struct snd_soc_component *component = codec_dai->component;
0447 unsigned int fmt;
0448 int ret;
0449
0450 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
0451
0452 if (drvdata->hs_codec_id != NAU8825)
0453 return -EINVAL;
0454
0455 if (drvdata->soc_mclk)
0456 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
0457 else
0458 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
0459
0460 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
0461 if (ret < 0) {
0462 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
0463 return ret;
0464 }
0465 ret = snd_soc_card_jack_new(card, "Headset Jack",
0466 SND_JACK_HEADSET | SND_JACK_LINEOUT |
0467 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0468 SND_JACK_BTN_2 | SND_JACK_BTN_3,
0469 &pco_jack);
0470 if (ret) {
0471 dev_err(card->dev, "HP jack creation failed %d\n", ret);
0472 return ret;
0473 }
0474
0475 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0476 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0477 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0478 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0479
0480 ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
0481 if (ret) {
0482 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
0483 return ret;
0484 }
0485
0486 return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8825_map, ARRAY_SIZE(nau8825_map));
0487 }
0488
0489 static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,
0490 struct snd_pcm_hw_params *params)
0491 {
0492 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0493 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0494 int ret;
0495
0496 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS,
0497 (48000 * 256), SND_SOC_CLOCK_IN);
0498 if (ret < 0)
0499 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
0500
0501 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
0502 params_rate(params) * 256);
0503 if (ret < 0) {
0504 dev_err(rtd->dev, "can't set FLL: %d\n", ret);
0505 return ret;
0506 }
0507
0508 return ret;
0509 }
0510
0511 static int acp_nau8825_startup(struct snd_pcm_substream *substream)
0512 {
0513 struct snd_pcm_runtime *runtime = substream->runtime;
0514
0515 runtime->hw.channels_max = 2;
0516 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0517 &constraints_channels);
0518
0519 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
0520 snd_pcm_hw_constraint_list(runtime, 0,
0521 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
0522 return 0;
0523 }
0524
0525 static const struct snd_soc_ops acp_card_nau8825_ops = {
0526 .startup = acp_nau8825_startup,
0527 .hw_params = acp_nau8825_hw_params,
0528 };
0529
0530
0531 SND_SOC_DAILINK_DEF(dmic_codec,
0532 DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
0533
0534
0535 static struct snd_soc_dai_link_component dummy_codec[] = {
0536 {
0537 .name = "snd-soc-dummy",
0538 .dai_name = "snd-soc-dummy-dai",
0539 }
0540 };
0541
0542 static struct snd_soc_dai_link_component platform_component[] = {
0543 {
0544 .name = "acp_asoc_renoir.0",
0545 }
0546 };
0547
0548 static struct snd_soc_dai_link_component platform_rmb_component[] = {
0549 {
0550 .name = "acp_asoc_rembrandt.0",
0551 }
0552 };
0553
0554 static struct snd_soc_dai_link_component sof_component[] = {
0555 {
0556 .name = "0000:04:00.5",
0557 }
0558 };
0559
0560 SND_SOC_DAILINK_DEF(i2s_sp,
0561 DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp")));
0562 SND_SOC_DAILINK_DEF(i2s_hs,
0563 DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));
0564 SND_SOC_DAILINK_DEF(sof_sp,
0565 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
0566 SND_SOC_DAILINK_DEF(sof_hs,
0567 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));
0568 SND_SOC_DAILINK_DEF(sof_dmic,
0569 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
0570 SND_SOC_DAILINK_DEF(pdm_dmic,
0571 DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic")));
0572
0573 int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
0574 {
0575 struct snd_soc_dai_link *links;
0576 struct device *dev = card->dev;
0577 struct acp_card_drvdata *drv_data = card->drvdata;
0578 int i = 0, num_links = 0;
0579
0580 if (drv_data->hs_cpu_id)
0581 num_links++;
0582 if (drv_data->amp_cpu_id)
0583 num_links++;
0584 if (drv_data->dmic_cpu_id)
0585 num_links++;
0586
0587 links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * num_links, GFP_KERNEL);
0588 if (!links)
0589 return -ENOMEM;
0590
0591 if (drv_data->hs_cpu_id == I2S_SP) {
0592 links[i].name = "acp-headset-codec";
0593 links[i].id = HEADSET_BE_ID;
0594 links[i].cpus = sof_sp;
0595 links[i].num_cpus = ARRAY_SIZE(sof_sp);
0596 links[i].platforms = sof_component;
0597 links[i].num_platforms = ARRAY_SIZE(sof_component);
0598 links[i].dpcm_playback = 1;
0599 links[i].dpcm_capture = 1;
0600 links[i].nonatomic = true;
0601 links[i].no_pcm = 1;
0602 if (!drv_data->hs_codec_id) {
0603
0604 links[i].codecs = dummy_codec;
0605 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0606 }
0607 if (drv_data->hs_codec_id == RT5682) {
0608 links[i].codecs = rt5682;
0609 links[i].num_codecs = ARRAY_SIZE(rt5682);
0610 links[i].init = acp_card_rt5682_init;
0611 links[i].ops = &acp_card_rt5682_ops;
0612 }
0613 if (drv_data->hs_codec_id == RT5682S) {
0614 links[i].codecs = rt5682s;
0615 links[i].num_codecs = ARRAY_SIZE(rt5682s);
0616 links[i].init = acp_card_rt5682s_init;
0617 links[i].ops = &acp_card_rt5682s_ops;
0618 }
0619 i++;
0620 }
0621
0622 if (drv_data->hs_cpu_id == I2S_HS) {
0623 links[i].name = "acp-headset-codec";
0624 links[i].id = HEADSET_BE_ID;
0625 links[i].cpus = sof_hs;
0626 links[i].num_cpus = ARRAY_SIZE(sof_hs);
0627 links[i].platforms = sof_component;
0628 links[i].num_platforms = ARRAY_SIZE(sof_component);
0629 links[i].dpcm_playback = 1;
0630 links[i].dpcm_capture = 1;
0631 links[i].nonatomic = true;
0632 links[i].no_pcm = 1;
0633 if (!drv_data->hs_codec_id) {
0634
0635 links[i].codecs = dummy_codec;
0636 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0637 }
0638 if (drv_data->hs_codec_id == NAU8825) {
0639 links[i].codecs = nau8825;
0640 links[i].num_codecs = ARRAY_SIZE(nau8825);
0641 links[i].init = acp_card_nau8825_init;
0642 links[i].ops = &acp_card_nau8825_ops;
0643 }
0644 if (drv_data->hs_codec_id == RT5682S) {
0645 links[i].codecs = rt5682s;
0646 links[i].num_codecs = ARRAY_SIZE(rt5682s);
0647 links[i].init = acp_card_rt5682s_init;
0648 links[i].ops = &acp_card_rt5682s_ops;
0649 }
0650 i++;
0651 }
0652
0653 if (drv_data->amp_cpu_id == I2S_SP) {
0654 links[i].name = "acp-amp-codec";
0655 links[i].id = AMP_BE_ID;
0656 links[i].cpus = sof_sp;
0657 links[i].num_cpus = ARRAY_SIZE(sof_sp);
0658 links[i].platforms = sof_component;
0659 links[i].num_platforms = ARRAY_SIZE(sof_component);
0660 links[i].dpcm_playback = 1;
0661 links[i].nonatomic = true;
0662 links[i].no_pcm = 1;
0663 if (!drv_data->amp_codec_id) {
0664
0665 links[i].codecs = dummy_codec;
0666 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0667 }
0668 if (drv_data->amp_codec_id == RT1019) {
0669 links[i].codecs = rt1019;
0670 links[i].num_codecs = ARRAY_SIZE(rt1019);
0671 links[i].ops = &acp_card_rt1019_ops;
0672 links[i].init = acp_card_rt1019_init;
0673 card->codec_conf = rt1019_conf;
0674 card->num_configs = ARRAY_SIZE(rt1019_conf);
0675 }
0676 if (drv_data->amp_codec_id == MAX98360A) {
0677 links[i].codecs = max98360a;
0678 links[i].num_codecs = ARRAY_SIZE(max98360a);
0679 links[i].ops = &acp_card_maxim_ops;
0680 links[i].init = acp_card_maxim_init;
0681 }
0682 i++;
0683 }
0684
0685 if (drv_data->amp_cpu_id == I2S_HS) {
0686 links[i].name = "acp-amp-codec";
0687 links[i].id = AMP_BE_ID;
0688 links[i].cpus = sof_hs;
0689 links[i].num_cpus = ARRAY_SIZE(sof_hs);
0690 links[i].platforms = sof_component;
0691 links[i].num_platforms = ARRAY_SIZE(sof_component);
0692 links[i].dpcm_playback = 1;
0693 links[i].nonatomic = true;
0694 links[i].no_pcm = 1;
0695 if (!drv_data->amp_codec_id) {
0696
0697 links[i].codecs = dummy_codec;
0698 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0699 }
0700 if (drv_data->amp_codec_id == MAX98360A) {
0701 links[i].codecs = max98360a;
0702 links[i].num_codecs = ARRAY_SIZE(max98360a);
0703 links[i].ops = &acp_card_maxim_ops;
0704 links[i].init = acp_card_maxim_init;
0705 }
0706 if (drv_data->amp_codec_id == RT1019) {
0707 links[i].codecs = rt1019;
0708 links[i].num_codecs = ARRAY_SIZE(rt1019);
0709 links[i].ops = &acp_card_rt1019_ops;
0710 links[i].init = acp_card_rt1019_init;
0711 card->codec_conf = rt1019_conf;
0712 card->num_configs = ARRAY_SIZE(rt1019_conf);
0713 }
0714 i++;
0715 }
0716
0717 if (drv_data->dmic_cpu_id == DMIC) {
0718 links[i].name = "acp-dmic-codec";
0719 links[i].id = DMIC_BE_ID;
0720 links[i].codecs = dmic_codec;
0721 links[i].num_codecs = ARRAY_SIZE(dmic_codec);
0722 links[i].cpus = sof_dmic;
0723 links[i].num_cpus = ARRAY_SIZE(sof_dmic);
0724 links[i].platforms = sof_component;
0725 links[i].num_platforms = ARRAY_SIZE(sof_component);
0726 links[i].dpcm_capture = 1;
0727 links[i].nonatomic = true;
0728 links[i].no_pcm = 1;
0729 }
0730
0731 card->dai_link = links;
0732 card->num_links = num_links;
0733
0734 return 0;
0735 }
0736 EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, SND_SOC_AMD_MACH);
0737
0738 int acp_legacy_dai_links_create(struct snd_soc_card *card)
0739 {
0740 struct snd_soc_dai_link *links;
0741 struct device *dev = card->dev;
0742 struct acp_card_drvdata *drv_data = card->drvdata;
0743 int i = 0, num_links = 0;
0744
0745 if (drv_data->hs_cpu_id)
0746 num_links++;
0747 if (drv_data->amp_cpu_id)
0748 num_links++;
0749 if (drv_data->dmic_cpu_id)
0750 num_links++;
0751
0752 links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * num_links, GFP_KERNEL);
0753 if (!links)
0754 return -ENOMEM;
0755
0756 if (drv_data->hs_cpu_id == I2S_SP) {
0757 links[i].name = "acp-headset-codec";
0758 links[i].id = HEADSET_BE_ID;
0759 links[i].cpus = i2s_sp;
0760 links[i].num_cpus = ARRAY_SIZE(i2s_sp);
0761 links[i].platforms = platform_component;
0762 links[i].num_platforms = ARRAY_SIZE(platform_component);
0763 links[i].dpcm_playback = 1;
0764 links[i].dpcm_capture = 1;
0765 if (!drv_data->hs_codec_id) {
0766
0767 links[i].codecs = dummy_codec;
0768 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0769 }
0770 if (drv_data->hs_codec_id == RT5682) {
0771 links[i].codecs = rt5682;
0772 links[i].num_codecs = ARRAY_SIZE(rt5682);
0773 links[i].init = acp_card_rt5682_init;
0774 links[i].ops = &acp_card_rt5682_ops;
0775 }
0776 if (drv_data->hs_codec_id == RT5682S) {
0777 links[i].codecs = rt5682s;
0778 links[i].num_codecs = ARRAY_SIZE(rt5682s);
0779 links[i].init = acp_card_rt5682s_init;
0780 links[i].ops = &acp_card_rt5682s_ops;
0781 }
0782 i++;
0783 }
0784
0785 if (drv_data->hs_cpu_id == I2S_HS) {
0786 links[i].name = "acp-headset-codec";
0787 links[i].id = HEADSET_BE_ID;
0788 links[i].cpus = i2s_hs;
0789 links[i].num_cpus = ARRAY_SIZE(i2s_hs);
0790 if (drv_data->platform == REMBRANDT) {
0791 links[i].platforms = platform_rmb_component;
0792 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
0793 } else {
0794 links[i].platforms = platform_component;
0795 links[i].num_platforms = ARRAY_SIZE(platform_component);
0796 }
0797 links[i].dpcm_playback = 1;
0798 links[i].dpcm_capture = 1;
0799 if (!drv_data->hs_codec_id) {
0800
0801 links[i].codecs = dummy_codec;
0802 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0803 }
0804 if (drv_data->hs_codec_id == NAU8825) {
0805 links[i].codecs = nau8825;
0806 links[i].num_codecs = ARRAY_SIZE(nau8825);
0807 links[i].init = acp_card_nau8825_init;
0808 links[i].ops = &acp_card_nau8825_ops;
0809 }
0810 if (drv_data->hs_codec_id == RT5682S) {
0811 links[i].codecs = rt5682s;
0812 links[i].num_codecs = ARRAY_SIZE(rt5682s);
0813 links[i].init = acp_card_rt5682s_init;
0814 links[i].ops = &acp_card_rt5682s_ops;
0815 }
0816 i++;
0817 }
0818
0819 if (drv_data->amp_cpu_id == I2S_SP) {
0820 links[i].name = "acp-amp-codec";
0821 links[i].id = AMP_BE_ID;
0822 links[i].cpus = i2s_sp;
0823 links[i].num_cpus = ARRAY_SIZE(i2s_sp);
0824 links[i].platforms = platform_component;
0825 links[i].num_platforms = ARRAY_SIZE(platform_component);
0826 links[i].dpcm_playback = 1;
0827 if (!drv_data->amp_codec_id) {
0828
0829 links[i].codecs = dummy_codec;
0830 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0831 }
0832 if (drv_data->amp_codec_id == RT1019) {
0833 links[i].codecs = rt1019;
0834 links[i].num_codecs = ARRAY_SIZE(rt1019);
0835 links[i].ops = &acp_card_rt1019_ops;
0836 links[i].init = acp_card_rt1019_init;
0837 card->codec_conf = rt1019_conf;
0838 card->num_configs = ARRAY_SIZE(rt1019_conf);
0839 }
0840 if (drv_data->amp_codec_id == MAX98360A) {
0841 links[i].codecs = max98360a;
0842 links[i].num_codecs = ARRAY_SIZE(max98360a);
0843 links[i].ops = &acp_card_maxim_ops;
0844 links[i].init = acp_card_maxim_init;
0845 }
0846 i++;
0847 }
0848
0849 if (drv_data->amp_cpu_id == I2S_HS) {
0850 links[i].name = "acp-amp-codec";
0851 links[i].id = AMP_BE_ID;
0852 links[i].cpus = i2s_hs;
0853 links[i].num_cpus = ARRAY_SIZE(i2s_hs);
0854 if (drv_data->platform == REMBRANDT) {
0855 links[i].platforms = platform_rmb_component;
0856 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
0857 } else {
0858 links[i].platforms = platform_component;
0859 links[i].num_platforms = ARRAY_SIZE(platform_component);
0860 }
0861 links[i].dpcm_playback = 1;
0862 if (!drv_data->amp_codec_id) {
0863
0864 links[i].codecs = dummy_codec;
0865 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0866 }
0867 if (drv_data->amp_codec_id == MAX98360A) {
0868 links[i].codecs = max98360a;
0869 links[i].num_codecs = ARRAY_SIZE(max98360a);
0870 links[i].ops = &acp_card_maxim_ops;
0871 links[i].init = acp_card_maxim_init;
0872 }
0873 if (drv_data->amp_codec_id == RT1019) {
0874 links[i].codecs = rt1019;
0875 links[i].num_codecs = ARRAY_SIZE(rt1019);
0876 links[i].ops = &acp_card_rt1019_ops;
0877 links[i].init = acp_card_rt1019_init;
0878 card->codec_conf = rt1019_conf;
0879 card->num_configs = ARRAY_SIZE(rt1019_conf);
0880 }
0881 i++;
0882 }
0883
0884 if (drv_data->dmic_cpu_id == DMIC) {
0885 links[i].name = "acp-dmic-codec";
0886 links[i].id = DMIC_BE_ID;
0887 if (drv_data->dmic_codec_id == DMIC) {
0888 links[i].codecs = dmic_codec;
0889 links[i].num_codecs = ARRAY_SIZE(dmic_codec);
0890 } else {
0891
0892 links[i].codecs = dummy_codec;
0893 links[i].num_codecs = ARRAY_SIZE(dummy_codec);
0894 }
0895 links[i].cpus = pdm_dmic;
0896 links[i].num_cpus = ARRAY_SIZE(pdm_dmic);
0897 if (drv_data->platform == REMBRANDT) {
0898 links[i].platforms = platform_rmb_component;
0899 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
0900 } else {
0901 links[i].platforms = platform_component;
0902 links[i].num_platforms = ARRAY_SIZE(platform_component);
0903 }
0904 links[i].ops = &acp_card_dmic_ops;
0905 links[i].dpcm_capture = 1;
0906 }
0907
0908 card->dai_link = links;
0909 card->num_links = num_links;
0910
0911 return 0;
0912 }
0913 EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH);
0914
0915 MODULE_LICENSE("GPL v2");