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