video: tegra: host: nvdla: Avoid contiguos alloc
[linux-nvidia.git] / sound / soc / tegra-alt / machine_drivers / tegra_machine_driver_mobile.c
1 /*
2  * tegra_machine_driver_mobile.c - Tegra ASoC Machine driver for mobile
3  *
4  * Copyright (c) 2017-2019 NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/of_platform.h>
22 #include <linux/input.h>
23 #include <linux/gpio.h>
24 #include <linux/pm_runtime.h>
25 #include <sound/core.h>
26 #include <sound/jack.h>
27 #include <sound/pcm.h>
28 #include <sound/pcm_params.h>
29 #include <sound/soc.h>
30 #include <dt-bindings/sound/tas2552.h>
31 #include "rt5659.h"
32 #include "sgtl5000.h"
33 #include "tegra_asoc_machine_alt.h"
34 #include "tegra210_xbar_alt.h"
35
36 #define DRV_NAME "tegra-asoc:"
37
38 #define PARAMS(sformat, channels)               \
39         {                                       \
40                 .formats = sformat,             \
41                 .rate_min = 48000,              \
42                 .rate_max = 48000,              \
43                 .channels_min = channels,       \
44                 .channels_max = channels,       \
45         }
46
47 /* t210 soc data */
48 static const struct tegra_machine_soc_data soc_data_tegra210 = {
49         .admaif_dai_link_start          = TEGRA210_DAI_LINK_ADMAIF1,
50         .admaif_dai_link_end            = TEGRA210_DAI_LINK_ADMAIF10,
51 #if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
52         .adsp_pcm_dai_link_start        = TEGRA210_DAI_LINK_ADSP_PCM1,
53         .adsp_pcm_dai_link_end          = TEGRA210_DAI_LINK_ADSP_PCM2,
54         .adsp_compr_dai_link_start      = TEGRA210_DAI_LINK_ADSP_COMPR1,
55         .adsp_compr_dai_link_end        = TEGRA210_DAI_LINK_ADSP_COMPR2,
56 #endif
57         .sfc_dai_link                   = TEGRA210_DAI_LINK_SFC1_RX,
58
59         .write_idle_bias_off_state      = false,
60
61         .ahub_links                     = tegra210_xbar_dai_links,
62         .num_ahub_links                 = TEGRA210_XBAR_DAI_LINKS,
63         .ahub_confs                     = tegra210_xbar_codec_conf,
64         .num_ahub_confs                 = TEGRA210_XBAR_CODEC_CONF,
65 };
66
67 /* t186 soc data */
68 static const struct tegra_machine_soc_data soc_data_tegra186 = {
69         .admaif_dai_link_start          = TEGRA186_DAI_LINK_ADMAIF1,
70         .admaif_dai_link_end            = TEGRA186_DAI_LINK_ADMAIF10,
71 #if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
72         .adsp_pcm_dai_link_start        = TEGRA186_DAI_LINK_ADSP_PCM1,
73         .adsp_pcm_dai_link_end          = TEGRA186_DAI_LINK_ADSP_PCM2,
74         .adsp_compr_dai_link_start      = TEGRA186_DAI_LINK_ADSP_COMPR1,
75         .adsp_compr_dai_link_end        = TEGRA186_DAI_LINK_ADSP_COMPR2,
76 #endif
77         .sfc_dai_link                   = TEGRA186_DAI_LINK_SFC1_RX,
78
79         .write_idle_bias_off_state      = true,
80
81         .ahub_links                     = tegra186_xbar_dai_links,
82         .num_ahub_links                 = TEGRA186_XBAR_DAI_LINKS,
83         .ahub_confs                     = tegra186_xbar_codec_conf,
84         .num_ahub_confs                 = TEGRA186_XBAR_CODEC_CONF,
85 };
86
87 static const char * const tegra_machine_srate_text[] = {
88         "None",
89         "8kHz",
90         "16kHz",
91         "44kHz",
92         "48kHz",
93         "11kHz",
94         "22kHz",
95         "24kHz",
96         "32kHz",
97         "88kHz",
98         "96kHz",
99         "176kHz",
100         "192kHz",
101 };
102
103 static const char * const tegra_machine_format_text[] = {
104         "None",
105         "16",
106         "32",
107 };
108
109 static const struct soc_enum tegra_machine_codec_rate =
110         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tegra_machine_srate_text),
111                             tegra_machine_srate_text);
112
113 static const struct soc_enum tegra_machine_codec_format =
114         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tegra_machine_format_text),
115                             tegra_machine_format_text);
116
117 static const int tegra_machine_srate_values[] = {
118         0,
119         8000,
120         16000,
121         44100,
122         48000,
123         11025,
124         22050,
125         24000,
126         32000,
127         88200,
128         96000,
129         176400,
130         192000,
131 };
132
133 static const struct snd_soc_dapm_widget tegra_machine_dapm_widgets[] = {
134         SND_SOC_DAPM_SPK("x Int Spk", NULL),
135         SND_SOC_DAPM_HP("x Headphone Jack", NULL),
136         SND_SOC_DAPM_MIC("x Int Mic", NULL),
137         SND_SOC_DAPM_MIC("x Mic Jack", NULL),
138
139         SND_SOC_DAPM_SPK("d1 Headphone", NULL),
140         SND_SOC_DAPM_SPK("d2 Headphone", NULL),
141         SND_SOC_DAPM_SPK("d3 Headphone", NULL),
142
143         SND_SOC_DAPM_HP("w Headphone", NULL),
144         SND_SOC_DAPM_HP("x Headphone", NULL),
145         SND_SOC_DAPM_HP("y Headphone", NULL),
146         SND_SOC_DAPM_HP("z Headphone", NULL),
147         SND_SOC_DAPM_HP("l Headphone", NULL),
148         SND_SOC_DAPM_HP("m Headphone", NULL),
149         SND_SOC_DAPM_HP("n Headphone", NULL),
150         SND_SOC_DAPM_HP("o Headphone", NULL),
151         SND_SOC_DAPM_HP("s Headphone", NULL),
152
153         SND_SOC_DAPM_MIC("Int Mic", NULL),
154         SND_SOC_DAPM_MIC("w Mic", NULL),
155         SND_SOC_DAPM_MIC("x Mic", NULL),
156         SND_SOC_DAPM_MIC("y Mic", NULL),
157         SND_SOC_DAPM_MIC("z Mic", NULL),
158         SND_SOC_DAPM_MIC("l Mic", NULL),
159         SND_SOC_DAPM_MIC("m Mic", NULL),
160         SND_SOC_DAPM_MIC("n Mic", NULL),
161         SND_SOC_DAPM_MIC("o Mic", NULL),
162         SND_SOC_DAPM_MIC("a Mic", NULL),
163         SND_SOC_DAPM_MIC("b Mic", NULL),
164         SND_SOC_DAPM_MIC("c Mic", NULL),
165         SND_SOC_DAPM_MIC("d Mic", NULL),
166         SND_SOC_DAPM_MIC("s Mic", NULL),
167 };
168
169 static struct snd_soc_pcm_stream tegra_machine_asrc_link_params[] = {
170         PARAMS(SNDRV_PCM_FMTBIT_S32_LE, 8),
171         PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2),
172         PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2),
173         PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2),
174         PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2),
175         PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2),
176 };
177
178 static int tegra_machine_codec_get_rate(struct snd_kcontrol *kcontrol,
179                                         struct snd_ctl_elem_value *ucontrol)
180 {
181         struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
182         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
183
184         ucontrol->value.integer.value[0] = machine->rate_via_kcontrol;
185
186         return 0;
187 }
188
189 static int tegra_machine_codec_put_rate(struct snd_kcontrol *kcontrol,
190                                         struct snd_ctl_elem_value *ucontrol)
191 {
192         struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
193         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
194
195         /* set the rate control flag */
196         machine->rate_via_kcontrol = ucontrol->value.integer.value[0];
197
198         return 0;
199 }
200
201 static int tegra_machine_codec_get_format(struct snd_kcontrol *kcontrol,
202         struct snd_ctl_elem_value *ucontrol)
203 {
204         struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
205         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
206
207         ucontrol->value.integer.value[0] = machine->fmt_via_kcontrol;
208
209         return 0;
210 }
211
212 static int tegra_machine_codec_put_format(struct snd_kcontrol *kcontrol,
213         struct snd_ctl_elem_value *ucontrol)
214 {
215         struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
216         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
217
218         /* set the format control flag */
219         machine->fmt_via_kcontrol = ucontrol->value.integer.value[0];
220
221         return 0;
222 }
223
224 static int tegra_machine_set_params(struct snd_soc_card *card,
225                                     struct tegra_machine *machine,
226                                     unsigned int rate,
227                                     unsigned int channels,
228                                     u64 formats)
229 {
230         unsigned int mask = (1 << channels) - 1;
231         struct snd_soc_pcm_runtime *rtd;
232         int idx = 0, err = 0;
233         u64 format_k;
234
235         int num_of_dai_links = machine->soc_data->num_ahub_links +
236                                machine->num_codec_links;
237
238         format_k = (machine->fmt_via_kcontrol == 2) ?
239                         (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
240
241         /* update dai link hw_params */
242         list_for_each_entry(rtd, &card->rtd_list, list) {
243                 if (rtd->dai_link->params) {
244                         struct snd_soc_pcm_stream *dai_params;
245
246                         dai_params =
247                           (struct snd_soc_pcm_stream *)
248                           rtd->dai_link->params;
249
250                         dai_params->rate_min = rate;
251                         dai_params->channels_min = channels;
252                         dai_params->formats = format_k;
253
254                         if ((idx >= machine->soc_data->num_ahub_links)
255                                 && (idx < num_of_dai_links)) {
256                                 unsigned int fmt;
257
258                                 /* TODO: why below overrite is needed */
259                                 dai_params->formats = formats;
260
261                                 fmt = rtd->dai_link->dai_fmt;
262                                 fmt &= SND_SOC_DAIFMT_FORMAT_MASK;
263
264                                 /* set TDM slot mask */
265                                 if (fmt == SND_SOC_DAIFMT_DSP_A ||
266                                     fmt == SND_SOC_DAIFMT_DSP_B) {
267                                         err = snd_soc_dai_set_tdm_slot(
268                                                         rtd->cpu_dai, mask,
269                                                         mask, 0, 0);
270                                         if (err < 0) {
271                                                 dev_err(card->dev,
272                                                 "%s cpu DAI slot mask not set\n",
273                                                 rtd->cpu_dai->name);
274                                                 return err;
275                                         }
276                                 }
277                         }
278                 }
279                 idx++;
280         }
281         return 0;
282 }
283
284 static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
285                                   unsigned int rate, unsigned int channels,
286                                   u64 formats)
287 {
288         struct snd_soc_card *card = runtime->card;
289         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
290         struct snd_soc_pcm_stream *dai_params;
291         unsigned int aud_mclk, srate;
292         int err;
293         struct snd_soc_pcm_runtime *rtd;
294
295         srate = (machine->rate_via_kcontrol) ?
296                         tegra_machine_srate_values[machine->rate_via_kcontrol] :
297                         rate;
298
299         err = tegra_alt_asoc_utils_set_rate(&machine->audio_clock, srate, 0, 0);
300         if (err < 0) {
301                 dev_err(card->dev, "Can't configure clocks\n");
302                 return err;
303         }
304
305         aud_mclk = machine->audio_clock.set_aud_mclk_rate;
306
307         pr_debug("pll_a_out0 = %u Hz, aud_mclk = %u Hz, sample rate = %u Hz\n",
308                  machine->audio_clock.set_pll_out_rate, aud_mclk, srate);
309
310         err = tegra_machine_set_params(card, machine, rate, channels, formats);
311         if (err < 0)
312                 return err;
313
314         rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback");
315         if (rtd) {
316                 dai_params =
317                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
318
319                 dai_params->rate_min = srate;
320                 dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
321                         (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
322
323                 err = snd_soc_dai_set_sysclk(rtd->codec_dai, RT5659_SCLK_S_MCLK,
324                                              aud_mclk, SND_SOC_CLOCK_IN);
325                 if (err < 0) {
326                         dev_err(card->dev, "codec_dai clock not set\n");
327                         return err;
328                 }
329         }
330
331         rtd = snd_soc_get_pcm_runtime(card, "rt565x-codec-sysclk-bclk1");
332         if (rtd) {
333                 dai_params =
334                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
335
336                 dai_params->rate_min = srate;
337                 dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
338                         (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
339
340                 err = rt565x_manage_codec_sysclk(dai_params, rtd->codec_dai,
341                                                  RT5659_PLL1_S_BCLK1);
342                 if (err < 0) {
343                         dev_err(card->dev, "codec_dai clock not set\n");
344                         return err;
345                 }
346         }
347
348         rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-0");
349         if (rtd) {
350                 dai_params =
351                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
352
353                 dai_params->rate_min = srate;
354         }
355
356         rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-1");
357         if (rtd) {
358                 dai_params =
359                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
360
361                 dai_params->rate_min = srate;
362         }
363
364         /* set clk rate for i2s3 dai link*/
365         rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-2");
366         if (rtd) {
367                 dai_params =
368                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
369
370                 dai_params->rate_min = srate;
371         }
372
373         rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-3");
374         if (rtd) {
375                 dai_params =
376                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
377
378                 dai_params->rate_min = srate;
379         }
380
381         rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-5");
382         if (rtd) {
383                 dai_params =
384                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
385
386                 /* update link_param to update hw_param for DAPM */
387                 dai_params->rate_min = srate;
388                 dai_params->channels_min = channels;
389                 dai_params->formats = formats;
390         }
391
392         rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-r");
393         if (rtd) {
394                 dai_params =
395                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
396
397                 if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
398                         err = snd_soc_dai_set_sysclk(rtd->codec_dai,
399                                 TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
400                                 SND_SOC_CLOCK_IN);
401                         if (err < 0) {
402                                 dev_err(card->dev, "codec_dai clock not set\n");
403                                 return err;
404                         }
405                 }
406         }
407
408         rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-l");
409         if (rtd) {
410                 dai_params =
411                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
412
413                 if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
414                         err = snd_soc_dai_set_sysclk(rtd->codec_dai,
415                                 TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
416                                 SND_SOC_CLOCK_IN);
417                         if (err < 0) {
418                                 dev_err(card->dev, "codec_dai clock not set\n");
419                                 return err;
420                         }
421                 }
422         }
423
424         rtd = snd_soc_get_pcm_runtime(card, "fe-pi-audio-z-v2");
425         if (rtd) {
426                 dai_params =
427                 (struct snd_soc_pcm_stream *)rtd->dai_link->params;
428
429                 dai_params->rate_min = srate;
430                 dai_params->channels_min = channels;
431                 dai_params->formats = formats;
432         }
433
434         return 0;
435 }
436
437 static int tegra_machine_pcm_hw_params(struct snd_pcm_substream *substream,
438                                         struct snd_pcm_hw_params *params)
439 {
440         struct snd_soc_pcm_runtime *rtd = substream->private_data;
441         struct snd_soc_card *card = rtd->card;
442         int err;
443
444         err = tegra_machine_dai_init(rtd, params_rate(params),
445                                      params_channels(params),
446                                      1ULL << params_format(params));
447         if (err < 0) {
448                 dev_err(card->dev, "Failed dai init\n");
449                 return err;
450         }
451
452         return 0;
453 }
454
455 static int tegra_machine_pcm_startup(struct snd_pcm_substream *substream)
456 {
457         struct snd_soc_pcm_runtime *rtd = substream->private_data;
458         struct tegra_machine *machine = snd_soc_card_get_drvdata(rtd->card);
459
460         tegra_alt_asoc_utils_clk_enable(&machine->audio_clock);
461
462         return 0;
463 }
464
465 static void tegra_machine_pcm_shutdown(struct snd_pcm_substream *substream)
466 {
467         struct snd_soc_pcm_runtime *rtd = substream->private_data;
468         struct tegra_machine *machine = snd_soc_card_get_drvdata(rtd->card);
469
470         tegra_alt_asoc_utils_clk_disable(&machine->audio_clock);
471 }
472
473 static int tegra_machine_suspend_pre(struct snd_soc_card *card)
474 {
475         struct snd_soc_pcm_runtime *rtd;
476
477         /* DAPM dai link stream work for non pcm links */
478         list_for_each_entry(rtd, &card->rtd_list, list) {
479                 if (rtd->dai_link->params)
480                         INIT_DELAYED_WORK(&rtd->delayed_work, NULL);
481         }
482
483         return 0;
484 }
485
486 #if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
487 static int tegra_machine_compr_startup(struct snd_compr_stream *cstream)
488 {
489         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
490         struct snd_soc_card *card = rtd->card;
491         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
492
493         tegra_alt_asoc_utils_clk_enable(&machine->audio_clock);
494
495         return 0;
496 }
497
498 static void tegra_machine_compr_shutdown(struct snd_compr_stream *cstream)
499 {
500         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
501         struct snd_soc_card *card = rtd->card;
502         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
503
504         tegra_alt_asoc_utils_clk_disable(&machine->audio_clock);
505 }
506
507 static int tegra_machine_compr_set_params(struct snd_compr_stream *cstream)
508 {
509         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
510         struct snd_soc_card *card = rtd->card;
511         struct snd_soc_platform *platform = rtd->platform;
512         struct snd_codec codec_params;
513         int err;
514
515         if (platform->driver->compr_ops &&
516                 platform->driver->compr_ops->get_params) {
517                 err = platform->driver->compr_ops->get_params(cstream,
518                         &codec_params);
519                 if (err < 0) {
520                         dev_err(card->dev, "Failed to get compr params\n");
521                         return err;
522                 }
523         } else {
524                 dev_err(card->dev, "compr ops not set\n");
525                 return -EINVAL;
526         }
527
528         err = tegra_machine_dai_init(rtd, codec_params.sample_rate,
529                                      codec_params.ch_out,
530                                      SNDRV_PCM_FMTBIT_S16_LE);
531         if (err < 0) {
532                 dev_err(card->dev, "Failed dai init\n");
533                 return err;
534         }
535
536         return 0;
537 }
538 #endif
539
540 static int tegra_machine_fepi_init(struct snd_soc_pcm_runtime *rtd)
541 {
542         struct device *dev = rtd->card->dev;
543         int err;
544
545         err = snd_soc_dai_set_sysclk(rtd->codec_dai, SGTL5000_SYSCLK, 12288000,
546                                      SND_SOC_CLOCK_IN);
547         if (err) {
548                 dev_err(dev, "failed to set sgtl5000 sysclk!\n");
549                 return err;
550         }
551
552         return 0;
553 }
554
555 static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
556 {
557         struct snd_soc_card *card = rtd->card;
558         struct snd_soc_jack *jack;
559         int err;
560
561         jack = devm_kzalloc(card->dev, sizeof(struct snd_soc_jack), GFP_KERNEL);
562         if (!jack)
563                 return -ENOMEM;
564
565         err = snd_soc_card_jack_new(card, "Headset Jack", SND_JACK_HEADSET,
566                                     jack, NULL, 0);
567         if (err) {
568                 dev_err(card->dev, "Headset Jack creation failed %d\n", err);
569                 return err;
570         }
571
572         err = tegra_machine_add_codec_jack_control(card, rtd, jack);
573         if (err) {
574                 dev_err(card->dev, "Failed to add jack control: %d\n", err);
575                 return err;
576         }
577
578         err = rt5659_set_jack_detect(rtd->codec, jack);
579         if (err) {
580                 dev_err(card->dev, "Failed to set jack for RT565x: %d\n", err);
581                 return err;
582         }
583
584         /* single button supporting play/pause */
585         snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
586
587         /* multiple buttons supporting play/pause and volume up/down */
588         snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_MEDIA);
589         snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
590         snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
591
592         snd_soc_dapm_sync(&card->dapm);
593
594         return 0;
595 }
596
597 static int codec_init(struct tegra_machine *machine)
598 {
599         struct snd_soc_dai_link *dai_links = machine->asoc->dai_links;
600         unsigned int num_links = machine->asoc->num_links, i;
601
602         if (!dai_links || !num_links)
603                 return -EINVAL;
604
605         for (i = 0; i < num_links; i++) {
606                 if (!dai_links[i].name)
607                         continue;
608
609                 if (strstr(dai_links[i].name, "rt565x-playback") ||
610                     strstr(dai_links[i].name, "rt565x-codec-sysclk-bclk1"))
611                         dai_links[i].init = tegra_machine_rt565x_init;
612                 else if (strstr(dai_links[i].name, "fe-pi-audio-z-v2"))
613                         dai_links[i].init = tegra_machine_fepi_init;
614         }
615
616         return 0;
617 }
618
619 static struct snd_soc_ops tegra_machine_pcm_ops = {
620         .hw_params      = tegra_machine_pcm_hw_params,
621         .startup        = tegra_machine_pcm_startup,
622         .shutdown       = tegra_machine_pcm_shutdown,
623 };
624
625 #if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
626 static struct snd_soc_compr_ops tegra_machine_compr_ops = {
627         .set_params     = tegra_machine_compr_set_params,
628         .startup        = tegra_machine_compr_startup,
629         .shutdown       = tegra_machine_compr_shutdown,
630 };
631 #endif
632
633 static void set_dai_ops(struct tegra_machine *machine)
634 {
635         int i;
636
637         /* set ADMAIF dai_ops */
638         for (i = machine->soc_data->admaif_dai_link_start;
639              i <= machine->soc_data->admaif_dai_link_end; i++)
640                 machine->asoc->dai_links[i].ops = &tegra_machine_pcm_ops;
641 #if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
642         /* set ADSP PCM/COMPR */
643         for (i = machine->soc_data->adsp_pcm_dai_link_start;
644              i <= machine->soc_data->adsp_pcm_dai_link_end; i++)
645                 machine->asoc->dai_links[i].ops = &tegra_machine_pcm_ops;
646         /* set ADSP COMPR */
647         for (i = machine->soc_data->adsp_compr_dai_link_start;
648              i <= machine->soc_data->adsp_compr_dai_link_end; i++)
649                 machine->asoc->dai_links[i].compr_ops =
650                         &tegra_machine_compr_ops;
651 #endif
652 #if IS_ENABLED(CONFIG_SND_SOC_TEGRA186_ASRC_ALT)
653         if (!(of_machine_is_compatible("nvidia,tegra210")  ||
654                 of_machine_is_compatible("nvidia,tegra210b01"))) {
655                 /* set ASRC params. The default is 2 channels */
656                 for (i = 0; i < 6; i++) {
657                         int tx = TEGRA186_DAI_LINK_ASRC1_TX1 + i;
658                         int rx = TEGRA186_DAI_LINK_ASRC1_RX1 + i;
659
660                         machine->asoc->dai_links[tx].params =
661                                 &tegra_machine_asrc_link_params[i];
662                         machine->asoc->dai_links[rx].params =
663                                 &tegra_machine_asrc_link_params[i];
664                 }
665         }
666 #endif
667 }
668
669 static int add_dai_links(struct platform_device *pdev)
670 {
671         struct snd_soc_card *card = platform_get_drvdata(pdev);
672         struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
673         int ret;
674
675         machine->asoc = devm_kzalloc(&pdev->dev, sizeof(*machine->asoc),
676                                      GFP_KERNEL);
677         if (!machine->asoc)
678                 return -ENOMEM;
679
680         ret = tegra_asoc_populate_dai_links(pdev);
681         if (ret < 0)
682                 return ret;
683
684         ret = tegra_asoc_populate_codec_confs(pdev);
685         if (ret < 0)
686                 return ret;
687
688         ret = codec_init(machine);
689         if (ret < 0)
690                 return ret;
691
692         set_dai_ops(machine);
693
694         return 0;
695 }
696
697 static const struct snd_kcontrol_new tegra_machine_controls[] = {
698         SOC_ENUM_EXT("codec-x rate", tegra_machine_codec_rate,
699                 tegra_machine_codec_get_rate, tegra_machine_codec_put_rate),
700         SOC_ENUM_EXT("codec-x format", tegra_machine_codec_format,
701                 tegra_machine_codec_get_format, tegra_machine_codec_put_format),
702 };
703
704 static struct snd_soc_card snd_soc_tegra_card = {
705         .owner = THIS_MODULE,
706         .controls = tegra_machine_controls,
707         .num_controls = ARRAY_SIZE(tegra_machine_controls),
708         .dapm_widgets = tegra_machine_dapm_widgets,
709         .num_dapm_widgets = ARRAY_SIZE(tegra_machine_dapm_widgets),
710         .suspend_pre = tegra_machine_suspend_pre,
711         .fully_routed = true,
712 };
713
714 /* structure to match device tree node */
715 static const struct of_device_id tegra_machine_of_match[] = {
716         { .compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x",
717                 .data = &soc_data_tegra186 },
718         { .compatible = "nvidia,tegra-audio-t210ref-mobile-rt565x",
719                 .data = &soc_data_tegra210 },
720         { .compatible = "nvidia,tegra-audio-mystique",
721                 .data = &soc_data_tegra186 },
722         {},
723 };
724
725 static int tegra_machine_driver_probe(struct platform_device *pdev)
726 {
727         struct device_node *np = pdev->dev.of_node;
728         struct snd_soc_card *card = &snd_soc_tegra_card;
729         struct tegra_machine *machine;
730         int ret = 0;
731         const struct of_device_id *match;
732
733         card->dev = &pdev->dev;
734         /* parse card name first to log errors with proper device name */
735         ret = snd_soc_of_parse_card_name(card, "nvidia,model");
736         if (ret)
737                 return ret;
738
739         match = of_match_device(tegra_machine_of_match, &pdev->dev);
740         if (!match) {
741                 dev_err(&pdev->dev, "Error: No device match found\n");
742                 return -ENODEV;
743         }
744
745         if (!np) {
746                 dev_err(&pdev->dev, "No DT node for tegra machine driver");
747                 return -ENODEV;
748         }
749
750         machine = devm_kzalloc(&pdev->dev, sizeof(*machine), GFP_KERNEL);
751         if (!machine)
752                 return -ENOMEM;
753
754         machine->soc_data = (struct tegra_machine_soc_data *)match->data;
755         if (!machine->soc_data)
756                 return -EINVAL;
757
758         platform_set_drvdata(pdev, card);
759         snd_soc_card_set_drvdata(card, machine);
760
761         if (machine->soc_data->write_cdev1_state)
762                 machine->audio_clock.clk_cdev1_state = 0;
763
764         if (machine->soc_data->write_idle_bias_off_state)
765                 card->dapm.idle_bias_off = true;
766
767         ret = snd_soc_of_parse_audio_routing(card,
768                                 "nvidia,audio-routing");
769         if (ret)
770                 return ret;
771
772         memset(&machine->audio_clock, 0, sizeof(machine->audio_clock));
773         if (of_property_read_u32(np, "mclk-fs",
774                                  &machine->audio_clock.mclk_scale) < 0)
775                 dev_dbg(&pdev->dev, "Missing property mclk-fs\n");
776
777         tegra_machine_dma_set_mask(pdev);
778
779         ret = add_dai_links(pdev);
780         if (ret < 0)
781                 goto cleanup_asoc;
782
783         ret = tegra_alt_asoc_utils_init(&machine->audio_clock,
784                                         &pdev->dev,
785                                         card);
786         if (ret < 0)
787                 goto cleanup_asoc;
788
789         ret = snd_soc_register_card(card);
790         if (ret) {
791                 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
792                         ret);
793                 goto cleanup_asoc;
794         }
795
796         tegra_machine_add_i2s_codec_controls(card,
797                                         machine->soc_data->num_ahub_links +
798                                         machine->num_codec_links);
799
800         return 0;
801 cleanup_asoc:
802         release_asoc_phandles(machine);
803         return ret;
804 }
805
806 static int tegra_machine_driver_remove(struct platform_device *pdev)
807 {
808         struct snd_soc_card *card = platform_get_drvdata(pdev);
809
810         snd_soc_unregister_card(card);
811
812         return 0;
813 }
814
815 #if CONFIG_PM
816 static void tegra_asoc_machine_resume(struct device *dev)
817 {
818         WARN_ON(snd_soc_resume(dev));
819 }
820 #else
821 #define tegra_asoc_machine_resume NULL
822 #endif
823
824 static const struct dev_pm_ops tegra_asoc_machine_pm_ops = {
825         .prepare = snd_soc_suspend,
826         .complete = tegra_asoc_machine_resume,
827         .poweroff = snd_soc_poweroff,
828 };
829
830 static struct platform_driver tegra_asoc_machine_driver = {
831         .driver = {
832                 .name = DRV_NAME,
833                 .owner = THIS_MODULE,
834                 .pm = &tegra_asoc_machine_pm_ops,
835                 .of_match_table = tegra_machine_of_match,
836         },
837         .probe = tegra_machine_driver_probe,
838         .remove = tegra_machine_driver_remove,
839 };
840 module_platform_driver(tegra_asoc_machine_driver);
841
842 MODULE_AUTHOR("Mohan Kumar <mkumard@nvidia.com>, Sameer Pujar <spujar@nvidia.com>");
843 MODULE_DESCRIPTION("Tegra ASoC machine driver");
844 MODULE_LICENSE("GPL");
845 MODULE_ALIAS("platform:" DRV_NAME);
846 MODULE_DEVICE_TABLE(of, tegra_machine_of_match);