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