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