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