0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/i2c.h>
0009 #include <linux/input.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/clk.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/rt5682.h>
0021 #include <sound/rt5682s.h>
0022 #include <sound/soc-acpi.h>
0023 #include "../../codecs/rt5682.h"
0024 #include "../../codecs/rt5682s.h"
0025 #include "../../codecs/hdac_hdmi.h"
0026 #include "../common/soc-intel-quirks.h"
0027 #include "hda_dsp_common.h"
0028 #include "sof_maxim_common.h"
0029 #include "sof_realtek_common.h"
0030
0031 #define NAME_SIZE 32
0032
0033 #define SOF_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
0034 #define SOF_RT5682_SSP_CODEC_MASK (GENMASK(2, 0))
0035 #define SOF_RT5682_MCLK_EN BIT(3)
0036 #define SOF_RT5682_MCLK_24MHZ BIT(4)
0037 #define SOF_SPEAKER_AMP_PRESENT BIT(5)
0038 #define SOF_RT5682_SSP_AMP_SHIFT 6
0039 #define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6))
0040 #define SOF_RT5682_SSP_AMP(quirk) \
0041 (((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
0042 #define SOF_RT5682_MCLK_BYTCHT_EN BIT(9)
0043 #define SOF_RT5682_NUM_HDMIDEV_SHIFT 10
0044 #define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10))
0045 #define SOF_RT5682_NUM_HDMIDEV(quirk) \
0046 ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
0047 #define SOF_RT1011_SPEAKER_AMP_PRESENT BIT(13)
0048 #define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(14)
0049 #define SOF_RT1015_SPEAKER_AMP_100FS BIT(15)
0050 #define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(16)
0051 #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(17)
0052 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(18)
0053
0054
0055 #define SOF_BT_OFFLOAD_SSP_SHIFT 19
0056 #define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(21, 19))
0057 #define SOF_BT_OFFLOAD_SSP(quirk) \
0058 (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
0059 #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(22)
0060 #define SOF_RT5682S_HEADPHONE_CODEC_PRESENT BIT(23)
0061 #define SOF_MAX98390_SPEAKER_AMP_PRESENT BIT(24)
0062 #define SOF_MAX98390_TWEETER_SPEAKER_PRESENT BIT(25)
0063 #define SOF_RT1019_SPEAKER_AMP_PRESENT BIT(26)
0064
0065
0066
0067 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
0068 SOF_RT5682_SSP_CODEC(0);
0069
0070 static int is_legacy_cpu;
0071
0072 struct sof_hdmi_pcm {
0073 struct list_head head;
0074 struct snd_soc_dai *codec_dai;
0075 struct snd_soc_jack hdmi_jack;
0076 int device;
0077 };
0078
0079 struct sof_card_private {
0080 struct clk *mclk;
0081 struct snd_soc_jack sof_headset;
0082 struct list_head hdmi_pcm_list;
0083 bool common_hdmi_codec_drv;
0084 bool idisp_codec;
0085 };
0086
0087 static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
0088 {
0089 sof_rt5682_quirk = (unsigned long)id->driver_data;
0090 return 1;
0091 }
0092
0093 static const struct dmi_system_id sof_rt5682_quirk_table[] = {
0094 {
0095 .callback = sof_rt5682_quirk_cb,
0096 .matches = {
0097 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
0098 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"),
0099 },
0100 .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
0101 },
0102 {
0103 .callback = sof_rt5682_quirk_cb,
0104 .matches = {
0105 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
0106 DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"),
0107 },
0108 .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
0109 },
0110 {
0111 .callback = sof_rt5682_quirk_cb,
0112 .matches = {
0113 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
0114 DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
0115 },
0116 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0117 SOF_RT5682_MCLK_24MHZ |
0118 SOF_RT5682_SSP_CODEC(1)),
0119 },
0120 {
0121
0122
0123
0124
0125 .callback = sof_rt5682_quirk_cb,
0126 .matches = {
0127 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
0128 DMI_MATCH(DMI_PRODUCT_NAME, "Dooly"),
0129 },
0130 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0131 SOF_RT5682_MCLK_24MHZ |
0132 SOF_RT5682_SSP_CODEC(0) |
0133 SOF_SPEAKER_AMP_PRESENT |
0134 SOF_RT1015_SPEAKER_AMP_PRESENT |
0135 SOF_RT1015_SPEAKER_AMP_100FS |
0136 SOF_RT5682_SSP_AMP(1)),
0137 },
0138 {
0139 .callback = sof_rt5682_quirk_cb,
0140 .matches = {
0141 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
0142 },
0143 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0144 SOF_RT5682_MCLK_24MHZ |
0145 SOF_RT5682_SSP_CODEC(0) |
0146 SOF_SPEAKER_AMP_PRESENT |
0147 SOF_RT5682_SSP_AMP(1)),
0148 },
0149 {
0150 .callback = sof_rt5682_quirk_cb,
0151 .matches = {
0152 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
0153 DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
0154 },
0155 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0156 SOF_RT5682_SSP_CODEC(0)),
0157 },
0158 {
0159 .callback = sof_rt5682_quirk_cb,
0160 .matches = {
0161 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"),
0162 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"),
0163 },
0164 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0165 SOF_RT5682_SSP_CODEC(0) |
0166 SOF_SPEAKER_AMP_PRESENT |
0167 SOF_MAX98373_SPEAKER_AMP_PRESENT |
0168 SOF_RT5682_SSP_AMP(2) |
0169 SOF_RT5682_NUM_HDMIDEV(4)),
0170 },
0171 {
0172 .callback = sof_rt5682_quirk_cb,
0173 .matches = {
0174 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
0175 DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
0176 DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"),
0177 },
0178 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0179 SOF_RT5682_SSP_CODEC(0) |
0180 SOF_SPEAKER_AMP_PRESENT |
0181 SOF_MAX98373_SPEAKER_AMP_PRESENT |
0182 SOF_RT5682_SSP_AMP(2) |
0183 SOF_RT5682_NUM_HDMIDEV(4)),
0184 },
0185 {
0186 .callback = sof_rt5682_quirk_cb,
0187 .matches = {
0188 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
0189 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S"),
0190 },
0191 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0192 SOF_RT5682_SSP_CODEC(0) |
0193 SOF_SPEAKER_AMP_PRESENT |
0194 SOF_MAX98390_SPEAKER_AMP_PRESENT |
0195 SOF_RT5682_SSP_AMP(2) |
0196 SOF_RT5682_NUM_HDMIDEV(4)),
0197 },
0198 {
0199 .callback = sof_rt5682_quirk_cb,
0200 .matches = {
0201 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
0202 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S_4SPK"),
0203 },
0204 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0205 SOF_RT5682_SSP_CODEC(0) |
0206 SOF_SPEAKER_AMP_PRESENT |
0207 SOF_MAX98390_SPEAKER_AMP_PRESENT |
0208 SOF_MAX98390_TWEETER_SPEAKER_PRESENT |
0209 SOF_RT5682_SSP_AMP(1) |
0210 SOF_RT5682_NUM_HDMIDEV(4) |
0211 SOF_BT_OFFLOAD_SSP(2) |
0212 SOF_SSP_BT_OFFLOAD_PRESENT),
0213
0214 },
0215 {
0216 .callback = sof_rt5682_quirk_cb,
0217 .matches = {
0218 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
0219 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S_AMP_SSP2"),
0220 },
0221 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
0222 SOF_RT5682_SSP_CODEC(0) |
0223 SOF_SPEAKER_AMP_PRESENT |
0224 SOF_MAX98360A_SPEAKER_AMP_PRESENT |
0225 SOF_RT5682_SSP_AMP(2) |
0226 SOF_RT5682_NUM_HDMIDEV(4)),
0227 },
0228 {}
0229 };
0230
0231 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
0232 {
0233 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
0234 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
0235 struct sof_hdmi_pcm *pcm;
0236
0237 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
0238 if (!pcm)
0239 return -ENOMEM;
0240
0241
0242 pcm->device = rtd->dai_link->id;
0243 pcm->codec_dai = dai;
0244
0245 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
0246
0247 return 0;
0248 }
0249
0250 static struct snd_soc_jack_pin jack_pins[] = {
0251 {
0252 .pin = "Headphone Jack",
0253 .mask = SND_JACK_HEADPHONE,
0254 },
0255 {
0256 .pin = "Headset Mic",
0257 .mask = SND_JACK_MICROPHONE,
0258 },
0259 };
0260
0261 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
0262 {
0263 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
0264 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
0265 struct snd_soc_jack *jack;
0266 int ret;
0267
0268
0269 if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) &&
0270 (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) {
0271 if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
0272 rt5682s_sel_asrc_clk_src(component,
0273 RT5682S_DA_STEREO1_FILTER |
0274 RT5682S_AD_STEREO1_FILTER,
0275 RT5682S_CLK_SEL_I2S1_ASRC);
0276 else
0277 rt5682_sel_asrc_clk_src(component,
0278 RT5682_DA_STEREO1_FILTER |
0279 RT5682_AD_STEREO1_FILTER,
0280 RT5682_CLK_SEL_I2S1_ASRC);
0281 }
0282
0283 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294 ret = clk_prepare_enable(ctx->mclk);
0295 if (!ret)
0296 clk_disable_unprepare(ctx->mclk);
0297
0298 ret = clk_set_rate(ctx->mclk, 19200000);
0299
0300 if (ret)
0301 dev_err(rtd->dev, "unable to set MCLK rate\n");
0302 }
0303
0304
0305
0306
0307
0308 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
0309 SND_JACK_HEADSET | SND_JACK_BTN_0 |
0310 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
0311 SND_JACK_BTN_3,
0312 &ctx->sof_headset,
0313 jack_pins,
0314 ARRAY_SIZE(jack_pins));
0315 if (ret) {
0316 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
0317 return ret;
0318 }
0319
0320 jack = &ctx->sof_headset;
0321
0322 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0323 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0324 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0325 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0326 ret = snd_soc_component_set_jack(component, jack, NULL);
0327
0328 if (ret) {
0329 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
0330 return ret;
0331 }
0332
0333 return ret;
0334 };
0335
0336 static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd)
0337 {
0338 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
0339
0340 snd_soc_component_set_jack(component, NULL, NULL);
0341 }
0342
0343 static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
0344 struct snd_pcm_hw_params *params)
0345 {
0346 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0347 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
0348 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0349 int pll_id, pll_source, pll_in, pll_out, clk_id, ret;
0350
0351 if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
0352 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
0353 ret = clk_prepare_enable(ctx->mclk);
0354 if (ret < 0) {
0355 dev_err(rtd->dev,
0356 "could not configure MCLK state");
0357 return ret;
0358 }
0359 }
0360
0361 if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
0362 pll_source = RT5682S_PLL_S_MCLK;
0363 else
0364 pll_source = RT5682_PLL1_S_MCLK;
0365
0366
0367 pll_in = sof_dai_get_mclk(rtd);
0368
0369
0370 if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) {
0371 if (pll_in != 24000000)
0372 dev_warn(rtd->dev, "configure wrong mclk in tplg, please use 24MHz.\n");
0373 pll_in = 24000000;
0374 } else if (pll_in == 0) {
0375
0376 pll_in = 19200000;
0377 } else if (pll_in < 0) {
0378 return pll_in;
0379 }
0380 } else {
0381 if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
0382 pll_source = RT5682S_PLL_S_BCLK1;
0383 else
0384 pll_source = RT5682_PLL1_S_BCLK1;
0385
0386 pll_in = params_rate(params) * 50;
0387 }
0388
0389 if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) {
0390 pll_id = RT5682S_PLL2;
0391 clk_id = RT5682S_SCLK_S_PLL2;
0392 } else {
0393 pll_id = RT5682_PLL1;
0394 clk_id = RT5682_SCLK_S_PLL1;
0395 }
0396
0397 pll_out = params_rate(params) * 512;
0398
0399
0400 if (pll_in == pll_out)
0401 clk_id = RT5682S_SCLK_S_MCLK;
0402 else {
0403
0404 ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in,
0405 pll_out);
0406 if (ret < 0)
0407 dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
0408 }
0409
0410
0411 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id,
0412 pll_out, SND_SOC_CLOCK_IN);
0413 if (ret < 0)
0414 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
0415
0416
0417
0418
0419
0420 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
0421 params_width(params));
0422 if (ret < 0) {
0423 dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
0424 return ret;
0425 }
0426
0427 return ret;
0428 }
0429
0430 static struct snd_soc_ops sof_rt5682_ops = {
0431 .hw_params = sof_rt5682_hw_params,
0432 };
0433
0434 static struct snd_soc_dai_link_component platform_component[] = {
0435 {
0436
0437 .name = "0000:00:1f.3"
0438 }
0439 };
0440
0441 static int sof_card_late_probe(struct snd_soc_card *card)
0442 {
0443 struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
0444 struct snd_soc_component *component = NULL;
0445 struct snd_soc_dapm_context *dapm = &card->dapm;
0446 char jack_name[NAME_SIZE];
0447 struct sof_hdmi_pcm *pcm;
0448 int err;
0449
0450 if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
0451
0452 snd_soc_dapm_disable_pin(dapm, "Left Spk");
0453 snd_soc_dapm_disable_pin(dapm, "Right Spk");
0454 err = snd_soc_dapm_sync(dapm);
0455 if (err < 0)
0456 return err;
0457 }
0458
0459
0460 if (is_legacy_cpu || !ctx->idisp_codec)
0461 return 0;
0462
0463 if (list_empty(&ctx->hdmi_pcm_list))
0464 return -EINVAL;
0465
0466 if (ctx->common_hdmi_codec_drv) {
0467 pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
0468 head);
0469 component = pcm->codec_dai->component;
0470 return hda_dsp_hdmi_build_controls(card, component);
0471 }
0472
0473 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
0474 component = pcm->codec_dai->component;
0475 snprintf(jack_name, sizeof(jack_name),
0476 "HDMI/DP, pcm=%d Jack", pcm->device);
0477 err = snd_soc_card_jack_new(card, jack_name,
0478 SND_JACK_AVOUT, &pcm->hdmi_jack);
0479
0480 if (err)
0481 return err;
0482
0483 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
0484 &pcm->hdmi_jack);
0485 if (err < 0)
0486 return err;
0487 }
0488
0489 return hdac_hdmi_jack_port_init(component, &card->dapm);
0490 }
0491
0492 static const struct snd_kcontrol_new sof_controls[] = {
0493 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
0494 SOC_DAPM_PIN_SWITCH("Headset Mic"),
0495 SOC_DAPM_PIN_SWITCH("Left Spk"),
0496 SOC_DAPM_PIN_SWITCH("Right Spk"),
0497
0498 };
0499
0500 static const struct snd_soc_dapm_widget sof_widgets[] = {
0501 SND_SOC_DAPM_HP("Headphone Jack", NULL),
0502 SND_SOC_DAPM_MIC("Headset Mic", NULL),
0503 SND_SOC_DAPM_SPK("Left Spk", NULL),
0504 SND_SOC_DAPM_SPK("Right Spk", NULL),
0505 };
0506
0507 static const struct snd_soc_dapm_widget dmic_widgets[] = {
0508 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
0509 };
0510
0511 static const struct snd_soc_dapm_route sof_map[] = {
0512
0513 { "Headphone Jack", NULL, "HPOL" },
0514 { "Headphone Jack", NULL, "HPOR" },
0515
0516
0517 { "IN1P", NULL, "Headset Mic" },
0518 };
0519
0520 static const struct snd_soc_dapm_route dmic_map[] = {
0521
0522 {"DMic", NULL, "SoC DMIC"},
0523 };
0524
0525 static int dmic_init(struct snd_soc_pcm_runtime *rtd)
0526 {
0527 struct snd_soc_card *card = rtd->card;
0528 int ret;
0529
0530 ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
0531 ARRAY_SIZE(dmic_widgets));
0532 if (ret) {
0533 dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
0534
0535 return ret;
0536 }
0537
0538 ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
0539 ARRAY_SIZE(dmic_map));
0540
0541 if (ret)
0542 dev_err(card->dev, "DMic map addition failed: %d\n", ret);
0543
0544 return ret;
0545 }
0546
0547
0548 static struct snd_soc_card sof_audio_card_rt5682 = {
0549 .name = "rt5682",
0550 .owner = THIS_MODULE,
0551 .controls = sof_controls,
0552 .num_controls = ARRAY_SIZE(sof_controls),
0553 .dapm_widgets = sof_widgets,
0554 .num_dapm_widgets = ARRAY_SIZE(sof_widgets),
0555 .dapm_routes = sof_map,
0556 .num_dapm_routes = ARRAY_SIZE(sof_map),
0557 .fully_routed = true,
0558 .late_probe = sof_card_late_probe,
0559 };
0560
0561 static struct snd_soc_dai_link_component rt5682_component[] = {
0562 {
0563 .name = "i2c-10EC5682:00",
0564 .dai_name = "rt5682-aif1",
0565 }
0566 };
0567
0568 static struct snd_soc_dai_link_component rt5682s_component[] = {
0569 {
0570 .name = "i2c-RTL5682:00",
0571 .dai_name = "rt5682s-aif1",
0572 }
0573 };
0574
0575 static struct snd_soc_dai_link_component dmic_component[] = {
0576 {
0577 .name = "dmic-codec",
0578 .dai_name = "dmic-hifi",
0579 }
0580 };
0581
0582 static struct snd_soc_dai_link_component dummy_component[] = {
0583 {
0584 .name = "snd-soc-dummy",
0585 .dai_name = "snd-soc-dummy-dai",
0586 }
0587 };
0588
0589 #define IDISP_CODEC_MASK 0x4
0590
0591 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
0592 int ssp_codec,
0593 int ssp_amp,
0594 int dmic_be_num,
0595 int hdmi_num,
0596 bool idisp_codec)
0597 {
0598 struct snd_soc_dai_link_component *idisp_components;
0599 struct snd_soc_dai_link_component *cpus;
0600 struct snd_soc_dai_link *links;
0601 int i, id = 0;
0602
0603 links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
0604 sof_audio_card_rt5682.num_links, GFP_KERNEL);
0605 cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
0606 sof_audio_card_rt5682.num_links, GFP_KERNEL);
0607 if (!links || !cpus)
0608 goto devm_err;
0609
0610
0611 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
0612 "SSP%d-Codec", ssp_codec);
0613 if (!links[id].name)
0614 goto devm_err;
0615
0616 links[id].id = id;
0617 if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) {
0618 links[id].codecs = rt5682s_component;
0619 links[id].num_codecs = ARRAY_SIZE(rt5682s_component);
0620 } else {
0621 links[id].codecs = rt5682_component;
0622 links[id].num_codecs = ARRAY_SIZE(rt5682_component);
0623 }
0624 links[id].platforms = platform_component;
0625 links[id].num_platforms = ARRAY_SIZE(platform_component);
0626 links[id].init = sof_rt5682_codec_init;
0627 links[id].exit = sof_rt5682_codec_exit;
0628 links[id].ops = &sof_rt5682_ops;
0629 links[id].dpcm_playback = 1;
0630 links[id].dpcm_capture = 1;
0631 links[id].no_pcm = 1;
0632 links[id].cpus = &cpus[id];
0633 links[id].num_cpus = 1;
0634 if (is_legacy_cpu) {
0635 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0636 "ssp%d-port",
0637 ssp_codec);
0638 if (!links[id].cpus->dai_name)
0639 goto devm_err;
0640 } else {
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650 links[id].ignore_pmdown_time = 1;
0651 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0652 "SSP%d Pin",
0653 ssp_codec);
0654 if (!links[id].cpus->dai_name)
0655 goto devm_err;
0656 }
0657 id++;
0658
0659
0660 if (dmic_be_num > 0) {
0661
0662 links[id].name = "dmic01";
0663 links[id].cpus = &cpus[id];
0664 links[id].cpus->dai_name = "DMIC01 Pin";
0665 links[id].init = dmic_init;
0666 if (dmic_be_num > 1) {
0667
0668 links[id + 1].name = "dmic16k";
0669 links[id + 1].cpus = &cpus[id + 1];
0670 links[id + 1].cpus->dai_name = "DMIC16k Pin";
0671 dmic_be_num = 2;
0672 }
0673 }
0674
0675 for (i = 0; i < dmic_be_num; i++) {
0676 links[id].id = id;
0677 links[id].num_cpus = 1;
0678 links[id].codecs = dmic_component;
0679 links[id].num_codecs = ARRAY_SIZE(dmic_component);
0680 links[id].platforms = platform_component;
0681 links[id].num_platforms = ARRAY_SIZE(platform_component);
0682 links[id].ignore_suspend = 1;
0683 links[id].dpcm_capture = 1;
0684 links[id].no_pcm = 1;
0685 id++;
0686 }
0687
0688
0689 if (hdmi_num > 0) {
0690 idisp_components = devm_kzalloc(dev,
0691 sizeof(struct snd_soc_dai_link_component) *
0692 hdmi_num, GFP_KERNEL);
0693 if (!idisp_components)
0694 goto devm_err;
0695 }
0696 for (i = 1; i <= hdmi_num; i++) {
0697 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
0698 "iDisp%d", i);
0699 if (!links[id].name)
0700 goto devm_err;
0701
0702 links[id].id = id;
0703 links[id].cpus = &cpus[id];
0704 links[id].num_cpus = 1;
0705 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0706 "iDisp%d Pin", i);
0707 if (!links[id].cpus->dai_name)
0708 goto devm_err;
0709
0710 if (idisp_codec) {
0711 idisp_components[i - 1].name = "ehdaudio0D2";
0712 idisp_components[i - 1].dai_name = devm_kasprintf(dev,
0713 GFP_KERNEL,
0714 "intel-hdmi-hifi%d",
0715 i);
0716 if (!idisp_components[i - 1].dai_name)
0717 goto devm_err;
0718 } else {
0719 idisp_components[i - 1].name = "snd-soc-dummy";
0720 idisp_components[i - 1].dai_name = "snd-soc-dummy-dai";
0721 }
0722
0723 links[id].codecs = &idisp_components[i - 1];
0724 links[id].num_codecs = 1;
0725 links[id].platforms = platform_component;
0726 links[id].num_platforms = ARRAY_SIZE(platform_component);
0727 links[id].init = sof_hdmi_init;
0728 links[id].dpcm_playback = 1;
0729 links[id].no_pcm = 1;
0730 id++;
0731 }
0732
0733
0734 if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) {
0735 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
0736 "SSP%d-Codec", ssp_amp);
0737 if (!links[id].name)
0738 goto devm_err;
0739
0740 links[id].id = id;
0741 if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) {
0742 sof_rt1015_dai_link(&links[id], (sof_rt5682_quirk &
0743 SOF_RT1015_SPEAKER_AMP_100FS) ? 100 : 64);
0744 } else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) {
0745 sof_rt1015p_dai_link(&links[id]);
0746 } else if (sof_rt5682_quirk & SOF_RT1019_SPEAKER_AMP_PRESENT) {
0747 sof_rt1019p_dai_link(&links[id]);
0748 } else if (sof_rt5682_quirk &
0749 SOF_MAX98373_SPEAKER_AMP_PRESENT) {
0750 links[id].codecs = max_98373_components;
0751 links[id].num_codecs = ARRAY_SIZE(max_98373_components);
0752 links[id].init = max_98373_spk_codec_init;
0753 links[id].ops = &max_98373_ops;
0754
0755 links[id].dpcm_capture = 1;
0756 } else if (sof_rt5682_quirk &
0757 SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
0758 max_98360a_dai_link(&links[id]);
0759 } else if (sof_rt5682_quirk &
0760 SOF_RT1011_SPEAKER_AMP_PRESENT) {
0761 sof_rt1011_dai_link(&links[id]);
0762 } else if (sof_rt5682_quirk &
0763 SOF_MAX98390_SPEAKER_AMP_PRESENT) {
0764 if (sof_rt5682_quirk &
0765 SOF_MAX98390_TWEETER_SPEAKER_PRESENT) {
0766 links[id].codecs = max_98390_4spk_components;
0767 links[id].num_codecs = ARRAY_SIZE(max_98390_4spk_components);
0768 } else {
0769 links[id].codecs = max_98390_components;
0770 links[id].num_codecs = ARRAY_SIZE(max_98390_components);
0771 }
0772 links[id].init = max_98390_spk_codec_init;
0773 links[id].ops = &max_98390_ops;
0774 links[id].dpcm_capture = 1;
0775
0776 } else {
0777 max_98357a_dai_link(&links[id]);
0778 }
0779 links[id].platforms = platform_component;
0780 links[id].num_platforms = ARRAY_SIZE(platform_component);
0781 links[id].dpcm_playback = 1;
0782 links[id].no_pcm = 1;
0783 links[id].cpus = &cpus[id];
0784 links[id].num_cpus = 1;
0785 if (is_legacy_cpu) {
0786 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0787 "ssp%d-port",
0788 ssp_amp);
0789 if (!links[id].cpus->dai_name)
0790 goto devm_err;
0791
0792 } else {
0793 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0794 "SSP%d Pin",
0795 ssp_amp);
0796 if (!links[id].cpus->dai_name)
0797 goto devm_err;
0798 }
0799 id++;
0800 }
0801
0802
0803 if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
0804 int port = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
0805 SOF_BT_OFFLOAD_SSP_SHIFT;
0806
0807 links[id].id = id;
0808 links[id].cpus = &cpus[id];
0809 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
0810 "SSP%d Pin", port);
0811 if (!links[id].cpus->dai_name)
0812 goto devm_err;
0813 links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
0814 if (!links[id].name)
0815 goto devm_err;
0816 links[id].codecs = dummy_component;
0817 links[id].num_codecs = ARRAY_SIZE(dummy_component);
0818 links[id].platforms = platform_component;
0819 links[id].num_platforms = ARRAY_SIZE(platform_component);
0820 links[id].dpcm_playback = 1;
0821 links[id].dpcm_capture = 1;
0822 links[id].no_pcm = 1;
0823 links[id].num_cpus = 1;
0824 }
0825
0826 return links;
0827 devm_err:
0828 return NULL;
0829 }
0830
0831 static int sof_audio_probe(struct platform_device *pdev)
0832 {
0833 struct snd_soc_dai_link *dai_links;
0834 struct snd_soc_acpi_mach *mach;
0835 struct sof_card_private *ctx;
0836 int dmic_be_num, hdmi_num;
0837 int ret, ssp_amp, ssp_codec;
0838
0839 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
0840 if (!ctx)
0841 return -ENOMEM;
0842
0843 if (pdev->id_entry && pdev->id_entry->driver_data)
0844 sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
0845
0846 dmi_check_system(sof_rt5682_quirk_table);
0847
0848 mach = pdev->dev.platform_data;
0849
0850
0851
0852
0853 if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
0854 sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT;
0855
0856
0857 if (acpi_dev_present("RTL5682", NULL, -1))
0858 sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT;
0859
0860
0861 if (acpi_dev_present("RTL5682", NULL, -1))
0862 sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT;
0863
0864 if (soc_intel_is_byt() || soc_intel_is_cht()) {
0865 is_legacy_cpu = 1;
0866 dmic_be_num = 0;
0867 hdmi_num = 0;
0868
0869 sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
0870 SOF_RT5682_MCLK_BYTCHT_EN |
0871 SOF_RT5682_SSP_CODEC(2);
0872 } else {
0873 dmic_be_num = 2;
0874 hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
0875 SOF_RT5682_NUM_HDMIDEV_SHIFT;
0876
0877 if (!hdmi_num)
0878 hdmi_num = 3;
0879
0880 if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
0881 ctx->idisp_codec = true;
0882 }
0883
0884
0885 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
0886 ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
0887 if (IS_ERR(ctx->mclk)) {
0888 ret = PTR_ERR(ctx->mclk);
0889
0890 dev_err(&pdev->dev,
0891 "Failed to get MCLK from pmc_plt_clk_3: %d\n",
0892 ret);
0893 return ret;
0894 }
0895
0896 ret = clk_prepare_enable(ctx->mclk);
0897 if (ret < 0) {
0898 dev_err(&pdev->dev,
0899 "could not configure MCLK state");
0900 return ret;
0901 }
0902 }
0903
0904 dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
0905
0906 ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
0907 SOF_RT5682_SSP_AMP_SHIFT;
0908
0909 ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
0910
0911
0912 sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
0913
0914 if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT)
0915 sof_audio_card_rt5682.num_links++;
0916
0917 if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT)
0918 max_98373_set_codec_conf(&sof_audio_card_rt5682);
0919 else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT)
0920 sof_rt1011_codec_conf(&sof_audio_card_rt5682);
0921 else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT)
0922 sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
0923 else if (sof_rt5682_quirk & SOF_MAX98390_SPEAKER_AMP_PRESENT) {
0924 if (sof_rt5682_quirk & SOF_MAX98390_TWEETER_SPEAKER_PRESENT)
0925 max_98390_set_codec_conf(&sof_audio_card_rt5682,
0926 ARRAY_SIZE(max_98390_4spk_components));
0927 else
0928 max_98390_set_codec_conf(&sof_audio_card_rt5682,
0929 ARRAY_SIZE(max_98390_components));
0930 }
0931
0932 if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
0933 sof_audio_card_rt5682.num_links++;
0934
0935 dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
0936 dmic_be_num, hdmi_num, ctx->idisp_codec);
0937 if (!dai_links)
0938 return -ENOMEM;
0939
0940 sof_audio_card_rt5682.dai_link = dai_links;
0941
0942 if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT)
0943 sof_rt1015_codec_conf(&sof_audio_card_rt5682);
0944
0945 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
0946
0947 sof_audio_card_rt5682.dev = &pdev->dev;
0948
0949
0950 ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
0951 mach->mach_params.platform);
0952 if (ret)
0953 return ret;
0954
0955 ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
0956
0957 snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
0958
0959 return devm_snd_soc_register_card(&pdev->dev,
0960 &sof_audio_card_rt5682);
0961 }
0962
0963 static const struct platform_device_id board_ids[] = {
0964 {
0965 .name = "sof_rt5682",
0966 },
0967 {
0968 .name = "tgl_mx98357_rt5682",
0969 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
0970 SOF_RT5682_SSP_CODEC(0) |
0971 SOF_SPEAKER_AMP_PRESENT |
0972 SOF_RT5682_SSP_AMP(1) |
0973 SOF_RT5682_NUM_HDMIDEV(4) |
0974 SOF_BT_OFFLOAD_SSP(2) |
0975 SOF_SSP_BT_OFFLOAD_PRESENT),
0976 },
0977 {
0978 .name = "jsl_rt5682_rt1015",
0979 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
0980 SOF_RT5682_MCLK_24MHZ |
0981 SOF_RT5682_SSP_CODEC(0) |
0982 SOF_SPEAKER_AMP_PRESENT |
0983 SOF_RT1015_SPEAKER_AMP_PRESENT |
0984 SOF_RT5682_SSP_AMP(1)),
0985 },
0986 {
0987 .name = "tgl_mx98373_rt5682",
0988 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
0989 SOF_RT5682_SSP_CODEC(0) |
0990 SOF_SPEAKER_AMP_PRESENT |
0991 SOF_MAX98373_SPEAKER_AMP_PRESENT |
0992 SOF_RT5682_SSP_AMP(1) |
0993 SOF_RT5682_NUM_HDMIDEV(4) |
0994 SOF_BT_OFFLOAD_SSP(2) |
0995 SOF_SSP_BT_OFFLOAD_PRESENT),
0996 },
0997 {
0998 .name = "jsl_rt5682_mx98360",
0999 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1000 SOF_RT5682_MCLK_24MHZ |
1001 SOF_RT5682_SSP_CODEC(0) |
1002 SOF_SPEAKER_AMP_PRESENT |
1003 SOF_MAX98360A_SPEAKER_AMP_PRESENT |
1004 SOF_RT5682_SSP_AMP(1)),
1005 },
1006 {
1007 .name = "cml_rt1015_rt5682",
1008 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1009 SOF_RT5682_MCLK_24MHZ |
1010 SOF_RT5682_SSP_CODEC(0) |
1011 SOF_SPEAKER_AMP_PRESENT |
1012 SOF_RT1015_SPEAKER_AMP_PRESENT |
1013 SOF_RT1015_SPEAKER_AMP_100FS |
1014 SOF_RT5682_SSP_AMP(1)),
1015 },
1016 {
1017 .name = "tgl_rt1011_rt5682",
1018 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1019 SOF_RT5682_SSP_CODEC(0) |
1020 SOF_SPEAKER_AMP_PRESENT |
1021 SOF_RT1011_SPEAKER_AMP_PRESENT |
1022 SOF_RT5682_SSP_AMP(1) |
1023 SOF_RT5682_NUM_HDMIDEV(4) |
1024 SOF_BT_OFFLOAD_SSP(2) |
1025 SOF_SSP_BT_OFFLOAD_PRESENT),
1026 },
1027 {
1028 .name = "jsl_rt5682_rt1015p",
1029 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1030 SOF_RT5682_MCLK_24MHZ |
1031 SOF_RT5682_SSP_CODEC(0) |
1032 SOF_SPEAKER_AMP_PRESENT |
1033 SOF_RT1015P_SPEAKER_AMP_PRESENT |
1034 SOF_RT5682_SSP_AMP(1)),
1035 },
1036 {
1037 .name = "adl_mx98373_rt5682",
1038 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1039 SOF_RT5682_SSP_CODEC(0) |
1040 SOF_SPEAKER_AMP_PRESENT |
1041 SOF_MAX98373_SPEAKER_AMP_PRESENT |
1042 SOF_RT5682_SSP_AMP(1) |
1043 SOF_RT5682_NUM_HDMIDEV(4) |
1044 SOF_BT_OFFLOAD_SSP(2) |
1045 SOF_SSP_BT_OFFLOAD_PRESENT),
1046 },
1047 {
1048 .name = "adl_mx98357_rt5682",
1049 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1050 SOF_RT5682_SSP_CODEC(0) |
1051 SOF_SPEAKER_AMP_PRESENT |
1052 SOF_RT5682_SSP_AMP(2) |
1053 SOF_RT5682_NUM_HDMIDEV(4)),
1054 },
1055 {
1056 .name = "adl_max98390_rt5682",
1057 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1058 SOF_RT5682_SSP_CODEC(0) |
1059 SOF_SPEAKER_AMP_PRESENT |
1060 SOF_MAX98390_SPEAKER_AMP_PRESENT |
1061 SOF_RT5682_SSP_AMP(1) |
1062 SOF_RT5682_NUM_HDMIDEV(4) |
1063 SOF_BT_OFFLOAD_SSP(2) |
1064 SOF_SSP_BT_OFFLOAD_PRESENT),
1065 },
1066 {
1067 .name = "adl_mx98360_rt5682",
1068 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1069 SOF_RT5682_SSP_CODEC(0) |
1070 SOF_SPEAKER_AMP_PRESENT |
1071 SOF_MAX98360A_SPEAKER_AMP_PRESENT |
1072 SOF_RT5682_SSP_AMP(1) |
1073 SOF_RT5682_NUM_HDMIDEV(4) |
1074 SOF_BT_OFFLOAD_SSP(2) |
1075 SOF_SSP_BT_OFFLOAD_PRESENT),
1076 },
1077 {
1078 .name = "adl_rt5682",
1079 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1080 SOF_RT5682_SSP_CODEC(0) |
1081 SOF_RT5682_NUM_HDMIDEV(4) |
1082 SOF_BT_OFFLOAD_SSP(2) |
1083 SOF_SSP_BT_OFFLOAD_PRESENT),
1084 },
1085 {
1086 .name = "adl_rt1019_rt5682s",
1087 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1088 SOF_RT5682_SSP_CODEC(0) |
1089 SOF_RT5682S_HEADPHONE_CODEC_PRESENT |
1090 SOF_SPEAKER_AMP_PRESENT |
1091 SOF_RT1019_SPEAKER_AMP_PRESENT |
1092 SOF_RT5682_SSP_AMP(1) |
1093 SOF_RT5682_NUM_HDMIDEV(4)),
1094 },
1095 {
1096 .name = "mtl_mx98357_rt5682",
1097 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1098 SOF_RT5682_SSP_CODEC(0) |
1099 SOF_SPEAKER_AMP_PRESENT |
1100 SOF_RT5682_SSP_AMP(1) |
1101 SOF_RT5682_NUM_HDMIDEV(4)),
1102 },
1103 { }
1104 };
1105 MODULE_DEVICE_TABLE(platform, board_ids);
1106
1107 static struct platform_driver sof_audio = {
1108 .probe = sof_audio_probe,
1109 .driver = {
1110 .name = "sof_rt5682",
1111 .pm = &snd_soc_pm_ops,
1112 },
1113 .id_table = board_ids,
1114 };
1115 module_platform_driver(sof_audio)
1116
1117
1118 MODULE_DESCRIPTION("SOF Audio Machine driver");
1119 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
1120 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
1121 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
1122 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
1123 MODULE_LICENSE("GPL v2");
1124 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
1125 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
1126 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);