xref: /openbmc/linux/sound/soc/intel/boards/sof_sdw.c (revision aa74c44b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (c) 2020 Intel Corporation
3 
4 /*
5  *  sof_sdw - ASOC Machine driver for Intel SoundWire platforms
6  */
7 
8 #include <linux/device.h>
9 #include <linux/dmi.h>
10 #include <linux/module.h>
11 #include <linux/soundwire/sdw.h>
12 #include <linux/soundwire/sdw_type.h>
13 #include <sound/soc.h>
14 #include <sound/soc-acpi.h>
15 #include "sof_sdw_common.h"
16 #include "../../codecs/rt711.h"
17 
18 unsigned long sof_sdw_quirk = RT711_JD1;
19 static int quirk_override = -1;
20 module_param_named(quirk, quirk_override, int, 0444);
21 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
22 
23 #define INC_ID(BE, CPU, LINK)	do { (BE)++; (CPU)++; (LINK)++; } while (0)
24 
25 static void log_quirks(struct device *dev)
26 {
27 	if (SOF_RT711_JDSRC(sof_sdw_quirk))
28 		dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n",
29 			SOF_RT711_JDSRC(sof_sdw_quirk));
30 	if (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
31 		dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n");
32 	if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
33 		dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n");
34 	if (sof_sdw_quirk & SOF_SDW_PCH_DMIC)
35 		dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n");
36 	if (SOF_SSP_GET_PORT(sof_sdw_quirk))
37 		dev_dbg(dev, "SSP port %ld\n",
38 			SOF_SSP_GET_PORT(sof_sdw_quirk));
39 	if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION)
40 		dev_dbg(dev, "quirk SOF_SDW_NO_AGGREGATION enabled\n");
41 }
42 
43 static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
44 {
45 	sof_sdw_quirk = (unsigned long)id->driver_data;
46 	return 1;
47 }
48 
49 static const struct dmi_system_id sof_sdw_quirk_table[] = {
50 	/* CometLake devices */
51 	{
52 		.callback = sof_sdw_quirk_cb,
53 		.matches = {
54 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
55 			DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"),
56 		},
57 		.driver_data = (void *)SOF_SDW_PCH_DMIC,
58 	},
59 	{
60 		.callback = sof_sdw_quirk_cb,
61 		.matches = {
62 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
63 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
64 		},
65 		.driver_data = (void *)RT711_JD2,
66 	},
67 	{
68 		/* early version of SKU 09C6 */
69 		.callback = sof_sdw_quirk_cb,
70 		.matches = {
71 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
72 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
73 		},
74 		.driver_data = (void *)RT711_JD2,
75 	},
76 	{
77 		.callback = sof_sdw_quirk_cb,
78 		.matches = {
79 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
80 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
81 		},
82 		.driver_data = (void *)(RT711_JD2 |
83 					SOF_SDW_FOUR_SPK),
84 	},
85 	{
86 		.callback = sof_sdw_quirk_cb,
87 		.matches = {
88 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
89 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
90 		},
91 		.driver_data = (void *)(RT711_JD2 |
92 					SOF_SDW_FOUR_SPK),
93 	},
94 	/* IceLake devices */
95 	{
96 		.callback = sof_sdw_quirk_cb,
97 		.matches = {
98 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
99 			DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
100 		},
101 		.driver_data = (void *)SOF_SDW_PCH_DMIC,
102 	},
103 	/* TigerLake devices */
104 	{
105 		.callback = sof_sdw_quirk_cb,
106 		.matches = {
107 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
108 			DMI_MATCH(DMI_PRODUCT_NAME,
109 				  "Tiger Lake Client Platform"),
110 		},
111 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
112 					RT711_JD1 |
113 					SOF_SDW_PCH_DMIC |
114 					SOF_SSP_PORT(SOF_I2S_SSP2)),
115 	},
116 	{
117 		.callback = sof_sdw_quirk_cb,
118 		.matches = {
119 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
120 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E")
121 		},
122 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
123 					RT711_JD2),
124 	},
125 	{
126 		/* another SKU of Dell Latitude 9520 */
127 		.callback = sof_sdw_quirk_cb,
128 		.matches = {
129 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
130 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3F")
131 		},
132 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
133 					RT711_JD2),
134 	},
135 	{
136 		/* Dell XPS 9710 */
137 		.callback = sof_sdw_quirk_cb,
138 		.matches = {
139 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
140 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D")
141 		},
142 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
143 					RT711_JD2 |
144 					SOF_SDW_FOUR_SPK),
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 					SOF_SDW_FOUR_SPK),
155 	},
156 	{
157 		.callback = sof_sdw_quirk_cb,
158 		.matches = {
159 			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
160 			DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"),
161 		},
162 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
163 					SOF_SDW_PCH_DMIC |
164 					SOF_SDW_FOUR_SPK |
165 					SOF_BT_OFFLOAD_SSP(2) |
166 					SOF_SSP_BT_OFFLOAD_PRESENT),
167 	},
168 	{
169 		.callback = sof_sdw_quirk_cb,
170 		.matches = {
171 			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
172 			DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"),
173 		},
174 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
175 					SOF_SDW_PCH_DMIC |
176 					SOF_SDW_FOUR_SPK),
177 	},
178 	{
179 		/*
180 		 * this entry covers multiple HP SKUs. The family name
181 		 * does not seem robust enough, so we use a partial
182 		 * match that ignores the product name suffix
183 		 * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx)
184 		 */
185 		.callback = sof_sdw_quirk_cb,
186 		.matches = {
187 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
188 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"),
189 		},
190 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
191 					SOF_SDW_PCH_DMIC |
192 					RT711_JD1),
193 	},
194 	{
195 		/* NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */
196 		.callback = sof_sdw_quirk_cb,
197 		.matches = {
198 			DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
199 			DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"),
200 		},
201 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
202 					SOF_SDW_PCH_DMIC |
203 					RT711_JD1),
204 	},
205 	/* TigerLake-SDCA devices */
206 	{
207 		.callback = sof_sdw_quirk_cb,
208 		.matches = {
209 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
210 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32")
211 		},
212 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
213 					RT711_JD2 |
214 					SOF_SDW_FOUR_SPK),
215 	},
216 	{
217 		.callback = sof_sdw_quirk_cb,
218 		.matches = {
219 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
220 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A45")
221 		},
222 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
223 					RT711_JD2),
224 	},
225 	/* AlderLake devices */
226 	{
227 		.callback = sof_sdw_quirk_cb,
228 		.matches = {
229 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
230 			DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
231 		},
232 		.driver_data = (void *)(RT711_JD2_100K |
233 					SOF_SDW_TGL_HDMI |
234 					SOF_BT_OFFLOAD_SSP(2) |
235 					SOF_SSP_BT_OFFLOAD_PRESENT),
236 	},
237 	{
238 		.callback = sof_sdw_quirk_cb,
239 		.matches = {
240 			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
241 			DMI_MATCH(DMI_PRODUCT_NAME, "Brya"),
242 		},
243 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
244 					SOF_SDW_PCH_DMIC |
245 					SOF_SDW_FOUR_SPK |
246 					SOF_BT_OFFLOAD_SSP(2) |
247 					SOF_SSP_BT_OFFLOAD_PRESENT),
248 	},
249 	{
250 		.callback = sof_sdw_quirk_cb,
251 		.matches = {
252 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
253 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF3"),
254 		},
255 		/* No Jack */
256 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
257 					SOF_SDW_FOUR_SPK),
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, "0B00")
264 		},
265 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
266 					RT711_JD2 |
267 					SOF_SDW_FOUR_SPK),
268 	},
269 	{
270 		.callback = sof_sdw_quirk_cb,
271 		.matches = {
272 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
273 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01")
274 		},
275 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
276 					RT711_JD2 |
277 					SOF_SDW_FOUR_SPK),
278 	},
279 	{
280 		.callback = sof_sdw_quirk_cb,
281 		.matches = {
282 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
283 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B11")
284 		},
285 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
286 					RT711_JD2 |
287 					SOF_SDW_FOUR_SPK),
288 	},
289 	{
290 		.callback = sof_sdw_quirk_cb,
291 		.matches = {
292 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
293 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B12")
294 		},
295 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
296 					RT711_JD2 |
297 					SOF_SDW_FOUR_SPK),
298 	},
299 	{
300 		.callback = sof_sdw_quirk_cb,
301 		.matches = {
302 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
303 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B13"),
304 		},
305 		/* No Jack */
306 		.driver_data = (void *)SOF_SDW_TGL_HDMI,
307 	},
308 	{
309 		.callback = sof_sdw_quirk_cb,
310 		.matches = {
311 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
312 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B29"),
313 		},
314 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
315 					RT711_JD2 |
316 					SOF_SDW_FOUR_SPK),
317 	},
318 	{}
319 };
320 
321 static struct snd_soc_dai_link_component dmic_component[] = {
322 	{
323 		.name = "dmic-codec",
324 		.dai_name = "dmic-hifi",
325 	}
326 };
327 
328 static struct snd_soc_dai_link_component platform_component[] = {
329 	{
330 		/* name might be overridden during probe */
331 		.name = "0000:00:1f.3"
332 	}
333 };
334 
335 /* these wrappers are only needed to avoid typecast compilation errors */
336 int sdw_startup(struct snd_pcm_substream *substream)
337 {
338 	return sdw_startup_stream(substream);
339 }
340 
341 int sdw_prepare(struct snd_pcm_substream *substream)
342 {
343 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
344 	struct sdw_stream_runtime *sdw_stream;
345 	struct snd_soc_dai *dai;
346 
347 	/* Find stream from first CPU DAI */
348 	dai = asoc_rtd_to_cpu(rtd, 0);
349 
350 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
351 
352 	if (IS_ERR(sdw_stream)) {
353 		dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
354 		return PTR_ERR(sdw_stream);
355 	}
356 
357 	return sdw_prepare_stream(sdw_stream);
358 }
359 
360 int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
361 {
362 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
363 	struct sdw_stream_runtime *sdw_stream;
364 	struct snd_soc_dai *dai;
365 	int ret;
366 
367 	/* Find stream from first CPU DAI */
368 	dai = asoc_rtd_to_cpu(rtd, 0);
369 
370 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
371 
372 	if (IS_ERR(sdw_stream)) {
373 		dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
374 		return PTR_ERR(sdw_stream);
375 	}
376 
377 	switch (cmd) {
378 	case SNDRV_PCM_TRIGGER_START:
379 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
380 	case SNDRV_PCM_TRIGGER_RESUME:
381 		ret = sdw_enable_stream(sdw_stream);
382 		break;
383 
384 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
385 	case SNDRV_PCM_TRIGGER_SUSPEND:
386 	case SNDRV_PCM_TRIGGER_STOP:
387 		ret = sdw_disable_stream(sdw_stream);
388 		break;
389 	default:
390 		ret = -EINVAL;
391 		break;
392 	}
393 
394 	if (ret)
395 		dev_err(rtd->dev, "%s trigger %d failed: %d", __func__, cmd, ret);
396 
397 	return ret;
398 }
399 
400 int sdw_hw_free(struct snd_pcm_substream *substream)
401 {
402 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
403 	struct sdw_stream_runtime *sdw_stream;
404 	struct snd_soc_dai *dai;
405 
406 	/* Find stream from first CPU DAI */
407 	dai = asoc_rtd_to_cpu(rtd, 0);
408 
409 	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
410 
411 	if (IS_ERR(sdw_stream)) {
412 		dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
413 		return PTR_ERR(sdw_stream);
414 	}
415 
416 	return sdw_deprepare_stream(sdw_stream);
417 }
418 
419 void sdw_shutdown(struct snd_pcm_substream *substream)
420 {
421 	sdw_shutdown_stream(substream);
422 }
423 
424 static const struct snd_soc_ops sdw_ops = {
425 	.startup = sdw_startup,
426 	.prepare = sdw_prepare,
427 	.trigger = sdw_trigger,
428 	.hw_free = sdw_hw_free,
429 	.shutdown = sdw_shutdown,
430 };
431 
432 static struct sof_sdw_codec_info codec_info_list[] = {
433 	{
434 		.part_id = 0x700,
435 		.direction = {true, true},
436 		.dai_name = "rt700-aif1",
437 		.init = sof_sdw_rt700_init,
438 		.codec_type = SOF_SDW_CODEC_TYPE_JACK,
439 	},
440 	{
441 		.part_id = 0x711,
442 		.version_id = 3,
443 		.direction = {true, true},
444 		.dai_name = "rt711-sdca-aif1",
445 		.init = sof_sdw_rt711_sdca_init,
446 		.exit = sof_sdw_rt711_sdca_exit,
447 		.codec_type = SOF_SDW_CODEC_TYPE_JACK,
448 	},
449 	{
450 		.part_id = 0x711,
451 		.version_id = 2,
452 		.direction = {true, true},
453 		.dai_name = "rt711-aif1",
454 		.init = sof_sdw_rt711_init,
455 		.exit = sof_sdw_rt711_exit,
456 		.codec_type = SOF_SDW_CODEC_TYPE_JACK,
457 	},
458 	{
459 		.part_id = 0x1308,
460 		.acpi_id = "10EC1308",
461 		.direction = {true, false},
462 		.dai_name = "rt1308-aif",
463 		.ops = &sof_sdw_rt1308_i2s_ops,
464 		.init = sof_sdw_rt1308_init,
465 		.codec_type = SOF_SDW_CODEC_TYPE_AMP,
466 	},
467 	{
468 		.part_id = 0x1316,
469 		.direction = {true, true},
470 		.dai_name = "rt1316-aif",
471 		.init = sof_sdw_rt1316_init,
472 		.codec_type = SOF_SDW_CODEC_TYPE_AMP,
473 	},
474 	{
475 		.part_id = 0x714,
476 		.version_id = 3,
477 		.direction = {false, true},
478 		.ignore_pch_dmic = true,
479 		.dai_name = "rt715-aif2",
480 		.init = sof_sdw_rt715_sdca_init,
481 		.codec_type = SOF_SDW_CODEC_TYPE_MIC,
482 	},
483 	{
484 		.part_id = 0x715,
485 		.version_id = 3,
486 		.direction = {false, true},
487 		.ignore_pch_dmic = true,
488 		.dai_name = "rt715-aif2",
489 		.init = sof_sdw_rt715_sdca_init,
490 		.codec_type = SOF_SDW_CODEC_TYPE_MIC,
491 	},
492 	{
493 		.part_id = 0x714,
494 		.version_id = 2,
495 		.direction = {false, true},
496 		.ignore_pch_dmic = true,
497 		.dai_name = "rt715-aif2",
498 		.init = sof_sdw_rt715_init,
499 		.codec_type = SOF_SDW_CODEC_TYPE_MIC,
500 	},
501 	{
502 		.part_id = 0x715,
503 		.version_id = 2,
504 		.direction = {false, true},
505 		.ignore_pch_dmic = true,
506 		.dai_name = "rt715-aif2",
507 		.init = sof_sdw_rt715_init,
508 		.codec_type = SOF_SDW_CODEC_TYPE_MIC,
509 	},
510 	{
511 		.part_id = 0x8373,
512 		.direction = {true, true},
513 		.dai_name = "max98373-aif1",
514 		.init = sof_sdw_mx8373_init,
515 		.codec_card_late_probe = sof_sdw_mx8373_late_probe,
516 		.codec_type = SOF_SDW_CODEC_TYPE_AMP,
517 	},
518 	{
519 		.part_id = 0x5682,
520 		.direction = {true, true},
521 		.dai_name = "rt5682-sdw",
522 		.init = sof_sdw_rt5682_init,
523 		.codec_type = SOF_SDW_CODEC_TYPE_JACK,
524 	},
525 	{
526 		.part_id = 0xaaaa, /* generic codec mockup */
527 		.version_id = 0,
528 		.direction = {true, true},
529 		.dai_name = "sdw-mockup-aif1",
530 		.init = NULL,
531 		.codec_type = SOF_SDW_CODEC_TYPE_JACK,
532 	},
533 	{
534 		.part_id = 0xaa55, /* headset codec mockup */
535 		.version_id = 0,
536 		.direction = {true, true},
537 		.dai_name = "sdw-mockup-aif1",
538 		.init = NULL,
539 		.codec_type = SOF_SDW_CODEC_TYPE_JACK,
540 	},
541 	{
542 		.part_id = 0x55aa, /* amplifier mockup */
543 		.version_id = 0,
544 		.direction = {true, false},
545 		.dai_name = "sdw-mockup-aif1",
546 		.init = NULL,
547 		.codec_type = SOF_SDW_CODEC_TYPE_AMP,
548 	},
549 	{
550 		.part_id = 0x5555,
551 		.version_id = 0,
552 		.direction = {false, true},
553 		.dai_name = "sdw-mockup-aif1",
554 		.codec_type = SOF_SDW_CODEC_TYPE_MIC,
555 	},
556 };
557 
558 static inline int find_codec_info_part(u64 adr)
559 {
560 	unsigned int part_id, sdw_version;
561 	int i;
562 
563 	part_id = SDW_PART_ID(adr);
564 	sdw_version = SDW_VERSION(adr);
565 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
566 		/*
567 		 * A codec info is for all sdw version with the part id if
568 		 * version_id is not specified in the codec info.
569 		 */
570 		if (part_id == codec_info_list[i].part_id &&
571 		    (!codec_info_list[i].version_id ||
572 		     sdw_version == codec_info_list[i].version_id))
573 			return i;
574 
575 	return -EINVAL;
576 
577 }
578 
579 static inline int find_codec_info_acpi(const u8 *acpi_id)
580 {
581 	int i;
582 
583 	if (!acpi_id[0])
584 		return -EINVAL;
585 
586 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
587 		if (!memcmp(codec_info_list[i].acpi_id, acpi_id,
588 			    ACPI_ID_LEN))
589 			break;
590 
591 	if (i == ARRAY_SIZE(codec_info_list))
592 		return -EINVAL;
593 
594 	return i;
595 }
596 
597 /*
598  * get BE dailink number and CPU DAI number based on sdw link adr.
599  * Since some sdw slaves may be aggregated, the CPU DAI number
600  * may be larger than the number of BE dailinks.
601  */
602 static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_link_adr *links,
603 				int *sdw_be_num, int *sdw_cpu_dai_num)
604 {
605 	const struct snd_soc_acpi_link_adr *link;
606 	int _codec_type = SOF_SDW_CODEC_TYPE_JACK;
607 	bool group_visited[SDW_MAX_GROUPS];
608 	bool no_aggregation;
609 	int i;
610 
611 	no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION;
612 	*sdw_cpu_dai_num = 0;
613 	*sdw_be_num  = 0;
614 
615 	if (!links)
616 		return -EINVAL;
617 
618 	for (i = 0; i < SDW_MAX_GROUPS; i++)
619 		group_visited[i] = false;
620 
621 	for (link = links; link->num_adr; link++) {
622 		const struct snd_soc_acpi_endpoint *endpoint;
623 		int codec_index;
624 		int stream;
625 		u64 adr;
626 
627 		adr = link->adr_d->adr;
628 		codec_index = find_codec_info_part(adr);
629 		if (codec_index < 0)
630 			return codec_index;
631 
632 		if (codec_info_list[codec_index].codec_type < _codec_type)
633 			dev_warn(dev,
634 				 "Unexpected address table ordering. Expected order: jack -> amp -> mic\n");
635 
636 		_codec_type = codec_info_list[codec_index].codec_type;
637 
638 		endpoint = link->adr_d->endpoints;
639 
640 		/* count DAI number for playback and capture */
641 		for_each_pcm_streams(stream) {
642 			if (!codec_info_list[codec_index].direction[stream])
643 				continue;
644 
645 			(*sdw_cpu_dai_num)++;
646 
647 			/* count BE for each non-aggregated slave or group */
648 			if (!endpoint->aggregated || no_aggregation ||
649 			    !group_visited[endpoint->group_id])
650 				(*sdw_be_num)++;
651 		}
652 
653 		if (endpoint->aggregated)
654 			group_visited[endpoint->group_id] = true;
655 	}
656 
657 	return 0;
658 }
659 
660 static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
661 			  int be_id, char *name, int playback, int capture,
662 			  struct snd_soc_dai_link_component *cpus, int cpus_num,
663 			  struct snd_soc_dai_link_component *codecs, int codecs_num,
664 			  int (*init)(struct snd_soc_pcm_runtime *rtd),
665 			  const struct snd_soc_ops *ops)
666 {
667 	dev_dbg(dev, "create dai link %s, id %d\n", name, be_id);
668 	dai_links->id = be_id;
669 	dai_links->name = name;
670 	dai_links->platforms = platform_component;
671 	dai_links->num_platforms = ARRAY_SIZE(platform_component);
672 	dai_links->no_pcm = 1;
673 	dai_links->cpus = cpus;
674 	dai_links->num_cpus = cpus_num;
675 	dai_links->codecs = codecs;
676 	dai_links->num_codecs = codecs_num;
677 	dai_links->dpcm_playback = playback;
678 	dai_links->dpcm_capture = capture;
679 	dai_links->init = init;
680 	dai_links->ops = ops;
681 }
682 
683 static bool is_unique_device(const struct snd_soc_acpi_link_adr *link,
684 			     unsigned int sdw_version,
685 			     unsigned int mfg_id,
686 			     unsigned int part_id,
687 			     unsigned int class_id,
688 			     int index_in_link
689 			    )
690 {
691 	int i;
692 
693 	for (i = 0; i < link->num_adr; i++) {
694 		unsigned int sdw1_version, mfg1_id, part1_id, class1_id;
695 		u64 adr;
696 
697 		/* skip itself */
698 		if (i == index_in_link)
699 			continue;
700 
701 		adr = link->adr_d[i].adr;
702 
703 		sdw1_version = SDW_VERSION(adr);
704 		mfg1_id = SDW_MFG_ID(adr);
705 		part1_id = SDW_PART_ID(adr);
706 		class1_id = SDW_CLASS_ID(adr);
707 
708 		if (sdw_version == sdw1_version &&
709 		    mfg_id == mfg1_id &&
710 		    part_id == part1_id &&
711 		    class_id == class1_id)
712 			return false;
713 	}
714 
715 	return true;
716 }
717 
718 static int create_codec_dai_name(struct device *dev,
719 				 const struct snd_soc_acpi_link_adr *link,
720 				 struct snd_soc_dai_link_component *codec,
721 				 int offset,
722 				 struct snd_soc_codec_conf *codec_conf,
723 				 int codec_count,
724 				 int *codec_conf_index)
725 {
726 	int i;
727 
728 	/* sanity check */
729 	if (*codec_conf_index + link->num_adr > codec_count) {
730 		dev_err(dev, "codec_conf: out-of-bounds access requested\n");
731 		return -EINVAL;
732 	}
733 
734 	for (i = 0; i < link->num_adr; i++) {
735 		unsigned int sdw_version, unique_id, mfg_id;
736 		unsigned int link_id, part_id, class_id;
737 		int codec_index, comp_index;
738 		char *codec_str;
739 		u64 adr;
740 
741 		adr = link->adr_d[i].adr;
742 
743 		sdw_version = SDW_VERSION(adr);
744 		link_id = SDW_DISCO_LINK_ID(adr);
745 		unique_id = SDW_UNIQUE_ID(adr);
746 		mfg_id = SDW_MFG_ID(adr);
747 		part_id = SDW_PART_ID(adr);
748 		class_id = SDW_CLASS_ID(adr);
749 
750 		comp_index = i + offset;
751 		if (is_unique_device(link, sdw_version, mfg_id, part_id,
752 				     class_id, i)) {
753 			codec_str = "sdw:%01x:%04x:%04x:%02x";
754 			codec[comp_index].name =
755 				devm_kasprintf(dev, GFP_KERNEL, codec_str,
756 					       link_id, mfg_id, part_id,
757 					       class_id);
758 		} else {
759 			codec_str = "sdw:%01x:%04x:%04x:%02x:%01x";
760 			codec[comp_index].name =
761 				devm_kasprintf(dev, GFP_KERNEL, codec_str,
762 					       link_id, mfg_id, part_id,
763 					       class_id, unique_id);
764 		}
765 
766 		if (!codec[comp_index].name)
767 			return -ENOMEM;
768 
769 		codec_index = find_codec_info_part(adr);
770 		if (codec_index < 0)
771 			return codec_index;
772 
773 		codec[comp_index].dai_name =
774 			codec_info_list[codec_index].dai_name;
775 
776 		codec_conf[*codec_conf_index].dlc = codec[comp_index];
777 		codec_conf[*codec_conf_index].name_prefix = link->adr_d[i].name_prefix;
778 
779 		++*codec_conf_index;
780 	}
781 
782 	return 0;
783 }
784 
785 static int set_codec_init_func(struct snd_soc_card *card,
786 			       const struct snd_soc_acpi_link_adr *link,
787 			       struct snd_soc_dai_link *dai_links,
788 			       bool playback, int group_id)
789 {
790 	int i;
791 
792 	do {
793 		/*
794 		 * Initialize the codec. If codec is part of an aggregated
795 		 * group (group_id>0), initialize all codecs belonging to
796 		 * same group.
797 		 */
798 		for (i = 0; i < link->num_adr; i++) {
799 			int codec_index;
800 
801 			codec_index = find_codec_info_part(link->adr_d[i].adr);
802 
803 			if (codec_index < 0)
804 				return codec_index;
805 			/* The group_id is > 0 iff the codec is aggregated */
806 			if (link->adr_d[i].endpoints->group_id != group_id)
807 				continue;
808 			if (codec_info_list[codec_index].init)
809 				codec_info_list[codec_index].init(card,
810 						link,
811 						dai_links,
812 						&codec_info_list[codec_index],
813 						playback);
814 		}
815 		link++;
816 	} while (link->mask && group_id);
817 
818 	return 0;
819 }
820 
821 /*
822  * check endpoint status in slaves and gather link ID for all slaves in
823  * the same group to generate different CPU DAI. Now only support
824  * one sdw link with all slaves set with only single group id.
825  *
826  * one slave on one sdw link with aggregated = 0
827  * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI
828  *
829  * two or more slaves on one sdw link with aggregated = 0
830  * one sdw BE DAI  <---> one-cpu DAI <---> multi-codec DAIs
831  *
832  * multiple links with multiple slaves with aggregated = 1
833  * one sdw BE DAI  <---> 1 .. N CPU DAIs <----> 1 .. N codec DAIs
834  */
835 static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
836 			  struct device *dev, int *cpu_dai_id, int *cpu_dai_num,
837 			  int *codec_num, unsigned int *group_id,
838 			  bool *group_generated)
839 {
840 	const struct snd_soc_acpi_adr_device *adr_d;
841 	const struct snd_soc_acpi_link_adr *adr_next;
842 	bool no_aggregation;
843 	int index = 0;
844 
845 	no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION;
846 	*codec_num = adr_link->num_adr;
847 	adr_d = adr_link->adr_d;
848 
849 	/* make sure the link mask has a single bit set */
850 	if (!is_power_of_2(adr_link->mask))
851 		return -EINVAL;
852 
853 	cpu_dai_id[index++] = ffs(adr_link->mask) - 1;
854 	if (!adr_d->endpoints->aggregated || no_aggregation) {
855 		*cpu_dai_num = 1;
856 		*group_id = 0;
857 		return 0;
858 	}
859 
860 	*group_id = adr_d->endpoints->group_id;
861 
862 	/* gather other link ID of slaves in the same group */
863 	for (adr_next = adr_link + 1; adr_next && adr_next->num_adr;
864 		adr_next++) {
865 		const struct snd_soc_acpi_endpoint *endpoint;
866 
867 		endpoint = adr_next->adr_d->endpoints;
868 		if (!endpoint->aggregated ||
869 		    endpoint->group_id != *group_id)
870 			continue;
871 
872 		/* make sure the link mask has a single bit set */
873 		if (!is_power_of_2(adr_next->mask))
874 			return -EINVAL;
875 
876 		if (index >= SDW_MAX_CPU_DAIS) {
877 			dev_err(dev, " cpu_dai_id array overflows");
878 			return -EINVAL;
879 		}
880 
881 		cpu_dai_id[index++] = ffs(adr_next->mask) - 1;
882 		*codec_num += adr_next->num_adr;
883 	}
884 
885 	/*
886 	 * indicate CPU DAIs for this group have been generated
887 	 * to avoid generating CPU DAIs for this group again.
888 	 */
889 	group_generated[*group_id] = true;
890 	*cpu_dai_num = index;
891 
892 	return 0;
893 }
894 
895 static int create_sdw_dailink(struct snd_soc_card *card,
896 			      struct device *dev, int *link_index,
897 			      struct snd_soc_dai_link *dai_links,
898 			      int sdw_be_num, int sdw_cpu_dai_num,
899 			      struct snd_soc_dai_link_component *cpus,
900 			      const struct snd_soc_acpi_link_adr *link,
901 			      int *cpu_id, bool *group_generated,
902 			      struct snd_soc_codec_conf *codec_conf,
903 			      int codec_count, int *link_id,
904 			      int *codec_conf_index,
905 			      bool *ignore_pch_dmic)
906 {
907 	const struct snd_soc_acpi_link_adr *link_next;
908 	struct snd_soc_dai_link_component *codecs;
909 	int cpu_dai_id[SDW_MAX_CPU_DAIS];
910 	int cpu_dai_num, cpu_dai_index;
911 	unsigned int group_id;
912 	int codec_idx = 0;
913 	int i = 0, j = 0;
914 	int codec_index;
915 	int codec_num;
916 	int stream;
917 	int ret;
918 	int k;
919 
920 	ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num,
921 			     &group_id, group_generated);
922 	if (ret)
923 		return ret;
924 
925 	codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL);
926 	if (!codecs)
927 		return -ENOMEM;
928 
929 	/* generate codec name on different links in the same group */
930 	for (link_next = link; link_next && link_next->num_adr &&
931 	     i < cpu_dai_num; link_next++) {
932 		const struct snd_soc_acpi_endpoint *endpoints;
933 
934 		endpoints = link_next->adr_d->endpoints;
935 		if (group_id && (!endpoints->aggregated ||
936 				 endpoints->group_id != group_id))
937 			continue;
938 
939 		/* skip the link excluded by this processed group */
940 		if (cpu_dai_id[i] != ffs(link_next->mask) - 1)
941 			continue;
942 
943 		ret = create_codec_dai_name(dev, link_next, codecs, codec_idx,
944 					    codec_conf, codec_count, codec_conf_index);
945 		if (ret < 0)
946 			return ret;
947 
948 		/* check next link to create codec dai in the processed group */
949 		i++;
950 		codec_idx += link_next->num_adr;
951 	}
952 
953 	/* find codec info to create BE DAI */
954 	codec_index = find_codec_info_part(link->adr_d[0].adr);
955 	if (codec_index < 0)
956 		return codec_index;
957 
958 	if (codec_info_list[codec_index].ignore_pch_dmic)
959 		*ignore_pch_dmic = true;
960 
961 	/* Shift the first amplifier's *link_id to SDW_AMP_DAI_ID */
962 	if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_AMP &&
963 	    *link_id < SDW_AMP_DAI_ID)
964 		*link_id = SDW_AMP_DAI_ID;
965 
966 	/*
967 	 * DAI ID is fixed at SDW_DMIC_DAI_ID for MICs to
968 	 * keep sdw DMIC and HDMI setting static in UCM
969 	 */
970 	if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_MIC &&
971 	    *link_id < SDW_DMIC_DAI_ID)
972 		*link_id = SDW_DMIC_DAI_ID;
973 
974 	cpu_dai_index = *cpu_id;
975 	for_each_pcm_streams(stream) {
976 		char *name, *cpu_name;
977 		int playback, capture;
978 		static const char * const sdw_stream_name[] = {
979 			"SDW%d-Playback",
980 			"SDW%d-Capture",
981 		};
982 
983 		if (!codec_info_list[codec_index].direction[stream])
984 			continue;
985 
986 		/* create stream name according to first link id */
987 		name = devm_kasprintf(dev, GFP_KERNEL,
988 				      sdw_stream_name[stream], cpu_dai_id[0]);
989 		if (!name)
990 			return -ENOMEM;
991 
992 		/*
993 		 * generate CPU DAI name base on the sdw link ID and
994 		 * PIN ID with offset of 2 according to sdw dai driver.
995 		 */
996 		for (k = 0; k < cpu_dai_num; k++) {
997 			cpu_name = devm_kasprintf(dev, GFP_KERNEL,
998 						  "SDW%d Pin%d", cpu_dai_id[k],
999 						  j + SDW_INTEL_BIDIR_PDI_BASE);
1000 			if (!cpu_name)
1001 				return -ENOMEM;
1002 
1003 			if (cpu_dai_index >= sdw_cpu_dai_num) {
1004 				dev_err(dev, "invalid cpu dai index %d",
1005 					cpu_dai_index);
1006 				return -EINVAL;
1007 			}
1008 
1009 			cpus[cpu_dai_index++].dai_name = cpu_name;
1010 		}
1011 
1012 		/*
1013 		 * We create sdw dai links at first stage, so link index should
1014 		 * not be larger than sdw_be_num
1015 		 */
1016 		if (*link_index >= sdw_be_num) {
1017 			dev_err(dev, "invalid dai link index %d", *link_index);
1018 			return -EINVAL;
1019 		}
1020 
1021 		if (*cpu_id >= sdw_cpu_dai_num) {
1022 			dev_err(dev, " invalid cpu dai index %d", *cpu_id);
1023 			return -EINVAL;
1024 		}
1025 
1026 		playback = (stream == SNDRV_PCM_STREAM_PLAYBACK);
1027 		capture = (stream == SNDRV_PCM_STREAM_CAPTURE);
1028 		init_dai_link(dev, dai_links + *link_index, (*link_id)++, name,
1029 			      playback, capture,
1030 			      cpus + *cpu_id, cpu_dai_num,
1031 			      codecs, codec_num,
1032 			      NULL, &sdw_ops);
1033 
1034 		/*
1035 		 * SoundWire DAILINKs use 'stream' functions and Bank Switch operations
1036 		 * based on wait_for_completion(), tag them as 'nonatomic'.
1037 		 */
1038 		dai_links[*link_index].nonatomic = true;
1039 
1040 		ret = set_codec_init_func(card, link, dai_links + (*link_index)++,
1041 					  playback, group_id);
1042 		if (ret < 0) {
1043 			dev_err(dev, "failed to init codec %d", codec_index);
1044 			return ret;
1045 		}
1046 
1047 		*cpu_id += cpu_dai_num;
1048 		j++;
1049 	}
1050 
1051 	return 0;
1052 }
1053 
1054 #define IDISP_CODEC_MASK	0x4
1055 
1056 static int sof_card_codec_conf_alloc(struct device *dev,
1057 				     struct snd_soc_acpi_mach_params *mach_params,
1058 				     struct snd_soc_codec_conf **codec_conf,
1059 				     int *codec_conf_count)
1060 {
1061 	const struct snd_soc_acpi_link_adr *adr_link;
1062 	struct snd_soc_codec_conf *c_conf;
1063 	int num_codecs = 0;
1064 	int i;
1065 
1066 	adr_link = mach_params->links;
1067 	if (!adr_link)
1068 		return -EINVAL;
1069 
1070 	/* generate DAI links by each sdw link */
1071 	for (; adr_link->num_adr; adr_link++) {
1072 		for (i = 0; i < adr_link->num_adr; i++) {
1073 			if (!adr_link->adr_d[i].name_prefix) {
1074 				dev_err(dev, "codec 0x%llx does not have a name prefix\n",
1075 					adr_link->adr_d[i].adr);
1076 				return -EINVAL;
1077 			}
1078 		}
1079 		num_codecs += adr_link->num_adr;
1080 	}
1081 
1082 	c_conf = devm_kzalloc(dev, num_codecs * sizeof(*c_conf), GFP_KERNEL);
1083 	if (!c_conf)
1084 		return -ENOMEM;
1085 
1086 	*codec_conf = c_conf;
1087 	*codec_conf_count = num_codecs;
1088 
1089 	return 0;
1090 }
1091 
1092 static int sof_card_dai_links_create(struct device *dev,
1093 				     struct snd_soc_acpi_mach *mach,
1094 				     struct snd_soc_card *card)
1095 {
1096 	int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num;
1097 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
1098 	struct snd_soc_dai_link_component *idisp_components;
1099 	struct snd_soc_dai_link_component *ssp_components;
1100 	struct snd_soc_acpi_mach_params *mach_params;
1101 	const struct snd_soc_acpi_link_adr *adr_link;
1102 	struct snd_soc_dai_link_component *cpus;
1103 	struct snd_soc_codec_conf *codec_conf;
1104 	bool ignore_pch_dmic = false;
1105 	int codec_conf_count;
1106 	int codec_conf_index = 0;
1107 	bool group_generated[SDW_MAX_GROUPS];
1108 	int ssp_codec_index, ssp_mask;
1109 	struct snd_soc_dai_link *links;
1110 	int num_links, link_index = 0;
1111 	char *name, *cpu_name;
1112 	int total_cpu_dai_num;
1113 	int sdw_cpu_dai_num;
1114 	int i, j, be_id = 0;
1115 	int cpu_id = 0;
1116 	int comp_num;
1117 	int ret;
1118 
1119 	mach_params = &mach->mach_params;
1120 
1121 	/* allocate codec conf, will be populated when dailinks are created */
1122 	ret = sof_card_codec_conf_alloc(dev, mach_params, &codec_conf, &codec_conf_count);
1123 	if (ret < 0)
1124 		return ret;
1125 
1126 	/* reset amp_num to ensure amp_num++ starts from 0 in each probe */
1127 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1128 		codec_info_list[i].amp_num = 0;
1129 
1130 	if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
1131 		hdmi_num = SOF_TGL_HDMI_COUNT;
1132 	else
1133 		hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
1134 
1135 	ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk);
1136 	/*
1137 	 * on generic tgl platform, I2S or sdw mode is supported
1138 	 * based on board rework. A ACPI device is registered in
1139 	 * system only when I2S mode is supported, not sdw mode.
1140 	 * Here check ACPI ID to confirm I2S is supported.
1141 	 */
1142 	ssp_codec_index = find_codec_info_acpi(mach->id);
1143 	ssp_num = ssp_codec_index >= 0 ? hweight_long(ssp_mask) : 0;
1144 	comp_num = hdmi_num + ssp_num;
1145 
1146 	ret = get_sdw_dailink_info(dev, mach_params->links,
1147 				   &sdw_be_num, &sdw_cpu_dai_num);
1148 	if (ret < 0) {
1149 		dev_err(dev, "failed to get sdw link info %d", ret);
1150 		return ret;
1151 	}
1152 
1153 	if (mach_params->codec_mask & IDISP_CODEC_MASK)
1154 		ctx->idisp_codec = true;
1155 
1156 	/* enable dmic01 & dmic16k */
1157 	dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) ? 2 : 0;
1158 	comp_num += dmic_num;
1159 
1160 	if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
1161 		comp_num++;
1162 
1163 	dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num,
1164 		dmic_num, ctx->idisp_codec ? hdmi_num : 0);
1165 
1166 	/* allocate BE dailinks */
1167 	num_links = comp_num + sdw_be_num;
1168 	links = devm_kcalloc(dev, num_links, sizeof(*links), GFP_KERNEL);
1169 
1170 	/* allocated CPU DAIs */
1171 	total_cpu_dai_num = comp_num + sdw_cpu_dai_num;
1172 	cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus),
1173 			    GFP_KERNEL);
1174 
1175 	if (!links || !cpus)
1176 		return -ENOMEM;
1177 
1178 	/* SDW */
1179 	if (!sdw_be_num)
1180 		goto SSP;
1181 
1182 	adr_link = mach_params->links;
1183 	if (!adr_link)
1184 		return -EINVAL;
1185 
1186 	/*
1187 	 * SoundWire Slaves aggregated in the same group may be
1188 	 * located on different hardware links. Clear array to indicate
1189 	 * CPU DAIs for this group have not been generated.
1190 	 */
1191 	for (i = 0; i < SDW_MAX_GROUPS; i++)
1192 		group_generated[i] = false;
1193 
1194 	/* generate DAI links by each sdw link */
1195 	for (; adr_link->num_adr; adr_link++) {
1196 		const struct snd_soc_acpi_endpoint *endpoint;
1197 
1198 		endpoint = adr_link->adr_d->endpoints;
1199 		if (endpoint->aggregated && !endpoint->group_id) {
1200 			dev_err(dev, "invalid group id on link %x",
1201 				adr_link->mask);
1202 			continue;
1203 		}
1204 
1205 		/* this group has been generated */
1206 		if (endpoint->aggregated &&
1207 		    group_generated[endpoint->group_id])
1208 			continue;
1209 
1210 		ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num,
1211 					 sdw_cpu_dai_num, cpus, adr_link,
1212 					 &cpu_id, group_generated,
1213 					 codec_conf, codec_conf_count,
1214 					 &be_id, &codec_conf_index,
1215 					 &ignore_pch_dmic);
1216 		if (ret < 0) {
1217 			dev_err(dev, "failed to create dai link %d", link_index);
1218 			return ret;
1219 		}
1220 	}
1221 
1222 SSP:
1223 	/* SSP */
1224 	if (!ssp_num)
1225 		goto DMIC;
1226 
1227 	for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) {
1228 		struct sof_sdw_codec_info *info;
1229 		int playback, capture;
1230 		char *codec_name;
1231 
1232 		if (!(ssp_mask & 0x1))
1233 			continue;
1234 
1235 		name = devm_kasprintf(dev, GFP_KERNEL,
1236 				      "SSP%d-Codec", i);
1237 		if (!name)
1238 			return -ENOMEM;
1239 
1240 		cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i);
1241 		if (!cpu_name)
1242 			return -ENOMEM;
1243 
1244 		ssp_components = devm_kzalloc(dev, sizeof(*ssp_components),
1245 					      GFP_KERNEL);
1246 		if (!ssp_components)
1247 			return -ENOMEM;
1248 
1249 		info = &codec_info_list[ssp_codec_index];
1250 		codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d",
1251 					    info->acpi_id, j++);
1252 		if (!codec_name)
1253 			return -ENOMEM;
1254 
1255 		ssp_components->name = codec_name;
1256 		ssp_components->dai_name = info->dai_name;
1257 		cpus[cpu_id].dai_name = cpu_name;
1258 
1259 		playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK];
1260 		capture = info->direction[SNDRV_PCM_STREAM_CAPTURE];
1261 		init_dai_link(dev, links + link_index, be_id, name,
1262 			      playback, capture,
1263 			      cpus + cpu_id, 1,
1264 			      ssp_components, 1,
1265 			      NULL, info->ops);
1266 
1267 		ret = info->init(card, NULL, links + link_index, info, 0);
1268 		if (ret < 0)
1269 			return ret;
1270 
1271 		INC_ID(be_id, cpu_id, link_index);
1272 	}
1273 
1274 DMIC:
1275 	/* dmic */
1276 	if (dmic_num > 0) {
1277 		if (ignore_pch_dmic) {
1278 			dev_warn(dev, "Ignoring PCH DMIC\n");
1279 			goto HDMI;
1280 		}
1281 		cpus[cpu_id].dai_name = "DMIC01 Pin";
1282 		init_dai_link(dev, links + link_index, be_id, "dmic01",
1283 			      0, 1, // DMIC only supports capture
1284 			      cpus + cpu_id, 1,
1285 			      dmic_component, 1,
1286 			      sof_sdw_dmic_init, NULL);
1287 		INC_ID(be_id, cpu_id, link_index);
1288 
1289 		cpus[cpu_id].dai_name = "DMIC16k Pin";
1290 		init_dai_link(dev, links + link_index, be_id, "dmic16k",
1291 			      0, 1, // DMIC only supports capture
1292 			      cpus + cpu_id, 1,
1293 			      dmic_component, 1,
1294 			      /* don't call sof_sdw_dmic_init() twice */
1295 			      NULL, NULL);
1296 		INC_ID(be_id, cpu_id, link_index);
1297 	}
1298 
1299 HDMI:
1300 	/* HDMI */
1301 	if (hdmi_num > 0) {
1302 		idisp_components = devm_kcalloc(dev, hdmi_num,
1303 						sizeof(*idisp_components),
1304 						GFP_KERNEL);
1305 		if (!idisp_components)
1306 			return -ENOMEM;
1307 	}
1308 
1309 	for (i = 0; i < hdmi_num; i++) {
1310 		name = devm_kasprintf(dev, GFP_KERNEL,
1311 				      "iDisp%d", i + 1);
1312 		if (!name)
1313 			return -ENOMEM;
1314 
1315 		if (ctx->idisp_codec) {
1316 			idisp_components[i].name = "ehdaudio0D2";
1317 			idisp_components[i].dai_name = devm_kasprintf(dev,
1318 								      GFP_KERNEL,
1319 								      "intel-hdmi-hifi%d",
1320 								      i + 1);
1321 			if (!idisp_components[i].dai_name)
1322 				return -ENOMEM;
1323 		} else {
1324 			idisp_components[i].name = "snd-soc-dummy";
1325 			idisp_components[i].dai_name = "snd-soc-dummy-dai";
1326 		}
1327 
1328 		cpu_name = devm_kasprintf(dev, GFP_KERNEL,
1329 					  "iDisp%d Pin", i + 1);
1330 		if (!cpu_name)
1331 			return -ENOMEM;
1332 
1333 		cpus[cpu_id].dai_name = cpu_name;
1334 		init_dai_link(dev, links + link_index, be_id, name,
1335 			      1, 0, // HDMI only supports playback
1336 			      cpus + cpu_id, 1,
1337 			      idisp_components + i, 1,
1338 			      sof_sdw_hdmi_init, NULL);
1339 		INC_ID(be_id, cpu_id, link_index);
1340 	}
1341 
1342 	if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
1343 		int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
1344 				SOF_BT_OFFLOAD_SSP_SHIFT;
1345 
1346 		name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
1347 		if (!name)
1348 			return -ENOMEM;
1349 
1350 		ssp_components = devm_kzalloc(dev, sizeof(*ssp_components),
1351 						GFP_KERNEL);
1352 		if (!ssp_components)
1353 			return -ENOMEM;
1354 
1355 		ssp_components->name = "snd-soc-dummy";
1356 		ssp_components->dai_name = "snd-soc-dummy-dai";
1357 
1358 		cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port);
1359 		if (!cpu_name)
1360 			return -ENOMEM;
1361 
1362 		cpus[cpu_id].dai_name = cpu_name;
1363 		init_dai_link(dev, links + link_index, be_id, name, 1, 1,
1364 				cpus + cpu_id, 1, ssp_components, 1, NULL, NULL);
1365 	}
1366 
1367 	card->dai_link = links;
1368 	card->num_links = num_links;
1369 
1370 	card->codec_conf = codec_conf;
1371 	card->num_configs = codec_conf_count;
1372 
1373 	return 0;
1374 }
1375 
1376 static int sof_sdw_card_late_probe(struct snd_soc_card *card)
1377 {
1378 	int i, ret;
1379 
1380 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
1381 		if (!codec_info_list[i].late_probe)
1382 			continue;
1383 
1384 		ret = codec_info_list[i].codec_card_late_probe(card);
1385 		if (ret < 0)
1386 			return ret;
1387 	}
1388 
1389 	return sof_sdw_hdmi_card_late_probe(card);
1390 }
1391 
1392 /* SoC card */
1393 static const char sdw_card_long_name[] = "Intel Soundwire SOF";
1394 
1395 static struct snd_soc_card card_sof_sdw = {
1396 	.name = "soundwire",
1397 	.owner = THIS_MODULE,
1398 	.late_probe = sof_sdw_card_late_probe,
1399 };
1400 
1401 static int mc_probe(struct platform_device *pdev)
1402 {
1403 	struct snd_soc_card *card = &card_sof_sdw;
1404 	struct snd_soc_acpi_mach *mach;
1405 	struct mc_private *ctx;
1406 	int amp_num = 0, i;
1407 	int ret;
1408 
1409 	dev_dbg(&pdev->dev, "Entry %s\n", __func__);
1410 
1411 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1412 	if (!ctx)
1413 		return -ENOMEM;
1414 
1415 	dmi_check_system(sof_sdw_quirk_table);
1416 
1417 	if (quirk_override != -1) {
1418 		dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
1419 			 sof_sdw_quirk, quirk_override);
1420 		sof_sdw_quirk = quirk_override;
1421 	}
1422 	log_quirks(&pdev->dev);
1423 
1424 	INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
1425 
1426 	card->dev = &pdev->dev;
1427 	snd_soc_card_set_drvdata(card, ctx);
1428 
1429 	mach = pdev->dev.platform_data;
1430 	ret = sof_card_dai_links_create(&pdev->dev, mach,
1431 					card);
1432 	if (ret < 0)
1433 		return ret;
1434 
1435 	/*
1436 	 * the default amp_num is zero for each codec and
1437 	 * amp_num will only be increased for active amp
1438 	 * codecs on used platform
1439 	 */
1440 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1441 		amp_num += codec_info_list[i].amp_num;
1442 
1443 	card->components = devm_kasprintf(card->dev, GFP_KERNEL,
1444 					  "cfg-spk:%d cfg-amp:%d",
1445 					  (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
1446 					  ? 4 : 2, amp_num);
1447 	if (!card->components)
1448 		return -ENOMEM;
1449 
1450 	if (mach->mach_params.dmic_num) {
1451 		card->components = devm_kasprintf(card->dev, GFP_KERNEL,
1452 						  "%s mic:dmic cfg-mics:%d",
1453 						  card->components,
1454 						  mach->mach_params.dmic_num);
1455 		if (!card->components)
1456 			return -ENOMEM;
1457 	}
1458 
1459 	card->long_name = sdw_card_long_name;
1460 
1461 	/* Register the card */
1462 	ret = devm_snd_soc_register_card(&pdev->dev, card);
1463 	if (ret) {
1464 		dev_err(card->dev, "snd_soc_register_card failed %d\n", ret);
1465 		return ret;
1466 	}
1467 
1468 	platform_set_drvdata(pdev, card);
1469 
1470 	return ret;
1471 }
1472 
1473 static int mc_remove(struct platform_device *pdev)
1474 {
1475 	struct snd_soc_card *card = platform_get_drvdata(pdev);
1476 	struct snd_soc_dai_link *link;
1477 	int ret;
1478 	int i, j;
1479 
1480 	for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
1481 		if (!codec_info_list[i].exit)
1482 			continue;
1483 		/*
1484 		 * We don't need to call .exit function if there is no matched
1485 		 * dai link found.
1486 		 */
1487 		for_each_card_prelinks(card, j, link) {
1488 			if (!strcmp(link->codecs[0].dai_name,
1489 				    codec_info_list[i].dai_name)) {
1490 				ret = codec_info_list[i].exit(card, link);
1491 				if (ret)
1492 					dev_warn(&pdev->dev,
1493 						 "codec exit failed %d\n",
1494 						 ret);
1495 				break;
1496 			}
1497 		}
1498 	}
1499 
1500 	return 0;
1501 }
1502 
1503 static struct platform_driver sof_sdw_driver = {
1504 	.driver = {
1505 		.name = "sof_sdw",
1506 		.pm = &snd_soc_pm_ops,
1507 	},
1508 	.probe = mc_probe,
1509 	.remove = mc_remove,
1510 };
1511 
1512 module_platform_driver(sof_sdw_driver);
1513 
1514 MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver");
1515 MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>");
1516 MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>");
1517 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
1518 MODULE_LICENSE("GPL v2");
1519 MODULE_ALIAS("platform:sof_sdw");
1520 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
1521 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
1522