GNU Linux-libre 5.10.76-gnu1
[releases.git] / sound / soc / rockchip / rk3399_gru_sound.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219
4  *
5  * Copyright (c) 2016, ROCKCHIP CORPORATION.  All rights reserved.
6  */
7
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/slab.h>
11 #include <linux/gpio.h>
12 #include <linux/of_gpio.h>
13 #include <linux/delay.h>
14 #include <linux/spi/spi.h>
15 #include <linux/i2c.h>
16 #include <linux/input.h>
17 #include <sound/core.h>
18 #include <sound/jack.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include "rockchip_i2s.h"
23 #include "../codecs/da7219.h"
24 #include "../codecs/da7219-aad.h"
25 #include "../codecs/rt5514.h"
26
27 #define DRV_NAME "rk3399-gru-sound"
28
29 #define SOUND_FS        256
30
31 static unsigned int dmic_wakeup_delay;
32
33 static struct snd_soc_jack rockchip_sound_jack;
34
35 /* Headset jack detection DAPM pins */
36 static struct snd_soc_jack_pin rockchip_sound_jack_pins[] = {
37         {
38                 .pin = "Headphones",
39                 .mask = SND_JACK_HEADPHONE,
40         },
41         {
42                 .pin = "Headset Mic",
43                 .mask = SND_JACK_MICROPHONE,
44         },
45
46 };
47
48 static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
49         SND_SOC_DAPM_HP("Headphones", NULL),
50         SND_SOC_DAPM_SPK("Speakers", NULL),
51         SND_SOC_DAPM_MIC("Headset Mic", NULL),
52         SND_SOC_DAPM_MIC("Int Mic", NULL),
53         SND_SOC_DAPM_LINE("HDMI", NULL),
54 };
55
56 static const struct snd_kcontrol_new rockchip_controls[] = {
57         SOC_DAPM_PIN_SWITCH("Headphones"),
58         SOC_DAPM_PIN_SWITCH("Speakers"),
59         SOC_DAPM_PIN_SWITCH("Headset Mic"),
60         SOC_DAPM_PIN_SWITCH("Int Mic"),
61         SOC_DAPM_PIN_SWITCH("HDMI"),
62 };
63
64 static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream,
65                              struct snd_pcm_hw_params *params)
66 {
67         struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
68         unsigned int mclk;
69         int ret;
70
71         mclk = params_rate(params) * SOUND_FS;
72
73         ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
74         if (ret) {
75                 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
76                                 __func__, mclk, ret);
77                 return ret;
78         }
79
80         return 0;
81 }
82
83 static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
84                              struct snd_pcm_hw_params *params)
85 {
86         struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
87         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
88         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
89         unsigned int mclk;
90         int ret;
91
92         mclk = params_rate(params) * SOUND_FS;
93
94         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
95                                      SND_SOC_CLOCK_OUT);
96         if (ret < 0) {
97                 dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret);
98                 return ret;
99         }
100
101         ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK,
102                                      mclk, SND_SOC_CLOCK_IN);
103         if (ret) {
104                 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
105                                 __func__, params_rate(params) * 512, ret);
106                 return ret;
107         }
108
109         /* Wait for DMIC stable */
110         msleep(dmic_wakeup_delay);
111
112         return 0;
113 }
114
115 static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
116                              struct snd_pcm_hw_params *params)
117 {
118         struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
119         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
120         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
121         int mclk, ret;
122
123         /* in bypass mode, the mclk has to be one of the frequencies below */
124         switch (params_rate(params)) {
125         case 8000:
126         case 16000:
127         case 24000:
128         case 32000:
129         case 48000:
130         case 64000:
131         case 96000:
132                 mclk = 12288000;
133                 break;
134         case 11025:
135         case 22050:
136         case 44100:
137         case 88200:
138                 mclk = 11289600;
139                 break;
140         default:
141                 return -EINVAL;
142         }
143
144         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
145                                      SND_SOC_CLOCK_OUT);
146         if (ret < 0) {
147                 dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
148                 return ret;
149         }
150
151         ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
152                                      SND_SOC_CLOCK_IN);
153         if (ret < 0) {
154                 dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret);
155                 return ret;
156         }
157
158         ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
159         if (ret < 0) {
160                 dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret);
161                 return ret;
162         }
163
164         return 0;
165 }
166
167 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
168 {
169         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
170         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
171         int ret;
172
173         /* We need default MCLK and PLL settings for the accessory detection */
174         ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
175                                      SND_SOC_CLOCK_IN);
176         if (ret < 0) {
177                 dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret);
178                 return ret;
179         }
180
181         ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
182         if (ret < 0) {
183                 dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret);
184                 return ret;
185         }
186
187         /* Enable Headset and 4 Buttons Jack detection */
188         ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
189                                     SND_JACK_HEADSET | SND_JACK_LINEOUT |
190                                     SND_JACK_BTN_0 | SND_JACK_BTN_1 |
191                                     SND_JACK_BTN_2 | SND_JACK_BTN_3,
192                                     &rockchip_sound_jack,
193                                     rockchip_sound_jack_pins,
194                                     ARRAY_SIZE(rockchip_sound_jack_pins));
195
196         if (ret) {
197                 dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret);
198                 return ret;
199         }
200
201         snd_jack_set_key(
202                 rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
203         snd_jack_set_key(
204                 rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
205         snd_jack_set_key(
206                 rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
207         snd_jack_set_key(
208                 rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
209
210         da7219_aad_jack_det(component, &rockchip_sound_jack);
211
212         return 0;
213 }
214
215 static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
216                              struct snd_pcm_hw_params *params)
217 {
218         struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
219         unsigned int mclk;
220         int ret;
221
222         mclk = params_rate(params) * SOUND_FS;
223
224         ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
225         if (ret) {
226                 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
227                                 __func__, mclk, ret);
228                 return ret;
229         }
230
231         /* Wait for DMIC stable */
232         msleep(dmic_wakeup_delay);
233
234         return 0;
235 }
236
237 static int rockchip_sound_startup(struct snd_pcm_substream *substream)
238 {
239         struct snd_pcm_runtime *runtime = substream->runtime;
240
241         runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
242         return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
243                         8000, 96000);
244 }
245
246 static const struct snd_soc_ops rockchip_sound_max98357a_ops = {
247         .startup = rockchip_sound_startup,
248         .hw_params = rockchip_sound_max98357a_hw_params,
249 };
250
251 static const struct snd_soc_ops rockchip_sound_rt5514_ops = {
252         .startup = rockchip_sound_startup,
253         .hw_params = rockchip_sound_rt5514_hw_params,
254 };
255
256 static const struct snd_soc_ops rockchip_sound_da7219_ops = {
257         .startup = rockchip_sound_startup,
258         .hw_params = rockchip_sound_da7219_hw_params,
259 };
260
261 static const struct snd_soc_ops rockchip_sound_dmic_ops = {
262         .startup = rockchip_sound_startup,
263         .hw_params = rockchip_sound_dmic_hw_params,
264 };
265
266 static struct snd_soc_card rockchip_sound_card = {
267         .name = "rk3399-gru-sound",
268         .owner = THIS_MODULE,
269         .dapm_widgets = rockchip_dapm_widgets,
270         .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
271         .controls = rockchip_controls,
272         .num_controls = ARRAY_SIZE(rockchip_controls),
273 };
274
275 enum {
276         DAILINK_CDNDP,
277         DAILINK_DA7219,
278         DAILINK_DMIC,
279         DAILINK_MAX98357A,
280         DAILINK_RT5514,
281         DAILINK_RT5514_DSP,
282 };
283
284 SND_SOC_DAILINK_DEFS(cdndp,
285         DAILINK_COMP_ARRAY(COMP_EMPTY()),
286         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "spdif-hifi")),
287         DAILINK_COMP_ARRAY(COMP_EMPTY()));
288
289 SND_SOC_DAILINK_DEFS(da7219,
290         DAILINK_COMP_ARRAY(COMP_EMPTY()),
291         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "da7219-hifi")),
292         DAILINK_COMP_ARRAY(COMP_EMPTY()));
293
294 SND_SOC_DAILINK_DEFS(dmic,
295         DAILINK_COMP_ARRAY(COMP_EMPTY()),
296         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "dmic-hifi")),
297         DAILINK_COMP_ARRAY(COMP_EMPTY()));
298
299 SND_SOC_DAILINK_DEFS(max98357a,
300         DAILINK_COMP_ARRAY(COMP_EMPTY()),
301         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")),
302         DAILINK_COMP_ARRAY(COMP_EMPTY()));
303
304 SND_SOC_DAILINK_DEFS(rt5514,
305         DAILINK_COMP_ARRAY(COMP_EMPTY()),
306         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5514-aif1")),
307         DAILINK_COMP_ARRAY(COMP_EMPTY()));
308
309 SND_SOC_DAILINK_DEFS(rt5514_dsp,
310         DAILINK_COMP_ARRAY(COMP_EMPTY()),
311         DAILINK_COMP_ARRAY(COMP_DUMMY()),
312         DAILINK_COMP_ARRAY(COMP_EMPTY()));
313
314 static const struct snd_soc_dai_link rockchip_dais[] = {
315         [DAILINK_CDNDP] = {
316                 .name = "DP",
317                 .stream_name = "DP PCM",
318                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
319                         SND_SOC_DAIFMT_CBS_CFS,
320                 SND_SOC_DAILINK_REG(cdndp),
321         },
322         [DAILINK_DA7219] = {
323                 .name = "DA7219",
324                 .stream_name = "DA7219 PCM",
325                 .init = rockchip_sound_da7219_init,
326                 .ops = &rockchip_sound_da7219_ops,
327                 /* set da7219 as slave */
328                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
329                         SND_SOC_DAIFMT_CBS_CFS,
330                 SND_SOC_DAILINK_REG(da7219),
331         },
332         [DAILINK_DMIC] = {
333                 .name = "DMIC",
334                 .stream_name = "DMIC PCM",
335                 .ops = &rockchip_sound_dmic_ops,
336                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
337                         SND_SOC_DAIFMT_CBS_CFS,
338                 SND_SOC_DAILINK_REG(dmic),
339         },
340         [DAILINK_MAX98357A] = {
341                 .name = "MAX98357A",
342                 .stream_name = "MAX98357A PCM",
343                 .ops = &rockchip_sound_max98357a_ops,
344                 /* set max98357a as slave */
345                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
346                         SND_SOC_DAIFMT_CBS_CFS,
347                 SND_SOC_DAILINK_REG(max98357a),
348         },
349         [DAILINK_RT5514] = {
350                 .name = "RT5514",
351                 .stream_name = "RT5514 PCM",
352                 .ops = &rockchip_sound_rt5514_ops,
353                 /* set rt5514 as slave */
354                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
355                         SND_SOC_DAIFMT_CBS_CFS,
356                 SND_SOC_DAILINK_REG(rt5514),
357         },
358         /* RT5514 DSP for voice wakeup via spi bus */
359         [DAILINK_RT5514_DSP] = {
360                 .name = "RT5514 DSP",
361                 .stream_name = "Wake on Voice",
362                 SND_SOC_DAILINK_REG(rt5514_dsp),
363         },
364 };
365
366 static const struct snd_soc_dapm_route rockchip_sound_cdndp_routes[] = {
367         /* Output */
368         {"HDMI", NULL, "TX"},
369 };
370
371 static const struct snd_soc_dapm_route rockchip_sound_da7219_routes[] = {
372         /* Output */
373         {"Headphones", NULL, "HPL"},
374         {"Headphones", NULL, "HPR"},
375
376         /* Input */
377         {"MIC", NULL, "Headset Mic"},
378 };
379
380 static const struct snd_soc_dapm_route rockchip_sound_dmic_routes[] = {
381         /* Input */
382         {"DMic", NULL, "Int Mic"},
383 };
384
385 static const struct snd_soc_dapm_route rockchip_sound_max98357a_routes[] = {
386         /* Output */
387         {"Speakers", NULL, "Speaker"},
388 };
389
390 static const struct snd_soc_dapm_route rockchip_sound_rt5514_routes[] = {
391         /* Input */
392         {"DMIC1L", NULL, "Int Mic"},
393         {"DMIC1R", NULL, "Int Mic"},
394 };
395
396 struct rockchip_sound_route {
397         const struct snd_soc_dapm_route *routes;
398         int num_routes;
399 };
400
401 static const struct rockchip_sound_route rockchip_routes[] = {
402         [DAILINK_CDNDP] = {
403                 .routes = rockchip_sound_cdndp_routes,
404                 .num_routes = ARRAY_SIZE(rockchip_sound_cdndp_routes),
405         },
406         [DAILINK_DA7219] = {
407                 .routes = rockchip_sound_da7219_routes,
408                 .num_routes = ARRAY_SIZE(rockchip_sound_da7219_routes),
409         },
410         [DAILINK_DMIC] = {
411                 .routes = rockchip_sound_dmic_routes,
412                 .num_routes = ARRAY_SIZE(rockchip_sound_dmic_routes),
413         },
414         [DAILINK_MAX98357A] = {
415                 .routes = rockchip_sound_max98357a_routes,
416                 .num_routes = ARRAY_SIZE(rockchip_sound_max98357a_routes),
417         },
418         [DAILINK_RT5514] = {
419                 .routes = rockchip_sound_rt5514_routes,
420                 .num_routes = ARRAY_SIZE(rockchip_sound_rt5514_routes),
421         },
422         [DAILINK_RT5514_DSP] = {},
423 };
424
425 struct dailink_match_data {
426         const char *compatible;
427         struct bus_type *bus_type;
428 };
429
430 static const struct dailink_match_data dailink_match[] = {
431         [DAILINK_CDNDP] = {
432                 .compatible = "rockchip,rk3399-cdn-dp",
433         },
434         [DAILINK_DA7219] = {
435                 .compatible = "dlg,da7219",
436         },
437         [DAILINK_DMIC] = {
438                 .compatible = "dmic-codec",
439         },
440         [DAILINK_MAX98357A] = {
441                 .compatible = "maxim,max98357a",
442         },
443         [DAILINK_RT5514] = {
444                 .compatible = "realtek,rt5514",
445                 .bus_type = &i2c_bus_type,
446         },
447         [DAILINK_RT5514_DSP] = {
448                 .compatible = "realtek,rt5514",
449                 .bus_type = &spi_bus_type,
450         },
451 };
452
453 static int rockchip_sound_codec_node_match(struct device_node *np_codec)
454 {
455         struct device *dev;
456         int i;
457
458         for (i = 0; i < ARRAY_SIZE(dailink_match); i++) {
459                 if (!of_device_is_compatible(np_codec,
460                                              dailink_match[i].compatible))
461                         continue;
462
463                 if (dailink_match[i].bus_type) {
464                         dev = bus_find_device_by_of_node(dailink_match[i].bus_type,
465                                                          np_codec);
466                         if (!dev)
467                                 continue;
468                         put_device(dev);
469                 }
470
471                 return i;
472         }
473         return -1;
474 }
475
476 static int rockchip_sound_of_parse_dais(struct device *dev,
477                                         struct snd_soc_card *card)
478 {
479         struct device_node *np_cpu, *np_cpu0, *np_cpu1;
480         struct device_node *np_codec;
481         struct snd_soc_dai_link *dai;
482         struct snd_soc_dapm_route *routes;
483         int i, index;
484         int num_routes;
485
486         card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais),
487                                       GFP_KERNEL);
488         if (!card->dai_link)
489                 return -ENOMEM;
490
491         num_routes = 0;
492         for (i = 0; i < ARRAY_SIZE(rockchip_routes); i++)
493                 num_routes += rockchip_routes[i].num_routes;
494         routes = devm_kcalloc(dev, num_routes, sizeof(*routes),
495                               GFP_KERNEL);
496         if (!routes)
497                 return -ENOMEM;
498         card->dapm_routes = routes;
499
500         np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0);
501         np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1);
502
503         card->num_dapm_routes = 0;
504         card->num_links = 0;
505         for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) {
506                 np_codec = of_parse_phandle(dev->of_node,
507                                             "rockchip,codec", i);
508                 if (!np_codec)
509                         break;
510
511                 if (!of_device_is_available(np_codec))
512                         continue;
513
514                 index = rockchip_sound_codec_node_match(np_codec);
515                 if (index < 0)
516                         continue;
517
518                 switch (index) {
519                 case DAILINK_CDNDP:
520                         np_cpu = np_cpu1;
521                         break;
522                 case DAILINK_RT5514_DSP:
523                         np_cpu = np_codec;
524                         break;
525                 default:
526                         np_cpu = np_cpu0;
527                         break;
528                 }
529
530                 if (!np_cpu) {
531                         dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
532                                 rockchip_dais[index].name);
533                         return -EINVAL;
534                 }
535
536                 dai = &card->dai_link[card->num_links++];
537                 *dai = rockchip_dais[index];
538
539                 if (!dai->codecs->name)
540                         dai->codecs->of_node = np_codec;
541                 dai->platforms->of_node = np_cpu;
542                 dai->cpus->of_node = np_cpu;
543
544                 if (card->num_dapm_routes + rockchip_routes[index].num_routes >
545                     num_routes) {
546                         dev_err(dev, "Too many routes\n");
547                         return -EINVAL;
548                 }
549
550                 memcpy(routes + card->num_dapm_routes,
551                        rockchip_routes[index].routes,
552                        rockchip_routes[index].num_routes * sizeof(*routes));
553                 card->num_dapm_routes += rockchip_routes[index].num_routes;
554         }
555
556         return 0;
557 }
558
559 static int rockchip_sound_probe(struct platform_device *pdev)
560 {
561         struct snd_soc_card *card = &rockchip_sound_card;
562         int ret;
563
564         ret = rockchip_sound_of_parse_dais(&pdev->dev, card);
565         if (ret < 0) {
566                 dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret);
567                 return ret;
568         }
569
570         /* Set DMIC wakeup delay */
571         ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms",
572                                         &dmic_wakeup_delay);
573         if (ret) {
574                 dmic_wakeup_delay = 0;
575                 dev_dbg(&pdev->dev,
576                         "no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n");
577         }
578
579         card->dev = &pdev->dev;
580         return devm_snd_soc_register_card(&pdev->dev, card);
581 }
582
583 static const struct of_device_id rockchip_sound_of_match[] = {
584         { .compatible = "rockchip,rk3399-gru-sound", },
585         {},
586 };
587
588 static struct platform_driver rockchip_sound_driver = {
589         .probe = rockchip_sound_probe,
590         .driver = {
591                 .name = DRV_NAME,
592                 .of_match_table = rockchip_sound_of_match,
593 #ifdef CONFIG_PM
594                 .pm = &snd_soc_pm_ops,
595 #endif
596         },
597 };
598
599 module_platform_driver(rockchip_sound_driver);
600
601 MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
602 MODULE_DESCRIPTION("Rockchip ASoC Machine Driver");
603 MODULE_LICENSE("GPL v2");
604 MODULE_ALIAS("platform:" DRV_NAME);
605 MODULE_DEVICE_TABLE(of, rockchip_sound_of_match);