Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 //
0003 // This file is provided under a dual BSD/GPLv2 license. When using or
0004 // redistributing this file, you may do so under either license.
0005 //
0006 // Copyright(c) 2021 Advanced Micro Devices, Inc.
0007 //
0008 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
0009 //      Vijendar Mukunda <Vijendar.Mukunda@amd.com>
0010 //
0011 
0012 /*
0013  * Machine Driver Interface for ACP HW block
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 /* Declare RT5682 codec components */
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 /* Define card ops for RT5682 CODEC */
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     /* Set tdm/i2s1 master bclk ratio */
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 /* Define RT5682S CODEC component*/
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     /* Set tdm/i2s1 master bclk ratio */
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 /* Declare RT1019 codec components */
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 /* Declare Maxim codec components */
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 /* Declare nau8825 codec components */
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 /* Declare DMIC codec components */
0531 SND_SOC_DAILINK_DEF(dmic_codec,
0532         DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
0533 
0534 /* Declare ACP CPU components */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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             /* Use dummy codec if codec id not specified */
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");