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