Linux Audio

Check our new training course

Open-source upstreaming

Need help get the support for your hardware in upstream Linux?
Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2//
  3// Copyright(c) 2023 Intel Corporation
  4
  5#include <sound/soc.h>
  6#include "../common/soc-intel-quirks.h"
  7#include "hda_dsp_common.h"
  8#include "sof_board_helpers.h"
  9
 10/*
 11 * Intel HDMI DAI Link
 12 */
 13static int hdmi_init(struct snd_soc_pcm_runtime *rtd)
 14{
 15	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 16	struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
 17
 18	ctx->hdmi.hdmi_comp = dai->component;
 19
 20	return 0;
 21}
 22
 23int sof_intel_board_card_late_probe(struct snd_soc_card *card)
 24{
 25	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
 26
 27	if (!ctx->hdmi_num)
 28		return 0;
 29
 30	if (!ctx->hdmi.idisp_codec)
 31		return 0;
 32
 33	if (!ctx->hdmi.hdmi_comp)
 34		return -EINVAL;
 35
 36	return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
 37}
 38EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, "SND_SOC_INTEL_SOF_BOARD_HELPERS");
 39
 40/*
 41 * DMIC DAI Link
 42 */
 43static const struct snd_soc_dapm_widget dmic_widgets[] = {
 44	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
 45};
 46
 47static const struct snd_soc_dapm_route dmic_routes[] = {
 48	{"DMic", NULL, "SoC DMIC"},
 49};
 50
 51static int dmic_init(struct snd_soc_pcm_runtime *rtd)
 52{
 53	struct snd_soc_card *card = rtd->card;
 54	int ret;
 55
 56	ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
 57					ARRAY_SIZE(dmic_widgets));
 58	if (ret) {
 59		dev_err(rtd->dev, "fail to add dmic widgets, ret %d\n", ret);
 60		return ret;
 61	}
 62
 63	ret = snd_soc_dapm_add_routes(&card->dapm, dmic_routes,
 64				      ARRAY_SIZE(dmic_routes));
 65	if (ret) {
 66		dev_err(rtd->dev, "fail to add dmic routes, ret %d\n", ret);
 67		return ret;
 68	}
 69
 70	return 0;
 71}
 72
 73/*
 74 * HDA External Codec DAI Link
 75 */
 76static const struct snd_soc_dapm_widget hda_widgets[] = {
 77	SND_SOC_DAPM_MIC("Analog In", NULL),
 78	SND_SOC_DAPM_MIC("Digital In", NULL),
 79	SND_SOC_DAPM_MIC("Alt Analog In", NULL),
 80
 81	SND_SOC_DAPM_HP("Analog Out", NULL),
 82	SND_SOC_DAPM_SPK("Digital Out", NULL),
 83	SND_SOC_DAPM_HP("Alt Analog Out", NULL),
 84};
 85
 86static const struct snd_soc_dapm_route hda_routes[] = {
 87	{ "Codec Input Pin1", NULL, "Analog In" },
 88	{ "Codec Input Pin2", NULL, "Digital In" },
 89	{ "Codec Input Pin3", NULL, "Alt Analog In" },
 90
 91	{ "Analog Out", NULL, "Codec Output Pin1" },
 92	{ "Digital Out", NULL, "Codec Output Pin2" },
 93	{ "Alt Analog Out", NULL, "Codec Output Pin3" },
 94
 95	/* CODEC BE connections */
 96	{ "codec0_in", NULL, "Analog CPU Capture" },
 97	{ "Analog CPU Capture", NULL, "Analog Codec Capture" },
 98	{ "codec1_in", NULL, "Digital CPU Capture" },
 99	{ "Digital CPU Capture", NULL, "Digital Codec Capture" },
100	{ "codec2_in", NULL, "Alt Analog CPU Capture" },
101	{ "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" },
102
103	{ "Analog Codec Playback", NULL, "Analog CPU Playback" },
104	{ "Analog CPU Playback", NULL, "codec0_out" },
105	{ "Digital Codec Playback", NULL, "Digital CPU Playback" },
106	{ "Digital CPU Playback", NULL, "codec1_out" },
107	{ "Alt Analog Codec Playback", NULL, "Alt Analog CPU Playback" },
108	{ "Alt Analog CPU Playback", NULL, "codec2_out" },
109};
110
111static int hda_init(struct snd_soc_pcm_runtime *rtd)
112{
113	struct snd_soc_card *card = rtd->card;
114	int ret;
115
116	ret = snd_soc_dapm_new_controls(&card->dapm, hda_widgets,
117					ARRAY_SIZE(hda_widgets));
118	if (ret) {
119		dev_err(rtd->dev, "fail to add hda widgets, ret %d\n", ret);
120		return ret;
121	}
122
123	ret = snd_soc_dapm_add_routes(&card->dapm, hda_routes,
124				      ARRAY_SIZE(hda_routes));
125	if (ret)
126		dev_err(rtd->dev, "fail to add hda routes, ret %d\n", ret);
127
128	return ret;
129}
130
131/*
132 * DAI Link Helpers
133 */
134
135enum sof_dmic_be_type {
136	SOF_DMIC_01,
137	SOF_DMIC_16K,
138};
139
140enum sof_hda_be_type {
141	SOF_HDA_ANALOG,
142	SOF_HDA_DIGITAL,
143};
144
145/* DEFAULT_LINK_ORDER: the order used in sof_rt5682 */
146#define DEFAULT_LINK_ORDER	SOF_LINK_ORDER(SOF_LINK_CODEC, \
147					SOF_LINK_DMIC01,       \
148					SOF_LINK_DMIC16K,      \
149					SOF_LINK_IDISP_HDMI,   \
150					SOF_LINK_AMP,          \
151					SOF_LINK_BT_OFFLOAD,   \
152					SOF_LINK_HDMI_IN)
153
154static struct snd_soc_dai_link_component dmic_component[] = {
155	{
156		.name = "dmic-codec",
157		.dai_name = "dmic-hifi",
158	}
159};
160
161SND_SOC_DAILINK_DEF(hda_analog_cpus,
162		    DAILINK_COMP_ARRAY(COMP_CPU("Analog CPU DAI")));
163SND_SOC_DAILINK_DEF(hda_analog_codecs,
164		    DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Analog Codec DAI")));
165
166SND_SOC_DAILINK_DEF(hda_digital_cpus,
167		    DAILINK_COMP_ARRAY(COMP_CPU("Digital CPU DAI")));
168SND_SOC_DAILINK_DEF(hda_digital_codecs,
169		    DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Digital Codec DAI")));
170
171static struct snd_soc_dai_link_component platform_component[] = {
172	{
173		/* name might be overridden during probe */
174		.name = "0000:00:1f.3"
175	}
176};
177
178static int set_ssp_codec_link(struct device *dev, struct snd_soc_dai_link *link,
179			      int be_id, enum snd_soc_acpi_intel_codec codec_type,
180			      int ssp_codec)
181{
182	struct snd_soc_dai_link_component *cpus;
183
184	dev_dbg(dev, "link %d: ssp codec %s, ssp %d\n", be_id,
185		snd_soc_acpi_intel_get_codec_name(codec_type), ssp_codec);
186
187	/* link name */
188	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec);
189	if (!link->name)
190		return -ENOMEM;
191
192	/* cpus */
193	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
194			    GFP_KERNEL);
195	if (!cpus)
196		return -ENOMEM;
197
198	if (soc_intel_is_byt() || soc_intel_is_cht()) {
199		/* backward-compatibility for BYT/CHT boards */
200		cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "ssp%d-port",
201						ssp_codec);
202	} else {
203		cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin",
204						ssp_codec);
205	}
206	if (!cpus->dai_name)
207		return -ENOMEM;
208
209	link->cpus = cpus;
210	link->num_cpus = 1;
211
212	/* codecs - caller to handle */
213
214	/* platforms */
215	link->platforms = platform_component;
216	link->num_platforms = ARRAY_SIZE(platform_component);
217
218	link->id = be_id;
219	link->no_pcm = 1;
 
 
220
221	return 0;
222}
 
223
224static int set_dmic_link(struct device *dev, struct snd_soc_dai_link *link,
225			 int be_id, enum sof_dmic_be_type be_type)
 
226{
227	struct snd_soc_dai_link_component *cpus;
228
229	/* cpus */
230	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
231			    GFP_KERNEL);
232	if (!cpus)
233		return -ENOMEM;
234
235	switch (be_type) {
236	case SOF_DMIC_01:
237		dev_dbg(dev, "link %d: dmic01\n", be_id);
238
239		link->name = "dmic01";
240		cpus->dai_name = "DMIC01 Pin";
241		break;
242	case SOF_DMIC_16K:
243		dev_dbg(dev, "link %d: dmic16k\n", be_id);
244
245		link->name = "dmic16k";
246		cpus->dai_name = "DMIC16k Pin";
247		break;
248	default:
249		dev_err(dev, "invalid be type %d\n", be_type);
250		return -EINVAL;
251	}
252
253	link->cpus = cpus;
254	link->num_cpus = 1;
255
256	/* codecs */
257	link->codecs = dmic_component;
258	link->num_codecs = ARRAY_SIZE(dmic_component);
259
260	/* platforms */
261	link->platforms = platform_component;
262	link->num_platforms = ARRAY_SIZE(platform_component);
263
264	link->id = be_id;
265	if (be_type == SOF_DMIC_01)
266		link->init = dmic_init;
267	link->ignore_suspend = 1;
268	link->no_pcm = 1;
269	link->capture_only = 1;
270
271	return 0;
272}
 
273
274static int set_idisp_hdmi_link(struct device *dev, struct snd_soc_dai_link *link,
275			       int be_id, int hdmi_id, bool idisp_codec)
 
276{
277	struct snd_soc_dai_link_component *cpus, *codecs;
278
279	dev_dbg(dev, "link %d: idisp hdmi %d, idisp codec %d\n", be_id, hdmi_id,
280		idisp_codec);
281
282	/* link name */
283	link->name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", hdmi_id);
284	if (!link->name)
285		return -ENOMEM;
286
287	/* cpus */
288	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
289			    GFP_KERNEL);
290	if (!cpus)
291		return -ENOMEM;
292
293	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", hdmi_id);
294	if (!cpus->dai_name)
295		return -ENOMEM;
296
297	link->cpus = cpus;
298	link->num_cpus = 1;
299
300	/* codecs */
301	if (idisp_codec) {
302		codecs = devm_kzalloc(dev,
303				      sizeof(struct snd_soc_dai_link_component),
304				      GFP_KERNEL);
305		if (!codecs)
306			return -ENOMEM;
307
308		codecs->name = "ehdaudio0D2";
309		codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL,
310						  "intel-hdmi-hifi%d", hdmi_id);
311		if (!codecs->dai_name)
312			return -ENOMEM;
313
314		link->codecs = codecs;
315	} else {
316		link->codecs = &snd_soc_dummy_dlc;
317	}
318	link->num_codecs = 1;
319
320	/* platforms */
321	link->platforms = platform_component;
322	link->num_platforms = ARRAY_SIZE(platform_component);
323
324	link->id = be_id;
325	link->init = (hdmi_id == 1) ? hdmi_init : NULL;
326	link->no_pcm = 1;
327	link->playback_only = 1;
328
329	return 0;
330}
 
331
332static int set_ssp_amp_link(struct device *dev, struct snd_soc_dai_link *link,
333			    int be_id, enum snd_soc_acpi_intel_codec amp_type,
334			    int ssp_amp)
335{
336	struct snd_soc_dai_link_component *cpus;
337
338	dev_dbg(dev, "link %d: ssp amp %s, ssp %d\n", be_id,
339		snd_soc_acpi_intel_get_codec_name(amp_type), ssp_amp);
340
341	/* link name */
342	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_amp);
343	if (!link->name)
344		return -ENOMEM;
345
346	/* cpus */
347	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
348			    GFP_KERNEL);
349	if (!cpus)
350		return -ENOMEM;
351
352	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_amp);
353	if (!cpus->dai_name)
354		return -ENOMEM;
355
356	link->cpus = cpus;
357	link->num_cpus = 1;
358
359	/* codecs - caller to handle */
360
361	/* platforms */
362	/* feedback stream or firmware-generated echo reference */
363	link->platforms = platform_component;
364	link->num_platforms = ARRAY_SIZE(platform_component);
365
366	link->id = be_id;
367	link->no_pcm = 1;
 
 
368
369	return 0;
370}
 
371
372static int set_bt_offload_link(struct device *dev, struct snd_soc_dai_link *link,
373			       int be_id, int ssp_bt)
 
374{
375	struct snd_soc_dai_link_component *cpus;
376
377	dev_dbg(dev, "link %d: bt offload, ssp %d\n", be_id, ssp_bt);
378
379	/* link name */
380	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", ssp_bt);
381	if (!link->name)
382		return -ENOMEM;
383
384	/* cpus */
385	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
386			    GFP_KERNEL);
387	if (!cpus)
388		return -ENOMEM;
389
390	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_bt);
391	if (!cpus->dai_name)
392		return -ENOMEM;
393
394	link->cpus = cpus;
395	link->num_cpus = 1;
396
397	/* codecs */
398	link->codecs = &snd_soc_dummy_dlc;
399	link->num_codecs = 1;
400
401	/* platforms */
402	link->platforms = platform_component;
403	link->num_platforms = ARRAY_SIZE(platform_component);
404
405	link->id = be_id;
406	link->no_pcm = 1;
 
 
407
408	return 0;
409}
 
410
411static int set_hdmi_in_link(struct device *dev, struct snd_soc_dai_link *link,
412			    int be_id, int ssp_hdmi)
 
413{
414	struct snd_soc_dai_link_component *cpus;
415
416	dev_dbg(dev, "link %d: hdmi-in, ssp %d\n", be_id, ssp_hdmi);
417
418	/* link name */
419	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", ssp_hdmi);
420	if (!link->name)
421		return -ENOMEM;
422
423	/* cpus */
424	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
425			    GFP_KERNEL);
426	if (!cpus)
427		return -ENOMEM;
428
429	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_hdmi);
430	if (!cpus->dai_name)
431		return -ENOMEM;
432
433	link->cpus = cpus;
434	link->num_cpus = 1;
435
436	/* codecs */
437	link->codecs = &snd_soc_dummy_dlc;
438	link->num_codecs = 1;
439
440	/* platforms */
441	link->platforms = platform_component;
442	link->num_platforms = ARRAY_SIZE(platform_component);
443
444	link->id = be_id;
445	link->no_pcm = 1;
446	link->capture_only = 1;
447
448	return 0;
449}
450
451static int set_hda_codec_link(struct device *dev, struct snd_soc_dai_link *link,
452			      int be_id, enum sof_hda_be_type be_type)
453{
454	switch (be_type) {
455	case SOF_HDA_ANALOG:
456		dev_dbg(dev, "link %d: hda analog\n", be_id);
457
458		link->name = "Analog Playback and Capture";
459
460		/* cpus */
461		link->cpus = hda_analog_cpus;
462		link->num_cpus = ARRAY_SIZE(hda_analog_cpus);
463
464		/* codecs */
465		link->codecs = hda_analog_codecs;
466		link->num_codecs = ARRAY_SIZE(hda_analog_codecs);
467		break;
468	case SOF_HDA_DIGITAL:
469		dev_dbg(dev, "link %d: hda digital\n", be_id);
470
471		link->name = "Digital Playback and Capture";
472
473		/* cpus */
474		link->cpus = hda_digital_cpus;
475		link->num_cpus = ARRAY_SIZE(hda_digital_cpus);
476
477		/* codecs */
478		link->codecs = hda_digital_codecs;
479		link->num_codecs = ARRAY_SIZE(hda_digital_codecs);
480		break;
481	default:
482		dev_err(dev, "invalid be type %d\n", be_type);
483		return -EINVAL;
484	}
485
486	/* platforms */
487	link->platforms = platform_component;
488	link->num_platforms = ARRAY_SIZE(platform_component);
489
490	link->id = be_id;
491	if (be_type == SOF_HDA_ANALOG)
492		link->init = hda_init;
493	link->no_pcm = 1;
494
495	return 0;
496}
 
497
498static int calculate_num_links(struct sof_card_private *ctx)
499{
500	int num_links = 0;
501
502	/* headphone codec */
503	if (ctx->codec_type != CODEC_NONE)
504		num_links++;
505
506	/* dmic01 and dmic16k */
507	if (ctx->dmic_be_num > 0)
508		num_links++;
509
510	if (ctx->dmic_be_num > 1)
511		num_links++;
512
513	/* idisp HDMI */
514	num_links += ctx->hdmi_num;
515
516	/* speaker amp */
517	if (ctx->amp_type != CODEC_NONE)
518		num_links++;
519
520	/* BT audio offload */
521	if (ctx->bt_offload_present)
522		num_links++;
523
524	/* HDMI-In */
525	num_links += hweight32(ctx->ssp_mask_hdmi_in);
526
527	/* HDA external codec */
528	if (ctx->hda_codec_present)
529		num_links += 2;
530
531	return num_links;
532}
533
534int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
535				 struct sof_card_private *ctx)
536{
537	struct snd_soc_dai_link *links;
538	int num_links;
539	int i;
540	int idx = 0;
541	int ret;
542	int ssp_hdmi_in = 0;
543	unsigned long link_order, link;
544	unsigned long link_ids, be_id;
545
546	num_links = calculate_num_links(ctx);
547
548	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link),
549			     GFP_KERNEL);
550	if (!links)
551		return -ENOMEM;
552
553	if (ctx->link_order_overwrite)
554		link_order = ctx->link_order_overwrite;
555	else
556		link_order = DEFAULT_LINK_ORDER;
557
558	if (ctx->link_id_overwrite)
559		link_ids = ctx->link_id_overwrite;
560	else
561		link_ids = 0;
562
563	dev_dbg(dev, "create dai links, link_order 0x%lx, id_overwrite 0x%lx\n",
564		link_order, link_ids);
565
566	while (link_order) {
567		link = link_order & SOF_LINK_ORDER_MASK;
568		link_order >>= SOF_LINK_ORDER_SHIFT;
569
570		if (ctx->link_id_overwrite) {
571			be_id = link_ids & SOF_LINK_IDS_MASK;
572			link_ids >>= SOF_LINK_IDS_SHIFT;
573		} else {
574			/* use array index as link id */
575			be_id = idx;
576		}
577
578		switch (link) {
579		case SOF_LINK_CODEC:
580			/* headphone codec */
581			if (ctx->codec_type == CODEC_NONE)
582				continue;
583
584			ret = set_ssp_codec_link(dev, &links[idx], be_id,
585						 ctx->codec_type, ctx->ssp_codec);
 
 
586			if (ret) {
587				dev_err(dev, "fail to set codec link, ret %d\n",
588					ret);
589				return ret;
590			}
591
592			ctx->codec_link = &links[idx];
593			idx++;
594			break;
595		case SOF_LINK_DMIC01:
596			/* dmic01 */
597			if (ctx->dmic_be_num == 0)
598				continue;
599
600			/* at least we have dmic01 */
601			ret = set_dmic_link(dev, &links[idx], be_id, SOF_DMIC_01);
 
602			if (ret) {
603				dev_err(dev, "fail to set dmic01 link, ret %d\n",
604					ret);
605				return ret;
606			}
607
608			idx++;
609			break;
610		case SOF_LINK_DMIC16K:
611			/* dmic16k */
612			if (ctx->dmic_be_num <= 1)
613				continue;
614
615			/* set up 2 BE links at most */
616			ret = set_dmic_link(dev, &links[idx], be_id,
617					    SOF_DMIC_16K);
618			if (ret) {
619				dev_err(dev, "fail to set dmic16k link, ret %d\n",
620					ret);
621				return ret;
622			}
623
624			idx++;
625			break;
626		case SOF_LINK_IDISP_HDMI:
627			/* idisp HDMI */
628			for (i = 1; i <= ctx->hdmi_num; i++) {
629				ret = set_idisp_hdmi_link(dev, &links[idx],
630							  be_id, i,
631							  ctx->hdmi.idisp_codec);
 
632				if (ret) {
633					dev_err(dev, "fail to set hdmi link, ret %d\n",
634						ret);
635					return ret;
636				}
637
638				idx++;
639				be_id++;
640			}
641			break;
642		case SOF_LINK_AMP:
643			/* speaker amp */
644			if (ctx->amp_type == CODEC_NONE)
645				continue;
646
647			ret = set_ssp_amp_link(dev, &links[idx], be_id,
648					       ctx->amp_type, ctx->ssp_amp);
 
 
649			if (ret) {
650				dev_err(dev, "fail to set amp link, ret %d\n",
651					ret);
652				return ret;
653			}
654
655			ctx->amp_link = &links[idx];
656			idx++;
657			break;
658		case SOF_LINK_BT_OFFLOAD:
659			/* BT audio offload */
660			if (!ctx->bt_offload_present)
661				continue;
662
663			ret = set_bt_offload_link(dev, &links[idx], be_id,
664						  ctx->ssp_bt);
665			if (ret) {
666				dev_err(dev, "fail to set bt link, ret %d\n",
667					ret);
668				return ret;
669			}
670
671			idx++;
672			break;
673		case SOF_LINK_HDMI_IN:
674			/* HDMI-In */
675			for_each_set_bit(ssp_hdmi_in, &ctx->ssp_mask_hdmi_in, 32) {
676				ret = set_hdmi_in_link(dev, &links[idx], be_id,
677						       ssp_hdmi_in);
 
 
678				if (ret) {
679					dev_err(dev, "fail to set hdmi-in link, ret %d\n",
680						ret);
681					return ret;
682				}
683
684				idx++;
685				be_id++;
686			}
687			break;
688		case SOF_LINK_HDA:
689			/* HDA external codec */
690			if (!ctx->hda_codec_present)
691				continue;
692
693			ret = set_hda_codec_link(dev, &links[idx], be_id,
694						 SOF_HDA_ANALOG);
695			if (ret) {
696				dev_err(dev, "fail to set hda analog link, ret %d\n",
697					ret);
698				return ret;
699			}
700
701			idx++;
702			be_id++;
703
704			ret = set_hda_codec_link(dev, &links[idx], be_id,
705						 SOF_HDA_DIGITAL);
706			if (ret) {
707				dev_err(dev, "fail to set hda digital link, ret %d\n",
708					ret);
709				return ret;
710			}
711
712			idx++;
713			break;
714		case SOF_LINK_NONE:
715			/* caught here if it's not used as terminator in macro */
716			fallthrough;
717		default:
718			dev_err(dev, "invalid link type %ld\n", link);
719			return -EINVAL;
720		}
721	}
722
723	if (idx != num_links) {
724		dev_err(dev, "link number mismatch, idx %d, num_links %d\n", idx,
725			num_links);
726		return -EINVAL;
727	}
728
729	card->dai_link = links;
730	card->num_links = num_links;
731
732	return 0;
733}
734EXPORT_SYMBOL_NS(sof_intel_board_set_dai_link, "SND_SOC_INTEL_SOF_BOARD_HELPERS");
735
736struct sof_card_private *
737sof_intel_board_get_ctx(struct device *dev, unsigned long board_quirk)
738{
739	struct sof_card_private *ctx;
740
741	dev_dbg(dev, "create ctx, board_quirk 0x%lx\n", board_quirk);
742
743	ctx = devm_kzalloc(dev, sizeof(struct sof_card_private), GFP_KERNEL);
744	if (!ctx)
745		return NULL;
746
747	ctx->codec_type = snd_soc_acpi_intel_detect_codec_type(dev);
748	ctx->amp_type = snd_soc_acpi_intel_detect_amp_type(dev);
749
750	ctx->dmic_be_num = 2;
751	ctx->hdmi_num = (board_quirk & SOF_NUM_IDISP_HDMI_MASK) >>
752			SOF_NUM_IDISP_HDMI_SHIFT;
753	/* default number of HDMI DAI's */
754	if (!ctx->hdmi_num)
755		ctx->hdmi_num = 3;
756
757	/* port number/mask of peripherals attached to ssp interface */
758	if (ctx->codec_type != CODEC_NONE)
759		ctx->ssp_codec = (board_quirk & SOF_SSP_PORT_CODEC_MASK) >>
760				SOF_SSP_PORT_CODEC_SHIFT;
761
762	if (ctx->amp_type != CODEC_NONE)
763		ctx->ssp_amp = (board_quirk & SOF_SSP_PORT_AMP_MASK) >>
764				SOF_SSP_PORT_AMP_SHIFT;
765
766	if (board_quirk & SOF_BT_OFFLOAD_PRESENT) {
767		ctx->bt_offload_present = true;
768		ctx->ssp_bt = (board_quirk & SOF_SSP_PORT_BT_OFFLOAD_MASK) >>
769				SOF_SSP_PORT_BT_OFFLOAD_SHIFT;
770	}
771
772	ctx->ssp_mask_hdmi_in = (board_quirk & SOF_SSP_MASK_HDMI_CAPTURE_MASK) >>
773				SOF_SSP_MASK_HDMI_CAPTURE_SHIFT;
 
 
 
 
774
775	return ctx;
776}
777EXPORT_SYMBOL_NS(sof_intel_board_get_ctx, "SND_SOC_INTEL_SOF_BOARD_HELPERS");
778
779MODULE_DESCRIPTION("ASoC Intel SOF Machine Driver Board Helpers");
780MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
781MODULE_LICENSE("GPL");
782MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON");
783MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_MATCH");
v6.9.4
  1// SPDX-License-Identifier: GPL-2.0-only
  2//
  3// Copyright(c) 2023 Intel Corporation. All rights reserved.
  4
  5#include <sound/soc.h>
  6#include "../common/soc-intel-quirks.h"
  7#include "hda_dsp_common.h"
  8#include "sof_board_helpers.h"
  9
 10/*
 11 * Intel HDMI DAI Link
 12 */
 13static int hdmi_init(struct snd_soc_pcm_runtime *rtd)
 14{
 15	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 16	struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
 17
 18	ctx->hdmi.hdmi_comp = dai->component;
 19
 20	return 0;
 21}
 22
 23int sof_intel_board_card_late_probe(struct snd_soc_card *card)
 24{
 25	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
 26
 27	if (!ctx->hdmi_num)
 28		return 0;
 29
 30	if (!ctx->hdmi.idisp_codec)
 31		return 0;
 32
 33	if (!ctx->hdmi.hdmi_comp)
 34		return -EINVAL;
 35
 36	return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
 37}
 38EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, SND_SOC_INTEL_SOF_BOARD_HELPERS);
 39
 40/*
 41 * DMIC DAI Link
 42 */
 43static const struct snd_soc_dapm_widget dmic_widgets[] = {
 44	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
 45};
 46
 47static const struct snd_soc_dapm_route dmic_routes[] = {
 48	{"DMic", NULL, "SoC DMIC"},
 49};
 50
 51static int dmic_init(struct snd_soc_pcm_runtime *rtd)
 52{
 53	struct snd_soc_card *card = rtd->card;
 54	int ret;
 55
 56	ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
 57					ARRAY_SIZE(dmic_widgets));
 58	if (ret) {
 59		dev_err(rtd->dev, "fail to add dmic widgets, ret %d\n", ret);
 60		return ret;
 61	}
 62
 63	ret = snd_soc_dapm_add_routes(&card->dapm, dmic_routes,
 64				      ARRAY_SIZE(dmic_routes));
 65	if (ret) {
 66		dev_err(rtd->dev, "fail to add dmic routes, ret %d\n", ret);
 67		return ret;
 68	}
 69
 70	return 0;
 71}
 72
 73/*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 74 * DAI Link Helpers
 75 */
 76
 
 
 
 
 
 
 
 
 
 
 77/* DEFAULT_LINK_ORDER: the order used in sof_rt5682 */
 78#define DEFAULT_LINK_ORDER	SOF_LINK_ORDER(SOF_LINK_CODEC, \
 79					SOF_LINK_DMIC01,       \
 80					SOF_LINK_DMIC16K,      \
 81					SOF_LINK_IDISP_HDMI,   \
 82					SOF_LINK_AMP,          \
 83					SOF_LINK_BT_OFFLOAD,   \
 84					SOF_LINK_HDMI_IN)
 85
 86static struct snd_soc_dai_link_component dmic_component[] = {
 87	{
 88		.name = "dmic-codec",
 89		.dai_name = "dmic-hifi",
 90	}
 91};
 92
 
 
 
 
 
 
 
 
 
 
 93static struct snd_soc_dai_link_component platform_component[] = {
 94	{
 95		/* name might be overridden during probe */
 96		.name = "0000:00:1f.3"
 97	}
 98};
 99
100int sof_intel_board_set_codec_link(struct device *dev,
101				   struct snd_soc_dai_link *link, int be_id,
102				   enum sof_ssp_codec codec_type, int ssp_codec)
103{
104	struct snd_soc_dai_link_component *cpus;
105
106	dev_dbg(dev, "link %d: codec %s, ssp %d\n", be_id,
107		sof_ssp_get_codec_name(codec_type), ssp_codec);
108
109	/* link name */
110	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec);
111	if (!link->name)
112		return -ENOMEM;
113
114	/* cpus */
115	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
116			    GFP_KERNEL);
117	if (!cpus)
118		return -ENOMEM;
119
120	if (soc_intel_is_byt() || soc_intel_is_cht()) {
121		/* backward-compatibility for BYT/CHT boards */
122		cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "ssp%d-port",
123						ssp_codec);
124	} else {
125		cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin",
126						ssp_codec);
127	}
128	if (!cpus->dai_name)
129		return -ENOMEM;
130
131	link->cpus = cpus;
132	link->num_cpus = 1;
133
134	/* codecs - caller to handle */
135
136	/* platforms */
137	link->platforms = platform_component;
138	link->num_platforms = ARRAY_SIZE(platform_component);
139
140	link->id = be_id;
141	link->no_pcm = 1;
142	link->dpcm_capture = 1;
143	link->dpcm_playback = 1;
144
145	return 0;
146}
147EXPORT_SYMBOL_NS(sof_intel_board_set_codec_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
148
149int sof_intel_board_set_dmic_link(struct device *dev,
150				  struct snd_soc_dai_link *link, int be_id,
151				  enum sof_dmic_be_type be_type)
152{
153	struct snd_soc_dai_link_component *cpus;
154
155	/* cpus */
156	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
157			    GFP_KERNEL);
158	if (!cpus)
159		return -ENOMEM;
160
161	switch (be_type) {
162	case SOF_DMIC_01:
163		dev_dbg(dev, "link %d: dmic01\n", be_id);
164
165		link->name = "dmic01";
166		cpus->dai_name = "DMIC01 Pin";
167		break;
168	case SOF_DMIC_16K:
169		dev_dbg(dev, "link %d: dmic16k\n", be_id);
170
171		link->name = "dmic16k";
172		cpus->dai_name = "DMIC16k Pin";
173		break;
174	default:
175		dev_err(dev, "invalid be type %d\n", be_type);
176		return -EINVAL;
177	}
178
179	link->cpus = cpus;
180	link->num_cpus = 1;
181
182	/* codecs */
183	link->codecs = dmic_component;
184	link->num_codecs = ARRAY_SIZE(dmic_component);
185
186	/* platforms */
187	link->platforms = platform_component;
188	link->num_platforms = ARRAY_SIZE(platform_component);
189
190	link->id = be_id;
191	if (be_type == SOF_DMIC_01)
192		link->init = dmic_init;
193	link->ignore_suspend = 1;
194	link->no_pcm = 1;
195	link->dpcm_capture = 1;
196
197	return 0;
198}
199EXPORT_SYMBOL_NS(sof_intel_board_set_dmic_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
200
201int sof_intel_board_set_intel_hdmi_link(struct device *dev,
202					struct snd_soc_dai_link *link, int be_id,
203					int hdmi_id, bool idisp_codec)
204{
205	struct snd_soc_dai_link_component *cpus, *codecs;
206
207	dev_dbg(dev, "link %d: intel hdmi, hdmi id %d, idisp codec %d\n",
208		be_id, hdmi_id, idisp_codec);
209
210	/* link name */
211	link->name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", hdmi_id);
212	if (!link->name)
213		return -ENOMEM;
214
215	/* cpus */
216	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
217			    GFP_KERNEL);
218	if (!cpus)
219		return -ENOMEM;
220
221	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", hdmi_id);
222	if (!cpus->dai_name)
223		return -ENOMEM;
224
225	link->cpus = cpus;
226	link->num_cpus = 1;
227
228	/* codecs */
229	if (idisp_codec) {
230		codecs = devm_kzalloc(dev,
231				      sizeof(struct snd_soc_dai_link_component),
232				      GFP_KERNEL);
233		if (!codecs)
234			return -ENOMEM;
235
236		codecs->name = "ehdaudio0D2";
237		codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL,
238						  "intel-hdmi-hifi%d", hdmi_id);
239		if (!codecs->dai_name)
240			return -ENOMEM;
241
242		link->codecs = codecs;
243	} else {
244		link->codecs = &snd_soc_dummy_dlc;
245	}
246	link->num_codecs = 1;
247
248	/* platforms */
249	link->platforms = platform_component;
250	link->num_platforms = ARRAY_SIZE(platform_component);
251
252	link->id = be_id;
253	link->init = (hdmi_id == 1) ? hdmi_init : NULL;
254	link->no_pcm = 1;
255	link->dpcm_playback = 1;
256
257	return 0;
258}
259EXPORT_SYMBOL_NS(sof_intel_board_set_intel_hdmi_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
260
261int sof_intel_board_set_ssp_amp_link(struct device *dev,
262				     struct snd_soc_dai_link *link, int be_id,
263				     enum sof_ssp_codec amp_type, int ssp_amp)
264{
265	struct snd_soc_dai_link_component *cpus;
266
267	dev_dbg(dev, "link %d: ssp amp %s, ssp %d\n", be_id,
268		sof_ssp_get_codec_name(amp_type), ssp_amp);
269
270	/* link name */
271	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_amp);
272	if (!link->name)
273		return -ENOMEM;
274
275	/* cpus */
276	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
277			    GFP_KERNEL);
278	if (!cpus)
279		return -ENOMEM;
280
281	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_amp);
282	if (!cpus->dai_name)
283		return -ENOMEM;
284
285	link->cpus = cpus;
286	link->num_cpus = 1;
287
288	/* codecs - caller to handle */
289
290	/* platforms */
 
291	link->platforms = platform_component;
292	link->num_platforms = ARRAY_SIZE(platform_component);
293
294	link->id = be_id;
295	link->no_pcm = 1;
296	link->dpcm_capture = 1; /* feedback stream or firmware-generated echo reference */
297	link->dpcm_playback = 1;
298
299	return 0;
300}
301EXPORT_SYMBOL_NS(sof_intel_board_set_ssp_amp_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
302
303int sof_intel_board_set_bt_link(struct device *dev,
304				struct snd_soc_dai_link *link, int be_id,
305				int ssp_bt)
306{
307	struct snd_soc_dai_link_component *cpus;
308
309	dev_dbg(dev, "link %d: bt offload, ssp %d\n", be_id, ssp_bt);
310
311	/* link name */
312	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", ssp_bt);
313	if (!link->name)
314		return -ENOMEM;
315
316	/* cpus */
317	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
318			    GFP_KERNEL);
319	if (!cpus)
320		return -ENOMEM;
321
322	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_bt);
323	if (!cpus->dai_name)
324		return -ENOMEM;
325
326	link->cpus = cpus;
327	link->num_cpus = 1;
328
329	/* codecs */
330	link->codecs = &snd_soc_dummy_dlc;
331	link->num_codecs = 1;
332
333	/* platforms */
334	link->platforms = platform_component;
335	link->num_platforms = ARRAY_SIZE(platform_component);
336
337	link->id = be_id;
338	link->no_pcm = 1;
339	link->dpcm_capture = 1;
340	link->dpcm_playback = 1;
341
342	return 0;
343}
344EXPORT_SYMBOL_NS(sof_intel_board_set_bt_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
345
346int sof_intel_board_set_hdmi_in_link(struct device *dev,
347				     struct snd_soc_dai_link *link, int be_id,
348				     int ssp_hdmi)
349{
350	struct snd_soc_dai_link_component *cpus;
351
352	dev_dbg(dev, "link %d: hdmi-in, ssp %d\n", be_id, ssp_hdmi);
353
354	/* link name */
355	link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", ssp_hdmi);
356	if (!link->name)
357		return -ENOMEM;
358
359	/* cpus */
360	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
361			    GFP_KERNEL);
362	if (!cpus)
363		return -ENOMEM;
364
365	cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_hdmi);
366	if (!cpus->dai_name)
367		return -ENOMEM;
368
369	link->cpus = cpus;
370	link->num_cpus = 1;
371
372	/* codecs */
373	link->codecs = &snd_soc_dummy_dlc;
374	link->num_codecs = 1;
375
376	/* platforms */
377	link->platforms = platform_component;
378	link->num_platforms = ARRAY_SIZE(platform_component);
379
380	link->id = be_id;
381	link->no_pcm = 1;
382	link->dpcm_capture = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
384	return 0;
385}
386EXPORT_SYMBOL_NS(sof_intel_board_set_hdmi_in_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
387
388static int calculate_num_links(struct sof_card_private *ctx)
389{
390	int num_links = 0;
391
392	/* headphone codec */
393	if (ctx->codec_type != CODEC_NONE)
394		num_links++;
395
396	/* dmic01 and dmic16k */
397	if (ctx->dmic_be_num > 0)
398		num_links++;
399
400	if (ctx->dmic_be_num > 1)
401		num_links++;
402
403	/* idisp HDMI */
404	num_links += ctx->hdmi_num;
405
406	/* speaker amp */
407	if (ctx->amp_type != CODEC_NONE)
408		num_links++;
409
410	/* BT audio offload */
411	if (ctx->bt_offload_present)
412		num_links++;
413
414	/* HDMI-In */
415	num_links += hweight32(ctx->ssp_mask_hdmi_in);
416
 
 
 
 
417	return num_links;
418}
419
420int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
421				 struct sof_card_private *ctx)
422{
423	struct snd_soc_dai_link *links;
424	int num_links;
425	int i;
426	int idx = 0;
427	int ret;
428	int ssp_hdmi_in = 0;
429	unsigned long link_order, link;
 
430
431	num_links = calculate_num_links(ctx);
432
433	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link),
434			     GFP_KERNEL);
435	if (!links)
436		return -ENOMEM;
437
438	if (ctx->link_order_overwrite)
439		link_order = ctx->link_order_overwrite;
440	else
441		link_order = DEFAULT_LINK_ORDER;
442
443	dev_dbg(dev, "create dai links, link_order 0x%lx\n", link_order);
 
 
 
 
 
 
444
445	while (link_order) {
446		link = link_order & SOF_LINK_ORDER_MASK;
447		link_order >>= SOF_LINK_ORDER_SHIFT;
448
 
 
 
 
 
 
 
 
449		switch (link) {
450		case SOF_LINK_CODEC:
451			/* headphone codec */
452			if (ctx->codec_type == CODEC_NONE)
453				continue;
454
455			ret = sof_intel_board_set_codec_link(dev, &links[idx],
456							     idx,
457							     ctx->codec_type,
458							     ctx->ssp_codec);
459			if (ret) {
460				dev_err(dev, "fail to set codec link, ret %d\n",
461					ret);
462				return ret;
463			}
464
465			ctx->codec_link = &links[idx];
466			idx++;
467			break;
468		case SOF_LINK_DMIC01:
469			/* dmic01 */
470			if (ctx->dmic_be_num == 0)
471				continue;
472
473			/* at least we have dmic01 */
474			ret = sof_intel_board_set_dmic_link(dev, &links[idx],
475							    idx, SOF_DMIC_01);
476			if (ret) {
477				dev_err(dev, "fail to set dmic01 link, ret %d\n",
478					ret);
479				return ret;
480			}
481
482			idx++;
483			break;
484		case SOF_LINK_DMIC16K:
485			/* dmic16k */
486			if (ctx->dmic_be_num <= 1)
487				continue;
488
489			/* set up 2 BE links at most */
490			ret = sof_intel_board_set_dmic_link(dev, &links[idx],
491							    idx, SOF_DMIC_16K);
492			if (ret) {
493				dev_err(dev, "fail to set dmic16k link, ret %d\n",
494					ret);
495				return ret;
496			}
497
498			idx++;
499			break;
500		case SOF_LINK_IDISP_HDMI:
501			/* idisp HDMI */
502			for (i = 1; i <= ctx->hdmi_num; i++) {
503				ret = sof_intel_board_set_intel_hdmi_link(dev,
504									  &links[idx],
505									  idx, i,
506									  ctx->hdmi.idisp_codec);
507				if (ret) {
508					dev_err(dev, "fail to set hdmi link, ret %d\n",
509						ret);
510					return ret;
511				}
512
513				idx++;
 
514			}
515			break;
516		case SOF_LINK_AMP:
517			/* speaker amp */
518			if (ctx->amp_type == CODEC_NONE)
519				continue;
520
521			ret = sof_intel_board_set_ssp_amp_link(dev, &links[idx],
522							       idx,
523							       ctx->amp_type,
524							       ctx->ssp_amp);
525			if (ret) {
526				dev_err(dev, "fail to set amp link, ret %d\n",
527					ret);
528				return ret;
529			}
530
531			ctx->amp_link = &links[idx];
532			idx++;
533			break;
534		case SOF_LINK_BT_OFFLOAD:
535			/* BT audio offload */
536			if (!ctx->bt_offload_present)
537				continue;
538
539			ret = sof_intel_board_set_bt_link(dev, &links[idx], idx,
540							  ctx->ssp_bt);
541			if (ret) {
542				dev_err(dev, "fail to set bt link, ret %d\n",
543					ret);
544				return ret;
545			}
546
547			idx++;
548			break;
549		case SOF_LINK_HDMI_IN:
550			/* HDMI-In */
551			for_each_set_bit(ssp_hdmi_in, &ctx->ssp_mask_hdmi_in, 32) {
552				ret = sof_intel_board_set_hdmi_in_link(dev,
553								       &links[idx],
554								       idx,
555								       ssp_hdmi_in);
556				if (ret) {
557					dev_err(dev, "fail to set hdmi-in link, ret %d\n",
558						ret);
559					return ret;
560				}
561
562				idx++;
 
563			}
564			break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565		case SOF_LINK_NONE:
566			/* caught here if it's not used as terminator in macro */
567			fallthrough;
568		default:
569			dev_err(dev, "invalid link type %ld\n", link);
570			return -EINVAL;
571		}
572	}
573
574	if (idx != num_links) {
575		dev_err(dev, "link number mismatch, idx %d, num_links %d\n", idx,
576			num_links);
577		return -EINVAL;
578	}
579
580	card->dai_link = links;
581	card->num_links = num_links;
582
583	return 0;
584}
585EXPORT_SYMBOL_NS(sof_intel_board_set_dai_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
586
587struct snd_soc_dai *get_codec_dai_by_name(struct snd_soc_pcm_runtime *rtd,
588					  const char * const dai_name[], int num_dais)
589{
590	struct snd_soc_dai *dai;
591	int index;
592	int i;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
593
594	for (index = 0; index < num_dais; index++)
595		for_each_rtd_codec_dais(rtd, i, dai)
596			if (strstr(dai->name, dai_name[index])) {
597				dev_dbg(rtd->card->dev, "get dai %s\n", dai->name);
598				return dai;
599			}
600
601	return NULL;
602}
603EXPORT_SYMBOL_NS(get_codec_dai_by_name, SND_SOC_INTEL_SOF_BOARD_HELPERS);
604
605MODULE_DESCRIPTION("ASoC Intel SOF Machine Driver Board Helpers");
606MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
607MODULE_LICENSE("GPL");
608MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
609MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);