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