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