xref: /linux/sound/soc/intel/boards/sof_sdw.c (revision 27aa58180473f81990f35238dc8aec40d34c778d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (c) 2020 Intel Corporation
3 
4 /*
5  *  sof_sdw - ASOC Machine driver for Intel SoundWire platforms
6  */
7 
8 #include <linux/bitmap.h>
9 #include <linux/device.h>
10 #include <linux/dmi.h>
11 #include <linux/module.h>
12 #include <linux/soundwire/sdw.h>
13 #include <linux/soundwire/sdw_type.h>
14 #include <sound/soc.h>
15 #include <sound/soc-acpi.h>
16 #include "sof_sdw_common.h"
17 #include "../../codecs/rt711.h"
18 
19 unsigned long sof_sdw_quirk = RT711_JD1;
20 static int quirk_override = -1;
21 module_param_named(quirk, quirk_override, int, 0444);
22 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
23 
24 static void log_quirks(struct device *dev)
25 {
26 	if (SOF_JACK_JDSRC(sof_sdw_quirk))
27 		dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n",
28 			SOF_JACK_JDSRC(sof_sdw_quirk));
29 	if (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
30 		dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n");
31 	if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
32 		dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n");
33 	if (sof_sdw_quirk & SOF_SDW_PCH_DMIC)
34 		dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n");
35 	if (SOF_SSP_GET_PORT(sof_sdw_quirk))
36 		dev_dbg(dev, "SSP port %ld\n",
37 			SOF_SSP_GET_PORT(sof_sdw_quirk));
38 	if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION)
39 		dev_err(dev, "quirk SOF_SDW_NO_AGGREGATION enabled but no longer supported\n");
40 	if (sof_sdw_quirk & SOF_CODEC_SPKR)
41 		dev_dbg(dev, "quirk SOF_CODEC_SPKR enabled\n");
42 }
43 
44 static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
45 {
46 	sof_sdw_quirk = (unsigned long)id->driver_data;
47 	return 1;
48 }
49 
50 static const struct dmi_system_id sof_sdw_quirk_table[] = {
51 	/* CometLake devices */
52 	{
53 		.callback = sof_sdw_quirk_cb,
54 		.matches = {
55 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
56 			DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"),
57 		},
58 		.driver_data = (void *)SOF_SDW_PCH_DMIC,
59 	},
60 	{
61 		.callback = sof_sdw_quirk_cb,
62 		.matches = {
63 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
64 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
65 		},
66 		.driver_data = (void *)RT711_JD2,
67 	},
68 	{
69 		/* early version of SKU 09C6 */
70 		.callback = sof_sdw_quirk_cb,
71 		.matches = {
72 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
73 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
74 		},
75 		.driver_data = (void *)RT711_JD2,
76 	},
77 	{
78 		.callback = sof_sdw_quirk_cb,
79 		.matches = {
80 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
81 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
82 		},
83 		.driver_data = (void *)(RT711_JD2 |
84 					SOF_SDW_FOUR_SPK),
85 	},
86 	{
87 		.callback = sof_sdw_quirk_cb,
88 		.matches = {
89 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
90 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
91 		},
92 		.driver_data = (void *)(RT711_JD2 |
93 					SOF_SDW_FOUR_SPK),
94 	},
95 	/* IceLake devices */
96 	{
97 		.callback = sof_sdw_quirk_cb,
98 		.matches = {
99 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
100 			DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
101 		},
102 		.driver_data = (void *)SOF_SDW_PCH_DMIC,
103 	},
104 	/* TigerLake devices */
105 	{
106 		.callback = sof_sdw_quirk_cb,
107 		.matches = {
108 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
109 			DMI_MATCH(DMI_PRODUCT_NAME,
110 				  "Tiger Lake Client Platform"),
111 		},
112 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
113 					RT711_JD1 |
114 					SOF_SDW_PCH_DMIC |
115 					SOF_SSP_PORT(SOF_I2S_SSP2)),
116 	},
117 	{
118 		.callback = sof_sdw_quirk_cb,
119 		.matches = {
120 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
121 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E")
122 		},
123 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
124 					RT711_JD2),
125 	},
126 	{
127 		/* another SKU of Dell Latitude 9520 */
128 		.callback = sof_sdw_quirk_cb,
129 		.matches = {
130 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
131 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3F")
132 		},
133 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
134 					RT711_JD2),
135 	},
136 	{
137 		/* Dell XPS 9710 */
138 		.callback = sof_sdw_quirk_cb,
139 		.matches = {
140 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
141 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D")
142 		},
143 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
144 					RT711_JD2 |
145 					SOF_SDW_FOUR_SPK),
146 	},
147 	{
148 		.callback = sof_sdw_quirk_cb,
149 		.matches = {
150 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
151 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E")
152 		},
153 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
154 					RT711_JD2 |
155 					SOF_SDW_FOUR_SPK),
156 	},
157 	{
158 		.callback = sof_sdw_quirk_cb,
159 		.matches = {
160 			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
161 			DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"),
162 		},
163 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
164 					SOF_SDW_PCH_DMIC |
165 					SOF_SDW_FOUR_SPK |
166 					SOF_BT_OFFLOAD_SSP(2) |
167 					SOF_SSP_BT_OFFLOAD_PRESENT),
168 	},
169 	{
170 		.callback = sof_sdw_quirk_cb,
171 		.matches = {
172 			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
173 			DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"),
174 		},
175 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
176 					SOF_SDW_PCH_DMIC |
177 					SOF_SDW_FOUR_SPK),
178 	},
179 	{
180 		/*
181 		 * this entry covers multiple HP SKUs. The family name
182 		 * does not seem robust enough, so we use a partial
183 		 * match that ignores the product name suffix
184 		 * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx)
185 		 */
186 		.callback = sof_sdw_quirk_cb,
187 		.matches = {
188 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
189 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"),
190 		},
191 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
192 					SOF_SDW_PCH_DMIC |
193 					RT711_JD1),
194 	},
195 	{
196 		/*
197 		 * this entry covers HP Spectre x360 where the DMI information
198 		 * changed somehow
199 		 */
200 		.callback = sof_sdw_quirk_cb,
201 		.matches = {
202 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
203 			DMI_MATCH(DMI_BOARD_NAME, "8709"),
204 		},
205 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
206 					SOF_SDW_PCH_DMIC |
207 					RT711_JD1),
208 	},
209 	{
210 		/* NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */
211 		.callback = sof_sdw_quirk_cb,
212 		.matches = {
213 			DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
214 			DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"),
215 		},
216 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
217 					SOF_SDW_PCH_DMIC |
218 					RT711_JD1),
219 	},
220 	{
221 		/* NUC15 LAPBC710 skews */
222 		.callback = sof_sdw_quirk_cb,
223 		.matches = {
224 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
225 			DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
226 		},
227 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
228 					SOF_SDW_PCH_DMIC |
229 					RT711_JD1),
230 	},
231 	{
232 		/* NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */
233 		.callback = sof_sdw_quirk_cb,
234 		.matches = {
235 			DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
236 			DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"),
237 		},
238 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
239 					SOF_SDW_PCH_DMIC |
240 					RT711_JD2_100K),
241 	},
242 	{
243 		/* NUC15 LAPRC710 skews */
244 		.callback = sof_sdw_quirk_cb,
245 		.matches = {
246 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
247 			DMI_MATCH(DMI_BOARD_NAME, "LAPRC710"),
248 		},
249 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
250 					SOF_SDW_PCH_DMIC |
251 					RT711_JD2_100K),
252 	},
253 	/* TigerLake-SDCA devices */
254 	{
255 		.callback = sof_sdw_quirk_cb,
256 		.matches = {
257 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
258 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32")
259 		},
260 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
261 					RT711_JD2 |
262 					SOF_SDW_FOUR_SPK),
263 	},
264 	{
265 		.callback = sof_sdw_quirk_cb,
266 		.matches = {
267 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
268 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A45")
269 		},
270 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
271 					RT711_JD2),
272 	},
273 	/* AlderLake devices */
274 	{
275 		.callback = sof_sdw_quirk_cb,
276 		.matches = {
277 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
278 			DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
279 		},
280 		.driver_data = (void *)(RT711_JD2_100K |
281 					SOF_SDW_TGL_HDMI |
282 					SOF_BT_OFFLOAD_SSP(2) |
283 					SOF_SSP_BT_OFFLOAD_PRESENT),
284 	},
285 	{
286 		.callback = sof_sdw_quirk_cb,
287 		.matches = {
288 			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
289 			DMI_MATCH(DMI_PRODUCT_NAME, "Brya"),
290 		},
291 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
292 					SOF_SDW_PCH_DMIC |
293 					SOF_SDW_FOUR_SPK |
294 					SOF_BT_OFFLOAD_SSP(2) |
295 					SOF_SSP_BT_OFFLOAD_PRESENT),
296 	},
297 	{
298 		.callback = sof_sdw_quirk_cb,
299 		.matches = {
300 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
301 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF0")
302 		},
303 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
304 					RT711_JD2 |
305 					SOF_SDW_FOUR_SPK),
306 	},
307 	{
308 		.callback = sof_sdw_quirk_cb,
309 		.matches = {
310 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
311 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF3"),
312 		},
313 		/* No Jack */
314 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
315 					SOF_SDW_FOUR_SPK),
316 	},
317 	{
318 		.callback = sof_sdw_quirk_cb,
319 		.matches = {
320 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
321 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE")
322 		},
323 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
324 					RT711_JD2 |
325 					SOF_SDW_FOUR_SPK),
326 	},
327 	{
328 		.callback = sof_sdw_quirk_cb,
329 		.matches = {
330 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
331 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF")
332 		},
333 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
334 					RT711_JD2 |
335 					SOF_SDW_FOUR_SPK),
336 	},
337 	{
338 		.callback = sof_sdw_quirk_cb,
339 		.matches = {
340 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
341 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00")
342 		},
343 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
344 					RT711_JD2 |
345 					SOF_SDW_FOUR_SPK),
346 	},
347 	{
348 		.callback = sof_sdw_quirk_cb,
349 		.matches = {
350 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
351 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01")
352 		},
353 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
354 					RT711_JD2 |
355 					SOF_SDW_FOUR_SPK),
356 	},
357 	{
358 		.callback = sof_sdw_quirk_cb,
359 		.matches = {
360 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
361 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B11")
362 		},
363 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
364 					RT711_JD2 |
365 					SOF_SDW_FOUR_SPK),
366 	},
367 	{
368 		.callback = sof_sdw_quirk_cb,
369 		.matches = {
370 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
371 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B12")
372 		},
373 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
374 					RT711_JD2 |
375 					SOF_SDW_FOUR_SPK),
376 	},
377 	{
378 		.callback = sof_sdw_quirk_cb,
379 		.matches = {
380 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
381 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B13"),
382 		},
383 		/* No Jack */
384 		.driver_data = (void *)SOF_SDW_TGL_HDMI,
385 	},
386 	{
387 		.callback = sof_sdw_quirk_cb,
388 		.matches = {
389 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
390 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B14"),
391 		},
392 		/* No Jack */
393 		.driver_data = (void *)SOF_SDW_TGL_HDMI,
394 	},
395 
396 	{
397 		.callback = sof_sdw_quirk_cb,
398 		.matches = {
399 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
400 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B29"),
401 		},
402 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
403 					RT711_JD2 |
404 					SOF_SDW_FOUR_SPK),
405 	},
406 	{
407 		.callback = sof_sdw_quirk_cb,
408 		.matches = {
409 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
410 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B34"),
411 		},
412 		/* No Jack */
413 		.driver_data = (void *)SOF_SDW_TGL_HDMI,
414 	},
415 	{
416 		.callback = sof_sdw_quirk_cb,
417 		.matches = {
418 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
419 			DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"),
420 		},
421 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
422 					RT711_JD2),
423 	},
424 	/* RaptorLake devices */
425 	{
426 		.callback = sof_sdw_quirk_cb,
427 		.matches = {
428 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
429 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0BDA")
430 		},
431 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
432 					RT711_JD2 |
433 					SOF_SDW_FOUR_SPK),
434 	},
435 	{
436 		.callback = sof_sdw_quirk_cb,
437 		.matches = {
438 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
439 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"),
440 		},
441 		/* No Jack */
442 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
443 					SOF_SDW_FOUR_SPK),
444 	},
445 	{
446 		.callback = sof_sdw_quirk_cb,
447 		.matches = {
448 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
449 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C11")
450 		},
451 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
452 					RT711_JD2 |
453 					SOF_SDW_FOUR_SPK),
454 	},
455 	{
456 		.callback = sof_sdw_quirk_cb,
457 		.matches = {
458 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
459 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C40")
460 		},
461 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
462 					RT711_JD2 |
463 					SOF_SDW_FOUR_SPK),
464 	},
465 	{
466 		.callback = sof_sdw_quirk_cb,
467 		.matches = {
468 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
469 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C4F")
470 		},
471 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
472 					RT711_JD2 |
473 					SOF_SDW_FOUR_SPK),
474 	},
475 	/* MeteorLake devices */
476 	{
477 		.callback = sof_sdw_quirk_cb,
478 		.matches = {
479 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"),
480 		},
481 		.driver_data = (void *)(RT711_JD1),
482 	},
483 	{
484 		.callback = sof_sdw_quirk_cb,
485 		.matches = {
486 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
487 			DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"),
488 		},
489 		.driver_data = (void *)(RT711_JD2_100K),
490 	},
491 	{
492 		.callback = sof_sdw_quirk_cb,
493 		.matches = {
494 			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
495 			DMI_MATCH(DMI_PRODUCT_NAME, "Rex"),
496 		},
497 		.driver_data = (void *)(SOF_SDW_PCH_DMIC |
498 					SOF_BT_OFFLOAD_SSP(1) |
499 					SOF_SSP_BT_OFFLOAD_PRESENT),
500 	},
501 	/* LunarLake devices */
502 	{
503 		.callback = sof_sdw_quirk_cb,
504 		.matches = {
505 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
506 			DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"),
507 		},
508 		.driver_data = (void *)(RT711_JD2),
509 	},
510 	{}
511 };
512 
513 static struct snd_soc_dai_link_component platform_component[] = {
514 	{
515 		/* name might be overridden during probe */
516 		.name = "0000:00:1f.3"
517 	}
518 };
519 
520 struct snd_soc_dai *get_codec_dai_by_name(struct snd_soc_pcm_runtime *rtd,
521 					  const char * const dai_name[],
522 					  int num_dais)
523 {
524 	struct snd_soc_dai *dai;
525 	int index;
526 	int i;
527 
528 	for (index = 0; index < num_dais; index++)
529 		for_each_rtd_codec_dais(rtd, i, dai)
530 			if (strstr(dai->name, dai_name[index])) {
531 				dev_dbg(rtd->card->dev, "get dai %s\n", dai->name);
532 				return dai;
533 			}
534 
535 	return NULL;
536 }
537 
538 /* these wrappers are only needed to avoid typecast compilation errors */
539 int sdw_startup(struct snd_pcm_substream *substream)
540 {
541 	return sdw_startup_stream(substream);
542 }
543 
544 int sdw_prepare(struct snd_pcm_substream *substream)
545 {
546 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
547 	struct sdw_stream_runtime *sdw_stream;
548 	struct snd_soc_dai *dai;
549 
550 	/* Find stream from first CPU DAI */
551 	dai = snd_soc_rtd_to_cpu(rtd, 0);
552 
553 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
554 	if (IS_ERR(sdw_stream)) {
555 		dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
556 		return PTR_ERR(sdw_stream);
557 	}
558 
559 	return sdw_prepare_stream(sdw_stream);
560 }
561 
562 int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
563 {
564 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
565 	struct sdw_stream_runtime *sdw_stream;
566 	struct snd_soc_dai *dai;
567 	int ret;
568 
569 	/* Find stream from first CPU DAI */
570 	dai = snd_soc_rtd_to_cpu(rtd, 0);
571 
572 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
573 	if (IS_ERR(sdw_stream)) {
574 		dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
575 		return PTR_ERR(sdw_stream);
576 	}
577 
578 	switch (cmd) {
579 	case SNDRV_PCM_TRIGGER_START:
580 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
581 	case SNDRV_PCM_TRIGGER_RESUME:
582 		ret = sdw_enable_stream(sdw_stream);
583 		break;
584 
585 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
586 	case SNDRV_PCM_TRIGGER_SUSPEND:
587 	case SNDRV_PCM_TRIGGER_STOP:
588 		ret = sdw_disable_stream(sdw_stream);
589 		break;
590 	default:
591 		ret = -EINVAL;
592 		break;
593 	}
594 
595 	if (ret)
596 		dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret);
597 
598 	return ret;
599 }
600 
601 int sdw_hw_params(struct snd_pcm_substream *substream,
602 		  struct snd_pcm_hw_params *params)
603 {
604 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
605 	struct snd_soc_dai_link_ch_map *ch_maps;
606 	int ch = params_channels(params);
607 	unsigned int ch_mask;
608 	int num_codecs;
609 	int step;
610 	int i;
611 
612 	if (!rtd->dai_link->ch_maps)
613 		return 0;
614 
615 	/* Identical data will be sent to all codecs in playback */
616 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
617 		ch_mask = GENMASK(ch - 1, 0);
618 		step = 0;
619 	} else {
620 		num_codecs = rtd->dai_link->num_codecs;
621 
622 		if (ch < num_codecs || ch % num_codecs != 0) {
623 			dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n",
624 				ch, num_codecs);
625 			return -EINVAL;
626 		}
627 
628 		ch_mask = GENMASK(ch / num_codecs - 1, 0);
629 		step = hweight_long(ch_mask);
630 
631 	}
632 
633 	/*
634 	 * The captured data will be combined from each cpu DAI if the dai
635 	 * link has more than one codec DAIs. Set codec channel mask and
636 	 * ASoC will set the corresponding channel numbers for each cpu dai.
637 	 */
638 	for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
639 		ch_maps->ch_mask = ch_mask << (i * step);
640 
641 	return 0;
642 }
643 
644 int sdw_hw_free(struct snd_pcm_substream *substream)
645 {
646 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
647 	struct sdw_stream_runtime *sdw_stream;
648 	struct snd_soc_dai *dai;
649 
650 	/* Find stream from first CPU DAI */
651 	dai = snd_soc_rtd_to_cpu(rtd, 0);
652 
653 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
654 	if (IS_ERR(sdw_stream)) {
655 		dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
656 		return PTR_ERR(sdw_stream);
657 	}
658 
659 	return sdw_deprepare_stream(sdw_stream);
660 }
661 
662 void sdw_shutdown(struct snd_pcm_substream *substream)
663 {
664 	sdw_shutdown_stream(substream);
665 }
666 
667 static const struct snd_soc_ops sdw_ops = {
668 	.startup = sdw_startup,
669 	.prepare = sdw_prepare,
670 	.trigger = sdw_trigger,
671 	.hw_params = sdw_hw_params,
672 	.hw_free = sdw_hw_free,
673 	.shutdown = sdw_shutdown,
674 };
675 
676 static struct sof_sdw_codec_info codec_info_list[] = {
677 	{
678 		.part_id = 0x700,
679 		.dais = {
680 			{
681 				.direction = {true, true},
682 				.dai_name = "rt700-aif1",
683 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
684 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
685 				.rtd_init = rt700_rtd_init,
686 			},
687 		},
688 		.dai_num = 1,
689 	},
690 	{
691 		.part_id = 0x711,
692 		.version_id = 3,
693 		.dais = {
694 			{
695 				.direction = {true, true},
696 				.dai_name = "rt711-sdca-aif1",
697 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
698 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
699 				.init = sof_sdw_rt_sdca_jack_init,
700 				.exit = sof_sdw_rt_sdca_jack_exit,
701 				.rtd_init = rt_sdca_jack_rtd_init,
702 			},
703 		},
704 		.dai_num = 1,
705 	},
706 	{
707 		.part_id = 0x711,
708 		.version_id = 2,
709 		.dais = {
710 			{
711 				.direction = {true, true},
712 				.dai_name = "rt711-aif1",
713 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
714 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
715 				.init = sof_sdw_rt711_init,
716 				.exit = sof_sdw_rt711_exit,
717 				.rtd_init = rt711_rtd_init,
718 			},
719 		},
720 		.dai_num = 1,
721 	},
722 	{
723 		.part_id = 0x712,
724 		.version_id = 3,
725 		.dais =	{
726 			{
727 				.direction = {true, true},
728 				.dai_name = "rt712-sdca-aif1",
729 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
730 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
731 				.init = sof_sdw_rt_sdca_jack_init,
732 				.exit = sof_sdw_rt_sdca_jack_exit,
733 				.rtd_init = rt_sdca_jack_rtd_init,
734 			},
735 			{
736 				.direction = {true, false},
737 				.dai_name = "rt712-sdca-aif2",
738 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
739 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
740 				.rtd_init = rt712_spk_rtd_init,
741 			},
742 		},
743 		.dai_num = 2,
744 	},
745 	{
746 		.part_id = 0x1712,
747 		.version_id = 3,
748 		.dais =	{
749 			{
750 				.direction = {false, true},
751 				.dai_name = "rt712-sdca-dmic-aif1",
752 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
753 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
754 				.rtd_init = rt_dmic_rtd_init,
755 			},
756 		},
757 		.dai_num = 1,
758 	},
759 	{
760 		.part_id = 0x713,
761 		.version_id = 3,
762 		.dais =	{
763 			{
764 				.direction = {true, true},
765 				.dai_name = "rt712-sdca-aif1",
766 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
767 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
768 				.init = sof_sdw_rt_sdca_jack_init,
769 				.exit = sof_sdw_rt_sdca_jack_exit,
770 				.rtd_init = rt_sdca_jack_rtd_init,
771 			},
772 		},
773 		.dai_num = 1,
774 	},
775 	{
776 		.part_id = 0x1713,
777 		.version_id = 3,
778 		.dais =	{
779 			{
780 				.direction = {false, true},
781 				.dai_name = "rt712-sdca-dmic-aif1",
782 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
783 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
784 				.rtd_init = rt_dmic_rtd_init,
785 			},
786 		},
787 		.dai_num = 1,
788 	},
789 	{
790 		.part_id = 0x1308,
791 		.acpi_id = "10EC1308",
792 		.dais = {
793 			{
794 				.direction = {true, false},
795 				.dai_name = "rt1308-aif",
796 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
797 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
798 				.init = sof_sdw_rt_amp_init,
799 				.exit = sof_sdw_rt_amp_exit,
800 				.rtd_init = rt_amp_spk_rtd_init,
801 			},
802 		},
803 		.dai_num = 1,
804 		.ops = &sof_sdw_rt1308_i2s_ops,
805 	},
806 	{
807 		.part_id = 0x1316,
808 		.dais = {
809 			{
810 				.direction = {true, true},
811 				.dai_name = "rt1316-aif",
812 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
813 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
814 				.init = sof_sdw_rt_amp_init,
815 				.exit = sof_sdw_rt_amp_exit,
816 				.rtd_init = rt_amp_spk_rtd_init,
817 			},
818 		},
819 		.dai_num = 1,
820 	},
821 	{
822 		.part_id = 0x1318,
823 		.dais = {
824 			{
825 				.direction = {true, true},
826 				.dai_name = "rt1318-aif",
827 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
828 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
829 				.init = sof_sdw_rt_amp_init,
830 				.exit = sof_sdw_rt_amp_exit,
831 				.rtd_init = rt_amp_spk_rtd_init,
832 			},
833 		},
834 		.dai_num = 1,
835 	},
836 	{
837 		.part_id = 0x714,
838 		.version_id = 3,
839 		.ignore_pch_dmic = true,
840 		.dais = {
841 			{
842 				.direction = {false, true},
843 				.dai_name = "rt715-sdca-aif2",
844 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
845 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
846 				.rtd_init = rt_dmic_rtd_init,
847 			},
848 		},
849 		.dai_num = 1,
850 	},
851 	{
852 		.part_id = 0x715,
853 		.version_id = 3,
854 		.ignore_pch_dmic = true,
855 		.dais = {
856 			{
857 				.direction = {false, true},
858 				.dai_name = "rt715-sdca-aif2",
859 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
860 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
861 				.rtd_init = rt_dmic_rtd_init,
862 			},
863 		},
864 		.dai_num = 1,
865 	},
866 	{
867 		.part_id = 0x714,
868 		.version_id = 2,
869 		.ignore_pch_dmic = true,
870 		.dais = {
871 			{
872 				.direction = {false, true},
873 				.dai_name = "rt715-aif2",
874 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
875 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
876 				.rtd_init = rt_dmic_rtd_init,
877 			},
878 		},
879 		.dai_num = 1,
880 	},
881 	{
882 		.part_id = 0x715,
883 		.version_id = 2,
884 		.ignore_pch_dmic = true,
885 		.dais = {
886 			{
887 				.direction = {false, true},
888 				.dai_name = "rt715-aif2",
889 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
890 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
891 				.rtd_init = rt_dmic_rtd_init,
892 			},
893 		},
894 		.dai_num = 1,
895 	},
896 	{
897 		.part_id = 0x722,
898 		.version_id = 3,
899 		.dais = {
900 			{
901 				.direction = {true, true},
902 				.dai_name = "rt722-sdca-aif1",
903 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
904 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
905 				.init = sof_sdw_rt_sdca_jack_init,
906 				.exit = sof_sdw_rt_sdca_jack_exit,
907 				.rtd_init = rt_sdca_jack_rtd_init,
908 			},
909 			{
910 				.direction = {true, false},
911 				.dai_name = "rt722-sdca-aif2",
912 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
913 				/* No feedback capability is provided by rt722-sdca codec driver*/
914 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
915 				.rtd_init = rt722_spk_rtd_init,
916 			},
917 			{
918 				.direction = {false, true},
919 				.dai_name = "rt722-sdca-aif3",
920 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
921 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
922 				.rtd_init = rt_dmic_rtd_init,
923 			},
924 		},
925 		.dai_num = 3,
926 	},
927 	{
928 		.part_id = 0x8373,
929 		.dais = {
930 			{
931 				.direction = {true, true},
932 				.dai_name = "max98373-aif1",
933 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
934 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
935 				.init = sof_sdw_maxim_init,
936 				.rtd_init = maxim_spk_rtd_init,
937 			},
938 		},
939 		.dai_num = 1,
940 	},
941 	{
942 		.part_id = 0x8363,
943 		.dais = {
944 			{
945 				.direction = {true, false},
946 				.dai_name = "max98363-aif1",
947 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
948 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
949 				.init = sof_sdw_maxim_init,
950 				.rtd_init = maxim_spk_rtd_init,
951 			},
952 		},
953 		.dai_num = 1,
954 	},
955 	{
956 		.part_id = 0x5682,
957 		.dais = {
958 			{
959 				.direction = {true, true},
960 				.dai_name = "rt5682-sdw",
961 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
962 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
963 				.rtd_init = rt5682_rtd_init,
964 			},
965 		},
966 		.dai_num = 1,
967 	},
968 	{
969 		.part_id = 0x3556,
970 		.dais = {
971 			{
972 				.direction = {true, true},
973 				.dai_name = "cs35l56-sdw1",
974 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
975 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
976 				.init = sof_sdw_cs_amp_init,
977 				.rtd_init = cs_spk_rtd_init,
978 			},
979 		},
980 		.dai_num = 1,
981 	},
982 	{
983 		.part_id = 0x4242,
984 		.dais = {
985 			{
986 				.direction = {true, true},
987 				.dai_name = "cs42l42-sdw",
988 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
989 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
990 				.rtd_init = cs42l42_rtd_init,
991 			},
992 		},
993 		.dai_num = 1,
994 	},
995 	{
996 		.part_id = 0x4243,
997 		.codec_name = "cs42l43-codec",
998 		.dais = {
999 			{
1000 				.direction = {true, false},
1001 				.dai_name = "cs42l43-dp5",
1002 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1003 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
1004 				.rtd_init = cs42l43_hs_rtd_init,
1005 			},
1006 			{
1007 				.direction = {false, true},
1008 				.dai_name = "cs42l43-dp1",
1009 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
1010 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
1011 				.rtd_init = cs42l43_dmic_rtd_init,
1012 			},
1013 			{
1014 				.direction = {false, true},
1015 				.dai_name = "cs42l43-dp2",
1016 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1017 				.dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID},
1018 			},
1019 			{
1020 				.direction = {true, false},
1021 				.dai_name = "cs42l43-dp6",
1022 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
1023 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
1024 				.init = sof_sdw_cs42l43_spk_init,
1025 				.rtd_init = cs42l43_spk_rtd_init,
1026 				.quirk = SOF_CODEC_SPKR,
1027 			},
1028 		},
1029 		.dai_num = 4,
1030 	},
1031 	{
1032 		.part_id = 0xaaaa, /* generic codec mockup */
1033 		.version_id = 0,
1034 		.dais = {
1035 			{
1036 				.direction = {true, true},
1037 				.dai_name = "sdw-mockup-aif1",
1038 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1039 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
1040 			},
1041 		},
1042 		.dai_num = 1,
1043 	},
1044 	{
1045 		.part_id = 0xaa55, /* headset codec mockup */
1046 		.version_id = 0,
1047 		.dais = {
1048 			{
1049 				.direction = {true, true},
1050 				.dai_name = "sdw-mockup-aif1",
1051 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1052 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
1053 			},
1054 		},
1055 		.dai_num = 1,
1056 	},
1057 	{
1058 		.part_id = 0x55aa, /* amplifier mockup */
1059 		.version_id = 0,
1060 		.dais = {
1061 			{
1062 				.direction = {true, true},
1063 				.dai_name = "sdw-mockup-aif1",
1064 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
1065 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
1066 			},
1067 		},
1068 		.dai_num = 1,
1069 	},
1070 	{
1071 		.part_id = 0x5555,
1072 		.version_id = 0,
1073 		.dais = {
1074 			{
1075 				.dai_name = "sdw-mockup-aif1",
1076 				.direction = {false, true},
1077 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
1078 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
1079 			},
1080 		},
1081 		.dai_num = 1,
1082 	},
1083 };
1084 
1085 static struct sof_sdw_codec_info *find_codec_info_part(const u64 adr)
1086 {
1087 	unsigned int part_id, sdw_version;
1088 	int i;
1089 
1090 	part_id = SDW_PART_ID(adr);
1091 	sdw_version = SDW_VERSION(adr);
1092 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1093 		/*
1094 		 * A codec info is for all sdw version with the part id if
1095 		 * version_id is not specified in the codec info.
1096 		 */
1097 		if (part_id == codec_info_list[i].part_id &&
1098 		    (!codec_info_list[i].version_id ||
1099 		     sdw_version == codec_info_list[i].version_id))
1100 			return &codec_info_list[i];
1101 
1102 	return NULL;
1103 
1104 }
1105 
1106 static struct sof_sdw_codec_info *find_codec_info_acpi(const u8 *acpi_id)
1107 {
1108 	int i;
1109 
1110 	if (!acpi_id[0])
1111 		return NULL;
1112 
1113 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1114 		if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN))
1115 			return &codec_info_list[i];
1116 
1117 	return NULL;
1118 }
1119 
1120 static struct sof_sdw_codec_info *find_codec_info_dai(const char *dai_name,
1121 						      int *dai_index)
1122 {
1123 	int i, j;
1124 
1125 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
1126 		for (j = 0; j < codec_info_list[i].dai_num; j++) {
1127 			if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) {
1128 				*dai_index = j;
1129 				return &codec_info_list[i];
1130 			}
1131 		}
1132 	}
1133 
1134 	return NULL;
1135 }
1136 
1137 static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
1138 			  int *be_id, char *name, int playback, int capture,
1139 			  struct snd_soc_dai_link_component *cpus, int cpus_num,
1140 			  struct snd_soc_dai_link_component *codecs, int codecs_num,
1141 			  int (*init)(struct snd_soc_pcm_runtime *rtd),
1142 			  const struct snd_soc_ops *ops)
1143 {
1144 	dev_dbg(dev, "create dai link %s, id %d\n", name, *be_id);
1145 	dai_links->id = (*be_id)++;
1146 	dai_links->name = name;
1147 	dai_links->platforms = platform_component;
1148 	dai_links->num_platforms = ARRAY_SIZE(platform_component);
1149 	dai_links->no_pcm = 1;
1150 	dai_links->cpus = cpus;
1151 	dai_links->num_cpus = cpus_num;
1152 	dai_links->codecs = codecs;
1153 	dai_links->num_codecs = codecs_num;
1154 	dai_links->dpcm_playback = playback;
1155 	dai_links->dpcm_capture = capture;
1156 	dai_links->init = init;
1157 	dai_links->ops = ops;
1158 }
1159 
1160 static int init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
1161 				int *be_id, char *name, int playback, int capture,
1162 				const char *cpu_dai_name,
1163 				const char *codec_name, const char *codec_dai_name,
1164 				int (*init)(struct snd_soc_pcm_runtime *rtd),
1165 				const struct snd_soc_ops *ops)
1166 {
1167 	struct snd_soc_dai_link_component *dlc;
1168 
1169 	/* Allocate two DLCs one for the CPU, one for the CODEC */
1170 	dlc = devm_kcalloc(dev, 2, sizeof(*dlc), GFP_KERNEL);
1171 	if (!dlc || !name || !cpu_dai_name || !codec_name || !codec_dai_name)
1172 		return -ENOMEM;
1173 
1174 	dlc[0].dai_name = cpu_dai_name;
1175 
1176 	dlc[1].name = codec_name;
1177 	dlc[1].dai_name = codec_dai_name;
1178 
1179 	init_dai_link(dev, dai_links, be_id, name, playback, capture,
1180 		      &dlc[0], 1, &dlc[1], 1, init, ops);
1181 
1182 	return 0;
1183 }
1184 
1185 static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link,
1186 			     unsigned int sdw_version,
1187 			     unsigned int mfg_id,
1188 			     unsigned int part_id,
1189 			     unsigned int class_id,
1190 			     int index_in_link)
1191 {
1192 	int i;
1193 
1194 	for (i = 0; i < adr_link->num_adr; i++) {
1195 		unsigned int sdw1_version, mfg1_id, part1_id, class1_id;
1196 		u64 adr;
1197 
1198 		/* skip itself */
1199 		if (i == index_in_link)
1200 			continue;
1201 
1202 		adr = adr_link->adr_d[i].adr;
1203 
1204 		sdw1_version = SDW_VERSION(adr);
1205 		mfg1_id = SDW_MFG_ID(adr);
1206 		part1_id = SDW_PART_ID(adr);
1207 		class1_id = SDW_CLASS_ID(adr);
1208 
1209 		if (sdw_version == sdw1_version &&
1210 		    mfg_id == mfg1_id &&
1211 		    part_id == part1_id &&
1212 		    class_id == class1_id)
1213 			return false;
1214 	}
1215 
1216 	return true;
1217 }
1218 
1219 static const char *get_codec_name(struct device *dev,
1220 				  const struct sof_sdw_codec_info *codec_info,
1221 				  const struct snd_soc_acpi_link_adr *adr_link,
1222 				  int adr_index)
1223 {
1224 	u64 adr = adr_link->adr_d[adr_index].adr;
1225 	unsigned int sdw_version = SDW_VERSION(adr);
1226 	unsigned int link_id = SDW_DISCO_LINK_ID(adr);
1227 	unsigned int unique_id = SDW_UNIQUE_ID(adr);
1228 	unsigned int mfg_id = SDW_MFG_ID(adr);
1229 	unsigned int part_id = SDW_PART_ID(adr);
1230 	unsigned int class_id = SDW_CLASS_ID(adr);
1231 
1232 	if (codec_info->codec_name)
1233 		return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL);
1234 	else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id,
1235 				  class_id, adr_index))
1236 		return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x",
1237 				      link_id, mfg_id, part_id, class_id);
1238 	else
1239 		return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x:%01x",
1240 				      link_id, mfg_id, part_id, class_id, unique_id);
1241 
1242 	return NULL;
1243 }
1244 
1245 static int sof_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
1246 {
1247 	struct sof_sdw_codec_info *codec_info;
1248 	struct snd_soc_dai *dai;
1249 	int dai_index;
1250 	int ret;
1251 	int i;
1252 
1253 	for_each_rtd_codec_dais(rtd, i, dai) {
1254 		codec_info = find_codec_info_dai(dai->name, &dai_index);
1255 		if (!codec_info)
1256 			return -EINVAL;
1257 
1258 		/*
1259 		 * A codec dai can be connected to different dai links for capture and playback,
1260 		 * but we only need to call the rtd_init function once.
1261 		 * The rtd_init for each codec dai is independent. So, the order of rtd_init
1262 		 * doesn't matter.
1263 		 */
1264 		if (codec_info->dais[dai_index].rtd_init_done)
1265 			continue;
1266 		if (codec_info->dais[dai_index].rtd_init) {
1267 			ret = codec_info->dais[dai_index].rtd_init(rtd);
1268 			if (ret)
1269 				return ret;
1270 		}
1271 		codec_info->dais[dai_index].rtd_init_done = true;
1272 	}
1273 
1274 	return 0;
1275 }
1276 
1277 struct sof_sdw_endpoint {
1278 	struct list_head list;
1279 
1280 	u32 link_mask;
1281 	const char *codec_name;
1282 
1283 	struct sof_sdw_codec_info *codec_info;
1284 	const struct sof_sdw_dai_info *dai_info;
1285 };
1286 
1287 struct sof_sdw_dailink {
1288 	bool initialised;
1289 
1290 	u8 group_id;
1291 	u32 link_mask[SNDRV_PCM_STREAM_LAST + 1];
1292 	int num_devs[SNDRV_PCM_STREAM_LAST + 1];
1293 	struct list_head endpoints;
1294 };
1295 
1296 static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"};
1297 
1298 static int count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends)
1299 {
1300 	struct device *dev = card->dev;
1301 	struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
1302 	struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
1303 	const struct snd_soc_acpi_link_adr *adr_link;
1304 	int i;
1305 
1306 	for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
1307 		*num_devs += adr_link->num_adr;
1308 
1309 		for (i = 0; i < adr_link->num_adr; i++)
1310 			*num_ends += adr_link->adr_d[i].num_endpoints;
1311 	}
1312 
1313 	dev_dbg(dev, "Found %d devices with %d endpoints\n", *num_devs, *num_ends);
1314 
1315 	return 0;
1316 }
1317 
1318 static struct sof_sdw_dailink *find_dailink(struct sof_sdw_dailink *dailinks,
1319 					    const struct snd_soc_acpi_endpoint *new)
1320 {
1321 	while (dailinks->initialised) {
1322 		if (new->aggregated && dailinks->group_id == new->group_id)
1323 			return dailinks;
1324 
1325 		dailinks++;
1326 	}
1327 
1328 	INIT_LIST_HEAD(&dailinks->endpoints);
1329 	dailinks->group_id = new->group_id;
1330 	dailinks->initialised = true;
1331 
1332 	return dailinks;
1333 }
1334 
1335 static int parse_sdw_endpoints(struct snd_soc_card *card,
1336 			       struct sof_sdw_dailink *sof_dais,
1337 			       struct sof_sdw_endpoint *sof_ends)
1338 {
1339 	struct device *dev = card->dev;
1340 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1341 	struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
1342 	struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
1343 	struct snd_soc_codec_conf *codec_conf = card->codec_conf;
1344 	const struct snd_soc_acpi_link_adr *adr_link;
1345 	struct sof_sdw_endpoint *sof_end = sof_ends;
1346 	int num_dais = 0;
1347 	int i, j;
1348 
1349 	for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
1350 		int num_link_dailinks = 0;
1351 
1352 		if (!is_power_of_2(adr_link->mask)) {
1353 			dev_err(dev, "link with multiple mask bits: 0x%x\n",
1354 				adr_link->mask);
1355 			return -EINVAL;
1356 		}
1357 
1358 		for (i = 0; i < adr_link->num_adr; i++) {
1359 			const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i];
1360 			struct sof_sdw_codec_info *codec_info;
1361 			const char *codec_name;
1362 
1363 			if (!adr_dev->name_prefix) {
1364 				dev_err(dev, "codec 0x%llx does not have a name prefix\n",
1365 					adr_dev->adr);
1366 				return -EINVAL;
1367 			}
1368 
1369 			codec_info = find_codec_info_part(adr_dev->adr);
1370 			if (!codec_info)
1371 				return -EINVAL;
1372 
1373 			ctx->ignore_pch_dmic |= codec_info->ignore_pch_dmic;
1374 
1375 			codec_name = get_codec_name(dev, codec_info, adr_link, i);
1376 			if (!codec_name)
1377 				return -ENOMEM;
1378 
1379 			codec_conf->dlc.name = codec_name;
1380 			codec_conf->name_prefix = adr_dev->name_prefix;
1381 			codec_conf++;
1382 
1383 			dev_dbg(dev, "Adding prefix %s for %s\n",
1384 				adr_dev->name_prefix, codec_name);
1385 
1386 			for (j = 0; j < adr_dev->num_endpoints; j++) {
1387 				const struct snd_soc_acpi_endpoint *adr_end;
1388 				const struct sof_sdw_dai_info *dai_info;
1389 				struct sof_sdw_dailink *sof_dai;
1390 				int stream;
1391 
1392 				adr_end = &adr_dev->endpoints[j];
1393 				dai_info = &codec_info->dais[adr_end->num];
1394 				sof_dai = find_dailink(sof_dais, adr_end);
1395 
1396 				if (dai_info->quirk && !(dai_info->quirk & sof_sdw_quirk))
1397 					continue;
1398 
1399 				dev_dbg(dev,
1400 					"Add dev: %d, 0x%llx end: %d, %s, %c/%c to %s: %d\n",
1401 					ffs(adr_link->mask) - 1, adr_dev->adr,
1402 					adr_end->num, type_strings[dai_info->dai_type],
1403 					dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-',
1404 					dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-',
1405 					adr_end->aggregated ? "group" : "solo",
1406 					adr_end->group_id);
1407 
1408 				if (adr_end->num >= codec_info->dai_num) {
1409 					dev_err(dev,
1410 						"%d is too many endpoints for codec: 0x%x\n",
1411 						adr_end->num, codec_info->part_id);
1412 					return -EINVAL;
1413 				}
1414 
1415 				for_each_pcm_streams(stream) {
1416 					if (dai_info->direction[stream] &&
1417 					    dai_info->dailink[stream] < 0) {
1418 						dev_err(dev,
1419 							"Invalid dailink id %d for codec: 0x%x\n",
1420 							dai_info->dailink[stream],
1421 							codec_info->part_id);
1422 						return -EINVAL;
1423 					}
1424 
1425 					if (dai_info->direction[stream]) {
1426 						num_dais += !sof_dai->num_devs[stream];
1427 						sof_dai->num_devs[stream]++;
1428 						sof_dai->link_mask[stream] |= adr_link->mask;
1429 					}
1430 				}
1431 
1432 				num_link_dailinks += !!list_empty(&sof_dai->endpoints);
1433 				list_add_tail(&sof_end->list, &sof_dai->endpoints);
1434 
1435 				sof_end->link_mask = adr_link->mask;
1436 				sof_end->codec_name = codec_name;
1437 				sof_end->codec_info = codec_info;
1438 				sof_end->dai_info = dai_info;
1439 				sof_end++;
1440 			}
1441 		}
1442 
1443 		ctx->append_dai_type |= (num_link_dailinks > 1);
1444 	}
1445 
1446 	WARN_ON(codec_conf != card->codec_conf + card->num_configs);
1447 
1448 	return num_dais;
1449 }
1450 
1451 static int create_sdw_dailink(struct snd_soc_card *card,
1452 			      struct sof_sdw_dailink *sof_dai,
1453 			      struct snd_soc_dai_link **dai_links,
1454 			      int *be_id)
1455 {
1456 	struct device *dev = card->dev;
1457 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1458 	struct sof_sdw_endpoint *sof_end;
1459 	int stream;
1460 
1461 	for_each_pcm_streams(stream) {
1462 		static const char * const sdw_stream_name[] = {
1463 			"SDW%d-Playback",
1464 			"SDW%d-Capture",
1465 			"SDW%d-Playback-%s",
1466 			"SDW%d-Capture-%s",
1467 		};
1468 		struct snd_soc_dai_link_ch_map *codec_maps;
1469 		struct snd_soc_dai_link_component *codecs;
1470 		struct snd_soc_dai_link_component *cpus;
1471 		int num_cpus = hweight32(sof_dai->link_mask[stream]);
1472 		int num_codecs = sof_dai->num_devs[stream];
1473 		int playback, capture;
1474 		int cur_link = 0;
1475 		int i = 0, j = 0;
1476 		char *name;
1477 
1478 		if (!sof_dai->num_devs[stream])
1479 			continue;
1480 
1481 		sof_end = list_first_entry(&sof_dai->endpoints,
1482 					   struct sof_sdw_endpoint, list);
1483 
1484 		*be_id = sof_end->dai_info->dailink[stream];
1485 		if (*be_id < 0) {
1486 			dev_err(dev, "Invalid dailink id %d\n", *be_id);
1487 			return -EINVAL;
1488 		}
1489 
1490 		/* create stream name according to first link id */
1491 		if (ctx->append_dai_type)
1492 			name = devm_kasprintf(dev, GFP_KERNEL,
1493 					      sdw_stream_name[stream + 2],
1494 					      ffs(sof_end->link_mask) - 1,
1495 					      type_strings[sof_end->dai_info->dai_type]);
1496 		else
1497 			name = devm_kasprintf(dev, GFP_KERNEL,
1498 					      sdw_stream_name[stream],
1499 					      ffs(sof_end->link_mask) - 1);
1500 		if (!name)
1501 			return -ENOMEM;
1502 
1503 		cpus = devm_kcalloc(dev, num_cpus, sizeof(*cpus), GFP_KERNEL);
1504 		if (!cpus)
1505 			return -ENOMEM;
1506 
1507 		codecs = devm_kcalloc(dev, num_codecs, sizeof(*codecs), GFP_KERNEL);
1508 		if (!codecs)
1509 			return -ENOMEM;
1510 
1511 		codec_maps = devm_kcalloc(dev, num_codecs, sizeof(*codec_maps), GFP_KERNEL);
1512 		if (!codec_maps)
1513 			return -ENOMEM;
1514 
1515 		list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
1516 			if (!sof_end->dai_info->direction[stream])
1517 				continue;
1518 
1519 			if (cur_link != sof_end->link_mask) {
1520 				int link_num = ffs(sof_end->link_mask) - 1;
1521 				int pin_num = ctx->sdw_pin_index[link_num]++;
1522 
1523 				cur_link = sof_end->link_mask;
1524 
1525 				cpus[i].dai_name = devm_kasprintf(dev, GFP_KERNEL,
1526 								  "SDW%d Pin%d",
1527 								  link_num, pin_num);
1528 				if (!cpus[i].dai_name)
1529 					return -ENOMEM;
1530 				i++;
1531 			}
1532 
1533 			codec_maps[j].cpu = i - 1;
1534 			codec_maps[j].codec = j;
1535 
1536 			codecs[j].name = sof_end->codec_name;
1537 			codecs[j].dai_name = sof_end->dai_info->dai_name;
1538 			j++;
1539 		}
1540 
1541 		WARN_ON(i != num_cpus || j != num_codecs);
1542 
1543 		playback = (stream == SNDRV_PCM_STREAM_PLAYBACK);
1544 		capture = (stream == SNDRV_PCM_STREAM_CAPTURE);
1545 
1546 		init_dai_link(dev, *dai_links, be_id, name, playback, capture,
1547 			      cpus, num_cpus, codecs, num_codecs,
1548 			      sof_sdw_rtd_init, &sdw_ops);
1549 
1550 		/*
1551 		 * SoundWire DAILINKs use 'stream' functions and Bank Switch operations
1552 		 * based on wait_for_completion(), tag them as 'nonatomic'.
1553 		 */
1554 		(*dai_links)->nonatomic = true;
1555 		(*dai_links)->ch_maps = codec_maps;
1556 
1557 		list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
1558 			if (sof_end->dai_info->init)
1559 				sof_end->dai_info->init(card, *dai_links,
1560 							sof_end->codec_info,
1561 							playback);
1562 		}
1563 
1564 		(*dai_links)++;
1565 	}
1566 
1567 	return 0;
1568 }
1569 
1570 static int create_sdw_dailinks(struct snd_soc_card *card,
1571 			       struct snd_soc_dai_link **dai_links, int *be_id,
1572 			       struct sof_sdw_dailink *sof_dais)
1573 {
1574 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1575 	int ret, i;
1576 
1577 	for (i = 0; i < SDW_MAX_LINKS; i++)
1578 		ctx->sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE;
1579 
1580 	/* generate DAI links by each sdw link */
1581 	while (sof_dais->initialised) {
1582 		int current_be_id;
1583 
1584 		ret = create_sdw_dailink(card, sof_dais, dai_links, &current_be_id);
1585 		if (ret)
1586 			return ret;
1587 
1588 		/* Update the be_id to match the highest ID used for SDW link */
1589 		if (*be_id < current_be_id)
1590 			*be_id = current_be_id;
1591 
1592 		sof_dais++;
1593 	}
1594 
1595 	return 0;
1596 }
1597 
1598 static int create_ssp_dailinks(struct snd_soc_card *card,
1599 			       struct snd_soc_dai_link **dai_links, int *be_id,
1600 			       struct sof_sdw_codec_info *ssp_info,
1601 			       unsigned long ssp_mask)
1602 {
1603 	struct device *dev = card->dev;
1604 	int i, j = 0;
1605 	int ret;
1606 
1607 	for_each_set_bit(i, &ssp_mask, BITS_PER_TYPE(ssp_mask)) {
1608 		char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", i);
1609 		char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i);
1610 		char *codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d",
1611 						  ssp_info->acpi_id, j++);
1612 		int playback = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK];
1613 		int capture = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE];
1614 
1615 		ret = init_simple_dai_link(dev, *dai_links, be_id, name,
1616 					   playback, capture, cpu_dai_name,
1617 					   codec_name, ssp_info->dais[0].dai_name,
1618 					   NULL, ssp_info->ops);
1619 		if (ret)
1620 			return ret;
1621 
1622 		ret = ssp_info->dais[0].init(card, *dai_links, ssp_info, 0);
1623 		if (ret < 0)
1624 			return ret;
1625 
1626 		(*dai_links)++;
1627 	}
1628 
1629 	return 0;
1630 }
1631 
1632 static int create_dmic_dailinks(struct snd_soc_card *card,
1633 				struct snd_soc_dai_link **dai_links, int *be_id)
1634 {
1635 	struct device *dev = card->dev;
1636 	int ret;
1637 
1638 	ret = init_simple_dai_link(dev, *dai_links, be_id, "dmic01",
1639 				   0, 1, // DMIC only supports capture
1640 				   "DMIC01 Pin", "dmic-codec", "dmic-hifi",
1641 				   sof_sdw_dmic_init, NULL);
1642 	if (ret)
1643 		return ret;
1644 
1645 	(*dai_links)++;
1646 
1647 	ret = init_simple_dai_link(dev, *dai_links, be_id, "dmic16k",
1648 				   0, 1, // DMIC only supports capture
1649 				   "DMIC16k Pin", "dmic-codec", "dmic-hifi",
1650 				   /* don't call sof_sdw_dmic_init() twice */
1651 				   NULL, NULL);
1652 	if (ret)
1653 		return ret;
1654 
1655 	(*dai_links)++;
1656 
1657 	return 0;
1658 }
1659 
1660 static int create_hdmi_dailinks(struct snd_soc_card *card,
1661 				struct snd_soc_dai_link **dai_links, int *be_id,
1662 				int hdmi_num)
1663 {
1664 	struct device *dev = card->dev;
1665 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1666 	int i, ret;
1667 
1668 	for (i = 0; i < hdmi_num; i++) {
1669 		char *name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1);
1670 		char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1);
1671 		char *codec_name, *codec_dai_name;
1672 
1673 		if (ctx->hdmi.idisp_codec) {
1674 			codec_name = "ehdaudio0D2";
1675 			codec_dai_name = devm_kasprintf(dev, GFP_KERNEL,
1676 							"intel-hdmi-hifi%d", i + 1);
1677 		} else {
1678 			codec_name = "snd-soc-dummy";
1679 			codec_dai_name = "snd-soc-dummy-dai";
1680 		}
1681 
1682 		ret = init_simple_dai_link(dev, *dai_links, be_id, name,
1683 					   1, 0, // HDMI only supports playback
1684 					   cpu_dai_name, codec_name, codec_dai_name,
1685 					   i == 0 ? sof_sdw_hdmi_init : NULL, NULL);
1686 		if (ret)
1687 			return ret;
1688 
1689 		(*dai_links)++;
1690 	}
1691 
1692 	return 0;
1693 }
1694 
1695 static int create_bt_dailinks(struct snd_soc_card *card,
1696 			      struct snd_soc_dai_link **dai_links, int *be_id)
1697 {
1698 	struct device *dev = card->dev;
1699 	int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
1700 			SOF_BT_OFFLOAD_SSP_SHIFT;
1701 	char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
1702 	char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port);
1703 	int ret;
1704 
1705 	ret = init_simple_dai_link(dev, *dai_links, be_id, name,
1706 				   1, 1, cpu_dai_name, snd_soc_dummy_dlc.name,
1707 				   snd_soc_dummy_dlc.dai_name, NULL, NULL);
1708 	if (ret)
1709 		return ret;
1710 
1711 	(*dai_links)++;
1712 
1713 	return 0;
1714 }
1715 
1716 static int sof_card_dai_links_create(struct snd_soc_card *card)
1717 {
1718 	struct device *dev = card->dev;
1719 	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
1720 	int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, bt_num = 0;
1721 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1722 	struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
1723 	struct snd_soc_codec_conf *codec_conf;
1724 	struct sof_sdw_codec_info *ssp_info;
1725 	struct sof_sdw_endpoint *sof_ends;
1726 	struct sof_sdw_dailink *sof_dais;
1727 	int num_devs = 0;
1728 	int num_ends = 0;
1729 	struct snd_soc_dai_link *dai_links;
1730 	int num_links;
1731 	int be_id = 0;
1732 	int hdmi_num;
1733 	unsigned long ssp_mask;
1734 	int ret;
1735 
1736 	ret = count_sdw_endpoints(card, &num_devs, &num_ends);
1737 	if (ret < 0) {
1738 		dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
1739 		return ret;
1740 	}
1741 
1742 	/* One per DAI link, worst case is a DAI link for every endpoint */
1743 	sof_dais = kcalloc(num_ends, sizeof(*sof_dais), GFP_KERNEL);
1744 	if (!sof_dais)
1745 		return -ENOMEM;
1746 
1747 	/* One per endpoint, ie. each DAI on each codec/amp */
1748 	sof_ends = kcalloc(num_ends, sizeof(*sof_ends), GFP_KERNEL);
1749 	if (!sof_ends) {
1750 		ret = -ENOMEM;
1751 		goto err_dai;
1752 	}
1753 
1754 	/* will be populated when acpi endpoints are parsed */
1755 	codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
1756 	if (!codec_conf) {
1757 		ret = -ENOMEM;
1758 		goto err_end;
1759 	}
1760 
1761 	card->codec_conf = codec_conf;
1762 	card->num_configs = num_devs;
1763 
1764 	ret = parse_sdw_endpoints(card, sof_dais, sof_ends);
1765 	if (ret < 0)
1766 		goto err_end;
1767 
1768 	sdw_be_num = ret;
1769 
1770 	/*
1771 	 * on generic tgl platform, I2S or sdw mode is supported
1772 	 * based on board rework. A ACPI device is registered in
1773 	 * system only when I2S mode is supported, not sdw mode.
1774 	 * Here check ACPI ID to confirm I2S is supported.
1775 	 */
1776 	ssp_info = find_codec_info_acpi(mach->id);
1777 	if (ssp_info) {
1778 		ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk);
1779 		ssp_num = hweight_long(ssp_mask);
1780 	}
1781 
1782 	if (mach_params->codec_mask & IDISP_CODEC_MASK)
1783 		ctx->hdmi.idisp_codec = true;
1784 
1785 	if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
1786 		hdmi_num = SOF_TGL_HDMI_COUNT;
1787 	else
1788 		hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
1789 
1790 	/* enable dmic01 & dmic16k */
1791 	if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num)
1792 		dmic_num = 2;
1793 
1794 	if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
1795 		bt_num = 1;
1796 
1797 	dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n",
1798 		sdw_be_num, ssp_num, dmic_num,
1799 		ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
1800 
1801 	/* allocate BE dailinks */
1802 	num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num;
1803 	dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL);
1804 	if (!dai_links) {
1805 		ret = -ENOMEM;
1806 		goto err_end;
1807 	}
1808 
1809 	card->dai_link = dai_links;
1810 	card->num_links = num_links;
1811 
1812 	/* SDW */
1813 	if (sdw_be_num) {
1814 		ret = create_sdw_dailinks(card, &dai_links, &be_id, sof_dais);
1815 		if (ret)
1816 			goto err_end;
1817 	}
1818 
1819 	/* SSP */
1820 	if (ssp_num) {
1821 		ret = create_ssp_dailinks(card, &dai_links, &be_id,
1822 					  ssp_info, ssp_mask);
1823 		if (ret)
1824 			goto err_end;
1825 	}
1826 
1827 	/* dmic */
1828 	if (dmic_num > 0) {
1829 		if (ctx->ignore_pch_dmic) {
1830 			dev_warn(dev, "Ignoring PCH DMIC\n");
1831 		} else {
1832 			ret = create_dmic_dailinks(card, &dai_links, &be_id);
1833 			if (ret)
1834 				goto err_end;
1835 		}
1836 	}
1837 
1838 	/* HDMI */
1839 	ret = create_hdmi_dailinks(card, &dai_links, &be_id, hdmi_num);
1840 	if (ret)
1841 		goto err_end;
1842 
1843 	/* BT */
1844 	if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
1845 		ret = create_bt_dailinks(card, &dai_links, &be_id);
1846 		if (ret)
1847 			goto err_end;
1848 	}
1849 
1850 	WARN_ON(dai_links != card->dai_link + card->num_links);
1851 
1852 err_end:
1853 	kfree(sof_ends);
1854 err_dai:
1855 	kfree(sof_dais);
1856 
1857 	return ret;
1858 }
1859 
1860 static int sof_sdw_card_late_probe(struct snd_soc_card *card)
1861 {
1862 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1863 	int ret = 0;
1864 	int i;
1865 
1866 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
1867 		if (codec_info_list[i].codec_card_late_probe) {
1868 			ret = codec_info_list[i].codec_card_late_probe(card);
1869 
1870 			if (ret < 0)
1871 				return ret;
1872 		}
1873 	}
1874 
1875 	if (ctx->hdmi.idisp_codec)
1876 		ret = sof_sdw_hdmi_card_late_probe(card);
1877 
1878 	return ret;
1879 }
1880 
1881 /* SoC card */
1882 static const char sdw_card_long_name[] = "Intel Soundwire SOF";
1883 
1884 static struct snd_soc_card card_sof_sdw = {
1885 	.name = "soundwire",
1886 	.owner = THIS_MODULE,
1887 	.late_probe = sof_sdw_card_late_probe,
1888 };
1889 
1890 /* helper to get the link that the codec DAI is used */
1891 static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card,
1892 						       const char *dai_name)
1893 {
1894 	struct snd_soc_dai_link *dai_link;
1895 	int i;
1896 	int j;
1897 
1898 	for_each_card_prelinks(card, i, dai_link) {
1899 		for (j = 0; j < dai_link->num_codecs; j++) {
1900 			/* Check each codec in a link */
1901 			if (!strcmp(dai_link->codecs[j].dai_name, dai_name))
1902 				return dai_link;
1903 		}
1904 	}
1905 	return NULL;
1906 }
1907 
1908 static void mc_dailink_exit_loop(struct snd_soc_card *card)
1909 {
1910 	struct snd_soc_dai_link *dai_link;
1911 	int ret;
1912 	int i, j;
1913 
1914 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
1915 		for (j = 0; j < codec_info_list[i].dai_num; j++) {
1916 			codec_info_list[i].dais[j].rtd_init_done = false;
1917 			/* Check each dai in codec_info_lis to see if it is used in the link */
1918 			if (!codec_info_list[i].dais[j].exit)
1919 				continue;
1920 			/*
1921 			 * We don't need to call .exit function if there is no matched
1922 			 * dai link found.
1923 			 */
1924 			dai_link = mc_find_codec_dai_used(card,
1925 							  codec_info_list[i].dais[j].dai_name);
1926 			if (dai_link) {
1927 				/* Do the .exit function if the codec dai is used in the link */
1928 				ret = codec_info_list[i].dais[j].exit(card, dai_link);
1929 				if (ret)
1930 					dev_warn(card->dev,
1931 						 "codec exit failed %d\n",
1932 						 ret);
1933 				break;
1934 			}
1935 		}
1936 	}
1937 }
1938 
1939 static int mc_probe(struct platform_device *pdev)
1940 {
1941 	struct snd_soc_card *card = &card_sof_sdw;
1942 	struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev);
1943 	struct mc_private *ctx;
1944 	int amp_num = 0, i;
1945 	int ret;
1946 
1947 	card->dev = &pdev->dev;
1948 
1949 	dev_dbg(card->dev, "Entry\n");
1950 
1951 	ctx = devm_kzalloc(card->dev, sizeof(*ctx), GFP_KERNEL);
1952 	if (!ctx)
1953 		return -ENOMEM;
1954 
1955 	snd_soc_card_set_drvdata(card, ctx);
1956 
1957 	dmi_check_system(sof_sdw_quirk_table);
1958 
1959 	if (quirk_override != -1) {
1960 		dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n",
1961 			 sof_sdw_quirk, quirk_override);
1962 		sof_sdw_quirk = quirk_override;
1963 	}
1964 
1965 	log_quirks(card->dev);
1966 
1967 	/* reset amp_num to ensure amp_num++ starts from 0 in each probe */
1968 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1969 		codec_info_list[i].amp_num = 0;
1970 
1971 	if (mach->mach_params.subsystem_id_set) {
1972 		snd_soc_card_set_pci_ssid(card,
1973 					  mach->mach_params.subsystem_vendor,
1974 					  mach->mach_params.subsystem_device);
1975 	}
1976 
1977 	ret = sof_card_dai_links_create(card);
1978 	if (ret < 0)
1979 		return ret;
1980 
1981 	/*
1982 	 * the default amp_num is zero for each codec and
1983 	 * amp_num will only be increased for active amp
1984 	 * codecs on used platform
1985 	 */
1986 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1987 		amp_num += codec_info_list[i].amp_num;
1988 
1989 	card->components = devm_kasprintf(card->dev, GFP_KERNEL,
1990 					  "cfg-spk:%d cfg-amp:%d",
1991 					  (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
1992 					  ? 4 : 2, amp_num);
1993 	if (!card->components)
1994 		return -ENOMEM;
1995 
1996 	if (mach->mach_params.dmic_num) {
1997 		card->components = devm_kasprintf(card->dev, GFP_KERNEL,
1998 						  "%s mic:dmic cfg-mics:%d",
1999 						  card->components,
2000 						  mach->mach_params.dmic_num);
2001 		if (!card->components)
2002 			return -ENOMEM;
2003 	}
2004 
2005 	card->long_name = sdw_card_long_name;
2006 
2007 	/* Register the card */
2008 	ret = devm_snd_soc_register_card(card->dev, card);
2009 	if (ret) {
2010 		dev_err_probe(card->dev, ret, "snd_soc_register_card failed %d\n", ret);
2011 		mc_dailink_exit_loop(card);
2012 		return ret;
2013 	}
2014 
2015 	platform_set_drvdata(pdev, card);
2016 
2017 	return ret;
2018 }
2019 
2020 static void mc_remove(struct platform_device *pdev)
2021 {
2022 	struct snd_soc_card *card = platform_get_drvdata(pdev);
2023 
2024 	mc_dailink_exit_loop(card);
2025 }
2026 
2027 static const struct platform_device_id mc_id_table[] = {
2028 	{ "sof_sdw", },
2029 	{}
2030 };
2031 MODULE_DEVICE_TABLE(platform, mc_id_table);
2032 
2033 static struct platform_driver sof_sdw_driver = {
2034 	.driver = {
2035 		.name = "sof_sdw",
2036 		.pm = &snd_soc_pm_ops,
2037 	},
2038 	.probe = mc_probe,
2039 	.remove_new = mc_remove,
2040 	.id_table = mc_id_table,
2041 };
2042 
2043 module_platform_driver(sof_sdw_driver);
2044 
2045 MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver");
2046 MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>");
2047 MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>");
2048 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
2049 MODULE_LICENSE("GPL v2");
2050 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
2051 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
2052