arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / sound / soc / intel / boards / sof_nau8825.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2021 Intel Corporation.
3 // Copyright(c) 2021 Nuvoton Corporation.
4
5 /*
6  * Intel SOF Machine Driver with Nuvoton headphone codec NAU8825
7  * and speaker codec RT1019P MAX98360a or MAX98373
8  */
9 #include <linux/i2c.h>
10 #include <linux/input.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.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 "../../codecs/nau8825.h"
22 #include "../common/soc-intel-quirks.h"
23 #include "sof_board_helpers.h"
24 #include "sof_realtek_common.h"
25 #include "sof_maxim_common.h"
26 #include "sof_nuvoton_common.h"
27 #include "sof_ssp_common.h"
28
29 #define SOF_NAU8825_SSP_CODEC(quirk)            ((quirk) & GENMASK(2, 0))
30 #define SOF_NAU8825_SSP_CODEC_MASK              (GENMASK(2, 0))
31 #define SOF_NAU8825_SSP_AMP_SHIFT               4
32 #define SOF_NAU8825_SSP_AMP_MASK                (GENMASK(6, 4))
33 #define SOF_NAU8825_SSP_AMP(quirk)      \
34         (((quirk) << SOF_NAU8825_SSP_AMP_SHIFT) & SOF_NAU8825_SSP_AMP_MASK)
35 #define SOF_NAU8825_NUM_HDMIDEV_SHIFT           7
36 #define SOF_NAU8825_NUM_HDMIDEV_MASK            (GENMASK(9, 7))
37 #define SOF_NAU8825_NUM_HDMIDEV(quirk)  \
38         (((quirk) << SOF_NAU8825_NUM_HDMIDEV_SHIFT) & SOF_NAU8825_NUM_HDMIDEV_MASK)
39
40 /* BT audio offload: reserve 3 bits for future */
41 #define SOF_BT_OFFLOAD_SSP_SHIFT                10
42 #define SOF_BT_OFFLOAD_SSP_MASK         (GENMASK(12, 10))
43 #define SOF_BT_OFFLOAD_SSP(quirk)       \
44         (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
45 #define SOF_SSP_BT_OFFLOAD_PRESENT              BIT(13)
46
47 static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0);
48
49 static struct snd_soc_jack_pin jack_pins[] = {
50         {
51                 .pin    = "Headphone Jack",
52                 .mask   = SND_JACK_HEADPHONE,
53         },
54         {
55                 .pin    = "Headset Mic",
56                 .mask   = SND_JACK_MICROPHONE,
57         },
58 };
59
60 static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
61 {
62         struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
63         struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
64         struct snd_soc_jack *jack = &ctx->headset_jack;
65         int ret;
66
67         /*
68          * Headset buttons map to the google Reference headset.
69          * These can be configured by userspace.
70          */
71         ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
72                                          SND_JACK_HEADSET | SND_JACK_BTN_0 |
73                                          SND_JACK_BTN_1 | SND_JACK_BTN_2 |
74                                          SND_JACK_BTN_3,
75                                          jack,
76                                          jack_pins,
77                                          ARRAY_SIZE(jack_pins));
78         if (ret) {
79                 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
80                 return ret;
81         }
82
83         snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
84         snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
85         snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
86         snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
87
88         ret = snd_soc_component_set_jack(component, jack, NULL);
89         if (ret) {
90                 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
91                 return ret;
92         }
93
94         return ret;
95 };
96
97 static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd)
98 {
99         struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
100
101         snd_soc_component_set_jack(component, NULL, NULL);
102 }
103
104 static int sof_nau8825_hw_params(struct snd_pcm_substream *substream,
105                                  struct snd_pcm_hw_params *params)
106 {
107         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
108         struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
109         int clk_freq, ret;
110
111         clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */
112
113         if (clk_freq <= 0) {
114                 dev_err(rtd->dev, "get bclk freq failed: %d\n", clk_freq);
115                 return -EINVAL;
116         }
117
118         /* Configure clock for codec */
119         ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,
120                                      SND_SOC_CLOCK_IN);
121         if (ret < 0) {
122                 dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);
123                 return ret;
124         }
125
126         /* Configure pll for codec */
127         ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,
128                                   params_rate(params) * 256);
129         if (ret < 0) {
130                 dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);
131                 return ret;
132         }
133
134         return ret;
135 }
136
137 static struct snd_soc_ops sof_nau8825_ops = {
138         .hw_params = sof_nau8825_hw_params,
139 };
140
141 static struct snd_soc_dai_link_component platform_component[] = {
142         {
143                 /* name might be overridden during probe */
144                 .name = "0000:00:1f.3"
145         }
146 };
147
148 static int sof_card_late_probe(struct snd_soc_card *card)
149 {
150         struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
151         struct snd_soc_dapm_context *dapm = &card->dapm;
152         int err;
153
154         if (ctx->amp_type == CODEC_MAX98373) {
155                 /* Disable Left and Right Spk pin after boot */
156                 snd_soc_dapm_disable_pin(dapm, "Left Spk");
157                 snd_soc_dapm_disable_pin(dapm, "Right Spk");
158                 err = snd_soc_dapm_sync(dapm);
159                 if (err < 0)
160                         return err;
161         }
162
163         return sof_intel_board_card_late_probe(card);
164 }
165
166 static const struct snd_kcontrol_new sof_controls[] = {
167         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
168         SOC_DAPM_PIN_SWITCH("Headset Mic"),
169         SOC_DAPM_PIN_SWITCH("Left Spk"),
170         SOC_DAPM_PIN_SWITCH("Right Spk"),
171 };
172
173 static const struct snd_soc_dapm_widget sof_widgets[] = {
174         SND_SOC_DAPM_HP("Headphone Jack", NULL),
175         SND_SOC_DAPM_MIC("Headset Mic", NULL),
176         SND_SOC_DAPM_SPK("Left Spk", NULL),
177         SND_SOC_DAPM_SPK("Right Spk", NULL),
178 };
179
180 static const struct snd_soc_dapm_route sof_map[] = {
181         /* HP jack connectors - unknown if we have jack detection */
182         { "Headphone Jack", NULL, "HPOL" },
183         { "Headphone Jack", NULL, "HPOR" },
184
185         /* other jacks */
186         { "MIC", NULL, "Headset Mic" },
187 };
188
189 /* sof audio machine driver for nau8825 codec */
190 static struct snd_soc_card sof_audio_card_nau8825 = {
191         .name = "nau8825", /* the sof- prefix is added by the core */
192         .owner = THIS_MODULE,
193         .controls = sof_controls,
194         .num_controls = ARRAY_SIZE(sof_controls),
195         .dapm_widgets = sof_widgets,
196         .num_dapm_widgets = ARRAY_SIZE(sof_widgets),
197         .dapm_routes = sof_map,
198         .num_dapm_routes = ARRAY_SIZE(sof_map),
199         .fully_routed = true,
200         .late_probe = sof_card_late_probe,
201 };
202
203 static struct snd_soc_dai_link_component nau8825_component[] = {
204         {
205                 .name = "i2c-10508825:00",
206                 .dai_name = "nau8825-hifi",
207         }
208 };
209
210 static struct snd_soc_dai_link *
211 sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
212                           int ssp_codec, int ssp_amp, int dmic_be_num,
213                           int hdmi_num, bool idisp_codec)
214 {
215         struct snd_soc_dai_link_component *cpus;
216         struct snd_soc_dai_link *links;
217         int i;
218         int id = 0;
219         int ret;
220
221         links = devm_kcalloc(dev, sof_audio_card_nau8825.num_links,
222                             sizeof(struct snd_soc_dai_link), GFP_KERNEL);
223         cpus = devm_kcalloc(dev, sof_audio_card_nau8825.num_links,
224                             sizeof(struct snd_soc_dai_link_component), GFP_KERNEL);
225         if (!links || !cpus)
226                 goto devm_err;
227
228         /* codec SSP */
229         links[id].name = devm_kasprintf(dev, GFP_KERNEL,
230                                         "SSP%d-Codec", ssp_codec);
231         if (!links[id].name)
232                 goto devm_err;
233
234         links[id].id = id;
235         links[id].codecs = nau8825_component;
236         links[id].num_codecs = ARRAY_SIZE(nau8825_component);
237         links[id].platforms = platform_component;
238         links[id].num_platforms = ARRAY_SIZE(platform_component);
239         links[id].init = sof_nau8825_codec_init;
240         links[id].exit = sof_nau8825_codec_exit;
241         links[id].ops = &sof_nau8825_ops;
242         links[id].dpcm_playback = 1;
243         links[id].dpcm_capture = 1;
244         links[id].no_pcm = 1;
245         links[id].cpus = &cpus[id];
246         links[id].num_cpus = 1;
247
248         links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
249                                                   "SSP%d Pin",
250                                                   ssp_codec);
251         if (!links[id].cpus->dai_name)
252                 goto devm_err;
253
254         id++;
255
256         /* dmic */
257         if (dmic_be_num > 0) {
258                 /* at least we have dmic01 */
259                 ret = sof_intel_board_set_dmic_link(dev, &links[id], id,
260                                                     SOF_DMIC_01);
261                 if (ret)
262                         return NULL;
263
264                 id++;
265         }
266
267         if (dmic_be_num > 1) {
268                 /* set up 2 BE links at most */
269                 ret = sof_intel_board_set_dmic_link(dev, &links[id], id,
270                                                     SOF_DMIC_16K);
271                 if (ret)
272                         return NULL;
273
274                 id++;
275         }
276
277         /* HDMI */
278         for (i = 1; i <= hdmi_num; i++) {
279                 ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id,
280                                                           i, idisp_codec);
281                 if (ret)
282                         return NULL;
283
284                 id++;
285         }
286
287         /* speaker amp */
288         if (amp_type != CODEC_NONE) {
289                 links[id].name = devm_kasprintf(dev, GFP_KERNEL,
290                                                 "SSP%d-Codec", ssp_amp);
291                 if (!links[id].name)
292                         goto devm_err;
293
294                 links[id].id = id;
295
296                 switch (amp_type) {
297                 case CODEC_MAX98360A:
298                         max_98360a_dai_link(&links[id]);
299                         break;
300                 case CODEC_MAX98373:
301                         links[id].codecs = max_98373_components;
302                         links[id].num_codecs = ARRAY_SIZE(max_98373_components);
303                         links[id].init = max_98373_spk_codec_init;
304                         links[id].ops = &max_98373_ops;
305                         break;
306                 case CODEC_NAU8318:
307                         nau8318_set_dai_link(&links[id]);
308                         break;
309                 case CODEC_RT1015P:
310                         sof_rt1015p_dai_link(&links[id]);
311                         break;
312                 case CODEC_RT1019P:
313                         sof_rt1019p_dai_link(&links[id]);
314                         break;
315                 default:
316                         dev_err(dev, "invalid amp type %d\n", amp_type);
317                         return NULL;
318                 }
319
320                 links[id].platforms = platform_component;
321                 links[id].num_platforms = ARRAY_SIZE(platform_component);
322                 links[id].dpcm_playback = 1;
323                 /* feedback stream or firmware-generated echo reference */
324                 links[id].dpcm_capture = 1;
325
326                 links[id].no_pcm = 1;
327                 links[id].cpus = &cpus[id];
328                 links[id].num_cpus = 1;
329                 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
330                                                           "SSP%d Pin",
331                                                           ssp_amp);
332                 if (!links[id].cpus->dai_name)
333                         goto devm_err;
334                 id++;
335         }
336
337         /* BT audio offload */
338         if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
339                 int port = (sof_nau8825_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
340                                 SOF_BT_OFFLOAD_SSP_SHIFT;
341
342                 links[id].id = id;
343                 links[id].cpus = &cpus[id];
344                 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
345                                                           "SSP%d Pin", port);
346                 if (!links[id].cpus->dai_name)
347                         goto devm_err;
348                 links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
349                 if (!links[id].name)
350                         goto devm_err;
351                 links[id].codecs = &snd_soc_dummy_dlc;
352                 links[id].num_codecs = 1;
353                 links[id].platforms = platform_component;
354                 links[id].num_platforms = ARRAY_SIZE(platform_component);
355                 links[id].dpcm_playback = 1;
356                 links[id].dpcm_capture = 1;
357                 links[id].no_pcm = 1;
358                 links[id].num_cpus = 1;
359         }
360
361         return links;
362 devm_err:
363         return NULL;
364 }
365
366 static int sof_audio_probe(struct platform_device *pdev)
367 {
368         struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
369         struct snd_soc_dai_link *dai_links;
370         struct sof_card_private *ctx;
371         int ret, ssp_amp, ssp_codec;
372
373         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
374         if (!ctx)
375                 return -ENOMEM;
376
377         if (pdev->id_entry && pdev->id_entry->driver_data)
378                 sof_nau8825_quirk = (unsigned long)pdev->id_entry->driver_data;
379
380         ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
381         ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
382
383         dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk);
384
385         /* default number of DMIC DAI's */
386         ctx->dmic_be_num = 2;
387         ctx->hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >>
388                         SOF_NAU8825_NUM_HDMIDEV_SHIFT;
389         /* default number of HDMI DAI's */
390         if (!ctx->hdmi_num)
391                 ctx->hdmi_num = 3;
392
393         if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
394                 ctx->hdmi.idisp_codec = true;
395
396         ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >>
397                         SOF_NAU8825_SSP_AMP_SHIFT;
398
399         ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK;
400
401         /* compute number of dai links */
402         sof_audio_card_nau8825.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num;
403
404         if (ctx->amp_type != CODEC_NONE)
405                 sof_audio_card_nau8825.num_links++;
406
407         if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
408                 sof_audio_card_nau8825.num_links++;
409
410         dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type,
411                                               ssp_codec, ssp_amp,
412                                               ctx->dmic_be_num, ctx->hdmi_num,
413                                               ctx->hdmi.idisp_codec);
414         if (!dai_links)
415                 return -ENOMEM;
416
417         sof_audio_card_nau8825.dai_link = dai_links;
418
419         /* update codec_conf */
420         switch (ctx->amp_type) {
421         case CODEC_MAX98373:
422                 max_98373_set_codec_conf(&sof_audio_card_nau8825);
423                 break;
424         case CODEC_RT1015P:
425                 sof_rt1015p_codec_conf(&sof_audio_card_nau8825);
426                 break;
427         case CODEC_NONE:
428         case CODEC_MAX98360A:
429         case CODEC_NAU8318:
430         case CODEC_RT1019P:
431                 /* no codec conf required */
432                 break;
433         default:
434                 dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type);
435                 return -EINVAL;
436         }
437
438         sof_audio_card_nau8825.dev = &pdev->dev;
439
440         /* set platform name for each dailink */
441         ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_nau8825,
442                                                     mach->mach_params.platform);
443         if (ret)
444                 return ret;
445
446         snd_soc_card_set_drvdata(&sof_audio_card_nau8825, ctx);
447
448         return devm_snd_soc_register_card(&pdev->dev,
449                                           &sof_audio_card_nau8825);
450 }
451
452 static const struct platform_device_id board_ids[] = {
453         {
454                 .name = "sof_nau8825",
455                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
456                                         SOF_NAU8825_NUM_HDMIDEV(4) |
457                                         SOF_BT_OFFLOAD_SSP(2) |
458                                         SOF_SSP_BT_OFFLOAD_PRESENT),
459
460         },
461         {
462                 .name = "adl_rt1019p_8825",
463                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
464                                         SOF_NAU8825_SSP_AMP(2) |
465                                         SOF_NAU8825_NUM_HDMIDEV(4)),
466         },
467         {
468                 .name = "adl_max98373_8825",
469                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
470                                         SOF_NAU8825_SSP_AMP(1) |
471                                         SOF_NAU8825_NUM_HDMIDEV(4) |
472                                         SOF_BT_OFFLOAD_SSP(2) |
473                                         SOF_SSP_BT_OFFLOAD_PRESENT),
474         },
475         {
476                 /* The limitation of length of char array, shorten the name */
477                 .name = "adl_mx98360a_8825",
478                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
479                                         SOF_NAU8825_SSP_AMP(1) |
480                                         SOF_NAU8825_NUM_HDMIDEV(4) |
481                                         SOF_BT_OFFLOAD_SSP(2) |
482                                         SOF_SSP_BT_OFFLOAD_PRESENT),
483
484         },
485         {
486                 .name = "adl_rt1015p_8825",
487                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
488                                         SOF_NAU8825_SSP_AMP(1) |
489                                         SOF_NAU8825_NUM_HDMIDEV(4) |
490                                         SOF_BT_OFFLOAD_SSP(2) |
491                                         SOF_SSP_BT_OFFLOAD_PRESENT),
492         },
493         {
494                 .name = "adl_nau8318_8825",
495                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
496                                         SOF_NAU8825_SSP_AMP(1) |
497                                         SOF_NAU8825_NUM_HDMIDEV(4) |
498                                         SOF_BT_OFFLOAD_SSP(2) |
499                                         SOF_SSP_BT_OFFLOAD_PRESENT),
500         },
501         {
502                 .name = "rpl_max98373_8825",
503                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
504                                         SOF_NAU8825_SSP_AMP(1) |
505                                         SOF_NAU8825_NUM_HDMIDEV(4) |
506                                         SOF_BT_OFFLOAD_SSP(2) |
507                                         SOF_SSP_BT_OFFLOAD_PRESENT),
508         },
509         {
510                 .name = "rpl_mx98360a_8825",
511                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
512                                         SOF_NAU8825_SSP_AMP(1) |
513                                         SOF_NAU8825_NUM_HDMIDEV(4) |
514                                         SOF_BT_OFFLOAD_SSP(2) |
515                                         SOF_SSP_BT_OFFLOAD_PRESENT),
516         },
517         {
518                 .name = "rpl_nau8318_8825",
519                 .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
520                                         SOF_NAU8825_SSP_AMP(1) |
521                                         SOF_NAU8825_NUM_HDMIDEV(4) |
522                                         SOF_BT_OFFLOAD_SSP(2) |
523                                         SOF_SSP_BT_OFFLOAD_PRESENT),
524         },
525         { }
526 };
527 MODULE_DEVICE_TABLE(platform, board_ids);
528
529 static struct platform_driver sof_audio = {
530         .probe = sof_audio_probe,
531         .driver = {
532                 .name = "sof_nau8825",
533                 .pm = &snd_soc_pm_ops,
534         },
535         .id_table = board_ids,
536 };
537 module_platform_driver(sof_audio)
538
539 /* Module information */
540 MODULE_DESCRIPTION("SOF Audio Machine driver for NAU8825");
541 MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");
542 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
543 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
544 MODULE_LICENSE("GPL");
545 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
546 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
547 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_NUVOTON_COMMON);
548 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
549 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);