This source file includes following definitions.
- sof_rt5682_quirk_cb
- sof_hdmi_init
- sof_rt5682_codec_init
- sof_rt5682_hw_params
- sof_card_late_probe
- speaker_codec_init
- dmic_init
- sof_card_dai_links_create
- sof_audio_probe
- sof_rt5682_remove
1
2
3
4
5
6
7
8 #include <linux/i2c.h>
9 #include <linux/input.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/clk.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/rt5682.h>
20 #include <sound/soc-acpi.h>
21 #include "../../codecs/rt5682.h"
22 #include "../../codecs/hdac_hdmi.h"
23 #include "../common/soc-intel-quirks.h"
24
25 #define NAME_SIZE 32
26
27 #define SOF_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
28 #define SOF_RT5682_SSP_CODEC_MASK (GENMASK(2, 0))
29 #define SOF_RT5682_MCLK_EN BIT(3)
30 #define SOF_RT5682_MCLK_24MHZ BIT(4)
31 #define SOF_SPEAKER_AMP_PRESENT BIT(5)
32 #define SOF_RT5682_SSP_AMP_SHIFT 6
33 #define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6))
34 #define SOF_RT5682_SSP_AMP(quirk) \
35 (((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
36 #define SOF_RT5682_MCLK_BYTCHT_EN BIT(9)
37 #define SOF_RT5682_NUM_HDMIDEV_SHIFT 10
38 #define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10))
39 #define SOF_RT5682_NUM_HDMIDEV(quirk) \
40 ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
41
42
43 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
44 SOF_RT5682_SSP_CODEC(0);
45
46 static int is_legacy_cpu;
47
48 static struct snd_soc_jack sof_hdmi[3];
49
50 struct sof_hdmi_pcm {
51 struct list_head head;
52 struct snd_soc_dai *codec_dai;
53 int device;
54 };
55
56 struct sof_card_private {
57 struct clk *mclk;
58 struct snd_soc_jack sof_headset;
59 struct list_head hdmi_pcm_list;
60 };
61
62 static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
63 {
64 sof_rt5682_quirk = (unsigned long)id->driver_data;
65 return 1;
66 }
67
68 static const struct dmi_system_id sof_rt5682_quirk_table[] = {
69 {
70 .callback = sof_rt5682_quirk_cb,
71 .matches = {
72 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
73 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"),
74 },
75 .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
76 },
77 {
78 .callback = sof_rt5682_quirk_cb,
79 .matches = {
80 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
81 DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"),
82 },
83 .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
84 },
85 {
86 .callback = sof_rt5682_quirk_cb,
87 .matches = {
88 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
89 DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
90 },
91 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
92 SOF_RT5682_MCLK_24MHZ |
93 SOF_RT5682_SSP_CODEC(1)),
94 },
95 {
96 .callback = sof_rt5682_quirk_cb,
97 .matches = {
98 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
99 },
100 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
101 SOF_RT5682_MCLK_24MHZ |
102 SOF_RT5682_SSP_CODEC(0) |
103 SOF_SPEAKER_AMP_PRESENT |
104 SOF_RT5682_SSP_AMP(1)),
105 },
106 {
107 .callback = sof_rt5682_quirk_cb,
108 .matches = {
109 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
110 DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
111 },
112 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
113 SOF_RT5682_SSP_CODEC(0)),
114 },
115 {}
116 };
117
118 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
119 {
120 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
121 struct snd_soc_dai *dai = rtd->codec_dai;
122 struct sof_hdmi_pcm *pcm;
123
124 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
125 if (!pcm)
126 return -ENOMEM;
127
128
129 pcm->device = rtd->dai_link->id;
130 pcm->codec_dai = dai;
131
132 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
133
134 return 0;
135 }
136
137 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
138 {
139 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
140 struct snd_soc_component *component = rtd->codec_dai->component;
141 struct snd_soc_jack *jack;
142 int ret;
143
144
145 if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) &&
146 (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) {
147 rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER |
148 RT5682_AD_STEREO1_FILTER,
149 RT5682_CLK_SEL_I2S1_ASRC);
150 }
151
152 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
153
154
155
156
157
158
159
160
161
162
163 ret = clk_prepare_enable(ctx->mclk);
164 if (!ret)
165 clk_disable_unprepare(ctx->mclk);
166
167 ret = clk_set_rate(ctx->mclk, 19200000);
168
169 if (ret)
170 dev_err(rtd->dev, "unable to set MCLK rate\n");
171 }
172
173
174
175
176
177 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
178 SND_JACK_HEADSET | SND_JACK_BTN_0 |
179 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
180 SND_JACK_BTN_3,
181 &ctx->sof_headset, NULL, 0);
182 if (ret) {
183 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
184 return ret;
185 }
186
187 jack = &ctx->sof_headset;
188
189 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
190 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
191 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
192 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
193 ret = snd_soc_component_set_jack(component, jack, NULL);
194
195 if (ret) {
196 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
197 return ret;
198 }
199
200 return ret;
201 };
202
203 static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
204 struct snd_pcm_hw_params *params)
205 {
206 struct snd_soc_pcm_runtime *rtd = substream->private_data;
207 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
208 struct snd_soc_dai *codec_dai = rtd->codec_dai;
209 int clk_id, clk_freq, pll_out, ret;
210
211 if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
212 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
213 ret = clk_prepare_enable(ctx->mclk);
214 if (ret < 0) {
215 dev_err(rtd->dev,
216 "could not configure MCLK state");
217 return ret;
218 }
219 }
220
221 clk_id = RT5682_PLL1_S_MCLK;
222 if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)
223 clk_freq = 24000000;
224 else
225 clk_freq = 19200000;
226 } else {
227 clk_id = RT5682_PLL1_S_BCLK1;
228 clk_freq = params_rate(params) * 50;
229 }
230
231 pll_out = params_rate(params) * 512;
232
233 ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
234 if (ret < 0)
235 dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
236
237
238 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
239 pll_out, SND_SOC_CLOCK_IN);
240 if (ret < 0)
241 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
242
243
244
245
246
247 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
248 params_width(params));
249 if (ret < 0) {
250 dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
251 return ret;
252 }
253
254 return ret;
255 }
256
257 static struct snd_soc_ops sof_rt5682_ops = {
258 .hw_params = sof_rt5682_hw_params,
259 };
260
261 static struct snd_soc_dai_link_component platform_component[] = {
262 {
263
264 .name = "0000:00:1f.3"
265 }
266 };
267
268 static int sof_card_late_probe(struct snd_soc_card *card)
269 {
270 struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
271 struct snd_soc_component *component = NULL;
272 char jack_name[NAME_SIZE];
273 struct sof_hdmi_pcm *pcm;
274 int err = 0;
275 int i = 0;
276
277
278 if (is_legacy_cpu)
279 return 0;
280
281 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
282 component = pcm->codec_dai->component;
283 snprintf(jack_name, sizeof(jack_name),
284 "HDMI/DP, pcm=%d Jack", pcm->device);
285 err = snd_soc_card_jack_new(card, jack_name,
286 SND_JACK_AVOUT, &sof_hdmi[i],
287 NULL, 0);
288
289 if (err)
290 return err;
291
292 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
293 &sof_hdmi[i]);
294 if (err < 0)
295 return err;
296
297 i++;
298 }
299 if (!component)
300 return -EINVAL;
301
302 return hdac_hdmi_jack_port_init(component, &card->dapm);
303 }
304
305 static const struct snd_kcontrol_new sof_controls[] = {
306 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
307 SOC_DAPM_PIN_SWITCH("Headset Mic"),
308 SOC_DAPM_PIN_SWITCH("Spk"),
309 };
310
311 static const struct snd_soc_dapm_widget sof_widgets[] = {
312 SND_SOC_DAPM_HP("Headphone Jack", NULL),
313 SND_SOC_DAPM_MIC("Headset Mic", NULL),
314 SND_SOC_DAPM_SPK("Spk", NULL),
315 };
316
317 static const struct snd_soc_dapm_widget dmic_widgets[] = {
318 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
319 };
320
321 static const struct snd_soc_dapm_route sof_map[] = {
322
323 { "Headphone Jack", NULL, "HPOL" },
324 { "Headphone Jack", NULL, "HPOR" },
325
326
327 { "IN1P", NULL, "Headset Mic" },
328 };
329
330 static const struct snd_soc_dapm_route speaker_map[] = {
331
332 { "Spk", NULL, "Speaker" },
333 };
334
335 static const struct snd_soc_dapm_route dmic_map[] = {
336
337 {"DMic", NULL, "SoC DMIC"},
338 };
339
340 static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
341 {
342 struct snd_soc_card *card = rtd->card;
343 int ret;
344
345 ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map,
346 ARRAY_SIZE(speaker_map));
347
348 if (ret)
349 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
350 return ret;
351 }
352
353 static int dmic_init(struct snd_soc_pcm_runtime *rtd)
354 {
355 struct snd_soc_card *card = rtd->card;
356 int ret;
357
358 ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
359 ARRAY_SIZE(dmic_widgets));
360 if (ret) {
361 dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
362
363 return ret;
364 }
365
366 ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
367 ARRAY_SIZE(dmic_map));
368
369 if (ret)
370 dev_err(card->dev, "DMic map addition failed: %d\n", ret);
371
372 return ret;
373 }
374
375
376 static struct snd_soc_card sof_audio_card_rt5682 = {
377 .name = "rt5682",
378 .owner = THIS_MODULE,
379 .controls = sof_controls,
380 .num_controls = ARRAY_SIZE(sof_controls),
381 .dapm_widgets = sof_widgets,
382 .num_dapm_widgets = ARRAY_SIZE(sof_widgets),
383 .dapm_routes = sof_map,
384 .num_dapm_routes = ARRAY_SIZE(sof_map),
385 .fully_routed = true,
386 .late_probe = sof_card_late_probe,
387 };
388
389 static struct snd_soc_dai_link_component rt5682_component[] = {
390 {
391 .name = "i2c-10EC5682:00",
392 .dai_name = "rt5682-aif1",
393 }
394 };
395
396 static struct snd_soc_dai_link_component dmic_component[] = {
397 {
398 .name = "dmic-codec",
399 .dai_name = "dmic-hifi",
400 }
401 };
402
403 static struct snd_soc_dai_link_component max98357a_component[] = {
404 {
405 .name = "MX98357A:00",
406 .dai_name = "HiFi",
407 }
408 };
409
410 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
411 int ssp_codec,
412 int ssp_amp,
413 int dmic_be_num,
414 int hdmi_num)
415 {
416 struct snd_soc_dai_link_component *idisp_components;
417 struct snd_soc_dai_link_component *cpus;
418 struct snd_soc_dai_link *links;
419 int i, id = 0;
420
421 links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
422 sof_audio_card_rt5682.num_links, GFP_KERNEL);
423 cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
424 sof_audio_card_rt5682.num_links, GFP_KERNEL);
425 if (!links || !cpus)
426 goto devm_err;
427
428
429 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
430 "SSP%d-Codec", ssp_codec);
431 if (!links[id].name)
432 goto devm_err;
433
434 links[id].id = id;
435 links[id].codecs = rt5682_component;
436 links[id].num_codecs = ARRAY_SIZE(rt5682_component);
437 links[id].platforms = platform_component;
438 links[id].num_platforms = ARRAY_SIZE(platform_component);
439 links[id].init = sof_rt5682_codec_init;
440 links[id].ops = &sof_rt5682_ops;
441 links[id].nonatomic = true;
442 links[id].dpcm_playback = 1;
443 links[id].dpcm_capture = 1;
444 links[id].no_pcm = 1;
445 links[id].cpus = &cpus[id];
446 links[id].num_cpus = 1;
447 if (is_legacy_cpu) {
448 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
449 "ssp%d-port",
450 ssp_codec);
451 if (!links[id].cpus->dai_name)
452 goto devm_err;
453 } else {
454
455
456
457
458
459
460
461
462
463 links[id].ignore_pmdown_time = 1;
464 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
465 "SSP%d Pin",
466 ssp_codec);
467 if (!links[id].cpus->dai_name)
468 goto devm_err;
469 }
470 id++;
471
472
473 if (dmic_be_num > 0) {
474
475 links[id].name = "dmic01";
476 links[id].cpus = &cpus[id];
477 links[id].cpus->dai_name = "DMIC01 Pin";
478 links[id].init = dmic_init;
479 if (dmic_be_num > 1) {
480
481 links[id + 1].name = "dmic16k";
482 links[id + 1].cpus = &cpus[id + 1];
483 links[id + 1].cpus->dai_name = "DMIC16k Pin";
484 dmic_be_num = 2;
485 }
486 }
487
488 for (i = 0; i < dmic_be_num; i++) {
489 links[id].id = id;
490 links[id].num_cpus = 1;
491 links[id].codecs = dmic_component;
492 links[id].num_codecs = ARRAY_SIZE(dmic_component);
493 links[id].platforms = platform_component;
494 links[id].num_platforms = ARRAY_SIZE(platform_component);
495 links[id].ignore_suspend = 1;
496 links[id].dpcm_capture = 1;
497 links[id].no_pcm = 1;
498 id++;
499 }
500
501
502 if (hdmi_num > 0) {
503 idisp_components = devm_kzalloc(dev,
504 sizeof(struct snd_soc_dai_link_component) *
505 hdmi_num, GFP_KERNEL);
506 if (!idisp_components)
507 goto devm_err;
508 }
509 for (i = 1; i <= hdmi_num; i++) {
510 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
511 "iDisp%d", i);
512 if (!links[id].name)
513 goto devm_err;
514
515 links[id].id = id;
516 links[id].cpus = &cpus[id];
517 links[id].num_cpus = 1;
518 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
519 "iDisp%d Pin", i);
520 if (!links[id].cpus->dai_name)
521 goto devm_err;
522
523 idisp_components[i - 1].name = "ehdaudio0D2";
524 idisp_components[i - 1].dai_name = devm_kasprintf(dev,
525 GFP_KERNEL,
526 "intel-hdmi-hifi%d",
527 i);
528 if (!idisp_components[i - 1].dai_name)
529 goto devm_err;
530
531 links[id].codecs = &idisp_components[i - 1];
532 links[id].num_codecs = 1;
533 links[id].platforms = platform_component;
534 links[id].num_platforms = ARRAY_SIZE(platform_component);
535 links[id].init = sof_hdmi_init;
536 links[id].dpcm_playback = 1;
537 links[id].no_pcm = 1;
538 id++;
539 }
540
541
542 if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) {
543 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
544 "SSP%d-Codec", ssp_amp);
545 if (!links[id].name)
546 goto devm_err;
547
548 links[id].id = id;
549 links[id].codecs = max98357a_component;
550 links[id].num_codecs = ARRAY_SIZE(max98357a_component);
551 links[id].platforms = platform_component;
552 links[id].num_platforms = ARRAY_SIZE(platform_component);
553 links[id].init = speaker_codec_init,
554 links[id].nonatomic = true;
555 links[id].dpcm_playback = 1;
556 links[id].no_pcm = 1;
557 links[id].cpus = &cpus[id];
558 links[id].num_cpus = 1;
559 if (is_legacy_cpu) {
560 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
561 "ssp%d-port",
562 ssp_amp);
563 if (!links[id].cpus->dai_name)
564 goto devm_err;
565
566 } else {
567 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
568 "SSP%d Pin",
569 ssp_amp);
570 if (!links[id].cpus->dai_name)
571 goto devm_err;
572 }
573 }
574
575 return links;
576 devm_err:
577 return NULL;
578 }
579
580 static int sof_audio_probe(struct platform_device *pdev)
581 {
582 struct snd_soc_dai_link *dai_links;
583 struct snd_soc_acpi_mach *mach;
584 struct sof_card_private *ctx;
585 int dmic_be_num, hdmi_num;
586 int ret, ssp_amp, ssp_codec;
587
588 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
589 if (!ctx)
590 return -ENOMEM;
591
592 if (pdev->id_entry && pdev->id_entry->driver_data)
593 sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
594
595 dmi_check_system(sof_rt5682_quirk_table);
596
597 mach = (&pdev->dev)->platform_data;
598
599
600
601
602 if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
603 sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT;
604
605 if (soc_intel_is_byt() || soc_intel_is_cht()) {
606 is_legacy_cpu = 1;
607 dmic_be_num = 0;
608 hdmi_num = 0;
609
610 sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
611 SOF_RT5682_MCLK_BYTCHT_EN |
612 SOF_RT5682_SSP_CODEC(2);
613 } else {
614 dmic_be_num = 2;
615 hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
616 SOF_RT5682_NUM_HDMIDEV_SHIFT;
617
618 if (!hdmi_num)
619 hdmi_num = 3;
620 }
621
622
623 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
624 ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
625 if (IS_ERR(ctx->mclk)) {
626 ret = PTR_ERR(ctx->mclk);
627
628 dev_err(&pdev->dev,
629 "Failed to get MCLK from pmc_plt_clk_3: %d\n",
630 ret);
631 return ret;
632 }
633
634 ret = clk_prepare_enable(ctx->mclk);
635 if (ret < 0) {
636 dev_err(&pdev->dev,
637 "could not configure MCLK state");
638 return ret;
639 }
640 }
641
642 dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
643
644 ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
645 SOF_RT5682_SSP_AMP_SHIFT;
646
647 ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
648
649
650 sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
651
652 if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT)
653 sof_audio_card_rt5682.num_links++;
654
655 dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
656 dmic_be_num, hdmi_num);
657 if (!dai_links)
658 return -ENOMEM;
659
660 sof_audio_card_rt5682.dai_link = dai_links;
661
662 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
663
664 sof_audio_card_rt5682.dev = &pdev->dev;
665
666
667 ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
668 mach->mach_params.platform);
669 if (ret)
670 return ret;
671
672 snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
673
674 return devm_snd_soc_register_card(&pdev->dev,
675 &sof_audio_card_rt5682);
676 }
677
678 static int sof_rt5682_remove(struct platform_device *pdev)
679 {
680 struct snd_soc_card *card = platform_get_drvdata(pdev);
681 struct snd_soc_component *component = NULL;
682
683 for_each_card_components(card, component) {
684 if (!strcmp(component->name, rt5682_component[0].name)) {
685 snd_soc_component_set_jack(component, NULL, NULL);
686 break;
687 }
688 }
689
690 return 0;
691 }
692
693 static const struct platform_device_id board_ids[] = {
694 {
695 .name = "sof_rt5682",
696 },
697 {
698 .name = "tgl_max98357a_rt5682",
699 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
700 SOF_RT5682_SSP_CODEC(0) |
701 SOF_SPEAKER_AMP_PRESENT |
702 SOF_RT5682_SSP_AMP(1) |
703 SOF_RT5682_NUM_HDMIDEV(4)),
704 },
705 { }
706 };
707
708 static struct platform_driver sof_audio = {
709 .probe = sof_audio_probe,
710 .remove = sof_rt5682_remove,
711 .driver = {
712 .name = "sof_rt5682",
713 .pm = &snd_soc_pm_ops,
714 },
715 .id_table = board_ids,
716 };
717 module_platform_driver(sof_audio)
718
719
720 MODULE_DESCRIPTION("SOF Audio Machine driver");
721 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
722 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
723 MODULE_LICENSE("GPL v2");
724 MODULE_ALIAS("platform:sof_rt5682");
725 MODULE_ALIAS("platform:tgl_max98357a_rt5682");