1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright(c) 2021 Intel Corporation. 3 // Copyright(c) 2021 Nuvoton Corporation. 4 5 /* 6 * Intel SOF Machine Driver with Nuvoton headphone codec NAU8825 7 * and speaker codec RT1019P MAX98360a or MAX98373 8 */ 9 #include <linux/i2c.h> 10 #include <linux/input.h> 11 #include <linux/module.h> 12 #include <linux/platform_device.h> 13 #include <linux/dmi.h> 14 #include <sound/core.h> 15 #include <sound/jack.h> 16 #include <sound/pcm.h> 17 #include <sound/pcm_params.h> 18 #include <sound/soc.h> 19 #include <sound/sof.h> 20 #include <sound/soc-acpi.h> 21 #include "../../codecs/nau8825.h" 22 #include "../common/soc-intel-quirks.h" 23 #include "hda_dsp_common.h" 24 #include "sof_realtek_common.h" 25 #include "sof_maxim_common.h" 26 27 #define NAME_SIZE 32 28 29 #define SOF_NAU8825_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) 30 #define SOF_NAU8825_SSP_CODEC_MASK (GENMASK(2, 0)) 31 #define SOF_SPEAKER_AMP_PRESENT BIT(3) 32 #define SOF_NAU8825_SSP_AMP_SHIFT 4 33 #define SOF_NAU8825_SSP_AMP_MASK (GENMASK(6, 4)) 34 #define SOF_NAU8825_SSP_AMP(quirk) \ 35 (((quirk) << SOF_NAU8825_SSP_AMP_SHIFT) & SOF_NAU8825_SSP_AMP_MASK) 36 #define SOF_NAU8825_NUM_HDMIDEV_SHIFT 7 37 #define SOF_NAU8825_NUM_HDMIDEV_MASK (GENMASK(9, 7)) 38 #define SOF_NAU8825_NUM_HDMIDEV(quirk) \ 39 (((quirk) << SOF_NAU8825_NUM_HDMIDEV_SHIFT) & SOF_NAU8825_NUM_HDMIDEV_MASK) 40 41 /* BT audio offload: reserve 3 bits for future */ 42 #define SOF_BT_OFFLOAD_SSP_SHIFT 10 43 #define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(12, 10)) 44 #define SOF_BT_OFFLOAD_SSP(quirk) \ 45 (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) 46 #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(13) 47 #define SOF_RT1019P_SPEAKER_AMP_PRESENT BIT(14) 48 #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) 49 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) 50 #define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) 51 52 static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); 53 54 struct sof_hdmi_pcm { 55 struct list_head head; 56 struct snd_soc_dai *codec_dai; 57 int device; 58 }; 59 60 struct sof_card_private { 61 struct clk *mclk; 62 struct snd_soc_jack sof_headset; 63 struct list_head hdmi_pcm_list; 64 }; 65 66 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) 67 { 68 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 69 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 70 struct sof_hdmi_pcm *pcm; 71 72 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 73 if (!pcm) 74 return -ENOMEM; 75 76 /* dai_link id is 1:1 mapped to the PCM device */ 77 pcm->device = rtd->dai_link->id; 78 pcm->codec_dai = dai; 79 80 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 81 82 return 0; 83 } 84 85 static struct snd_soc_jack_pin jack_pins[] = { 86 { 87 .pin = "Headphone Jack", 88 .mask = SND_JACK_HEADPHONE, 89 }, 90 { 91 .pin = "Headset Mic", 92 .mask = SND_JACK_MICROPHONE, 93 }, 94 }; 95 96 static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) 97 { 98 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 99 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 100 101 struct snd_soc_jack *jack; 102 int ret; 103 104 /* 105 * Headset buttons map to the google Reference headset. 106 * These can be configured by userspace. 107 */ 108 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", 109 SND_JACK_HEADSET | SND_JACK_BTN_0 | 110 SND_JACK_BTN_1 | SND_JACK_BTN_2 | 111 SND_JACK_BTN_3, 112 &ctx->sof_headset, 113 jack_pins, 114 ARRAY_SIZE(jack_pins)); 115 if (ret) { 116 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); 117 return ret; 118 } 119 120 jack = &ctx->sof_headset; 121 122 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 123 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 124 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 125 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 126 ret = snd_soc_component_set_jack(component, jack, NULL); 127 128 if (ret) { 129 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 130 return ret; 131 } 132 133 return ret; 134 }; 135 136 static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) 137 { 138 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 139 140 snd_soc_component_set_jack(component, NULL, NULL); 141 } 142 143 static int sof_nau8825_hw_params(struct snd_pcm_substream *substream, 144 struct snd_pcm_hw_params *params) 145 { 146 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 147 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 148 int clk_freq, ret; 149 150 clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */ 151 152 if (clk_freq <= 0) { 153 dev_err(rtd->dev, "get bclk freq failed: %d\n", clk_freq); 154 return -EINVAL; 155 } 156 157 /* Configure clock for codec */ 158 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0, 159 SND_SOC_CLOCK_IN); 160 if (ret < 0) { 161 dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret); 162 return ret; 163 } 164 165 /* Configure pll for codec */ 166 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq, 167 params_rate(params) * 256); 168 if (ret < 0) { 169 dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret); 170 return ret; 171 } 172 173 return ret; 174 } 175 176 static struct snd_soc_ops sof_nau8825_ops = { 177 .hw_params = sof_nau8825_hw_params, 178 }; 179 180 static struct snd_soc_dai_link_component platform_component[] = { 181 { 182 /* name might be overridden during probe */ 183 .name = "0000:00:1f.3" 184 } 185 }; 186 187 static int sof_card_late_probe(struct snd_soc_card *card) 188 { 189 struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); 190 struct snd_soc_dapm_context *dapm = &card->dapm; 191 struct sof_hdmi_pcm *pcm; 192 int err; 193 194 if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) { 195 /* Disable Left and Right Spk pin after boot */ 196 snd_soc_dapm_disable_pin(dapm, "Left Spk"); 197 snd_soc_dapm_disable_pin(dapm, "Right Spk"); 198 err = snd_soc_dapm_sync(dapm); 199 if (err < 0) 200 return err; 201 } 202 203 if (list_empty(&ctx->hdmi_pcm_list)) 204 return -EINVAL; 205 206 pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, head); 207 208 return hda_dsp_hdmi_build_controls(card, pcm->codec_dai->component); 209 } 210 211 static const struct snd_kcontrol_new sof_controls[] = { 212 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 213 SOC_DAPM_PIN_SWITCH("Headset Mic"), 214 SOC_DAPM_PIN_SWITCH("Left Spk"), 215 SOC_DAPM_PIN_SWITCH("Right Spk"), 216 }; 217 218 static const struct snd_kcontrol_new speaker_controls[] = { 219 SOC_DAPM_PIN_SWITCH("Spk"), 220 }; 221 222 static const struct snd_soc_dapm_widget sof_widgets[] = { 223 SND_SOC_DAPM_HP("Headphone Jack", NULL), 224 SND_SOC_DAPM_MIC("Headset Mic", NULL), 225 SND_SOC_DAPM_SPK("Left Spk", NULL), 226 SND_SOC_DAPM_SPK("Right Spk", NULL), 227 }; 228 229 static const struct snd_soc_dapm_widget speaker_widgets[] = { 230 SND_SOC_DAPM_SPK("Spk", NULL), 231 }; 232 233 static const struct snd_soc_dapm_widget dmic_widgets[] = { 234 SND_SOC_DAPM_MIC("SoC DMIC", NULL), 235 }; 236 237 static const struct snd_soc_dapm_route sof_map[] = { 238 /* HP jack connectors - unknown if we have jack detection */ 239 { "Headphone Jack", NULL, "HPOL" }, 240 { "Headphone Jack", NULL, "HPOR" }, 241 242 /* other jacks */ 243 { "MIC", NULL, "Headset Mic" }, 244 }; 245 246 static const struct snd_soc_dapm_route speaker_map[] = { 247 /* speaker */ 248 { "Spk", NULL, "Speaker" }, 249 }; 250 251 static const struct snd_soc_dapm_route dmic_map[] = { 252 /* digital mics */ 253 {"DMic", NULL, "SoC DMIC"}, 254 }; 255 256 static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) 257 { 258 struct snd_soc_card *card = rtd->card; 259 int ret; 260 261 ret = snd_soc_dapm_new_controls(&card->dapm, speaker_widgets, 262 ARRAY_SIZE(speaker_widgets)); 263 if (ret) { 264 dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 265 /* Don't need to add routes if widget addition failed */ 266 return ret; 267 } 268 269 ret = snd_soc_add_card_controls(card, speaker_controls, 270 ARRAY_SIZE(speaker_controls)); 271 if (ret) { 272 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 273 return ret; 274 } 275 276 ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map, 277 ARRAY_SIZE(speaker_map)); 278 279 if (ret) 280 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 281 return ret; 282 } 283 284 static int dmic_init(struct snd_soc_pcm_runtime *rtd) 285 { 286 struct snd_soc_card *card = rtd->card; 287 int ret; 288 289 ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, 290 ARRAY_SIZE(dmic_widgets)); 291 if (ret) { 292 dev_err(card->dev, "DMic widget addition failed: %d\n", ret); 293 /* Don't need to add routes if widget addition failed */ 294 return ret; 295 } 296 297 ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, 298 ARRAY_SIZE(dmic_map)); 299 300 if (ret) 301 dev_err(card->dev, "DMic map addition failed: %d\n", ret); 302 303 return ret; 304 } 305 306 /* sof audio machine driver for nau8825 codec */ 307 static struct snd_soc_card sof_audio_card_nau8825 = { 308 .name = "nau8825", /* the sof- prefix is added by the core */ 309 .owner = THIS_MODULE, 310 .controls = sof_controls, 311 .num_controls = ARRAY_SIZE(sof_controls), 312 .dapm_widgets = sof_widgets, 313 .num_dapm_widgets = ARRAY_SIZE(sof_widgets), 314 .dapm_routes = sof_map, 315 .num_dapm_routes = ARRAY_SIZE(sof_map), 316 .fully_routed = true, 317 .late_probe = sof_card_late_probe, 318 }; 319 320 static struct snd_soc_dai_link_component nau8825_component[] = { 321 { 322 .name = "i2c-10508825:00", 323 .dai_name = "nau8825-hifi", 324 } 325 }; 326 327 static struct snd_soc_dai_link_component dmic_component[] = { 328 { 329 .name = "dmic-codec", 330 .dai_name = "dmic-hifi", 331 } 332 }; 333 334 static struct snd_soc_dai_link_component rt1019p_component[] = { 335 { 336 .name = "RTL1019:00", 337 .dai_name = "HiFi", 338 } 339 }; 340 341 static struct snd_soc_dai_link_component dummy_component[] = { 342 { 343 .name = "snd-soc-dummy", 344 .dai_name = "snd-soc-dummy-dai", 345 } 346 }; 347 348 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, 349 int ssp_codec, 350 int ssp_amp, 351 int dmic_be_num, 352 int hdmi_num) 353 { 354 struct snd_soc_dai_link_component *idisp_components; 355 struct snd_soc_dai_link_component *cpus; 356 struct snd_soc_dai_link *links; 357 int i, id = 0; 358 359 links = devm_kcalloc(dev, sof_audio_card_nau8825.num_links, 360 sizeof(struct snd_soc_dai_link), GFP_KERNEL); 361 cpus = devm_kcalloc(dev, sof_audio_card_nau8825.num_links, 362 sizeof(struct snd_soc_dai_link_component), GFP_KERNEL); 363 if (!links || !cpus) 364 goto devm_err; 365 366 /* codec SSP */ 367 links[id].name = devm_kasprintf(dev, GFP_KERNEL, 368 "SSP%d-Codec", ssp_codec); 369 if (!links[id].name) 370 goto devm_err; 371 372 links[id].id = id; 373 links[id].codecs = nau8825_component; 374 links[id].num_codecs = ARRAY_SIZE(nau8825_component); 375 links[id].platforms = platform_component; 376 links[id].num_platforms = ARRAY_SIZE(platform_component); 377 links[id].init = sof_nau8825_codec_init; 378 links[id].exit = sof_nau8825_codec_exit; 379 links[id].ops = &sof_nau8825_ops; 380 links[id].dpcm_playback = 1; 381 links[id].dpcm_capture = 1; 382 links[id].no_pcm = 1; 383 links[id].cpus = &cpus[id]; 384 links[id].num_cpus = 1; 385 386 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 387 "SSP%d Pin", 388 ssp_codec); 389 if (!links[id].cpus->dai_name) 390 goto devm_err; 391 392 id++; 393 394 /* dmic */ 395 if (dmic_be_num > 0) { 396 /* at least we have dmic01 */ 397 links[id].name = "dmic01"; 398 links[id].cpus = &cpus[id]; 399 links[id].cpus->dai_name = "DMIC01 Pin"; 400 links[id].init = dmic_init; 401 if (dmic_be_num > 1) { 402 /* set up 2 BE links at most */ 403 links[id + 1].name = "dmic16k"; 404 links[id + 1].cpus = &cpus[id + 1]; 405 links[id + 1].cpus->dai_name = "DMIC16k Pin"; 406 dmic_be_num = 2; 407 } 408 } 409 410 for (i = 0; i < dmic_be_num; i++) { 411 links[id].id = id; 412 links[id].num_cpus = 1; 413 links[id].codecs = dmic_component; 414 links[id].num_codecs = ARRAY_SIZE(dmic_component); 415 links[id].platforms = platform_component; 416 links[id].num_platforms = ARRAY_SIZE(platform_component); 417 links[id].ignore_suspend = 1; 418 links[id].dpcm_capture = 1; 419 links[id].no_pcm = 1; 420 id++; 421 } 422 423 /* HDMI */ 424 if (hdmi_num > 0) { 425 idisp_components = devm_kcalloc(dev, 426 hdmi_num, 427 sizeof(struct snd_soc_dai_link_component), 428 GFP_KERNEL); 429 if (!idisp_components) 430 goto devm_err; 431 } 432 for (i = 1; i <= hdmi_num; i++) { 433 links[id].name = devm_kasprintf(dev, GFP_KERNEL, 434 "iDisp%d", i); 435 if (!links[id].name) 436 goto devm_err; 437 438 links[id].id = id; 439 links[id].cpus = &cpus[id]; 440 links[id].num_cpus = 1; 441 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 442 "iDisp%d Pin", i); 443 if (!links[id].cpus->dai_name) 444 goto devm_err; 445 446 idisp_components[i - 1].name = "ehdaudio0D2"; 447 idisp_components[i - 1].dai_name = devm_kasprintf(dev, 448 GFP_KERNEL, 449 "intel-hdmi-hifi%d", 450 i); 451 if (!idisp_components[i - 1].dai_name) 452 goto devm_err; 453 454 links[id].codecs = &idisp_components[i - 1]; 455 links[id].num_codecs = 1; 456 links[id].platforms = platform_component; 457 links[id].num_platforms = ARRAY_SIZE(platform_component); 458 links[id].init = sof_hdmi_init; 459 links[id].dpcm_playback = 1; 460 links[id].no_pcm = 1; 461 id++; 462 } 463 464 /* speaker amp */ 465 if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) { 466 links[id].name = devm_kasprintf(dev, GFP_KERNEL, 467 "SSP%d-Codec", ssp_amp); 468 if (!links[id].name) 469 goto devm_err; 470 471 links[id].id = id; 472 if (sof_nau8825_quirk & SOF_RT1019P_SPEAKER_AMP_PRESENT) { 473 links[id].codecs = rt1019p_component; 474 links[id].num_codecs = ARRAY_SIZE(rt1019p_component); 475 links[id].init = speaker_codec_init; 476 } else if (sof_nau8825_quirk & 477 SOF_MAX98373_SPEAKER_AMP_PRESENT) { 478 links[id].codecs = max_98373_components; 479 links[id].num_codecs = ARRAY_SIZE(max_98373_components); 480 links[id].init = max_98373_spk_codec_init; 481 links[id].ops = &max_98373_ops; 482 /* feedback stream */ 483 links[id].dpcm_capture = 1; 484 } else if (sof_nau8825_quirk & 485 SOF_MAX98360A_SPEAKER_AMP_PRESENT) { 486 max_98360a_dai_link(&links[id]); 487 } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { 488 sof_rt1015p_dai_link(&links[id]); 489 } else { 490 goto devm_err; 491 } 492 493 links[id].platforms = platform_component; 494 links[id].num_platforms = ARRAY_SIZE(platform_component); 495 links[id].dpcm_playback = 1; 496 links[id].no_pcm = 1; 497 links[id].cpus = &cpus[id]; 498 links[id].num_cpus = 1; 499 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 500 "SSP%d Pin", 501 ssp_amp); 502 if (!links[id].cpus->dai_name) 503 goto devm_err; 504 id++; 505 } 506 507 /* BT audio offload */ 508 if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { 509 int port = (sof_nau8825_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> 510 SOF_BT_OFFLOAD_SSP_SHIFT; 511 512 links[id].id = id; 513 links[id].cpus = &cpus[id]; 514 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 515 "SSP%d Pin", port); 516 if (!links[id].cpus->dai_name) 517 goto devm_err; 518 links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); 519 if (!links[id].name) 520 goto devm_err; 521 links[id].codecs = dummy_component; 522 links[id].num_codecs = ARRAY_SIZE(dummy_component); 523 links[id].platforms = platform_component; 524 links[id].num_platforms = ARRAY_SIZE(platform_component); 525 links[id].dpcm_playback = 1; 526 links[id].dpcm_capture = 1; 527 links[id].no_pcm = 1; 528 links[id].num_cpus = 1; 529 } 530 531 return links; 532 devm_err: 533 return NULL; 534 } 535 536 static int sof_audio_probe(struct platform_device *pdev) 537 { 538 struct snd_soc_dai_link *dai_links; 539 struct snd_soc_acpi_mach *mach; 540 struct sof_card_private *ctx; 541 int dmic_be_num, hdmi_num; 542 int ret, ssp_amp, ssp_codec; 543 544 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 545 if (!ctx) 546 return -ENOMEM; 547 548 if (pdev->id_entry && pdev->id_entry->driver_data) 549 sof_nau8825_quirk = (unsigned long)pdev->id_entry->driver_data; 550 551 mach = pdev->dev.platform_data; 552 553 /* A speaker amp might not be present when the quirk claims one is. 554 * Detect this via whether the machine driver match includes quirk_data. 555 */ 556 if ((sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data) 557 sof_nau8825_quirk &= ~SOF_SPEAKER_AMP_PRESENT; 558 559 dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk); 560 561 /* default number of DMIC DAI's */ 562 dmic_be_num = 2; 563 hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >> 564 SOF_NAU8825_NUM_HDMIDEV_SHIFT; 565 /* default number of HDMI DAI's */ 566 if (!hdmi_num) 567 hdmi_num = 3; 568 569 ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >> 570 SOF_NAU8825_SSP_AMP_SHIFT; 571 572 ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK; 573 574 /* compute number of dai links */ 575 sof_audio_card_nau8825.num_links = 1 + dmic_be_num + hdmi_num; 576 577 if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) 578 sof_audio_card_nau8825.num_links++; 579 580 if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) 581 max_98373_set_codec_conf(&sof_audio_card_nau8825); 582 else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) 583 sof_rt1015p_codec_conf(&sof_audio_card_nau8825); 584 585 if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) 586 sof_audio_card_nau8825.num_links++; 587 588 dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, 589 dmic_be_num, hdmi_num); 590 if (!dai_links) 591 return -ENOMEM; 592 593 sof_audio_card_nau8825.dai_link = dai_links; 594 595 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 596 597 sof_audio_card_nau8825.dev = &pdev->dev; 598 599 /* set platform name for each dailink */ 600 ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_nau8825, 601 mach->mach_params.platform); 602 if (ret) 603 return ret; 604 605 snd_soc_card_set_drvdata(&sof_audio_card_nau8825, ctx); 606 607 return devm_snd_soc_register_card(&pdev->dev, 608 &sof_audio_card_nau8825); 609 } 610 611 static const struct platform_device_id board_ids[] = { 612 { 613 .name = "sof_nau8825", 614 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | 615 SOF_NAU8825_NUM_HDMIDEV(4) | 616 SOF_BT_OFFLOAD_SSP(2) | 617 SOF_SSP_BT_OFFLOAD_PRESENT), 618 619 }, 620 { 621 .name = "adl_rt1019p_nau8825", 622 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | 623 SOF_SPEAKER_AMP_PRESENT | 624 SOF_RT1019P_SPEAKER_AMP_PRESENT | 625 SOF_NAU8825_SSP_AMP(2) | 626 SOF_NAU8825_NUM_HDMIDEV(4)), 627 }, 628 { 629 .name = "adl_max98373_nau8825", 630 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | 631 SOF_SPEAKER_AMP_PRESENT | 632 SOF_MAX98373_SPEAKER_AMP_PRESENT | 633 SOF_NAU8825_SSP_AMP(1) | 634 SOF_NAU8825_NUM_HDMIDEV(4) | 635 SOF_BT_OFFLOAD_SSP(2) | 636 SOF_SSP_BT_OFFLOAD_PRESENT), 637 }, 638 { 639 /* The limitation of length of char array, shorten the name */ 640 .name = "adl_mx98360a_nau8825", 641 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | 642 SOF_SPEAKER_AMP_PRESENT | 643 SOF_MAX98360A_SPEAKER_AMP_PRESENT | 644 SOF_NAU8825_SSP_AMP(1) | 645 SOF_NAU8825_NUM_HDMIDEV(4) | 646 SOF_BT_OFFLOAD_SSP(2) | 647 SOF_SSP_BT_OFFLOAD_PRESENT), 648 649 }, 650 { 651 .name = "adl_rt1015p_nau8825", 652 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | 653 SOF_SPEAKER_AMP_PRESENT | 654 SOF_RT1015P_SPEAKER_AMP_PRESENT | 655 SOF_NAU8825_SSP_AMP(1) | 656 SOF_NAU8825_NUM_HDMIDEV(4) | 657 SOF_BT_OFFLOAD_SSP(2) | 658 SOF_SSP_BT_OFFLOAD_PRESENT), 659 }, 660 { } 661 }; 662 MODULE_DEVICE_TABLE(platform, board_ids); 663 664 static struct platform_driver sof_audio = { 665 .probe = sof_audio_probe, 666 .driver = { 667 .name = "sof_nau8825", 668 .pm = &snd_soc_pm_ops, 669 }, 670 .id_table = board_ids, 671 }; 672 module_platform_driver(sof_audio) 673 674 /* Module information */ 675 MODULE_DESCRIPTION("SOF Audio Machine driver for NAU8825"); 676 MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>"); 677 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); 678 MODULE_LICENSE("GPL"); 679 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); 680 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); 681 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); 682