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_device.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 = asoc_simple_startup, 27 .shutdown = asoc_simple_shutdown, 28 .hw_params = asoc_simple_hw_params, 29 }; 30 31 static int asoc_simple_parse_dai(struct device_node *node, 32 struct snd_soc_dai_link_component *dlc, 33 int *is_single_link) 34 { 35 struct of_phandle_args args; 36 int ret; 37 38 if (!node) 39 return 0; 40 41 /* 42 * Get node via "sound-dai = <&phandle port>" 43 * it will be used as xxx_of_node on soc_bind_dai_link() 44 */ 45 ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args); 46 if (ret) 47 return ret; 48 49 /* 50 * FIXME 51 * 52 * Here, dlc->dai_name is pointer to CPU/Codec DAI name. 53 * If user unbinded CPU or Codec driver, but not for Sound Card, 54 * dlc->dai_name is keeping unbinded CPU or Codec 55 * driver's pointer. 56 * 57 * If user re-bind CPU or Codec driver again, ALSA SoC will try 58 * to rebind Card via snd_soc_try_rebind_card(), but because of 59 * above reason, it might can't bind Sound Card. 60 * Because Sound Card is pointing to released dai_name pointer. 61 * 62 * To avoid this rebind Card issue, 63 * 1) It needs to alloc memory to keep dai_name eventhough 64 * CPU or Codec driver was unbinded, or 65 * 2) user need to rebind Sound Card everytime 66 * if he unbinded CPU or Codec. 67 */ 68 ret = snd_soc_of_get_dai_name(node, &dlc->dai_name); 69 if (ret < 0) 70 return ret; 71 72 dlc->of_node = args.np; 73 74 if (is_single_link) 75 *is_single_link = !args.args_count; 76 77 return 0; 78 } 79 80 static void simple_parse_convert(struct device *dev, 81 struct device_node *np, 82 struct asoc_simple_data *adata) 83 { 84 struct device_node *top = dev->of_node; 85 struct device_node *node = of_get_parent(np); 86 87 asoc_simple_parse_convert(top, PREFIX, adata); 88 asoc_simple_parse_convert(node, PREFIX, adata); 89 asoc_simple_parse_convert(node, NULL, adata); 90 asoc_simple_parse_convert(np, NULL, adata); 91 92 of_node_put(node); 93 } 94 95 static void simple_parse_mclk_fs(struct device_node *top, 96 struct device_node *np, 97 struct simple_dai_props *props, 98 char *prefix) 99 { 100 struct device_node *node = of_get_parent(np); 101 char prop[128]; 102 103 snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX); 104 of_property_read_u32(top, prop, &props->mclk_fs); 105 106 snprintf(prop, sizeof(prop), "%smclk-fs", prefix); 107 of_property_read_u32(node, prop, &props->mclk_fs); 108 of_property_read_u32(np, prop, &props->mclk_fs); 109 110 of_node_put(node); 111 } 112 113 static int simple_parse_node(struct asoc_simple_priv *priv, 114 struct device_node *np, 115 struct link_info *li, 116 char *prefix, 117 int *cpu) 118 { 119 struct device *dev = simple_priv_to_dev(priv); 120 struct device_node *top = dev->of_node; 121 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 122 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 123 struct snd_soc_dai_link_component *dlc; 124 struct asoc_simple_dai *dai; 125 int ret; 126 127 if (cpu) { 128 dlc = asoc_link_to_cpu(dai_link, 0); 129 dai = simple_props_to_dai_cpu(dai_props, 0); 130 } else { 131 dlc = asoc_link_to_codec(dai_link, 0); 132 dai = simple_props_to_dai_codec(dai_props, 0); 133 } 134 135 simple_parse_mclk_fs(top, np, dai_props, prefix); 136 137 ret = asoc_simple_parse_dai(np, dlc, cpu); 138 if (ret) 139 return ret; 140 141 ret = asoc_simple_parse_clk(dev, np, dai, dlc); 142 if (ret) 143 return ret; 144 145 ret = asoc_simple_parse_tdm(np, dai); 146 if (ret) 147 return ret; 148 149 return 0; 150 } 151 152 static int simple_link_init(struct asoc_simple_priv *priv, 153 struct device_node *node, 154 struct device_node *codec, 155 struct link_info *li, 156 char *prefix, char *name) 157 { 158 struct device *dev = simple_priv_to_dev(priv); 159 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 160 int ret; 161 162 ret = asoc_simple_parse_daifmt(dev, node, codec, 163 prefix, &dai_link->dai_fmt); 164 if (ret < 0) 165 return 0; 166 167 dai_link->init = asoc_simple_dai_init; 168 dai_link->ops = &simple_ops; 169 170 return asoc_simple_set_dailink_name(dev, dai_link, name); 171 } 172 173 static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, 174 struct device_node *np, 175 struct device_node *codec, 176 struct link_info *li, 177 bool is_top) 178 { 179 struct device *dev = simple_priv_to_dev(priv); 180 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 181 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 182 struct device_node *top = dev->of_node; 183 struct device_node *node = of_get_parent(np); 184 char *prefix = ""; 185 char dai_name[64]; 186 int ret; 187 188 dev_dbg(dev, "link_of DPCM (%pOF)\n", np); 189 190 /* For single DAI link & old style of DT node */ 191 if (is_top) 192 prefix = PREFIX; 193 194 if (li->cpu) { 195 struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); 196 struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0); 197 int is_single_links = 0; 198 199 /* Codec is dummy */ 200 201 /* FE settings */ 202 dai_link->dynamic = 1; 203 dai_link->dpcm_merged_format = 1; 204 205 ret = simple_parse_node(priv, np, li, prefix, &is_single_links); 206 if (ret < 0) 207 goto out_put_node; 208 209 snprintf(dai_name, sizeof(dai_name), "fe.%s", cpus->dai_name); 210 211 asoc_simple_canonicalize_cpu(cpus, is_single_links); 212 asoc_simple_canonicalize_platform(platforms, cpus); 213 } else { 214 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0); 215 struct snd_soc_codec_conf *cconf; 216 217 /* CPU is dummy */ 218 219 /* BE settings */ 220 dai_link->no_pcm = 1; 221 dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup; 222 223 cconf = simple_props_to_codec_conf(dai_props, 0); 224 225 ret = simple_parse_node(priv, np, li, prefix, NULL); 226 if (ret < 0) 227 goto out_put_node; 228 229 snprintf(dai_name, sizeof(dai_name), "be.%s", codecs->dai_name); 230 231 /* check "prefix" from top node */ 232 snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, 233 PREFIX "prefix"); 234 snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node, 235 "prefix"); 236 snd_soc_of_parse_node_prefix(np, cconf, codecs->of_node, 237 "prefix"); 238 } 239 240 simple_parse_convert(dev, np, &dai_props->adata); 241 242 snd_soc_dai_link_set_capabilities(dai_link); 243 244 ret = simple_link_init(priv, node, codec, li, prefix, dai_name); 245 246 out_put_node: 247 li->link++; 248 249 of_node_put(node); 250 return ret; 251 } 252 253 static int simple_dai_link_of(struct asoc_simple_priv *priv, 254 struct device_node *np, 255 struct device_node *codec, 256 struct link_info *li, 257 bool is_top) 258 { 259 struct device *dev = simple_priv_to_dev(priv); 260 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 261 struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); 262 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0); 263 struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0); 264 struct device_node *cpu = NULL; 265 struct device_node *node = NULL; 266 struct device_node *plat = NULL; 267 char dai_name[64]; 268 char prop[128]; 269 char *prefix = ""; 270 int ret, single_cpu = 0; 271 272 cpu = np; 273 node = of_get_parent(np); 274 275 dev_dbg(dev, "link_of (%pOF)\n", node); 276 277 /* For single DAI link & old style of DT node */ 278 if (is_top) 279 prefix = PREFIX; 280 281 snprintf(prop, sizeof(prop), "%splat", prefix); 282 plat = of_get_child_by_name(node, prop); 283 284 ret = simple_parse_node(priv, cpu, li, prefix, &single_cpu); 285 if (ret < 0) 286 goto dai_link_of_err; 287 288 ret = simple_parse_node(priv, codec, li, prefix, NULL); 289 if (ret < 0) 290 goto dai_link_of_err; 291 292 ret = asoc_simple_parse_dai(plat, platforms, NULL); 293 if (ret < 0) 294 goto dai_link_of_err; 295 296 snprintf(dai_name, sizeof(dai_name), 297 "%s-%s", cpus->dai_name, codecs->dai_name); 298 299 asoc_simple_canonicalize_cpu(cpus, single_cpu); 300 asoc_simple_canonicalize_platform(platforms, cpus); 301 302 ret = simple_link_init(priv, node, codec, li, prefix, dai_name); 303 304 dai_link_of_err: 305 of_node_put(plat); 306 of_node_put(node); 307 308 li->link++; 309 310 return ret; 311 } 312 313 static int __simple_for_each_link(struct asoc_simple_priv *priv, 314 struct link_info *li, 315 int (*func_noml)(struct asoc_simple_priv *priv, 316 struct device_node *np, 317 struct device_node *codec, 318 struct link_info *li, bool is_top), 319 int (*func_dpcm)(struct asoc_simple_priv *priv, 320 struct device_node *np, 321 struct device_node *codec, 322 struct link_info *li, bool is_top)) 323 { 324 struct device *dev = simple_priv_to_dev(priv); 325 struct device_node *top = dev->of_node; 326 struct device_node *node; 327 uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); 328 bool is_top = 0; 329 int ret = 0; 330 331 /* Check if it has dai-link */ 332 node = of_get_child_by_name(top, PREFIX "dai-link"); 333 if (!node) { 334 node = of_node_get(top); 335 is_top = 1; 336 } 337 338 /* loop for all dai-link */ 339 do { 340 struct asoc_simple_data adata; 341 struct device_node *codec; 342 struct device_node *plat; 343 struct device_node *np; 344 int num = of_get_child_count(node); 345 346 /* get codec */ 347 codec = of_get_child_by_name(node, is_top ? 348 PREFIX "codec" : "codec"); 349 if (!codec) { 350 ret = -ENODEV; 351 goto error; 352 } 353 /* get platform */ 354 plat = of_get_child_by_name(node, is_top ? 355 PREFIX "plat" : "plat"); 356 357 /* get convert-xxx property */ 358 memset(&adata, 0, sizeof(adata)); 359 for_each_child_of_node(node, np) 360 simple_parse_convert(dev, np, &adata); 361 362 /* loop for all CPU/Codec node */ 363 for_each_child_of_node(node, np) { 364 if (plat == np) 365 continue; 366 /* 367 * It is DPCM 368 * if it has many CPUs, 369 * or has convert-xxx property 370 */ 371 if (dpcm_selectable && 372 (num > 2 || 373 adata.convert_rate || adata.convert_channels)) { 374 /* 375 * np 376 * |1(CPU)|0(Codec) li->cpu 377 * CPU |Pass |return 378 * Codec |return|Pass 379 */ 380 if (li->cpu != (np == codec)) 381 ret = func_dpcm(priv, np, codec, li, is_top); 382 /* else normal sound */ 383 } else { 384 /* 385 * np 386 * |1(CPU)|0(Codec) li->cpu 387 * CPU |Pass |return 388 * Codec |return|return 389 */ 390 if (li->cpu && (np != codec)) 391 ret = func_noml(priv, np, codec, li, is_top); 392 } 393 394 if (ret < 0) { 395 of_node_put(codec); 396 of_node_put(np); 397 goto error; 398 } 399 } 400 401 of_node_put(codec); 402 node = of_get_next_child(top, node); 403 } while (!is_top && node); 404 405 error: 406 of_node_put(node); 407 return ret; 408 } 409 410 static int simple_for_each_link(struct asoc_simple_priv *priv, 411 struct link_info *li, 412 int (*func_noml)(struct asoc_simple_priv *priv, 413 struct device_node *np, 414 struct device_node *codec, 415 struct link_info *li, bool is_top), 416 int (*func_dpcm)(struct asoc_simple_priv *priv, 417 struct device_node *np, 418 struct device_node *codec, 419 struct link_info *li, bool is_top)) 420 { 421 int ret; 422 /* 423 * Detect all CPU first, and Detect all Codec 2nd. 424 * 425 * In Normal sound case, all DAIs are detected 426 * as "CPU-Codec". 427 * 428 * In DPCM sound case, 429 * all CPUs are detected as "CPU-dummy", and 430 * all Codecs are detected as "dummy-Codec". 431 * To avoid random sub-device numbering, 432 * detect "dummy-Codec" in last; 433 */ 434 for (li->cpu = 1; li->cpu >= 0; li->cpu--) { 435 ret = __simple_for_each_link(priv, li, func_noml, func_dpcm); 436 if (ret < 0) 437 break; 438 } 439 440 return ret; 441 } 442 443 static int simple_parse_of(struct asoc_simple_priv *priv, struct link_info *li) 444 { 445 struct snd_soc_card *card = simple_priv_to_card(priv); 446 int ret; 447 448 ret = asoc_simple_parse_widgets(card, PREFIX); 449 if (ret < 0) 450 return ret; 451 452 ret = asoc_simple_parse_routing(card, PREFIX); 453 if (ret < 0) 454 return ret; 455 456 ret = asoc_simple_parse_pin_switches(card, PREFIX); 457 if (ret < 0) 458 return ret; 459 460 /* Single/Muti DAI link(s) & New style of DT node */ 461 memset(li, 0, sizeof(*li)); 462 ret = simple_for_each_link(priv, li, 463 simple_dai_link_of, 464 simple_dai_link_of_dpcm); 465 if (ret < 0) 466 return ret; 467 468 ret = asoc_simple_parse_card_name(card, PREFIX); 469 if (ret < 0) 470 return ret; 471 472 ret = snd_soc_of_parse_aux_devs(card, PREFIX "aux-devs"); 473 474 return ret; 475 } 476 477 static int simple_count_noml(struct asoc_simple_priv *priv, 478 struct device_node *np, 479 struct device_node *codec, 480 struct link_info *li, bool is_top) 481 { 482 if (li->link >= SNDRV_MAX_LINKS) { 483 struct device *dev = simple_priv_to_dev(priv); 484 485 dev_err(dev, "too many links\n"); 486 return -EINVAL; 487 } 488 489 li->num[li->link].cpus = 1; 490 li->num[li->link].codecs = 1; 491 li->num[li->link].platforms = 1; 492 493 li->link += 1; 494 495 return 0; 496 } 497 498 static int simple_count_dpcm(struct asoc_simple_priv *priv, 499 struct device_node *np, 500 struct device_node *codec, 501 struct link_info *li, bool is_top) 502 { 503 if (li->link >= SNDRV_MAX_LINKS) { 504 struct device *dev = simple_priv_to_dev(priv); 505 506 dev_err(dev, "too many links\n"); 507 return -EINVAL; 508 } 509 510 if (li->cpu) { 511 li->num[li->link].cpus = 1; 512 li->num[li->link].platforms = 1; 513 514 li->link++; /* CPU-dummy */ 515 } else { 516 li->num[li->link].codecs = 1; 517 518 li->link++; /* dummy-Codec */ 519 } 520 521 return 0; 522 } 523 524 static int simple_get_dais_count(struct asoc_simple_priv *priv, 525 struct link_info *li) 526 { 527 struct device *dev = simple_priv_to_dev(priv); 528 struct device_node *top = dev->of_node; 529 530 /* 531 * link_num : number of links. 532 * CPU-Codec / CPU-dummy / dummy-Codec 533 * dais_num : number of DAIs 534 * ccnf_num : number of codec_conf 535 * same number for "dummy-Codec" 536 * 537 * ex1) 538 * CPU0 --- Codec0 link : 5 539 * CPU1 --- Codec1 dais : 7 540 * CPU2 -/ ccnf : 1 541 * CPU3 --- Codec2 542 * 543 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec 544 * => 7 DAIs = 4xCPU + 3xCodec 545 * => 1 ccnf = 1xdummy-Codec 546 * 547 * ex2) 548 * CPU0 --- Codec0 link : 5 549 * CPU1 --- Codec1 dais : 6 550 * CPU2 -/ ccnf : 1 551 * CPU3 -/ 552 * 553 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec 554 * => 6 DAIs = 4xCPU + 2xCodec 555 * => 1 ccnf = 1xdummy-Codec 556 * 557 * ex3) 558 * CPU0 --- Codec0 link : 6 559 * CPU1 -/ dais : 6 560 * CPU2 --- Codec1 ccnf : 2 561 * CPU3 -/ 562 * 563 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec 564 * => 6 DAIs = 4xCPU + 2xCodec 565 * => 2 ccnf = 2xdummy-Codec 566 * 567 * ex4) 568 * CPU0 --- Codec0 (convert-rate) link : 3 569 * CPU1 --- Codec1 dais : 4 570 * ccnf : 1 571 * 572 * => 3 links = 1xCPU-Codec + 1xCPU-dummy + 1xdummy-Codec 573 * => 4 DAIs = 2xCPU + 2xCodec 574 * => 1 ccnf = 1xdummy-Codec 575 */ 576 if (!top) { 577 li->num[0].cpus = 1; 578 li->num[0].codecs = 1; 579 li->num[0].platforms = 1; 580 581 li->link = 1; 582 return 0; 583 } 584 585 return simple_for_each_link(priv, li, 586 simple_count_noml, 587 simple_count_dpcm); 588 } 589 590 static int simple_soc_probe(struct snd_soc_card *card) 591 { 592 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); 593 int ret; 594 595 ret = asoc_simple_init_hp(card, &priv->hp_jack, PREFIX); 596 if (ret < 0) 597 return ret; 598 599 ret = asoc_simple_init_mic(card, &priv->mic_jack, PREFIX); 600 if (ret < 0) 601 return ret; 602 603 return 0; 604 } 605 606 static int asoc_simple_probe(struct platform_device *pdev) 607 { 608 struct asoc_simple_priv *priv; 609 struct device *dev = &pdev->dev; 610 struct device_node *np = dev->of_node; 611 struct snd_soc_card *card; 612 struct link_info *li; 613 int ret; 614 615 /* Allocate the private data and the DAI link array */ 616 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 617 if (!priv) 618 return -ENOMEM; 619 620 card = simple_priv_to_card(priv); 621 card->owner = THIS_MODULE; 622 card->dev = dev; 623 card->probe = simple_soc_probe; 624 card->driver_name = "simple-card"; 625 626 li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); 627 if (!li) 628 return -ENOMEM; 629 630 ret = simple_get_dais_count(priv, li); 631 if (ret < 0) 632 return ret; 633 634 if (!li->link) 635 return -EINVAL; 636 637 ret = asoc_simple_init_priv(priv, li); 638 if (ret < 0) 639 return ret; 640 641 if (np && of_device_is_available(np)) { 642 643 ret = simple_parse_of(priv, li); 644 if (ret < 0) { 645 dev_err_probe(dev, ret, "parse error\n"); 646 goto err; 647 } 648 649 } else { 650 struct asoc_simple_card_info *cinfo; 651 struct snd_soc_dai_link_component *cpus; 652 struct snd_soc_dai_link_component *codecs; 653 struct snd_soc_dai_link_component *platform; 654 struct snd_soc_dai_link *dai_link = priv->dai_link; 655 struct simple_dai_props *dai_props = priv->dai_props; 656 657 cinfo = dev->platform_data; 658 if (!cinfo) { 659 dev_err(dev, "no info for asoc-simple-card\n"); 660 return -EINVAL; 661 } 662 663 if (!cinfo->name || 664 !cinfo->codec_dai.name || 665 !cinfo->codec || 666 !cinfo->platform || 667 !cinfo->cpu_dai.name) { 668 dev_err(dev, "insufficient asoc_simple_card_info settings\n"); 669 return -EINVAL; 670 } 671 672 cpus = dai_link->cpus; 673 cpus->dai_name = cinfo->cpu_dai.name; 674 675 codecs = dai_link->codecs; 676 codecs->name = cinfo->codec; 677 codecs->dai_name = cinfo->codec_dai.name; 678 679 platform = dai_link->platforms; 680 platform->name = cinfo->platform; 681 682 card->name = (cinfo->card) ? cinfo->card : cinfo->name; 683 dai_link->name = cinfo->name; 684 dai_link->stream_name = cinfo->name; 685 dai_link->dai_fmt = cinfo->daifmt; 686 dai_link->init = asoc_simple_dai_init; 687 memcpy(dai_props->cpu_dai, &cinfo->cpu_dai, 688 sizeof(*dai_props->cpu_dai)); 689 memcpy(dai_props->codec_dai, &cinfo->codec_dai, 690 sizeof(*dai_props->codec_dai)); 691 } 692 693 snd_soc_card_set_drvdata(card, priv); 694 695 asoc_simple_debug_info(priv); 696 697 ret = devm_snd_soc_register_card(dev, card); 698 if (ret < 0) 699 goto err; 700 701 devm_kfree(dev, li); 702 return 0; 703 err: 704 asoc_simple_clean_reference(card); 705 706 return ret; 707 } 708 709 static const struct of_device_id simple_of_match[] = { 710 { .compatible = "simple-audio-card", }, 711 { .compatible = "simple-scu-audio-card", 712 .data = (void *)DPCM_SELECTABLE }, 713 {}, 714 }; 715 MODULE_DEVICE_TABLE(of, simple_of_match); 716 717 static struct platform_driver asoc_simple_card = { 718 .driver = { 719 .name = "asoc-simple-card", 720 .pm = &snd_soc_pm_ops, 721 .of_match_table = simple_of_match, 722 }, 723 .probe = asoc_simple_probe, 724 .remove = asoc_simple_remove, 725 }; 726 727 module_platform_driver(asoc_simple_card); 728 729 MODULE_ALIAS("platform:asoc-simple-card"); 730 MODULE_LICENSE("GPL v2"); 731 MODULE_DESCRIPTION("ASoC Simple Sound Card"); 732 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 733