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