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