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