Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 //
0003 // Machine driver for AMD ACP Audio engine using DA7219, RT5682 & MAX98357 codec
0004 //
0005 //Copyright 2017-2021 Advanced Micro Devices, Inc.
0006 
0007 #include <sound/core.h>
0008 #include <sound/soc.h>
0009 #include <sound/pcm.h>
0010 #include <sound/pcm_params.h>
0011 #include <sound/soc-dapm.h>
0012 #include <sound/jack.h>
0013 #include <linux/clk.h>
0014 #include <linux/gpio.h>
0015 #include <linux/module.h>
0016 #include <linux/regulator/machine.h>
0017 #include <linux/regulator/driver.h>
0018 #include <linux/i2c.h>
0019 #include <linux/input.h>
0020 #include <linux/acpi.h>
0021 
0022 #include "acp.h"
0023 #include "../codecs/da7219.h"
0024 #include "../codecs/da7219-aad.h"
0025 #include "../codecs/rt5682.h"
0026 
0027 #define CZ_PLAT_CLK 48000000
0028 #define DUAL_CHANNEL        2
0029 #define RT5682_PLL_FREQ (48000 * 512)
0030 
0031 static struct snd_soc_jack cz_jack;
0032 static struct clk *da7219_dai_wclk;
0033 static struct clk *da7219_dai_bclk;
0034 static struct clk *rt5682_dai_wclk;
0035 static struct clk *rt5682_dai_bclk;
0036 
0037 void *acp_soc_is_rltk_max(struct device *dev);
0038 
0039 static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
0040 {
0041     int ret;
0042     struct snd_soc_card *card = rtd->card;
0043     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0044     struct snd_soc_component *component = codec_dai->component;
0045 
0046     dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
0047 
0048     ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK,
0049                      CZ_PLAT_CLK, SND_SOC_CLOCK_IN);
0050     if (ret < 0) {
0051         dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
0052         return ret;
0053     }
0054 
0055     ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL,
0056                   CZ_PLAT_CLK, DA7219_PLL_FREQ_OUT_98304);
0057     if (ret < 0) {
0058         dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
0059         return ret;
0060     }
0061 
0062     da7219_dai_wclk = devm_clk_get(component->dev, "da7219-dai-wclk");
0063     if (IS_ERR(da7219_dai_wclk))
0064         return PTR_ERR(da7219_dai_wclk);
0065 
0066     da7219_dai_bclk = devm_clk_get(component->dev, "da7219-dai-bclk");
0067     if (IS_ERR(da7219_dai_bclk))
0068         return PTR_ERR(da7219_dai_bclk);
0069 
0070     ret = snd_soc_card_jack_new(card, "Headset Jack",
0071                 SND_JACK_HEADSET | SND_JACK_LINEOUT |
0072                 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0073                 SND_JACK_BTN_2 | SND_JACK_BTN_3,
0074                 &cz_jack);
0075     if (ret) {
0076         dev_err(card->dev, "HP jack creation failed %d\n", ret);
0077         return ret;
0078     }
0079 
0080     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0081     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
0082     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
0083     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
0084 
0085     da7219_aad_jack_det(component, &cz_jack);
0086 
0087     return 0;
0088 }
0089 
0090 static int da7219_clk_enable(struct snd_pcm_substream *substream)
0091 {
0092     int ret = 0;
0093     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0094 
0095     /*
0096      * Set wclk to 48000 because the rate constraint of this driver is
0097      * 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate that is
0098      * minimum of 64x the LRCLK sample rate." DA7219 is the only clk
0099      * source so for all codecs we have to limit bclk to 64X lrclk.
0100      */
0101     clk_set_rate(da7219_dai_wclk, 48000);
0102     clk_set_rate(da7219_dai_bclk, 48000 * 64);
0103     ret = clk_prepare_enable(da7219_dai_bclk);
0104     if (ret < 0) {
0105         dev_err(rtd->dev, "can't enable master clock %d\n", ret);
0106         return ret;
0107     }
0108 
0109     return ret;
0110 }
0111 
0112 static void da7219_clk_disable(void)
0113 {
0114     clk_disable_unprepare(da7219_dai_bclk);
0115 }
0116 
0117 static int cz_rt5682_init(struct snd_soc_pcm_runtime *rtd)
0118 {
0119     int ret;
0120     struct snd_soc_card *card = rtd->card;
0121     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0122     struct snd_soc_component *component = codec_dai->component;
0123 
0124     dev_info(codec_dai->dev, "codec dai name = %s\n", codec_dai->name);
0125 
0126     /* Set codec sysclk */
0127     ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
0128                      RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
0129     if (ret < 0) {
0130         dev_err(codec_dai->dev,
0131             "Failed to set rt5682 SYSCLK: %d\n", ret);
0132         return ret;
0133     }
0134     /* set codec PLL */
0135     ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
0136                   CZ_PLAT_CLK, RT5682_PLL_FREQ);
0137     if (ret < 0) {
0138         dev_err(codec_dai->dev, "can't set rt5682 PLL: %d\n", ret);
0139         return ret;
0140     }
0141 
0142     rt5682_dai_wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
0143     if (IS_ERR(rt5682_dai_wclk))
0144         return PTR_ERR(rt5682_dai_wclk);
0145 
0146     rt5682_dai_bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
0147     if (IS_ERR(rt5682_dai_bclk))
0148         return PTR_ERR(rt5682_dai_bclk);
0149 
0150     ret = snd_soc_card_jack_new(card, "Headset Jack",
0151                     SND_JACK_HEADSET | SND_JACK_LINEOUT |
0152                     SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0153                     SND_JACK_BTN_2 | SND_JACK_BTN_3,
0154                     &cz_jack);
0155     if (ret) {
0156         dev_err(card->dev, "HP jack creation failed %d\n", ret);
0157         return ret;
0158     }
0159 
0160     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0161     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
0162     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
0163     snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
0164 
0165     ret = snd_soc_component_set_jack(component, &cz_jack, NULL);
0166     if (ret) {
0167         dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
0168         return ret;
0169     }
0170     return 0;
0171 }
0172 
0173 static int rt5682_clk_enable(struct snd_pcm_substream *substream)
0174 {
0175     int ret;
0176     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0177 
0178     /*
0179      * Set wclk to 48000 because the rate constraint of this driver is
0180      * 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate that is
0181      * minimum of 64x the LRCLK sample rate." RT5682 is the only clk
0182      * source so for all codecs we have to limit bclk to 64X lrclk.
0183      */
0184     ret = clk_set_rate(rt5682_dai_wclk, 48000);
0185     if (ret) {
0186         dev_err(rtd->dev, "Error setting wclk rate: %d\n", ret);
0187         return ret;
0188     }
0189     ret = clk_set_rate(rt5682_dai_bclk, 48000 * 64);
0190     if (ret) {
0191         dev_err(rtd->dev, "Error setting bclk rate: %d\n", ret);
0192         return ret;
0193     }
0194     ret = clk_prepare_enable(rt5682_dai_wclk);
0195     if (ret < 0) {
0196         dev_err(rtd->dev, "can't enable wclk %d\n", ret);
0197         return ret;
0198     }
0199     return ret;
0200 }
0201 
0202 static void rt5682_clk_disable(void)
0203 {
0204     clk_disable_unprepare(rt5682_dai_wclk);
0205 }
0206 
0207 static const unsigned int channels[] = {
0208     DUAL_CHANNEL,
0209 };
0210 
0211 static const unsigned int rates[] = {
0212     48000,
0213 };
0214 
0215 static const struct snd_pcm_hw_constraint_list constraints_rates = {
0216     .count = ARRAY_SIZE(rates),
0217     .list  = rates,
0218     .mask = 0,
0219 };
0220 
0221 static const struct snd_pcm_hw_constraint_list constraints_channels = {
0222     .count = ARRAY_SIZE(channels),
0223     .list = channels,
0224     .mask = 0,
0225 };
0226 
0227 static int cz_da7219_play_startup(struct snd_pcm_substream *substream)
0228 {
0229     struct snd_pcm_runtime *runtime = substream->runtime;
0230     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0231     struct snd_soc_card *card = rtd->card;
0232     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0233 
0234     /*
0235      * On this platform for PCM device we support stereo
0236      */
0237 
0238     runtime->hw.channels_max = DUAL_CHANNEL;
0239     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0240                    &constraints_channels);
0241     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0242                    &constraints_rates);
0243 
0244     machine->play_i2s_instance = I2S_SP_INSTANCE;
0245     return da7219_clk_enable(substream);
0246 }
0247 
0248 static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
0249 {
0250     struct snd_pcm_runtime *runtime = substream->runtime;
0251     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0252     struct snd_soc_card *card = rtd->card;
0253     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0254 
0255     /*
0256      * On this platform for PCM device we support stereo
0257      */
0258 
0259     runtime->hw.channels_max = DUAL_CHANNEL;
0260     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0261                    &constraints_channels);
0262     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0263                    &constraints_rates);
0264 
0265     machine->cap_i2s_instance = I2S_SP_INSTANCE;
0266     machine->capture_channel = CAP_CHANNEL1;
0267     return da7219_clk_enable(substream);
0268 }
0269 
0270 static int cz_max_startup(struct snd_pcm_substream *substream)
0271 {
0272     struct snd_pcm_runtime *runtime = substream->runtime;
0273     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0274     struct snd_soc_card *card = rtd->card;
0275     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0276 
0277     /*
0278      * On this platform for PCM device we support stereo
0279      */
0280 
0281     runtime->hw.channels_max = DUAL_CHANNEL;
0282     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0283                    &constraints_channels);
0284     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0285                    &constraints_rates);
0286 
0287     machine->play_i2s_instance = I2S_BT_INSTANCE;
0288     return da7219_clk_enable(substream);
0289 }
0290 
0291 static int cz_dmic0_startup(struct snd_pcm_substream *substream)
0292 {
0293     struct snd_pcm_runtime *runtime = substream->runtime;
0294     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0295     struct snd_soc_card *card = rtd->card;
0296     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0297 
0298     /*
0299      * On this platform for PCM device we support stereo
0300      */
0301 
0302     runtime->hw.channels_max = DUAL_CHANNEL;
0303     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0304                    &constraints_channels);
0305     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0306                    &constraints_rates);
0307 
0308     machine->cap_i2s_instance = I2S_BT_INSTANCE;
0309     return da7219_clk_enable(substream);
0310 }
0311 
0312 static int cz_dmic1_startup(struct snd_pcm_substream *substream)
0313 {
0314     struct snd_pcm_runtime *runtime = substream->runtime;
0315     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0316     struct snd_soc_card *card = rtd->card;
0317     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0318 
0319     /*
0320      * On this platform for PCM device we support stereo
0321      */
0322 
0323     runtime->hw.channels_max = DUAL_CHANNEL;
0324     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0325                    &constraints_channels);
0326     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0327                    &constraints_rates);
0328 
0329     machine->cap_i2s_instance = I2S_SP_INSTANCE;
0330     machine->capture_channel = CAP_CHANNEL0;
0331     return da7219_clk_enable(substream);
0332 }
0333 
0334 static void cz_da7219_shutdown(struct snd_pcm_substream *substream)
0335 {
0336     da7219_clk_disable();
0337 }
0338 
0339 static int cz_rt5682_play_startup(struct snd_pcm_substream *substream)
0340 {
0341     struct snd_pcm_runtime *runtime = substream->runtime;
0342     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0343     struct snd_soc_card *card = rtd->card;
0344     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0345 
0346     /*
0347      * On this platform for PCM device we support stereo
0348      */
0349 
0350     runtime->hw.channels_max = DUAL_CHANNEL;
0351     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0352                    &constraints_channels);
0353     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0354                    &constraints_rates);
0355 
0356     machine->play_i2s_instance = I2S_SP_INSTANCE;
0357     return rt5682_clk_enable(substream);
0358 }
0359 
0360 static int cz_rt5682_cap_startup(struct snd_pcm_substream *substream)
0361 {
0362     struct snd_pcm_runtime *runtime = substream->runtime;
0363     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0364     struct snd_soc_card *card = rtd->card;
0365     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0366 
0367     /*
0368      * On this platform for PCM device we support stereo
0369      */
0370 
0371     runtime->hw.channels_max = DUAL_CHANNEL;
0372     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0373                    &constraints_channels);
0374     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0375                    &constraints_rates);
0376 
0377     machine->cap_i2s_instance = I2S_SP_INSTANCE;
0378     machine->capture_channel = CAP_CHANNEL1;
0379     return rt5682_clk_enable(substream);
0380 }
0381 
0382 static int cz_rt5682_max_startup(struct snd_pcm_substream *substream)
0383 {
0384     struct snd_pcm_runtime *runtime = substream->runtime;
0385     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0386     struct snd_soc_card *card = rtd->card;
0387     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0388 
0389     /*
0390      * On this platform for PCM device we support stereo
0391      */
0392 
0393     runtime->hw.channels_max = DUAL_CHANNEL;
0394     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0395                    &constraints_channels);
0396     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0397                    &constraints_rates);
0398 
0399     machine->play_i2s_instance = I2S_BT_INSTANCE;
0400     return rt5682_clk_enable(substream);
0401 }
0402 
0403 static int cz_rt5682_dmic0_startup(struct snd_pcm_substream *substream)
0404 {
0405     struct snd_pcm_runtime *runtime = substream->runtime;
0406     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0407     struct snd_soc_card *card = rtd->card;
0408     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0409 
0410     /*
0411      * On this platform for PCM device we support stereo
0412      */
0413 
0414     runtime->hw.channels_max = DUAL_CHANNEL;
0415     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0416                    &constraints_channels);
0417     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0418                    &constraints_rates);
0419 
0420     machine->cap_i2s_instance = I2S_BT_INSTANCE;
0421     return rt5682_clk_enable(substream);
0422 }
0423 
0424 static int cz_rt5682_dmic1_startup(struct snd_pcm_substream *substream)
0425 {
0426     struct snd_pcm_runtime *runtime = substream->runtime;
0427     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0428     struct snd_soc_card *card = rtd->card;
0429     struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
0430 
0431     /*
0432      * On this platform for PCM device we support stereo
0433      */
0434 
0435     runtime->hw.channels_max = DUAL_CHANNEL;
0436     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0437                    &constraints_channels);
0438     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
0439                    &constraints_rates);
0440 
0441     machine->cap_i2s_instance = I2S_SP_INSTANCE;
0442     machine->capture_channel = CAP_CHANNEL0;
0443     return rt5682_clk_enable(substream);
0444 }
0445 
0446 static void cz_rt5682_shutdown(struct snd_pcm_substream *substream)
0447 {
0448     rt5682_clk_disable();
0449 }
0450 
0451 static const struct snd_soc_ops cz_da7219_play_ops = {
0452     .startup = cz_da7219_play_startup,
0453     .shutdown = cz_da7219_shutdown,
0454 };
0455 
0456 static const struct snd_soc_ops cz_da7219_cap_ops = {
0457     .startup = cz_da7219_cap_startup,
0458     .shutdown = cz_da7219_shutdown,
0459 };
0460 
0461 static const struct snd_soc_ops cz_max_play_ops = {
0462     .startup = cz_max_startup,
0463     .shutdown = cz_da7219_shutdown,
0464 };
0465 
0466 static const struct snd_soc_ops cz_dmic0_cap_ops = {
0467     .startup = cz_dmic0_startup,
0468     .shutdown = cz_da7219_shutdown,
0469 };
0470 
0471 static const struct snd_soc_ops cz_dmic1_cap_ops = {
0472     .startup = cz_dmic1_startup,
0473     .shutdown = cz_da7219_shutdown,
0474 };
0475 
0476 static const struct snd_soc_ops cz_rt5682_play_ops = {
0477     .startup = cz_rt5682_play_startup,
0478     .shutdown = cz_rt5682_shutdown,
0479 };
0480 
0481 static const struct snd_soc_ops cz_rt5682_cap_ops = {
0482     .startup = cz_rt5682_cap_startup,
0483     .shutdown = cz_rt5682_shutdown,
0484 };
0485 
0486 static const struct snd_soc_ops cz_rt5682_max_play_ops = {
0487     .startup = cz_rt5682_max_startup,
0488     .shutdown = cz_rt5682_shutdown,
0489 };
0490 
0491 static const struct snd_soc_ops cz_rt5682_dmic0_cap_ops = {
0492     .startup = cz_rt5682_dmic0_startup,
0493     .shutdown = cz_rt5682_shutdown,
0494 };
0495 
0496 static const struct snd_soc_ops cz_rt5682_dmic1_cap_ops = {
0497     .startup = cz_rt5682_dmic1_startup,
0498     .shutdown = cz_rt5682_shutdown,
0499 };
0500 
0501 SND_SOC_DAILINK_DEF(designware1,
0502     DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));
0503 SND_SOC_DAILINK_DEF(designware2,
0504     DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
0505 SND_SOC_DAILINK_DEF(designware3,
0506     DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.3.auto")));
0507 
0508 SND_SOC_DAILINK_DEF(dlgs,
0509     DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", "da7219-hifi")));
0510 SND_SOC_DAILINK_DEF(rt5682,
0511     DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
0512 SND_SOC_DAILINK_DEF(mx,
0513     DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));
0514 SND_SOC_DAILINK_DEF(adau,
0515     DAILINK_COMP_ARRAY(COMP_CODEC("ADAU7002:00", "adau7002-hifi")));
0516 
0517 SND_SOC_DAILINK_DEF(platform,
0518     DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));
0519 
0520 static struct snd_soc_dai_link cz_dai_7219_98357[] = {
0521     {
0522         .name = "amd-da7219-play",
0523         .stream_name = "Playback",
0524         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0525                 | SND_SOC_DAIFMT_CBP_CFP,
0526         .init = cz_da7219_init,
0527         .dpcm_playback = 1,
0528         .stop_dma_first = 1,
0529         .ops = &cz_da7219_play_ops,
0530         SND_SOC_DAILINK_REG(designware1, dlgs, platform),
0531     },
0532     {
0533         .name = "amd-da7219-cap",
0534         .stream_name = "Capture",
0535         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0536                 | SND_SOC_DAIFMT_CBP_CFP,
0537         .dpcm_capture = 1,
0538         .stop_dma_first = 1,
0539         .ops = &cz_da7219_cap_ops,
0540         SND_SOC_DAILINK_REG(designware2, dlgs, platform),
0541     },
0542     {
0543         .name = "amd-max98357-play",
0544         .stream_name = "HiFi Playback",
0545         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0546                 | SND_SOC_DAIFMT_CBP_CFP,
0547         .dpcm_playback = 1,
0548         .stop_dma_first = 1,
0549         .ops = &cz_max_play_ops,
0550         SND_SOC_DAILINK_REG(designware3, mx, platform),
0551     },
0552     {
0553         /* C panel DMIC */
0554         .name = "dmic0",
0555         .stream_name = "DMIC0 Capture",
0556         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0557                 | SND_SOC_DAIFMT_CBP_CFP,
0558         .dpcm_capture = 1,
0559         .stop_dma_first = 1,
0560         .ops = &cz_dmic0_cap_ops,
0561         SND_SOC_DAILINK_REG(designware3, adau, platform),
0562     },
0563     {
0564         /* A/B panel DMIC */
0565         .name = "dmic1",
0566         .stream_name = "DMIC1 Capture",
0567         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0568                 | SND_SOC_DAIFMT_CBP_CFP,
0569         .dpcm_capture = 1,
0570         .stop_dma_first = 1,
0571         .ops = &cz_dmic1_cap_ops,
0572         SND_SOC_DAILINK_REG(designware2, adau, platform),
0573     },
0574 };
0575 
0576 static struct snd_soc_dai_link cz_dai_5682_98357[] = {
0577     {
0578         .name = "amd-rt5682-play",
0579         .stream_name = "Playback",
0580         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0581                 | SND_SOC_DAIFMT_CBP_CFP,
0582         .init = cz_rt5682_init,
0583         .dpcm_playback = 1,
0584         .stop_dma_first = 1,
0585         .ops = &cz_rt5682_play_ops,
0586         SND_SOC_DAILINK_REG(designware1, rt5682, platform),
0587     },
0588     {
0589         .name = "amd-rt5682-cap",
0590         .stream_name = "Capture",
0591         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0592                 | SND_SOC_DAIFMT_CBP_CFP,
0593         .dpcm_capture = 1,
0594         .stop_dma_first = 1,
0595         .ops = &cz_rt5682_cap_ops,
0596         SND_SOC_DAILINK_REG(designware2, rt5682, platform),
0597     },
0598     {
0599         .name = "amd-max98357-play",
0600         .stream_name = "HiFi Playback",
0601         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0602                 | SND_SOC_DAIFMT_CBP_CFP,
0603         .dpcm_playback = 1,
0604         .stop_dma_first = 1,
0605         .ops = &cz_rt5682_max_play_ops,
0606         SND_SOC_DAILINK_REG(designware3, mx, platform),
0607     },
0608     {
0609         /* C panel DMIC */
0610         .name = "dmic0",
0611         .stream_name = "DMIC0 Capture",
0612         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0613                 | SND_SOC_DAIFMT_CBP_CFP,
0614         .dpcm_capture = 1,
0615         .stop_dma_first = 1,
0616         .ops = &cz_rt5682_dmic0_cap_ops,
0617         SND_SOC_DAILINK_REG(designware3, adau, platform),
0618     },
0619     {
0620         /* A/B panel DMIC */
0621         .name = "dmic1",
0622         .stream_name = "DMIC1 Capture",
0623         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0624                 | SND_SOC_DAIFMT_CBP_CFP,
0625         .dpcm_capture = 1,
0626         .stop_dma_first = 1,
0627         .ops = &cz_rt5682_dmic1_cap_ops,
0628         SND_SOC_DAILINK_REG(designware2, adau, platform),
0629     },
0630 };
0631 
0632 static const struct snd_soc_dapm_widget cz_widgets[] = {
0633     SND_SOC_DAPM_HP("Headphones", NULL),
0634     SND_SOC_DAPM_SPK("Speakers", NULL),
0635     SND_SOC_DAPM_MIC("Headset Mic", NULL),
0636     SND_SOC_DAPM_MIC("Int Mic", NULL),
0637 };
0638 
0639 static const struct snd_soc_dapm_route cz_audio_route[] = {
0640     {"Headphones", NULL, "HPL"},
0641     {"Headphones", NULL, "HPR"},
0642     {"MIC", NULL, "Headset Mic"},
0643     {"Speakers", NULL, "Speaker"},
0644     {"PDM_DAT", NULL, "Int Mic"},
0645 };
0646 
0647 static const struct snd_soc_dapm_route cz_rt5682_audio_route[] = {
0648     {"Headphones", NULL, "HPOL"},
0649     {"Headphones", NULL, "HPOR"},
0650     {"IN1P", NULL, "Headset Mic"},
0651     {"Speakers", NULL, "Speaker"},
0652     {"PDM_DAT", NULL, "Int Mic"},
0653 };
0654 
0655 static const struct snd_kcontrol_new cz_mc_controls[] = {
0656     SOC_DAPM_PIN_SWITCH("Headphones"),
0657     SOC_DAPM_PIN_SWITCH("Speakers"),
0658     SOC_DAPM_PIN_SWITCH("Headset Mic"),
0659     SOC_DAPM_PIN_SWITCH("Int Mic"),
0660 };
0661 
0662 static struct snd_soc_card cz_card = {
0663     .name = "acpd7219m98357",
0664     .owner = THIS_MODULE,
0665     .dai_link = cz_dai_7219_98357,
0666     .num_links = ARRAY_SIZE(cz_dai_7219_98357),
0667     .dapm_widgets = cz_widgets,
0668     .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
0669     .dapm_routes = cz_audio_route,
0670     .num_dapm_routes = ARRAY_SIZE(cz_audio_route),
0671     .controls = cz_mc_controls,
0672     .num_controls = ARRAY_SIZE(cz_mc_controls),
0673 };
0674 
0675 static struct snd_soc_card cz_rt5682_card = {
0676     .name = "acpr5682m98357",
0677     .owner = THIS_MODULE,
0678     .dai_link = cz_dai_5682_98357,
0679     .num_links = ARRAY_SIZE(cz_dai_5682_98357),
0680     .dapm_widgets = cz_widgets,
0681     .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
0682     .dapm_routes = cz_rt5682_audio_route,
0683     .controls = cz_mc_controls,
0684     .num_controls = ARRAY_SIZE(cz_mc_controls),
0685 };
0686 
0687 void *acp_soc_is_rltk_max(struct device *dev)
0688 {
0689     const struct acpi_device_id *match;
0690 
0691     match = acpi_match_device(dev->driver->acpi_match_table, dev);
0692     if (!match)
0693         return NULL;
0694     return (void *)match->driver_data;
0695 }
0696 
0697 static struct regulator_consumer_supply acp_da7219_supplies[] = {
0698     REGULATOR_SUPPLY("VDD", "i2c-DLGS7219:00"),
0699     REGULATOR_SUPPLY("VDDMIC", "i2c-DLGS7219:00"),
0700     REGULATOR_SUPPLY("VDDIO", "i2c-DLGS7219:00"),
0701     REGULATOR_SUPPLY("IOVDD", "ADAU7002:00"),
0702 };
0703 
0704 static struct regulator_init_data acp_da7219_data = {
0705     .constraints = {
0706         .always_on = 1,
0707     },
0708     .num_consumer_supplies = ARRAY_SIZE(acp_da7219_supplies),
0709     .consumer_supplies = acp_da7219_supplies,
0710 };
0711 
0712 static struct regulator_config acp_da7219_cfg = {
0713     .init_data = &acp_da7219_data,
0714 };
0715 
0716 static struct regulator_ops acp_da7219_ops = {
0717 };
0718 
0719 static const struct regulator_desc acp_da7219_desc = {
0720     .name = "reg-fixed-1.8V",
0721     .type = REGULATOR_VOLTAGE,
0722     .owner = THIS_MODULE,
0723     .ops = &acp_da7219_ops,
0724     .fixed_uV = 1800000, /* 1.8V */
0725     .n_voltages = 1,
0726 };
0727 
0728 static int cz_probe(struct platform_device *pdev)
0729 {
0730     int ret;
0731     struct snd_soc_card *card;
0732     struct acp_platform_info *machine;
0733     struct regulator_dev *rdev;
0734     struct device *dev = &pdev->dev;
0735 
0736     card = (struct snd_soc_card *)acp_soc_is_rltk_max(dev);
0737     if (!card)
0738         return -ENODEV;
0739     if (!strcmp(card->name, "acpd7219m98357")) {
0740         acp_da7219_cfg.dev = &pdev->dev;
0741         rdev = devm_regulator_register(&pdev->dev, &acp_da7219_desc,
0742                            &acp_da7219_cfg);
0743         if (IS_ERR(rdev)) {
0744             dev_err(&pdev->dev, "Failed to register regulator: %d\n",
0745                 (int)PTR_ERR(rdev));
0746             return -EINVAL;
0747         }
0748     }
0749 
0750     machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info),
0751                    GFP_KERNEL);
0752     if (!machine)
0753         return -ENOMEM;
0754     card->dev = &pdev->dev;
0755     platform_set_drvdata(pdev, card);
0756     snd_soc_card_set_drvdata(card, machine);
0757     ret = devm_snd_soc_register_card(&pdev->dev, card);
0758     if (ret) {
0759         return dev_err_probe(&pdev->dev, ret,
0760                 "devm_snd_soc_register_card(%s) failed\n",
0761                 card->name);
0762     }
0763     acp_bt_uart_enable = !device_property_read_bool(&pdev->dev,
0764                             "bt-pad-enable");
0765     return 0;
0766 }
0767 
0768 #ifdef CONFIG_ACPI
0769 static const struct acpi_device_id cz_audio_acpi_match[] = {
0770     { "AMD7219", (unsigned long)&cz_card },
0771     { "AMDI5682", (unsigned long)&cz_rt5682_card},
0772     {},
0773 };
0774 MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
0775 #endif
0776 
0777 static struct platform_driver cz_pcm_driver = {
0778     .driver = {
0779         .name = "cz-da7219-max98357a",
0780         .acpi_match_table = ACPI_PTR(cz_audio_acpi_match),
0781         .pm = &snd_soc_pm_ops,
0782     },
0783     .probe = cz_probe,
0784 };
0785 
0786 module_platform_driver(cz_pcm_driver);
0787 
0788 MODULE_AUTHOR("akshu.agrawal@amd.com");
0789 MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
0790 MODULE_DESCRIPTION("DA7219, RT5682 & MAX98357A audio support");
0791 MODULE_LICENSE("GPL v2");