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 ret = simple_link_init(priv, np, codec, li, prefix, dai_name); 295 296 out_put_node: 297 li->link++; 298 299 of_node_put(node); 300 return ret; 301 } 302 303 static int simple_dai_link_of(struct simple_util_priv *priv, 304 struct device_node *np, 305 struct device_node *codec, 306 struct link_info *li, 307 bool is_top) 308 { 309 struct device *dev = simple_priv_to_dev(priv); 310 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 311 struct snd_soc_dai_link_component *cpus = snd_soc_link_to_cpu(dai_link, 0); 312 struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, 0); 313 struct snd_soc_dai_link_component *platforms = snd_soc_link_to_platform(dai_link, 0); 314 struct device_node *cpu = NULL; 315 struct device_node *node = NULL; 316 struct device_node *plat = NULL; 317 char dai_name[64]; 318 char prop[128]; 319 char *prefix = ""; 320 int ret, single_cpu = 0; 321 322 cpu = np; 323 node = of_get_parent(np); 324 325 dev_dbg(dev, "link_of (%pOF)\n", node); 326 327 /* For single DAI link & old style of DT node */ 328 if (is_top) 329 prefix = PREFIX; 330 331 snprintf(prop, sizeof(prop), "%splat", prefix); 332 plat = of_get_child_by_name(node, prop); 333 334 ret = simple_parse_node(priv, cpu, li, prefix, &single_cpu); 335 if (ret < 0) 336 goto dai_link_of_err; 337 338 ret = simple_parse_node(priv, codec, li, prefix, NULL); 339 if (ret < 0) 340 goto dai_link_of_err; 341 342 ret = simple_parse_platform(plat, platforms); 343 if (ret < 0) 344 goto dai_link_of_err; 345 346 snprintf(dai_name, sizeof(dai_name), 347 "%s-%s", cpus->dai_name, codecs->dai_name); 348 349 simple_util_canonicalize_cpu(cpus, single_cpu); 350 simple_util_canonicalize_platform(platforms, cpus); 351 352 ret = simple_link_init(priv, cpu, codec, li, prefix, dai_name); 353 354 dai_link_of_err: 355 of_node_put(plat); 356 of_node_put(node); 357 358 li->link++; 359 360 return ret; 361 } 362 363 static int __simple_for_each_link(struct simple_util_priv *priv, 364 struct link_info *li, 365 int (*func_noml)(struct simple_util_priv *priv, 366 struct device_node *np, 367 struct device_node *codec, 368 struct link_info *li, bool is_top), 369 int (*func_dpcm)(struct simple_util_priv *priv, 370 struct device_node *np, 371 struct device_node *codec, 372 struct link_info *li, bool is_top)) 373 { 374 struct device *dev = simple_priv_to_dev(priv); 375 struct device_node *top = dev->of_node; 376 struct device_node *node; 377 struct device_node *add_devs; 378 uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); 379 bool is_top = 0; 380 int ret = 0; 381 382 /* Check if it has dai-link */ 383 node = of_get_child_by_name(top, PREFIX "dai-link"); 384 if (!node) { 385 node = of_node_get(top); 386 is_top = 1; 387 } 388 389 add_devs = of_get_child_by_name(top, PREFIX "additional-devs"); 390 391 /* loop for all dai-link */ 392 do { 393 struct simple_util_data adata; 394 struct device_node *codec; 395 struct device_node *plat; 396 struct device_node *np; 397 int num = of_get_child_count(node); 398 399 /* Skip additional-devs node */ 400 if (node == add_devs) { 401 node = of_get_next_child(top, node); 402 continue; 403 } 404 405 /* get codec */ 406 codec = of_get_child_by_name(node, is_top ? 407 PREFIX "codec" : "codec"); 408 if (!codec) { 409 ret = -ENODEV; 410 goto error; 411 } 412 /* get platform */ 413 plat = of_get_child_by_name(node, is_top ? 414 PREFIX "plat" : "plat"); 415 416 /* get convert-xxx property */ 417 memset(&adata, 0, sizeof(adata)); 418 for_each_child_of_node(node, np) { 419 if (np == add_devs) 420 continue; 421 simple_parse_convert(dev, np, &adata); 422 } 423 424 /* loop for all CPU/Codec node */ 425 for_each_child_of_node(node, np) { 426 if (plat == np || add_devs == np) 427 continue; 428 /* 429 * It is DPCM 430 * if it has many CPUs, 431 * or has convert-xxx property 432 */ 433 if (dpcm_selectable && 434 (num > 2 || simple_util_is_convert_required(&adata))) { 435 /* 436 * np 437 * |1(CPU)|0(Codec) li->cpu 438 * CPU |Pass |return 439 * Codec |return|Pass 440 */ 441 if (li->cpu != (np == codec)) 442 ret = func_dpcm(priv, np, codec, li, is_top); 443 /* else normal sound */ 444 } else { 445 /* 446 * np 447 * |1(CPU)|0(Codec) li->cpu 448 * CPU |Pass |return 449 * Codec |return|return 450 */ 451 if (li->cpu && (np != codec)) 452 ret = func_noml(priv, np, codec, li, is_top); 453 } 454 455 if (ret < 0) { 456 of_node_put(codec); 457 of_node_put(plat); 458 of_node_put(np); 459 goto error; 460 } 461 } 462 463 of_node_put(codec); 464 of_node_put(plat); 465 node = of_get_next_child(top, node); 466 } while (!is_top && node); 467 468 error: 469 of_node_put(add_devs); 470 of_node_put(node); 471 return ret; 472 } 473 474 static int simple_for_each_link(struct simple_util_priv *priv, 475 struct link_info *li, 476 int (*func_noml)(struct simple_util_priv *priv, 477 struct device_node *np, 478 struct device_node *codec, 479 struct link_info *li, bool is_top), 480 int (*func_dpcm)(struct simple_util_priv *priv, 481 struct device_node *np, 482 struct device_node *codec, 483 struct link_info *li, bool is_top)) 484 { 485 int ret; 486 /* 487 * Detect all CPU first, and Detect all Codec 2nd. 488 * 489 * In Normal sound case, all DAIs are detected 490 * as "CPU-Codec". 491 * 492 * In DPCM sound case, 493 * all CPUs are detected as "CPU-dummy", and 494 * all Codecs are detected as "dummy-Codec". 495 * To avoid random sub-device numbering, 496 * detect "dummy-Codec" in last; 497 */ 498 for (li->cpu = 1; li->cpu >= 0; li->cpu--) { 499 ret = __simple_for_each_link(priv, li, func_noml, func_dpcm); 500 if (ret < 0) 501 break; 502 } 503 504 return ret; 505 } 506 507 static void simple_depopulate_aux(void *data) 508 { 509 struct simple_util_priv *priv = data; 510 511 of_platform_depopulate(simple_priv_to_dev(priv)); 512 } 513 514 static int simple_populate_aux(struct simple_util_priv *priv) 515 { 516 struct device *dev = simple_priv_to_dev(priv); 517 struct device_node *node; 518 int ret; 519 520 node = of_get_child_by_name(dev->of_node, PREFIX "additional-devs"); 521 if (!node) 522 return 0; 523 524 ret = of_platform_populate(node, NULL, NULL, dev); 525 of_node_put(node); 526 if (ret) 527 return ret; 528 529 return devm_add_action_or_reset(dev, simple_depopulate_aux, priv); 530 } 531 532 static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li) 533 { 534 struct snd_soc_card *card = simple_priv_to_card(priv); 535 int ret; 536 537 ret = simple_util_parse_widgets(card, PREFIX); 538 if (ret < 0) 539 return ret; 540 541 ret = simple_util_parse_routing(card, PREFIX); 542 if (ret < 0) 543 return ret; 544 545 ret = simple_util_parse_pin_switches(card, PREFIX); 546 if (ret < 0) 547 return ret; 548 549 /* Single/Muti DAI link(s) & New style of DT node */ 550 memset(li, 0, sizeof(*li)); 551 ret = simple_for_each_link(priv, li, 552 simple_dai_link_of, 553 simple_dai_link_of_dpcm); 554 if (ret < 0) 555 return ret; 556 557 ret = simple_util_parse_card_name(card, PREFIX); 558 if (ret < 0) 559 return ret; 560 561 ret = simple_populate_aux(priv); 562 if (ret < 0) 563 return ret; 564 565 ret = snd_soc_of_parse_aux_devs(card, PREFIX "aux-devs"); 566 567 return ret; 568 } 569 570 static int simple_count_noml(struct simple_util_priv *priv, 571 struct device_node *np, 572 struct device_node *codec, 573 struct link_info *li, bool is_top) 574 { 575 if (li->link >= SNDRV_MAX_LINKS) { 576 struct device *dev = simple_priv_to_dev(priv); 577 578 dev_err(dev, "too many links\n"); 579 return -EINVAL; 580 } 581 582 /* 583 * DON'T REMOVE platforms 584 * 585 * Some CPU might be using soc-generic-dmaengine-pcm. This means CPU and Platform 586 * are different Component, but are sharing same component->dev. 587 * Simple Card had been supported it without special Platform selection. 588 * We need platforms here. 589 * 590 * In case of no Platform, it will be Platform == CPU, but Platform will be 591 * ignored by snd_soc_rtd_add_component(). 592 * 593 * see 594 * simple-card-utils.c :: simple_util_canonicalize_platform() 595 */ 596 li->num[li->link].cpus = 1; 597 li->num[li->link].platforms = 1; 598 599 li->num[li->link].codecs = 1; 600 601 li->link += 1; 602 603 return 0; 604 } 605 606 static int simple_count_dpcm(struct simple_util_priv *priv, 607 struct device_node *np, 608 struct device_node *codec, 609 struct link_info *li, bool is_top) 610 { 611 if (li->link >= SNDRV_MAX_LINKS) { 612 struct device *dev = simple_priv_to_dev(priv); 613 614 dev_err(dev, "too many links\n"); 615 return -EINVAL; 616 } 617 618 if (li->cpu) { 619 /* 620 * DON'T REMOVE platforms 621 * see 622 * simple_count_noml() 623 */ 624 li->num[li->link].cpus = 1; 625 li->num[li->link].platforms = 1; 626 627 li->link++; /* CPU-dummy */ 628 } else { 629 li->num[li->link].codecs = 1; 630 631 li->link++; /* dummy-Codec */ 632 } 633 634 return 0; 635 } 636 637 static int simple_get_dais_count(struct simple_util_priv *priv, 638 struct link_info *li) 639 { 640 struct device *dev = simple_priv_to_dev(priv); 641 struct device_node *top = dev->of_node; 642 643 /* 644 * link_num : number of links. 645 * CPU-Codec / CPU-dummy / dummy-Codec 646 * dais_num : number of DAIs 647 * ccnf_num : number of codec_conf 648 * same number for "dummy-Codec" 649 * 650 * ex1) 651 * CPU0 --- Codec0 link : 5 652 * CPU1 --- Codec1 dais : 7 653 * CPU2 -/ ccnf : 1 654 * CPU3 --- Codec2 655 * 656 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec 657 * => 7 DAIs = 4xCPU + 3xCodec 658 * => 1 ccnf = 1xdummy-Codec 659 * 660 * ex2) 661 * CPU0 --- Codec0 link : 5 662 * CPU1 --- Codec1 dais : 6 663 * CPU2 -/ ccnf : 1 664 * CPU3 -/ 665 * 666 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec 667 * => 6 DAIs = 4xCPU + 2xCodec 668 * => 1 ccnf = 1xdummy-Codec 669 * 670 * ex3) 671 * CPU0 --- Codec0 link : 6 672 * CPU1 -/ dais : 6 673 * CPU2 --- Codec1 ccnf : 2 674 * CPU3 -/ 675 * 676 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec 677 * => 6 DAIs = 4xCPU + 2xCodec 678 * => 2 ccnf = 2xdummy-Codec 679 * 680 * ex4) 681 * CPU0 --- Codec0 (convert-rate) link : 3 682 * CPU1 --- Codec1 dais : 4 683 * ccnf : 1 684 * 685 * => 3 links = 1xCPU-Codec + 1xCPU-dummy + 1xdummy-Codec 686 * => 4 DAIs = 2xCPU + 2xCodec 687 * => 1 ccnf = 1xdummy-Codec 688 */ 689 if (!top) { 690 li->num[0].cpus = 1; 691 li->num[0].codecs = 1; 692 li->num[0].platforms = 1; 693 694 li->link = 1; 695 return 0; 696 } 697 698 return simple_for_each_link(priv, li, 699 simple_count_noml, 700 simple_count_dpcm); 701 } 702 703 static int simple_soc_probe(struct snd_soc_card *card) 704 { 705 struct simple_util_priv *priv = snd_soc_card_get_drvdata(card); 706 int ret; 707 708 ret = simple_util_init_hp(card, &priv->hp_jack, PREFIX); 709 if (ret < 0) 710 return ret; 711 712 ret = simple_util_init_mic(card, &priv->mic_jack, PREFIX); 713 if (ret < 0) 714 return ret; 715 716 ret = simple_util_init_aux_jacks(priv, PREFIX); 717 if (ret < 0) 718 return ret; 719 720 return 0; 721 } 722 723 static int simple_probe(struct platform_device *pdev) 724 { 725 struct simple_util_priv *priv; 726 struct device *dev = &pdev->dev; 727 struct device_node *np = dev->of_node; 728 struct snd_soc_card *card; 729 int ret; 730 731 /* Allocate the private data and the DAI link array */ 732 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 733 if (!priv) 734 return -ENOMEM; 735 736 card = simple_priv_to_card(priv); 737 card->owner = THIS_MODULE; 738 card->dev = dev; 739 card->probe = simple_soc_probe; 740 card->driver_name = "simple-card"; 741 742 struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL); 743 if (!li) 744 return -ENOMEM; 745 746 ret = simple_get_dais_count(priv, li); 747 if (ret < 0) 748 return ret; 749 750 if (!li->link) 751 return -EINVAL; 752 753 ret = simple_util_init_priv(priv, li); 754 if (ret < 0) 755 return ret; 756 757 if (np && of_device_is_available(np)) { 758 759 ret = simple_parse_of(priv, li); 760 if (ret < 0) { 761 dev_err_probe(dev, ret, "parse error\n"); 762 goto err; 763 } 764 765 } else { 766 struct simple_util_info *cinfo; 767 struct snd_soc_dai_link_component *cpus; 768 struct snd_soc_dai_link_component *codecs; 769 struct snd_soc_dai_link_component *platform; 770 struct snd_soc_dai_link *dai_link = priv->dai_link; 771 struct simple_dai_props *dai_props = priv->dai_props; 772 773 ret = -EINVAL; 774 775 cinfo = dev->platform_data; 776 if (!cinfo) { 777 dev_err(dev, "no info for asoc-simple-card\n"); 778 goto err; 779 } 780 781 if (!cinfo->name || 782 !cinfo->codec_dai.name || 783 !cinfo->codec || 784 !cinfo->platform || 785 !cinfo->cpu_dai.name) { 786 dev_err(dev, "insufficient simple_util_info settings\n"); 787 goto err; 788 } 789 790 cpus = dai_link->cpus; 791 cpus->dai_name = cinfo->cpu_dai.name; 792 793 codecs = dai_link->codecs; 794 codecs->name = cinfo->codec; 795 codecs->dai_name = cinfo->codec_dai.name; 796 797 platform = dai_link->platforms; 798 platform->name = cinfo->platform; 799 800 card->name = (cinfo->card) ? cinfo->card : cinfo->name; 801 dai_link->name = cinfo->name; 802 dai_link->stream_name = cinfo->name; 803 dai_link->dai_fmt = cinfo->daifmt; 804 dai_link->init = simple_util_dai_init; 805 memcpy(dai_props->cpu_dai, &cinfo->cpu_dai, 806 sizeof(*dai_props->cpu_dai)); 807 memcpy(dai_props->codec_dai, &cinfo->codec_dai, 808 sizeof(*dai_props->codec_dai)); 809 } 810 811 snd_soc_card_set_drvdata(card, priv); 812 813 simple_util_debug_info(priv); 814 815 ret = devm_snd_soc_register_card(dev, card); 816 if (ret < 0) 817 goto err; 818 819 return 0; 820 err: 821 simple_util_clean_reference(card); 822 823 return ret; 824 } 825 826 static const struct of_device_id simple_of_match[] = { 827 { .compatible = "simple-audio-card", }, 828 { .compatible = "simple-scu-audio-card", 829 .data = (void *)DPCM_SELECTABLE }, 830 {}, 831 }; 832 MODULE_DEVICE_TABLE(of, simple_of_match); 833 834 static struct platform_driver simple_card = { 835 .driver = { 836 .name = "asoc-simple-card", 837 .pm = &snd_soc_pm_ops, 838 .of_match_table = simple_of_match, 839 }, 840 .probe = simple_probe, 841 .remove = simple_util_remove, 842 }; 843 844 module_platform_driver(simple_card); 845 846 MODULE_ALIAS("platform:asoc-simple-card"); 847 MODULE_LICENSE("GPL v2"); 848 MODULE_DESCRIPTION("ASoC Simple Sound Card"); 849 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 850