Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/intel/avs/board_selection.c
26583 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
//
3
// Copyright(c) 2021-2022 Intel Corporation
4
//
5
// Authors: Cezary Rojewski <[email protected]>
6
// Amadeusz Slawinski <[email protected]>
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
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 = "10EC5640",
313
.uid = "1",
314
.drv_name = "avs_rt5640",
315
.mach_params = {
316
.i2s_link_mask = AVS_SSP(0),
317
},
318
.tplg_filename = "rt5640-tplg.bin",
319
},
320
{
321
.id = "10EC5640",
322
.uid = "3",
323
.drv_name = "avs_rt5640",
324
.mach_params = {
325
.i2s_link_mask = AVS_SSP(1),
326
},
327
.tplg_filename = "rt5640-tplg.bin",
328
},
329
{
330
.id = "10EC5640",
331
.uid = "2",
332
.drv_name = "avs_rt5640",
333
.mach_params = {
334
.i2s_link_mask = AVS_SSP(2),
335
},
336
.tplg_filename = "rt5640-tplg.bin",
337
},
338
{
339
.id = "ESSX8336",
340
.drv_name = "avs_es8336",
341
.mach_params = {
342
.i2s_link_mask = AVS_SSP(0),
343
},
344
.tplg_filename = "es8336-tplg.bin",
345
},
346
{},
347
};
348
349
static struct snd_soc_acpi_mach avs_mbl_i2s_machines[] = {
350
{
351
.id = "PCM3168A",
352
.drv_name = "avs_pcm3168a",
353
.mach_params = {
354
.i2s_link_mask = AVS_SSP(0) | AVS_SSP(2),
355
},
356
.tplg_filename = "pcm3168a-tplg.bin",
357
},
358
{}
359
};
360
361
struct avs_acpi_boards {
362
int id;
363
struct snd_soc_acpi_mach *machs;
364
};
365
366
#define AVS_MACH_ENTRY(_id, _mach) \
367
{ .id = PCI_DEVICE_ID_INTEL_##_id, .machs = (_mach), }
368
369
/* supported I2S boards per platform */
370
static const struct avs_acpi_boards i2s_boards[] = {
371
AVS_MACH_ENTRY(HDA_SKL_LP, avs_skl_i2s_machines),
372
AVS_MACH_ENTRY(HDA_KBL_LP, avs_kbl_i2s_machines),
373
AVS_MACH_ENTRY(HDA_APL, avs_apl_i2s_machines),
374
AVS_MACH_ENTRY(HDA_GML, avs_gml_i2s_machines),
375
AVS_MACH_ENTRY(HDA_CNL_LP, avs_cnl_i2s_machines),
376
AVS_MACH_ENTRY(HDA_CNL_H, avs_cnl_i2s_machines),
377
AVS_MACH_ENTRY(HDA_CML_LP, avs_cnl_i2s_machines),
378
AVS_MACH_ENTRY(HDA_ICL_LP, avs_icl_i2s_machines),
379
AVS_MACH_ENTRY(HDA_TGL_LP, avs_tgl_i2s_machines),
380
AVS_MACH_ENTRY(HDA_EHL_0, avs_tgl_i2s_machines),
381
AVS_MACH_ENTRY(HDA_ADL_N, avs_mbl_i2s_machines),
382
AVS_MACH_ENTRY(HDA_ADL_P, avs_tgl_i2s_machines),
383
AVS_MACH_ENTRY(HDA_RPL_P_0, avs_tgl_i2s_machines),
384
AVS_MACH_ENTRY(HDA_RPL_M, avs_mbl_i2s_machines),
385
AVS_MACH_ENTRY(HDA_FCL, avs_tgl_i2s_machines),
386
{ },
387
};
388
389
static const struct avs_acpi_boards *avs_get_i2s_boards(struct avs_dev *adev)
390
{
391
int id, i;
392
393
id = adev->base.pci->device;
394
for (i = 0; i < ARRAY_SIZE(i2s_boards); i++)
395
if (i2s_boards[i].id == id)
396
return &i2s_boards[i];
397
return NULL;
398
}
399
400
/* platform devices owned by AVS audio are removed with this hook */
401
static void board_pdev_unregister(void *data)
402
{
403
platform_device_unregister(data);
404
}
405
406
static int __maybe_unused avs_register_probe_board(struct avs_dev *adev)
407
{
408
struct platform_device *board;
409
struct snd_soc_acpi_mach mach = {{0}};
410
int ret;
411
412
ret = avs_probe_platform_register(adev, "probe-platform");
413
if (ret < 0)
414
return ret;
415
416
mach.mach_params.platform = "probe-platform";
417
418
board = platform_device_register_data(NULL, "avs_probe_mb", PLATFORM_DEVID_NONE,
419
(const void *)&mach, sizeof(mach));
420
if (IS_ERR(board)) {
421
dev_err(adev->dev, "probe board register failed\n");
422
return PTR_ERR(board);
423
}
424
425
ret = devm_add_action(adev->dev, board_pdev_unregister, board);
426
if (ret < 0) {
427
platform_device_unregister(board);
428
return ret;
429
}
430
return 0;
431
}
432
433
static int avs_register_dmic_board(struct avs_dev *adev)
434
{
435
struct platform_device *codec, *board;
436
struct snd_soc_acpi_mach mach = {{0}};
437
struct avs_mach_pdata *pdata;
438
int ret;
439
440
if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) {
441
dev_dbg(adev->dev, "no DMIC endpoints present\n");
442
return 0;
443
}
444
445
codec = platform_device_register_simple("dmic-codec", PLATFORM_DEVID_NONE, NULL, 0);
446
if (IS_ERR(codec)) {
447
dev_err(adev->dev, "dmic codec register failed\n");
448
return PTR_ERR(codec);
449
}
450
451
ret = devm_add_action(adev->dev, board_pdev_unregister, codec);
452
if (ret < 0) {
453
platform_device_unregister(codec);
454
return ret;
455
}
456
457
ret = avs_dmic_platform_register(adev, "dmic-platform");
458
if (ret < 0)
459
return ret;
460
461
pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
462
if (!pdata)
463
return -ENOMEM;
464
pdata->obsolete_card_names = obsolete_card_names;
465
mach.pdata = pdata;
466
mach.tplg_filename = "dmic-tplg.bin";
467
mach.mach_params.platform = "dmic-platform";
468
469
board = platform_device_register_data(NULL, "avs_dmic", PLATFORM_DEVID_NONE,
470
(const void *)&mach, sizeof(mach));
471
if (IS_ERR(board)) {
472
dev_err(adev->dev, "dmic board register failed\n");
473
return PTR_ERR(board);
474
}
475
476
ret = devm_add_action(adev->dev, board_pdev_unregister, board);
477
if (ret < 0) {
478
platform_device_unregister(board);
479
return ret;
480
}
481
482
return 0;
483
}
484
485
static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)
486
{
487
struct platform_device *board;
488
struct avs_mach_pdata *pdata;
489
int num_ssps;
490
char *name;
491
int ret;
492
int uid;
493
494
num_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
495
if (fls(mach->mach_params.i2s_link_mask) > num_ssps) {
496
dev_err(adev->dev, "Platform supports %d SSPs but board %s requires SSP%ld\n",
497
num_ssps, mach->drv_name,
498
(unsigned long)__fls(mach->mach_params.i2s_link_mask));
499
return -ENODEV;
500
}
501
502
pdata = mach->pdata;
503
if (!pdata)
504
pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
505
if (!pdata)
506
return -ENOMEM;
507
pdata->obsolete_card_names = obsolete_card_names;
508
mach->pdata = pdata;
509
510
uid = mach->mach_params.i2s_link_mask;
511
if (avs_mach_singular_ssp(mach))
512
uid = (uid << AVS_CHANNELS_MAX) + avs_mach_ssp_tdm(mach, avs_mach_ssp_port(mach));
513
514
name = devm_kasprintf(adev->dev, GFP_KERNEL, "%s.%d-platform", mach->drv_name, uid);
515
if (!name)
516
return -ENOMEM;
517
518
ret = avs_i2s_platform_register(adev, name, mach->mach_params.i2s_link_mask, pdata->tdms);
519
if (ret < 0)
520
return ret;
521
522
mach->mach_params.platform = name;
523
524
board = platform_device_register_data(NULL, mach->drv_name, uid,
525
(const void *)mach, sizeof(*mach));
526
if (IS_ERR(board)) {
527
dev_err(adev->dev, "ssp board register failed\n");
528
return PTR_ERR(board);
529
}
530
531
ret = devm_add_action(adev->dev, board_pdev_unregister, board);
532
if (ret < 0) {
533
platform_device_unregister(board);
534
return ret;
535
}
536
537
return 0;
538
}
539
540
static int avs_register_i2s_test_board(struct avs_dev *adev, int ssp_port, int tdm_slot)
541
{
542
struct snd_soc_acpi_mach *mach;
543
int tdm_mask = BIT(tdm_slot);
544
unsigned long *tdm_cfg;
545
char *tplg_name;
546
int ret;
547
548
mach = devm_kzalloc(adev->dev, sizeof(*mach), GFP_KERNEL);
549
tdm_cfg = devm_kcalloc(adev->dev, ssp_port + 1, sizeof(unsigned long), GFP_KERNEL);
550
tplg_name = devm_kasprintf(adev->dev, GFP_KERNEL, AVS_STRING_FMT("i2s", "-test-tplg.bin",
551
ssp_port, tdm_slot));
552
if (!mach || !tdm_cfg || !tplg_name)
553
return -ENOMEM;
554
555
mach->drv_name = "avs_i2s_test";
556
mach->mach_params.i2s_link_mask = AVS_SSP(ssp_port);
557
tdm_cfg[ssp_port] = tdm_mask;
558
mach->pdata = tdm_cfg;
559
mach->tplg_filename = tplg_name;
560
561
ret = avs_register_i2s_board(adev, mach);
562
if (ret < 0) {
563
dev_warn(adev->dev, "register i2s %s failed: %d\n", mach->drv_name, ret);
564
return ret;
565
}
566
567
return 0;
568
}
569
570
static int avs_register_i2s_test_boards(struct avs_dev *adev)
571
{
572
int max_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
573
int ssp_port, tdm_slot, ret;
574
unsigned long tdm_slots;
575
u32 *array, num_elems;
576
577
ret = parse_int_array(i2s_test, strlen(i2s_test), (int **)&array);
578
if (ret) {
579
dev_err(adev->dev, "failed to parse i2s_test parameter\n");
580
return ret;
581
}
582
583
num_elems = *array;
584
if (num_elems > max_ssps) {
585
dev_err(adev->dev, "board supports only %d SSP, %d specified\n",
586
max_ssps, num_elems);
587
return -EINVAL;
588
}
589
590
for (ssp_port = 0; ssp_port < num_elems; ssp_port++) {
591
tdm_slots = array[1 + ssp_port];
592
for_each_set_bit(tdm_slot, &tdm_slots, 16) {
593
ret = avs_register_i2s_test_board(adev, ssp_port, tdm_slot);
594
if (ret)
595
return ret;
596
}
597
}
598
599
return 0;
600
}
601
602
static int avs_register_i2s_boards(struct avs_dev *adev)
603
{
604
const struct avs_acpi_boards *boards;
605
struct snd_soc_acpi_mach *mach;
606
int ret;
607
608
if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_SSP, -1, -1, -1)) {
609
dev_dbg(adev->dev, "no I2S endpoints present\n");
610
return 0;
611
}
612
613
if (i2s_test)
614
return avs_register_i2s_test_boards(adev);
615
616
boards = avs_get_i2s_boards(adev);
617
if (!boards) {
618
dev_dbg(adev->dev, "no I2S endpoints supported\n");
619
return 0;
620
}
621
622
for (mach = boards->machs; mach->id[0]; mach++) {
623
if (!acpi_dev_present(mach->id, mach->uid, -1))
624
continue;
625
626
if (mach->machine_quirk)
627
if (!mach->machine_quirk(mach))
628
continue;
629
630
ret = avs_register_i2s_board(adev, mach);
631
if (ret < 0)
632
dev_warn(adev->dev, "register i2s %s failed: %d\n", mach->drv_name, ret);
633
}
634
635
return 0;
636
}
637
638
static int avs_register_hda_board(struct avs_dev *adev, struct hda_codec *codec)
639
{
640
struct snd_soc_acpi_mach mach = {{0}};
641
struct platform_device *board;
642
struct avs_mach_pdata *pdata;
643
struct hdac_device *hdev = &codec->core;
644
char *pname;
645
int ret, id;
646
647
pname = devm_kasprintf(adev->dev, GFP_KERNEL, "%s-platform", dev_name(&hdev->dev));
648
if (!pname)
649
return -ENOMEM;
650
651
pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
652
if (!pdata)
653
return -ENOMEM;
654
pdata->obsolete_card_names = obsolete_card_names;
655
pdata->codec = codec;
656
657
ret = avs_hda_platform_register(adev, pname);
658
if (ret < 0)
659
return ret;
660
661
mach.pdata = pdata;
662
mach.mach_params.platform = pname;
663
mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL, "hda-%08x-tplg.bin",
664
hdev->vendor_id);
665
if (!mach.tplg_filename)
666
return -ENOMEM;
667
668
id = adev->base.core.idx * HDA_MAX_CODECS + hdev->addr;
669
board = platform_device_register_data(NULL, "avs_hdaudio", id, (const void *)&mach,
670
sizeof(mach));
671
if (IS_ERR(board)) {
672
dev_err(adev->dev, "hda board register failed\n");
673
return PTR_ERR(board);
674
}
675
676
ret = devm_add_action(adev->dev, board_pdev_unregister, board);
677
if (ret < 0) {
678
platform_device_unregister(board);
679
return ret;
680
}
681
682
return 0;
683
}
684
685
static int avs_register_hda_boards(struct avs_dev *adev)
686
{
687
struct hdac_bus *bus = &adev->base.core;
688
struct hdac_device *hdev;
689
int ret;
690
691
if (!bus->num_codecs) {
692
dev_dbg(adev->dev, "no HDA endpoints present\n");
693
return 0;
694
}
695
696
list_for_each_entry(hdev, &bus->codec_list, list) {
697
struct hda_codec *codec;
698
699
codec = dev_to_hda_codec(&hdev->dev);
700
701
ret = avs_register_hda_board(adev, codec);
702
if (ret < 0)
703
dev_warn(adev->dev, "register hda-%08x failed: %d\n",
704
codec->core.vendor_id, ret);
705
}
706
707
return 0;
708
}
709
710
int avs_register_all_boards(struct avs_dev *adev)
711
{
712
int ret;
713
714
#ifdef CONFIG_DEBUG_FS
715
ret = avs_register_probe_board(adev);
716
if (ret < 0)
717
dev_warn(adev->dev, "enumerate PROBE endpoints failed: %d\n", ret);
718
#endif
719
720
ret = avs_register_dmic_board(adev);
721
if (ret < 0)
722
dev_warn(adev->dev, "enumerate DMIC endpoints failed: %d\n",
723
ret);
724
725
ret = avs_register_i2s_boards(adev);
726
if (ret < 0)
727
dev_warn(adev->dev, "enumerate I2S endpoints failed: %d\n",
728
ret);
729
730
ret = avs_register_hda_boards(adev);
731
if (ret < 0)
732
dev_warn(adev->dev, "enumerate HDA endpoints failed: %d\n",
733
ret);
734
735
return 0;
736
}
737
738
void avs_unregister_all_boards(struct avs_dev *adev)
739
{
740
snd_soc_unregister_component(adev->dev);
741
}
742
743