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_CBS_CFS, 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_CBS_CFS, 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_CBS_CFS, 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_CBS_CFS, 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_CBS_CFS, 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 <zhengxing@rock-chips.com>"); 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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.