root/sound/soc/generic/simple-card-utils.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. asoc_simple_convert_fixup
  2. asoc_simple_parse_convert
  3. asoc_simple_parse_daifmt
  4. asoc_simple_set_dailink_name
  5. asoc_simple_parse_card_name
  6. asoc_simple_clk_enable
  7. asoc_simple_clk_disable
  8. asoc_simple_parse_clk
  9. asoc_simple_startup
  10. asoc_simple_shutdown
  11. asoc_simple_set_clk_rate
  12. asoc_simple_hw_params
  13. asoc_simple_be_hw_params_fixup
  14. asoc_simple_init_dai
  15. asoc_simple_dai_init
  16. asoc_simple_canonicalize_platform
  17. asoc_simple_canonicalize_cpu
  18. asoc_simple_clean_reference
  19. asoc_simple_parse_routing
  20. asoc_simple_parse_widgets
  21. asoc_simple_parse_pin_switches
  22. asoc_simple_init_jack
  23. asoc_simple_init_priv

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // simple-card-utils.c
   4 //
   5 // Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
   6 
   7 #include <linux/clk.h>
   8 #include <linux/gpio.h>
   9 #include <linux/gpio/consumer.h>
  10 #include <linux/module.h>
  11 #include <linux/of.h>
  12 #include <linux/of_gpio.h>
  13 #include <linux/of_graph.h>
  14 #include <sound/jack.h>
  15 #include <sound/simple_card_utils.h>
  16 
  17 void asoc_simple_convert_fixup(struct asoc_simple_data *data,
  18                                struct snd_pcm_hw_params *params)
  19 {
  20         struct snd_interval *rate = hw_param_interval(params,
  21                                                 SNDRV_PCM_HW_PARAM_RATE);
  22         struct snd_interval *channels = hw_param_interval(params,
  23                                                 SNDRV_PCM_HW_PARAM_CHANNELS);
  24 
  25         if (data->convert_rate)
  26                 rate->min =
  27                 rate->max = data->convert_rate;
  28 
  29         if (data->convert_channels)
  30                 channels->min =
  31                 channels->max = data->convert_channels;
  32 }
  33 EXPORT_SYMBOL_GPL(asoc_simple_convert_fixup);
  34 
  35 void asoc_simple_parse_convert(struct device *dev,
  36                                struct device_node *np,
  37                                char *prefix,
  38                                struct asoc_simple_data *data)
  39 {
  40         char prop[128];
  41 
  42         if (!prefix)
  43                 prefix = "";
  44 
  45         /* sampling rate convert */
  46         snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-rate");
  47         of_property_read_u32(np, prop, &data->convert_rate);
  48 
  49         /* channels transfer */
  50         snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-channels");
  51         of_property_read_u32(np, prop, &data->convert_channels);
  52 }
  53 EXPORT_SYMBOL_GPL(asoc_simple_parse_convert);
  54 
  55 int asoc_simple_parse_daifmt(struct device *dev,
  56                              struct device_node *node,
  57                              struct device_node *codec,
  58                              char *prefix,
  59                              unsigned int *retfmt)
  60 {
  61         struct device_node *bitclkmaster = NULL;
  62         struct device_node *framemaster = NULL;
  63         unsigned int daifmt;
  64 
  65         daifmt = snd_soc_of_parse_daifmt(node, prefix,
  66                                          &bitclkmaster, &framemaster);
  67         daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
  68 
  69         if (!bitclkmaster && !framemaster) {
  70                 /*
  71                  * No dai-link level and master setting was not found from
  72                  * sound node level, revert back to legacy DT parsing and
  73                  * take the settings from codec node.
  74                  */
  75                 dev_dbg(dev, "Revert to legacy daifmt parsing\n");
  76 
  77                 daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
  78                         (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
  79         } else {
  80                 if (codec == bitclkmaster)
  81                         daifmt |= (codec == framemaster) ?
  82                                 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
  83                 else
  84                         daifmt |= (codec == framemaster) ?
  85                                 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
  86         }
  87 
  88         of_node_put(bitclkmaster);
  89         of_node_put(framemaster);
  90 
  91         *retfmt = daifmt;
  92 
  93         return 0;
  94 }
  95 EXPORT_SYMBOL_GPL(asoc_simple_parse_daifmt);
  96 
  97 int asoc_simple_set_dailink_name(struct device *dev,
  98                                  struct snd_soc_dai_link *dai_link,
  99                                  const char *fmt, ...)
 100 {
 101         va_list ap;
 102         char *name = NULL;
 103         int ret = -ENOMEM;
 104 
 105         va_start(ap, fmt);
 106         name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap);
 107         va_end(ap);
 108 
 109         if (name) {
 110                 ret = 0;
 111 
 112                 dai_link->name          = name;
 113                 dai_link->stream_name   = name;
 114         }
 115 
 116         return ret;
 117 }
 118 EXPORT_SYMBOL_GPL(asoc_simple_set_dailink_name);
 119 
 120 int asoc_simple_parse_card_name(struct snd_soc_card *card,
 121                                 char *prefix)
 122 {
 123         int ret;
 124 
 125         if (!prefix)
 126                 prefix = "";
 127 
 128         /* Parse the card name from DT */
 129         ret = snd_soc_of_parse_card_name(card, "label");
 130         if (ret < 0 || !card->name) {
 131                 char prop[128];
 132 
 133                 snprintf(prop, sizeof(prop), "%sname", prefix);
 134                 ret = snd_soc_of_parse_card_name(card, prop);
 135                 if (ret < 0)
 136                         return ret;
 137         }
 138 
 139         if (!card->name && card->dai_link)
 140                 card->name = card->dai_link->name;
 141 
 142         return 0;
 143 }
 144 EXPORT_SYMBOL_GPL(asoc_simple_parse_card_name);
 145 
 146 static int asoc_simple_clk_enable(struct asoc_simple_dai *dai)
 147 {
 148         if (dai)
 149                 return clk_prepare_enable(dai->clk);
 150 
 151         return 0;
 152 }
 153 
 154 static void asoc_simple_clk_disable(struct asoc_simple_dai *dai)
 155 {
 156         if (dai)
 157                 clk_disable_unprepare(dai->clk);
 158 }
 159 
 160 int asoc_simple_parse_clk(struct device *dev,
 161                           struct device_node *node,
 162                           struct asoc_simple_dai *simple_dai,
 163                           struct snd_soc_dai_link_component *dlc)
 164 {
 165         struct clk *clk;
 166         u32 val;
 167 
 168         /*
 169          * Parse dai->sysclk come from "clocks = <&xxx>"
 170          * (if system has common clock)
 171          *  or "system-clock-frequency = <xxx>"
 172          *  or device's module clock.
 173          */
 174         clk = devm_get_clk_from_child(dev, node, NULL);
 175         if (!IS_ERR(clk)) {
 176                 simple_dai->sysclk = clk_get_rate(clk);
 177 
 178                 simple_dai->clk = clk;
 179         } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
 180                 simple_dai->sysclk = val;
 181         } else {
 182                 clk = devm_get_clk_from_child(dev, dlc->of_node, NULL);
 183                 if (!IS_ERR(clk))
 184                         simple_dai->sysclk = clk_get_rate(clk);
 185         }
 186 
 187         if (of_property_read_bool(node, "system-clock-direction-out"))
 188                 simple_dai->clk_direction = SND_SOC_CLOCK_OUT;
 189 
 190         return 0;
 191 }
 192 EXPORT_SYMBOL_GPL(asoc_simple_parse_clk);
 193 
 194 int asoc_simple_startup(struct snd_pcm_substream *substream)
 195 {
 196         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 197         struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 198         struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
 199         int ret;
 200 
 201         ret = asoc_simple_clk_enable(dai_props->cpu_dai);
 202         if (ret)
 203                 return ret;
 204 
 205         ret = asoc_simple_clk_enable(dai_props->codec_dai);
 206         if (ret)
 207                 asoc_simple_clk_disable(dai_props->cpu_dai);
 208 
 209         return ret;
 210 }
 211 EXPORT_SYMBOL_GPL(asoc_simple_startup);
 212 
 213 void asoc_simple_shutdown(struct snd_pcm_substream *substream)
 214 {
 215         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 216         struct snd_soc_dai *codec_dai = rtd->codec_dai;
 217         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 218         struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 219         struct simple_dai_props *dai_props =
 220                 simple_priv_to_props(priv, rtd->num);
 221 
 222         if (dai_props->mclk_fs) {
 223                 snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
 224                 snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
 225         }
 226 
 227         asoc_simple_clk_disable(dai_props->cpu_dai);
 228 
 229         asoc_simple_clk_disable(dai_props->codec_dai);
 230 }
 231 EXPORT_SYMBOL_GPL(asoc_simple_shutdown);
 232 
 233 static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai,
 234                                     unsigned long rate)
 235 {
 236         if (!simple_dai)
 237                 return 0;
 238 
 239         if (!simple_dai->clk)
 240                 return 0;
 241 
 242         if (clk_get_rate(simple_dai->clk) == rate)
 243                 return 0;
 244 
 245         return clk_set_rate(simple_dai->clk, rate);
 246 }
 247 
 248 int asoc_simple_hw_params(struct snd_pcm_substream *substream,
 249                           struct snd_pcm_hw_params *params)
 250 {
 251         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 252         struct snd_soc_dai *codec_dai = rtd->codec_dai;
 253         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 254         struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 255         struct simple_dai_props *dai_props =
 256                 simple_priv_to_props(priv, rtd->num);
 257         unsigned int mclk, mclk_fs = 0;
 258         int ret = 0;
 259 
 260         if (dai_props->mclk_fs)
 261                 mclk_fs = dai_props->mclk_fs;
 262 
 263         if (mclk_fs) {
 264                 mclk = params_rate(params) * mclk_fs;
 265 
 266                 ret = asoc_simple_set_clk_rate(dai_props->codec_dai, mclk);
 267                 if (ret < 0)
 268                         return ret;
 269 
 270                 ret = asoc_simple_set_clk_rate(dai_props->cpu_dai, mclk);
 271                 if (ret < 0)
 272                         return ret;
 273 
 274                 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
 275                                              SND_SOC_CLOCK_IN);
 276                 if (ret && ret != -ENOTSUPP)
 277                         goto err;
 278 
 279                 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
 280                                              SND_SOC_CLOCK_OUT);
 281                 if (ret && ret != -ENOTSUPP)
 282                         goto err;
 283         }
 284         return 0;
 285 err:
 286         return ret;
 287 }
 288 EXPORT_SYMBOL_GPL(asoc_simple_hw_params);
 289 
 290 int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 291                                    struct snd_pcm_hw_params *params)
 292 {
 293         struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 294         struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
 295 
 296         asoc_simple_convert_fixup(&dai_props->adata, params);
 297 
 298         return 0;
 299 }
 300 EXPORT_SYMBOL_GPL(asoc_simple_be_hw_params_fixup);
 301 
 302 static int asoc_simple_init_dai(struct snd_soc_dai *dai,
 303                                      struct asoc_simple_dai *simple_dai)
 304 {
 305         int ret;
 306 
 307         if (!simple_dai)
 308                 return 0;
 309 
 310         if (simple_dai->sysclk) {
 311                 ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk,
 312                                              simple_dai->clk_direction);
 313                 if (ret && ret != -ENOTSUPP) {
 314                         dev_err(dai->dev, "simple-card: set_sysclk error\n");
 315                         return ret;
 316                 }
 317         }
 318 
 319         if (simple_dai->slots) {
 320                 ret = snd_soc_dai_set_tdm_slot(dai,
 321                                                simple_dai->tx_slot_mask,
 322                                                simple_dai->rx_slot_mask,
 323                                                simple_dai->slots,
 324                                                simple_dai->slot_width);
 325                 if (ret && ret != -ENOTSUPP) {
 326                         dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
 327                         return ret;
 328                 }
 329         }
 330 
 331         return 0;
 332 }
 333 
 334 int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd)
 335 {
 336         struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 337         struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
 338         int ret;
 339 
 340         ret = asoc_simple_init_dai(rtd->codec_dai,
 341                                    dai_props->codec_dai);
 342         if (ret < 0)
 343                 return ret;
 344 
 345         ret = asoc_simple_init_dai(rtd->cpu_dai,
 346                                    dai_props->cpu_dai);
 347         if (ret < 0)
 348                 return ret;
 349 
 350         return 0;
 351 }
 352 EXPORT_SYMBOL_GPL(asoc_simple_dai_init);
 353 
 354 void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link)
 355 {
 356         /* Assumes platform == cpu */
 357         if (!dai_link->platforms->of_node)
 358                 dai_link->platforms->of_node = dai_link->cpus->of_node;
 359 
 360         /*
 361          * DPCM BE can be no platform.
 362          * Alloced memory will be waste, but not leak.
 363          */
 364         if (!dai_link->platforms->of_node)
 365                 dai_link->num_platforms = 0;
 366 }
 367 EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_platform);
 368 
 369 void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
 370                                   int is_single_links)
 371 {
 372         /*
 373          * In soc_bind_dai_link() will check cpu name after
 374          * of_node matching if dai_link has cpu_dai_name.
 375          * but, it will never match if name was created by
 376          * fmt_single_name() remove cpu_dai_name if cpu_args
 377          * was 0. See:
 378          *      fmt_single_name()
 379          *      fmt_multiple_name()
 380          */
 381         if (is_single_links)
 382                 dai_link->cpus->dai_name = NULL;
 383 }
 384 EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_cpu);
 385 
 386 int asoc_simple_clean_reference(struct snd_soc_card *card)
 387 {
 388         struct snd_soc_dai_link *dai_link;
 389         int i;
 390 
 391         for_each_card_prelinks(card, i, dai_link) {
 392                 of_node_put(dai_link->cpus->of_node);
 393                 of_node_put(dai_link->codecs->of_node);
 394         }
 395         return 0;
 396 }
 397 EXPORT_SYMBOL_GPL(asoc_simple_clean_reference);
 398 
 399 int asoc_simple_parse_routing(struct snd_soc_card *card,
 400                               char *prefix)
 401 {
 402         struct device_node *node = card->dev->of_node;
 403         char prop[128];
 404 
 405         if (!prefix)
 406                 prefix = "";
 407 
 408         snprintf(prop, sizeof(prop), "%s%s", prefix, "routing");
 409 
 410         if (!of_property_read_bool(node, prop))
 411                 return 0;
 412 
 413         return snd_soc_of_parse_audio_routing(card, prop);
 414 }
 415 EXPORT_SYMBOL_GPL(asoc_simple_parse_routing);
 416 
 417 int asoc_simple_parse_widgets(struct snd_soc_card *card,
 418                               char *prefix)
 419 {
 420         struct device_node *node = card->dev->of_node;
 421         char prop[128];
 422 
 423         if (!prefix)
 424                 prefix = "";
 425 
 426         snprintf(prop, sizeof(prop), "%s%s", prefix, "widgets");
 427 
 428         if (of_property_read_bool(node, prop))
 429                 return snd_soc_of_parse_audio_simple_widgets(card, prop);
 430 
 431         /* no widgets is not error */
 432         return 0;
 433 }
 434 EXPORT_SYMBOL_GPL(asoc_simple_parse_widgets);
 435 
 436 int asoc_simple_parse_pin_switches(struct snd_soc_card *card,
 437                                    char *prefix)
 438 {
 439         const unsigned int nb_controls_max = 16;
 440         const char **strings, *control_name;
 441         struct snd_kcontrol_new *controls;
 442         struct device *dev = card->dev;
 443         unsigned int i, nb_controls;
 444         char prop[128];
 445         int ret;
 446 
 447         if (!prefix)
 448                 prefix = "";
 449 
 450         snprintf(prop, sizeof(prop), "%s%s", prefix, "pin-switches");
 451 
 452         if (!of_property_read_bool(dev->of_node, prop))
 453                 return 0;
 454 
 455         strings = devm_kcalloc(dev, nb_controls_max,
 456                                sizeof(*strings), GFP_KERNEL);
 457         if (!strings)
 458                 return -ENOMEM;
 459 
 460         ret = of_property_read_string_array(dev->of_node, prop,
 461                                             strings, nb_controls_max);
 462         if (ret < 0)
 463                 return ret;
 464 
 465         nb_controls = (unsigned int)ret;
 466 
 467         controls = devm_kcalloc(dev, nb_controls,
 468                                 sizeof(*controls), GFP_KERNEL);
 469         if (!controls)
 470                 return -ENOMEM;
 471 
 472         for (i = 0; i < nb_controls; i++) {
 473                 control_name = devm_kasprintf(dev, GFP_KERNEL,
 474                                               "%s Switch", strings[i]);
 475                 if (!control_name)
 476                         return -ENOMEM;
 477 
 478                 controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 479                 controls[i].name = control_name;
 480                 controls[i].info = snd_soc_dapm_info_pin_switch;
 481                 controls[i].get = snd_soc_dapm_get_pin_switch;
 482                 controls[i].put = snd_soc_dapm_put_pin_switch;
 483                 controls[i].private_value = (unsigned long)strings[i];
 484         }
 485 
 486         card->controls = controls;
 487         card->num_controls = nb_controls;
 488 
 489         return 0;
 490 }
 491 EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches);
 492 
 493 int asoc_simple_init_jack(struct snd_soc_card *card,
 494                           struct asoc_simple_jack *sjack,
 495                           int is_hp, char *prefix)
 496 {
 497         struct device *dev = card->dev;
 498         enum of_gpio_flags flags;
 499         char prop[128];
 500         char *pin_name;
 501         char *gpio_name;
 502         int mask;
 503         int det;
 504 
 505         if (!prefix)
 506                 prefix = "";
 507 
 508         sjack->gpio.gpio = -ENOENT;
 509 
 510         if (is_hp) {
 511                 snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
 512                 pin_name        = "Headphones";
 513                 gpio_name       = "Headphone detection";
 514                 mask            = SND_JACK_HEADPHONE;
 515         } else {
 516                 snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
 517                 pin_name        = "Mic Jack";
 518                 gpio_name       = "Mic detection";
 519                 mask            = SND_JACK_MICROPHONE;
 520         }
 521 
 522         det = of_get_named_gpio_flags(dev->of_node, prop, 0, &flags);
 523         if (det == -EPROBE_DEFER)
 524                 return -EPROBE_DEFER;
 525 
 526         if (gpio_is_valid(det)) {
 527                 sjack->pin.pin          = pin_name;
 528                 sjack->pin.mask         = mask;
 529 
 530                 sjack->gpio.name        = gpio_name;
 531                 sjack->gpio.report      = mask;
 532                 sjack->gpio.gpio        = det;
 533                 sjack->gpio.invert      = !!(flags & OF_GPIO_ACTIVE_LOW);
 534                 sjack->gpio.debounce_time = 150;
 535 
 536                 snd_soc_card_jack_new(card, pin_name, mask,
 537                                       &sjack->jack,
 538                                       &sjack->pin, 1);
 539 
 540                 snd_soc_jack_add_gpios(&sjack->jack, 1,
 541                                        &sjack->gpio);
 542         }
 543 
 544         return 0;
 545 }
 546 EXPORT_SYMBOL_GPL(asoc_simple_init_jack);
 547 
 548 int asoc_simple_init_priv(struct asoc_simple_priv *priv,
 549                           struct link_info *li)
 550 {
 551         struct snd_soc_card *card = simple_priv_to_card(priv);
 552         struct device *dev = simple_priv_to_dev(priv);
 553         struct snd_soc_dai_link *dai_link;
 554         struct simple_dai_props *dai_props;
 555         struct asoc_simple_dai *dais;
 556         struct snd_soc_codec_conf *cconf = NULL;
 557         int i;
 558 
 559         dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL);
 560         dai_link  = devm_kcalloc(dev, li->link, sizeof(*dai_link),  GFP_KERNEL);
 561         dais      = devm_kcalloc(dev, li->dais, sizeof(*dais),      GFP_KERNEL);
 562         if (!dai_props || !dai_link || !dais)
 563                 return -ENOMEM;
 564 
 565         if (li->conf) {
 566                 cconf = devm_kcalloc(dev, li->conf, sizeof(*cconf), GFP_KERNEL);
 567                 if (!cconf)
 568                         return -ENOMEM;
 569         }
 570 
 571         /*
 572          * Use snd_soc_dai_link_component instead of legacy style
 573          * It is codec only. but cpu/platform will be supported in the future.
 574          * see
 575          *      soc-core.c :: snd_soc_init_multicodec()
 576          *
 577          * "platform" might be removed
 578          * see
 579          *      simple-card-utils.c :: asoc_simple_canonicalize_platform()
 580          */
 581         for (i = 0; i < li->link; i++) {
 582                 dai_link[i].cpus                = &dai_props[i].cpus;
 583                 dai_link[i].num_cpus            = 1;
 584                 dai_link[i].codecs              = &dai_props[i].codecs;
 585                 dai_link[i].num_codecs          = 1;
 586                 dai_link[i].platforms           = &dai_props[i].platforms;
 587                 dai_link[i].num_platforms       = 1;
 588         }
 589 
 590         priv->dai_props         = dai_props;
 591         priv->dai_link          = dai_link;
 592         priv->dais              = dais;
 593         priv->codec_conf        = cconf;
 594 
 595         card->dai_link          = priv->dai_link;
 596         card->num_links         = li->link;
 597         card->codec_conf        = cconf;
 598         card->num_configs       = li->conf;
 599 
 600         return 0;
 601 }
 602 EXPORT_SYMBOL_GPL(asoc_simple_init_priv);
 603 
 604 /* Module information */
 605 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
 606 MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
 607 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */