~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/mediatek/mt8186/mt8186-mt6366.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 //
  3 // mt8186-mt6366.c
  4 //      --  MT8186-MT6366 ALSA SoC machine driver
  5 //
  6 // Copyright (c) 2022 MediaTek Inc.
  7 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
  8 //
  9 // Copyright (c) 2024 Collabora Ltd.
 10 //                    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
 11 //
 12 
 13 #include <linux/gpio/consumer.h>
 14 #include <linux/input.h>
 15 #include <linux/module.h>
 16 #include <linux/of.h>
 17 #include <sound/jack.h>
 18 #include <sound/pcm_params.h>
 19 #include <sound/rt5682.h>
 20 #include <sound/soc.h>
 21 
 22 #include "../../codecs/da7219.h"
 23 #include "../../codecs/mt6358.h"
 24 #include "../../codecs/rt5682.h"
 25 #include "../common/mtk-afe-platform-driver.h"
 26 #include "../common/mtk-dsp-sof-common.h"
 27 #include "../common/mtk-soc-card.h"
 28 #include "../common/mtk-soundcard-driver.h"
 29 #include "mt8186-afe-common.h"
 30 #include "mt8186-afe-clk.h"
 31 #include "mt8186-afe-gpio.h"
 32 #include "mt8186-mt6366-common.h"
 33 
 34 #define RT1019_CODEC_DAI        "HiFi"
 35 #define RT1019_DEV0_NAME        "rt1019p"
 36 
 37 #define RT5682S_CODEC_DAI       "rt5682s-aif1"
 38 #define RT5682S_DEV0_NAME       "rt5682s.5-001a"
 39 
 40 #define DA7219_CODEC_DAI        "da7219-hifi"
 41 #define DA7219_DEV_NAME         "da7219.5-001a"
 42 
 43 #define SOF_DMA_DL1 "SOF_DMA_DL1"
 44 #define SOF_DMA_DL2 "SOF_DMA_DL2"
 45 #define SOF_DMA_UL1 "SOF_DMA_UL1"
 46 #define SOF_DMA_UL2 "SOF_DMA_UL2"
 47 
 48 #define DA7219_CODEC_PRESENT    BIT(0)
 49 
 50 struct mt8186_mt6366_rt1019_rt5682s_priv {
 51         struct gpio_desc *dmic_sel;
 52         int dmic_switch;
 53 };
 54 
 55 enum mt8186_jacks {
 56         MT8186_JACK_HEADSET,
 57         MT8186_JACK_HDMI,
 58         MT8186_JACK_MAX,
 59 };
 60 
 61 /* Headset jack detection DAPM pins */
 62 static struct snd_soc_jack_pin mt8186_jack_pins[] = {
 63         {
 64                 .pin = "Headphone",
 65                 .mask = SND_JACK_HEADPHONE,
 66         },
 67         {
 68                 .pin = "Headset Mic",
 69                 .mask = SND_JACK_MICROPHONE,
 70         },
 71 };
 72 
 73 static struct snd_soc_codec_conf mt8186_mt6366_rt1019_rt5682s_codec_conf[] = {
 74         {
 75                 .dlc = COMP_CODEC_CONF("mt6358-sound"),
 76                 .name_prefix = "Mt6366",
 77         },
 78         {
 79                 .dlc = COMP_CODEC_CONF("bt-sco"),
 80                 .name_prefix = "Mt8186 bt",
 81         },
 82         {
 83                 .dlc = COMP_CODEC_CONF("hdmi-audio-codec"),
 84                 .name_prefix = "Mt8186 hdmi",
 85         },
 86 };
 87 
 88 static int dmic_get(struct snd_kcontrol *kcontrol,
 89                     struct snd_ctl_elem_value *ucontrol)
 90 {
 91         struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
 92         struct mtk_soc_card_data *soc_card_data =
 93                 snd_soc_card_get_drvdata(dapm->card);
 94         struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv;
 95 
 96         ucontrol->value.integer.value[0] = priv->dmic_switch;
 97         return 0;
 98 }
 99 
100 static int dmic_set(struct snd_kcontrol *kcontrol,
101                     struct snd_ctl_elem_value *ucontrol)
102 {
103         struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
104         struct mtk_soc_card_data *soc_card_data =
105                 snd_soc_card_get_drvdata(dapm->card);
106         struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv;
107 
108         priv->dmic_switch = ucontrol->value.integer.value[0];
109         if (priv->dmic_sel) {
110                 gpiod_set_value(priv->dmic_sel, priv->dmic_switch);
111                 dev_dbg(dapm->card->dev, "dmic_set_value %d\n",
112                          priv->dmic_switch);
113         }
114         return 0;
115 }
116 
117 static const char * const dmic_mux_text[] = {
118         "Front Mic",
119         "Rear Mic",
120 };
121 
122 static SOC_ENUM_SINGLE_DECL(mt8186_dmic_enum,
123                             SND_SOC_NOPM, 0, dmic_mux_text);
124 
125 static const struct snd_kcontrol_new mt8186_dmic_mux_control =
126         SOC_DAPM_ENUM_EXT("DMIC Select Mux", mt8186_dmic_enum,
127                           dmic_get, dmic_set);
128 
129 static const struct snd_soc_dapm_widget dmic_widgets[] = {
130         SND_SOC_DAPM_MIC("DMIC", NULL),
131         SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0, &mt8186_dmic_mux_control),
132 };
133 
134 static const struct snd_soc_dapm_route dmic_map[] = {
135         /* digital mics */
136         {"Dmic Mux", "Front Mic", "DMIC"},
137         {"Dmic Mux", "Rear Mic", "DMIC"},
138 };
139 
140 static int primary_codec_init(struct snd_soc_pcm_runtime *rtd)
141 {
142         struct snd_soc_card *card = rtd->card;
143         struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
144         struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv;
145         int ret;
146 
147         ret = mt8186_mt6366_init(rtd);
148 
149         if (ret) {
150                 dev_err(card->dev, "mt8186_mt6366_init failed: %d\n", ret);
151                 return ret;
152         }
153 
154         if (!priv->dmic_sel) {
155                 dev_dbg(card->dev, "dmic_sel is null\n");
156                 return 0;
157         }
158 
159         ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
160                                         ARRAY_SIZE(dmic_widgets));
161         if (ret) {
162                 dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
163                 /* Don't need to add routes if widget addition failed */
164                 return ret;
165         }
166 
167         ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
168                                       ARRAY_SIZE(dmic_map));
169 
170         if (ret)
171                 dev_err(card->dev, "DMic map addition failed: %d\n", ret);
172 
173         return ret;
174 }
175 
176 static int mt8186_headset_codec_init(struct snd_soc_pcm_runtime *rtd)
177 {
178         struct snd_soc_component *cmpnt_afe =
179                 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
180         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
181         struct mtk_soc_card_data *soc_card_data =
182                 snd_soc_card_get_drvdata(rtd->card);
183         struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8186_JACK_HEADSET];
184         struct snd_soc_component *cmpnt_codec =
185                 snd_soc_rtd_to_codec(rtd, 0)->component;
186         const int hs_keys_rt5682[] = {
187                 KEY_PLAYPAUSE, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_VOICECOMMAND
188         };
189         const int hs_keys_da7219[] = {
190                 KEY_PLAYPAUSE, KEY_VOICECOMMAND, KEY_VOLUMEUP, KEY_VOLUMEDOWN
191         };
192         const int *hs_keys;
193         int ret;
194         int type;
195 
196         ret = mt8186_dai_i2s_set_share(afe, "I2S1", "I2S0");
197         if (ret) {
198                 dev_err(rtd->dev, "Failed to set up shared clocks\n");
199                 return ret;
200         }
201 
202         ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
203                                     SND_JACK_HEADSET | SND_JACK_BTN_0 |
204                                     SND_JACK_BTN_1 | SND_JACK_BTN_2 |
205                                     SND_JACK_BTN_3,
206                                     jack, mt8186_jack_pins,
207                                     ARRAY_SIZE(mt8186_jack_pins));
208         if (ret) {
209                 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
210                 return ret;
211         }
212 
213         if (soc_card_data->card_data->flags & DA7219_CODEC_PRESENT)
214                 hs_keys = hs_keys_da7219;
215         else
216                 hs_keys = hs_keys_rt5682;
217 
218         snd_jack_set_key(jack->jack, SND_JACK_BTN_0, hs_keys[0]);
219         snd_jack_set_key(jack->jack, SND_JACK_BTN_1, hs_keys[1]);
220         snd_jack_set_key(jack->jack, SND_JACK_BTN_2, hs_keys[2]);
221         snd_jack_set_key(jack->jack, SND_JACK_BTN_3, hs_keys[3]);
222 
223         type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3;
224         return snd_soc_component_set_jack(cmpnt_codec, jack, (void *)&type);
225 }
226 
227 static int mt8186_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
228                                        struct snd_pcm_hw_params *params)
229 {
230         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
231         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
232         struct snd_soc_dai *codec_dai;
233         unsigned int rate = params_rate(params);
234         unsigned int mclk_fs_ratio = 256;
235         unsigned int mclk_fs = rate * mclk_fs_ratio;
236         unsigned int freq;
237         int ret, j;
238 
239         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
240         if (ret < 0) {
241                 dev_err(rtd->dev, "failed to set cpu dai sysclk: %d\n", ret);
242                 return ret;
243         }
244 
245         for_each_rtd_codec_dais(rtd, j, codec_dai) {
246                 if (strcmp(codec_dai->component->name, DA7219_DEV_NAME))
247                         continue;
248 
249                 ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK,
250                                              mclk_fs, SND_SOC_CLOCK_IN);
251                 if (ret < 0) {
252                         dev_err(rtd->dev, "failed to set sysclk: %d\n", ret);
253                         return ret;
254                 }
255 
256                 if ((rate % 8000) == 0)
257                         freq = DA7219_PLL_FREQ_OUT_98304;
258                 else
259                         freq = DA7219_PLL_FREQ_OUT_90316;
260 
261                 ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM,
262                                           0, freq);
263                 if (ret) {
264                         dev_err(rtd->dev, "failed to start PLL: %d\n", ret);
265                         return ret;
266                 }
267         }
268 
269         return 0;
270 }
271 
272 static int mt8186_da7219_i2s_hw_free(struct snd_pcm_substream *substream)
273 {
274         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
275         struct snd_soc_dai *codec_dai;
276         int j, ret;
277 
278         for_each_rtd_codec_dais(rtd, j, codec_dai) {
279                 if (strcmp(codec_dai->component->name, DA7219_DEV_NAME))
280                         continue;
281 
282                 ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
283                 if (ret < 0) {
284                         dev_err(rtd->dev, "failed to stop PLL: %d\n", ret);
285                         return ret;
286                 }
287         }
288 
289         return 0;
290 }
291 
292 static const struct snd_soc_ops mt8186_da7219_i2s_ops = {
293         .hw_params = mt8186_da7219_i2s_hw_params,
294         .hw_free = mt8186_da7219_i2s_hw_free,
295 };
296 
297 static int mt8186_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,
298                                         struct snd_pcm_hw_params *params)
299 {
300         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
301         struct snd_soc_card *card = rtd->card;
302         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
303         struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
304         unsigned int rate = params_rate(params);
305         unsigned int mclk_fs_ratio = 128;
306         unsigned int mclk_fs = rate * mclk_fs_ratio;
307         int bitwidth;
308         int ret;
309 
310         bitwidth = snd_pcm_format_width(params_format(params));
311         if (bitwidth < 0) {
312                 dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
313                 return bitwidth;
314         }
315 
316         ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
317         if (ret) {
318                 dev_err(card->dev, "failed to set tdm slot\n");
319                 return ret;
320         }
321 
322         ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
323                                   RT5682_PLL1_S_BCLK1,
324                                   params_rate(params) * 64,
325                                   params_rate(params) * 512);
326         if (ret) {
327                 dev_err(card->dev, "failed to set pll\n");
328                 return ret;
329         }
330 
331         ret = snd_soc_dai_set_sysclk(codec_dai,
332                                      RT5682_SCLK_S_PLL1,
333                                      params_rate(params) * 512,
334                                      SND_SOC_CLOCK_IN);
335         if (ret) {
336                 dev_err(card->dev, "failed to set sysclk\n");
337                 return ret;
338         }
339 
340         return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
341 }
342 
343 static const struct snd_soc_ops mt8186_rt5682s_i2s_ops = {
344         .hw_params = mt8186_rt5682s_i2s_hw_params,
345 };
346 
347 static int mt8186_mt6366_rt1019_rt5682s_hdmi_init(struct snd_soc_pcm_runtime *rtd)
348 {
349         struct snd_soc_component *cmpnt_afe =
350                 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
351         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
352         struct snd_soc_component *cmpnt_codec =
353                 snd_soc_rtd_to_codec(rtd, 0)->component;
354         struct mtk_soc_card_data *soc_card_data =
355                 snd_soc_card_get_drvdata(rtd->card);
356         struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8186_JACK_HDMI];
357         int ret;
358 
359         ret = mt8186_dai_i2s_set_share(afe, "I2S2", "I2S3");
360         if (ret) {
361                 dev_err(rtd->dev, "Failed to set up shared clocks\n");
362                 return ret;
363         }
364 
365         ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, jack);
366         if (ret) {
367                 dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
368                 return ret;
369         }
370 
371         return snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
372 }
373 
374 static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
375                                   struct snd_pcm_hw_params *params,
376                                   snd_pcm_format_t fmt)
377 {
378         struct snd_interval *channels = hw_param_interval(params,
379                 SNDRV_PCM_HW_PARAM_CHANNELS);
380 
381         dev_dbg(rtd->dev, "%s(), fix format to %d\n", __func__, fmt);
382 
383         /* fix BE i2s channel to 2 channel */
384         channels->min = 2;
385         channels->max = 2;
386 
387         /* clean param mask first */
388         snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
389                              0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
390 
391         params_set_format(params, fmt);
392 
393         return 0;
394 }
395 
396 static int mt8186_i2s_hw_params_24le_fixup(struct snd_soc_pcm_runtime *rtd,
397                                            struct snd_pcm_hw_params *params)
398 {
399         return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE);
400 }
401 
402 static int mt8186_i2s_hw_params_32le_fixup(struct snd_soc_pcm_runtime *rtd,
403                                            struct snd_pcm_hw_params *params)
404 {
405         return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE);
406 }
407 
408 /* fixup the BE DAI link to match any values from topology */
409 static int mt8186_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
410                                      struct snd_pcm_hw_params *params)
411 {
412         struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
413         int ret;
414 
415         ret = mtk_sof_dai_link_fixup(rtd, params);
416 
417         if (!strcmp(rtd->dai_link->name, "I2S0") ||
418             !strcmp(rtd->dai_link->name, "I2S1") ||
419             !strcmp(rtd->dai_link->name, "I2S2")) {
420                 if (soc_card_data->card_data->flags & DA7219_CODEC_PRESENT)
421                         mt8186_i2s_hw_params_32le_fixup(rtd, params);
422                 else
423                         mt8186_i2s_hw_params_24le_fixup(rtd, params);
424         } else if (!strcmp(rtd->dai_link->name, "I2S3")) {
425                 if (soc_card_data->card_data->flags & DA7219_CODEC_PRESENT)
426                         mt8186_i2s_hw_params_24le_fixup(rtd, params);
427                 else
428                         mt8186_i2s_hw_params_32le_fixup(rtd, params);
429         }
430 
431         return ret;
432 }
433 
434 /* FE */
435 SND_SOC_DAILINK_DEFS(playback1,
436                      DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
437                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
438                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
439 
440 SND_SOC_DAILINK_DEFS(playback12,
441                      DAILINK_COMP_ARRAY(COMP_CPU("DL12")),
442                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
443                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
444 
445 SND_SOC_DAILINK_DEFS(playback2,
446                      DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
447                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
448                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
449 
450 SND_SOC_DAILINK_DEFS(playback3,
451                      DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
452                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
453                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
454 
455 SND_SOC_DAILINK_DEFS(playback4,
456                      DAILINK_COMP_ARRAY(COMP_CPU("DL4")),
457                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
458                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
459 
460 SND_SOC_DAILINK_DEFS(playback5,
461                      DAILINK_COMP_ARRAY(COMP_CPU("DL5")),
462                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
463                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
464 
465 SND_SOC_DAILINK_DEFS(playback6,
466                      DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
467                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
468                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
469 
470 SND_SOC_DAILINK_DEFS(playback7,
471                      DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
472                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
473                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
474 
475 SND_SOC_DAILINK_DEFS(playback8,
476                      DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
477                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
478                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
479 
480 SND_SOC_DAILINK_DEFS(capture1,
481                      DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
482                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
483                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
484 
485 SND_SOC_DAILINK_DEFS(capture2,
486                      DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
487                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
488                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
489 
490 SND_SOC_DAILINK_DEFS(capture3,
491                      DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
492                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
493                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
494 
495 SND_SOC_DAILINK_DEFS(capture4,
496                      DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
497                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
498                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
499 
500 SND_SOC_DAILINK_DEFS(capture5,
501                      DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
502                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
503                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
504 
505 SND_SOC_DAILINK_DEFS(capture6,
506                      DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
507                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
508                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
509 
510 SND_SOC_DAILINK_DEFS(capture7,
511                      DAILINK_COMP_ARRAY(COMP_CPU("UL7")),
512                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
513                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
514 
515 /* hostless */
516 SND_SOC_DAILINK_DEFS(hostless_lpbk,
517                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")),
518                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
519                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
520 SND_SOC_DAILINK_DEFS(hostless_fm,
521                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless FM DAI")),
522                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
523                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
524 SND_SOC_DAILINK_DEFS(hostless_src1,
525                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_1_DAI")),
526                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
527                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
528 SND_SOC_DAILINK_DEFS(hostless_src_bargein,
529                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_Bargein_DAI")),
530                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
531                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
532 
533 /* BE */
534 SND_SOC_DAILINK_DEFS(adda,
535                      DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
536                      DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound",
537                                                    "mt6358-snd-codec-aif1"),
538                                         COMP_CODEC("dmic-codec",
539                                                    "dmic-hifi")),
540                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
541 SND_SOC_DAILINK_DEFS(i2s0,
542                      DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
543                      DAILINK_COMP_ARRAY(COMP_EMPTY()),
544                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
545 SND_SOC_DAILINK_DEFS(i2s1,
546                      DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
547                      DAILINK_COMP_ARRAY(COMP_EMPTY()),
548                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
549 SND_SOC_DAILINK_DEFS(i2s2,
550                      DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
551                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
552                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
553 SND_SOC_DAILINK_DEFS(i2s3,
554                      DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
555                      DAILINK_COMP_ARRAY(COMP_EMPTY()),
556                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
557 SND_SOC_DAILINK_DEFS(hw_gain1,
558                      DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 1")),
559                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
560                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
561 SND_SOC_DAILINK_DEFS(hw_gain2,
562                      DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 2")),
563                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
564                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
565 SND_SOC_DAILINK_DEFS(hw_src1,
566                      DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_1")),
567                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
568                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
569 SND_SOC_DAILINK_DEFS(hw_src2,
570                      DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_2")),
571                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
572                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
573 SND_SOC_DAILINK_DEFS(connsys_i2s,
574                      DAILINK_COMP_ARRAY(COMP_CPU("CONNSYS_I2S")),
575                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
576                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
577 SND_SOC_DAILINK_DEFS(pcm1,
578                      DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
579                      DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
580                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
581 SND_SOC_DAILINK_DEFS(tdm_in,
582                      DAILINK_COMP_ARRAY(COMP_CPU("TDM IN")),
583                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
584                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
585 
586 /* hostless */
587 SND_SOC_DAILINK_DEFS(hostless_ul1,
588                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL1 DAI")),
589                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
590                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
591 SND_SOC_DAILINK_DEFS(hostless_ul2,
592                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL2 DAI")),
593                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
594                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
595 SND_SOC_DAILINK_DEFS(hostless_ul3,
596                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL3 DAI")),
597                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
598                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
599 SND_SOC_DAILINK_DEFS(hostless_ul5,
600                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL5 DAI")),
601                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
602                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
603 SND_SOC_DAILINK_DEFS(hostless_ul6,
604                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL6 DAI")),
605                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
606                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
607 SND_SOC_DAILINK_DEFS(hostless_hw_gain_aaudio,
608                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless HW Gain AAudio DAI")),
609                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
610                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
611 SND_SOC_DAILINK_DEFS(hostless_src_aaudio,
612                      DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")),
613                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
614                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
615 SND_SOC_DAILINK_DEFS(AFE_SOF_DL1,
616                      DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")),
617                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
618                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
619 
620 SND_SOC_DAILINK_DEFS(AFE_SOF_DL2,
621                      DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")),
622                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
623                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
624 
625 SND_SOC_DAILINK_DEFS(AFE_SOF_UL1,
626                      DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")),
627                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
628                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
629 
630 SND_SOC_DAILINK_DEFS(AFE_SOF_UL2,
631                      DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")),
632                      DAILINK_COMP_ARRAY(COMP_DUMMY()),
633                      DAILINK_COMP_ARRAY(COMP_EMPTY()));
634 
635 static const struct sof_conn_stream g_sof_conn_streams[] = {
636         { "I2S1", "AFE_SOF_DL1", SOF_DMA_DL1, SNDRV_PCM_STREAM_PLAYBACK},
637         { "I2S3", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK},
638         { "Primary Codec", "AFE_SOF_UL1", SOF_DMA_UL1, SNDRV_PCM_STREAM_CAPTURE},
639         { "I2S0", "AFE_SOF_UL2", SOF_DMA_UL2, SNDRV_PCM_STREAM_CAPTURE},
640 };
641 
642 static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = {
643         /* Front End DAI links */
644         {
645                 .name = "Playback_1",
646                 .stream_name = "Playback_1",
647                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
648                             SND_SOC_DPCM_TRIGGER_PRE},
649                 .dynamic = 1,
650                 .dpcm_playback = 1,
651                 .dpcm_merged_format = 1,
652                 .dpcm_merged_chan = 1,
653                 .dpcm_merged_rate = 1,
654                 .ops = &mtk_soundcard_common_playback_ops,
655                 SND_SOC_DAILINK_REG(playback1),
656         },
657         {
658                 .name = "Playback_12",
659                 .stream_name = "Playback_12",
660                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
661                             SND_SOC_DPCM_TRIGGER_PRE},
662                 .dynamic = 1,
663                 .dpcm_playback = 1,
664                 SND_SOC_DAILINK_REG(playback12),
665         },
666         {
667                 .name = "Playback_2",
668                 .stream_name = "Playback_2",
669                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
670                             SND_SOC_DPCM_TRIGGER_PRE},
671                 .dynamic = 1,
672                 .dpcm_playback = 1,
673                 .dpcm_merged_format = 1,
674                 .dpcm_merged_chan = 1,
675                 .dpcm_merged_rate = 1,
676                 SND_SOC_DAILINK_REG(playback2),
677         },
678         {
679                 .name = "Playback_3",
680                 .stream_name = "Playback_3",
681                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
682                             SND_SOC_DPCM_TRIGGER_PRE},
683                 .dynamic = 1,
684                 .dpcm_playback = 1,
685                 .dpcm_merged_format = 1,
686                 .dpcm_merged_chan = 1,
687                 .dpcm_merged_rate = 1,
688                 .ops = &mtk_soundcard_common_playback_ops,
689                 SND_SOC_DAILINK_REG(playback3),
690         },
691         {
692                 .name = "Playback_4",
693                 .stream_name = "Playback_4",
694                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
695                             SND_SOC_DPCM_TRIGGER_PRE},
696                 .dynamic = 1,
697                 .dpcm_playback = 1,
698                 SND_SOC_DAILINK_REG(playback4),
699         },
700         {
701                 .name = "Playback_5",
702                 .stream_name = "Playback_5",
703                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
704                             SND_SOC_DPCM_TRIGGER_PRE},
705                 .dynamic = 1,
706                 .dpcm_playback = 1,
707                 SND_SOC_DAILINK_REG(playback5),
708         },
709         {
710                 .name = "Playback_6",
711                 .stream_name = "Playback_6",
712                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
713                             SND_SOC_DPCM_TRIGGER_PRE},
714                 .dynamic = 1,
715                 .dpcm_playback = 1,
716                 SND_SOC_DAILINK_REG(playback6),
717         },
718         {
719                 .name = "Playback_7",
720                 .stream_name = "Playback_7",
721                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
722                             SND_SOC_DPCM_TRIGGER_PRE},
723                 .dynamic = 1,
724                 .dpcm_playback = 1,
725                 SND_SOC_DAILINK_REG(playback7),
726         },
727         {
728                 .name = "Playback_8",
729                 .stream_name = "Playback_8",
730                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
731                             SND_SOC_DPCM_TRIGGER_PRE},
732                 .dynamic = 1,
733                 .dpcm_playback = 1,
734                 SND_SOC_DAILINK_REG(playback8),
735         },
736         {
737                 .name = "Capture_1",
738                 .stream_name = "Capture_1",
739                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
740                             SND_SOC_DPCM_TRIGGER_PRE},
741                 .dynamic = 1,
742                 .dpcm_capture = 1,
743                 SND_SOC_DAILINK_REG(capture1),
744         },
745         {
746                 .name = "Capture_2",
747                 .stream_name = "Capture_2",
748                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
749                             SND_SOC_DPCM_TRIGGER_PRE},
750                 .dynamic = 1,
751                 .dpcm_capture = 1,
752                 .dpcm_merged_format = 1,
753                 .dpcm_merged_chan = 1,
754                 .dpcm_merged_rate = 1,
755                 .ops = &mtk_soundcard_common_capture_ops,
756                 SND_SOC_DAILINK_REG(capture2),
757         },
758         {
759                 .name = "Capture_3",
760                 .stream_name = "Capture_3",
761                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
762                             SND_SOC_DPCM_TRIGGER_PRE},
763                 .dynamic = 1,
764                 .dpcm_capture = 1,
765                 SND_SOC_DAILINK_REG(capture3),
766         },
767         {
768                 .name = "Capture_4",
769                 .stream_name = "Capture_4",
770                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
771                             SND_SOC_DPCM_TRIGGER_PRE},
772                 .dynamic = 1,
773                 .dpcm_capture = 1,
774                 .dpcm_merged_format = 1,
775                 .dpcm_merged_chan = 1,
776                 .dpcm_merged_rate = 1,
777                 .ops = &mtk_soundcard_common_capture_ops,
778                 SND_SOC_DAILINK_REG(capture4),
779         },
780         {
781                 .name = "Capture_5",
782                 .stream_name = "Capture_5",
783                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
784                             SND_SOC_DPCM_TRIGGER_PRE},
785                 .dynamic = 1,
786                 .dpcm_capture = 1,
787                 SND_SOC_DAILINK_REG(capture5),
788         },
789         {
790                 .name = "Capture_6",
791                 .stream_name = "Capture_6",
792                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
793                             SND_SOC_DPCM_TRIGGER_PRE},
794                 .dynamic = 1,
795                 .dpcm_capture = 1,
796                 .dpcm_merged_format = 1,
797                 .dpcm_merged_chan = 1,
798                 .dpcm_merged_rate = 1,
799                 SND_SOC_DAILINK_REG(capture6),
800         },
801         {
802                 .name = "Capture_7",
803                 .stream_name = "Capture_7",
804                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
805                             SND_SOC_DPCM_TRIGGER_PRE},
806                 .dynamic = 1,
807                 .dpcm_capture = 1,
808                 SND_SOC_DAILINK_REG(capture7),
809         },
810         {
811                 .name = "Hostless_LPBK",
812                 .stream_name = "Hostless_LPBK",
813                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
814                             SND_SOC_DPCM_TRIGGER_PRE},
815                 .dynamic = 1,
816                 .dpcm_playback = 1,
817                 .dpcm_capture = 1,
818                 .ignore_suspend = 1,
819                 SND_SOC_DAILINK_REG(hostless_lpbk),
820         },
821         {
822                 .name = "Hostless_FM",
823                 .stream_name = "Hostless_FM",
824                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
825                             SND_SOC_DPCM_TRIGGER_PRE},
826                 .dynamic = 1,
827                 .dpcm_playback = 1,
828                 .dpcm_capture = 1,
829                 .ignore_suspend = 1,
830                 SND_SOC_DAILINK_REG(hostless_fm),
831         },
832         {
833                 .name = "Hostless_SRC_1",
834                 .stream_name = "Hostless_SRC_1",
835                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
836                             SND_SOC_DPCM_TRIGGER_PRE},
837                 .dynamic = 1,
838                 .dpcm_playback = 1,
839                 .dpcm_capture = 1,
840                 .ignore_suspend = 1,
841                 SND_SOC_DAILINK_REG(hostless_src1),
842         },
843         {
844                 .name = "Hostless_SRC_Bargein",
845                 .stream_name = "Hostless_SRC_Bargein",
846                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
847                             SND_SOC_DPCM_TRIGGER_PRE},
848                 .dynamic = 1,
849                 .dpcm_playback = 1,
850                 .dpcm_capture = 1,
851                 .ignore_suspend = 1,
852                 SND_SOC_DAILINK_REG(hostless_src_bargein),
853         },
854         {
855                 .name = "Hostless_HW_Gain_AAudio",
856                 .stream_name = "Hostless_HW_Gain_AAudio",
857                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
858                             SND_SOC_DPCM_TRIGGER_PRE},
859                 .dynamic = 1,
860                 .dpcm_capture = 1,
861                 .ignore_suspend = 1,
862                 SND_SOC_DAILINK_REG(hostless_hw_gain_aaudio),
863         },
864         {
865                 .name = "Hostless_SRC_AAudio",
866                 .stream_name = "Hostless_SRC_AAudio",
867                 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
868                             SND_SOC_DPCM_TRIGGER_PRE},
869                 .dynamic = 1,
870                 .dpcm_playback = 1,
871                 .dpcm_capture = 1,
872                 .ignore_suspend = 1,
873                 SND_SOC_DAILINK_REG(hostless_src_aaudio),
874         },
875         /* Back End DAI links */
876         {
877                 .name = "Primary Codec",
878                 .no_pcm = 1,
879                 .dpcm_playback = 1,
880                 .dpcm_capture = 1,
881                 .ignore_suspend = 1,
882                 .init = primary_codec_init,
883                 SND_SOC_DAILINK_REG(adda),
884         },
885         {
886                 .name = "I2S3",
887                 .no_pcm = 1,
888                 .dai_fmt = SND_SOC_DAIFMT_I2S |
889                            SND_SOC_DAIFMT_IB_IF |
890                            SND_SOC_DAIFMT_CBM_CFM,
891                 .dpcm_playback = 1,
892                 .ignore_suspend = 1,
893                 .init = mt8186_mt6366_rt1019_rt5682s_hdmi_init,
894                 SND_SOC_DAILINK_REG(i2s3),
895         },
896         {
897                 .name = "I2S0",
898                 .no_pcm = 1,
899                 .dpcm_capture = 1,
900                 .ignore_suspend = 1,
901                 .ops = &mt8186_rt5682s_i2s_ops,
902                 SND_SOC_DAILINK_REG(i2s0),
903         },
904         {
905                 .name = "I2S1",
906                 .no_pcm = 1,
907                 .dpcm_playback = 1,
908                 .ignore_suspend = 1,
909                 .init = mt8186_headset_codec_init,
910                 SND_SOC_DAILINK_REG(i2s1),
911         },
912         {
913                 .name = "I2S2",
914                 .no_pcm = 1,
915                 .dpcm_capture = 1,
916                 .ignore_suspend = 1,
917                 SND_SOC_DAILINK_REG(i2s2),
918         },
919         {
920                 .name = "HW Gain 1",
921                 .no_pcm = 1,
922                 .dpcm_playback = 1,
923                 .dpcm_capture = 1,
924                 .ignore_suspend = 1,
925                 SND_SOC_DAILINK_REG(hw_gain1),
926         },
927         {
928                 .name = "HW Gain 2",
929                 .no_pcm = 1,
930                 .dpcm_playback = 1,
931                 .dpcm_capture = 1,
932                 .ignore_suspend = 1,
933                 SND_SOC_DAILINK_REG(hw_gain2),
934         },
935         {
936                 .name = "HW_SRC_1",
937                 .no_pcm = 1,
938                 .dpcm_playback = 1,
939                 .dpcm_capture = 1,
940                 .ignore_suspend = 1,
941                 SND_SOC_DAILINK_REG(hw_src1),
942         },
943         {
944                 .name = "HW_SRC_2",
945                 .no_pcm = 1,
946                 .dpcm_playback = 1,
947                 .dpcm_capture = 1,
948                 .ignore_suspend = 1,
949                 SND_SOC_DAILINK_REG(hw_src2),
950         },
951         {
952                 .name = "CONNSYS_I2S",
953                 .no_pcm = 1,
954                 .dpcm_capture = 1,
955                 .ignore_suspend = 1,
956                 SND_SOC_DAILINK_REG(connsys_i2s),
957         },
958         {
959                 .name = "PCM 1",
960                 .dai_fmt = SND_SOC_DAIFMT_I2S |
961                            SND_SOC_DAIFMT_NB_IF,
962                 .no_pcm = 1,
963                 .dpcm_playback = 1,
964                 .dpcm_capture = 1,
965                 .ignore_suspend = 1,
966                 SND_SOC_DAILINK_REG(pcm1),
967         },
968         {
969                 .name = "TDM IN",
970                 .no_pcm = 1,
971                 .dpcm_capture = 1,
972                 .ignore_suspend = 1,
973                 SND_SOC_DAILINK_REG(tdm_in),
974         },
975         /* dummy BE for ul memif to record from dl memif */
976         {
977                 .name = "Hostless_UL1",
978                 .no_pcm = 1,
979                 .dpcm_capture = 1,
980                 .ignore_suspend = 1,
981                 SND_SOC_DAILINK_REG(hostless_ul1),
982         },
983         {
984                 .name = "Hostless_UL2",
985                 .no_pcm = 1,
986                 .dpcm_capture = 1,
987                 .ignore_suspend = 1,
988                 SND_SOC_DAILINK_REG(hostless_ul2),
989         },
990         {
991                 .name = "Hostless_UL3",
992                 .no_pcm = 1,
993                 .dpcm_capture = 1,
994                 .ignore_suspend = 1,
995                 SND_SOC_DAILINK_REG(hostless_ul3),
996         },
997         {
998                 .name = "Hostless_UL5",
999                 .no_pcm = 1,
1000                 .dpcm_capture = 1,
1001                 .ignore_suspend = 1,
1002                 SND_SOC_DAILINK_REG(hostless_ul5),
1003         },
1004         {
1005                 .name = "Hostless_UL6",
1006                 .no_pcm = 1,
1007                 .dpcm_capture = 1,
1008                 .ignore_suspend = 1,
1009                 SND_SOC_DAILINK_REG(hostless_ul6),
1010         },
1011         /* SOF BE */
1012         {
1013                 .name = "AFE_SOF_DL1",
1014                 .no_pcm = 1,
1015                 .dpcm_playback = 1,
1016                 SND_SOC_DAILINK_REG(AFE_SOF_DL1),
1017         },
1018         {
1019                 .name = "AFE_SOF_DL2",
1020                 .no_pcm = 1,
1021                 .dpcm_playback = 1,
1022                 SND_SOC_DAILINK_REG(AFE_SOF_DL2),
1023         },
1024         {
1025                 .name = "AFE_SOF_UL1",
1026                 .no_pcm = 1,
1027                 .dpcm_capture = 1,
1028                 SND_SOC_DAILINK_REG(AFE_SOF_UL1),
1029         },
1030         {
1031                 .name = "AFE_SOF_UL2",
1032                 .no_pcm = 1,
1033                 .dpcm_capture = 1,
1034                 SND_SOC_DAILINK_REG(AFE_SOF_UL2),
1035         },
1036 };
1037 
1038 static const struct snd_soc_dapm_widget
1039 mt8186_mt6366_da7219_max98357_widgets[] = {
1040         SND_SOC_DAPM_SPK("Speakers", NULL),
1041         SND_SOC_DAPM_HP("Headphones", NULL),
1042         SND_SOC_DAPM_MIC("Headset Mic", NULL),
1043         SND_SOC_DAPM_LINE("Line Out", NULL),
1044         SND_SOC_DAPM_LINE("HDMI1", NULL),
1045         SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1046         SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1047         SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1048         SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1049 };
1050 
1051 static const struct snd_soc_dapm_widget
1052 mt8186_mt6366_rt1019_rt5682s_widgets[] = {
1053         SND_SOC_DAPM_SPK("Speakers", NULL),
1054         SND_SOC_DAPM_HP("Headphone", NULL),
1055         SND_SOC_DAPM_MIC("Headset Mic", NULL),
1056         SND_SOC_DAPM_OUTPUT("HDMI1"),
1057         SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1058         SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1059         SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0),
1060         SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0),
1061 };
1062 
1063 static const struct snd_soc_dapm_route
1064 mt8186_mt6366_rt1019_rt5682s_routes[] = {
1065         /* SPK */
1066         { "Speakers", NULL, "Speaker" },
1067         /* Headset */
1068         { "Headphone", NULL, "HPOL" },
1069         { "Headphone", NULL, "HPOR" },
1070         { "IN1P", NULL, "Headset Mic" },
1071         /* HDMI */
1072         { "HDMI1", NULL, "TX" },
1073         /* SOF Uplink */
1074         {SOF_DMA_UL1, NULL, "UL1_CH1"},
1075         {SOF_DMA_UL1, NULL, "UL1_CH2"},
1076         {SOF_DMA_UL2, NULL, "UL2_CH1"},
1077         {SOF_DMA_UL2, NULL, "UL2_CH2"},
1078         /* SOF Downlink */
1079         {"DSP_DL1_VIRT", NULL, SOF_DMA_DL1},
1080         {"DSP_DL2_VIRT", NULL, SOF_DMA_DL2},
1081 };
1082 
1083 static const struct snd_soc_dapm_route mt8186_mt6366_rt5650_routes[] = {
1084         /* SPK */
1085         {"Speakers", NULL, "SPOL"},
1086         {"Speakers", NULL, "SPOR"},
1087         /* Headset */
1088         { "Headphone", NULL, "HPOL" },
1089         { "Headphone", NULL, "HPOR" },
1090         { "IN1P", NULL, "Headset Mic" },
1091         { "IN1N", NULL, "Headset Mic"},
1092         /* HDMI */
1093         { "HDMI1", NULL, "TX" },
1094         /* SOF Uplink */
1095         {SOF_DMA_UL1, NULL, "UL1_CH1"},
1096         {SOF_DMA_UL1, NULL, "UL1_CH2"},
1097         {SOF_DMA_UL2, NULL, "UL2_CH1"},
1098         {SOF_DMA_UL2, NULL, "UL2_CH2"},
1099         /* SOF Downlink */
1100         {"DSP_DL1_VIRT", NULL, SOF_DMA_DL1},
1101         {"DSP_DL2_VIRT", NULL, SOF_DMA_DL2},
1102 };
1103 
1104 static const struct snd_kcontrol_new mt8186_mt6366_da7219_max98357_controls[] = {
1105         SOC_DAPM_PIN_SWITCH("Speakers"),
1106         SOC_DAPM_PIN_SWITCH("Headphones"),
1107         SOC_DAPM_PIN_SWITCH("Headset Mic"),
1108         SOC_DAPM_PIN_SWITCH("Line Out"),
1109         SOC_DAPM_PIN_SWITCH("HDMI1"),
1110 };
1111 
1112 static const struct snd_kcontrol_new
1113 mt8186_mt6366_rt1019_rt5682s_controls[] = {
1114         SOC_DAPM_PIN_SWITCH("Speakers"),
1115         SOC_DAPM_PIN_SWITCH("Headphone"),
1116         SOC_DAPM_PIN_SWITCH("Headset Mic"),
1117         SOC_DAPM_PIN_SWITCH("HDMI1"),
1118 };
1119 
1120 static struct snd_soc_card mt8186_mt6366_da7219_max98357_soc_card = {
1121         .name = "mt8186_da7219_max98357",
1122         .owner = THIS_MODULE,
1123         .dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1124         .num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1125         .controls = mt8186_mt6366_da7219_max98357_controls,
1126         .num_controls = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_controls),
1127         .dapm_widgets = mt8186_mt6366_da7219_max98357_widgets,
1128         .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_widgets),
1129         .dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
1130         .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
1131         .codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1132         .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1133 };
1134 
1135 static struct snd_soc_card mt8186_mt6366_rt1019_rt5682s_soc_card = {
1136         .name = "mt8186_rt1019_rt5682s",
1137         .owner = THIS_MODULE,
1138         .dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1139         .num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1140         .controls = mt8186_mt6366_rt1019_rt5682s_controls,
1141         .num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
1142         .dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
1143         .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
1144         .dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
1145         .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
1146         .codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1147         .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1148 };
1149 
1150 static struct snd_soc_card mt8186_mt6366_rt5682s_max98360_soc_card = {
1151         .name = "mt8186_rt5682s_max98360",
1152         .owner = THIS_MODULE,
1153         .dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1154         .num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1155         .controls = mt8186_mt6366_rt1019_rt5682s_controls,
1156         .num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
1157         .dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
1158         .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
1159         .dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
1160         .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
1161         .codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1162         .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1163 };
1164 
1165 static struct snd_soc_card mt8186_mt6366_rt5650_soc_card = {
1166         .name = "mt8186_rt5650",
1167         .owner = THIS_MODULE,
1168         .dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
1169         .num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
1170         .controls = mt8186_mt6366_rt1019_rt5682s_controls,
1171         .num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
1172         .dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
1173         .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
1174         .dapm_routes = mt8186_mt6366_rt5650_routes,
1175         .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt5650_routes),
1176         .codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
1177         .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
1178 };
1179 
1180 static int mt8186_mt6366_legacy_probe(struct mtk_soc_card_data *soc_card_data)
1181 {
1182         struct mtk_platform_card_data *card_data = soc_card_data->card_data;
1183         struct snd_soc_card *card = card_data->card;
1184         struct device *dev = card->dev;
1185         struct snd_soc_dai_link *dai_link;
1186         struct device_node *headset_codec, *playback_codec;
1187         int ret, i;
1188 
1189         playback_codec = of_get_child_by_name(dev->of_node, "playback-codecs");
1190         if (!playback_codec)
1191                 return dev_err_probe(dev, -EINVAL,
1192                                      "Property 'playback-codecs' missing or invalid\n");
1193 
1194         headset_codec = of_get_child_by_name(dev->of_node, "headset-codec");
1195         if (!headset_codec) {
1196                 of_node_put(playback_codec);
1197                 return dev_err_probe(dev, -EINVAL,
1198                                      "Property 'headset-codec' missing or invalid\n");
1199         }
1200 
1201         for_each_card_prelinks(card, i, dai_link) {
1202                 ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3");
1203                 if (ret) {
1204                         dev_err_probe(dev, ret, "%s set playback_codec fail\n",
1205                                       dai_link->name);
1206                         break;
1207                 }
1208 
1209                 ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S0");
1210                 if (ret) {
1211                         dev_err_probe(dev, ret, "%s set headset_codec fail\n",
1212                                       dai_link->name);
1213                         break;
1214                 }
1215 
1216                 ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S1");
1217                 if (ret) {
1218                         dev_err_probe(dev, ret, "%s set headset_codec fail\n",
1219                                       dai_link->name);
1220                         break;
1221                 }
1222         }
1223         of_node_put(headset_codec);
1224         of_node_put(playback_codec);
1225 
1226         return ret;
1227 }
1228 
1229 static int mt8186_mt6366_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)
1230 {
1231         struct mtk_platform_card_data *card_data = soc_card_data->card_data;
1232         struct snd_soc_card *card = card_data->card;
1233         struct snd_soc_dai_link *dai_link;
1234         struct mt8186_mt6366_rt1019_rt5682s_priv *mach_priv;
1235         int i, ret;
1236 
1237         mach_priv = devm_kzalloc(card->dev, sizeof(*mach_priv), GFP_KERNEL);
1238         if (!mach_priv)
1239                 return -ENOMEM;
1240 
1241         soc_card_data->mach_priv = mach_priv;
1242 
1243         mach_priv->dmic_sel = devm_gpiod_get_optional(card->dev,
1244                                                       "dmic", GPIOD_OUT_LOW);
1245         if (IS_ERR(mach_priv->dmic_sel))
1246                 return dev_err_probe(card->dev, PTR_ERR(mach_priv->dmic_sel),
1247                                      "DMIC gpio failed\n");
1248 
1249         for_each_card_prelinks(card, i, dai_link) {
1250                 if (strcmp(dai_link->name, "I2S0") == 0 ||
1251                     strcmp(dai_link->name, "I2S1") == 0 ||
1252                     strcmp(dai_link->name, "I2S2") == 0) {
1253                         if (card_data->flags & DA7219_CODEC_PRESENT) {
1254                                 dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_32le_fixup;
1255                                 dai_link->ops = &mt8186_da7219_i2s_ops;
1256                         } else {
1257                                 dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_24le_fixup;
1258                                 dai_link->ops = &mt8186_rt5682s_i2s_ops;
1259                         }
1260                 } else if (strcmp(dai_link->name, "I2S3") == 0) {
1261                         if (card_data->flags & DA7219_CODEC_PRESENT)
1262                                 dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_24le_fixup;
1263                         else
1264                                 dai_link->be_hw_params_fixup = mt8186_i2s_hw_params_32le_fixup;
1265                 }
1266         }
1267 
1268         if (legacy) {
1269                 ret = mt8186_mt6366_legacy_probe(soc_card_data);
1270                 if (ret)
1271                         return ret;
1272         }
1273 
1274         ret = mt8186_afe_gpio_init(card->dev);
1275         if (ret)
1276                 return dev_err_probe(card->dev, ret, "init AFE gpio error\n");
1277 
1278         return 0;
1279 }
1280 
1281 static const unsigned int mt8186_pcm_playback_channels[] = { 2 };
1282 static const unsigned int mt8186_pcm_capture_channels[] = { 1, 2 };
1283 static const unsigned int mt8186_pcm_rates[] = { 48000 };
1284 
1285 static const struct snd_pcm_hw_constraint_list mt8186_rate_constraint = {
1286         .list = mt8186_pcm_rates,
1287         .count = ARRAY_SIZE(mt8186_pcm_rates)
1288 };
1289 
1290 static const struct mtk_pcm_constraints_data mt8186_pcm_constraints[MTK_CONSTRAINT_CAPTURE + 1] = {
1291         [MTK_CONSTRAINT_PLAYBACK] = {
1292                 .channels = &(const struct snd_pcm_hw_constraint_list) {
1293                         .list = mt8186_pcm_playback_channels,
1294                         .count = ARRAY_SIZE(mt8186_pcm_playback_channels)
1295                 },
1296                 .rates = &mt8186_rate_constraint,
1297         },
1298         [MTK_CONSTRAINT_CAPTURE] = {
1299                 .channels = &(const struct snd_pcm_hw_constraint_list) {
1300                         .list = mt8186_pcm_capture_channels,
1301                         .count = ARRAY_SIZE(mt8186_pcm_capture_channels)
1302                 },
1303                 .rates = &mt8186_rate_constraint,
1304         }
1305 };
1306 
1307 static const struct mtk_sof_priv mt8186_sof_priv = {
1308         .conn_streams = g_sof_conn_streams,
1309         .num_streams = ARRAY_SIZE(g_sof_conn_streams),
1310         .sof_dai_link_fixup = mt8186_sof_dai_link_fixup
1311 };
1312 
1313 static const struct mtk_soundcard_pdata mt8186_mt6366_da7219_max98357_pdata = {
1314         .card_data = &(struct mtk_platform_card_data) {
1315                 .card = &mt8186_mt6366_da7219_max98357_soc_card,
1316                 .num_jacks = MT8186_JACK_MAX,
1317                 .pcm_constraints = mt8186_pcm_constraints,
1318                 .num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1319                 .flags = DA7219_CODEC_PRESENT,
1320         },
1321         .sof_priv = &mt8186_sof_priv,
1322         .soc_probe = mt8186_mt6366_soc_card_probe
1323 };
1324 
1325 static const struct mtk_soundcard_pdata mt8186_mt6366_rt1019_rt5682s_pdata = {
1326         .card_data = &(struct mtk_platform_card_data) {
1327                 .card = &mt8186_mt6366_rt1019_rt5682s_soc_card,
1328                 .num_jacks = MT8186_JACK_MAX,
1329                 .pcm_constraints = mt8186_pcm_constraints,
1330                 .num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1331         },
1332         .sof_priv = &mt8186_sof_priv,
1333         .soc_probe = mt8186_mt6366_soc_card_probe
1334 };
1335 
1336 static const struct mtk_soundcard_pdata mt8186_mt6366_rt5682s_max98360_pdata = {
1337         .card_data = &(struct mtk_platform_card_data) {
1338                 .card = &mt8186_mt6366_rt5682s_max98360_soc_card,
1339                 .num_jacks = MT8186_JACK_MAX,
1340                 .pcm_constraints = mt8186_pcm_constraints,
1341                 .num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1342         },
1343         .sof_priv = &mt8186_sof_priv,
1344         .soc_probe = mt8186_mt6366_soc_card_probe
1345 };
1346 
1347 static const struct mtk_soundcard_pdata mt8186_mt6366_rt5650_pdata = {
1348         .card_data = &(struct mtk_platform_card_data) {
1349                 .card = &mt8186_mt6366_rt5650_soc_card,
1350                 .num_jacks = MT8186_JACK_MAX,
1351                 .pcm_constraints = mt8186_pcm_constraints,
1352                 .num_pcm_constraints = ARRAY_SIZE(mt8186_pcm_constraints),
1353         },
1354         .sof_priv = &mt8186_sof_priv,
1355         .soc_probe = mt8186_mt6366_soc_card_probe
1356 };
1357 
1358 #if IS_ENABLED(CONFIG_OF)
1359 static const struct of_device_id mt8186_mt6366_dt_match[] = {
1360         {
1361                 .compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound",
1362                 .data = &mt8186_mt6366_rt1019_rt5682s_pdata,
1363         },
1364         {
1365                 .compatible = "mediatek,mt8186-mt6366-rt5682s-max98360-sound",
1366                 .data = &mt8186_mt6366_rt5682s_max98360_pdata,
1367         },
1368         {
1369                 .compatible = "mediatek,mt8186-mt6366-rt5650-sound",
1370                 .data = &mt8186_mt6366_rt5650_pdata,
1371         },
1372         {
1373                 .compatible = "mediatek,mt8186-mt6366-da7219-max98357-sound",
1374                 .data = &mt8186_mt6366_da7219_max98357_pdata,
1375         },
1376         { /* sentinel */ }
1377 };
1378 MODULE_DEVICE_TABLE(of, mt8186_mt6366_dt_match);
1379 #endif
1380 
1381 static struct platform_driver mt8186_mt6366_driver = {
1382         .driver = {
1383                 .name = "mt8186_mt6366",
1384 #if IS_ENABLED(CONFIG_OF)
1385                 .of_match_table = mt8186_mt6366_dt_match,
1386 #endif
1387                 .pm = &snd_soc_pm_ops,
1388         },
1389         .probe = mtk_soundcard_common_probe,
1390 };
1391 
1392 module_platform_driver(mt8186_mt6366_driver);
1393 
1394 /* Module information */
1395 MODULE_DESCRIPTION("MT8186-MT6366 ALSA SoC machine driver");
1396 MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
1397 MODULE_LICENSE("GPL v2");
1398 MODULE_ALIAS("mt8186_mt6366 soc card");
1399 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php