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