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