ASoC: Intel: sof_cs42l42: use function devm_kcalloc() instead of devm_kzalloc()
[platform/kernel/linux-starfive.git] / sound / soc / intel / boards / sof_cs42l42.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2021 Intel Corporation.
3
4 /*
5  * Intel SOF Machine Driver with Cirrus Logic CS42L42 Codec
6  * and speaker codec MAX98357A
7  */
8 #include <linux/i2c.h>
9 #include <linux/input.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/regulator/consumer.h>
13 #include <linux/dmi.h>
14 #include <sound/core.h>
15 #include <sound/jack.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 #include <sound/sof.h>
20 #include <sound/soc-acpi.h>
21 #include <dt-bindings/sound/cs42l42.h>
22 #include "../../codecs/hdac_hdmi.h"
23 #include "../common/soc-intel-quirks.h"
24 #include "hda_dsp_common.h"
25 #include "sof_maxim_common.h"
26
27 #define NAME_SIZE 32
28
29 #define SOF_CS42L42_SSP_CODEC(quirk)            ((quirk) & GENMASK(2, 0))
30 #define SOF_CS42L42_SSP_CODEC_MASK              (GENMASK(2, 0))
31 #define SOF_SPEAKER_AMP_PRESENT                 BIT(3)
32 #define SOF_CS42L42_SSP_AMP_SHIFT               4
33 #define SOF_CS42L42_SSP_AMP_MASK                (GENMASK(6, 4))
34 #define SOF_CS42L42_SSP_AMP(quirk)      \
35         (((quirk) << SOF_CS42L42_SSP_AMP_SHIFT) & SOF_CS42L42_SSP_AMP_MASK)
36 #define SOF_CS42L42_NUM_HDMIDEV_SHIFT           7
37 #define SOF_CS42L42_NUM_HDMIDEV_MASK            (GENMASK(9, 7))
38 #define SOF_CS42L42_NUM_HDMIDEV(quirk)  \
39         (((quirk) << SOF_CS42L42_NUM_HDMIDEV_SHIFT) & SOF_CS42L42_NUM_HDMIDEV_MASK)
40 #define SOF_CS42L42_DAILINK_SHIFT               10
41 #define SOF_CS42L42_DAILINK_MASK                (GENMASK(24, 10))
42 #define SOF_CS42L42_DAILINK(link1, link2, link3, link4, link5) \
43         ((((link1) | ((link2) << 3) | ((link3) << 6) | ((link4) << 9) | ((link5) << 12)) << SOF_CS42L42_DAILINK_SHIFT) & SOF_CS42L42_DAILINK_MASK)
44 #define SOF_BT_OFFLOAD_PRESENT                  BIT(25)
45 #define SOF_CS42L42_SSP_BT_SHIFT                26
46 #define SOF_CS42L42_SSP_BT_MASK                 (GENMASK(28, 26))
47 #define SOF_CS42L42_SSP_BT(quirk)       \
48         (((quirk) << SOF_CS42L42_SSP_BT_SHIFT) & SOF_CS42L42_SSP_BT_MASK)
49 #define SOF_MAX98357A_SPEAKER_AMP_PRESENT       BIT(29)
50 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT       BIT(30)
51
52 enum {
53         LINK_NONE = 0,
54         LINK_HP = 1,
55         LINK_SPK = 2,
56         LINK_DMIC = 3,
57         LINK_HDMI = 4,
58         LINK_BT = 5,
59 };
60
61 static struct snd_soc_jack_pin jack_pins[] = {
62         {
63                 .pin    = "Headphone Jack",
64                 .mask   = SND_JACK_HEADPHONE,
65         },
66         {
67                 .pin    = "Headset Mic",
68                 .mask   = SND_JACK_MICROPHONE,
69         },
70 };
71
72 /* Default: SSP2 */
73 static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2);
74
75 struct sof_hdmi_pcm {
76         struct list_head head;
77         struct snd_soc_dai *codec_dai;
78         struct snd_soc_jack hdmi_jack;
79         int device;
80 };
81
82 struct sof_card_private {
83         struct snd_soc_jack headset_jack;
84         struct list_head hdmi_pcm_list;
85         bool common_hdmi_codec_drv;
86 };
87
88 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
89 {
90         struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
91         struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
92         struct sof_hdmi_pcm *pcm;
93
94         pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
95         if (!pcm)
96                 return -ENOMEM;
97
98         /* dai_link id is 1:1 mapped to the PCM device */
99         pcm->device = rtd->dai_link->id;
100         pcm->codec_dai = dai;
101
102         list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
103
104         return 0;
105 }
106
107 static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd)
108 {
109         struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
110         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
111         struct snd_soc_jack *jack = &ctx->headset_jack;
112         int ret;
113
114         /*
115          * Headset buttons map to the google Reference headset.
116          * These can be configured by userspace.
117          */
118         ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
119                                          SND_JACK_HEADSET | SND_JACK_BTN_0 |
120                                          SND_JACK_BTN_1 | SND_JACK_BTN_2 |
121                                          SND_JACK_BTN_3,
122                                          jack,
123                                          jack_pins,
124                                          ARRAY_SIZE(jack_pins));
125         if (ret) {
126                 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
127                 return ret;
128         }
129
130         snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
131         snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
132         snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
133         snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
134
135         ret = snd_soc_component_set_jack(component, jack, NULL);
136         if (ret) {
137                 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
138                 return ret;
139         }
140
141         return ret;
142 };
143
144 static void sof_cs42l42_exit(struct snd_soc_pcm_runtime *rtd)
145 {
146         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
147
148         snd_soc_component_set_jack(component, NULL, NULL);
149 }
150
151 static int sof_cs42l42_hw_params(struct snd_pcm_substream *substream,
152                                  struct snd_pcm_hw_params *params)
153 {
154         struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
155         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
156         int clk_freq, ret;
157
158         clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */
159
160         if (clk_freq <= 0) {
161                 dev_err(rtd->dev, "get bclk freq failed: %d\n", clk_freq);
162                 return -EINVAL;
163         }
164
165         /* Configure sysclk for codec */
166         ret = snd_soc_dai_set_sysclk(codec_dai, 0,
167                                      clk_freq, SND_SOC_CLOCK_IN);
168         if (ret < 0)
169                 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
170
171         return ret;
172 }
173
174 static const struct snd_soc_ops sof_cs42l42_ops = {
175         .hw_params = sof_cs42l42_hw_params,
176 };
177
178 static struct snd_soc_dai_link_component platform_component[] = {
179         {
180                 /* name might be overridden during probe */
181                 .name = "0000:00:1f.3"
182         }
183 };
184
185 static int sof_card_late_probe(struct snd_soc_card *card)
186 {
187         struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
188         struct snd_soc_component *component = NULL;
189         char jack_name[NAME_SIZE];
190         struct sof_hdmi_pcm *pcm;
191         int err;
192
193         if (list_empty(&ctx->hdmi_pcm_list))
194                 return -EINVAL;
195
196         if (ctx->common_hdmi_codec_drv) {
197                 pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
198                                        head);
199                 component = pcm->codec_dai->component;
200                 return hda_dsp_hdmi_build_controls(card, component);
201         }
202
203         list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
204                 component = pcm->codec_dai->component;
205                 snprintf(jack_name, sizeof(jack_name),
206                          "HDMI/DP, pcm=%d Jack", pcm->device);
207                 err = snd_soc_card_jack_new(card, jack_name,
208                                             SND_JACK_AVOUT, &pcm->hdmi_jack);
209
210                 if (err)
211                         return err;
212
213                 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
214                                           &pcm->hdmi_jack);
215                 if (err < 0)
216                         return err;
217         }
218
219         return hdac_hdmi_jack_port_init(component, &card->dapm);
220 }
221
222 static const struct snd_kcontrol_new sof_controls[] = {
223         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
224         SOC_DAPM_PIN_SWITCH("Headset Mic"),
225 };
226
227 static const struct snd_soc_dapm_widget sof_widgets[] = {
228         SND_SOC_DAPM_HP("Headphone Jack", NULL),
229         SND_SOC_DAPM_MIC("Headset Mic", NULL),
230 };
231
232 static const struct snd_soc_dapm_widget dmic_widgets[] = {
233         SND_SOC_DAPM_MIC("SoC DMIC", NULL),
234 };
235
236 static const struct snd_soc_dapm_route sof_map[] = {
237         /* HP jack connectors - unknown if we have jack detection */
238         {"Headphone Jack", NULL, "HP"},
239
240         /* other jacks */
241         {"HS", NULL, "Headset Mic"},
242 };
243
244 static const struct snd_soc_dapm_route dmic_map[] = {
245         /* digital mics */
246         {"DMic", NULL, "SoC DMIC"},
247 };
248
249 static int dmic_init(struct snd_soc_pcm_runtime *rtd)
250 {
251         struct snd_soc_card *card = rtd->card;
252         int ret;
253
254         ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
255                                         ARRAY_SIZE(dmic_widgets));
256         if (ret) {
257                 dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
258                 /* Don't need to add routes if widget addition failed */
259                 return ret;
260         }
261
262         ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
263                                       ARRAY_SIZE(dmic_map));
264
265         if (ret)
266                 dev_err(card->dev, "DMic map addition failed: %d\n", ret);
267
268         return ret;
269 }
270
271 /* sof audio machine driver for cs42l42 codec */
272 static struct snd_soc_card sof_audio_card_cs42l42 = {
273         .name = "cs42l42", /* the sof- prefix is added by the core */
274         .owner = THIS_MODULE,
275         .controls = sof_controls,
276         .num_controls = ARRAY_SIZE(sof_controls),
277         .dapm_widgets = sof_widgets,
278         .num_dapm_widgets = ARRAY_SIZE(sof_widgets),
279         .dapm_routes = sof_map,
280         .num_dapm_routes = ARRAY_SIZE(sof_map),
281         .fully_routed = true,
282         .late_probe = sof_card_late_probe,
283 };
284
285 static struct snd_soc_dai_link_component cs42l42_component[] = {
286         {
287                 .name = "i2c-10134242:00",
288                 .dai_name = "cs42l42",
289         }
290 };
291
292 static struct snd_soc_dai_link_component dmic_component[] = {
293         {
294                 .name = "dmic-codec",
295                 .dai_name = "dmic-hifi",
296         }
297 };
298
299 static struct snd_soc_dai_link_component dummy_component[] = {
300         {
301                 .name = "snd-soc-dummy",
302                 .dai_name = "snd-soc-dummy-dai",
303         }
304 };
305
306 static int create_spk_amp_dai_links(struct device *dev,
307                                     struct snd_soc_dai_link *links,
308                                     struct snd_soc_dai_link_component *cpus,
309                                     int *id, int ssp_amp)
310 {
311         int ret = 0;
312
313         /* speaker amp */
314         if (!(sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT))
315                 return 0;
316
317         links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec",
318                                          ssp_amp);
319         if (!links[*id].name) {
320                 ret = -ENOMEM;
321                 goto devm_err;
322         }
323
324         links[*id].id = *id;
325
326         if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) {
327                 max_98357a_dai_link(&links[*id]);
328         } else if (sof_cs42l42_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
329                 max_98360a_dai_link(&links[*id]);
330         } else {
331                 dev_err(dev, "no amp defined\n");
332                 ret = -EINVAL;
333                 goto devm_err;
334         }
335
336         links[*id].platforms = platform_component;
337         links[*id].num_platforms = ARRAY_SIZE(platform_component);
338         links[*id].dpcm_playback = 1;
339         links[*id].no_pcm = 1;
340         links[*id].cpus = &cpus[*id];
341         links[*id].num_cpus = 1;
342
343         links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
344                                                    "SSP%d Pin", ssp_amp);
345         if (!links[*id].cpus->dai_name) {
346                 ret = -ENOMEM;
347                 goto devm_err;
348         }
349
350         (*id)++;
351
352 devm_err:
353         return ret;
354 }
355
356 static int create_hp_codec_dai_links(struct device *dev,
357                                      struct snd_soc_dai_link *links,
358                                      struct snd_soc_dai_link_component *cpus,
359                                      int *id, int ssp_codec)
360 {
361         /* codec SSP */
362         links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec",
363                                          ssp_codec);
364         if (!links[*id].name)
365                 goto devm_err;
366
367         links[*id].id = *id;
368         links[*id].codecs = cs42l42_component;
369         links[*id].num_codecs = ARRAY_SIZE(cs42l42_component);
370         links[*id].platforms = platform_component;
371         links[*id].num_platforms = ARRAY_SIZE(platform_component);
372         links[*id].init = sof_cs42l42_init;
373         links[*id].exit = sof_cs42l42_exit;
374         links[*id].ops = &sof_cs42l42_ops;
375         links[*id].dpcm_playback = 1;
376         links[*id].dpcm_capture = 1;
377         links[*id].no_pcm = 1;
378         links[*id].cpus = &cpus[*id];
379         links[*id].num_cpus = 1;
380
381         links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
382                                                    "SSP%d Pin",
383                                                    ssp_codec);
384         if (!links[*id].cpus->dai_name)
385                 goto devm_err;
386
387         (*id)++;
388
389         return 0;
390
391 devm_err:
392         return -ENOMEM;
393 }
394
395 static int create_dmic_dai_links(struct device *dev,
396                                  struct snd_soc_dai_link *links,
397                                  struct snd_soc_dai_link_component *cpus,
398                                  int *id, int dmic_be_num)
399 {
400         int i;
401
402         /* dmic */
403         if (dmic_be_num <= 0)
404                 return 0;
405
406         /* at least we have dmic01 */
407         links[*id].name = "dmic01";
408         links[*id].cpus = &cpus[*id];
409         links[*id].cpus->dai_name = "DMIC01 Pin";
410         links[*id].init = dmic_init;
411         if (dmic_be_num > 1) {
412                 /* set up 2 BE links at most */
413                 links[*id + 1].name = "dmic16k";
414                 links[*id + 1].cpus = &cpus[*id + 1];
415                 links[*id + 1].cpus->dai_name = "DMIC16k Pin";
416                 dmic_be_num = 2;
417         }
418
419         for (i = 0; i < dmic_be_num; i++) {
420                 links[*id].id = *id;
421                 links[*id].num_cpus = 1;
422                 links[*id].codecs = dmic_component;
423                 links[*id].num_codecs = ARRAY_SIZE(dmic_component);
424                 links[*id].platforms = platform_component;
425                 links[*id].num_platforms = ARRAY_SIZE(platform_component);
426                 links[*id].ignore_suspend = 1;
427                 links[*id].dpcm_capture = 1;
428                 links[*id].no_pcm = 1;
429
430                 (*id)++;
431         }
432
433         return 0;
434 }
435
436 static int create_hdmi_dai_links(struct device *dev,
437                                  struct snd_soc_dai_link *links,
438                                  struct snd_soc_dai_link_component *cpus,
439                                  int *id, int hdmi_num)
440 {
441         struct snd_soc_dai_link_component *idisp_components;
442         int i;
443
444         /* HDMI */
445         if (hdmi_num <= 0)
446                 return 0;
447
448         idisp_components = devm_kcalloc(dev,
449                                         hdmi_num,
450                                         sizeof(struct snd_soc_dai_link_component), GFP_KERNEL);
451         if (!idisp_components)
452                 goto devm_err;
453
454         for (i = 1; i <= hdmi_num; i++) {
455                 links[*id].name = devm_kasprintf(dev, GFP_KERNEL,
456                                                  "iDisp%d", i);
457                 if (!links[*id].name)
458                         goto devm_err;
459
460                 links[*id].id = *id;
461                 links[*id].cpus = &cpus[*id];
462                 links[*id].num_cpus = 1;
463                 links[*id].cpus->dai_name = devm_kasprintf(dev,
464                                                            GFP_KERNEL,
465                                                            "iDisp%d Pin",
466                                                            i);
467                 if (!links[*id].cpus->dai_name)
468                         goto devm_err;
469
470                 idisp_components[i - 1].name = "ehdaudio0D2";
471                 idisp_components[i - 1].dai_name = devm_kasprintf(dev,
472                                                                   GFP_KERNEL,
473                                                                   "intel-hdmi-hifi%d",
474                                                                   i);
475                 if (!idisp_components[i - 1].dai_name)
476                         goto devm_err;
477
478                 links[*id].codecs = &idisp_components[i - 1];
479                 links[*id].num_codecs = 1;
480                 links[*id].platforms = platform_component;
481                 links[*id].num_platforms = ARRAY_SIZE(platform_component);
482                 links[*id].init = sof_hdmi_init;
483                 links[*id].dpcm_playback = 1;
484                 links[*id].no_pcm = 1;
485
486                 (*id)++;
487         }
488
489         return 0;
490
491 devm_err:
492         return -ENOMEM;
493 }
494
495 static int create_bt_offload_dai_links(struct device *dev,
496                                        struct snd_soc_dai_link *links,
497                                        struct snd_soc_dai_link_component *cpus,
498                                        int *id, int ssp_bt)
499 {
500         /* bt offload */
501         if (!(sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT))
502                 return 0;
503
504         links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT",
505                                          ssp_bt);
506         if (!links[*id].name)
507                 goto devm_err;
508
509         links[*id].id = *id;
510         links[*id].codecs = dummy_component;
511         links[*id].num_codecs = ARRAY_SIZE(dummy_component);
512         links[*id].platforms = platform_component;
513         links[*id].num_platforms = ARRAY_SIZE(platform_component);
514
515         links[*id].dpcm_playback = 1;
516         links[*id].dpcm_capture = 1;
517         links[*id].no_pcm = 1;
518         links[*id].cpus = &cpus[*id];
519         links[*id].num_cpus = 1;
520
521         links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
522                                                    "SSP%d Pin",
523                                                    ssp_bt);
524         if (!links[*id].cpus->dai_name)
525                 goto devm_err;
526
527         (*id)++;
528
529         return 0;
530
531 devm_err:
532         return -ENOMEM;
533 }
534
535 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
536                                                           int ssp_codec,
537                                                           int ssp_amp,
538                                                           int ssp_bt,
539                                                           int dmic_be_num,
540                                                           int hdmi_num)
541 {
542         struct snd_soc_dai_link_component *cpus;
543         struct snd_soc_dai_link *links;
544         int ret, id = 0, link_seq;
545
546         links = devm_kcalloc(dev, sof_audio_card_cs42l42.num_links,
547                             sizeof(struct snd_soc_dai_link), GFP_KERNEL);
548         cpus = devm_kcalloc(dev, sof_audio_card_cs42l42.num_links,
549                             sizeof(struct snd_soc_dai_link_component), GFP_KERNEL);
550         if (!links || !cpus)
551                 goto devm_err;
552
553         link_seq = (sof_cs42l42_quirk & SOF_CS42L42_DAILINK_MASK) >> SOF_CS42L42_DAILINK_SHIFT;
554
555         while (link_seq) {
556                 int link_type = link_seq & 0x07;
557
558                 switch (link_type) {
559                 case LINK_HP:
560                         ret = create_hp_codec_dai_links(dev, links, cpus, &id, ssp_codec);
561                         if (ret < 0) {
562                                 dev_err(dev, "fail to create hp codec dai links, ret %d\n",
563                                         ret);
564                                 goto devm_err;
565                         }
566                         break;
567                 case LINK_SPK:
568                         ret = create_spk_amp_dai_links(dev, links, cpus, &id, ssp_amp);
569                         if (ret < 0) {
570                                 dev_err(dev, "fail to create spk amp dai links, ret %d\n",
571                                         ret);
572                                 goto devm_err;
573                         }
574                         break;
575                 case LINK_DMIC:
576                         ret = create_dmic_dai_links(dev, links, cpus, &id, dmic_be_num);
577                         if (ret < 0) {
578                                 dev_err(dev, "fail to create dmic dai links, ret %d\n",
579                                         ret);
580                                 goto devm_err;
581                         }
582                         break;
583                 case LINK_HDMI:
584                         ret = create_hdmi_dai_links(dev, links, cpus, &id, hdmi_num);
585                         if (ret < 0) {
586                                 dev_err(dev, "fail to create hdmi dai links, ret %d\n",
587                                         ret);
588                                 goto devm_err;
589                         }
590                         break;
591                 case LINK_BT:
592                         ret = create_bt_offload_dai_links(dev, links, cpus, &id, ssp_bt);
593                         if (ret < 0) {
594                                 dev_err(dev, "fail to create bt offload dai links, ret %d\n",
595                                         ret);
596                                 goto devm_err;
597                         }
598                         break;
599                 case LINK_NONE:
600                         /* caught here if it's not used as terminator in macro */
601                 default:
602                         dev_err(dev, "invalid link type %d\n", link_type);
603                         goto devm_err;
604                 }
605
606                 link_seq >>= 3;
607         }
608
609         return links;
610 devm_err:
611         return NULL;
612 }
613
614 static int sof_audio_probe(struct platform_device *pdev)
615 {
616         struct snd_soc_dai_link *dai_links;
617         struct snd_soc_acpi_mach *mach;
618         struct sof_card_private *ctx;
619         int dmic_be_num, hdmi_num;
620         int ret, ssp_bt, ssp_amp, ssp_codec;
621
622         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
623         if (!ctx)
624                 return -ENOMEM;
625
626         if (pdev->id_entry && pdev->id_entry->driver_data)
627                 sof_cs42l42_quirk = (unsigned long)pdev->id_entry->driver_data;
628
629         mach = pdev->dev.platform_data;
630
631         if (soc_intel_is_glk()) {
632                 dmic_be_num = 1;
633                 hdmi_num = 3;
634         } else {
635                 dmic_be_num = 2;
636                 hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >>
637                          SOF_CS42L42_NUM_HDMIDEV_SHIFT;
638                 /* default number of HDMI DAI's */
639                 if (!hdmi_num)
640                         hdmi_num = 3;
641         }
642
643         dev_dbg(&pdev->dev, "sof_cs42l42_quirk = %lx\n", sof_cs42l42_quirk);
644
645         ssp_bt = (sof_cs42l42_quirk & SOF_CS42L42_SSP_BT_MASK) >>
646                         SOF_CS42L42_SSP_BT_SHIFT;
647
648         ssp_amp = (sof_cs42l42_quirk & SOF_CS42L42_SSP_AMP_MASK) >>
649                         SOF_CS42L42_SSP_AMP_SHIFT;
650
651         ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK;
652
653         /* compute number of dai links */
654         sof_audio_card_cs42l42.num_links = 1 + dmic_be_num + hdmi_num;
655
656         if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT)
657                 sof_audio_card_cs42l42.num_links++;
658         if (sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT)
659                 sof_audio_card_cs42l42.num_links++;
660
661         dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
662                                               ssp_bt, dmic_be_num, hdmi_num);
663         if (!dai_links)
664                 return -ENOMEM;
665
666         sof_audio_card_cs42l42.dai_link = dai_links;
667
668         INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
669
670         sof_audio_card_cs42l42.dev = &pdev->dev;
671
672         /* set platform name for each dailink */
673         ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_cs42l42,
674                                                     mach->mach_params.platform);
675         if (ret)
676                 return ret;
677
678         ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
679
680         snd_soc_card_set_drvdata(&sof_audio_card_cs42l42, ctx);
681
682         return devm_snd_soc_register_card(&pdev->dev,
683                                           &sof_audio_card_cs42l42);
684 }
685
686 static const struct platform_device_id board_ids[] = {
687         {
688                 .name = "glk_cs4242_mx98357a",
689                 .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(2) |
690                                         SOF_SPEAKER_AMP_PRESENT |
691                                         SOF_MAX98357A_SPEAKER_AMP_PRESENT |
692                                         SOF_CS42L42_SSP_AMP(1)) |
693                                         SOF_CS42L42_DAILINK(LINK_SPK, LINK_HP, LINK_DMIC, LINK_HDMI, LINK_NONE),
694         },
695         {
696                 .name = "jsl_cs4242_mx98360a",
697                 .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) |
698                                         SOF_SPEAKER_AMP_PRESENT |
699                                         SOF_MAX98360A_SPEAKER_AMP_PRESENT |
700                                         SOF_CS42L42_SSP_AMP(1)) |
701                                         SOF_CS42L42_DAILINK(LINK_HP, LINK_DMIC, LINK_HDMI, LINK_SPK, LINK_NONE),
702         },
703         {
704                 .name = "adl_mx98360a_cs4242",
705                 .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) |
706                                 SOF_SPEAKER_AMP_PRESENT |
707                                 SOF_MAX98360A_SPEAKER_AMP_PRESENT |
708                                 SOF_CS42L42_SSP_AMP(1) |
709                                 SOF_CS42L42_NUM_HDMIDEV(4) |
710                                 SOF_BT_OFFLOAD_PRESENT |
711                                 SOF_CS42L42_SSP_BT(2) |
712                                 SOF_CS42L42_DAILINK(LINK_HP, LINK_DMIC, LINK_HDMI, LINK_SPK, LINK_BT)),
713         },
714         { }
715 };
716 MODULE_DEVICE_TABLE(platform, board_ids);
717
718 static struct platform_driver sof_audio = {
719         .probe = sof_audio_probe,
720         .driver = {
721                 .name = "sof_cs42l42",
722                 .pm = &snd_soc_pm_ops,
723         },
724         .id_table = board_ids,
725 };
726 module_platform_driver(sof_audio)
727
728 /* Module information */
729 MODULE_DESCRIPTION("SOF Audio Machine driver for CS42L42");
730 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
731 MODULE_LICENSE("GPL");
732 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
733 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);