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