Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // mt8186-mt6366-rt1019-rt5682s.c
0004 //  --  MT8186-MT6366-RT1019-RT5682S ALSA SoC machine driver
0005 //
0006 // Copyright (c) 2022 MediaTek Inc.
0007 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
0008 //
0009 
0010 #include <linux/input.h>
0011 #include <linux/module.h>
0012 #include <linux/of_device.h>
0013 #include <linux/pm_runtime.h>
0014 #include <sound/jack.h>
0015 #include <sound/pcm_params.h>
0016 #include <sound/rt5682.h>
0017 #include <sound/soc.h>
0018 
0019 #include "../../codecs/mt6358.h"
0020 #include "../../codecs/rt5682.h"
0021 #include "../common/mtk-afe-platform-driver.h"
0022 #include "mt8186-afe-common.h"
0023 #include "mt8186-afe-clk.h"
0024 #include "mt8186-afe-gpio.h"
0025 #include "mt8186-mt6366-common.h"
0026 
0027 #define RT1019_CODEC_DAI    "HiFi"
0028 #define RT1019_DEV0_NAME    "rt1019p"
0029 
0030 #define RT5682S_CODEC_DAI   "rt5682s-aif1"
0031 #define RT5682S_DEV0_NAME   "rt5682s.5-001a"
0032 
0033 struct mt8186_mt6366_rt1019_rt5682s_priv {
0034     struct snd_soc_jack headset_jack, hdmi_jack;
0035 };
0036 
0037 static struct snd_soc_codec_conf mt8186_mt6366_rt1019_rt5682s_codec_conf[] = {
0038     {
0039         .dlc = COMP_CODEC_CONF("mt6358-sound"),
0040         .name_prefix = "Mt6366",
0041     },
0042     {
0043         .dlc = COMP_CODEC_CONF("bt-sco"),
0044         .name_prefix = "Mt8186 bt",
0045     },
0046     {
0047         .dlc = COMP_CODEC_CONF("hdmi-audio-codec"),
0048         .name_prefix = "Mt8186 hdmi",
0049     },
0050 };
0051 
0052 static int mt8186_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
0053 {
0054     struct mt8186_mt6366_rt1019_rt5682s_priv *priv =
0055         snd_soc_card_get_drvdata(rtd->card);
0056     struct snd_soc_jack *jack = &priv->headset_jack;
0057     struct snd_soc_component *cmpnt_codec =
0058         asoc_rtd_to_codec(rtd, 0)->component;
0059     int ret;
0060 
0061     ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
0062                     SND_JACK_HEADSET | SND_JACK_BTN_0 |
0063                     SND_JACK_BTN_1 | SND_JACK_BTN_2 |
0064                     SND_JACK_BTN_3,
0065                     jack);
0066     if (ret) {
0067         dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
0068         return ret;
0069     }
0070 
0071     snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0072     snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0073     snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0074     snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0075 
0076     return snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
0077 }
0078 
0079 static int mt8186_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,
0080                     struct snd_pcm_hw_params *params)
0081 {
0082     struct snd_soc_pcm_runtime *rtd = substream->private_data;
0083     struct snd_soc_card *card = rtd->card;
0084     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0085     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0086     unsigned int rate = params_rate(params);
0087     unsigned int mclk_fs_ratio = 128;
0088     unsigned int mclk_fs = rate * mclk_fs_ratio;
0089     int bitwidth;
0090     int ret;
0091 
0092     bitwidth = snd_pcm_format_width(params_format(params));
0093     if (bitwidth < 0) {
0094         dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
0095         return bitwidth;
0096     }
0097 
0098     ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
0099     if (ret) {
0100         dev_err(card->dev, "failed to set tdm slot\n");
0101         return ret;
0102     }
0103 
0104     ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
0105                   RT5682_PLL1_S_BCLK1,
0106                   params_rate(params) * 64,
0107                   params_rate(params) * 512);
0108     if (ret) {
0109         dev_err(card->dev, "failed to set pll\n");
0110         return ret;
0111     }
0112 
0113     ret = snd_soc_dai_set_sysclk(codec_dai,
0114                      RT5682_SCLK_S_PLL1,
0115                      params_rate(params) * 512,
0116                      SND_SOC_CLOCK_IN);
0117     if (ret) {
0118         dev_err(card->dev, "failed to set sysclk\n");
0119         return ret;
0120     }
0121 
0122     return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
0123 }
0124 
0125 static const struct snd_soc_ops mt8186_rt5682s_i2s_ops = {
0126     .hw_params = mt8186_rt5682s_i2s_hw_params,
0127 };
0128 
0129 static int mt8186_mt6366_rt1019_rt5682s_hdmi_init(struct snd_soc_pcm_runtime *rtd)
0130 {
0131     struct snd_soc_component *cmpnt_codec =
0132         asoc_rtd_to_codec(rtd, 0)->component;
0133     struct mt8186_mt6366_rt1019_rt5682s_priv *priv =
0134         snd_soc_card_get_drvdata(rtd->card);
0135     int ret;
0136 
0137     ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, &priv->hdmi_jack);
0138     if (ret) {
0139         dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
0140         return ret;
0141     }
0142 
0143     return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
0144 }
0145 
0146 static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0147                   struct snd_pcm_hw_params *params,
0148                   snd_pcm_format_t fmt)
0149 {
0150     struct snd_interval *channels = hw_param_interval(params,
0151         SNDRV_PCM_HW_PARAM_CHANNELS);
0152 
0153     dev_dbg(rtd->dev, "%s(), fix format to %d\n", __func__, fmt);
0154 
0155     /* fix BE i2s channel to 2 channel */
0156     channels->min = 2;
0157     channels->max = 2;
0158 
0159     /* clean param mask first */
0160     snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
0161                  0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
0162 
0163     params_set_format(params, fmt);
0164 
0165     return 0;
0166 }
0167 
0168 static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0169                       struct snd_pcm_hw_params *params)
0170 {
0171     return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE);
0172 }
0173 
0174 static int mt8186_it6505_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0175                          struct snd_pcm_hw_params *params)
0176 {
0177     return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE);
0178 }
0179 
0180 static int mt8186_mt6366_rt1019_rt5682s_playback_startup(struct snd_pcm_substream *substream)
0181 {
0182     static const unsigned int rates[] = {
0183         48000
0184     };
0185     static const unsigned int channels[] = {
0186         2
0187     };
0188     static const struct snd_pcm_hw_constraint_list constraints_rates = {
0189         .count = ARRAY_SIZE(rates),
0190         .list  = rates,
0191         .mask = 0,
0192     };
0193     static const struct snd_pcm_hw_constraint_list constraints_channels = {
0194         .count = ARRAY_SIZE(channels),
0195         .list  = channels,
0196         .mask = 0,
0197     };
0198 
0199     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0200     struct snd_pcm_runtime *runtime = substream->runtime;
0201     int ret;
0202 
0203     ret = snd_pcm_hw_constraint_list(runtime, 0,
0204                      SNDRV_PCM_HW_PARAM_RATE,
0205                      &constraints_rates);
0206     if (ret < 0) {
0207         dev_err(rtd->dev, "hw_constraint_list rate failed\n");
0208         return ret;
0209     }
0210 
0211     ret = snd_pcm_hw_constraint_list(runtime, 0,
0212                      SNDRV_PCM_HW_PARAM_CHANNELS,
0213                      &constraints_channels);
0214     if (ret < 0) {
0215         dev_err(rtd->dev, "hw_constraint_list channel failed\n");
0216         return ret;
0217     }
0218 
0219     return 0;
0220 }
0221 
0222 static const struct snd_soc_ops mt8186_mt6366_rt1019_rt5682s_playback_ops = {
0223     .startup = mt8186_mt6366_rt1019_rt5682s_playback_startup,
0224 };
0225 
0226 static int mt8186_mt6366_rt1019_rt5682s_capture_startup(struct snd_pcm_substream *substream)
0227 {
0228     static const unsigned int rates[] = {
0229         48000
0230     };
0231     static const unsigned int channels[] = {
0232         1, 2
0233     };
0234     static const struct snd_pcm_hw_constraint_list constraints_rates = {
0235         .count = ARRAY_SIZE(rates),
0236         .list  = rates,
0237         .mask = 0,
0238     };
0239     static const struct snd_pcm_hw_constraint_list constraints_channels = {
0240         .count = ARRAY_SIZE(channels),
0241         .list  = channels,
0242         .mask = 0,
0243     };
0244 
0245     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0246     struct snd_pcm_runtime *runtime = substream->runtime;
0247     int ret;
0248 
0249     ret = snd_pcm_hw_constraint_list(runtime, 0,
0250                      SNDRV_PCM_HW_PARAM_RATE,
0251                      &constraints_rates);
0252     if (ret < 0) {
0253         dev_err(rtd->dev, "hw_constraint_list rate failed\n");
0254         return ret;
0255     }
0256 
0257     ret = snd_pcm_hw_constraint_list(runtime, 0,
0258                      SNDRV_PCM_HW_PARAM_CHANNELS,
0259                      &constraints_channels);
0260     if (ret < 0) {
0261         dev_err(rtd->dev, "hw_constraint_list channel failed\n");
0262         return ret;
0263     }
0264 
0265     return 0;
0266 }
0267 
0268 static const struct snd_soc_ops mt8186_mt6366_rt1019_rt5682s_capture_ops = {
0269     .startup = mt8186_mt6366_rt1019_rt5682s_capture_startup,
0270 };
0271 
0272 /* FE */
0273 SND_SOC_DAILINK_DEFS(playback1,
0274              DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
0275              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0276              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0277 
0278 SND_SOC_DAILINK_DEFS(playback12,
0279              DAILINK_COMP_ARRAY(COMP_CPU("DL12")),
0280              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0281              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0282 
0283 SND_SOC_DAILINK_DEFS(playback2,
0284              DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
0285              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0286              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0287 
0288 SND_SOC_DAILINK_DEFS(playback3,
0289              DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
0290              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0291              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0292 
0293 SND_SOC_DAILINK_DEFS(playback4,
0294              DAILINK_COMP_ARRAY(COMP_CPU("DL4")),
0295              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0296              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0297 
0298 SND_SOC_DAILINK_DEFS(playback5,
0299              DAILINK_COMP_ARRAY(COMP_CPU("DL5")),
0300              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0301              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0302 
0303 SND_SOC_DAILINK_DEFS(playback6,
0304              DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
0305              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0306              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0307 
0308 SND_SOC_DAILINK_DEFS(playback7,
0309              DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
0310              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0311              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0312 
0313 SND_SOC_DAILINK_DEFS(playback8,
0314              DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
0315              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0316              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0317 
0318 SND_SOC_DAILINK_DEFS(capture1,
0319              DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
0320              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0321              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0322 
0323 SND_SOC_DAILINK_DEFS(capture2,
0324              DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
0325              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0326              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0327 
0328 SND_SOC_DAILINK_DEFS(capture3,
0329              DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
0330              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0331              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0332 
0333 SND_SOC_DAILINK_DEFS(capture4,
0334              DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
0335              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0336              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0337 
0338 SND_SOC_DAILINK_DEFS(capture5,
0339              DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
0340              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0341              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0342 
0343 SND_SOC_DAILINK_DEFS(capture6,
0344              DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
0345              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0346              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0347 
0348 SND_SOC_DAILINK_DEFS(capture7,
0349              DAILINK_COMP_ARRAY(COMP_CPU("UL7")),
0350              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0351              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0352 
0353 /* hostless */
0354 SND_SOC_DAILINK_DEFS(hostless_lpbk,
0355              DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")),
0356              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0357              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0358 SND_SOC_DAILINK_DEFS(hostless_fm,
0359              DAILINK_COMP_ARRAY(COMP_CPU("Hostless FM DAI")),
0360              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0361              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0362 SND_SOC_DAILINK_DEFS(hostless_src1,
0363              DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_1_DAI")),
0364              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0365              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0366 SND_SOC_DAILINK_DEFS(hostless_src_bargein,
0367              DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_Bargein_DAI")),
0368              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0369              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0370 
0371 /* BE */
0372 SND_SOC_DAILINK_DEFS(adda,
0373              DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
0374              DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound",
0375                            "mt6358-snd-codec-aif1"),
0376                     COMP_CODEC("dmic-codec",
0377                            "dmic-hifi")),
0378              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0379 SND_SOC_DAILINK_DEFS(i2s0,
0380              DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
0381              DAILINK_COMP_ARRAY(COMP_EMPTY()),
0382              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0383 SND_SOC_DAILINK_DEFS(i2s1,
0384              DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
0385              DAILINK_COMP_ARRAY(COMP_EMPTY()),
0386              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0387 SND_SOC_DAILINK_DEFS(i2s2,
0388              DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
0389              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0390              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0391 SND_SOC_DAILINK_DEFS(i2s3,
0392              DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
0393              DAILINK_COMP_ARRAY(COMP_EMPTY()),
0394              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0395 SND_SOC_DAILINK_DEFS(hw_gain1,
0396              DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 1")),
0397              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0398              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0399 SND_SOC_DAILINK_DEFS(hw_gain2,
0400              DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 2")),
0401              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0402              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0403 SND_SOC_DAILINK_DEFS(hw_src1,
0404              DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_1")),
0405              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0406              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0407 SND_SOC_DAILINK_DEFS(hw_src2,
0408              DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_2")),
0409              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0410              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0411 SND_SOC_DAILINK_DEFS(connsys_i2s,
0412              DAILINK_COMP_ARRAY(COMP_CPU("CONNSYS_I2S")),
0413              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0414              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0415 SND_SOC_DAILINK_DEFS(pcm1,
0416              DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
0417              DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
0418              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0419 SND_SOC_DAILINK_DEFS(tdm_in,
0420              DAILINK_COMP_ARRAY(COMP_CPU("TDM IN")),
0421              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0422              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0423 
0424 /* hostless */
0425 SND_SOC_DAILINK_DEFS(hostless_ul1,
0426              DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL1 DAI")),
0427              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0428              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0429 SND_SOC_DAILINK_DEFS(hostless_ul2,
0430              DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL2 DAI")),
0431              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0432              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0433 SND_SOC_DAILINK_DEFS(hostless_ul3,
0434              DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL3 DAI")),
0435              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0436              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0437 SND_SOC_DAILINK_DEFS(hostless_ul5,
0438              DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL5 DAI")),
0439              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0440              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0441 SND_SOC_DAILINK_DEFS(hostless_ul6,
0442              DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL6 DAI")),
0443              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0444              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0445 SND_SOC_DAILINK_DEFS(hostless_hw_gain_aaudio,
0446              DAILINK_COMP_ARRAY(COMP_CPU("Hostless HW Gain AAudio DAI")),
0447              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0448              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0449 SND_SOC_DAILINK_DEFS(hostless_src_aaudio,
0450              DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")),
0451              DAILINK_COMP_ARRAY(COMP_DUMMY()),
0452              DAILINK_COMP_ARRAY(COMP_EMPTY()));
0453 static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = {
0454     /* Front End DAI links */
0455     {
0456         .name = "Playback_1",
0457         .stream_name = "Playback_1",
0458         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0459                 SND_SOC_DPCM_TRIGGER_PRE},
0460         .dynamic = 1,
0461         .dpcm_playback = 1,
0462         .dpcm_merged_format = 1,
0463         .dpcm_merged_chan = 1,
0464         .dpcm_merged_rate = 1,
0465         .ops = &mt8186_mt6366_rt1019_rt5682s_playback_ops,
0466         SND_SOC_DAILINK_REG(playback1),
0467     },
0468     {
0469         .name = "Playback_12",
0470         .stream_name = "Playback_12",
0471         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0472                 SND_SOC_DPCM_TRIGGER_PRE},
0473         .dynamic = 1,
0474         .dpcm_playback = 1,
0475         SND_SOC_DAILINK_REG(playback12),
0476     },
0477     {
0478         .name = "Playback_2",
0479         .stream_name = "Playback_2",
0480         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0481                 SND_SOC_DPCM_TRIGGER_PRE},
0482         .dynamic = 1,
0483         .dpcm_playback = 1,
0484         .dpcm_merged_format = 1,
0485         .dpcm_merged_chan = 1,
0486         .dpcm_merged_rate = 1,
0487         SND_SOC_DAILINK_REG(playback2),
0488     },
0489     {
0490         .name = "Playback_3",
0491         .stream_name = "Playback_3",
0492         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0493                 SND_SOC_DPCM_TRIGGER_PRE},
0494         .dynamic = 1,
0495         .dpcm_playback = 1,
0496         .dpcm_merged_format = 1,
0497         .dpcm_merged_chan = 1,
0498         .dpcm_merged_rate = 1,
0499         .ops = &mt8186_mt6366_rt1019_rt5682s_playback_ops,
0500         SND_SOC_DAILINK_REG(playback3),
0501     },
0502     {
0503         .name = "Playback_4",
0504         .stream_name = "Playback_4",
0505         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0506                 SND_SOC_DPCM_TRIGGER_PRE},
0507         .dynamic = 1,
0508         .dpcm_playback = 1,
0509         SND_SOC_DAILINK_REG(playback4),
0510     },
0511     {
0512         .name = "Playback_5",
0513         .stream_name = "Playback_5",
0514         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0515                 SND_SOC_DPCM_TRIGGER_PRE},
0516         .dynamic = 1,
0517         .dpcm_playback = 1,
0518         SND_SOC_DAILINK_REG(playback5),
0519     },
0520     {
0521         .name = "Playback_6",
0522         .stream_name = "Playback_6",
0523         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0524                 SND_SOC_DPCM_TRIGGER_PRE},
0525         .dynamic = 1,
0526         .dpcm_playback = 1,
0527         SND_SOC_DAILINK_REG(playback6),
0528     },
0529     {
0530         .name = "Playback_7",
0531         .stream_name = "Playback_7",
0532         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0533                 SND_SOC_DPCM_TRIGGER_PRE},
0534         .dynamic = 1,
0535         .dpcm_playback = 1,
0536         SND_SOC_DAILINK_REG(playback7),
0537     },
0538     {
0539         .name = "Playback_8",
0540         .stream_name = "Playback_8",
0541         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0542                 SND_SOC_DPCM_TRIGGER_PRE},
0543         .dynamic = 1,
0544         .dpcm_playback = 1,
0545         SND_SOC_DAILINK_REG(playback8),
0546     },
0547     {
0548         .name = "Capture_1",
0549         .stream_name = "Capture_1",
0550         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0551                 SND_SOC_DPCM_TRIGGER_PRE},
0552         .dynamic = 1,
0553         .dpcm_capture = 1,
0554         SND_SOC_DAILINK_REG(capture1),
0555     },
0556     {
0557         .name = "Capture_2",
0558         .stream_name = "Capture_2",
0559         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0560                 SND_SOC_DPCM_TRIGGER_PRE},
0561         .dynamic = 1,
0562         .dpcm_capture = 1,
0563         .dpcm_merged_format = 1,
0564         .dpcm_merged_chan = 1,
0565         .dpcm_merged_rate = 1,
0566         .ops = &mt8186_mt6366_rt1019_rt5682s_capture_ops,
0567         SND_SOC_DAILINK_REG(capture2),
0568     },
0569     {
0570         .name = "Capture_3",
0571         .stream_name = "Capture_3",
0572         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0573                 SND_SOC_DPCM_TRIGGER_PRE},
0574         .dynamic = 1,
0575         .dpcm_capture = 1,
0576         SND_SOC_DAILINK_REG(capture3),
0577     },
0578     {
0579         .name = "Capture_4",
0580         .stream_name = "Capture_4",
0581         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0582                 SND_SOC_DPCM_TRIGGER_PRE},
0583         .dynamic = 1,
0584         .dpcm_capture = 1,
0585         .dpcm_merged_format = 1,
0586         .dpcm_merged_chan = 1,
0587         .dpcm_merged_rate = 1,
0588         .ops = &mt8186_mt6366_rt1019_rt5682s_capture_ops,
0589         SND_SOC_DAILINK_REG(capture4),
0590     },
0591     {
0592         .name = "Capture_5",
0593         .stream_name = "Capture_5",
0594         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0595                 SND_SOC_DPCM_TRIGGER_PRE},
0596         .dynamic = 1,
0597         .dpcm_capture = 1,
0598         SND_SOC_DAILINK_REG(capture5),
0599     },
0600     {
0601         .name = "Capture_6",
0602         .stream_name = "Capture_6",
0603         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0604                 SND_SOC_DPCM_TRIGGER_PRE},
0605         .dynamic = 1,
0606         .dpcm_capture = 1,
0607         .dpcm_merged_format = 1,
0608         .dpcm_merged_chan = 1,
0609         .dpcm_merged_rate = 1,
0610         SND_SOC_DAILINK_REG(capture6),
0611     },
0612     {
0613         .name = "Capture_7",
0614         .stream_name = "Capture_7",
0615         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0616                 SND_SOC_DPCM_TRIGGER_PRE},
0617         .dynamic = 1,
0618         .dpcm_capture = 1,
0619         SND_SOC_DAILINK_REG(capture7),
0620     },
0621     {
0622         .name = "Hostless_LPBK",
0623         .stream_name = "Hostless_LPBK",
0624         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0625                 SND_SOC_DPCM_TRIGGER_PRE},
0626         .dynamic = 1,
0627         .dpcm_playback = 1,
0628         .dpcm_capture = 1,
0629         .ignore_suspend = 1,
0630         SND_SOC_DAILINK_REG(hostless_lpbk),
0631     },
0632     {
0633         .name = "Hostless_FM",
0634         .stream_name = "Hostless_FM",
0635         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0636                 SND_SOC_DPCM_TRIGGER_PRE},
0637         .dynamic = 1,
0638         .dpcm_playback = 1,
0639         .dpcm_capture = 1,
0640         .ignore_suspend = 1,
0641         SND_SOC_DAILINK_REG(hostless_fm),
0642     },
0643     {
0644         .name = "Hostless_SRC_1",
0645         .stream_name = "Hostless_SRC_1",
0646         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0647                 SND_SOC_DPCM_TRIGGER_PRE},
0648         .dynamic = 1,
0649         .dpcm_playback = 1,
0650         .dpcm_capture = 1,
0651         .ignore_suspend = 1,
0652         SND_SOC_DAILINK_REG(hostless_src1),
0653     },
0654     {
0655         .name = "Hostless_SRC_Bargein",
0656         .stream_name = "Hostless_SRC_Bargein",
0657         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0658                 SND_SOC_DPCM_TRIGGER_PRE},
0659         .dynamic = 1,
0660         .dpcm_playback = 1,
0661         .dpcm_capture = 1,
0662         .ignore_suspend = 1,
0663         SND_SOC_DAILINK_REG(hostless_src_bargein),
0664     },
0665     {
0666         .name = "Hostless_HW_Gain_AAudio",
0667         .stream_name = "Hostless_HW_Gain_AAudio",
0668         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0669                 SND_SOC_DPCM_TRIGGER_PRE},
0670         .dynamic = 1,
0671         .dpcm_capture = 1,
0672         .ignore_suspend = 1,
0673         SND_SOC_DAILINK_REG(hostless_hw_gain_aaudio),
0674     },
0675     {
0676         .name = "Hostless_SRC_AAudio",
0677         .stream_name = "Hostless_SRC_AAudio",
0678         .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
0679                 SND_SOC_DPCM_TRIGGER_PRE},
0680         .dynamic = 1,
0681         .dpcm_playback = 1,
0682         .dpcm_capture = 1,
0683         .ignore_suspend = 1,
0684         SND_SOC_DAILINK_REG(hostless_src_aaudio),
0685     },
0686     /* Back End DAI links */
0687     {
0688         .name = "Primary Codec",
0689         .no_pcm = 1,
0690         .dpcm_playback = 1,
0691         .dpcm_capture = 1,
0692         .ignore_suspend = 1,
0693         .init = mt8186_mt6366_init,
0694         SND_SOC_DAILINK_REG(adda),
0695     },
0696     {
0697         .name = "I2S3",
0698         .no_pcm = 1,
0699         .dai_fmt = SND_SOC_DAIFMT_I2S |
0700                SND_SOC_DAIFMT_IB_IF |
0701                SND_SOC_DAIFMT_CBM_CFM,
0702         .dpcm_playback = 1,
0703         .ignore_suspend = 1,
0704         .init = mt8186_mt6366_rt1019_rt5682s_hdmi_init,
0705         .be_hw_params_fixup = mt8186_it6505_i2s_hw_params_fixup,
0706         SND_SOC_DAILINK_REG(i2s3),
0707     },
0708     {
0709         .name = "I2S0",
0710         .no_pcm = 1,
0711         .dpcm_capture = 1,
0712         .ignore_suspend = 1,
0713         .be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
0714         .ops = &mt8186_rt5682s_i2s_ops,
0715         SND_SOC_DAILINK_REG(i2s0),
0716     },
0717     {
0718         .name = "I2S1",
0719         .no_pcm = 1,
0720         .dpcm_playback = 1,
0721         .ignore_suspend = 1,
0722         .be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
0723         .init = mt8186_rt5682s_init,
0724         .ops = &mt8186_rt5682s_i2s_ops,
0725         SND_SOC_DAILINK_REG(i2s1),
0726     },
0727     {
0728         .name = "I2S2",
0729         .no_pcm = 1,
0730         .dpcm_capture = 1,
0731         .ignore_suspend = 1,
0732         .be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
0733         SND_SOC_DAILINK_REG(i2s2),
0734     },
0735     {
0736         .name = "HW Gain 1",
0737         .no_pcm = 1,
0738         .dpcm_playback = 1,
0739         .dpcm_capture = 1,
0740         .ignore_suspend = 1,
0741         SND_SOC_DAILINK_REG(hw_gain1),
0742     },
0743     {
0744         .name = "HW Gain 2",
0745         .no_pcm = 1,
0746         .dpcm_playback = 1,
0747         .dpcm_capture = 1,
0748         .ignore_suspend = 1,
0749         SND_SOC_DAILINK_REG(hw_gain2),
0750     },
0751     {
0752         .name = "HW_SRC_1",
0753         .no_pcm = 1,
0754         .dpcm_playback = 1,
0755         .dpcm_capture = 1,
0756         .ignore_suspend = 1,
0757         SND_SOC_DAILINK_REG(hw_src1),
0758     },
0759     {
0760         .name = "HW_SRC_2",
0761         .no_pcm = 1,
0762         .dpcm_playback = 1,
0763         .dpcm_capture = 1,
0764         .ignore_suspend = 1,
0765         SND_SOC_DAILINK_REG(hw_src2),
0766     },
0767     {
0768         .name = "CONNSYS_I2S",
0769         .no_pcm = 1,
0770         .dpcm_capture = 1,
0771         .ignore_suspend = 1,
0772         SND_SOC_DAILINK_REG(connsys_i2s),
0773     },
0774     {
0775         .name = "PCM 1",
0776         .dai_fmt = SND_SOC_DAIFMT_I2S |
0777                SND_SOC_DAIFMT_NB_IF,
0778         .no_pcm = 1,
0779         .dpcm_playback = 1,
0780         .dpcm_capture = 1,
0781         .ignore_suspend = 1,
0782         SND_SOC_DAILINK_REG(pcm1),
0783     },
0784     {
0785         .name = "TDM IN",
0786         .no_pcm = 1,
0787         .dpcm_capture = 1,
0788         .ignore_suspend = 1,
0789         SND_SOC_DAILINK_REG(tdm_in),
0790     },
0791     /* dummy BE for ul memif to record from dl memif */
0792     {
0793         .name = "Hostless_UL1",
0794         .no_pcm = 1,
0795         .dpcm_capture = 1,
0796         .ignore_suspend = 1,
0797         SND_SOC_DAILINK_REG(hostless_ul1),
0798     },
0799     {
0800         .name = "Hostless_UL2",
0801         .no_pcm = 1,
0802         .dpcm_capture = 1,
0803         .ignore_suspend = 1,
0804         SND_SOC_DAILINK_REG(hostless_ul2),
0805     },
0806     {
0807         .name = "Hostless_UL3",
0808         .no_pcm = 1,
0809         .dpcm_capture = 1,
0810         .ignore_suspend = 1,
0811         SND_SOC_DAILINK_REG(hostless_ul3),
0812     },
0813     {
0814         .name = "Hostless_UL5",
0815         .no_pcm = 1,
0816         .dpcm_capture = 1,
0817         .ignore_suspend = 1,
0818         SND_SOC_DAILINK_REG(hostless_ul5),
0819     },
0820     {
0821         .name = "Hostless_UL6",
0822         .no_pcm = 1,
0823         .dpcm_capture = 1,
0824         .ignore_suspend = 1,
0825         SND_SOC_DAILINK_REG(hostless_ul6),
0826     },
0827 };
0828 
0829 static const struct snd_soc_dapm_widget
0830 mt8186_mt6366_rt1019_rt5682s_widgets[] = {
0831     SND_SOC_DAPM_SPK("Speakers", NULL),
0832     SND_SOC_DAPM_OUTPUT("HDMI1"),
0833 };
0834 
0835 static const struct snd_soc_dapm_route
0836 mt8186_mt6366_rt1019_rt5682s_routes[] = {
0837     /* SPK */
0838     { "Speakers", NULL, "Speaker" },
0839     /* HDMI */
0840     { "HDMI1", NULL, "TX" },
0841 };
0842 
0843 static const struct snd_kcontrol_new
0844 mt8186_mt6366_rt1019_rt5682s_controls[] = {
0845     SOC_DAPM_PIN_SWITCH("Speakers"),
0846     SOC_DAPM_PIN_SWITCH("HDMI1"),
0847 };
0848 
0849 static struct snd_soc_card mt8186_mt6366_rt1019_rt5682s_soc_card = {
0850     .name = "mt8186_mt6366_rt1019_rt5682s",
0851     .owner = THIS_MODULE,
0852     .dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
0853     .num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
0854     .controls = mt8186_mt6366_rt1019_rt5682s_controls,
0855     .num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
0856     .dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
0857     .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
0858     .dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
0859     .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
0860     .codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
0861     .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
0862 };
0863 
0864 static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev)
0865 {
0866     struct snd_soc_card *card;
0867     struct snd_soc_dai_link *dai_link;
0868     struct mt8186_mt6366_rt1019_rt5682s_priv *priv;
0869     struct device_node *platform_node, *headset_codec, *playback_codec;
0870     int ret, i;
0871 
0872     card = (struct snd_soc_card *)device_get_match_data(&pdev->dev);
0873     if (!card)
0874         return -EINVAL;
0875     card->dev = &pdev->dev;
0876 
0877     platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
0878     if (!platform_node) {
0879         ret = -EINVAL;
0880         dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n");
0881         return ret;
0882     }
0883 
0884     playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs");
0885     if (!playback_codec) {
0886         ret = -EINVAL;
0887         dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n");
0888         goto err_playback_codec;
0889     }
0890 
0891     headset_codec = of_get_child_by_name(pdev->dev.of_node, "headset-codec");
0892     if (!headset_codec) {
0893         ret = -EINVAL;
0894         dev_err_probe(&pdev->dev, ret, "Property 'headset-codec' missing or invalid\n");
0895         goto err_headset_codec;
0896     }
0897 
0898     for_each_card_prelinks(card, i, dai_link) {
0899         ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3");
0900         if (ret) {
0901             dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n",
0902                       dai_link->name);
0903             goto err_probe;
0904         }
0905 
0906         ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S0");
0907         if (ret) {
0908             dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
0909                       dai_link->name);
0910             goto err_probe;
0911         }
0912 
0913         ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S1");
0914         if (ret) {
0915             dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
0916                       dai_link->name);
0917             goto err_probe;
0918         }
0919 
0920         if (!dai_link->platforms->name)
0921             dai_link->platforms->of_node = platform_node;
0922     }
0923 
0924     priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0925     if (!priv) {
0926         ret = -ENOMEM;
0927         goto err_probe;
0928     }
0929 
0930     snd_soc_card_set_drvdata(card, priv);
0931 
0932     ret = mt8186_afe_gpio_init(&pdev->dev);
0933     if (ret) {
0934         dev_err_probe(&pdev->dev, ret, "%s init gpio error\n", __func__);
0935         goto err_probe;
0936     }
0937 
0938     ret = devm_snd_soc_register_card(&pdev->dev, card);
0939     if (ret)
0940         dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__);
0941 
0942 err_probe:
0943     of_node_put(headset_codec);
0944 err_headset_codec:
0945     of_node_put(playback_codec);
0946 err_playback_codec:
0947     of_node_put(platform_node);
0948 
0949     return ret;
0950 }
0951 
0952 #if IS_ENABLED(CONFIG_OF)
0953 static const struct of_device_id mt8186_mt6366_rt1019_rt5682s_dt_match[] = {
0954     {   .compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound",
0955         .data = &mt8186_mt6366_rt1019_rt5682s_soc_card,
0956     },
0957     {}
0958 };
0959 #endif
0960 
0961 static struct platform_driver mt8186_mt6366_rt1019_rt5682s_driver = {
0962     .driver = {
0963         .name = "mt8186_mt6366_rt1019_rt5682s",
0964 #if IS_ENABLED(CONFIG_OF)
0965         .of_match_table = mt8186_mt6366_rt1019_rt5682s_dt_match,
0966 #endif
0967         .pm = &snd_soc_pm_ops,
0968     },
0969     .probe = mt8186_mt6366_rt1019_rt5682s_dev_probe,
0970 };
0971 
0972 module_platform_driver(mt8186_mt6366_rt1019_rt5682s_driver);
0973 
0974 /* Module information */
0975 MODULE_DESCRIPTION("MT8186-MT6366-RT1019-RT5682S ALSA SoC machine driver");
0976 MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
0977 MODULE_LICENSE("GPL v2");
0978 MODULE_ALIAS("mt8186_mt6366_rt1019_rt5682s soc card");