1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * mt8188-mt6359.c -- MT8188-MT6359 ALSA SoC machine driver 4 * 5 * Copyright (c) 2022 MediaTek Inc. 6 * Author: Trevor Wu <trevor.wu@mediatek.com> 7 */ 8 9 #include <linux/bitfield.h> 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/soc.h> 17 #include "mt8188-afe-common.h" 18 #include "../../codecs/nau8825.h" 19 #include "../../codecs/mt6359.h" 20 #include "../common/mtk-afe-platform-driver.h" 21 #include "../common/mtk-soundcard-driver.h" 22 23 #define CKSYS_AUD_TOP_CFG 0x032c 24 #define RG_TEST_ON BIT(0) 25 #define RG_TEST_TYPE BIT(2) 26 #define CKSYS_AUD_TOP_MON 0x0330 27 #define TEST_MISO_COUNT_1 GENMASK(3, 0) 28 #define TEST_MISO_COUNT_2 GENMASK(7, 4) 29 #define TEST_MISO_DONE_1 BIT(28) 30 #define TEST_MISO_DONE_2 BIT(29) 31 32 #define NAU8825_HS_PRESENT BIT(0) 33 34 /* 35 * Maxim MAX98390 36 */ 37 #define MAX98390_CODEC_DAI "max98390-aif1" 38 #define MAX98390_DEV0_NAME "max98390.0-0038" /* rear right */ 39 #define MAX98390_DEV1_NAME "max98390.0-0039" /* rear left */ 40 #define MAX98390_DEV2_NAME "max98390.0-003a" /* front right */ 41 #define MAX98390_DEV3_NAME "max98390.0-003b" /* front left */ 42 43 /* 44 * Nau88l25 45 */ 46 #define NAU8825_CODEC_DAI "nau8825-hifi" 47 48 /* FE */ 49 SND_SOC_DAILINK_DEFS(playback2, 50 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 51 DAILINK_COMP_ARRAY(COMP_DUMMY()), 52 DAILINK_COMP_ARRAY(COMP_EMPTY())); 53 54 SND_SOC_DAILINK_DEFS(playback3, 55 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 56 DAILINK_COMP_ARRAY(COMP_DUMMY()), 57 DAILINK_COMP_ARRAY(COMP_EMPTY())); 58 59 SND_SOC_DAILINK_DEFS(playback6, 60 DAILINK_COMP_ARRAY(COMP_CPU("DL6")), 61 DAILINK_COMP_ARRAY(COMP_DUMMY()), 62 DAILINK_COMP_ARRAY(COMP_EMPTY())); 63 64 SND_SOC_DAILINK_DEFS(playback7, 65 DAILINK_COMP_ARRAY(COMP_CPU("DL7")), 66 DAILINK_COMP_ARRAY(COMP_DUMMY()), 67 DAILINK_COMP_ARRAY(COMP_EMPTY())); 68 69 SND_SOC_DAILINK_DEFS(playback8, 70 DAILINK_COMP_ARRAY(COMP_CPU("DL8")), 71 DAILINK_COMP_ARRAY(COMP_DUMMY()), 72 DAILINK_COMP_ARRAY(COMP_EMPTY())); 73 74 SND_SOC_DAILINK_DEFS(playback10, 75 DAILINK_COMP_ARRAY(COMP_CPU("DL10")), 76 DAILINK_COMP_ARRAY(COMP_DUMMY()), 77 DAILINK_COMP_ARRAY(COMP_EMPTY())); 78 79 SND_SOC_DAILINK_DEFS(playback11, 80 DAILINK_COMP_ARRAY(COMP_CPU("DL11")), 81 DAILINK_COMP_ARRAY(COMP_DUMMY()), 82 DAILINK_COMP_ARRAY(COMP_EMPTY())); 83 84 SND_SOC_DAILINK_DEFS(capture1, 85 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 86 DAILINK_COMP_ARRAY(COMP_DUMMY()), 87 DAILINK_COMP_ARRAY(COMP_EMPTY())); 88 89 SND_SOC_DAILINK_DEFS(capture2, 90 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 91 DAILINK_COMP_ARRAY(COMP_DUMMY()), 92 DAILINK_COMP_ARRAY(COMP_EMPTY())); 93 94 SND_SOC_DAILINK_DEFS(capture3, 95 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 96 DAILINK_COMP_ARRAY(COMP_DUMMY()), 97 DAILINK_COMP_ARRAY(COMP_EMPTY())); 98 99 SND_SOC_DAILINK_DEFS(capture4, 100 DAILINK_COMP_ARRAY(COMP_CPU("UL4")), 101 DAILINK_COMP_ARRAY(COMP_DUMMY()), 102 DAILINK_COMP_ARRAY(COMP_EMPTY())); 103 104 SND_SOC_DAILINK_DEFS(capture5, 105 DAILINK_COMP_ARRAY(COMP_CPU("UL5")), 106 DAILINK_COMP_ARRAY(COMP_DUMMY()), 107 DAILINK_COMP_ARRAY(COMP_EMPTY())); 108 109 SND_SOC_DAILINK_DEFS(capture6, 110 DAILINK_COMP_ARRAY(COMP_CPU("UL6")), 111 DAILINK_COMP_ARRAY(COMP_DUMMY()), 112 DAILINK_COMP_ARRAY(COMP_EMPTY())); 113 114 SND_SOC_DAILINK_DEFS(capture8, 115 DAILINK_COMP_ARRAY(COMP_CPU("UL8")), 116 DAILINK_COMP_ARRAY(COMP_DUMMY()), 117 DAILINK_COMP_ARRAY(COMP_EMPTY())); 118 119 SND_SOC_DAILINK_DEFS(capture9, 120 DAILINK_COMP_ARRAY(COMP_CPU("UL9")), 121 DAILINK_COMP_ARRAY(COMP_DUMMY()), 122 DAILINK_COMP_ARRAY(COMP_EMPTY())); 123 124 SND_SOC_DAILINK_DEFS(capture10, 125 DAILINK_COMP_ARRAY(COMP_CPU("UL10")), 126 DAILINK_COMP_ARRAY(COMP_DUMMY()), 127 DAILINK_COMP_ARRAY(COMP_EMPTY())); 128 129 /* BE */ 130 SND_SOC_DAILINK_DEFS(dl_src, 131 DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")), 132 DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 133 "mt6359-snd-codec-aif1")), 134 DAILINK_COMP_ARRAY(COMP_EMPTY())); 135 136 SND_SOC_DAILINK_DEFS(dptx, 137 DAILINK_COMP_ARRAY(COMP_CPU("DPTX")), 138 DAILINK_COMP_ARRAY(COMP_DUMMY()), 139 DAILINK_COMP_ARRAY(COMP_EMPTY())); 140 141 SND_SOC_DAILINK_DEFS(etdm1_in, 142 DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")), 143 DAILINK_COMP_ARRAY(COMP_DUMMY()), 144 DAILINK_COMP_ARRAY(COMP_EMPTY())); 145 146 SND_SOC_DAILINK_DEFS(etdm2_in, 147 DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")), 148 DAILINK_COMP_ARRAY(COMP_DUMMY()), 149 DAILINK_COMP_ARRAY(COMP_EMPTY())); 150 151 SND_SOC_DAILINK_DEFS(etdm1_out, 152 DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")), 153 DAILINK_COMP_ARRAY(COMP_DUMMY()), 154 DAILINK_COMP_ARRAY(COMP_EMPTY())); 155 156 SND_SOC_DAILINK_DEFS(etdm2_out, 157 DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")), 158 DAILINK_COMP_ARRAY(COMP_DUMMY()), 159 DAILINK_COMP_ARRAY(COMP_EMPTY())); 160 161 SND_SOC_DAILINK_DEFS(etdm3_out, 162 DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")), 163 DAILINK_COMP_ARRAY(COMP_DUMMY()), 164 DAILINK_COMP_ARRAY(COMP_EMPTY())); 165 166 SND_SOC_DAILINK_DEFS(pcm1, 167 DAILINK_COMP_ARRAY(COMP_CPU("PCM1")), 168 DAILINK_COMP_ARRAY(COMP_DUMMY()), 169 DAILINK_COMP_ARRAY(COMP_EMPTY())); 170 171 SND_SOC_DAILINK_DEFS(ul_src, 172 DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC")), 173 DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", 174 "mt6359-snd-codec-aif1"), 175 COMP_CODEC("dmic-codec", 176 "dmic-hifi")), 177 DAILINK_COMP_ARRAY(COMP_EMPTY())); 178 179 struct mt8188_mt6359_priv { 180 struct snd_soc_jack dp_jack; 181 struct snd_soc_jack hdmi_jack; 182 struct snd_soc_jack headset_jack; 183 void *private_data; 184 }; 185 186 static struct snd_soc_jack_pin mt8188_hdmi_jack_pins[] = { 187 { 188 .pin = "HDMI", 189 .mask = SND_JACK_LINEOUT, 190 }, 191 }; 192 193 static struct snd_soc_jack_pin mt8188_dp_jack_pins[] = { 194 { 195 .pin = "DP", 196 .mask = SND_JACK_LINEOUT, 197 }, 198 }; 199 200 static struct snd_soc_jack_pin nau8825_jack_pins[] = { 201 { 202 .pin = "Headphone Jack", 203 .mask = SND_JACK_HEADPHONE, 204 }, 205 { 206 .pin = "Headset Mic", 207 .mask = SND_JACK_MICROPHONE, 208 }, 209 }; 210 211 struct mt8188_card_data { 212 const char *name; 213 unsigned long quirk; 214 }; 215 216 static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = { 217 SOC_DAPM_PIN_SWITCH("Ext Spk"), 218 }; 219 220 static const struct snd_soc_dapm_widget mt8188_dumb_spk_widgets[] = { 221 SND_SOC_DAPM_SPK("Ext Spk", NULL), 222 }; 223 224 static const struct snd_kcontrol_new mt8188_dual_spk_controls[] = { 225 SOC_DAPM_PIN_SWITCH("Left Spk"), 226 SOC_DAPM_PIN_SWITCH("Right Spk"), 227 }; 228 229 static const struct snd_soc_dapm_widget mt8188_dual_spk_widgets[] = { 230 SND_SOC_DAPM_SPK("Left Spk", NULL), 231 SND_SOC_DAPM_SPK("Right Spk", NULL), 232 }; 233 234 static const struct snd_kcontrol_new mt8188_rear_spk_controls[] = { 235 SOC_DAPM_PIN_SWITCH("Rear Left Spk"), 236 SOC_DAPM_PIN_SWITCH("Rear Right Spk"), 237 }; 238 239 static const struct snd_soc_dapm_widget mt8188_rear_spk_widgets[] = { 240 SND_SOC_DAPM_SPK("Rear Left Spk", NULL), 241 SND_SOC_DAPM_SPK("Rear Right Spk", NULL), 242 }; 243 244 static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = { 245 SND_SOC_DAPM_HP("Headphone", NULL), 246 SND_SOC_DAPM_MIC("Headset Mic", NULL), 247 SND_SOC_DAPM_SINK("HDMI"), 248 SND_SOC_DAPM_SINK("DP"), 249 250 /* dynamic pinctrl */ 251 SND_SOC_DAPM_PINCTRL("ETDM_SPK_PIN", "aud_etdm_spk_on", "aud_etdm_spk_off"), 252 SND_SOC_DAPM_PINCTRL("ETDM_HP_PIN", "aud_etdm_hp_on", "aud_etdm_hp_off"), 253 SND_SOC_DAPM_PINCTRL("MTKAIF_PIN", "aud_mtkaif_on", "aud_mtkaif_off"), 254 }; 255 256 static const struct snd_kcontrol_new mt8188_mt6359_controls[] = { 257 SOC_DAPM_PIN_SWITCH("Headphone"), 258 SOC_DAPM_PIN_SWITCH("Headset Mic"), 259 }; 260 261 static const struct snd_soc_dapm_widget mt8188_nau8825_widgets[] = { 262 SND_SOC_DAPM_HP("Headphone Jack", NULL), 263 }; 264 265 static const struct snd_kcontrol_new mt8188_nau8825_controls[] = { 266 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 267 }; 268 269 static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) 270 { 271 struct snd_soc_component *cmpnt_afe = 272 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 273 struct snd_soc_component *cmpnt_codec = 274 asoc_rtd_to_codec(rtd, 0)->component; 275 struct snd_soc_dapm_widget *pin_w = NULL, *w; 276 struct mtk_base_afe *afe; 277 struct mt8188_afe_private *afe_priv; 278 struct mtkaif_param *param; 279 int chosen_phase_1, chosen_phase_2; 280 int prev_cycle_1, prev_cycle_2; 281 u8 test_done_1, test_done_2; 282 int cycle_1, cycle_2; 283 int mtkaif_chosen_phase[MT8188_MTKAIF_MISO_NUM]; 284 int mtkaif_phase_cycle[MT8188_MTKAIF_MISO_NUM]; 285 int mtkaif_calibration_num_phase; 286 bool mtkaif_calibration_ok; 287 u32 monitor = 0; 288 int counter; 289 int phase; 290 int i; 291 292 if (!cmpnt_afe) 293 return -EINVAL; 294 295 afe = snd_soc_component_get_drvdata(cmpnt_afe); 296 afe_priv = afe->platform_priv; 297 param = &afe_priv->mtkaif_params; 298 299 dev_dbg(afe->dev, "%s(), start\n", __func__); 300 301 param->mtkaif_calibration_ok = false; 302 for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++) { 303 param->mtkaif_chosen_phase[i] = -1; 304 param->mtkaif_phase_cycle[i] = 0; 305 mtkaif_chosen_phase[i] = -1; 306 mtkaif_phase_cycle[i] = 0; 307 } 308 309 if (IS_ERR(afe_priv->topckgen)) { 310 dev_info(afe->dev, "%s() Cannot find topckgen controller\n", 311 __func__); 312 return 0; 313 } 314 315 for_each_card_widgets(rtd->card, w) { 316 if (!strcmp(w->name, "MTKAIF_PIN")) { 317 pin_w = w; 318 break; 319 } 320 } 321 322 if (pin_w) 323 dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_PRE_PMU); 324 else 325 dev_dbg(afe->dev, "%s(), no pinmux widget, please check if default on\n", __func__); 326 327 pm_runtime_get_sync(afe->dev); 328 mt6359_mtkaif_calibration_enable(cmpnt_codec); 329 330 /* set test type to synchronizer pulse */ 331 regmap_write(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_TYPE); 332 mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */ 333 mtkaif_calibration_ok = true; 334 335 for (phase = 0; 336 phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok; 337 phase++) { 338 mt6359_set_mtkaif_calibration_phase(cmpnt_codec, 339 phase, phase, phase); 340 341 regmap_set_bits(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_ON); 342 343 test_done_1 = 0; 344 test_done_2 = 0; 345 346 cycle_1 = -1; 347 cycle_2 = -1; 348 349 counter = 0; 350 while (!(test_done_1 & test_done_2)) { 351 regmap_read(afe_priv->topckgen, 352 CKSYS_AUD_TOP_MON, &monitor); 353 test_done_1 = FIELD_GET(TEST_MISO_DONE_1, monitor); 354 test_done_2 = FIELD_GET(TEST_MISO_DONE_2, monitor); 355 356 if (test_done_1 == 1) 357 cycle_1 = FIELD_GET(TEST_MISO_COUNT_1, monitor); 358 359 if (test_done_2 == 1) 360 cycle_2 = FIELD_GET(TEST_MISO_COUNT_2, monitor); 361 362 /* handle if never test done */ 363 if (++counter > 10000) { 364 dev_err(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, monitor 0x%x\n", 365 __func__, cycle_1, cycle_2, monitor); 366 mtkaif_calibration_ok = false; 367 break; 368 } 369 } 370 371 if (phase == 0) { 372 prev_cycle_1 = cycle_1; 373 prev_cycle_2 = cycle_2; 374 } 375 376 if (cycle_1 != prev_cycle_1 && 377 mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) { 378 mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = phase - 1; 379 mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] = prev_cycle_1; 380 } 381 382 if (cycle_2 != prev_cycle_2 && 383 mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) { 384 mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = phase - 1; 385 mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] = prev_cycle_2; 386 } 387 388 regmap_clear_bits(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_ON); 389 390 if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] >= 0 && 391 mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] >= 0) 392 break; 393 } 394 395 if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) { 396 mtkaif_calibration_ok = false; 397 chosen_phase_1 = 0; 398 } else { 399 chosen_phase_1 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0]; 400 } 401 402 if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) { 403 mtkaif_calibration_ok = false; 404 chosen_phase_2 = 0; 405 } else { 406 chosen_phase_2 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1]; 407 } 408 409 mt6359_set_mtkaif_calibration_phase(cmpnt_codec, 410 chosen_phase_1, 411 chosen_phase_2, 412 0); 413 414 mt6359_mtkaif_calibration_disable(cmpnt_codec); 415 pm_runtime_put(afe->dev); 416 417 param->mtkaif_calibration_ok = mtkaif_calibration_ok; 418 param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = chosen_phase_1; 419 param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = chosen_phase_2; 420 421 for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++) 422 param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i]; 423 424 if (pin_w) 425 dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_POST_PMD); 426 427 dev_dbg(afe->dev, "%s(), end, calibration ok %d\n", 428 __func__, param->mtkaif_calibration_ok); 429 430 return 0; 431 } 432 433 static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd) 434 { 435 struct snd_soc_component *cmpnt_codec = 436 asoc_rtd_to_codec(rtd, 0)->component; 437 438 /* set mtkaif protocol */ 439 mt6359_set_mtkaif_protocol(cmpnt_codec, 440 MT6359_MTKAIF_PROTOCOL_2_CLK_P2); 441 442 /* mtkaif calibration */ 443 mt8188_mt6359_mtkaif_calibration(rtd); 444 445 return 0; 446 } 447 448 enum { 449 DAI_LINK_DL2_FE, 450 DAI_LINK_DL3_FE, 451 DAI_LINK_DL6_FE, 452 DAI_LINK_DL7_FE, 453 DAI_LINK_DL8_FE, 454 DAI_LINK_DL10_FE, 455 DAI_LINK_DL11_FE, 456 DAI_LINK_UL1_FE, 457 DAI_LINK_UL2_FE, 458 DAI_LINK_UL3_FE, 459 DAI_LINK_UL4_FE, 460 DAI_LINK_UL5_FE, 461 DAI_LINK_UL6_FE, 462 DAI_LINK_UL8_FE, 463 DAI_LINK_UL9_FE, 464 DAI_LINK_UL10_FE, 465 DAI_LINK_DL_SRC_BE, 466 DAI_LINK_DPTX_BE, 467 DAI_LINK_ETDM1_IN_BE, 468 DAI_LINK_ETDM2_IN_BE, 469 DAI_LINK_ETDM1_OUT_BE, 470 DAI_LINK_ETDM2_OUT_BE, 471 DAI_LINK_ETDM3_OUT_BE, 472 DAI_LINK_PCM1_BE, 473 DAI_LINK_UL_SRC_BE, 474 }; 475 476 static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream, 477 struct snd_pcm_hw_params *params) 478 { 479 struct snd_soc_pcm_runtime *rtd = substream->private_data; 480 unsigned int rate = params_rate(params); 481 unsigned int mclk_fs_ratio = 256; 482 unsigned int mclk_fs = rate * mclk_fs_ratio; 483 struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 484 485 return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT); 486 } 487 488 static const struct snd_soc_ops mt8188_dptx_ops = { 489 .hw_params = mt8188_dptx_hw_params, 490 }; 491 492 static int mt8188_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 493 struct snd_pcm_hw_params *params) 494 { 495 /* fix BE i2s format to 32bit, clean param mask first */ 496 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 497 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 498 499 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); 500 501 return 0; 502 } 503 504 static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) 505 { 506 struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 507 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 508 int ret = 0; 509 510 ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack", 511 SND_JACK_LINEOUT, &priv->hdmi_jack, 512 mt8188_hdmi_jack_pins, 513 ARRAY_SIZE(mt8188_hdmi_jack_pins)); 514 if (ret) { 515 dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret); 516 return ret; 517 } 518 519 ret = snd_soc_component_set_jack(component, &priv->hdmi_jack, NULL); 520 if (ret) { 521 dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n", 522 __func__, component->name, ret); 523 return ret; 524 } 525 526 return 0; 527 } 528 529 static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) 530 { 531 struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); 532 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 533 int ret = 0; 534 535 ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT, 536 &priv->dp_jack, mt8188_dp_jack_pins, 537 ARRAY_SIZE(mt8188_dp_jack_pins)); 538 if (ret) { 539 dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret); 540 return ret; 541 } 542 543 ret = snd_soc_component_set_jack(component, &priv->dp_jack, NULL); 544 if (ret) { 545 dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n", 546 __func__, component->name, ret); 547 return ret; 548 } 549 550 return 0; 551 } 552 553 static int mt8188_dumb_amp_init(struct snd_soc_pcm_runtime *rtd) 554 { 555 struct snd_soc_card *card = rtd->card; 556 int ret = 0; 557 558 ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dumb_spk_widgets, 559 ARRAY_SIZE(mt8188_dumb_spk_widgets)); 560 if (ret) { 561 dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret); 562 return ret; 563 } 564 565 ret = snd_soc_add_card_controls(card, mt8188_dumb_spk_controls, 566 ARRAY_SIZE(mt8188_dumb_spk_controls)); 567 if (ret) { 568 dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret); 569 return ret; 570 } 571 572 return 0; 573 } 574 575 static int mt8188_max98390_hw_params(struct snd_pcm_substream *substream, 576 struct snd_pcm_hw_params *params) 577 { 578 struct snd_soc_pcm_runtime *rtd = substream->private_data; 579 unsigned int bit_width = params_width(params); 580 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 581 struct snd_soc_dai *codec_dai; 582 int i; 583 584 snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0xf, 4, bit_width); 585 586 for_each_rtd_codec_dais(rtd, i, codec_dai) { 587 if (!strcmp(codec_dai->component->name, MAX98390_DEV0_NAME)) 588 snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x3, 4, bit_width); 589 590 if (!strcmp(codec_dai->component->name, MAX98390_DEV1_NAME)) 591 snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x3, 4, bit_width); 592 593 if (!strcmp(codec_dai->component->name, MAX98390_DEV2_NAME)) 594 snd_soc_dai_set_tdm_slot(codec_dai, 0x2, 0x3, 4, bit_width); 595 596 if (!strcmp(codec_dai->component->name, MAX98390_DEV3_NAME)) 597 snd_soc_dai_set_tdm_slot(codec_dai, 0x1, 0x3, 4, bit_width); 598 } 599 return 0; 600 } 601 602 static const struct snd_soc_ops mt8188_max98390_ops = { 603 .hw_params = mt8188_max98390_hw_params, 604 }; 605 606 static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd) 607 { 608 struct snd_soc_card *card = rtd->card; 609 int ret; 610 611 /* add regular speakers dapm route */ 612 ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dual_spk_widgets, 613 ARRAY_SIZE(mt8188_dual_spk_widgets)); 614 if (ret) { 615 dev_err(rtd->dev, "unable to add Left/Right Speaker widget, ret %d\n", ret); 616 return ret; 617 } 618 619 ret = snd_soc_add_card_controls(card, mt8188_dual_spk_controls, 620 ARRAY_SIZE(mt8188_dual_spk_controls)); 621 if (ret) { 622 dev_err(rtd->dev, "unable to add Left/Right card controls, ret %d\n", ret); 623 return ret; 624 } 625 626 if (rtd->dai_link->num_codecs <= 2) 627 return 0; 628 629 /* add widgets/controls/dapm for rear speakers */ 630 ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_rear_spk_widgets, 631 ARRAY_SIZE(mt8188_rear_spk_widgets)); 632 if (ret) { 633 dev_err(rtd->dev, "unable to add Rear Speaker widget, ret %d\n", ret); 634 /* Don't need to add routes if widget addition failed */ 635 return ret; 636 } 637 638 ret = snd_soc_add_card_controls(card, mt8188_rear_spk_controls, 639 ARRAY_SIZE(mt8188_rear_spk_controls)); 640 if (ret) { 641 dev_err(rtd->dev, "unable to add Rear card controls, ret %d\n", ret); 642 return ret; 643 } 644 645 return 0; 646 } 647 648 static int mt8188_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) 649 { 650 struct snd_soc_card *card = rtd->card; 651 struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card); 652 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 653 struct snd_soc_jack *jack = &priv->headset_jack; 654 int ret; 655 656 ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_nau8825_widgets, 657 ARRAY_SIZE(mt8188_nau8825_widgets)); 658 if (ret) { 659 dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret); 660 return ret; 661 } 662 663 ret = snd_soc_add_card_controls(card, mt8188_nau8825_controls, 664 ARRAY_SIZE(mt8188_nau8825_controls)); 665 if (ret) { 666 dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret); 667 return ret; 668 } 669 670 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", 671 SND_JACK_HEADSET | SND_JACK_BTN_0 | 672 SND_JACK_BTN_1 | SND_JACK_BTN_2 | 673 SND_JACK_BTN_3, 674 jack, 675 nau8825_jack_pins, 676 ARRAY_SIZE(nau8825_jack_pins)); 677 if (ret) { 678 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); 679 return ret; 680 } 681 682 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 683 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 684 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 685 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 686 ret = snd_soc_component_set_jack(component, jack, NULL); 687 688 if (ret) { 689 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 690 return ret; 691 } 692 693 return 0; 694 }; 695 696 static void mt8188_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) 697 { 698 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 699 700 snd_soc_component_set_jack(component, NULL, NULL); 701 } 702 703 static int mt8188_nau8825_hw_params(struct snd_pcm_substream *substream, 704 struct snd_pcm_hw_params *params) 705 { 706 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 707 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 708 unsigned int rate = params_rate(params); 709 unsigned int bit_width = params_width(params); 710 int clk_freq, ret; 711 712 clk_freq = rate * 2 * bit_width; 713 714 /* Configure clock for codec */ 715 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0, 716 SND_SOC_CLOCK_IN); 717 if (ret < 0) { 718 dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret); 719 return ret; 720 } 721 722 /* Configure pll for codec */ 723 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq, 724 params_rate(params) * 256); 725 if (ret < 0) { 726 dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret); 727 return ret; 728 } 729 730 return 0; 731 } 732 733 static const struct snd_soc_ops mt8188_nau8825_ops = { 734 .hw_params = mt8188_nau8825_hw_params, 735 }; 736 static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = { 737 /* FE */ 738 [DAI_LINK_DL2_FE] = { 739 .name = "DL2_FE", 740 .stream_name = "DL2 Playback", 741 .trigger = { 742 SND_SOC_DPCM_TRIGGER_POST, 743 SND_SOC_DPCM_TRIGGER_POST, 744 }, 745 .dynamic = 1, 746 .dpcm_playback = 1, 747 .dpcm_merged_chan = 1, 748 .dpcm_merged_rate = 1, 749 .dpcm_merged_format = 1, 750 SND_SOC_DAILINK_REG(playback2), 751 }, 752 [DAI_LINK_DL3_FE] = { 753 .name = "DL3_FE", 754 .stream_name = "DL3 Playback", 755 .trigger = { 756 SND_SOC_DPCM_TRIGGER_POST, 757 SND_SOC_DPCM_TRIGGER_POST, 758 }, 759 .dynamic = 1, 760 .dpcm_playback = 1, 761 .dpcm_merged_chan = 1, 762 .dpcm_merged_rate = 1, 763 .dpcm_merged_format = 1, 764 SND_SOC_DAILINK_REG(playback3), 765 }, 766 [DAI_LINK_DL6_FE] = { 767 .name = "DL6_FE", 768 .stream_name = "DL6 Playback", 769 .trigger = { 770 SND_SOC_DPCM_TRIGGER_POST, 771 SND_SOC_DPCM_TRIGGER_POST, 772 }, 773 .dynamic = 1, 774 .dpcm_playback = 1, 775 .dpcm_merged_chan = 1, 776 .dpcm_merged_rate = 1, 777 .dpcm_merged_format = 1, 778 SND_SOC_DAILINK_REG(playback6), 779 }, 780 [DAI_LINK_DL7_FE] = { 781 .name = "DL7_FE", 782 .stream_name = "DL7 Playback", 783 .trigger = { 784 SND_SOC_DPCM_TRIGGER_PRE, 785 SND_SOC_DPCM_TRIGGER_PRE, 786 }, 787 .dynamic = 1, 788 .dpcm_playback = 1, 789 SND_SOC_DAILINK_REG(playback7), 790 }, 791 [DAI_LINK_DL8_FE] = { 792 .name = "DL8_FE", 793 .stream_name = "DL8 Playback", 794 .trigger = { 795 SND_SOC_DPCM_TRIGGER_POST, 796 SND_SOC_DPCM_TRIGGER_POST, 797 }, 798 .dynamic = 1, 799 .dpcm_playback = 1, 800 SND_SOC_DAILINK_REG(playback8), 801 }, 802 [DAI_LINK_DL10_FE] = { 803 .name = "DL10_FE", 804 .stream_name = "DL10 Playback", 805 .trigger = { 806 SND_SOC_DPCM_TRIGGER_POST, 807 SND_SOC_DPCM_TRIGGER_POST, 808 }, 809 .dynamic = 1, 810 .dpcm_playback = 1, 811 SND_SOC_DAILINK_REG(playback10), 812 }, 813 [DAI_LINK_DL11_FE] = { 814 .name = "DL11_FE", 815 .stream_name = "DL11 Playback", 816 .trigger = { 817 SND_SOC_DPCM_TRIGGER_POST, 818 SND_SOC_DPCM_TRIGGER_POST, 819 }, 820 .dynamic = 1, 821 .dpcm_playback = 1, 822 SND_SOC_DAILINK_REG(playback11), 823 }, 824 [DAI_LINK_UL1_FE] = { 825 .name = "UL1_FE", 826 .stream_name = "UL1 Capture", 827 .trigger = { 828 SND_SOC_DPCM_TRIGGER_PRE, 829 SND_SOC_DPCM_TRIGGER_PRE, 830 }, 831 .dynamic = 1, 832 .dpcm_capture = 1, 833 SND_SOC_DAILINK_REG(capture1), 834 }, 835 [DAI_LINK_UL2_FE] = { 836 .name = "UL2_FE", 837 .stream_name = "UL2 Capture", 838 .trigger = { 839 SND_SOC_DPCM_TRIGGER_POST, 840 SND_SOC_DPCM_TRIGGER_POST, 841 }, 842 .dynamic = 1, 843 .dpcm_capture = 1, 844 SND_SOC_DAILINK_REG(capture2), 845 }, 846 [DAI_LINK_UL3_FE] = { 847 .name = "UL3_FE", 848 .stream_name = "UL3 Capture", 849 .trigger = { 850 SND_SOC_DPCM_TRIGGER_POST, 851 SND_SOC_DPCM_TRIGGER_POST, 852 }, 853 .dynamic = 1, 854 .dpcm_capture = 1, 855 SND_SOC_DAILINK_REG(capture3), 856 }, 857 [DAI_LINK_UL4_FE] = { 858 .name = "UL4_FE", 859 .stream_name = "UL4 Capture", 860 .trigger = { 861 SND_SOC_DPCM_TRIGGER_POST, 862 SND_SOC_DPCM_TRIGGER_POST, 863 }, 864 .dynamic = 1, 865 .dpcm_capture = 1, 866 .dpcm_merged_chan = 1, 867 .dpcm_merged_rate = 1, 868 .dpcm_merged_format = 1, 869 SND_SOC_DAILINK_REG(capture4), 870 }, 871 [DAI_LINK_UL5_FE] = { 872 .name = "UL5_FE", 873 .stream_name = "UL5 Capture", 874 .trigger = { 875 SND_SOC_DPCM_TRIGGER_POST, 876 SND_SOC_DPCM_TRIGGER_POST, 877 }, 878 .dynamic = 1, 879 .dpcm_capture = 1, 880 .dpcm_merged_chan = 1, 881 .dpcm_merged_rate = 1, 882 .dpcm_merged_format = 1, 883 SND_SOC_DAILINK_REG(capture5), 884 }, 885 [DAI_LINK_UL6_FE] = { 886 .name = "UL6_FE", 887 .stream_name = "UL6 Capture", 888 .trigger = { 889 SND_SOC_DPCM_TRIGGER_PRE, 890 SND_SOC_DPCM_TRIGGER_PRE, 891 }, 892 .dynamic = 1, 893 .dpcm_capture = 1, 894 SND_SOC_DAILINK_REG(capture6), 895 }, 896 [DAI_LINK_UL8_FE] = { 897 .name = "UL8_FE", 898 .stream_name = "UL8 Capture", 899 .trigger = { 900 SND_SOC_DPCM_TRIGGER_POST, 901 SND_SOC_DPCM_TRIGGER_POST, 902 }, 903 .dynamic = 1, 904 .dpcm_capture = 1, 905 SND_SOC_DAILINK_REG(capture8), 906 }, 907 [DAI_LINK_UL9_FE] = { 908 .name = "UL9_FE", 909 .stream_name = "UL9 Capture", 910 .trigger = { 911 SND_SOC_DPCM_TRIGGER_POST, 912 SND_SOC_DPCM_TRIGGER_POST, 913 }, 914 .dynamic = 1, 915 .dpcm_capture = 1, 916 SND_SOC_DAILINK_REG(capture9), 917 }, 918 [DAI_LINK_UL10_FE] = { 919 .name = "UL10_FE", 920 .stream_name = "UL10 Capture", 921 .trigger = { 922 SND_SOC_DPCM_TRIGGER_POST, 923 SND_SOC_DPCM_TRIGGER_POST, 924 }, 925 .dynamic = 1, 926 .dpcm_capture = 1, 927 SND_SOC_DAILINK_REG(capture10), 928 }, 929 /* BE */ 930 [DAI_LINK_DL_SRC_BE] = { 931 .name = "DL_SRC_BE", 932 .no_pcm = 1, 933 .dpcm_playback = 1, 934 SND_SOC_DAILINK_REG(dl_src), 935 }, 936 [DAI_LINK_DPTX_BE] = { 937 .name = "DPTX_BE", 938 .ops = &mt8188_dptx_ops, 939 .be_hw_params_fixup = mt8188_dptx_hw_params_fixup, 940 .no_pcm = 1, 941 .dpcm_playback = 1, 942 SND_SOC_DAILINK_REG(dptx), 943 }, 944 [DAI_LINK_ETDM1_IN_BE] = { 945 .name = "ETDM1_IN_BE", 946 .no_pcm = 1, 947 .dai_fmt = SND_SOC_DAIFMT_I2S | 948 SND_SOC_DAIFMT_NB_NF | 949 SND_SOC_DAIFMT_CBP_CFP, 950 .dpcm_capture = 1, 951 .ignore_suspend = 1, 952 SND_SOC_DAILINK_REG(etdm1_in), 953 }, 954 [DAI_LINK_ETDM2_IN_BE] = { 955 .name = "ETDM2_IN_BE", 956 .no_pcm = 1, 957 .dai_fmt = SND_SOC_DAIFMT_I2S | 958 SND_SOC_DAIFMT_NB_NF | 959 SND_SOC_DAIFMT_CBP_CFP, 960 .dpcm_capture = 1, 961 SND_SOC_DAILINK_REG(etdm2_in), 962 }, 963 [DAI_LINK_ETDM1_OUT_BE] = { 964 .name = "ETDM1_OUT_BE", 965 .no_pcm = 1, 966 .dai_fmt = SND_SOC_DAIFMT_I2S | 967 SND_SOC_DAIFMT_NB_NF | 968 SND_SOC_DAIFMT_CBC_CFC, 969 .dpcm_playback = 1, 970 SND_SOC_DAILINK_REG(etdm1_out), 971 }, 972 [DAI_LINK_ETDM2_OUT_BE] = { 973 .name = "ETDM2_OUT_BE", 974 .no_pcm = 1, 975 .dai_fmt = SND_SOC_DAIFMT_I2S | 976 SND_SOC_DAIFMT_NB_NF | 977 SND_SOC_DAIFMT_CBC_CFC, 978 .dpcm_playback = 1, 979 SND_SOC_DAILINK_REG(etdm2_out), 980 }, 981 [DAI_LINK_ETDM3_OUT_BE] = { 982 .name = "ETDM3_OUT_BE", 983 .no_pcm = 1, 984 .dai_fmt = SND_SOC_DAIFMT_I2S | 985 SND_SOC_DAIFMT_NB_NF | 986 SND_SOC_DAIFMT_CBC_CFC, 987 .dpcm_playback = 1, 988 SND_SOC_DAILINK_REG(etdm3_out), 989 }, 990 [DAI_LINK_PCM1_BE] = { 991 .name = "PCM1_BE", 992 .no_pcm = 1, 993 .dai_fmt = SND_SOC_DAIFMT_I2S | 994 SND_SOC_DAIFMT_NB_NF | 995 SND_SOC_DAIFMT_CBC_CFC, 996 .dpcm_playback = 1, 997 .dpcm_capture = 1, 998 SND_SOC_DAILINK_REG(pcm1), 999 }, 1000 [DAI_LINK_UL_SRC_BE] = { 1001 .name = "UL_SRC_BE", 1002 .no_pcm = 1, 1003 .dpcm_capture = 1, 1004 SND_SOC_DAILINK_REG(ul_src), 1005 }, 1006 }; 1007 1008 static void mt8188_fixup_controls(struct snd_soc_card *card) 1009 { 1010 struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card); 1011 struct mt8188_card_data *card_data = (struct mt8188_card_data *)priv->private_data; 1012 struct snd_kcontrol *kctl; 1013 1014 if (card_data->quirk & NAU8825_HS_PRESENT) { 1015 struct snd_soc_dapm_widget *w, *next_w; 1016 1017 for_each_card_widgets_safe(card, w, next_w) { 1018 if (strcmp(w->name, "Headphone")) 1019 continue; 1020 1021 snd_soc_dapm_free_widget(w); 1022 } 1023 1024 kctl = snd_ctl_find_id_mixer(card->snd_card, "Headphone Switch"); 1025 if (kctl) 1026 snd_ctl_remove(card->snd_card, kctl); 1027 else 1028 dev_warn(card->dev, "Cannot find ctl : Headphone Switch\n"); 1029 } 1030 } 1031 1032 static struct snd_soc_card mt8188_mt6359_soc_card = { 1033 .owner = THIS_MODULE, 1034 .dai_link = mt8188_mt6359_dai_links, 1035 .num_links = ARRAY_SIZE(mt8188_mt6359_dai_links), 1036 .dapm_widgets = mt8188_mt6359_widgets, 1037 .num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets), 1038 .controls = mt8188_mt6359_controls, 1039 .num_controls = ARRAY_SIZE(mt8188_mt6359_controls), 1040 .fixup_controls = mt8188_fixup_controls, 1041 }; 1042 1043 static int mt8188_mt6359_dev_probe(struct platform_device *pdev) 1044 { 1045 struct snd_soc_card *card = &mt8188_mt6359_soc_card; 1046 struct device_node *platform_node; 1047 struct mt8188_mt6359_priv *priv; 1048 struct mt8188_card_data *card_data; 1049 struct snd_soc_dai_link *dai_link; 1050 bool init_mt6359 = false; 1051 bool init_nau8825 = false; 1052 bool init_max98390 = false; 1053 bool init_dumb = false; 1054 int ret, i; 1055 1056 card_data = (struct mt8188_card_data *)of_device_get_match_data(&pdev->dev); 1057 card->dev = &pdev->dev; 1058 1059 ret = snd_soc_of_parse_card_name(card, "model"); 1060 if (ret) 1061 return dev_err_probe(&pdev->dev, ret, "%s new card name parsing error\n", 1062 __func__); 1063 1064 if (!card->name) 1065 card->name = card_data->name; 1066 1067 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 1068 if (!priv) 1069 return -ENOMEM; 1070 1071 if (of_property_read_bool(pdev->dev.of_node, "audio-routing")) { 1072 ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); 1073 if (ret) 1074 return ret; 1075 } 1076 1077 platform_node = of_parse_phandle(pdev->dev.of_node, 1078 "mediatek,platform", 0); 1079 if (!platform_node) { 1080 ret = -EINVAL; 1081 return dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n"); 1082 } 1083 1084 ret = parse_dai_link_info(card); 1085 if (ret) 1086 goto err; 1087 1088 for_each_card_prelinks(card, i, dai_link) { 1089 if (!dai_link->platforms->name) 1090 dai_link->platforms->of_node = platform_node; 1091 1092 if (strcmp(dai_link->name, "DPTX_BE") == 0) { 1093 if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) 1094 dai_link->init = mt8188_dptx_codec_init; 1095 } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { 1096 if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) 1097 dai_link->init = mt8188_hdmi_codec_init; 1098 } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || 1099 strcmp(dai_link->name, "UL_SRC_BE") == 0) { 1100 if (!init_mt6359) { 1101 dai_link->init = mt8188_mt6359_init; 1102 init_mt6359 = true; 1103 } 1104 } else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 || 1105 strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 || 1106 strcmp(dai_link->name, "ETDM1_IN_BE") == 0 || 1107 strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { 1108 if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) { 1109 dai_link->ops = &mt8188_max98390_ops; 1110 if (!init_max98390) { 1111 dai_link->init = mt8188_max98390_codec_init; 1112 init_max98390 = true; 1113 } 1114 } else if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) { 1115 dai_link->ops = &mt8188_nau8825_ops; 1116 if (!init_nau8825) { 1117 dai_link->init = mt8188_nau8825_codec_init; 1118 dai_link->exit = mt8188_nau8825_codec_exit; 1119 init_nau8825 = true; 1120 } 1121 } else { 1122 if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) { 1123 if (!init_dumb) { 1124 dai_link->init = mt8188_dumb_amp_init; 1125 init_dumb = true; 1126 } 1127 } 1128 } 1129 } 1130 } 1131 1132 priv->private_data = card_data; 1133 snd_soc_card_set_drvdata(card, priv); 1134 1135 ret = devm_snd_soc_register_card(&pdev->dev, card); 1136 if (ret) 1137 dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", 1138 __func__); 1139 err: 1140 of_node_put(platform_node); 1141 clean_card_reference(card); 1142 return ret; 1143 } 1144 1145 static struct mt8188_card_data mt8188_evb_card = { 1146 .name = "mt8188_mt6359", 1147 }; 1148 1149 static struct mt8188_card_data mt8188_nau8825_card = { 1150 .name = "mt8188_nau8825", 1151 .quirk = NAU8825_HS_PRESENT, 1152 }; 1153 1154 static const struct of_device_id mt8188_mt6359_dt_match[] = { 1155 { .compatible = "mediatek,mt8188-mt6359-evb", .data = &mt8188_evb_card, }, 1156 { .compatible = "mediatek,mt8188-nau8825", .data = &mt8188_nau8825_card, }, 1157 { /* sentinel */ }, 1158 }; 1159 MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match); 1160 1161 static struct platform_driver mt8188_mt6359_driver = { 1162 .driver = { 1163 .name = "mt8188_mt6359", 1164 .of_match_table = mt8188_mt6359_dt_match, 1165 .pm = &snd_soc_pm_ops, 1166 }, 1167 .probe = mt8188_mt6359_dev_probe, 1168 }; 1169 1170 module_platform_driver(mt8188_mt6359_driver); 1171 1172 /* Module information */ 1173 MODULE_DESCRIPTION("MT8188-MT6359 ALSA SoC machine driver"); 1174 MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>"); 1175 MODULE_LICENSE("GPL"); 1176 MODULE_ALIAS("mt8188 mt6359 soc card"); 1177