0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/i2c.h>
0010 #include <linux/input.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/dmi.h>
0014 #include <sound/core.h>
0015 #include <sound/jack.h>
0016 #include <sound/pcm.h>
0017 #include <sound/pcm_params.h>
0018 #include <sound/soc.h>
0019 #include <sound/sof.h>
0020 #include <sound/soc-acpi.h>
0021 #include "../../codecs/nau8825.h"
0022 #include "../common/soc-intel-quirks.h"
0023 #include "hda_dsp_common.h"
0024 #include "sof_realtek_common.h"
0025 #include "sof_maxim_common.h"
0026
0027 #define NAME_SIZE 32
0028
0029 #define SOF_NAU8825_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
0030 #define SOF_NAU8825_SSP_CODEC_MASK (GENMASK(2, 0))
0031 #define SOF_SPEAKER_AMP_PRESENT BIT(3)
0032 #define SOF_NAU8825_SSP_AMP_SHIFT 4
0033 #define SOF_NAU8825_SSP_AMP_MASK (GENMASK(6, 4))
0034 #define SOF_NAU8825_SSP_AMP(quirk) \
0035 (((quirk) << SOF_NAU8825_SSP_AMP_SHIFT) & SOF_NAU8825_SSP_AMP_MASK)
0036 #define SOF_NAU8825_NUM_HDMIDEV_SHIFT 7
0037 #define SOF_NAU8825_NUM_HDMIDEV_MASK (GENMASK(9, 7))
0038 #define SOF_NAU8825_NUM_HDMIDEV(quirk) \
0039 (((quirk) << SOF_NAU8825_NUM_HDMIDEV_SHIFT) & SOF_NAU8825_NUM_HDMIDEV_MASK)
0040
0041
0042 #define SOF_BT_OFFLOAD_SSP_SHIFT 10
0043 #define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(12, 10))
0044 #define SOF_BT_OFFLOAD_SSP(quirk) \
0045 (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
0046 #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(13)
0047 #define SOF_RT1019P_SPEAKER_AMP_PRESENT BIT(14)
0048 #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15)
0049 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16)
0050
0051 static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0);
0052
0053 struct sof_hdmi_pcm {
0054 struct list_head head;
0055 struct snd_soc_dai *codec_dai;
0056 int device;
0057 };
0058
0059 struct sof_card_private {
0060 struct clk *mclk;
0061 struct snd_soc_jack sof_headset;
0062 struct list_head hdmi_pcm_list;
0063 };
0064
0065 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
0066 {
0067 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
0068 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
0069 struct sof_hdmi_pcm *pcm;
0070
0071 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
0072 if (!pcm)
0073 return -ENOMEM;
0074
0075
0076 pcm->device = rtd->dai_link->id;
0077 pcm->codec_dai = dai;
0078
0079 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
0080
0081 return 0;
0082 }
0083
0084 static struct snd_soc_jack_pin jack_pins[] = {
0085 {
0086 .pin = "Headphone Jack",
0087 .mask = SND_JACK_HEADPHONE,
0088 },
0089 {
0090 .pin = "Headset Mic",
0091 .mask = SND_JACK_MICROPHONE,
0092 },
0093 };
0094
0095 static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
0096 {
0097 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
0098 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
0099
0100 struct snd_soc_jack *jack;
0101 int ret;
0102
0103
0104
0105
0106
0107 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
0108 SND_JACK_HEADSET | SND_JACK_BTN_0 |
0109 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
0110 SND_JACK_BTN_3,
0111 &ctx->sof_headset,
0112 jack_pins,
0113 ARRAY_SIZE(jack_pins));
0114 if (ret) {
0115 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
0116 return ret;
0117 }
0118
0119 jack = &ctx->sof_headset;
0120
0121 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0122 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0123 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0124 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0125 ret = snd_soc_component_set_jack(component, jack, NULL);
0126
0127 if (ret) {
0128 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
0129 return ret;
0130 }
0131
0132 return ret;
0133 };
0134
0135 static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd)
0136 {
0137 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
0138
0139 snd_soc_component_set_jack(component, NULL, NULL);
0140 }
0141
0142 static int sof_nau8825_hw_params(struct snd_pcm_substream *substream,
0143 struct snd_pcm_hw_params *params)
0144 {
0145 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0146 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0147 int clk_freq, ret;
0148
0149 clk_freq = sof_dai_get_bclk(rtd);
0150
0151 if (clk_freq <= 0) {
0152 dev_err(rtd->dev, "get bclk freq failed: %d\n", clk_freq);
0153 return -EINVAL;
0154 }
0155
0156
0157 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,
0158 SND_SOC_CLOCK_IN);
0159 if (ret < 0) {
0160 dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);
0161 return ret;
0162 }
0163
0164
0165 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,
0166 params_rate(params) * 256);
0167 if (ret < 0) {
0168 dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);
0169 return ret;
0170 }
0171
0172 return ret;
0173 }
0174
0175 static struct snd_soc_ops sof_nau8825_ops = {
0176 .hw_params = sof_nau8825_hw_params,
0177 };
0178
0179 static struct snd_soc_dai_link_component platform_component[] = {
0180 {
0181
0182 .name = "0000:00:1f.3"
0183 }
0184 };
0185
0186 static int sof_card_late_probe(struct snd_soc_card *card)
0187 {
0188 struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
0189 struct snd_soc_dapm_context *dapm = &card->dapm;
0190 struct sof_hdmi_pcm *pcm;
0191 int err;
0192
0193 if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
0194
0195 snd_soc_dapm_disable_pin(dapm, "Left Spk");
0196 snd_soc_dapm_disable_pin(dapm, "Right Spk");
0197 err = snd_soc_dapm_sync(dapm);
0198 if (err < 0)
0199 return err;
0200 }
0201
0202 if (list_empty(&ctx->hdmi_pcm_list))
0203 return -EINVAL;
0204
0205 pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, head);
0206
0207 return hda_dsp_hdmi_build_controls(card, pcm->codec_dai->component);
0208 }
0209
0210 static const struct snd_kcontrol_new sof_controls[] = {
0211 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
0212 SOC_DAPM_PIN_SWITCH("Headset Mic"),
0213 SOC_DAPM_PIN_SWITCH("Left Spk"),
0214 SOC_DAPM_PIN_SWITCH("Right Spk"),
0215 };
0216
0217 static const struct snd_kcontrol_new speaker_controls[] = {
0218 SOC_DAPM_PIN_SWITCH("Spk"),
0219 };
0220
0221 static const struct snd_soc_dapm_widget sof_widgets[] = {
0222 SND_SOC_DAPM_HP("Headphone Jack", NULL),
0223 SND_SOC_DAPM_MIC("Headset Mic", NULL),
0224 SND_SOC_DAPM_SPK("Left Spk", NULL),
0225 SND_SOC_DAPM_SPK("Right Spk", NULL),
0226 };
0227
0228 static const struct snd_soc_dapm_widget speaker_widgets[] = {
0229 SND_SOC_DAPM_SPK("Spk", NULL),
0230 };
0231
0232 static const struct snd_soc_dapm_widget dmic_widgets[] = {
0233 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
0234 };
0235
0236 static const struct snd_soc_dapm_route sof_map[] = {
0237
0238 { "Headphone Jack", NULL, "HPOL" },
0239 { "Headphone Jack", NULL, "HPOR" },
0240
0241
0242 { "MIC", NULL, "Headset Mic" },
0243 };
0244
0245 static const struct snd_soc_dapm_route speaker_map[] = {
0246
0247 { "Spk", NULL, "Speaker" },
0248 };
0249
0250 static const struct snd_soc_dapm_route dmic_map[] = {
0251
0252 {"DMic", NULL, "SoC DMIC"},
0253 };
0254
0255 static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
0256 {
0257 struct snd_soc_card *card = rtd->card;
0258 int ret;
0259
0260 ret = snd_soc_dapm_new_controls(&card->dapm, speaker_widgets,
0261 ARRAY_SIZE(speaker_widgets));
0262 if (ret) {
0263 dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret);
0264
0265 return ret;
0266 }
0267
0268 ret = snd_soc_add_card_controls(card, speaker_controls,
0269 ARRAY_SIZE(speaker_controls));
0270 if (ret) {
0271 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
0272 return ret;
0273 }
0274
0275 ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map,
0276 ARRAY_SIZE(speaker_map));
0277
0278 if (ret)
0279 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
0280 return ret;
0281 }
0282
0283 static int dmic_init(struct snd_soc_pcm_runtime *rtd)
0284 {
0285 struct snd_soc_card *card = rtd->card;
0286 int ret;
0287
0288 ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
0289 ARRAY_SIZE(dmic_widgets));
0290 if (ret) {
0291 dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
0292
0293 return ret;
0294 }
0295
0296 ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
0297 ARRAY_SIZE(dmic_map));
0298
0299 if (ret)
0300 dev_err(card->dev, "DMic map addition failed: %d\n", ret);
0301
0302 return ret;
0303 }
0304
0305
0306 static struct snd_soc_card sof_audio_card_nau8825 = {
0307 .name = "nau8825",
0308 .owner = THIS_MODULE,
0309 .controls = sof_controls,
0310 .num_controls = ARRAY_SIZE(sof_controls),
0311 .dapm_widgets = sof_widgets,
0312 .num_dapm_widgets = ARRAY_SIZE(sof_widgets),
0313 .dapm_routes = sof_map,
0314 .num_dapm_routes = ARRAY_SIZE(sof_map),
0315 .fully_routed = true,
0316 .late_probe = sof_card_late_probe,
0317 };
0318
0319 static struct snd_soc_dai_link_component nau8825_component[] = {
0320 {
0321 .name = "i2c-10508825:00",
0322 .dai_name = "nau8825-hifi",
0323 }
0324 };
0325
0326 static struct snd_soc_dai_link_component dmic_component[] = {
0327 {
0328 .name = "dmic-codec",
0329 .dai_name = "dmic-hifi",
0330 }
0331 };
0332
0333 static struct snd_soc_dai_link_component rt1019p_component[] = {
0334 {
0335 .name = "RTL1019:00",
0336 .dai_name = "HiFi",
0337 }
0338 };
0339
0340 static struct snd_soc_dai_link_component dummy_component[] = {
0341 {
0342 .name = "snd-soc-dummy",
0343 .dai_name = "snd-soc-dummy-dai",
0344 }
0345 };
0346
0347 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
0348 int ssp_codec,
0349 int ssp_amp,
0350 int dmic_be_num,
0351 int hdmi_num)
0352 {
0353 struct snd_soc_dai_link_component *idisp_components;
0354 struct snd_soc_dai_link_component *cpus;
0355 struct snd_soc_dai_link *links;
0356 int i, id = 0;
0357
0358 links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
0359 sof_audio_card_nau8825.num_links, GFP_KERNEL);
0360 cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
0361 sof_audio_card_nau8825.num_links, GFP_KERNEL);
0362 if (!links || !cpus)
0363 goto devm_err;
0364
0365
0366 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
0367 "SSP%d-Codec", ssp_codec);
0368 if (!links[id].name)
0369 goto devm_err;
0370
0371 links[id].id = id;
0372 links[id].codecs = nau8825_component;
0373 links[id].num_codecs = ARRAY_SIZE(nau8825_component);
0374 links[id].platforms = platform_component;
0375 links[id].num_platforms = ARRAY_SIZE(platform_component);
0376 links[id].init = sof_nau8825_codec_init;
0377 links[id].exit = sof_nau8825_codec_exit;
0378 links[id].ops = &sof_nau8825_ops;
0379 links[id].dpcm_playback = 1;
0380 links[id].dpcm_capture = 1;
0381 links[id].no_pcm = 1;
0382 links[id].cpus = &cpus[id];
0383 links[id].num_cpus = 1;
0384
0385 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0386 "SSP%d Pin",
0387 ssp_codec);
0388 if (!links[id].cpus->dai_name)
0389 goto devm_err;
0390
0391 id++;
0392
0393
0394 if (dmic_be_num > 0) {
0395
0396 links[id].name = "dmic01";
0397 links[id].cpus = &cpus[id];
0398 links[id].cpus->dai_name = "DMIC01 Pin";
0399 links[id].init = dmic_init;
0400 if (dmic_be_num > 1) {
0401
0402 links[id + 1].name = "dmic16k";
0403 links[id + 1].cpus = &cpus[id + 1];
0404 links[id + 1].cpus->dai_name = "DMIC16k Pin";
0405 dmic_be_num = 2;
0406 }
0407 }
0408
0409 for (i = 0; i < dmic_be_num; i++) {
0410 links[id].id = id;
0411 links[id].num_cpus = 1;
0412 links[id].codecs = dmic_component;
0413 links[id].num_codecs = ARRAY_SIZE(dmic_component);
0414 links[id].platforms = platform_component;
0415 links[id].num_platforms = ARRAY_SIZE(platform_component);
0416 links[id].ignore_suspend = 1;
0417 links[id].dpcm_capture = 1;
0418 links[id].no_pcm = 1;
0419 id++;
0420 }
0421
0422
0423 if (hdmi_num > 0) {
0424 idisp_components = devm_kzalloc(dev,
0425 sizeof(struct snd_soc_dai_link_component) *
0426 hdmi_num, GFP_KERNEL);
0427 if (!idisp_components)
0428 goto devm_err;
0429 }
0430 for (i = 1; i <= hdmi_num; i++) {
0431 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
0432 "iDisp%d", i);
0433 if (!links[id].name)
0434 goto devm_err;
0435
0436 links[id].id = id;
0437 links[id].cpus = &cpus[id];
0438 links[id].num_cpus = 1;
0439 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0440 "iDisp%d Pin", i);
0441 if (!links[id].cpus->dai_name)
0442 goto devm_err;
0443
0444 idisp_components[i - 1].name = "ehdaudio0D2";
0445 idisp_components[i - 1].dai_name = devm_kasprintf(dev,
0446 GFP_KERNEL,
0447 "intel-hdmi-hifi%d",
0448 i);
0449 if (!idisp_components[i - 1].dai_name)
0450 goto devm_err;
0451
0452 links[id].codecs = &idisp_components[i - 1];
0453 links[id].num_codecs = 1;
0454 links[id].platforms = platform_component;
0455 links[id].num_platforms = ARRAY_SIZE(platform_component);
0456 links[id].init = sof_hdmi_init;
0457 links[id].dpcm_playback = 1;
0458 links[id].no_pcm = 1;
0459 id++;
0460 }
0461
0462
0463 if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) {
0464 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
0465 "SSP%d-Codec", ssp_amp);
0466 if (!links[id].name)
0467 goto devm_err;
0468
0469 links[id].id = id;
0470 if (sof_nau8825_quirk & SOF_RT1019P_SPEAKER_AMP_PRESENT) {
0471 links[id].codecs = rt1019p_component;
0472 links[id].num_codecs = ARRAY_SIZE(rt1019p_component);
0473 links[id].init = speaker_codec_init;
0474 } else if (sof_nau8825_quirk &
0475 SOF_MAX98373_SPEAKER_AMP_PRESENT) {
0476 links[id].codecs = max_98373_components;
0477 links[id].num_codecs = ARRAY_SIZE(max_98373_components);
0478 links[id].init = max_98373_spk_codec_init;
0479 links[id].ops = &max_98373_ops;
0480
0481 links[id].dpcm_capture = 1;
0482 } else if (sof_nau8825_quirk &
0483 SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
0484 max_98360a_dai_link(&links[id]);
0485 } else {
0486 goto devm_err;
0487 }
0488
0489 links[id].platforms = platform_component;
0490 links[id].num_platforms = ARRAY_SIZE(platform_component);
0491 links[id].dpcm_playback = 1;
0492 links[id].no_pcm = 1;
0493 links[id].cpus = &cpus[id];
0494 links[id].num_cpus = 1;
0495 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0496 "SSP%d Pin",
0497 ssp_amp);
0498 if (!links[id].cpus->dai_name)
0499 goto devm_err;
0500 id++;
0501 }
0502
0503
0504 if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
0505 int port = (sof_nau8825_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
0506 SOF_BT_OFFLOAD_SSP_SHIFT;
0507
0508 links[id].id = id;
0509 links[id].cpus = &cpus[id];
0510 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0511 "SSP%d Pin", port);
0512 if (!links[id].cpus->dai_name)
0513 goto devm_err;
0514 links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
0515 if (!links[id].name)
0516 goto devm_err;
0517 links[id].codecs = dummy_component;
0518 links[id].num_codecs = ARRAY_SIZE(dummy_component);
0519 links[id].platforms = platform_component;
0520 links[id].num_platforms = ARRAY_SIZE(platform_component);
0521 links[id].dpcm_playback = 1;
0522 links[id].dpcm_capture = 1;
0523 links[id].no_pcm = 1;
0524 links[id].num_cpus = 1;
0525 }
0526
0527 return links;
0528 devm_err:
0529 return NULL;
0530 }
0531
0532 static int sof_audio_probe(struct platform_device *pdev)
0533 {
0534 struct snd_soc_dai_link *dai_links;
0535 struct snd_soc_acpi_mach *mach;
0536 struct sof_card_private *ctx;
0537 int dmic_be_num, hdmi_num;
0538 int ret, ssp_amp, ssp_codec;
0539
0540 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
0541 if (!ctx)
0542 return -ENOMEM;
0543
0544 if (pdev->id_entry && pdev->id_entry->driver_data)
0545 sof_nau8825_quirk = (unsigned long)pdev->id_entry->driver_data;
0546
0547 mach = pdev->dev.platform_data;
0548
0549
0550
0551
0552 if ((sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
0553 sof_nau8825_quirk &= ~SOF_SPEAKER_AMP_PRESENT;
0554
0555 dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk);
0556
0557
0558 dmic_be_num = 2;
0559 hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >>
0560 SOF_NAU8825_NUM_HDMIDEV_SHIFT;
0561
0562 if (!hdmi_num)
0563 hdmi_num = 3;
0564
0565 ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >>
0566 SOF_NAU8825_SSP_AMP_SHIFT;
0567
0568 ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK;
0569
0570
0571 sof_audio_card_nau8825.num_links = 1 + dmic_be_num + hdmi_num;
0572
0573 if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT)
0574 sof_audio_card_nau8825.num_links++;
0575
0576 if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT)
0577 max_98373_set_codec_conf(&sof_audio_card_nau8825);
0578
0579 if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
0580 sof_audio_card_nau8825.num_links++;
0581
0582 dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
0583 dmic_be_num, hdmi_num);
0584 if (!dai_links)
0585 return -ENOMEM;
0586
0587 sof_audio_card_nau8825.dai_link = dai_links;
0588
0589 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
0590
0591 sof_audio_card_nau8825.dev = &pdev->dev;
0592
0593
0594 ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_nau8825,
0595 mach->mach_params.platform);
0596 if (ret)
0597 return ret;
0598
0599 snd_soc_card_set_drvdata(&sof_audio_card_nau8825, ctx);
0600
0601 return devm_snd_soc_register_card(&pdev->dev,
0602 &sof_audio_card_nau8825);
0603 }
0604
0605 static const struct platform_device_id board_ids[] = {
0606 {
0607 .name = "sof_nau8825",
0608 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
0609 SOF_NAU8825_NUM_HDMIDEV(4) |
0610 SOF_BT_OFFLOAD_SSP(2) |
0611 SOF_SSP_BT_OFFLOAD_PRESENT),
0612
0613 },
0614 {
0615 .name = "adl_rt1019p_nau8825",
0616 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
0617 SOF_SPEAKER_AMP_PRESENT |
0618 SOF_RT1019P_SPEAKER_AMP_PRESENT |
0619 SOF_NAU8825_SSP_AMP(2) |
0620 SOF_NAU8825_NUM_HDMIDEV(4)),
0621 },
0622 {
0623 .name = "adl_max98373_nau8825",
0624 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
0625 SOF_SPEAKER_AMP_PRESENT |
0626 SOF_MAX98373_SPEAKER_AMP_PRESENT |
0627 SOF_NAU8825_SSP_AMP(1) |
0628 SOF_NAU8825_NUM_HDMIDEV(4) |
0629 SOF_BT_OFFLOAD_SSP(2) |
0630 SOF_SSP_BT_OFFLOAD_PRESENT),
0631 },
0632 {
0633
0634 .name = "adl_mx98360a_nau8825",
0635 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
0636 SOF_SPEAKER_AMP_PRESENT |
0637 SOF_MAX98360A_SPEAKER_AMP_PRESENT |
0638 SOF_NAU8825_SSP_AMP(1) |
0639 SOF_NAU8825_NUM_HDMIDEV(4) |
0640 SOF_BT_OFFLOAD_SSP(2) |
0641 SOF_SSP_BT_OFFLOAD_PRESENT),
0642
0643 },
0644 { }
0645 };
0646 MODULE_DEVICE_TABLE(platform, board_ids);
0647
0648 static struct platform_driver sof_audio = {
0649 .probe = sof_audio_probe,
0650 .driver = {
0651 .name = "sof_nau8825",
0652 .pm = &snd_soc_pm_ops,
0653 },
0654 .id_table = board_ids,
0655 };
0656 module_platform_driver(sof_audio)
0657
0658
0659 MODULE_DESCRIPTION("SOF Audio Machine driver for NAU8825");
0660 MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");
0661 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
0662 MODULE_LICENSE("GPL");
0663 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
0664 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);