xref: /linux/sound/soc/intel/avs/board_selection.c (revision 05a54fa773284d1a7923cdfdd8f0c8dabb98bd26)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2021-2022 Intel Corporation
4 //
5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7 //
8 
9 #include <linux/acpi.h>
10 #include <linux/module.h>
11 #include <linux/dmi.h>
12 #include <linux/pci.h>
13 #include <acpi/nhlt.h>
14 #include <linux/platform_device.h>
15 #include <sound/hda_codec.h>
16 #include <sound/hda_register.h>
17 #include <sound/soc-acpi.h>
18 #include <sound/soc-component.h>
19 #include "avs.h"
20 #include "debug.h"
21 #include "pcm.h"
22 #include "utils.h"
23 
24 static char *i2s_test;
25 module_param(i2s_test, charp, 0444);
26 MODULE_PARM_DESC(i2s_test, "Use I2S test-board instead of ACPI, i2s_test=ssp0tdm,ssp1tdm,... 0 to ignore port");
27 
28 bool obsolete_card_names = IS_ENABLED(CONFIG_SND_SOC_INTEL_AVS_CARDNAME_OBSOLETE);
29 module_param_named(obsolete_card_names, obsolete_card_names, bool, 0444);
30 MODULE_PARM_DESC(obsolete_card_names, "Use obsolete card names 0=no, 1=yes");
31 
32 static const struct dmi_system_id kbl_dmi_table[] = {
33 	{
34 		.matches = {
35 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
36 			DMI_MATCH(DMI_BOARD_NAME, "Skylake Y LPDDR3 RVP3"),
37 		},
38 	},
39 	{
40 		.matches = {
41 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
42 			DMI_MATCH(DMI_BOARD_NAME, "AmberLake Y"),
43 		},
44 	},
45 	{}
46 };
47 
48 static const struct dmi_system_id kblr_dmi_table[] = {
49 	{
50 		.matches = {
51 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
52 			DMI_MATCH(DMI_BOARD_NAME, "Kabylake R DDR4 RVP"),
53 		},
54 	},
55 	{}
56 };
57 
58 static struct snd_soc_acpi_mach *dmi_match_quirk(void *arg)
59 {
60 	struct snd_soc_acpi_mach *mach = arg;
61 	struct dmi_system_id *dmi_table;
62 
63 	dmi_table = (struct dmi_system_id *)mach->quirk_data;
64 
65 	if (!dmi_table || dmi_first_match(dmi_table))
66 		return mach;
67 	return NULL;
68 }
69 
70 #define AVS_SSP(x)		(BIT(x))
71 #define AVS_SSP_RANGE(a, b)	(GENMASK(b, a))
72 
73 /* supported I2S board codec configurations */
74 static struct snd_soc_acpi_mach avs_skl_i2s_machines[] = {
75 	{
76 		.id = "INT343A",
77 		.drv_name = "avs_rt286",
78 		.mach_params = {
79 			.i2s_link_mask = AVS_SSP(0),
80 		},
81 		.tplg_filename = "rt286-tplg.bin",
82 	},
83 	{
84 		.id = "10508825",
85 		.drv_name = "avs_nau8825",
86 		.mach_params = {
87 			.i2s_link_mask = AVS_SSP(1),
88 		},
89 		.tplg_filename = "nau8825-tplg.bin",
90 	},
91 	{
92 		.id = "INT343B",
93 		.drv_name = "avs_ssm4567",
94 		.mach_params = {
95 			.i2s_link_mask = AVS_SSP(0),
96 		},
97 		.tplg_filename = "ssm4567-tplg.bin",
98 	},
99 	{
100 		.id = "MX98357A",
101 		.drv_name = "avs_max98357a",
102 		.mach_params = {
103 			.i2s_link_mask = AVS_SSP(0),
104 		},
105 		.tplg_filename = "max98357a-tplg.bin",
106 	},
107 	{},
108 };
109 
110 static struct snd_soc_acpi_mach avs_kbl_i2s_machines[] = {
111 	{
112 		.id = "INT343A",
113 		.drv_name = "avs_rt286",
114 		.mach_params = {
115 			.i2s_link_mask = AVS_SSP(0),
116 		},
117 		.quirk_data = &kbl_dmi_table,
118 		.machine_quirk = dmi_match_quirk,
119 		.tplg_filename = "rt286-tplg.bin",
120 	},
121 	{
122 		.id = "INT343A",
123 		.drv_name = "avs_rt298",
124 		.mach_params = {
125 			.i2s_link_mask = AVS_SSP(0),
126 		},
127 		.quirk_data = &kblr_dmi_table,
128 		.machine_quirk = dmi_match_quirk,
129 		.tplg_filename = "rt298-tplg.bin",
130 	},
131 	{
132 		.id = "MX98927",
133 		.drv_name = "avs_max98927",
134 		.mach_params = {
135 			.i2s_link_mask = AVS_SSP(0),
136 		},
137 		.tplg_filename = "max98927-tplg.bin",
138 	},
139 	{
140 		.id = "10EC5514",
141 		.drv_name = "avs_rt5514",
142 		.mach_params = {
143 			.i2s_link_mask = AVS_SSP(0),
144 		},
145 		.pdata = (struct avs_mach_pdata[]){ { .tdms = (unsigned long[]){ 0x2 } } },
146 		.tplg_filename = "rt5514-tplg.bin",
147 	},
148 	{
149 		.id = "10EC5663",
150 		.drv_name = "avs_rt5663",
151 		.mach_params = {
152 			.i2s_link_mask = AVS_SSP(1),
153 		},
154 		.tplg_filename = "rt5663-tplg.bin",
155 	},
156 	{
157 		.id = "MX98373",
158 		.drv_name = "avs_max98373",
159 		.mach_params = {
160 			.i2s_link_mask = AVS_SSP(0),
161 		},
162 		.tplg_filename = "max98373-tplg.bin",
163 	},
164 	{
165 		.id = "MX98357A",
166 		.drv_name = "avs_max98357a",
167 		.mach_params = {
168 			.i2s_link_mask = AVS_SSP(0),
169 		},
170 		.tplg_filename = "max98357a-tplg.bin",
171 	},
172 	{
173 		.id = "DLGS7219",
174 		.drv_name = "avs_da7219",
175 		.mach_params = {
176 			.i2s_link_mask = AVS_SSP(1),
177 		},
178 		.tplg_filename = "da7219-tplg.bin",
179 	},
180 	{
181 		.id = "ESSX8336",
182 		.drv_name = "avs_es8336",
183 		.mach_params = {
184 			.i2s_link_mask = AVS_SSP(0),
185 		},
186 		.tplg_filename = "es8336-tplg.bin",
187 	},
188 	{},
189 };
190 
191 static struct snd_soc_acpi_mach avs_apl_i2s_machines[] = {
192 	{
193 		.id = "INT343A",
194 		.drv_name = "avs_rt298",
195 		.mach_params = {
196 			.i2s_link_mask = AVS_SSP(5),
197 		},
198 		.tplg_filename = "rt298-tplg.bin",
199 	},
200 	{
201 		.id = "INT34C3",
202 		.drv_name = "avs_tdf8532",
203 		.mach_params = {
204 			.i2s_link_mask = AVS_SSP_RANGE(0, 5),
205 		},
206 		.pdata = (struct avs_mach_pdata[]){ {
207 			.tdms = (unsigned long[]){ 0x1, 0x1, 0x14, 0x1, 0x1, 0x1 }
208 		} },
209 		.tplg_filename = "tdf8532-tplg.bin",
210 	},
211 	{
212 		.id = "MX98357A",
213 		.drv_name = "avs_max98357a",
214 		.mach_params = {
215 			.i2s_link_mask = AVS_SSP(5),
216 		},
217 		.tplg_filename = "max98357a-tplg.bin",
218 	},
219 	{
220 		.id = "DLGS7219",
221 		.drv_name = "avs_da7219",
222 		.mach_params = {
223 			.i2s_link_mask = AVS_SSP(1),
224 		},
225 		.tplg_filename = "da7219-tplg.bin",
226 	},
227 	{},
228 };
229 
230 static struct snd_soc_acpi_mach avs_gml_i2s_machines[] = {
231 	{
232 		.id = "INT343A",
233 		.drv_name = "avs_rt298",
234 		.mach_params = {
235 			.i2s_link_mask = AVS_SSP(2),
236 		},
237 		.tplg_filename = "rt298-tplg.bin",
238 	},
239 	{},
240 };
241 
242 static struct snd_soc_acpi_mach avs_cnl_i2s_machines[] = {
243 	{
244 		.id = "INT34C2",
245 		.drv_name = "avs_rt274",
246 		.mach_params = {
247 			.i2s_link_mask = AVS_SSP(0),
248 		},
249 		.tplg_filename = "rt274-tplg.bin",
250 	},
251 	{
252 		.id = "10EC5682",
253 		.drv_name = "avs_rt5682",
254 		.mach_params = {
255 			.i2s_link_mask = AVS_SSP(1),
256 		},
257 		.tplg_filename = "rt5682-tplg.bin",
258 	},
259 	{},
260 };
261 
262 static struct snd_soc_acpi_mach avs_icl_i2s_machines[] = {
263 	{
264 		.id = "INT343A",
265 		.drv_name = "avs_rt298",
266 		.mach_params = {
267 			.i2s_link_mask = AVS_SSP(0),
268 		},
269 		.tplg_filename = "rt298-tplg.bin",
270 	},
271 	{
272 		.id = "INT34C2",
273 		.drv_name = "avs_rt274",
274 		.mach_params = {
275 			.i2s_link_mask = AVS_SSP(0),
276 		},
277 		.tplg_filename = "rt274-tplg.bin",
278 	},
279 	{},
280 };
281 
282 static struct snd_soc_acpi_mach avs_tgl_i2s_machines[] = {
283 	{
284 		.id = "INT34C2",
285 		.drv_name = "avs_rt274",
286 		.mach_params = {
287 			.i2s_link_mask = AVS_SSP(0),
288 		},
289 		.tplg_filename = "rt274-tplg.bin",
290 	},
291 	{
292 		.id = "10EC0298",
293 		.drv_name = "avs_rt298",
294 		.mach_params = {
295 			.i2s_link_mask = AVS_SSP(0),
296 		},
297 		.tplg_filename = "rt298-tplg.bin",
298 	},
299 	{
300 		.id = "10EC1308",
301 		.drv_name = "avs_rt1308",
302 		.mach_params = {
303 			.i2s_link_mask = AVS_SSP(1),
304 		},
305 		.tplg_filename = "rt1308-tplg.bin",
306 	},
307 	{
308 		.id = "10EC5640",
309 		.uid = "1",
310 		.drv_name = "avs_rt5640",
311 		.mach_params = {
312 			.i2s_link_mask = AVS_SSP(0),
313 		},
314 		.tplg_filename = "rt5640-tplg.bin",
315 	},
316 	{
317 		.id = "10EC5640",
318 		.uid = "3",
319 		.drv_name = "avs_rt5640",
320 		.mach_params = {
321 			.i2s_link_mask = AVS_SSP(1),
322 		},
323 		.tplg_filename = "rt5640-tplg.bin",
324 	},
325 	{
326 		.id = "10EC5640",
327 		.uid = "2",
328 		.drv_name = "avs_rt5640",
329 		.mach_params = {
330 			.i2s_link_mask = AVS_SSP(2),
331 		},
332 		.tplg_filename = "rt5640-tplg.bin",
333 	},
334 	{
335 		.id = "ESSX8336",
336 		.drv_name = "avs_es8336",
337 		.mach_params = {
338 			.i2s_link_mask = AVS_SSP(0),
339 		},
340 		.tplg_filename = "es8336-tplg.bin",
341 	},
342 	{},
343 };
344 
345 static struct snd_soc_acpi_mach avs_mbl_i2s_machines[] = {
346 	{
347 		.id = "PCM3168A",
348 		.drv_name = "avs_pcm3168a",
349 		.mach_params = {
350 			.i2s_link_mask = AVS_SSP(0) | AVS_SSP(2),
351 		},
352 		.tplg_filename = "pcm3168a-tplg.bin",
353 	},
354 	{}
355 };
356 
357 struct avs_acpi_boards {
358 	int id;
359 	struct snd_soc_acpi_mach *machs;
360 };
361 
362 #define AVS_MACH_ENTRY(_id, _mach) \
363 	{ .id = PCI_DEVICE_ID_INTEL_##_id, .machs = (_mach), }
364 
365 /* supported I2S boards per platform */
366 static const struct avs_acpi_boards i2s_boards[] = {
367 	AVS_MACH_ENTRY(HDA_SKL_LP,	avs_skl_i2s_machines),
368 	AVS_MACH_ENTRY(HDA_KBL_LP,	avs_kbl_i2s_machines),
369 	AVS_MACH_ENTRY(HDA_APL,		avs_apl_i2s_machines),
370 	AVS_MACH_ENTRY(HDA_GML,		avs_gml_i2s_machines),
371 	AVS_MACH_ENTRY(HDA_CNL_LP,	avs_cnl_i2s_machines),
372 	AVS_MACH_ENTRY(HDA_CNL_H,	avs_cnl_i2s_machines),
373 	AVS_MACH_ENTRY(HDA_CML_LP,	avs_cnl_i2s_machines),
374 	AVS_MACH_ENTRY(HDA_ICL_LP,	avs_icl_i2s_machines),
375 	AVS_MACH_ENTRY(HDA_TGL_LP,	avs_tgl_i2s_machines),
376 	AVS_MACH_ENTRY(HDA_EHL_0,	avs_tgl_i2s_machines),
377 	AVS_MACH_ENTRY(HDA_ADL_N,	avs_mbl_i2s_machines),
378 	AVS_MACH_ENTRY(HDA_ADL_P,	avs_tgl_i2s_machines),
379 	AVS_MACH_ENTRY(HDA_RPL_P_0,	avs_tgl_i2s_machines),
380 	AVS_MACH_ENTRY(HDA_RPL_M,	avs_mbl_i2s_machines),
381 	AVS_MACH_ENTRY(HDA_FCL,		avs_tgl_i2s_machines),
382 	{ },
383 };
384 
385 static struct snd_soc_acpi_mach *avs_get_i2s_machines(struct avs_dev *adev)
386 {
387 	int id, i;
388 
389 	id = adev->base.pci->device;
390 	for (i = 0; i < ARRAY_SIZE(i2s_boards); i++)
391 		if (i2s_boards[i].id == id)
392 			return i2s_boards[i].machs;
393 	return NULL;
394 }
395 
396 /* Platform devices spawned by AVS driver are removed with this hook. */
397 static void avs_unregister_board(void *pdev)
398 {
399 	platform_device_unregister(pdev);
400 }
401 
402 static struct platform_device *avs_register_board(struct avs_dev *adev, const char *name,
403 						  const void *data, size_t size)
404 {
405 	struct platform_device *pdev;
406 	int ret;
407 
408 	pdev = platform_device_register_data(NULL, name, PLATFORM_DEVID_AUTO, data, size);
409 	if (IS_ERR(pdev))
410 		return pdev;
411 
412 	ret = devm_add_action_or_reset(adev->dev, avs_unregister_board, pdev);
413 	if (ret)
414 		return ERR_PTR(ret);
415 
416 	return pdev;
417 }
418 
419 static struct platform_device *avs_register_board_pdata(struct avs_dev *adev, const char *name,
420 							struct snd_soc_acpi_mach *mach,
421 							struct hda_codec *codec,
422 							unsigned long *tdms, char *codec_name)
423 {
424 	struct avs_mach_pdata *pdata;
425 
426 	pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
427 	if (!pdata)
428 		return ERR_PTR(-ENOMEM);
429 
430 	pdata->codec = codec;
431 	pdata->tdms = tdms;
432 	pdata->codec_name = codec_name;
433 	pdata->obsolete_card_names = obsolete_card_names;
434 	mach->pdata = pdata;
435 
436 	return avs_register_board(adev, name, mach, sizeof(*mach));
437 }
438 
439 static int __maybe_unused avs_register_probe_board(struct avs_dev *adev)
440 {
441 	struct platform_device *pdev;
442 
443 	pdev = avs_register_board(adev, "avs_probe_mb", NULL, 0);
444 	if (IS_ERR(pdev))
445 		return PTR_ERR(pdev);
446 
447 	return avs_register_probe_component(adev, dev_name(&pdev->dev));
448 }
449 
450 static int avs_register_dmic_board(struct avs_dev *adev)
451 {
452 	static struct snd_soc_acpi_mach mach = {
453 		.tplg_filename = "dmic-tplg.bin",
454 	};
455 	struct platform_device *pdev;
456 	char *codec_name;
457 
458 	if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) {
459 		dev_dbg(adev->dev, "no DMIC endpoints present\n");
460 		return 0;
461 	}
462 
463 	/* DMIC present in Intel PCH is enumerated statically. */
464 	pdev = avs_register_board(adev, "dmic-codec", NULL, 0);
465 	if (IS_ERR(pdev))
466 		return PTR_ERR(pdev);
467 
468 	codec_name = devm_kstrdup(adev->dev, dev_name(&pdev->dev), GFP_KERNEL);
469 	if (!codec_name)
470 		return -ENOMEM;
471 
472 	pdev = avs_register_board_pdata(adev, "avs_dmic", &mach, NULL, NULL, codec_name);
473 	if (IS_ERR(pdev))
474 		return PTR_ERR(pdev);
475 
476 	return avs_register_dmic_component(adev, dev_name(&pdev->dev));
477 }
478 
479 static int avs_register_i2s_test_board(struct avs_dev *adev, int ssp_port, int tdm_slot)
480 {
481 	struct snd_soc_acpi_mach mach = {{0}};
482 	struct platform_device *pdev;
483 	unsigned long *tdms;
484 
485 	tdms = devm_kcalloc(adev->dev, ssp_port + 1, sizeof(*tdms), GFP_KERNEL);
486 	mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
487 					    AVS_STRING_FMT("i2s", "-test-tplg.bin",
488 							   ssp_port, tdm_slot));
489 	if (!tdms || !mach.tplg_filename)
490 		return -ENOMEM;
491 
492 	tdms[ssp_port] = BIT(tdm_slot);
493 	mach.drv_name = "avs_i2s_test";
494 	mach.mach_params.i2s_link_mask = AVS_SSP(ssp_port);
495 
496 	pdev = avs_register_board_pdata(adev, mach.drv_name, &mach, NULL, tdms, NULL);
497 	if (IS_ERR(pdev))
498 		return PTR_ERR(pdev);
499 
500 	return avs_register_i2s_component(adev, dev_name(&pdev->dev), AVS_SSP(ssp_port), tdms);
501 }
502 
503 static int avs_register_i2s_test_boards(struct avs_dev *adev)
504 {
505 	int max_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
506 	int ssp_port, tdm_slot, ret;
507 	unsigned long tdm_slots;
508 	u32 *array, num_elems;
509 
510 	if (!i2s_test)
511 		return 0;
512 
513 	ret = parse_int_array(i2s_test, strlen(i2s_test), (int **)&array);
514 	if (ret) {
515 		dev_err(adev->dev, "failed to parse i2s_test parameter\n");
516 		return ret;
517 	}
518 
519 	num_elems = *array;
520 	if (num_elems > max_ssps) {
521 		dev_err(adev->dev, "board supports only %d SSP, %d specified\n",
522 			max_ssps, num_elems);
523 		return -EINVAL;
524 	}
525 
526 	for (ssp_port = 0; ssp_port < num_elems; ssp_port++) {
527 		tdm_slots = array[1 + ssp_port];
528 		for_each_set_bit(tdm_slot, &tdm_slots, 16) {
529 			ret = avs_register_i2s_test_board(adev, ssp_port, tdm_slot);
530 			if (ret)
531 				return ret;
532 		}
533 	}
534 
535 	return 0;
536 }
537 
538 static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)
539 {
540 	u32 i2s_mask = mach->mach_params.i2s_link_mask;
541 	struct platform_device *pdev;
542 	unsigned long *tdms = NULL;
543 
544 	if (mach->pdata)
545 		tdms = ((struct avs_mach_pdata *)mach->pdata)->tdms;
546 
547 	pdev = avs_register_board_pdata(adev, mach->drv_name, mach, NULL, tdms, NULL);
548 	if (IS_ERR(pdev))
549 		return PTR_ERR(pdev);
550 
551 	return avs_register_i2s_component(adev, dev_name(&pdev->dev), i2s_mask, tdms);
552 }
553 
554 static int avs_register_i2s_boards(struct avs_dev *adev)
555 {
556 	int num_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
557 	struct snd_soc_acpi_mach *machs;
558 	struct snd_soc_acpi_mach *mach;
559 	int ret;
560 
561 	if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_SSP, -1, -1, -1)) {
562 		dev_dbg(adev->dev, "no I2S endpoints present\n");
563 		return 0;
564 	}
565 
566 	machs = avs_get_i2s_machines(adev);
567 	if (!machs) {
568 		dev_dbg(adev->dev, "no I2S endpoints supported\n");
569 		return 0;
570 	}
571 
572 	for (mach = machs; mach->id[0]; mach++) {
573 		if (!acpi_dev_present(mach->id, mach->uid, -1))
574 			continue;
575 
576 		if (fls(mach->mach_params.i2s_link_mask) > num_ssps) {
577 			dev_err(adev->dev, "Platform supports %d SSPs but board %s requires SSP%ld\n",
578 				num_ssps, mach->drv_name,
579 				(unsigned long)__fls(mach->mach_params.i2s_link_mask));
580 			continue;
581 		}
582 		if (mach->machine_quirk)
583 			if (!mach->machine_quirk(mach))
584 				continue;
585 
586 		ret = avs_register_i2s_board(adev, mach);
587 		if (ret < 0)
588 			dev_warn(adev->dev, "register i2s %s failed: %d\n", mach->drv_name, ret);
589 	}
590 
591 	return 0;
592 }
593 
594 static int avs_register_hda_board(struct avs_dev *adev, struct hda_codec *codec)
595 {
596 	struct hdac_device *hdev = &codec->core;
597 	struct snd_soc_acpi_mach mach = {{0}};
598 	struct platform_device *pdev;
599 
600 	mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL, "hda-%08x-tplg.bin",
601 					    hdev->vendor_id);
602 	if (!mach.tplg_filename)
603 		return -ENOMEM;
604 
605 	pdev = avs_register_board_pdata(adev, "avs_hdaudio", &mach, codec, NULL, NULL);
606 	if (IS_ERR(pdev))
607 		return PTR_ERR(pdev);
608 
609 	return avs_register_hda_component(adev, dev_name(&pdev->dev));
610 }
611 
612 static int avs_register_hda_boards(struct avs_dev *adev)
613 {
614 	struct hdac_bus *bus = &adev->base.core;
615 	struct hdac_device *hdev;
616 	int ret;
617 
618 	if (!bus->num_codecs) {
619 		dev_dbg(adev->dev, "no HDA endpoints present\n");
620 		return 0;
621 	}
622 
623 	list_for_each_entry(hdev, &bus->codec_list, list) {
624 		struct hda_codec *codec;
625 
626 		codec = dev_to_hda_codec(&hdev->dev);
627 
628 		ret = avs_register_hda_board(adev, codec);
629 		if (ret < 0)
630 			dev_warn(adev->dev, "register hda-%08x failed: %d\n",
631 				 codec->core.vendor_id, ret);
632 	}
633 
634 	return 0;
635 }
636 
637 int avs_register_all_boards(struct avs_dev *adev)
638 {
639 	int ret;
640 
641 #ifdef CONFIG_DEBUG_FS
642 	ret = avs_register_probe_board(adev);
643 	if (ret < 0)
644 		dev_warn(adev->dev, "enumerate PROBE endpoints failed: %d\n", ret);
645 #endif
646 
647 	ret = avs_register_dmic_board(adev);
648 	if (ret < 0)
649 		dev_warn(adev->dev, "enumerate DMIC endpoints failed: %d\n",
650 			 ret);
651 
652 	ret = avs_register_i2s_test_boards(adev);
653 	if (ret)
654 		dev_dbg(adev->dev, "enumerate I2S TEST endpoints failed: %d\n", ret);
655 
656 	ret = avs_register_i2s_boards(adev);
657 	if (ret < 0)
658 		dev_warn(adev->dev, "enumerate I2S endpoints failed: %d\n",
659 			 ret);
660 
661 	ret = avs_register_hda_boards(adev);
662 	if (ret < 0)
663 		dev_warn(adev->dev, "enumerate HDA endpoints failed: %d\n",
664 			 ret);
665 
666 	return 0;
667 }
668 
669 void avs_unregister_all_boards(struct avs_dev *adev)
670 {
671 	snd_soc_unregister_component(adev->dev);
672 }
673