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