xref: /linux/sound/soc/intel/boards/sof_sdw.c (revision 34864c05a54d1bc544c8c3939aababbc481d99e3)
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 		.callback = sof_sdw_quirk_cb,
510 		.matches = {
511 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
512 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE3")
513 		},
514 		.driver_data = (void *)(SOF_SIDECAR_AMPS),
515 	},
516 	{
517 		.callback = sof_sdw_quirk_cb,
518 		.matches = {
519 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
520 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE4")
521 		},
522 		.driver_data = (void *)(SOF_SIDECAR_AMPS),
523 	},
524 	{}
525 };
526 
527 static struct snd_soc_dai_link_component platform_component[] = {
528 	{
529 		/* name might be overridden during probe */
530 		.name = "0000:00:1f.3"
531 	}
532 };
533 
534 static const struct snd_soc_dapm_widget generic_dmic_widgets[] = {
535 	SND_SOC_DAPM_MIC("DMIC", NULL),
536 };
537 
538 static const struct snd_soc_dapm_widget generic_jack_widgets[] = {
539 	SND_SOC_DAPM_HP("Headphone", NULL),
540 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
541 };
542 
543 static const struct snd_kcontrol_new generic_jack_controls[] = {
544 	SOC_DAPM_PIN_SWITCH("Headphone"),
545 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
546 };
547 
548 static const struct snd_soc_dapm_widget generic_spk_widgets[] = {
549 	SND_SOC_DAPM_SPK("Speaker", NULL),
550 };
551 
552 static const struct snd_kcontrol_new generic_spk_controls[] = {
553 	SOC_DAPM_PIN_SWITCH("Speaker"),
554 };
555 
556 static const struct snd_soc_dapm_widget maxim_widgets[] = {
557 	SND_SOC_DAPM_SPK("Left Spk", NULL),
558 	SND_SOC_DAPM_SPK("Right Spk", NULL),
559 };
560 
561 static const struct snd_kcontrol_new maxim_controls[] = {
562 	SOC_DAPM_PIN_SWITCH("Left Spk"),
563 	SOC_DAPM_PIN_SWITCH("Right Spk"),
564 };
565 
566 static const struct snd_soc_dapm_widget rt700_widgets[] = {
567 	SND_SOC_DAPM_HP("Headphones", NULL),
568 	SND_SOC_DAPM_MIC("AMIC", NULL),
569 	SND_SOC_DAPM_SPK("Speaker", NULL),
570 };
571 
572 static const struct snd_kcontrol_new rt700_controls[] = {
573 	SOC_DAPM_PIN_SWITCH("Headphones"),
574 	SOC_DAPM_PIN_SWITCH("AMIC"),
575 	SOC_DAPM_PIN_SWITCH("Speaker"),
576 };
577 
578 /* these wrappers are only needed to avoid typecast compilation errors */
579 int sdw_startup(struct snd_pcm_substream *substream)
580 {
581 	return sdw_startup_stream(substream);
582 }
583 
584 int sdw_prepare(struct snd_pcm_substream *substream)
585 {
586 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
587 	struct sdw_stream_runtime *sdw_stream;
588 	struct snd_soc_dai *dai;
589 
590 	/* Find stream from first CPU DAI */
591 	dai = snd_soc_rtd_to_cpu(rtd, 0);
592 
593 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
594 	if (IS_ERR(sdw_stream)) {
595 		dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
596 		return PTR_ERR(sdw_stream);
597 	}
598 
599 	return sdw_prepare_stream(sdw_stream);
600 }
601 
602 int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
603 {
604 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
605 	struct sdw_stream_runtime *sdw_stream;
606 	struct snd_soc_dai *dai;
607 	int ret;
608 
609 	/* Find stream from first CPU DAI */
610 	dai = snd_soc_rtd_to_cpu(rtd, 0);
611 
612 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
613 	if (IS_ERR(sdw_stream)) {
614 		dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
615 		return PTR_ERR(sdw_stream);
616 	}
617 
618 	switch (cmd) {
619 	case SNDRV_PCM_TRIGGER_START:
620 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
621 	case SNDRV_PCM_TRIGGER_RESUME:
622 		ret = sdw_enable_stream(sdw_stream);
623 		break;
624 
625 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
626 	case SNDRV_PCM_TRIGGER_SUSPEND:
627 	case SNDRV_PCM_TRIGGER_STOP:
628 		ret = sdw_disable_stream(sdw_stream);
629 		break;
630 	default:
631 		ret = -EINVAL;
632 		break;
633 	}
634 
635 	if (ret)
636 		dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret);
637 
638 	return ret;
639 }
640 
641 int sdw_hw_params(struct snd_pcm_substream *substream,
642 		  struct snd_pcm_hw_params *params)
643 {
644 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
645 	struct snd_soc_dai_link_ch_map *ch_maps;
646 	int ch = params_channels(params);
647 	unsigned int ch_mask;
648 	int num_codecs;
649 	int step;
650 	int i;
651 
652 	if (!rtd->dai_link->ch_maps)
653 		return 0;
654 
655 	/* Identical data will be sent to all codecs in playback */
656 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
657 		ch_mask = GENMASK(ch - 1, 0);
658 		step = 0;
659 	} else {
660 		num_codecs = rtd->dai_link->num_codecs;
661 
662 		if (ch < num_codecs || ch % num_codecs != 0) {
663 			dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n",
664 				ch, num_codecs);
665 			return -EINVAL;
666 		}
667 
668 		ch_mask = GENMASK(ch / num_codecs - 1, 0);
669 		step = hweight_long(ch_mask);
670 
671 	}
672 
673 	/*
674 	 * The captured data will be combined from each cpu DAI if the dai
675 	 * link has more than one codec DAIs. Set codec channel mask and
676 	 * ASoC will set the corresponding channel numbers for each cpu dai.
677 	 */
678 	for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
679 		ch_maps->ch_mask = ch_mask << (i * step);
680 
681 	return 0;
682 }
683 
684 int sdw_hw_free(struct snd_pcm_substream *substream)
685 {
686 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
687 	struct sdw_stream_runtime *sdw_stream;
688 	struct snd_soc_dai *dai;
689 
690 	/* Find stream from first CPU DAI */
691 	dai = snd_soc_rtd_to_cpu(rtd, 0);
692 
693 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
694 	if (IS_ERR(sdw_stream)) {
695 		dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
696 		return PTR_ERR(sdw_stream);
697 	}
698 
699 	return sdw_deprepare_stream(sdw_stream);
700 }
701 
702 void sdw_shutdown(struct snd_pcm_substream *substream)
703 {
704 	sdw_shutdown_stream(substream);
705 }
706 
707 static const struct snd_soc_ops sdw_ops = {
708 	.startup = sdw_startup,
709 	.prepare = sdw_prepare,
710 	.trigger = sdw_trigger,
711 	.hw_params = sdw_hw_params,
712 	.hw_free = sdw_hw_free,
713 	.shutdown = sdw_shutdown,
714 };
715 
716 static struct sof_sdw_codec_info codec_info_list[] = {
717 	{
718 		.part_id = 0x700,
719 		.dais = {
720 			{
721 				.direction = {true, true},
722 				.dai_name = "rt700-aif1",
723 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
724 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
725 				.rtd_init = rt700_rtd_init,
726 				.controls = rt700_controls,
727 				.num_controls = ARRAY_SIZE(rt700_controls),
728 				.widgets = rt700_widgets,
729 				.num_widgets = ARRAY_SIZE(rt700_widgets),
730 			},
731 		},
732 		.dai_num = 1,
733 	},
734 	{
735 		.part_id = 0x711,
736 		.version_id = 3,
737 		.dais = {
738 			{
739 				.direction = {true, true},
740 				.dai_name = "rt711-sdca-aif1",
741 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
742 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
743 				.init = sof_sdw_rt_sdca_jack_init,
744 				.exit = sof_sdw_rt_sdca_jack_exit,
745 				.rtd_init = rt_sdca_jack_rtd_init,
746 				.controls = generic_jack_controls,
747 				.num_controls = ARRAY_SIZE(generic_jack_controls),
748 				.widgets = generic_jack_widgets,
749 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
750 			},
751 		},
752 		.dai_num = 1,
753 	},
754 	{
755 		.part_id = 0x711,
756 		.version_id = 2,
757 		.dais = {
758 			{
759 				.direction = {true, true},
760 				.dai_name = "rt711-aif1",
761 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
762 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
763 				.init = sof_sdw_rt711_init,
764 				.exit = sof_sdw_rt711_exit,
765 				.rtd_init = rt711_rtd_init,
766 				.controls = generic_jack_controls,
767 				.num_controls = ARRAY_SIZE(generic_jack_controls),
768 				.widgets = generic_jack_widgets,
769 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
770 			},
771 		},
772 		.dai_num = 1,
773 	},
774 	{
775 		.part_id = 0x712,
776 		.version_id = 3,
777 		.dais =	{
778 			{
779 				.direction = {true, true},
780 				.dai_name = "rt712-sdca-aif1",
781 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
782 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
783 				.init = sof_sdw_rt_sdca_jack_init,
784 				.exit = sof_sdw_rt_sdca_jack_exit,
785 				.rtd_init = rt_sdca_jack_rtd_init,
786 				.controls = generic_jack_controls,
787 				.num_controls = ARRAY_SIZE(generic_jack_controls),
788 				.widgets = generic_jack_widgets,
789 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
790 			},
791 			{
792 				.direction = {true, false},
793 				.dai_name = "rt712-sdca-aif2",
794 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
795 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
796 				.init = sof_sdw_rt_amp_init,
797 				.exit = sof_sdw_rt_amp_exit,
798 				.rtd_init = rt712_spk_rtd_init,
799 				.controls = generic_spk_controls,
800 				.num_controls = ARRAY_SIZE(generic_spk_controls),
801 				.widgets = generic_spk_widgets,
802 				.num_widgets = ARRAY_SIZE(generic_spk_widgets),
803 			},
804 		},
805 		.dai_num = 2,
806 	},
807 	{
808 		.part_id = 0x1712,
809 		.version_id = 3,
810 		.dais =	{
811 			{
812 				.direction = {false, true},
813 				.dai_name = "rt712-sdca-dmic-aif1",
814 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
815 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
816 				.rtd_init = rt_dmic_rtd_init,
817 			},
818 		},
819 		.dai_num = 1,
820 	},
821 	{
822 		.part_id = 0x713,
823 		.version_id = 3,
824 		.dais =	{
825 			{
826 				.direction = {true, true},
827 				.dai_name = "rt712-sdca-aif1",
828 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
829 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
830 				.init = sof_sdw_rt_sdca_jack_init,
831 				.exit = sof_sdw_rt_sdca_jack_exit,
832 				.rtd_init = rt_sdca_jack_rtd_init,
833 				.controls = generic_jack_controls,
834 				.num_controls = ARRAY_SIZE(generic_jack_controls),
835 				.widgets = generic_jack_widgets,
836 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
837 			},
838 		},
839 		.dai_num = 1,
840 	},
841 	{
842 		.part_id = 0x1713,
843 		.version_id = 3,
844 		.dais =	{
845 			{
846 				.direction = {false, true},
847 				.dai_name = "rt712-sdca-dmic-aif1",
848 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
849 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
850 				.rtd_init = rt_dmic_rtd_init,
851 			},
852 		},
853 		.dai_num = 1,
854 	},
855 	{
856 		.part_id = 0x1308,
857 		.acpi_id = "10EC1308",
858 		.dais = {
859 			{
860 				.direction = {true, false},
861 				.dai_name = "rt1308-aif",
862 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
863 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
864 				.init = sof_sdw_rt_amp_init,
865 				.exit = sof_sdw_rt_amp_exit,
866 				.rtd_init = rt_amp_spk_rtd_init,
867 				.controls = generic_spk_controls,
868 				.num_controls = ARRAY_SIZE(generic_spk_controls),
869 				.widgets = generic_spk_widgets,
870 				.num_widgets = ARRAY_SIZE(generic_spk_widgets),
871 			},
872 		},
873 		.dai_num = 1,
874 		.ops = &sof_sdw_rt1308_i2s_ops,
875 	},
876 	{
877 		.part_id = 0x1316,
878 		.dais = {
879 			{
880 				.direction = {true, true},
881 				.dai_name = "rt1316-aif",
882 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
883 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
884 				.init = sof_sdw_rt_amp_init,
885 				.exit = sof_sdw_rt_amp_exit,
886 				.rtd_init = rt_amp_spk_rtd_init,
887 				.controls = generic_spk_controls,
888 				.num_controls = ARRAY_SIZE(generic_spk_controls),
889 				.widgets = generic_spk_widgets,
890 				.num_widgets = ARRAY_SIZE(generic_spk_widgets),
891 			},
892 		},
893 		.dai_num = 1,
894 	},
895 	{
896 		.part_id = 0x1318,
897 		.dais = {
898 			{
899 				.direction = {true, true},
900 				.dai_name = "rt1318-aif",
901 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
902 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
903 				.init = sof_sdw_rt_amp_init,
904 				.exit = sof_sdw_rt_amp_exit,
905 				.rtd_init = rt_amp_spk_rtd_init,
906 				.controls = generic_spk_controls,
907 				.num_controls = ARRAY_SIZE(generic_spk_controls),
908 				.widgets = generic_spk_widgets,
909 				.num_widgets = ARRAY_SIZE(generic_spk_widgets),
910 			},
911 		},
912 		.dai_num = 1,
913 	},
914 	{
915 		.part_id = 0x714,
916 		.version_id = 3,
917 		.ignore_pch_dmic = true,
918 		.dais = {
919 			{
920 				.direction = {false, true},
921 				.dai_name = "rt715-sdca-aif2",
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 = 1,
928 	},
929 	{
930 		.part_id = 0x715,
931 		.version_id = 3,
932 		.ignore_pch_dmic = true,
933 		.dais = {
934 			{
935 				.direction = {false, true},
936 				.dai_name = "rt715-sdca-aif2",
937 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
938 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
939 				.rtd_init = rt_dmic_rtd_init,
940 			},
941 		},
942 		.dai_num = 1,
943 	},
944 	{
945 		.part_id = 0x714,
946 		.version_id = 2,
947 		.ignore_pch_dmic = true,
948 		.dais = {
949 			{
950 				.direction = {false, true},
951 				.dai_name = "rt715-aif2",
952 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
953 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
954 				.rtd_init = rt_dmic_rtd_init,
955 			},
956 		},
957 		.dai_num = 1,
958 	},
959 	{
960 		.part_id = 0x715,
961 		.version_id = 2,
962 		.ignore_pch_dmic = true,
963 		.dais = {
964 			{
965 				.direction = {false, true},
966 				.dai_name = "rt715-aif2",
967 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
968 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
969 				.rtd_init = rt_dmic_rtd_init,
970 			},
971 		},
972 		.dai_num = 1,
973 	},
974 	{
975 		.part_id = 0x722,
976 		.version_id = 3,
977 		.dais = {
978 			{
979 				.direction = {true, true},
980 				.dai_name = "rt722-sdca-aif1",
981 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
982 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
983 				.init = sof_sdw_rt_sdca_jack_init,
984 				.exit = sof_sdw_rt_sdca_jack_exit,
985 				.rtd_init = rt_sdca_jack_rtd_init,
986 				.controls = generic_jack_controls,
987 				.num_controls = ARRAY_SIZE(generic_jack_controls),
988 				.widgets = generic_jack_widgets,
989 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
990 			},
991 			{
992 				.direction = {true, false},
993 				.dai_name = "rt722-sdca-aif2",
994 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
995 				/* No feedback capability is provided by rt722-sdca codec driver*/
996 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
997 				.init = sof_sdw_rt_amp_init,
998 				.exit = sof_sdw_rt_amp_exit,
999 				.rtd_init = rt722_spk_rtd_init,
1000 				.controls = generic_spk_controls,
1001 				.num_controls = ARRAY_SIZE(generic_spk_controls),
1002 				.widgets = generic_spk_widgets,
1003 				.num_widgets = ARRAY_SIZE(generic_spk_widgets),
1004 			},
1005 			{
1006 				.direction = {false, true},
1007 				.dai_name = "rt722-sdca-aif3",
1008 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
1009 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
1010 				.rtd_init = rt_dmic_rtd_init,
1011 			},
1012 		},
1013 		.dai_num = 3,
1014 	},
1015 	{
1016 		.part_id = 0x8373,
1017 		.dais = {
1018 			{
1019 				.direction = {true, true},
1020 				.dai_name = "max98373-aif1",
1021 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
1022 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
1023 				.init = sof_sdw_maxim_init,
1024 				.rtd_init = maxim_spk_rtd_init,
1025 				.controls = maxim_controls,
1026 				.num_controls = ARRAY_SIZE(maxim_controls),
1027 				.widgets = maxim_widgets,
1028 				.num_widgets = ARRAY_SIZE(maxim_widgets),
1029 			},
1030 		},
1031 		.dai_num = 1,
1032 	},
1033 	{
1034 		.part_id = 0x8363,
1035 		.dais = {
1036 			{
1037 				.direction = {true, false},
1038 				.dai_name = "max98363-aif1",
1039 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
1040 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
1041 				.init = sof_sdw_maxim_init,
1042 				.rtd_init = maxim_spk_rtd_init,
1043 				.controls = maxim_controls,
1044 				.num_controls = ARRAY_SIZE(maxim_controls),
1045 				.widgets = maxim_widgets,
1046 				.num_widgets = ARRAY_SIZE(maxim_widgets),
1047 			},
1048 		},
1049 		.dai_num = 1,
1050 	},
1051 	{
1052 		.part_id = 0x5682,
1053 		.dais = {
1054 			{
1055 				.direction = {true, true},
1056 				.dai_name = "rt5682-sdw",
1057 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1058 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
1059 				.rtd_init = rt5682_rtd_init,
1060 				.controls = generic_jack_controls,
1061 				.num_controls = ARRAY_SIZE(generic_jack_controls),
1062 				.widgets = generic_jack_widgets,
1063 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
1064 			},
1065 		},
1066 		.dai_num = 1,
1067 	},
1068 	{
1069 		.part_id = 0x3556,
1070 		.dais = {
1071 			{
1072 				.direction = {true, true},
1073 				.dai_name = "cs35l56-sdw1",
1074 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
1075 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
1076 				.init = sof_sdw_cs_amp_init,
1077 				.rtd_init = cs_spk_rtd_init,
1078 				.controls = generic_spk_controls,
1079 				.num_controls = ARRAY_SIZE(generic_spk_controls),
1080 				.widgets = generic_spk_widgets,
1081 				.num_widgets = ARRAY_SIZE(generic_spk_widgets),
1082 			},
1083 		},
1084 		.dai_num = 1,
1085 	},
1086 	{
1087 		.part_id = 0x4242,
1088 		.dais = {
1089 			{
1090 				.direction = {true, true},
1091 				.dai_name = "cs42l42-sdw",
1092 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1093 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
1094 				.rtd_init = cs42l42_rtd_init,
1095 				.controls = generic_jack_controls,
1096 				.num_controls = ARRAY_SIZE(generic_jack_controls),
1097 				.widgets = generic_jack_widgets,
1098 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
1099 			},
1100 		},
1101 		.dai_num = 1,
1102 	},
1103 	{
1104 		.part_id = 0x4243,
1105 		.codec_name = "cs42l43-codec",
1106 		.count_sidecar = bridge_cs35l56_count_sidecar,
1107 		.add_sidecar = bridge_cs35l56_add_sidecar,
1108 		.dais = {
1109 			{
1110 				.direction = {true, false},
1111 				.dai_name = "cs42l43-dp5",
1112 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1113 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
1114 				.rtd_init = cs42l43_hs_rtd_init,
1115 				.controls = generic_jack_controls,
1116 				.num_controls = ARRAY_SIZE(generic_jack_controls),
1117 				.widgets = generic_jack_widgets,
1118 				.num_widgets = ARRAY_SIZE(generic_jack_widgets),
1119 			},
1120 			{
1121 				.direction = {false, true},
1122 				.dai_name = "cs42l43-dp1",
1123 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
1124 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
1125 				.rtd_init = cs42l43_dmic_rtd_init,
1126 				.widgets = generic_dmic_widgets,
1127 				.num_widgets = ARRAY_SIZE(generic_dmic_widgets),
1128 			},
1129 			{
1130 				.direction = {false, true},
1131 				.dai_name = "cs42l43-dp2",
1132 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1133 				.dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID},
1134 			},
1135 			{
1136 				.direction = {true, false},
1137 				.dai_name = "cs42l43-dp6",
1138 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
1139 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
1140 				.init = sof_sdw_cs42l43_spk_init,
1141 				.rtd_init = cs42l43_spk_rtd_init,
1142 				.controls = generic_spk_controls,
1143 				.num_controls = ARRAY_SIZE(generic_spk_controls),
1144 				.widgets = generic_spk_widgets,
1145 				.num_widgets = ARRAY_SIZE(generic_spk_widgets),
1146 				.quirk = SOF_CODEC_SPKR | SOF_SIDECAR_AMPS,
1147 			},
1148 		},
1149 		.dai_num = 4,
1150 	},
1151 	{
1152 		.part_id = 0xaaaa, /* generic codec mockup */
1153 		.version_id = 0,
1154 		.dais = {
1155 			{
1156 				.direction = {true, true},
1157 				.dai_name = "sdw-mockup-aif1",
1158 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1159 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
1160 			},
1161 		},
1162 		.dai_num = 1,
1163 	},
1164 	{
1165 		.part_id = 0xaa55, /* headset codec mockup */
1166 		.version_id = 0,
1167 		.dais = {
1168 			{
1169 				.direction = {true, true},
1170 				.dai_name = "sdw-mockup-aif1",
1171 				.dai_type = SOF_SDW_DAI_TYPE_JACK,
1172 				.dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
1173 			},
1174 		},
1175 		.dai_num = 1,
1176 	},
1177 	{
1178 		.part_id = 0x55aa, /* amplifier mockup */
1179 		.version_id = 0,
1180 		.dais = {
1181 			{
1182 				.direction = {true, true},
1183 				.dai_name = "sdw-mockup-aif1",
1184 				.dai_type = SOF_SDW_DAI_TYPE_AMP,
1185 				.dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
1186 			},
1187 		},
1188 		.dai_num = 1,
1189 	},
1190 	{
1191 		.part_id = 0x5555,
1192 		.version_id = 0,
1193 		.dais = {
1194 			{
1195 				.dai_name = "sdw-mockup-aif1",
1196 				.direction = {false, true},
1197 				.dai_type = SOF_SDW_DAI_TYPE_MIC,
1198 				.dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
1199 			},
1200 		},
1201 		.dai_num = 1,
1202 	},
1203 };
1204 
1205 static struct sof_sdw_codec_info *find_codec_info_part(const u64 adr)
1206 {
1207 	unsigned int part_id, sdw_version;
1208 	int i;
1209 
1210 	part_id = SDW_PART_ID(adr);
1211 	sdw_version = SDW_VERSION(adr);
1212 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1213 		/*
1214 		 * A codec info is for all sdw version with the part id if
1215 		 * version_id is not specified in the codec info.
1216 		 */
1217 		if (part_id == codec_info_list[i].part_id &&
1218 		    (!codec_info_list[i].version_id ||
1219 		     sdw_version == codec_info_list[i].version_id))
1220 			return &codec_info_list[i];
1221 
1222 	return NULL;
1223 
1224 }
1225 
1226 static struct sof_sdw_codec_info *find_codec_info_acpi(const u8 *acpi_id)
1227 {
1228 	int i;
1229 
1230 	if (!acpi_id[0])
1231 		return NULL;
1232 
1233 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1234 		if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN))
1235 			return &codec_info_list[i];
1236 
1237 	return NULL;
1238 }
1239 
1240 static struct sof_sdw_codec_info *find_codec_info_dai(const char *dai_name,
1241 						      int *dai_index)
1242 {
1243 	int i, j;
1244 
1245 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
1246 		for (j = 0; j < codec_info_list[i].dai_num; j++) {
1247 			if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) {
1248 				*dai_index = j;
1249 				return &codec_info_list[i];
1250 			}
1251 		}
1252 	}
1253 
1254 	return NULL;
1255 }
1256 
1257 static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
1258 			  int *be_id, char *name, int playback, int capture,
1259 			  struct snd_soc_dai_link_component *cpus, int cpus_num,
1260 			  struct snd_soc_dai_link_component *codecs, int codecs_num,
1261 			  int (*init)(struct snd_soc_pcm_runtime *rtd),
1262 			  const struct snd_soc_ops *ops)
1263 {
1264 	dev_dbg(dev, "create dai link %s, id %d\n", name, *be_id);
1265 	dai_links->id = (*be_id)++;
1266 	dai_links->name = name;
1267 	dai_links->platforms = platform_component;
1268 	dai_links->num_platforms = ARRAY_SIZE(platform_component);
1269 	dai_links->no_pcm = 1;
1270 	dai_links->cpus = cpus;
1271 	dai_links->num_cpus = cpus_num;
1272 	dai_links->codecs = codecs;
1273 	dai_links->num_codecs = codecs_num;
1274 	dai_links->dpcm_playback = playback;
1275 	dai_links->dpcm_capture = capture;
1276 	dai_links->init = init;
1277 	dai_links->ops = ops;
1278 }
1279 
1280 static int init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
1281 				int *be_id, char *name, int playback, int capture,
1282 				const char *cpu_dai_name,
1283 				const char *codec_name, const char *codec_dai_name,
1284 				int (*init)(struct snd_soc_pcm_runtime *rtd),
1285 				const struct snd_soc_ops *ops)
1286 {
1287 	struct snd_soc_dai_link_component *dlc;
1288 
1289 	/* Allocate two DLCs one for the CPU, one for the CODEC */
1290 	dlc = devm_kcalloc(dev, 2, sizeof(*dlc), GFP_KERNEL);
1291 	if (!dlc || !name || !cpu_dai_name || !codec_name || !codec_dai_name)
1292 		return -ENOMEM;
1293 
1294 	dlc[0].dai_name = cpu_dai_name;
1295 
1296 	dlc[1].name = codec_name;
1297 	dlc[1].dai_name = codec_dai_name;
1298 
1299 	init_dai_link(dev, dai_links, be_id, name, playback, capture,
1300 		      &dlc[0], 1, &dlc[1], 1, init, ops);
1301 
1302 	return 0;
1303 }
1304 
1305 static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link,
1306 			     unsigned int sdw_version,
1307 			     unsigned int mfg_id,
1308 			     unsigned int part_id,
1309 			     unsigned int class_id,
1310 			     int index_in_link)
1311 {
1312 	int i;
1313 
1314 	for (i = 0; i < adr_link->num_adr; i++) {
1315 		unsigned int sdw1_version, mfg1_id, part1_id, class1_id;
1316 		u64 adr;
1317 
1318 		/* skip itself */
1319 		if (i == index_in_link)
1320 			continue;
1321 
1322 		adr = adr_link->adr_d[i].adr;
1323 
1324 		sdw1_version = SDW_VERSION(adr);
1325 		mfg1_id = SDW_MFG_ID(adr);
1326 		part1_id = SDW_PART_ID(adr);
1327 		class1_id = SDW_CLASS_ID(adr);
1328 
1329 		if (sdw_version == sdw1_version &&
1330 		    mfg_id == mfg1_id &&
1331 		    part_id == part1_id &&
1332 		    class_id == class1_id)
1333 			return false;
1334 	}
1335 
1336 	return true;
1337 }
1338 
1339 static const char *get_codec_name(struct device *dev,
1340 				  const struct sof_sdw_codec_info *codec_info,
1341 				  const struct snd_soc_acpi_link_adr *adr_link,
1342 				  int adr_index)
1343 {
1344 	u64 adr = adr_link->adr_d[adr_index].adr;
1345 	unsigned int sdw_version = SDW_VERSION(adr);
1346 	unsigned int link_id = SDW_DISCO_LINK_ID(adr);
1347 	unsigned int unique_id = SDW_UNIQUE_ID(adr);
1348 	unsigned int mfg_id = SDW_MFG_ID(adr);
1349 	unsigned int part_id = SDW_PART_ID(adr);
1350 	unsigned int class_id = SDW_CLASS_ID(adr);
1351 
1352 	if (codec_info->codec_name)
1353 		return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL);
1354 	else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id,
1355 				  class_id, adr_index))
1356 		return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x",
1357 				      link_id, mfg_id, part_id, class_id);
1358 	else
1359 		return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x:%01x",
1360 				      link_id, mfg_id, part_id, class_id, unique_id);
1361 
1362 	return NULL;
1363 }
1364 
1365 static int sof_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
1366 {
1367 	struct snd_soc_card *card = rtd->card;
1368 	struct sof_sdw_codec_info *codec_info;
1369 	struct snd_soc_dai *dai;
1370 	int dai_index;
1371 	int ret;
1372 	int i;
1373 
1374 	for_each_rtd_codec_dais(rtd, i, dai) {
1375 		codec_info = find_codec_info_dai(dai->name, &dai_index);
1376 		if (!codec_info)
1377 			return -EINVAL;
1378 
1379 		/*
1380 		 * A codec dai can be connected to different dai links for capture and playback,
1381 		 * but we only need to call the rtd_init function once.
1382 		 * The rtd_init for each codec dai is independent. So, the order of rtd_init
1383 		 * doesn't matter.
1384 		 */
1385 		if (codec_info->dais[dai_index].rtd_init_done)
1386 			continue;
1387 
1388 		/*
1389 		 * Add card controls and dapm widgets for the first codec dai.
1390 		 * The controls and widgets will be used for all codec dais.
1391 		 */
1392 
1393 		if (i > 0)
1394 			goto skip_add_controls_widgets;
1395 
1396 		if (codec_info->dais[dai_index].controls) {
1397 			ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls,
1398 							codec_info->dais[dai_index].num_controls);
1399 			if (ret) {
1400 				dev_err(card->dev, "%#x controls addition failed: %d\n",
1401 					codec_info->part_id, ret);
1402 				return ret;
1403 			}
1404 		}
1405 		if (codec_info->dais[dai_index].widgets) {
1406 			ret = snd_soc_dapm_new_controls(&card->dapm,
1407 							codec_info->dais[dai_index].widgets,
1408 							codec_info->dais[dai_index].num_widgets);
1409 			if (ret) {
1410 				dev_err(card->dev, "%#x widgets addition failed: %d\n",
1411 					codec_info->part_id, ret);
1412 				return ret;
1413 			}
1414 		}
1415 
1416 skip_add_controls_widgets:
1417 		if (codec_info->dais[dai_index].rtd_init) {
1418 			ret = codec_info->dais[dai_index].rtd_init(rtd, dai);
1419 			if (ret)
1420 				return ret;
1421 		}
1422 		codec_info->dais[dai_index].rtd_init_done = true;
1423 	}
1424 
1425 	return 0;
1426 }
1427 
1428 struct sof_sdw_endpoint {
1429 	struct list_head list;
1430 
1431 	u32 link_mask;
1432 	const char *codec_name;
1433 	const char *name_prefix;
1434 	bool include_sidecar;
1435 
1436 	struct sof_sdw_codec_info *codec_info;
1437 	const struct sof_sdw_dai_info *dai_info;
1438 };
1439 
1440 struct sof_sdw_dailink {
1441 	bool initialised;
1442 
1443 	u8 group_id;
1444 	u32 link_mask[SNDRV_PCM_STREAM_LAST + 1];
1445 	int num_devs[SNDRV_PCM_STREAM_LAST + 1];
1446 	struct list_head endpoints;
1447 };
1448 
1449 static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"};
1450 
1451 static int count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends)
1452 {
1453 	struct device *dev = card->dev;
1454 	struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
1455 	struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
1456 	const struct snd_soc_acpi_link_adr *adr_link;
1457 	int i;
1458 
1459 	for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
1460 		*num_devs += adr_link->num_adr;
1461 
1462 		for (i = 0; i < adr_link->num_adr; i++)
1463 			*num_ends += adr_link->adr_d[i].num_endpoints;
1464 	}
1465 
1466 	dev_dbg(dev, "Found %d devices with %d endpoints\n", *num_devs, *num_ends);
1467 
1468 	return 0;
1469 }
1470 
1471 static struct sof_sdw_dailink *find_dailink(struct sof_sdw_dailink *dailinks,
1472 					    const struct snd_soc_acpi_endpoint *new)
1473 {
1474 	while (dailinks->initialised) {
1475 		if (new->aggregated && dailinks->group_id == new->group_id)
1476 			return dailinks;
1477 
1478 		dailinks++;
1479 	}
1480 
1481 	INIT_LIST_HEAD(&dailinks->endpoints);
1482 	dailinks->group_id = new->group_id;
1483 	dailinks->initialised = true;
1484 
1485 	return dailinks;
1486 }
1487 
1488 static int parse_sdw_endpoints(struct snd_soc_card *card,
1489 			       struct sof_sdw_dailink *sof_dais,
1490 			       struct sof_sdw_endpoint *sof_ends,
1491 			       int *num_devs)
1492 {
1493 	struct device *dev = card->dev;
1494 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1495 	struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
1496 	struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
1497 	const struct snd_soc_acpi_link_adr *adr_link;
1498 	struct sof_sdw_endpoint *sof_end = sof_ends;
1499 	int num_dais = 0;
1500 	int i, j;
1501 	int ret;
1502 
1503 	for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
1504 		int num_link_dailinks = 0;
1505 
1506 		if (!is_power_of_2(adr_link->mask)) {
1507 			dev_err(dev, "link with multiple mask bits: 0x%x\n",
1508 				adr_link->mask);
1509 			return -EINVAL;
1510 		}
1511 
1512 		for (i = 0; i < adr_link->num_adr; i++) {
1513 			const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i];
1514 			struct sof_sdw_codec_info *codec_info;
1515 			const char *codec_name;
1516 
1517 			if (!adr_dev->name_prefix) {
1518 				dev_err(dev, "codec 0x%llx does not have a name prefix\n",
1519 					adr_dev->adr);
1520 				return -EINVAL;
1521 			}
1522 
1523 			codec_info = find_codec_info_part(adr_dev->adr);
1524 			if (!codec_info)
1525 				return -EINVAL;
1526 
1527 			ctx->ignore_pch_dmic |= codec_info->ignore_pch_dmic;
1528 
1529 			codec_name = get_codec_name(dev, codec_info, adr_link, i);
1530 			if (!codec_name)
1531 				return -ENOMEM;
1532 
1533 			dev_dbg(dev, "Adding prefix %s for %s\n",
1534 				adr_dev->name_prefix, codec_name);
1535 
1536 			sof_end->name_prefix = adr_dev->name_prefix;
1537 
1538 			if (codec_info->count_sidecar && codec_info->add_sidecar) {
1539 				ret = codec_info->count_sidecar(card, &num_dais, num_devs);
1540 				if (ret)
1541 					return ret;
1542 
1543 				sof_end->include_sidecar = true;
1544 			}
1545 
1546 			for (j = 0; j < adr_dev->num_endpoints; j++) {
1547 				const struct snd_soc_acpi_endpoint *adr_end;
1548 				const struct sof_sdw_dai_info *dai_info;
1549 				struct sof_sdw_dailink *sof_dai;
1550 				int stream;
1551 
1552 				adr_end = &adr_dev->endpoints[j];
1553 				dai_info = &codec_info->dais[adr_end->num];
1554 				sof_dai = find_dailink(sof_dais, adr_end);
1555 
1556 				if (dai_info->quirk && !(dai_info->quirk & sof_sdw_quirk))
1557 					continue;
1558 
1559 				dev_dbg(dev,
1560 					"Add dev: %d, 0x%llx end: %d, %s, %c/%c to %s: %d\n",
1561 					ffs(adr_link->mask) - 1, adr_dev->adr,
1562 					adr_end->num, type_strings[dai_info->dai_type],
1563 					dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-',
1564 					dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-',
1565 					adr_end->aggregated ? "group" : "solo",
1566 					adr_end->group_id);
1567 
1568 				if (adr_end->num >= codec_info->dai_num) {
1569 					dev_err(dev,
1570 						"%d is too many endpoints for codec: 0x%x\n",
1571 						adr_end->num, codec_info->part_id);
1572 					return -EINVAL;
1573 				}
1574 
1575 				for_each_pcm_streams(stream) {
1576 					if (dai_info->direction[stream] &&
1577 					    dai_info->dailink[stream] < 0) {
1578 						dev_err(dev,
1579 							"Invalid dailink id %d for codec: 0x%x\n",
1580 							dai_info->dailink[stream],
1581 							codec_info->part_id);
1582 						return -EINVAL;
1583 					}
1584 
1585 					if (dai_info->direction[stream]) {
1586 						num_dais += !sof_dai->num_devs[stream];
1587 						sof_dai->num_devs[stream]++;
1588 						sof_dai->link_mask[stream] |= adr_link->mask;
1589 					}
1590 				}
1591 
1592 				num_link_dailinks += !!list_empty(&sof_dai->endpoints);
1593 				list_add_tail(&sof_end->list, &sof_dai->endpoints);
1594 
1595 				sof_end->link_mask = adr_link->mask;
1596 				sof_end->codec_name = codec_name;
1597 				sof_end->codec_info = codec_info;
1598 				sof_end->dai_info = dai_info;
1599 				sof_end++;
1600 			}
1601 		}
1602 
1603 		ctx->append_dai_type |= (num_link_dailinks > 1);
1604 	}
1605 
1606 	return num_dais;
1607 }
1608 
1609 static int create_sdw_dailink(struct snd_soc_card *card,
1610 			      struct sof_sdw_dailink *sof_dai,
1611 			      struct snd_soc_dai_link **dai_links,
1612 			      int *be_id, struct snd_soc_codec_conf **codec_conf)
1613 {
1614 	struct device *dev = card->dev;
1615 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1616 	struct sof_sdw_endpoint *sof_end;
1617 	int stream;
1618 	int ret;
1619 
1620 	list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
1621 		if (sof_end->name_prefix) {
1622 			(*codec_conf)->dlc.name = sof_end->codec_name;
1623 			(*codec_conf)->name_prefix = sof_end->name_prefix;
1624 			(*codec_conf)++;
1625 		}
1626 
1627 		if (sof_end->include_sidecar) {
1628 			ret = sof_end->codec_info->add_sidecar(card, dai_links, codec_conf);
1629 			if (ret)
1630 				return ret;
1631 		}
1632 	}
1633 
1634 	for_each_pcm_streams(stream) {
1635 		static const char * const sdw_stream_name[] = {
1636 			"SDW%d-Playback",
1637 			"SDW%d-Capture",
1638 			"SDW%d-Playback-%s",
1639 			"SDW%d-Capture-%s",
1640 		};
1641 		struct snd_soc_dai_link_ch_map *codec_maps;
1642 		struct snd_soc_dai_link_component *codecs;
1643 		struct snd_soc_dai_link_component *cpus;
1644 		int num_cpus = hweight32(sof_dai->link_mask[stream]);
1645 		int num_codecs = sof_dai->num_devs[stream];
1646 		int playback, capture;
1647 		int cur_link = 0;
1648 		int i = 0, j = 0;
1649 		char *name;
1650 
1651 		if (!sof_dai->num_devs[stream])
1652 			continue;
1653 
1654 		sof_end = list_first_entry(&sof_dai->endpoints,
1655 					   struct sof_sdw_endpoint, list);
1656 
1657 		*be_id = sof_end->dai_info->dailink[stream];
1658 		if (*be_id < 0) {
1659 			dev_err(dev, "Invalid dailink id %d\n", *be_id);
1660 			return -EINVAL;
1661 		}
1662 
1663 		/* create stream name according to first link id */
1664 		if (ctx->append_dai_type)
1665 			name = devm_kasprintf(dev, GFP_KERNEL,
1666 					      sdw_stream_name[stream + 2],
1667 					      ffs(sof_end->link_mask) - 1,
1668 					      type_strings[sof_end->dai_info->dai_type]);
1669 		else
1670 			name = devm_kasprintf(dev, GFP_KERNEL,
1671 					      sdw_stream_name[stream],
1672 					      ffs(sof_end->link_mask) - 1);
1673 		if (!name)
1674 			return -ENOMEM;
1675 
1676 		cpus = devm_kcalloc(dev, num_cpus, sizeof(*cpus), GFP_KERNEL);
1677 		if (!cpus)
1678 			return -ENOMEM;
1679 
1680 		codecs = devm_kcalloc(dev, num_codecs, sizeof(*codecs), GFP_KERNEL);
1681 		if (!codecs)
1682 			return -ENOMEM;
1683 
1684 		codec_maps = devm_kcalloc(dev, num_codecs, sizeof(*codec_maps), GFP_KERNEL);
1685 		if (!codec_maps)
1686 			return -ENOMEM;
1687 
1688 		list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
1689 			if (!sof_end->dai_info->direction[stream])
1690 				continue;
1691 
1692 			if (cur_link != sof_end->link_mask) {
1693 				int link_num = ffs(sof_end->link_mask) - 1;
1694 				int pin_num = ctx->sdw_pin_index[link_num]++;
1695 
1696 				cur_link = sof_end->link_mask;
1697 
1698 				cpus[i].dai_name = devm_kasprintf(dev, GFP_KERNEL,
1699 								  "SDW%d Pin%d",
1700 								  link_num, pin_num);
1701 				if (!cpus[i].dai_name)
1702 					return -ENOMEM;
1703 				i++;
1704 			}
1705 
1706 			codec_maps[j].cpu = i - 1;
1707 			codec_maps[j].codec = j;
1708 
1709 			codecs[j].name = sof_end->codec_name;
1710 			codecs[j].dai_name = sof_end->dai_info->dai_name;
1711 			j++;
1712 		}
1713 
1714 		WARN_ON(i != num_cpus || j != num_codecs);
1715 
1716 		playback = (stream == SNDRV_PCM_STREAM_PLAYBACK);
1717 		capture = (stream == SNDRV_PCM_STREAM_CAPTURE);
1718 
1719 		init_dai_link(dev, *dai_links, be_id, name, playback, capture,
1720 			      cpus, num_cpus, codecs, num_codecs,
1721 			      sof_sdw_rtd_init, &sdw_ops);
1722 
1723 		/*
1724 		 * SoundWire DAILINKs use 'stream' functions and Bank Switch operations
1725 		 * based on wait_for_completion(), tag them as 'nonatomic'.
1726 		 */
1727 		(*dai_links)->nonatomic = true;
1728 		(*dai_links)->ch_maps = codec_maps;
1729 
1730 		list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
1731 			if (sof_end->dai_info->init)
1732 				sof_end->dai_info->init(card, *dai_links,
1733 							sof_end->codec_info,
1734 							playback);
1735 		}
1736 
1737 		(*dai_links)++;
1738 	}
1739 
1740 	return 0;
1741 }
1742 
1743 static int create_sdw_dailinks(struct snd_soc_card *card,
1744 			       struct snd_soc_dai_link **dai_links, int *be_id,
1745 			       struct sof_sdw_dailink *sof_dais,
1746 			       struct snd_soc_codec_conf **codec_conf)
1747 {
1748 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1749 	int ret, i;
1750 
1751 	for (i = 0; i < SDW_MAX_LINKS; i++)
1752 		ctx->sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE;
1753 
1754 	/* generate DAI links by each sdw link */
1755 	while (sof_dais->initialised) {
1756 		int current_be_id;
1757 
1758 		ret = create_sdw_dailink(card, sof_dais, dai_links,
1759 					 &current_be_id, codec_conf);
1760 		if (ret)
1761 			return ret;
1762 
1763 		/* Update the be_id to match the highest ID used for SDW link */
1764 		if (*be_id < current_be_id)
1765 			*be_id = current_be_id;
1766 
1767 		sof_dais++;
1768 	}
1769 
1770 	return 0;
1771 }
1772 
1773 static int create_ssp_dailinks(struct snd_soc_card *card,
1774 			       struct snd_soc_dai_link **dai_links, int *be_id,
1775 			       struct sof_sdw_codec_info *ssp_info,
1776 			       unsigned long ssp_mask)
1777 {
1778 	struct device *dev = card->dev;
1779 	int i, j = 0;
1780 	int ret;
1781 
1782 	for_each_set_bit(i, &ssp_mask, BITS_PER_TYPE(ssp_mask)) {
1783 		char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", i);
1784 		char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i);
1785 		char *codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d",
1786 						  ssp_info->acpi_id, j++);
1787 		int playback = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK];
1788 		int capture = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE];
1789 
1790 		ret = init_simple_dai_link(dev, *dai_links, be_id, name,
1791 					   playback, capture, cpu_dai_name,
1792 					   codec_name, ssp_info->dais[0].dai_name,
1793 					   NULL, ssp_info->ops);
1794 		if (ret)
1795 			return ret;
1796 
1797 		ret = ssp_info->dais[0].init(card, *dai_links, ssp_info, 0);
1798 		if (ret < 0)
1799 			return ret;
1800 
1801 		(*dai_links)++;
1802 	}
1803 
1804 	return 0;
1805 }
1806 
1807 static int create_dmic_dailinks(struct snd_soc_card *card,
1808 				struct snd_soc_dai_link **dai_links, int *be_id)
1809 {
1810 	struct device *dev = card->dev;
1811 	int ret;
1812 
1813 	ret = init_simple_dai_link(dev, *dai_links, be_id, "dmic01",
1814 				   0, 1, // DMIC only supports capture
1815 				   "DMIC01 Pin", "dmic-codec", "dmic-hifi",
1816 				   sof_sdw_dmic_init, NULL);
1817 	if (ret)
1818 		return ret;
1819 
1820 	(*dai_links)++;
1821 
1822 	ret = init_simple_dai_link(dev, *dai_links, be_id, "dmic16k",
1823 				   0, 1, // DMIC only supports capture
1824 				   "DMIC16k Pin", "dmic-codec", "dmic-hifi",
1825 				   /* don't call sof_sdw_dmic_init() twice */
1826 				   NULL, NULL);
1827 	if (ret)
1828 		return ret;
1829 
1830 	(*dai_links)++;
1831 
1832 	return 0;
1833 }
1834 
1835 static int create_hdmi_dailinks(struct snd_soc_card *card,
1836 				struct snd_soc_dai_link **dai_links, int *be_id,
1837 				int hdmi_num)
1838 {
1839 	struct device *dev = card->dev;
1840 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1841 	int i, ret;
1842 
1843 	for (i = 0; i < hdmi_num; i++) {
1844 		char *name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1);
1845 		char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1);
1846 		char *codec_name, *codec_dai_name;
1847 
1848 		if (ctx->hdmi.idisp_codec) {
1849 			codec_name = "ehdaudio0D2";
1850 			codec_dai_name = devm_kasprintf(dev, GFP_KERNEL,
1851 							"intel-hdmi-hifi%d", i + 1);
1852 		} else {
1853 			codec_name = "snd-soc-dummy";
1854 			codec_dai_name = "snd-soc-dummy-dai";
1855 		}
1856 
1857 		ret = init_simple_dai_link(dev, *dai_links, be_id, name,
1858 					   1, 0, // HDMI only supports playback
1859 					   cpu_dai_name, codec_name, codec_dai_name,
1860 					   i == 0 ? sof_sdw_hdmi_init : NULL, NULL);
1861 		if (ret)
1862 			return ret;
1863 
1864 		(*dai_links)++;
1865 	}
1866 
1867 	return 0;
1868 }
1869 
1870 static int create_bt_dailinks(struct snd_soc_card *card,
1871 			      struct snd_soc_dai_link **dai_links, int *be_id)
1872 {
1873 	struct device *dev = card->dev;
1874 	int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
1875 			SOF_BT_OFFLOAD_SSP_SHIFT;
1876 	char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
1877 	char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port);
1878 	int ret;
1879 
1880 	ret = init_simple_dai_link(dev, *dai_links, be_id, name,
1881 				   1, 1, cpu_dai_name, snd_soc_dummy_dlc.name,
1882 				   snd_soc_dummy_dlc.dai_name, NULL, NULL);
1883 	if (ret)
1884 		return ret;
1885 
1886 	(*dai_links)++;
1887 
1888 	return 0;
1889 }
1890 
1891 static int sof_card_dai_links_create(struct snd_soc_card *card)
1892 {
1893 	struct device *dev = card->dev;
1894 	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
1895 	int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, bt_num = 0;
1896 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1897 	struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
1898 	struct snd_soc_codec_conf *codec_conf;
1899 	struct sof_sdw_codec_info *ssp_info;
1900 	struct sof_sdw_endpoint *sof_ends;
1901 	struct sof_sdw_dailink *sof_dais;
1902 	int num_devs = 0;
1903 	int num_ends = 0;
1904 	struct snd_soc_dai_link *dai_links;
1905 	int num_links;
1906 	int be_id = 0;
1907 	int hdmi_num;
1908 	unsigned long ssp_mask;
1909 	int ret;
1910 
1911 	ret = count_sdw_endpoints(card, &num_devs, &num_ends);
1912 	if (ret < 0) {
1913 		dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
1914 		return ret;
1915 	}
1916 
1917 	/* One per DAI link, worst case is a DAI link for every endpoint */
1918 	sof_dais = kcalloc(num_ends, sizeof(*sof_dais), GFP_KERNEL);
1919 	if (!sof_dais)
1920 		return -ENOMEM;
1921 
1922 	/* One per endpoint, ie. each DAI on each codec/amp */
1923 	sof_ends = kcalloc(num_ends, sizeof(*sof_ends), GFP_KERNEL);
1924 	if (!sof_ends) {
1925 		ret = -ENOMEM;
1926 		goto err_dai;
1927 	}
1928 
1929 	ret = parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs);
1930 	if (ret < 0)
1931 		goto err_end;
1932 
1933 	sdw_be_num = ret;
1934 
1935 	/*
1936 	 * on generic tgl platform, I2S or sdw mode is supported
1937 	 * based on board rework. A ACPI device is registered in
1938 	 * system only when I2S mode is supported, not sdw mode.
1939 	 * Here check ACPI ID to confirm I2S is supported.
1940 	 */
1941 	ssp_info = find_codec_info_acpi(mach->id);
1942 	if (ssp_info) {
1943 		ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk);
1944 		ssp_num = hweight_long(ssp_mask);
1945 	}
1946 
1947 	if (mach_params->codec_mask & IDISP_CODEC_MASK)
1948 		ctx->hdmi.idisp_codec = true;
1949 
1950 	if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
1951 		hdmi_num = SOF_TGL_HDMI_COUNT;
1952 	else
1953 		hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
1954 
1955 	/* enable dmic01 & dmic16k */
1956 	if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num)
1957 		dmic_num = 2;
1958 
1959 	if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
1960 		bt_num = 1;
1961 
1962 	dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n",
1963 		sdw_be_num, ssp_num, dmic_num,
1964 		ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
1965 
1966 	codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
1967 	if (!codec_conf) {
1968 		ret = -ENOMEM;
1969 		goto err_end;
1970 	}
1971 
1972 	/* allocate BE dailinks */
1973 	num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num;
1974 	dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL);
1975 	if (!dai_links) {
1976 		ret = -ENOMEM;
1977 		goto err_end;
1978 	}
1979 
1980 	card->codec_conf = codec_conf;
1981 	card->num_configs = num_devs;
1982 	card->dai_link = dai_links;
1983 	card->num_links = num_links;
1984 
1985 	/* SDW */
1986 	if (sdw_be_num) {
1987 		ret = create_sdw_dailinks(card, &dai_links, &be_id,
1988 					  sof_dais, &codec_conf);
1989 		if (ret)
1990 			goto err_end;
1991 	}
1992 
1993 	/* SSP */
1994 	if (ssp_num) {
1995 		ret = create_ssp_dailinks(card, &dai_links, &be_id,
1996 					  ssp_info, ssp_mask);
1997 		if (ret)
1998 			goto err_end;
1999 	}
2000 
2001 	/* dmic */
2002 	if (dmic_num > 0) {
2003 		if (ctx->ignore_pch_dmic) {
2004 			dev_warn(dev, "Ignoring PCH DMIC\n");
2005 		} else {
2006 			ret = create_dmic_dailinks(card, &dai_links, &be_id);
2007 			if (ret)
2008 				goto err_end;
2009 		}
2010 	}
2011 
2012 	/* HDMI */
2013 	ret = create_hdmi_dailinks(card, &dai_links, &be_id, hdmi_num);
2014 	if (ret)
2015 		goto err_end;
2016 
2017 	/* BT */
2018 	if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
2019 		ret = create_bt_dailinks(card, &dai_links, &be_id);
2020 		if (ret)
2021 			goto err_end;
2022 	}
2023 
2024 	WARN_ON(codec_conf != card->codec_conf + card->num_configs);
2025 	WARN_ON(dai_links != card->dai_link + card->num_links);
2026 
2027 err_end:
2028 	kfree(sof_ends);
2029 err_dai:
2030 	kfree(sof_dais);
2031 
2032 	return ret;
2033 }
2034 
2035 static int sof_sdw_card_late_probe(struct snd_soc_card *card)
2036 {
2037 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
2038 	int ret = 0;
2039 	int i;
2040 
2041 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
2042 		if (codec_info_list[i].codec_card_late_probe) {
2043 			ret = codec_info_list[i].codec_card_late_probe(card);
2044 
2045 			if (ret < 0)
2046 				return ret;
2047 		}
2048 	}
2049 
2050 	if (ctx->hdmi.idisp_codec)
2051 		ret = sof_sdw_hdmi_card_late_probe(card);
2052 
2053 	return ret;
2054 }
2055 
2056 /* helper to get the link that the codec DAI is used */
2057 static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card,
2058 						       const char *dai_name)
2059 {
2060 	struct snd_soc_dai_link *dai_link;
2061 	int i;
2062 	int j;
2063 
2064 	for_each_card_prelinks(card, i, dai_link) {
2065 		for (j = 0; j < dai_link->num_codecs; j++) {
2066 			/* Check each codec in a link */
2067 			if (!strcmp(dai_link->codecs[j].dai_name, dai_name))
2068 				return dai_link;
2069 		}
2070 	}
2071 	return NULL;
2072 }
2073 
2074 static void mc_dailink_exit_loop(struct snd_soc_card *card)
2075 {
2076 	struct snd_soc_dai_link *dai_link;
2077 	int ret;
2078 	int i, j;
2079 
2080 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
2081 		for (j = 0; j < codec_info_list[i].dai_num; j++) {
2082 			codec_info_list[i].dais[j].rtd_init_done = false;
2083 			/* Check each dai in codec_info_lis to see if it is used in the link */
2084 			if (!codec_info_list[i].dais[j].exit)
2085 				continue;
2086 			/*
2087 			 * We don't need to call .exit function if there is no matched
2088 			 * dai link found.
2089 			 */
2090 			dai_link = mc_find_codec_dai_used(card,
2091 							  codec_info_list[i].dais[j].dai_name);
2092 			if (dai_link) {
2093 				/* Do the .exit function if the codec dai is used in the link */
2094 				ret = codec_info_list[i].dais[j].exit(card, dai_link);
2095 				if (ret)
2096 					dev_warn(card->dev,
2097 						 "codec exit failed %d\n",
2098 						 ret);
2099 				break;
2100 			}
2101 		}
2102 	}
2103 }
2104 
2105 static int mc_probe(struct platform_device *pdev)
2106 {
2107 	struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev);
2108 	struct snd_soc_card *card;
2109 	struct mc_private *ctx;
2110 	int amp_num = 0, i;
2111 	int ret;
2112 
2113 	dev_dbg(&pdev->dev, "Entry\n");
2114 
2115 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
2116 	if (!ctx)
2117 		return -ENOMEM;
2118 
2119 	card = &ctx->card;
2120 	card->dev = &pdev->dev;
2121 	card->name = "soundwire",
2122 	card->owner = THIS_MODULE,
2123 	card->late_probe = sof_sdw_card_late_probe,
2124 
2125 	snd_soc_card_set_drvdata(card, ctx);
2126 
2127 	dmi_check_system(sof_sdw_quirk_table);
2128 
2129 	if (quirk_override != -1) {
2130 		dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n",
2131 			 sof_sdw_quirk, quirk_override);
2132 		sof_sdw_quirk = quirk_override;
2133 	}
2134 
2135 	log_quirks(card->dev);
2136 
2137 	/* reset amp_num to ensure amp_num++ starts from 0 in each probe */
2138 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
2139 		codec_info_list[i].amp_num = 0;
2140 
2141 	if (mach->mach_params.subsystem_id_set) {
2142 		snd_soc_card_set_pci_ssid(card,
2143 					  mach->mach_params.subsystem_vendor,
2144 					  mach->mach_params.subsystem_device);
2145 	}
2146 
2147 	ret = sof_card_dai_links_create(card);
2148 	if (ret < 0)
2149 		return ret;
2150 
2151 	/*
2152 	 * the default amp_num is zero for each codec and
2153 	 * amp_num will only be increased for active amp
2154 	 * codecs on used platform
2155 	 */
2156 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
2157 		amp_num += codec_info_list[i].amp_num;
2158 
2159 	card->components = devm_kasprintf(card->dev, GFP_KERNEL,
2160 					  " cfg-amp:%d", amp_num);
2161 	if (!card->components)
2162 		return -ENOMEM;
2163 
2164 	if (mach->mach_params.dmic_num) {
2165 		card->components = devm_kasprintf(card->dev, GFP_KERNEL,
2166 						  "%s mic:dmic cfg-mics:%d",
2167 						  card->components,
2168 						  mach->mach_params.dmic_num);
2169 		if (!card->components)
2170 			return -ENOMEM;
2171 	}
2172 
2173 	/* Register the card */
2174 	ret = devm_snd_soc_register_card(card->dev, card);
2175 	if (ret) {
2176 		dev_err_probe(card->dev, ret, "snd_soc_register_card failed %d\n", ret);
2177 		mc_dailink_exit_loop(card);
2178 		return ret;
2179 	}
2180 
2181 	platform_set_drvdata(pdev, card);
2182 
2183 	return ret;
2184 }
2185 
2186 static void mc_remove(struct platform_device *pdev)
2187 {
2188 	struct snd_soc_card *card = platform_get_drvdata(pdev);
2189 
2190 	mc_dailink_exit_loop(card);
2191 }
2192 
2193 static const struct platform_device_id mc_id_table[] = {
2194 	{ "sof_sdw", },
2195 	{}
2196 };
2197 MODULE_DEVICE_TABLE(platform, mc_id_table);
2198 
2199 static struct platform_driver sof_sdw_driver = {
2200 	.driver = {
2201 		.name = "sof_sdw",
2202 		.pm = &snd_soc_pm_ops,
2203 	},
2204 	.probe = mc_probe,
2205 	.remove_new = mc_remove,
2206 	.id_table = mc_id_table,
2207 };
2208 
2209 module_platform_driver(sof_sdw_driver);
2210 
2211 MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver");
2212 MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>");
2213 MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>");
2214 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
2215 MODULE_LICENSE("GPL v2");
2216 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
2217