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