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