GNU Linux-libre 6.1.91-gnu
[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 struct snd_soc_jack cdn_dp_card_jack;
168
169 static int rockchip_sound_cdndp_init(struct snd_soc_pcm_runtime *rtd)
170 {
171         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
172         struct snd_soc_card *card = rtd->card;
173         int ret;
174
175         /* Enable jack detection. */
176         ret = snd_soc_card_jack_new(card, "DP Jack", SND_JACK_LINEOUT,
177                                     &cdn_dp_card_jack);
178         if (ret) {
179                 dev_err(card->dev, "Can't create DP Jack %d\n", ret);
180                 return ret;
181         }
182
183         return snd_soc_component_set_jack(component, &cdn_dp_card_jack, NULL);
184 }
185
186 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
187 {
188         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
189         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
190         int ret;
191
192         /* We need default MCLK and PLL settings for the accessory detection */
193         ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
194                                      SND_SOC_CLOCK_IN);
195         if (ret < 0) {
196                 dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret);
197                 return ret;
198         }
199
200         ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
201         if (ret < 0) {
202                 dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret);
203                 return ret;
204         }
205
206         /* Enable Headset and 4 Buttons Jack detection */
207         ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
208                                          SND_JACK_HEADSET | SND_JACK_LINEOUT |
209                                          SND_JACK_BTN_0 | SND_JACK_BTN_1 |
210                                          SND_JACK_BTN_2 | SND_JACK_BTN_3,
211                                          &rockchip_sound_jack,
212                                          rockchip_sound_jack_pins,
213                                          ARRAY_SIZE(rockchip_sound_jack_pins));
214
215         if (ret) {
216                 dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret);
217                 return ret;
218         }
219
220         snd_jack_set_key(
221                 rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
222         snd_jack_set_key(
223                 rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
224         snd_jack_set_key(
225                 rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
226         snd_jack_set_key(
227                 rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
228
229         da7219_aad_jack_det(component, &rockchip_sound_jack);
230
231         return 0;
232 }
233
234 static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
235                              struct snd_pcm_hw_params *params)
236 {
237         struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
238         unsigned int mclk;
239         int ret;
240
241         mclk = params_rate(params) * SOUND_FS;
242
243         ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
244         if (ret) {
245                 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
246                                 __func__, mclk, ret);
247                 return ret;
248         }
249
250         /* Wait for DMIC stable */
251         msleep(dmic_wakeup_delay);
252
253         return 0;
254 }
255
256 static int rockchip_sound_startup(struct snd_pcm_substream *substream)
257 {
258         struct snd_pcm_runtime *runtime = substream->runtime;
259
260         runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
261         return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
262                         8000, 96000);
263 }
264
265 static const struct snd_soc_ops rockchip_sound_max98357a_ops = {
266         .startup = rockchip_sound_startup,
267         .hw_params = rockchip_sound_max98357a_hw_params,
268 };
269
270 static const struct snd_soc_ops rockchip_sound_rt5514_ops = {
271         .startup = rockchip_sound_startup,
272         .hw_params = rockchip_sound_rt5514_hw_params,
273 };
274
275 static const struct snd_soc_ops rockchip_sound_da7219_ops = {
276         .startup = rockchip_sound_startup,
277         .hw_params = rockchip_sound_da7219_hw_params,
278 };
279
280 static const struct snd_soc_ops rockchip_sound_dmic_ops = {
281         .startup = rockchip_sound_startup,
282         .hw_params = rockchip_sound_dmic_hw_params,
283 };
284
285 static struct snd_soc_card rockchip_sound_card = {
286         .name = "rk3399-gru-sound",
287         .owner = THIS_MODULE,
288         .dapm_widgets = rockchip_dapm_widgets,
289         .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
290         .controls = rockchip_controls,
291         .num_controls = ARRAY_SIZE(rockchip_controls),
292 };
293
294 enum {
295         DAILINK_CDNDP,
296         DAILINK_DA7219,
297         DAILINK_DMIC,
298         DAILINK_MAX98357A,
299         DAILINK_RT5514,
300         DAILINK_RT5514_DSP,
301 };
302
303 SND_SOC_DAILINK_DEFS(cdndp,
304         DAILINK_COMP_ARRAY(COMP_EMPTY()),
305         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "spdif-hifi")),
306         DAILINK_COMP_ARRAY(COMP_EMPTY()));
307
308 SND_SOC_DAILINK_DEFS(da7219,
309         DAILINK_COMP_ARRAY(COMP_EMPTY()),
310         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "da7219-hifi")),
311         DAILINK_COMP_ARRAY(COMP_EMPTY()));
312
313 SND_SOC_DAILINK_DEFS(dmic,
314         DAILINK_COMP_ARRAY(COMP_EMPTY()),
315         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "dmic-hifi")),
316         DAILINK_COMP_ARRAY(COMP_EMPTY()));
317
318 SND_SOC_DAILINK_DEFS(max98357a,
319         DAILINK_COMP_ARRAY(COMP_EMPTY()),
320         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")),
321         DAILINK_COMP_ARRAY(COMP_EMPTY()));
322
323 SND_SOC_DAILINK_DEFS(rt5514,
324         DAILINK_COMP_ARRAY(COMP_EMPTY()),
325         DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5514-aif1")),
326         DAILINK_COMP_ARRAY(COMP_EMPTY()));
327
328 SND_SOC_DAILINK_DEFS(rt5514_dsp,
329         DAILINK_COMP_ARRAY(COMP_EMPTY()),
330         DAILINK_COMP_ARRAY(COMP_DUMMY()),
331         DAILINK_COMP_ARRAY(COMP_EMPTY()));
332
333 static const struct snd_soc_dai_link rockchip_dais[] = {
334         [DAILINK_CDNDP] = {
335                 .name = "DP",
336                 .stream_name = "DP PCM",
337                 .init = rockchip_sound_cdndp_init,
338                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
339                         SND_SOC_DAIFMT_CBS_CFS,
340                 SND_SOC_DAILINK_REG(cdndp),
341         },
342         [DAILINK_DA7219] = {
343                 .name = "DA7219",
344                 .stream_name = "DA7219 PCM",
345                 .init = rockchip_sound_da7219_init,
346                 .ops = &rockchip_sound_da7219_ops,
347                 /* set da7219 as slave */
348                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
349                         SND_SOC_DAIFMT_CBS_CFS,
350                 SND_SOC_DAILINK_REG(da7219),
351         },
352         [DAILINK_DMIC] = {
353                 .name = "DMIC",
354                 .stream_name = "DMIC PCM",
355                 .ops = &rockchip_sound_dmic_ops,
356                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
357                         SND_SOC_DAIFMT_CBS_CFS,
358                 SND_SOC_DAILINK_REG(dmic),
359         },
360         [DAILINK_MAX98357A] = {
361                 .name = "MAX98357A",
362                 .stream_name = "MAX98357A PCM",
363                 .ops = &rockchip_sound_max98357a_ops,
364                 /* set max98357a as slave */
365                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
366                         SND_SOC_DAIFMT_CBS_CFS,
367                 SND_SOC_DAILINK_REG(max98357a),
368         },
369         [DAILINK_RT5514] = {
370                 .name = "RT5514",
371                 .stream_name = "RT5514 PCM",
372                 .ops = &rockchip_sound_rt5514_ops,
373                 /* set rt5514 as slave */
374                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
375                         SND_SOC_DAIFMT_CBS_CFS,
376                 SND_SOC_DAILINK_REG(rt5514),
377         },
378         /* RT5514 DSP for voice wakeup via spi bus */
379         [DAILINK_RT5514_DSP] = {
380                 .name = "RT5514 DSP",
381                 .stream_name = "Wake on Voice",
382                 SND_SOC_DAILINK_REG(rt5514_dsp),
383         },
384 };
385
386 static const struct snd_soc_dapm_route rockchip_sound_cdndp_routes[] = {
387         /* Output */
388         {"HDMI", NULL, "TX"},
389 };
390
391 static const struct snd_soc_dapm_route rockchip_sound_da7219_routes[] = {
392         /* Output */
393         {"Headphones", NULL, "HPL"},
394         {"Headphones", NULL, "HPR"},
395
396         /* Input */
397         {"MIC", NULL, "Headset Mic"},
398 };
399
400 static const struct snd_soc_dapm_route rockchip_sound_dmic_routes[] = {
401         /* Input */
402         {"DMic", NULL, "Int Mic"},
403 };
404
405 static const struct snd_soc_dapm_route rockchip_sound_max98357a_routes[] = {
406         /* Output */
407         {"Speakers", NULL, "Speaker"},
408 };
409
410 static const struct snd_soc_dapm_route rockchip_sound_rt5514_routes[] = {
411         /* Input */
412         {"DMIC1L", NULL, "Int Mic"},
413         {"DMIC1R", NULL, "Int Mic"},
414 };
415
416 struct rockchip_sound_route {
417         const struct snd_soc_dapm_route *routes;
418         int num_routes;
419 };
420
421 static const struct rockchip_sound_route rockchip_routes[] = {
422         [DAILINK_CDNDP] = {
423                 .routes = rockchip_sound_cdndp_routes,
424                 .num_routes = ARRAY_SIZE(rockchip_sound_cdndp_routes),
425         },
426         [DAILINK_DA7219] = {
427                 .routes = rockchip_sound_da7219_routes,
428                 .num_routes = ARRAY_SIZE(rockchip_sound_da7219_routes),
429         },
430         [DAILINK_DMIC] = {
431                 .routes = rockchip_sound_dmic_routes,
432                 .num_routes = ARRAY_SIZE(rockchip_sound_dmic_routes),
433         },
434         [DAILINK_MAX98357A] = {
435                 .routes = rockchip_sound_max98357a_routes,
436                 .num_routes = ARRAY_SIZE(rockchip_sound_max98357a_routes),
437         },
438         [DAILINK_RT5514] = {
439                 .routes = rockchip_sound_rt5514_routes,
440                 .num_routes = ARRAY_SIZE(rockchip_sound_rt5514_routes),
441         },
442         [DAILINK_RT5514_DSP] = {},
443 };
444
445 struct dailink_match_data {
446         const char *compatible;
447         struct bus_type *bus_type;
448 };
449
450 static const struct dailink_match_data dailink_match[] = {
451         [DAILINK_CDNDP] = {
452                 .compatible = "rockchip,rk3399-cdn-dp",
453         },
454         [DAILINK_DA7219] = {
455                 .compatible = "dlg,da7219",
456         },
457         [DAILINK_DMIC] = {
458                 .compatible = "dmic-codec",
459         },
460         [DAILINK_MAX98357A] = {
461                 .compatible = "maxim,max98357a",
462         },
463         [DAILINK_RT5514] = {
464                 .compatible = "realtek,rt5514",
465                 .bus_type = &i2c_bus_type,
466         },
467         [DAILINK_RT5514_DSP] = {
468                 .compatible = "realtek,rt5514",
469                 .bus_type = &spi_bus_type,
470         },
471 };
472
473 static int rockchip_sound_codec_node_match(struct device_node *np_codec)
474 {
475         struct device *dev;
476         int i;
477
478         for (i = 0; i < ARRAY_SIZE(dailink_match); i++) {
479                 if (!of_device_is_compatible(np_codec,
480                                              dailink_match[i].compatible))
481                         continue;
482
483                 if (dailink_match[i].bus_type) {
484                         dev = bus_find_device_by_of_node(dailink_match[i].bus_type,
485                                                          np_codec);
486                         if (!dev)
487                                 continue;
488                         put_device(dev);
489                 }
490
491                 return i;
492         }
493         return -1;
494 }
495
496 static int rockchip_sound_of_parse_dais(struct device *dev,
497                                         struct snd_soc_card *card)
498 {
499         struct device_node *np_cpu, *np_cpu0, *np_cpu1;
500         struct device_node *np_codec;
501         struct snd_soc_dai_link *dai;
502         struct snd_soc_dapm_route *routes;
503         int i, index;
504         int num_routes;
505
506         card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais),
507                                       GFP_KERNEL);
508         if (!card->dai_link)
509                 return -ENOMEM;
510
511         num_routes = 0;
512         for (i = 0; i < ARRAY_SIZE(rockchip_routes); i++)
513                 num_routes += rockchip_routes[i].num_routes;
514         routes = devm_kcalloc(dev, num_routes, sizeof(*routes),
515                               GFP_KERNEL);
516         if (!routes)
517                 return -ENOMEM;
518         card->dapm_routes = routes;
519
520         np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0);
521         np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1);
522
523         card->num_dapm_routes = 0;
524         card->num_links = 0;
525         for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) {
526                 np_codec = of_parse_phandle(dev->of_node,
527                                             "rockchip,codec", i);
528                 if (!np_codec)
529                         break;
530
531                 if (!of_device_is_available(np_codec))
532                         continue;
533
534                 index = rockchip_sound_codec_node_match(np_codec);
535                 if (index < 0)
536                         continue;
537
538                 switch (index) {
539                 case DAILINK_CDNDP:
540                         np_cpu = np_cpu1;
541                         break;
542                 case DAILINK_RT5514_DSP:
543                         np_cpu = np_codec;
544                         break;
545                 default:
546                         np_cpu = np_cpu0;
547                         break;
548                 }
549
550                 if (!np_cpu) {
551                         dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
552                                 rockchip_dais[index].name);
553                         return -EINVAL;
554                 }
555
556                 dai = &card->dai_link[card->num_links++];
557                 *dai = rockchip_dais[index];
558
559                 if (!dai->codecs->name)
560                         dai->codecs->of_node = np_codec;
561                 dai->platforms->of_node = np_cpu;
562                 dai->cpus->of_node = np_cpu;
563
564                 if (card->num_dapm_routes + rockchip_routes[index].num_routes >
565                     num_routes) {
566                         dev_err(dev, "Too many routes\n");
567                         return -EINVAL;
568                 }
569
570                 memcpy(routes + card->num_dapm_routes,
571                        rockchip_routes[index].routes,
572                        rockchip_routes[index].num_routes * sizeof(*routes));
573                 card->num_dapm_routes += rockchip_routes[index].num_routes;
574         }
575
576         return 0;
577 }
578
579 static int rockchip_sound_probe(struct platform_device *pdev)
580 {
581         struct snd_soc_card *card = &rockchip_sound_card;
582         int ret;
583
584         ret = rockchip_sound_of_parse_dais(&pdev->dev, card);
585         if (ret < 0) {
586                 dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret);
587                 return ret;
588         }
589
590         /* Set DMIC wakeup delay */
591         ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms",
592                                         &dmic_wakeup_delay);
593         if (ret) {
594                 dmic_wakeup_delay = 0;
595                 dev_dbg(&pdev->dev,
596                         "no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n");
597         }
598
599         card->dev = &pdev->dev;
600         return devm_snd_soc_register_card(&pdev->dev, card);
601 }
602
603 static const struct of_device_id rockchip_sound_of_match[] = {
604         { .compatible = "rockchip,rk3399-gru-sound", },
605         {},
606 };
607
608 static struct platform_driver rockchip_sound_driver = {
609         .probe = rockchip_sound_probe,
610         .driver = {
611                 .name = DRV_NAME,
612                 .of_match_table = rockchip_sound_of_match,
613 #ifdef CONFIG_PM
614                 .pm = &snd_soc_pm_ops,
615 #endif
616         },
617 };
618
619 module_platform_driver(rockchip_sound_driver);
620
621 MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
622 MODULE_DESCRIPTION("Rockchip ASoC Machine Driver");
623 MODULE_LICENSE("GPL v2");
624 MODULE_ALIAS("platform:" DRV_NAME);
625 MODULE_DEVICE_TABLE(of, rockchip_sound_of_match);