1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mt8186-mt6366-da7219-max98357.c 4 // -- MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver 5 // 6 // Copyright (c) 2022 MediaTek Inc. 7 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com> 8 // 9 10 #include <linux/input.h> 11 #include <linux/module.h> 12 #include <linux/of_device.h> 13 #include <sound/jack.h> 14 #include <sound/pcm_params.h> 15 #include <sound/soc.h> 16 17 #include "../../codecs/da7219.h" 18 #include "../../codecs/mt6358.h" 19 #include "../common/mtk-afe-platform-driver.h" 20 #include "../common/mtk-dsp-sof-common.h" 21 #include "../common/mtk-soc-card.h" 22 #include "mt8186-afe-common.h" 23 #include "mt8186-afe-clk.h" 24 #include "mt8186-afe-gpio.h" 25 #include "mt8186-mt6366-common.h" 26 27 #define DA7219_CODEC_DAI "da7219-hifi" 28 #define DA7219_DEV_NAME "da7219.5-001a" 29 30 #define SOF_DMA_DL1 "SOF_DMA_DL1" 31 #define SOF_DMA_DL2 "SOF_DMA_DL2" 32 #define SOF_DMA_UL1 "SOF_DMA_UL1" 33 #define SOF_DMA_UL2 "SOF_DMA_UL2" 34 35 struct mt8186_mt6366_da7219_max98357_priv { 36 struct snd_soc_jack headset_jack, hdmi_jack; 37 }; 38 39 /* Headset jack detection DAPM pins */ 40 static struct snd_soc_jack_pin mt8186_jack_pins[] = { 41 { 42 .pin = "Headphones", 43 .mask = SND_JACK_HEADPHONE, 44 }, 45 { 46 .pin = "Headset Mic", 47 .mask = SND_JACK_MICROPHONE, 48 }, 49 { 50 .pin = "Line Out", 51 .mask = SND_JACK_LINEOUT, 52 }, 53 }; 54 55 static struct snd_soc_codec_conf mt8186_mt6366_da7219_max98357_codec_conf[] = { 56 { 57 .dlc = COMP_CODEC_CONF("mt6358-sound"), 58 .name_prefix = "Mt6366", 59 }, 60 { 61 .dlc = COMP_CODEC_CONF("bt-sco"), 62 .name_prefix = "Mt8186 bt", 63 }, 64 { 65 .dlc = COMP_CODEC_CONF("hdmi-audio-codec"), 66 .name_prefix = "Mt8186 hdmi", 67 }, 68 }; 69 70 static int mt8186_da7219_init(struct snd_soc_pcm_runtime *rtd) 71 { 72 struct snd_soc_component *cmpnt_afe = 73 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 74 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 75 struct mtk_soc_card_data *soc_card_data = 76 snd_soc_card_get_drvdata(rtd->card); 77 struct mt8186_mt6366_da7219_max98357_priv *priv = soc_card_data->mach_priv; 78 struct snd_soc_jack *jack = &priv->headset_jack; 79 struct snd_soc_component *cmpnt_codec = 80 asoc_rtd_to_codec(rtd, 0)->component; 81 int ret; 82 83 ret = mt8186_dai_i2s_set_share(afe, "I2S1", "I2S0"); 84 if (ret) { 85 dev_err(rtd->dev, "Failed to set up shared clocks\n"); 86 return ret; 87 } 88 89 /* Enable Headset and 4 Buttons Jack detection */ 90 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", 91 SND_JACK_HEADSET | SND_JACK_BTN_0 | 92 SND_JACK_BTN_1 | SND_JACK_BTN_2 | 93 SND_JACK_BTN_3 | SND_JACK_LINEOUT, 94 jack, mt8186_jack_pins, 95 ARRAY_SIZE(mt8186_jack_pins)); 96 if (ret) { 97 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); 98 return ret; 99 } 100 101 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 102 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 103 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 104 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 105 106 snd_soc_component_set_jack(cmpnt_codec, &priv->headset_jack, NULL); 107 108 return 0; 109 } 110 111 static int mt8186_da7219_i2s_hw_params(struct snd_pcm_substream *substream, 112 struct snd_pcm_hw_params *params) 113 { 114 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 115 struct snd_soc_dai *codec_dai; 116 unsigned int rate = params_rate(params); 117 unsigned int mclk_fs_ratio = 256; 118 unsigned int mclk_fs = rate * mclk_fs_ratio; 119 unsigned int freq; 120 int ret, j; 121 122 ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, 123 mclk_fs, SND_SOC_CLOCK_OUT); 124 if (ret < 0) { 125 dev_err(rtd->dev, "failed to set cpu dai sysclk: %d\n", ret); 126 return ret; 127 } 128 129 for_each_rtd_codec_dais(rtd, j, codec_dai) { 130 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { 131 ret = snd_soc_dai_set_sysclk(codec_dai, 132 DA7219_CLKSRC_MCLK, 133 mclk_fs, 134 SND_SOC_CLOCK_IN); 135 if (ret < 0) { 136 dev_err(rtd->dev, "failed to set sysclk: %d\n", 137 ret); 138 return ret; 139 } 140 141 if ((rate % 8000) == 0) 142 freq = DA7219_PLL_FREQ_OUT_98304; 143 else 144 freq = DA7219_PLL_FREQ_OUT_90316; 145 146 ret = snd_soc_dai_set_pll(codec_dai, 0, 147 DA7219_SYSCLK_PLL_SRM, 148 0, freq); 149 if (ret) { 150 dev_err(rtd->dev, "failed to start PLL: %d\n", 151 ret); 152 return ret; 153 } 154 } 155 } 156 157 return 0; 158 } 159 160 static int mt8186_da7219_i2s_hw_free(struct snd_pcm_substream *substream) 161 { 162 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 163 struct snd_soc_dai *codec_dai; 164 int ret = 0, j; 165 166 for_each_rtd_codec_dais(rtd, j, codec_dai) { 167 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { 168 ret = snd_soc_dai_set_pll(codec_dai, 169 0, DA7219_SYSCLK_MCLK, 0, 0); 170 if (ret < 0) { 171 dev_err(rtd->dev, "failed to stop PLL: %d\n", 172 ret); 173 return ret; 174 } 175 } 176 } 177 178 return 0; 179 } 180 181 static const struct snd_soc_ops mt8186_da7219_i2s_ops = { 182 .hw_params = mt8186_da7219_i2s_hw_params, 183 .hw_free = mt8186_da7219_i2s_hw_free, 184 }; 185 186 static int mt8186_mt6366_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd) 187 { 188 struct snd_soc_component *cmpnt_afe = 189 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 190 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 191 struct snd_soc_component *cmpnt_codec = 192 asoc_rtd_to_codec(rtd, 0)->component; 193 struct mtk_soc_card_data *soc_card_data = 194 snd_soc_card_get_drvdata(rtd->card); 195 struct mt8186_mt6366_da7219_max98357_priv *priv = soc_card_data->mach_priv; 196 int ret; 197 198 ret = mt8186_dai_i2s_set_share(afe, "I2S2", "I2S3"); 199 if (ret) { 200 dev_err(rtd->dev, "Failed to set up shared clocks\n"); 201 return ret; 202 } 203 204 ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, &priv->hdmi_jack); 205 if (ret) { 206 dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret); 207 return ret; 208 } 209 210 return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); 211 } 212 213 static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 214 struct snd_pcm_hw_params *params, 215 snd_pcm_format_t fmt) 216 { 217 struct snd_interval *channels = hw_param_interval(params, 218 SNDRV_PCM_HW_PARAM_CHANNELS); 219 220 dev_dbg(rtd->dev, "%s(), fix format to %d\n", __func__, fmt); 221 222 /* fix BE i2s channel to 2 channel */ 223 channels->min = 2; 224 channels->max = 2; 225 226 /* clean param mask first */ 227 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 228 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 229 230 params_set_format(params, fmt); 231 232 return 0; 233 } 234 235 static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 236 struct snd_pcm_hw_params *params) 237 { 238 return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE); 239 } 240 241 static int mt8186_anx7625_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 242 struct snd_pcm_hw_params *params) 243 { 244 return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE); 245 } 246 247 /* fixup the BE DAI link to match any values from topology */ 248 static int mt8186_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, 249 struct snd_pcm_hw_params *params) 250 { 251 int ret; 252 253 ret = mtk_sof_dai_link_fixup(rtd, params); 254 255 if (!strcmp(rtd->dai_link->name, "I2S0") || 256 !strcmp(rtd->dai_link->name, "I2S1") || 257 !strcmp(rtd->dai_link->name, "I2S2")) 258 mt8186_i2s_hw_params_fixup(rtd, params); 259 else if (!strcmp(rtd->dai_link->name, "I2S3")) 260 mt8186_anx7625_i2s_hw_params_fixup(rtd, params); 261 262 return ret; 263 } 264 265 static int mt8186_mt6366_da7219_max98357_playback_startup(struct snd_pcm_substream *substream) 266 { 267 static const unsigned int rates[] = { 268 48000 269 }; 270 static const unsigned int channels[] = { 271 2 272 }; 273 static const struct snd_pcm_hw_constraint_list constraints_rates = { 274 .count = ARRAY_SIZE(rates), 275 .list = rates, 276 .mask = 0, 277 }; 278 static const struct snd_pcm_hw_constraint_list constraints_channels = { 279 .count = ARRAY_SIZE(channels), 280 .list = channels, 281 .mask = 0, 282 }; 283 284 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 285 struct snd_pcm_runtime *runtime = substream->runtime; 286 int ret; 287 288 ret = snd_pcm_hw_constraint_list(runtime, 0, 289 SNDRV_PCM_HW_PARAM_RATE, 290 &constraints_rates); 291 if (ret < 0) { 292 dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 293 return ret; 294 } 295 296 ret = snd_pcm_hw_constraint_list(runtime, 0, 297 SNDRV_PCM_HW_PARAM_CHANNELS, 298 &constraints_channels); 299 if (ret < 0) { 300 dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 301 return ret; 302 } 303 304 return 0; 305 } 306 307 static const struct snd_soc_ops mt8186_mt6366_da7219_max98357_playback_ops = { 308 .startup = mt8186_mt6366_da7219_max98357_playback_startup, 309 }; 310 311 static int mt8186_mt6366_da7219_max98357_capture_startup(struct snd_pcm_substream *substream) 312 { 313 static const unsigned int rates[] = { 314 48000 315 }; 316 static const unsigned int channels[] = { 317 1, 2 318 }; 319 static const struct snd_pcm_hw_constraint_list constraints_rates = { 320 .count = ARRAY_SIZE(rates), 321 .list = rates, 322 .mask = 0, 323 }; 324 static const struct snd_pcm_hw_constraint_list constraints_channels = { 325 .count = ARRAY_SIZE(channels), 326 .list = channels, 327 .mask = 0, 328 }; 329 330 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 331 struct snd_pcm_runtime *runtime = substream->runtime; 332 int ret; 333 334 ret = snd_pcm_hw_constraint_list(runtime, 0, 335 SNDRV_PCM_HW_PARAM_RATE, 336 &constraints_rates); 337 if (ret < 0) { 338 dev_err(rtd->dev, "hw_constraint_list rate failed\n"); 339 return ret; 340 } 341 342 ret = snd_pcm_hw_constraint_list(runtime, 0, 343 SNDRV_PCM_HW_PARAM_CHANNELS, 344 &constraints_channels); 345 if (ret < 0) { 346 dev_err(rtd->dev, "hw_constraint_list channel failed\n"); 347 return ret; 348 } 349 350 return 0; 351 } 352 353 static const struct snd_soc_ops mt8186_mt6366_da7219_max98357_capture_ops = { 354 .startup = mt8186_mt6366_da7219_max98357_capture_startup, 355 }; 356 357 /* FE */ 358 SND_SOC_DAILINK_DEFS(playback1, 359 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 360 DAILINK_COMP_ARRAY(COMP_DUMMY()), 361 DAILINK_COMP_ARRAY(COMP_EMPTY())); 362 363 SND_SOC_DAILINK_DEFS(playback12, 364 DAILINK_COMP_ARRAY(COMP_CPU("DL12")), 365 DAILINK_COMP_ARRAY(COMP_DUMMY()), 366 DAILINK_COMP_ARRAY(COMP_EMPTY())); 367 368 SND_SOC_DAILINK_DEFS(playback2, 369 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 370 DAILINK_COMP_ARRAY(COMP_DUMMY()), 371 DAILINK_COMP_ARRAY(COMP_EMPTY())); 372 373 SND_SOC_DAILINK_DEFS(playback3, 374 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 375 DAILINK_COMP_ARRAY(COMP_DUMMY()), 376 DAILINK_COMP_ARRAY(COMP_EMPTY())); 377 378 SND_SOC_DAILINK_DEFS(playback4, 379 DAILINK_COMP_ARRAY(COMP_CPU("DL4")), 380 DAILINK_COMP_ARRAY(COMP_DUMMY()), 381 DAILINK_COMP_ARRAY(COMP_EMPTY())); 382 383 SND_SOC_DAILINK_DEFS(playback5, 384 DAILINK_COMP_ARRAY(COMP_CPU("DL5")), 385 DAILINK_COMP_ARRAY(COMP_DUMMY()), 386 DAILINK_COMP_ARRAY(COMP_EMPTY())); 387 388 SND_SOC_DAILINK_DEFS(playback6, 389 DAILINK_COMP_ARRAY(COMP_CPU("DL6")), 390 DAILINK_COMP_ARRAY(COMP_DUMMY()), 391 DAILINK_COMP_ARRAY(COMP_EMPTY())); 392 393 SND_SOC_DAILINK_DEFS(playback7, 394 DAILINK_COMP_ARRAY(COMP_CPU("DL7")), 395 DAILINK_COMP_ARRAY(COMP_DUMMY()), 396 DAILINK_COMP_ARRAY(COMP_EMPTY())); 397 398 SND_SOC_DAILINK_DEFS(playback8, 399 DAILINK_COMP_ARRAY(COMP_CPU("DL8")), 400 DAILINK_COMP_ARRAY(COMP_DUMMY()), 401 DAILINK_COMP_ARRAY(COMP_EMPTY())); 402 403 SND_SOC_DAILINK_DEFS(capture1, 404 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 405 DAILINK_COMP_ARRAY(COMP_DUMMY()), 406 DAILINK_COMP_ARRAY(COMP_EMPTY())); 407 408 SND_SOC_DAILINK_DEFS(capture2, 409 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 410 DAILINK_COMP_ARRAY(COMP_DUMMY()), 411 DAILINK_COMP_ARRAY(COMP_EMPTY())); 412 413 SND_SOC_DAILINK_DEFS(capture3, 414 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 415 DAILINK_COMP_ARRAY(COMP_DUMMY()), 416 DAILINK_COMP_ARRAY(COMP_EMPTY())); 417 418 SND_SOC_DAILINK_DEFS(capture4, 419 DAILINK_COMP_ARRAY(COMP_CPU("UL4")), 420 DAILINK_COMP_ARRAY(COMP_DUMMY()), 421 DAILINK_COMP_ARRAY(COMP_EMPTY())); 422 423 SND_SOC_DAILINK_DEFS(capture5, 424 DAILINK_COMP_ARRAY(COMP_CPU("UL5")), 425 DAILINK_COMP_ARRAY(COMP_DUMMY()), 426 DAILINK_COMP_ARRAY(COMP_EMPTY())); 427 428 SND_SOC_DAILINK_DEFS(capture6, 429 DAILINK_COMP_ARRAY(COMP_CPU("UL6")), 430 DAILINK_COMP_ARRAY(COMP_DUMMY()), 431 DAILINK_COMP_ARRAY(COMP_EMPTY())); 432 433 SND_SOC_DAILINK_DEFS(capture7, 434 DAILINK_COMP_ARRAY(COMP_CPU("UL7")), 435 DAILINK_COMP_ARRAY(COMP_DUMMY()), 436 DAILINK_COMP_ARRAY(COMP_EMPTY())); 437 438 /* hostless */ 439 SND_SOC_DAILINK_DEFS(hostless_lpbk, 440 DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")), 441 DAILINK_COMP_ARRAY(COMP_DUMMY()), 442 DAILINK_COMP_ARRAY(COMP_EMPTY())); 443 SND_SOC_DAILINK_DEFS(hostless_fm, 444 DAILINK_COMP_ARRAY(COMP_CPU("Hostless FM DAI")), 445 DAILINK_COMP_ARRAY(COMP_DUMMY()), 446 DAILINK_COMP_ARRAY(COMP_EMPTY())); 447 SND_SOC_DAILINK_DEFS(hostless_src1, 448 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_1_DAI")), 449 DAILINK_COMP_ARRAY(COMP_DUMMY()), 450 DAILINK_COMP_ARRAY(COMP_EMPTY())); 451 SND_SOC_DAILINK_DEFS(hostless_src_bargein, 452 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_Bargein_DAI")), 453 DAILINK_COMP_ARRAY(COMP_DUMMY()), 454 DAILINK_COMP_ARRAY(COMP_EMPTY())); 455 456 /* BE */ 457 SND_SOC_DAILINK_DEFS(adda, 458 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), 459 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", 460 "mt6358-snd-codec-aif1"), 461 COMP_CODEC("dmic-codec", 462 "dmic-hifi")), 463 DAILINK_COMP_ARRAY(COMP_EMPTY())); 464 SND_SOC_DAILINK_DEFS(i2s0, 465 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")), 466 DAILINK_COMP_ARRAY(COMP_EMPTY()), 467 DAILINK_COMP_ARRAY(COMP_EMPTY())); 468 SND_SOC_DAILINK_DEFS(i2s1, 469 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")), 470 DAILINK_COMP_ARRAY(COMP_EMPTY()), 471 DAILINK_COMP_ARRAY(COMP_EMPTY())); 472 SND_SOC_DAILINK_DEFS(i2s2, 473 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")), 474 DAILINK_COMP_ARRAY(COMP_DUMMY()), 475 DAILINK_COMP_ARRAY(COMP_EMPTY())); 476 SND_SOC_DAILINK_DEFS(i2s3, 477 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 478 DAILINK_COMP_ARRAY(COMP_EMPTY()), 479 DAILINK_COMP_ARRAY(COMP_EMPTY())); 480 SND_SOC_DAILINK_DEFS(hw_gain1, 481 DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 1")), 482 DAILINK_COMP_ARRAY(COMP_DUMMY()), 483 DAILINK_COMP_ARRAY(COMP_EMPTY())); 484 SND_SOC_DAILINK_DEFS(hw_gain2, 485 DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 2")), 486 DAILINK_COMP_ARRAY(COMP_DUMMY()), 487 DAILINK_COMP_ARRAY(COMP_EMPTY())); 488 SND_SOC_DAILINK_DEFS(hw_src1, 489 DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_1")), 490 DAILINK_COMP_ARRAY(COMP_DUMMY()), 491 DAILINK_COMP_ARRAY(COMP_EMPTY())); 492 SND_SOC_DAILINK_DEFS(hw_src2, 493 DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_2")), 494 DAILINK_COMP_ARRAY(COMP_DUMMY()), 495 DAILINK_COMP_ARRAY(COMP_EMPTY())); 496 SND_SOC_DAILINK_DEFS(connsys_i2s, 497 DAILINK_COMP_ARRAY(COMP_CPU("CONNSYS_I2S")), 498 DAILINK_COMP_ARRAY(COMP_DUMMY()), 499 DAILINK_COMP_ARRAY(COMP_EMPTY())); 500 SND_SOC_DAILINK_DEFS(pcm1, 501 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")), 502 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")), 503 DAILINK_COMP_ARRAY(COMP_EMPTY())); 504 SND_SOC_DAILINK_DEFS(tdm_in, 505 DAILINK_COMP_ARRAY(COMP_CPU("TDM IN")), 506 DAILINK_COMP_ARRAY(COMP_DUMMY()), 507 DAILINK_COMP_ARRAY(COMP_EMPTY())); 508 509 /* hostless */ 510 SND_SOC_DAILINK_DEFS(hostless_ul1, 511 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL1 DAI")), 512 DAILINK_COMP_ARRAY(COMP_DUMMY()), 513 DAILINK_COMP_ARRAY(COMP_EMPTY())); 514 SND_SOC_DAILINK_DEFS(hostless_ul2, 515 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL2 DAI")), 516 DAILINK_COMP_ARRAY(COMP_DUMMY()), 517 DAILINK_COMP_ARRAY(COMP_EMPTY())); 518 SND_SOC_DAILINK_DEFS(hostless_ul3, 519 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL3 DAI")), 520 DAILINK_COMP_ARRAY(COMP_DUMMY()), 521 DAILINK_COMP_ARRAY(COMP_EMPTY())); 522 SND_SOC_DAILINK_DEFS(hostless_ul5, 523 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL5 DAI")), 524 DAILINK_COMP_ARRAY(COMP_DUMMY()), 525 DAILINK_COMP_ARRAY(COMP_EMPTY())); 526 SND_SOC_DAILINK_DEFS(hostless_ul6, 527 DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL6 DAI")), 528 DAILINK_COMP_ARRAY(COMP_DUMMY()), 529 DAILINK_COMP_ARRAY(COMP_EMPTY())); 530 SND_SOC_DAILINK_DEFS(hostless_hw_gain_aaudio, 531 DAILINK_COMP_ARRAY(COMP_CPU("Hostless HW Gain AAudio DAI")), 532 DAILINK_COMP_ARRAY(COMP_DUMMY()), 533 DAILINK_COMP_ARRAY(COMP_EMPTY())); 534 SND_SOC_DAILINK_DEFS(hostless_src_aaudio, 535 DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")), 536 DAILINK_COMP_ARRAY(COMP_DUMMY()), 537 DAILINK_COMP_ARRAY(COMP_EMPTY())); 538 SND_SOC_DAILINK_DEFS(AFE_SOF_DL1, 539 DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")), 540 DAILINK_COMP_ARRAY(COMP_DUMMY()), 541 DAILINK_COMP_ARRAY(COMP_EMPTY())); 542 543 SND_SOC_DAILINK_DEFS(AFE_SOF_DL2, 544 DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")), 545 DAILINK_COMP_ARRAY(COMP_DUMMY()), 546 DAILINK_COMP_ARRAY(COMP_EMPTY())); 547 548 SND_SOC_DAILINK_DEFS(AFE_SOF_UL1, 549 DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")), 550 DAILINK_COMP_ARRAY(COMP_DUMMY()), 551 DAILINK_COMP_ARRAY(COMP_EMPTY())); 552 553 SND_SOC_DAILINK_DEFS(AFE_SOF_UL2, 554 DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")), 555 DAILINK_COMP_ARRAY(COMP_DUMMY()), 556 DAILINK_COMP_ARRAY(COMP_EMPTY())); 557 558 static const struct sof_conn_stream g_sof_conn_streams[] = { 559 { "I2S1", "AFE_SOF_DL1", SOF_DMA_DL1, SNDRV_PCM_STREAM_PLAYBACK}, 560 { "I2S3", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK}, 561 { "Primary Codec", "AFE_SOF_UL1", SOF_DMA_UL1, SNDRV_PCM_STREAM_CAPTURE}, 562 { "I2S0", "AFE_SOF_UL2", SOF_DMA_UL2, SNDRV_PCM_STREAM_CAPTURE}, 563 }; 564 565 static struct snd_soc_dai_link mt8186_mt6366_da7219_max98357_dai_links[] = { 566 /* Front End DAI links */ 567 { 568 .name = "Playback_1", 569 .stream_name = "Playback_1", 570 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 571 SND_SOC_DPCM_TRIGGER_PRE}, 572 .dynamic = 1, 573 .dpcm_playback = 1, 574 .dpcm_merged_format = 1, 575 .dpcm_merged_chan = 1, 576 .dpcm_merged_rate = 1, 577 .ops = &mt8186_mt6366_da7219_max98357_playback_ops, 578 SND_SOC_DAILINK_REG(playback1), 579 }, 580 { 581 .name = "Playback_12", 582 .stream_name = "Playback_12", 583 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 584 SND_SOC_DPCM_TRIGGER_PRE}, 585 .dynamic = 1, 586 .dpcm_playback = 1, 587 SND_SOC_DAILINK_REG(playback12), 588 }, 589 { 590 .name = "Playback_2", 591 .stream_name = "Playback_2", 592 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 593 SND_SOC_DPCM_TRIGGER_PRE}, 594 .dynamic = 1, 595 .dpcm_playback = 1, 596 .dpcm_merged_format = 1, 597 .dpcm_merged_chan = 1, 598 .dpcm_merged_rate = 1, 599 SND_SOC_DAILINK_REG(playback2), 600 }, 601 { 602 .name = "Playback_3", 603 .stream_name = "Playback_3", 604 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 605 SND_SOC_DPCM_TRIGGER_PRE}, 606 .dynamic = 1, 607 .dpcm_playback = 1, 608 .dpcm_merged_format = 1, 609 .dpcm_merged_chan = 1, 610 .dpcm_merged_rate = 1, 611 .ops = &mt8186_mt6366_da7219_max98357_playback_ops, 612 SND_SOC_DAILINK_REG(playback3), 613 }, 614 { 615 .name = "Playback_4", 616 .stream_name = "Playback_4", 617 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 618 SND_SOC_DPCM_TRIGGER_PRE}, 619 .dynamic = 1, 620 .dpcm_playback = 1, 621 SND_SOC_DAILINK_REG(playback4), 622 }, 623 { 624 .name = "Playback_5", 625 .stream_name = "Playback_5", 626 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 627 SND_SOC_DPCM_TRIGGER_PRE}, 628 .dynamic = 1, 629 .dpcm_playback = 1, 630 SND_SOC_DAILINK_REG(playback5), 631 }, 632 { 633 .name = "Playback_6", 634 .stream_name = "Playback_6", 635 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 636 SND_SOC_DPCM_TRIGGER_PRE}, 637 .dynamic = 1, 638 .dpcm_playback = 1, 639 SND_SOC_DAILINK_REG(playback6), 640 }, 641 { 642 .name = "Playback_7", 643 .stream_name = "Playback_7", 644 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 645 SND_SOC_DPCM_TRIGGER_PRE}, 646 .dynamic = 1, 647 .dpcm_playback = 1, 648 SND_SOC_DAILINK_REG(playback7), 649 }, 650 { 651 .name = "Playback_8", 652 .stream_name = "Playback_8", 653 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 654 SND_SOC_DPCM_TRIGGER_PRE}, 655 .dynamic = 1, 656 .dpcm_playback = 1, 657 SND_SOC_DAILINK_REG(playback8), 658 }, 659 { 660 .name = "Capture_1", 661 .stream_name = "Capture_1", 662 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 663 SND_SOC_DPCM_TRIGGER_PRE}, 664 .dynamic = 1, 665 .dpcm_capture = 1, 666 SND_SOC_DAILINK_REG(capture1), 667 }, 668 { 669 .name = "Capture_2", 670 .stream_name = "Capture_2", 671 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 672 SND_SOC_DPCM_TRIGGER_PRE}, 673 .dynamic = 1, 674 .dpcm_capture = 1, 675 .dpcm_merged_format = 1, 676 .dpcm_merged_chan = 1, 677 .dpcm_merged_rate = 1, 678 .ops = &mt8186_mt6366_da7219_max98357_capture_ops, 679 SND_SOC_DAILINK_REG(capture2), 680 }, 681 { 682 .name = "Capture_3", 683 .stream_name = "Capture_3", 684 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 685 SND_SOC_DPCM_TRIGGER_PRE}, 686 .dynamic = 1, 687 .dpcm_capture = 1, 688 SND_SOC_DAILINK_REG(capture3), 689 }, 690 { 691 .name = "Capture_4", 692 .stream_name = "Capture_4", 693 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 694 SND_SOC_DPCM_TRIGGER_PRE}, 695 .dynamic = 1, 696 .dpcm_capture = 1, 697 .dpcm_merged_format = 1, 698 .dpcm_merged_chan = 1, 699 .dpcm_merged_rate = 1, 700 .ops = &mt8186_mt6366_da7219_max98357_capture_ops, 701 SND_SOC_DAILINK_REG(capture4), 702 }, 703 { 704 .name = "Capture_5", 705 .stream_name = "Capture_5", 706 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 707 SND_SOC_DPCM_TRIGGER_PRE}, 708 .dynamic = 1, 709 .dpcm_capture = 1, 710 SND_SOC_DAILINK_REG(capture5), 711 }, 712 { 713 .name = "Capture_6", 714 .stream_name = "Capture_6", 715 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 716 SND_SOC_DPCM_TRIGGER_PRE}, 717 .dynamic = 1, 718 .dpcm_capture = 1, 719 .dpcm_merged_format = 1, 720 .dpcm_merged_chan = 1, 721 .dpcm_merged_rate = 1, 722 SND_SOC_DAILINK_REG(capture6), 723 }, 724 { 725 .name = "Capture_7", 726 .stream_name = "Capture_7", 727 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 728 SND_SOC_DPCM_TRIGGER_PRE}, 729 .dynamic = 1, 730 .dpcm_capture = 1, 731 SND_SOC_DAILINK_REG(capture7), 732 }, 733 { 734 .name = "Hostless_LPBK", 735 .stream_name = "Hostless_LPBK", 736 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 737 SND_SOC_DPCM_TRIGGER_PRE}, 738 .dynamic = 1, 739 .dpcm_playback = 1, 740 .dpcm_capture = 1, 741 .ignore_suspend = 1, 742 SND_SOC_DAILINK_REG(hostless_lpbk), 743 }, 744 { 745 .name = "Hostless_FM", 746 .stream_name = "Hostless_FM", 747 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 748 SND_SOC_DPCM_TRIGGER_PRE}, 749 .dynamic = 1, 750 .dpcm_playback = 1, 751 .dpcm_capture = 1, 752 .ignore_suspend = 1, 753 SND_SOC_DAILINK_REG(hostless_fm), 754 }, 755 { 756 .name = "Hostless_SRC_1", 757 .stream_name = "Hostless_SRC_1", 758 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 759 SND_SOC_DPCM_TRIGGER_PRE}, 760 .dynamic = 1, 761 .dpcm_playback = 1, 762 .dpcm_capture = 1, 763 .ignore_suspend = 1, 764 SND_SOC_DAILINK_REG(hostless_src1), 765 }, 766 { 767 .name = "Hostless_SRC_Bargein", 768 .stream_name = "Hostless_SRC_Bargein", 769 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 770 SND_SOC_DPCM_TRIGGER_PRE}, 771 .dynamic = 1, 772 .dpcm_playback = 1, 773 .dpcm_capture = 1, 774 .ignore_suspend = 1, 775 SND_SOC_DAILINK_REG(hostless_src_bargein), 776 }, 777 { 778 .name = "Hostless_HW_Gain_AAudio", 779 .stream_name = "Hostless_HW_Gain_AAudio", 780 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 781 SND_SOC_DPCM_TRIGGER_PRE}, 782 .dynamic = 1, 783 .dpcm_capture = 1, 784 .ignore_suspend = 1, 785 SND_SOC_DAILINK_REG(hostless_hw_gain_aaudio), 786 }, 787 { 788 .name = "Hostless_SRC_AAudio", 789 .stream_name = "Hostless_SRC_AAudio", 790 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 791 SND_SOC_DPCM_TRIGGER_PRE}, 792 .dynamic = 1, 793 .dpcm_playback = 1, 794 .dpcm_capture = 1, 795 .ignore_suspend = 1, 796 SND_SOC_DAILINK_REG(hostless_src_aaudio), 797 }, 798 /* Back End DAI links */ 799 { 800 .name = "Primary Codec", 801 .no_pcm = 1, 802 .dpcm_playback = 1, 803 .dpcm_capture = 1, 804 .ignore_suspend = 1, 805 .init = mt8186_mt6366_init, 806 SND_SOC_DAILINK_REG(adda), 807 }, 808 { 809 .name = "I2S3", 810 .no_pcm = 1, 811 .dai_fmt = SND_SOC_DAIFMT_I2S | 812 SND_SOC_DAIFMT_IB_IF | 813 SND_SOC_DAIFMT_CBM_CFM, 814 .dpcm_playback = 1, 815 .ignore_suspend = 1, 816 .init = mt8186_mt6366_da7219_max98357_hdmi_init, 817 .be_hw_params_fixup = mt8186_anx7625_i2s_hw_params_fixup, 818 SND_SOC_DAILINK_REG(i2s3), 819 }, 820 { 821 .name = "I2S0", 822 .no_pcm = 1, 823 .dpcm_capture = 1, 824 .ignore_suspend = 1, 825 .be_hw_params_fixup = mt8186_i2s_hw_params_fixup, 826 .ops = &mt8186_da7219_i2s_ops, 827 SND_SOC_DAILINK_REG(i2s0), 828 }, 829 { 830 .name = "I2S1", 831 .no_pcm = 1, 832 .dpcm_playback = 1, 833 .ignore_suspend = 1, 834 .be_hw_params_fixup = mt8186_i2s_hw_params_fixup, 835 .init = mt8186_da7219_init, 836 .ops = &mt8186_da7219_i2s_ops, 837 SND_SOC_DAILINK_REG(i2s1), 838 }, 839 { 840 .name = "I2S2", 841 .no_pcm = 1, 842 .dpcm_capture = 1, 843 .ignore_suspend = 1, 844 .be_hw_params_fixup = mt8186_i2s_hw_params_fixup, 845 SND_SOC_DAILINK_REG(i2s2), 846 }, 847 { 848 .name = "HW Gain 1", 849 .no_pcm = 1, 850 .dpcm_playback = 1, 851 .dpcm_capture = 1, 852 .ignore_suspend = 1, 853 SND_SOC_DAILINK_REG(hw_gain1), 854 }, 855 { 856 .name = "HW Gain 2", 857 .no_pcm = 1, 858 .dpcm_playback = 1, 859 .dpcm_capture = 1, 860 .ignore_suspend = 1, 861 SND_SOC_DAILINK_REG(hw_gain2), 862 }, 863 { 864 .name = "HW_SRC_1", 865 .no_pcm = 1, 866 .dpcm_playback = 1, 867 .dpcm_capture = 1, 868 .ignore_suspend = 1, 869 SND_SOC_DAILINK_REG(hw_src1), 870 }, 871 { 872 .name = "HW_SRC_2", 873 .no_pcm = 1, 874 .dpcm_playback = 1, 875 .dpcm_capture = 1, 876 .ignore_suspend = 1, 877 SND_SOC_DAILINK_REG(hw_src2), 878 }, 879 { 880 .name = "CONNSYS_I2S", 881 .no_pcm = 1, 882 .dpcm_capture = 1, 883 .ignore_suspend = 1, 884 SND_SOC_DAILINK_REG(connsys_i2s), 885 }, 886 { 887 .name = "PCM 1", 888 .dai_fmt = SND_SOC_DAIFMT_I2S | 889 SND_SOC_DAIFMT_NB_IF, 890 .no_pcm = 1, 891 .dpcm_playback = 1, 892 .dpcm_capture = 1, 893 .ignore_suspend = 1, 894 SND_SOC_DAILINK_REG(pcm1), 895 }, 896 { 897 .name = "TDM IN", 898 .no_pcm = 1, 899 .dpcm_capture = 1, 900 .ignore_suspend = 1, 901 SND_SOC_DAILINK_REG(tdm_in), 902 }, 903 /* dummy BE for ul memif to record from dl memif */ 904 { 905 .name = "Hostless_UL1", 906 .no_pcm = 1, 907 .dpcm_capture = 1, 908 .ignore_suspend = 1, 909 SND_SOC_DAILINK_REG(hostless_ul1), 910 }, 911 { 912 .name = "Hostless_UL2", 913 .no_pcm = 1, 914 .dpcm_capture = 1, 915 .ignore_suspend = 1, 916 SND_SOC_DAILINK_REG(hostless_ul2), 917 }, 918 { 919 .name = "Hostless_UL3", 920 .no_pcm = 1, 921 .dpcm_capture = 1, 922 .ignore_suspend = 1, 923 SND_SOC_DAILINK_REG(hostless_ul3), 924 }, 925 { 926 .name = "Hostless_UL5", 927 .no_pcm = 1, 928 .dpcm_capture = 1, 929 .ignore_suspend = 1, 930 SND_SOC_DAILINK_REG(hostless_ul5), 931 }, 932 { 933 .name = "Hostless_UL6", 934 .no_pcm = 1, 935 .dpcm_capture = 1, 936 .ignore_suspend = 1, 937 SND_SOC_DAILINK_REG(hostless_ul6), 938 }, 939 /* SOF BE */ 940 { 941 .name = "AFE_SOF_DL1", 942 .no_pcm = 1, 943 .dpcm_playback = 1, 944 SND_SOC_DAILINK_REG(AFE_SOF_DL1), 945 }, 946 { 947 .name = "AFE_SOF_DL2", 948 .no_pcm = 1, 949 .dpcm_playback = 1, 950 SND_SOC_DAILINK_REG(AFE_SOF_DL2), 951 }, 952 { 953 .name = "AFE_SOF_UL1", 954 .no_pcm = 1, 955 .dpcm_capture = 1, 956 SND_SOC_DAILINK_REG(AFE_SOF_UL1), 957 }, 958 { 959 .name = "AFE_SOF_UL2", 960 .no_pcm = 1, 961 .dpcm_capture = 1, 962 SND_SOC_DAILINK_REG(AFE_SOF_UL2), 963 }, 964 }; 965 966 static const struct snd_soc_dapm_widget 967 mt8186_mt6366_da7219_max98357_widgets[] = { 968 SND_SOC_DAPM_SPK("Speakers", NULL), 969 SND_SOC_DAPM_HP("Headphones", NULL), 970 SND_SOC_DAPM_MIC("Headset Mic", NULL), 971 SND_SOC_DAPM_LINE("Line Out", NULL), 972 SND_SOC_DAPM_OUTPUT("HDMI1"), 973 SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0), 974 SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), 975 SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0), 976 SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0), 977 }; 978 979 static const struct snd_soc_dapm_route 980 mt8186_mt6366_da7219_max98357_routes[] = { 981 /* SPK */ 982 { "Speakers", NULL, "Speaker"}, 983 /* Headset */ 984 { "Headphones", NULL, "HPL" }, 985 { "Headphones", NULL, "HPR" }, 986 { "MIC", NULL, "Headset Mic" }, 987 /* HDMI */ 988 { "HDMI1", NULL, "TX"}, 989 /* SOF Uplink */ 990 {SOF_DMA_UL1, NULL, "UL1_CH1"}, 991 {SOF_DMA_UL1, NULL, "UL1_CH2"}, 992 {SOF_DMA_UL2, NULL, "UL2_CH1"}, 993 {SOF_DMA_UL2, NULL, "UL2_CH2"}, 994 /* SOF Downlink */ 995 {"DSP_DL1_VIRT", NULL, SOF_DMA_DL1}, 996 {"DSP_DL2_VIRT", NULL, SOF_DMA_DL2}, 997 }; 998 999 static const struct snd_kcontrol_new 1000 mt8186_mt6366_da7219_max98357_controls[] = { 1001 SOC_DAPM_PIN_SWITCH("Speakers"), 1002 SOC_DAPM_PIN_SWITCH("Headphones"), 1003 SOC_DAPM_PIN_SWITCH("Headset Mic"), 1004 SOC_DAPM_PIN_SWITCH("Line Out"), 1005 SOC_DAPM_PIN_SWITCH("HDMI1"), 1006 }; 1007 1008 static struct snd_soc_card mt8186_mt6366_da7219_max98357_soc_card = { 1009 .name = "mt8186_da7219_max98357", 1010 .owner = THIS_MODULE, 1011 .dai_link = mt8186_mt6366_da7219_max98357_dai_links, 1012 .num_links = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links), 1013 .controls = mt8186_mt6366_da7219_max98357_controls, 1014 .num_controls = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_controls), 1015 .dapm_widgets = mt8186_mt6366_da7219_max98357_widgets, 1016 .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_widgets), 1017 .dapm_routes = mt8186_mt6366_da7219_max98357_routes, 1018 .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_routes), 1019 .codec_conf = mt8186_mt6366_da7219_max98357_codec_conf, 1020 .num_configs = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_codec_conf), 1021 }; 1022 1023 static int mt8186_mt6366_da7219_max98357_dev_probe(struct platform_device *pdev) 1024 { 1025 struct snd_soc_card *card; 1026 struct snd_soc_dai_link *dai_link; 1027 struct mtk_soc_card_data *soc_card_data; 1028 struct mt8186_mt6366_da7219_max98357_priv *mach_priv; 1029 struct device_node *platform_node, *headset_codec, *playback_codec, *adsp_node; 1030 int sof_on = 0; 1031 int ret, i; 1032 1033 card = (struct snd_soc_card *)device_get_match_data(&pdev->dev); 1034 if (!card) 1035 return -EINVAL; 1036 card->dev = &pdev->dev; 1037 1038 soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*soc_card_data), GFP_KERNEL); 1039 if (!soc_card_data) 1040 return -ENOMEM; 1041 mach_priv = devm_kzalloc(&pdev->dev, sizeof(*mach_priv), GFP_KERNEL); 1042 if (!mach_priv) 1043 return -ENOMEM; 1044 1045 soc_card_data->mach_priv = mach_priv; 1046 1047 adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0); 1048 if (adsp_node) { 1049 struct mtk_sof_priv *sof_priv; 1050 1051 sof_priv = devm_kzalloc(&pdev->dev, sizeof(*sof_priv), GFP_KERNEL); 1052 if (!sof_priv) { 1053 ret = -ENOMEM; 1054 goto err_adsp_node; 1055 } 1056 sof_priv->conn_streams = g_sof_conn_streams; 1057 sof_priv->num_streams = ARRAY_SIZE(g_sof_conn_streams); 1058 sof_priv->sof_dai_link_fixup = mt8186_sof_dai_link_fixup; 1059 soc_card_data->sof_priv = sof_priv; 1060 card->probe = mtk_sof_card_probe; 1061 card->late_probe = mtk_sof_card_late_probe; 1062 if (!card->topology_shortname_created) { 1063 snprintf(card->topology_shortname, 32, "sof-%s", card->name); 1064 card->topology_shortname_created = true; 1065 } 1066 card->name = card->topology_shortname; 1067 sof_on = 1; 1068 } else { 1069 dev_dbg(&pdev->dev, "Probe without adsp\n"); 1070 } 1071 1072 if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) { 1073 ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node, 1074 "mediatek,dai-link", 1075 mt8186_mt6366_da7219_max98357_dai_links, 1076 ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links)); 1077 if (ret) { 1078 dev_dbg(&pdev->dev, "Parse dai-link fail\n"); 1079 goto err_adsp_node; 1080 } 1081 } else { 1082 if (!sof_on) 1083 card->num_links = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links) 1084 - ARRAY_SIZE(g_sof_conn_streams); 1085 } 1086 1087 platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); 1088 if (!platform_node) { 1089 ret = -EINVAL; 1090 dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n"); 1091 goto err_platform_node; 1092 } 1093 1094 playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs"); 1095 if (!playback_codec) { 1096 ret = -EINVAL; 1097 dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n"); 1098 goto err_playback_codec; 1099 } 1100 1101 headset_codec = of_get_child_by_name(pdev->dev.of_node, "headset-codec"); 1102 if (!headset_codec) { 1103 ret = -EINVAL; 1104 dev_err_probe(&pdev->dev, ret, "Property 'headset-codec' missing or invalid\n"); 1105 goto err_headset_codec; 1106 } 1107 1108 for_each_card_prelinks(card, i, dai_link) { 1109 ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3"); 1110 if (ret) { 1111 dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n", 1112 dai_link->name); 1113 goto err_probe; 1114 } 1115 1116 ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S0"); 1117 if (ret) { 1118 dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n", 1119 dai_link->name); 1120 goto err_probe; 1121 } 1122 1123 ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S1"); 1124 if (ret) { 1125 dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n", 1126 dai_link->name); 1127 goto err_probe; 1128 } 1129 1130 if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && sof_on) 1131 dai_link->platforms->of_node = adsp_node; 1132 1133 if (!dai_link->platforms->name && !dai_link->platforms->of_node) 1134 dai_link->platforms->of_node = platform_node; 1135 } 1136 1137 snd_soc_card_set_drvdata(card, soc_card_data); 1138 1139 ret = mt8186_afe_gpio_init(&pdev->dev); 1140 if (ret) { 1141 dev_err_probe(&pdev->dev, ret, "%s init gpio error\n", __func__); 1142 goto err_probe; 1143 } 1144 1145 ret = devm_snd_soc_register_card(&pdev->dev, card); 1146 if (ret) 1147 dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__); 1148 1149 err_probe: 1150 of_node_put(headset_codec); 1151 err_headset_codec: 1152 of_node_put(playback_codec); 1153 err_playback_codec: 1154 of_node_put(platform_node); 1155 err_platform_node: 1156 err_adsp_node: 1157 of_node_put(adsp_node); 1158 1159 return ret; 1160 } 1161 1162 #if IS_ENABLED(CONFIG_OF) 1163 static const struct of_device_id mt8186_mt6366_da7219_max98357_dt_match[] = { 1164 { .compatible = "mediatek,mt8186-mt6366-da7219-max98357-sound", 1165 .data = &mt8186_mt6366_da7219_max98357_soc_card, 1166 }, 1167 {} 1168 }; 1169 MODULE_DEVICE_TABLE(of, mt8186_mt6366_da7219_max98357_dt_match); 1170 #endif 1171 1172 static struct platform_driver mt8186_mt6366_da7219_max98357_driver = { 1173 .driver = { 1174 .name = "mt8186_mt6366_da7219_max98357", 1175 #if IS_ENABLED(CONFIG_OF) 1176 .of_match_table = mt8186_mt6366_da7219_max98357_dt_match, 1177 #endif 1178 .pm = &snd_soc_pm_ops, 1179 }, 1180 .probe = mt8186_mt6366_da7219_max98357_dev_probe, 1181 }; 1182 1183 module_platform_driver(mt8186_mt6366_da7219_max98357_driver); 1184 1185 /* Module information */ 1186 MODULE_DESCRIPTION("MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver"); 1187 MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>"); 1188 MODULE_LICENSE("GPL v2"); 1189 MODULE_ALIAS("mt8186_mt6366_da7219_max98357 soc card"); 1190