1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // ASoC simple sound card support 4 // 5 // Copyright (C) 2012 Renesas Solutions Corp. 6 // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 7 8 #include <linux/clk.h> 9 #include <linux/device.h> 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/of_platform.h> 13 #include <linux/platform_device.h> 14 #include <linux/string.h> 15 #include <sound/simple_card.h> 16 #include <sound/soc-dai.h> 17 #include <sound/soc.h> 18 19 #define DPCM_SELECTABLE 1 20 21 #define DAI "sound-dai" 22 #define CELL "#sound-dai-cells" 23 #define PREFIX "simple-audio-card," 24 25 static const struct snd_soc_ops simple_ops = { 26 .startup = simple_util_startup, 27 .shutdown = simple_util_shutdown, 28 .hw_params = simple_util_hw_params, 29 }; 30 31 static int simple_parse_platform(struct device_node *node, struct snd_soc_dai_link_component *dlc) 32 { 33 struct of_phandle_args args; 34 int ret; 35 36 if (!node) 37 return 0; 38 39 /* 40 * Get node via "sound-dai = <&phandle port>" 41 * it will be used as xxx_of_node on soc_bind_dai_link() 42 */ 43 ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args); 44 if (ret) 45 return ret; 46 47 /* dai_name is not required and may not exist for plat component */ 48 49 dlc->of_node = args.np; 50 51 return 0; 52 } 53 54 static int simple_parse_dai(struct device *dev, 55 struct device_node *node, 56 struct snd_soc_dai_link_component *dlc, 57 int *is_single_link) 58 { 59 struct of_phandle_args args; 60 struct snd_soc_dai *dai; 61 int ret; 62 63 if (!node) 64 return 0; 65 66 /* 67 * Get node via "sound-dai = <&phandle port>" 68 * it will be used as xxx_of_node on soc_bind_dai_link() 69 */ 70 ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args); 71 if (ret) 72 return ret; 73 74 /* 75 * Try to find from DAI args 76 */ 77 dai = snd_soc_get_dai_via_args(&args); 78 if (dai) { 79 dlc->dai_name = snd_soc_dai_name_get(dai); 80 dlc->dai_args = snd_soc_copy_dai_args(dev, &args); 81 if (!dlc->dai_args) 82 return -ENOMEM; 83 84 goto parse_dai_end; 85 } 86 87 /* 88 * FIXME 89 * 90 * Here, dlc->dai_name is pointer to CPU/Codec DAI name. 91 * If user unbinded CPU or Codec driver, but not for Sound Card, 92 * dlc->dai_name is keeping unbinded CPU or Codec 93 * driver's pointer. 94 * 95 * If user re-bind CPU or Codec driver again, ALSA SoC will try 96 * to rebind Card via snd_soc_try_rebind_card(), but because of 97 * above reason, it might can't bind Sound Card. 98 * Because Sound Card is pointing to released dai_name pointer. 99 * 100 * To avoid this rebind Card issue, 101 * 1) It needs to alloc memory to keep dai_name eventhough 102 * CPU or Codec driver was unbinded, or 103 * 2) user need to rebind Sound Card everytime 104 * if he unbinded CPU or Codec. 105 */ 106 ret = snd_soc_get_dlc(&args, dlc); 107 if (ret < 0) 108 return ret; 109 110 parse_dai_end: 111 if (is_single_link) 112 *is_single_link = !args.args_count; 113 114 return 0; 115 } 116 117 static void simple_parse_convert(struct device *dev, 118 struct device_node *np, 119 struct simple_util_data *adata) 120 { 121 struct device_node *top = dev->of_node; 122 struct device_node *node = of_get_parent(np); 123 124 simple_util_parse_convert(top, PREFIX, adata); 125 simple_util_parse_convert(node, PREFIX, adata); 126 simple_util_parse_convert(node, NULL, adata); 127 simple_util_parse_convert(np, NULL, adata); 128 129 of_node_put(node); 130 } 131 132 static void simple_parse_mclk_fs(struct device_node *top, 133 struct device_node *np, 134 struct simple_dai_props *props, 135 char *prefix) 136 { 137 struct device_node *node = of_get_parent(np); 138 char prop[128]; 139 140 snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX); 141 of_property_read_u32(top, prop, &props->mclk_fs); 142 143 snprintf(prop, sizeof(prop), "%smclk-fs", prefix); 144 of_property_read_u32(node, prop, &props->mclk_fs); 145 of_property_read_u32(np, prop, &props->mclk_fs); 146 147 of_node_put(node); 148 } 149 150 static int simple_parse_node(struct simple_util_priv *priv, 151 struct device_node *np, 152 struct link_info *li, 153 char *prefix, 154 int *cpu) 155 { 156 struct device *dev = simple_priv_to_dev(priv); 157 struct device_node *top = dev->of_node; 158 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 159 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 160 struct snd_soc_dai_link_component *dlc; 161 struct simple_util_dai *dai; 162 int ret; 163 164 if (cpu) { 165 dlc = snd_soc_link_to_cpu(dai_link, 0); 166 dai = simple_props_to_dai_cpu(dai_props, 0); 167 } else { 168 dlc = snd_soc_link_to_codec(dai_link, 0); 169 dai = simple_props_to_dai_codec(dai_props, 0); 170 } 171 172 simple_parse_mclk_fs(top, np, dai_props, prefix); 173 174 ret = simple_parse_dai(dev, np, dlc, cpu); 175 if (ret) 176 return ret; 177 178 ret = simple_util_parse_clk(dev, np, dai, dlc); 179 if (ret) 180 return ret; 181 182 ret = simple_util_parse_tdm(np, dai); 183 if (ret) 184 return ret; 185 186 return 0; 187 } 188 189 static int simple_link_init(struct simple_util_priv *priv, 190 struct device_node *node, 191 struct device_node *codec, 192 struct link_info *li, 193 char *prefix, char *name) 194 { 195 struct device *dev = simple_priv_to_dev(priv); 196 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 197 int ret; 198 199 ret = simple_util_parse_daifmt(dev, node, codec, 200 prefix, &dai_link->dai_fmt); 201 if (ret < 0) 202 return 0; 203 204 dai_link->init = simple_util_dai_init; 205 dai_link->ops = &simple_ops; 206 207 return simple_util_set_dailink_name(dev, dai_link, name); 208 } 209 210 static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, 211 struct device_node *np, 212 struct device_node *codec, 213 struct link_info *li, 214 bool is_top) 215 { 216 struct device *dev = simple_priv_to_dev(priv); 217 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 218 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 219 struct device_node *top = dev->of_node; 220 struct device_node *node = of_get_parent(np); 221 char *prefix = ""; 222 char dai_name[64]; 223 int ret; 224 225 dev_dbg(dev, "link_of DPCM (%pOF)\n", np); 226 227 /* For single DAI link & old style of DT node */ 228 if (is_top) 229 prefix = PREFIX; 230 231 if (li->cpu) { 232 struct snd_soc_dai_link_component *cpus = snd_soc_link_to_cpu(dai_link, 0); 233 struct snd_soc_dai_link_component *platforms = snd_soc_link_to_platform(dai_link, 0); 234 int is_single_links = 0; 235 236 /* Codec is dummy */ 237 238 /* FE settings */ 239 dai_link->dynamic = 1; 240 dai_link->dpcm_merged_format = 1; 241 242 ret = simple_parse_node(priv, np, li, prefix, &is_single_links); 243 if (ret < 0) 244 goto out_put_node; 245 246 snprintf(dai_name, sizeof(dai_name), "fe.%s", cpus->dai_name); 247 248 simple_util_canonicalize_cpu(cpus, is_single_links); 249 simple_util_canonicalize_platform(platforms, cpus); 250 } else { 251 struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, 0); 252 struct snd_soc_codec_conf *cconf; 253 254 /* CPU is dummy */ 255 256 /* BE settings */ 257 dai_link->no_pcm = 1; 258 dai_link->be_hw_params_fixup = simple_util_be_hw_params_fixup; 259 260 cconf = simple_props_to_codec_conf(dai_props, 0); 261 262 ret = simple_parse_node(priv, np, li, prefix, NULL); 263 if (ret < 0) 264 goto out_put_node; 265 266 snprintf(dai_name, sizeof(dai_name), "be.%s", codecs->dai_name); 267 268 /* check "prefix" from top node */ 269 snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, 270 PREFIX "prefix"); 271 snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node, 272 "prefix"); 273 snd_soc_of_parse_node_prefix(np, cconf, codecs->of_node, 274 "prefix"); 275 } 276 277 simple_parse_convert(dev, np, &dai_props->adata); 278 279 snd_soc_dai_link_set_capabilities(dai_link); 280 281 ret = simple_link_init(priv, node, codec, li, prefix, dai_name); 282 283 out_put_node: 284 li->link++; 285 286 of_node_put(node); 287 return ret; 288 } 289 290 static int simple_dai_link_of(struct simple_util_priv *priv, 291 struct device_node *np, 292 struct device_node *codec, 293 struct link_info *li, 294 bool is_top) 295 { 296 struct device *dev = simple_priv_to_dev(priv); 297 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 298 struct snd_soc_dai_link_component *cpus = snd_soc_link_to_cpu(dai_link, 0); 299 struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, 0); 300 struct snd_soc_dai_link_component *platforms = snd_soc_link_to_platform(dai_link, 0); 301 struct device_node *cpu = NULL; 302 struct device_node *node = NULL; 303 struct device_node *plat = NULL; 304 char dai_name[64]; 305 char prop[128]; 306 char *prefix = ""; 307 int ret, single_cpu = 0; 308 309 cpu = np; 310 node = of_get_parent(np); 311 312 dev_dbg(dev, "link_of (%pOF)\n", node); 313 314 /* For single DAI link & old style of DT node */ 315 if (is_top) 316 prefix = PREFIX; 317 318 snprintf(prop, sizeof(prop), "%splat", prefix); 319 plat = of_get_child_by_name(node, prop); 320 321 ret = simple_parse_node(priv, cpu, li, prefix, &single_cpu); 322 if (ret < 0) 323 goto dai_link_of_err; 324 325 ret = simple_parse_node(priv, codec, li, prefix, NULL); 326 if (ret < 0) 327 goto dai_link_of_err; 328 329 ret = simple_parse_platform(plat, platforms); 330 if (ret < 0) 331 goto dai_link_of_err; 332 333 snprintf(dai_name, sizeof(dai_name), 334 "%s-%s", cpus->dai_name, codecs->dai_name); 335 336 simple_util_canonicalize_cpu(cpus, single_cpu); 337 simple_util_canonicalize_platform(platforms, cpus); 338 339 ret = simple_link_init(priv, node, codec, li, prefix, dai_name); 340 341 dai_link_of_err: 342 of_node_put(plat); 343 of_node_put(node); 344 345 li->link++; 346 347 return ret; 348 } 349 350 static int __simple_for_each_link(struct simple_util_priv *priv, 351 struct link_info *li, 352 int (*func_noml)(struct simple_util_priv *priv, 353 struct device_node *np, 354 struct device_node *codec, 355 struct link_info *li, bool is_top), 356 int (*func_dpcm)(struct simple_util_priv *priv, 357 struct device_node *np, 358 struct device_node *codec, 359 struct link_info *li, bool is_top)) 360 { 361 struct device *dev = simple_priv_to_dev(priv); 362 struct device_node *top = dev->of_node; 363 struct device_node *node; 364 struct device_node *add_devs; 365 uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); 366 bool is_top = 0; 367 int ret = 0; 368 369 /* Check if it has dai-link */ 370 node = of_get_child_by_name(top, PREFIX "dai-link"); 371 if (!node) { 372 node = of_node_get(top); 373 is_top = 1; 374 } 375 376 add_devs = of_get_child_by_name(top, PREFIX "additional-devs"); 377 378 /* loop for all dai-link */ 379 do { 380 struct simple_util_data adata; 381 struct device_node *codec; 382 struct device_node *plat; 383 struct device_node *np; 384 int num = of_get_child_count(node); 385 386 /* Skip additional-devs node */ 387 if (node == add_devs) { 388 node = of_get_next_child(top, node); 389 continue; 390 } 391 392 /* get codec */ 393 codec = of_get_child_by_name(node, is_top ? 394 PREFIX "codec" : "codec"); 395 if (!codec) { 396 ret = -ENODEV; 397 goto error; 398 } 399 /* get platform */ 400 plat = of_get_child_by_name(node, is_top ? 401 PREFIX "plat" : "plat"); 402 403 /* get convert-xxx property */ 404 memset(&adata, 0, sizeof(adata)); 405 for_each_child_of_node(node, np) { 406 if (np == add_devs) 407 continue; 408 simple_parse_convert(dev, np, &adata); 409 } 410 411 /* loop for all CPU/Codec node */ 412 for_each_child_of_node(node, np) { 413 if (plat == np || add_devs == np) 414 continue; 415 /* 416 * It is DPCM 417 * if it has many CPUs, 418 * or has convert-xxx property 419 */ 420 if (dpcm_selectable && 421 (num > 2 || simple_util_is_convert_required(&adata))) { 422 /* 423 * np 424 * |1(CPU)|0(Codec) li->cpu 425 * CPU |Pass |return 426 * Codec |return|Pass 427 */ 428 if (li->cpu != (np == codec)) 429 ret = func_dpcm(priv, np, codec, li, is_top); 430 /* else normal sound */ 431 } else { 432 /* 433 * np 434 * |1(CPU)|0(Codec) li->cpu 435 * CPU |Pass |return 436 * Codec |return|return 437 */ 438 if (li->cpu && (np != codec)) 439 ret = func_noml(priv, np, codec, li, is_top); 440 } 441 442 if (ret < 0) { 443 of_node_put(codec); 444 of_node_put(plat); 445 of_node_put(np); 446 goto error; 447 } 448 } 449 450 of_node_put(codec); 451 of_node_put(plat); 452 node = of_get_next_child(top, node); 453 } while (!is_top && node); 454 455 error: 456 of_node_put(add_devs); 457 of_node_put(node); 458 return ret; 459 } 460 461 static int simple_for_each_link(struct simple_util_priv *priv, 462 struct link_info *li, 463 int (*func_noml)(struct simple_util_priv *priv, 464 struct device_node *np, 465 struct device_node *codec, 466 struct link_info *li, bool is_top), 467 int (*func_dpcm)(struct simple_util_priv *priv, 468 struct device_node *np, 469 struct device_node *codec, 470 struct link_info *li, bool is_top)) 471 { 472 int ret; 473 /* 474 * Detect all CPU first, and Detect all Codec 2nd. 475 * 476 * In Normal sound case, all DAIs are detected 477 * as "CPU-Codec". 478 * 479 * In DPCM sound case, 480 * all CPUs are detected as "CPU-dummy", and 481 * all Codecs are detected as "dummy-Codec". 482 * To avoid random sub-device numbering, 483 * detect "dummy-Codec" in last; 484 */ 485 for (li->cpu = 1; li->cpu >= 0; li->cpu--) { 486 ret = __simple_for_each_link(priv, li, func_noml, func_dpcm); 487 if (ret < 0) 488 break; 489 } 490 491 return ret; 492 } 493 494 static void simple_depopulate_aux(void *data) 495 { 496 struct simple_util_priv *priv = data; 497 498 of_platform_depopulate(simple_priv_to_dev(priv)); 499 } 500 501 static int simple_populate_aux(struct simple_util_priv *priv) 502 { 503 struct device *dev = simple_priv_to_dev(priv); 504 struct device_node *node; 505 int ret; 506 507 node = of_get_child_by_name(dev->of_node, PREFIX "additional-devs"); 508 if (!node) 509 return 0; 510 511 ret = of_platform_populate(node, NULL, NULL, dev); 512 of_node_put(node); 513 if (ret) 514 return ret; 515 516 return devm_add_action_or_reset(dev, simple_depopulate_aux, priv); 517 } 518 519 static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li) 520 { 521 struct snd_soc_card *card = simple_priv_to_card(priv); 522 int ret; 523 524 ret = simple_util_parse_widgets(card, PREFIX); 525 if (ret < 0) 526 return ret; 527 528 ret = simple_util_parse_routing(card, PREFIX); 529 if (ret < 0) 530 return ret; 531 532 ret = simple_util_parse_pin_switches(card, PREFIX); 533 if (ret < 0) 534 return ret; 535 536 /* Single/Muti DAI link(s) & New style of DT node */ 537 memset(li, 0, sizeof(*li)); 538 ret = simple_for_each_link(priv, li, 539 simple_dai_link_of, 540 simple_dai_link_of_dpcm); 541 if (ret < 0) 542 return ret; 543 544 ret = simple_util_parse_card_name(card, PREFIX); 545 if (ret < 0) 546 return ret; 547 548 ret = simple_populate_aux(priv); 549 if (ret < 0) 550 return ret; 551 552 ret = snd_soc_of_parse_aux_devs(card, PREFIX "aux-devs"); 553 554 return ret; 555 } 556 557 static int simple_count_noml(struct simple_util_priv *priv, 558 struct device_node *np, 559 struct device_node *codec, 560 struct link_info *li, bool is_top) 561 { 562 if (li->link >= SNDRV_MAX_LINKS) { 563 struct device *dev = simple_priv_to_dev(priv); 564 565 dev_err(dev, "too many links\n"); 566 return -EINVAL; 567 } 568 569 /* 570 * DON'T REMOVE platforms 571 * 572 * Some CPU might be using soc-generic-dmaengine-pcm. This means CPU and Platform 573 * are different Component, but are sharing same component->dev. 574 * Simple Card had been supported it without special Platform selection. 575 * We need platforms here. 576 * 577 * In case of no Platform, it will be Platform == CPU, but Platform will be 578 * ignored by snd_soc_rtd_add_component(). 579 * 580 * see 581 * simple-card-utils.c :: simple_util_canonicalize_platform() 582 */ 583 li->num[li->link].cpus = 1; 584 li->num[li->link].platforms = 1; 585 586 li->num[li->link].codecs = 1; 587 588 li->link += 1; 589 590 return 0; 591 } 592 593 static int simple_count_dpcm(struct simple_util_priv *priv, 594 struct device_node *np, 595 struct device_node *codec, 596 struct link_info *li, bool is_top) 597 { 598 if (li->link >= SNDRV_MAX_LINKS) { 599 struct device *dev = simple_priv_to_dev(priv); 600 601 dev_err(dev, "too many links\n"); 602 return -EINVAL; 603 } 604 605 if (li->cpu) { 606 /* 607 * DON'T REMOVE platforms 608 * see 609 * simple_count_noml() 610 */ 611 li->num[li->link].cpus = 1; 612 li->num[li->link].platforms = 1; 613 614 li->link++; /* CPU-dummy */ 615 } else { 616 li->num[li->link].codecs = 1; 617 618 li->link++; /* dummy-Codec */ 619 } 620 621 return 0; 622 } 623 624 static int simple_get_dais_count(struct simple_util_priv *priv, 625 struct link_info *li) 626 { 627 struct device *dev = simple_priv_to_dev(priv); 628 struct device_node *top = dev->of_node; 629 630 /* 631 * link_num : number of links. 632 * CPU-Codec / CPU-dummy / dummy-Codec 633 * dais_num : number of DAIs 634 * ccnf_num : number of codec_conf 635 * same number for "dummy-Codec" 636 * 637 * ex1) 638 * CPU0 --- Codec0 link : 5 639 * CPU1 --- Codec1 dais : 7 640 * CPU2 -/ ccnf : 1 641 * CPU3 --- Codec2 642 * 643 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec 644 * => 7 DAIs = 4xCPU + 3xCodec 645 * => 1 ccnf = 1xdummy-Codec 646 * 647 * ex2) 648 * CPU0 --- Codec0 link : 5 649 * CPU1 --- Codec1 dais : 6 650 * CPU2 -/ ccnf : 1 651 * CPU3 -/ 652 * 653 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec 654 * => 6 DAIs = 4xCPU + 2xCodec 655 * => 1 ccnf = 1xdummy-Codec 656 * 657 * ex3) 658 * CPU0 --- Codec0 link : 6 659 * CPU1 -/ dais : 6 660 * CPU2 --- Codec1 ccnf : 2 661 * CPU3 -/ 662 * 663 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec 664 * => 6 DAIs = 4xCPU + 2xCodec 665 * => 2 ccnf = 2xdummy-Codec 666 * 667 * ex4) 668 * CPU0 --- Codec0 (convert-rate) link : 3 669 * CPU1 --- Codec1 dais : 4 670 * ccnf : 1 671 * 672 * => 3 links = 1xCPU-Codec + 1xCPU-dummy + 1xdummy-Codec 673 * => 4 DAIs = 2xCPU + 2xCodec 674 * => 1 ccnf = 1xdummy-Codec 675 */ 676 if (!top) { 677 li->num[0].cpus = 1; 678 li->num[0].codecs = 1; 679 li->num[0].platforms = 1; 680 681 li->link = 1; 682 return 0; 683 } 684 685 return simple_for_each_link(priv, li, 686 simple_count_noml, 687 simple_count_dpcm); 688 } 689 690 static int simple_soc_probe(struct snd_soc_card *card) 691 { 692 struct simple_util_priv *priv = snd_soc_card_get_drvdata(card); 693 int ret; 694 695 ret = simple_util_init_hp(card, &priv->hp_jack, PREFIX); 696 if (ret < 0) 697 return ret; 698 699 ret = simple_util_init_mic(card, &priv->mic_jack, PREFIX); 700 if (ret < 0) 701 return ret; 702 703 ret = simple_util_init_aux_jacks(priv, PREFIX); 704 if (ret < 0) 705 return ret; 706 707 return 0; 708 } 709 710 static int simple_probe(struct platform_device *pdev) 711 { 712 struct simple_util_priv *priv; 713 struct device *dev = &pdev->dev; 714 struct device_node *np = dev->of_node; 715 struct snd_soc_card *card; 716 struct link_info *li; 717 int ret; 718 719 /* Allocate the private data and the DAI link array */ 720 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 721 if (!priv) 722 return -ENOMEM; 723 724 card = simple_priv_to_card(priv); 725 card->owner = THIS_MODULE; 726 card->dev = dev; 727 card->probe = simple_soc_probe; 728 card->driver_name = "simple-card"; 729 730 li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); 731 if (!li) 732 return -ENOMEM; 733 734 ret = simple_get_dais_count(priv, li); 735 if (ret < 0) 736 return ret; 737 738 if (!li->link) 739 return -EINVAL; 740 741 ret = simple_util_init_priv(priv, li); 742 if (ret < 0) 743 return ret; 744 745 if (np && of_device_is_available(np)) { 746 747 ret = simple_parse_of(priv, li); 748 if (ret < 0) { 749 dev_err_probe(dev, ret, "parse error\n"); 750 goto err; 751 } 752 753 } else { 754 struct simple_util_info *cinfo; 755 struct snd_soc_dai_link_component *cpus; 756 struct snd_soc_dai_link_component *codecs; 757 struct snd_soc_dai_link_component *platform; 758 struct snd_soc_dai_link *dai_link = priv->dai_link; 759 struct simple_dai_props *dai_props = priv->dai_props; 760 761 ret = -EINVAL; 762 763 cinfo = dev->platform_data; 764 if (!cinfo) { 765 dev_err(dev, "no info for asoc-simple-card\n"); 766 goto err; 767 } 768 769 if (!cinfo->name || 770 !cinfo->codec_dai.name || 771 !cinfo->codec || 772 !cinfo->platform || 773 !cinfo->cpu_dai.name) { 774 dev_err(dev, "insufficient simple_util_info settings\n"); 775 goto err; 776 } 777 778 cpus = dai_link->cpus; 779 cpus->dai_name = cinfo->cpu_dai.name; 780 781 codecs = dai_link->codecs; 782 codecs->name = cinfo->codec; 783 codecs->dai_name = cinfo->codec_dai.name; 784 785 platform = dai_link->platforms; 786 platform->name = cinfo->platform; 787 788 card->name = (cinfo->card) ? cinfo->card : cinfo->name; 789 dai_link->name = cinfo->name; 790 dai_link->stream_name = cinfo->name; 791 dai_link->dai_fmt = cinfo->daifmt; 792 dai_link->init = simple_util_dai_init; 793 memcpy(dai_props->cpu_dai, &cinfo->cpu_dai, 794 sizeof(*dai_props->cpu_dai)); 795 memcpy(dai_props->codec_dai, &cinfo->codec_dai, 796 sizeof(*dai_props->codec_dai)); 797 } 798 799 snd_soc_card_set_drvdata(card, priv); 800 801 simple_util_debug_info(priv); 802 803 ret = devm_snd_soc_register_card(dev, card); 804 if (ret < 0) 805 goto err; 806 807 devm_kfree(dev, li); 808 return 0; 809 err: 810 simple_util_clean_reference(card); 811 812 return ret; 813 } 814 815 static const struct of_device_id simple_of_match[] = { 816 { .compatible = "simple-audio-card", }, 817 { .compatible = "simple-scu-audio-card", 818 .data = (void *)DPCM_SELECTABLE }, 819 {}, 820 }; 821 MODULE_DEVICE_TABLE(of, simple_of_match); 822 823 static struct platform_driver simple_card = { 824 .driver = { 825 .name = "asoc-simple-card", 826 .pm = &snd_soc_pm_ops, 827 .of_match_table = simple_of_match, 828 }, 829 .probe = simple_probe, 830 .remove_new = simple_util_remove, 831 }; 832 833 module_platform_driver(simple_card); 834 835 MODULE_ALIAS("platform:asoc-simple-card"); 836 MODULE_LICENSE("GPL v2"); 837 MODULE_DESCRIPTION("ASoC Simple Sound Card"); 838 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 839