1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // ASoC Audio Graph Card2 support 4 // 5 // Copyright (C) 2020 Renesas Electronics Corp. 6 // Copyright (C) 2020 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 7 // 8 // based on ${LINUX}/sound/soc/generic/audio-graph-card.c 9 #include <linux/clk.h> 10 #include <linux/device.h> 11 #include <linux/gpio.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/of_graph.h> 16 #include <linux/platform_device.h> 17 #include <linux/string.h> 18 #include <sound/graph_card.h> 19 20 /************************************ 21 daifmt 22 ************************************ 23 ports { 24 format = "left_j"; 25 port@0 { 26 bitclock-master; 27 sample0: endpoint@0 { 28 frame-master; 29 }; 30 sample1: endpoint@1 { 31 format = "i2s"; 32 }; 33 }; 34 ... 35 }; 36 37 You can set daifmt at ports/port/endpoint. 38 It uses *latest* format, and *share* master settings. 39 In above case, 40 sample0: left_j, bitclock-master, frame-master 41 sample1: i2s, bitclock-master 42 43 If there was no settings, *Codec* will be 44 bitclock/frame provider as default. 45 see 46 graph_parse_daifmt(). 47 48 "format" property is no longer needed on DT if both CPU/Codec drivers are 49 supporting snd_soc_dai_ops :: .auto_selectable_formats. 50 see 51 snd_soc_runtime_get_dai_fmt() 52 53 sample driver 54 linux/sound/soc/sh/rcar/core.c 55 linux/sound/soc/codecs/ak4613.c 56 linux/sound/soc/codecs/pcm3168a.c 57 linux/sound/soc/soc-utils.c 58 linux/sound/soc/generic/test-component.c 59 60 ************************************ 61 Normal Audio-Graph 62 ************************************ 63 64 CPU <---> Codec 65 66 sound { 67 compatible = "audio-graph-card2"; 68 links = <&cpu>; 69 }; 70 71 CPU { 72 cpu: port { 73 bitclock-master; 74 frame-master; 75 cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; }; 76 }; 77 78 Codec { 79 port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; }; 80 }; 81 82 ************************************ 83 Multi-CPU/Codec 84 ************************************ 85 86 It has connection part (= X) and list part (= y). 87 links indicates connection part of CPU side (= A). 88 89 +-+ (A) +-+ 90 CPU1 --(y) | | <-(X)--(X)-> | | (y)-- Codec1 91 CPU2 --(y) | | | | (y)-- Codec2 92 +-+ +-+ 93 94 sound { 95 compatible = "audio-graph-card2"; 96 97 (A) links = <&mcpu>; 98 99 multi { 100 ports@0 { 101 (X) (A) mcpu: port@0 { mcpu0_ep: endpoint { remote-endpoint = <&mcodec0_ep>; }; }; 102 (y) port@1 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; 103 (y) port@2 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; 104 }; 105 ports@1 { 106 (X) port@0 { mcodec0_ep: endpoint { remote-endpoint = <&mcpu0_ep>; }; }; 107 (y) port@1 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; 108 (y) port@2 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; 109 }; 110 }; 111 }; 112 113 CPU { 114 ports { 115 bitclock-master; 116 frame-master; 117 port@0 { cpu1_ep: endpoint { remote-endpoint = <&mcpu1_ep>; }; }; 118 port@1 { cpu2_ep: endpoint { remote-endpoint = <&mcpu2_ep>; }; }; 119 }; 120 }; 121 122 Codec { 123 ports { 124 port@0 { codec1_ep: endpoint { remote-endpoint = <&mcodec1_ep>; }; }; 125 port@1 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; }; 126 }; 127 }; 128 129 ************************************ 130 DPCM 131 ************************************ 132 133 DSP 134 ************ 135 PCM0 <--> * fe0 be0 * <--> DAI0: Codec Headset 136 PCM1 <--> * fe1 be1 * <--> DAI1: Codec Speakers 137 PCM2 <--> * fe2 be2 * <--> DAI2: MODEM 138 PCM3 <--> * fe3 be3 * <--> DAI3: BT 139 * be4 * <--> DAI4: DMIC 140 * be5 * <--> DAI5: FM 141 ************ 142 143 sound { 144 compatible = "audio-graph-card2"; 145 146 // indicate routing 147 routing = "xxx Playback", "xxx Playback", 148 "xxx Playback", "xxx Playback", 149 "xxx Playback", "xxx Playback"; 150 151 // indicate all Front-End, Back-End 152 links = <&fe0, &fe1, ..., 153 &be0, &be1, ...>; 154 155 dpcm { 156 // Front-End 157 ports@0 { 158 fe0: port@0 { fe0_ep: endpoint { remote-endpoint = <&pcm0_ep>; }; }; 159 fe1: port@1 { fe1_ep: endpoint { remote-endpoint = <&pcm1_ep>; }; }; 160 ... 161 }; 162 // Back-End 163 ports@1 { 164 be0: port@0 { be0_ep: endpoint { remote-endpoint = <&dai0_ep>; }; }; 165 be1: port@1 { be1_ep: endpoint { remote-endpoint = <&dai1_ep>; }; }; 166 ... 167 }; 168 }; 169 }; 170 171 CPU { 172 ports { 173 bitclock-master; 174 frame-master; 175 port@0 { pcm0_ep: endpoint { remote-endpoint = <&fe0_ep>; }; }; 176 port@1 { pcm1_ep: endpoint { remote-endpoint = <&fe1_ep>; }; }; 177 ... 178 }; 179 }; 180 181 Codec { 182 ports { 183 port@0 { dai0_ep: endpoint { remote-endpoint = <&be0_ep>; }; }; 184 port@1 { dai1_ep: endpoint { remote-endpoint = <&be1_ep>; }; }; 185 ... 186 }; 187 }; 188 189 ************************************ 190 Codec to Codec 191 ************************************ 192 193 +--+ 194 | |<-- Codec0 <- IN 195 | |--> Codec1 -> OUT 196 +--+ 197 198 sound { 199 compatible = "audio-graph-card2"; 200 201 routing = "OUT" ,"DAI1 Playback", 202 "DAI0 Capture", "IN"; 203 204 links = <&c2c>; 205 206 codec2codec { 207 ports { 208 rate = <48000>; 209 c2c: port@0 { c2cf_ep: endpoint { remote-endpoint = <&codec0_ep>; }; }; 210 port@1 { c2cb_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; 211 }; 212 }; 213 214 Codec { 215 ports { 216 port@0 { 217 bitclock-master; 218 frame-master; 219 codec0_ep: endpoint { remote-endpoint = <&c2cf_ep>; }; }; 220 port@1 { codec1_ep: endpoint { remote-endpoint = <&c2cb_ep>; }; }; 221 }; 222 }; 223 224 */ 225 226 enum graph_type { 227 GRAPH_NORMAL, 228 GRAPH_DPCM, 229 GRAPH_C2C, 230 231 GRAPH_MULTI, /* don't use ! Use this only in __graph_get_type() */ 232 }; 233 234 #define GRAPH_NODENAME_MULTI "multi" 235 #define GRAPH_NODENAME_DPCM "dpcm" 236 #define GRAPH_NODENAME_C2C "codec2codec" 237 238 #define port_to_endpoint(port) of_get_child_by_name(port, "endpoint") 239 240 static enum graph_type __graph_get_type(struct device_node *lnk) 241 { 242 struct device_node *np, *parent_np; 243 enum graph_type ret; 244 245 /* 246 * target { 247 * ports { 248 * => lnk: port@0 { ... }; 249 * port@1 { ... }; 250 * }; 251 * }; 252 */ 253 np = of_get_parent(lnk); 254 if (of_node_name_eq(np, "ports")) { 255 parent_np = of_get_parent(np); 256 of_node_put(np); 257 np = parent_np; 258 } 259 260 if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) { 261 ret = GRAPH_MULTI; 262 goto out_put; 263 } 264 265 if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) { 266 ret = GRAPH_DPCM; 267 goto out_put; 268 } 269 270 if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) { 271 ret = GRAPH_C2C; 272 goto out_put; 273 } 274 275 ret = GRAPH_NORMAL; 276 277 out_put: 278 of_node_put(np); 279 return ret; 280 281 } 282 283 static enum graph_type graph_get_type(struct simple_util_priv *priv, 284 struct device_node *lnk) 285 { 286 enum graph_type type = __graph_get_type(lnk); 287 288 /* GRAPH_MULTI here means GRAPH_NORMAL */ 289 if (type == GRAPH_MULTI) 290 type = GRAPH_NORMAL; 291 292 #ifdef DEBUG 293 { 294 struct device *dev = simple_priv_to_dev(priv); 295 const char *str = "Normal"; 296 297 switch (type) { 298 case GRAPH_DPCM: 299 if (graph_util_is_ports0(lnk)) 300 str = "DPCM Front-End"; 301 else 302 str = "DPCM Back-End"; 303 break; 304 case GRAPH_C2C: 305 str = "Codec2Codec"; 306 break; 307 default: 308 break; 309 } 310 311 dev_dbg(dev, "%pOF (%s)", lnk, str); 312 } 313 #endif 314 return type; 315 } 316 317 static int graph_lnk_is_multi(struct device_node *lnk) 318 { 319 return __graph_get_type(lnk) == GRAPH_MULTI; 320 } 321 322 static struct device_node *graph_get_next_multi_ep(struct device_node **port) 323 { 324 struct device_node *ports = of_get_parent(*port); 325 struct device_node *ep = NULL; 326 struct device_node *rep = NULL; 327 328 /* 329 * multi { 330 * ports { 331 * => lnk: port@0 { ... }; 332 * port@1 { ep { ... = rep0 } }; 333 * port@2 { ep { ... = rep1 } }; 334 * ... 335 * }; 336 * }; 337 * 338 * xxx { 339 * port@0 { rep0 }; 340 * port@1 { rep1 }; 341 * }; 342 */ 343 do { 344 *port = of_get_next_child(ports, *port); 345 if (!*port) 346 break; 347 } while (!of_node_name_eq(*port, "port")); 348 349 if (*port) { 350 ep = port_to_endpoint(*port); 351 rep = of_graph_get_remote_endpoint(ep); 352 } 353 354 of_node_put(ep); 355 of_node_put(ports); 356 357 return rep; 358 } 359 360 static const struct snd_soc_ops graph_ops = { 361 .startup = simple_util_startup, 362 .shutdown = simple_util_shutdown, 363 .hw_params = simple_util_hw_params, 364 }; 365 366 static void graph_parse_convert(struct device_node *ep, 367 struct simple_dai_props *props) 368 { 369 struct device_node *port = of_get_parent(ep); 370 struct device_node *ports = of_get_parent(port); 371 struct simple_util_data *adata = &props->adata; 372 373 if (of_node_name_eq(ports, "ports")) 374 simple_util_parse_convert(ports, NULL, adata); 375 simple_util_parse_convert(port, NULL, adata); 376 simple_util_parse_convert(ep, NULL, adata); 377 378 of_node_put(port); 379 of_node_put(ports); 380 } 381 382 static void graph_parse_mclk_fs(struct device_node *ep, 383 struct simple_dai_props *props) 384 { 385 struct device_node *port = of_get_parent(ep); 386 struct device_node *ports = of_get_parent(port); 387 388 if (of_node_name_eq(ports, "ports")) 389 of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); 390 of_property_read_u32(port, "mclk-fs", &props->mclk_fs); 391 of_property_read_u32(ep, "mclk-fs", &props->mclk_fs); 392 393 of_node_put(port); 394 of_node_put(ports); 395 } 396 397 static int __graph_parse_node(struct simple_util_priv *priv, 398 enum graph_type gtype, 399 struct device_node *ep, 400 struct link_info *li, 401 int is_cpu, int idx) 402 { 403 struct device *dev = simple_priv_to_dev(priv); 404 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 405 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 406 struct snd_soc_dai_link_component *dlc; 407 struct simple_util_dai *dai; 408 int ret, is_single_links = 0; 409 410 if (is_cpu) { 411 dlc = snd_soc_link_to_cpu(dai_link, idx); 412 dai = simple_props_to_dai_cpu(dai_props, idx); 413 } else { 414 dlc = snd_soc_link_to_codec(dai_link, idx); 415 dai = simple_props_to_dai_codec(dai_props, idx); 416 } 417 418 graph_parse_mclk_fs(ep, dai_props); 419 420 ret = graph_util_parse_dai(dev, ep, dlc, &is_single_links); 421 if (ret < 0) 422 return ret; 423 424 ret = simple_util_parse_tdm(ep, dai); 425 if (ret < 0) 426 return ret; 427 428 ret = simple_util_parse_tdm_width_map(dev, ep, dai); 429 if (ret < 0) 430 return ret; 431 432 ret = simple_util_parse_clk(dev, ep, dai, dlc); 433 if (ret < 0) 434 return ret; 435 436 /* 437 * set DAI Name 438 */ 439 if (!dai_link->name) { 440 struct snd_soc_dai_link_component *cpus = dlc; 441 struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, idx); 442 char *cpu_multi = ""; 443 char *codec_multi = ""; 444 445 if (dai_link->num_cpus > 1) 446 cpu_multi = "_multi"; 447 if (dai_link->num_codecs > 1) 448 codec_multi = "_multi"; 449 450 switch (gtype) { 451 case GRAPH_NORMAL: 452 /* run is_cpu only. see audio_graph2_link_normal() */ 453 if (is_cpu) 454 simple_util_set_dailink_name(dev, dai_link, "%s%s-%s%s", 455 cpus->dai_name, cpu_multi, 456 codecs->dai_name, codec_multi); 457 break; 458 case GRAPH_DPCM: 459 if (is_cpu) 460 simple_util_set_dailink_name(dev, dai_link, "fe.%pOFP.%s%s", 461 cpus->of_node, cpus->dai_name, cpu_multi); 462 else 463 simple_util_set_dailink_name(dev, dai_link, "be.%pOFP.%s%s", 464 codecs->of_node, codecs->dai_name, codec_multi); 465 break; 466 case GRAPH_C2C: 467 /* run is_cpu only. see audio_graph2_link_c2c() */ 468 if (is_cpu) 469 simple_util_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s", 470 cpus->dai_name, cpu_multi, 471 codecs->dai_name, codec_multi); 472 break; 473 default: 474 break; 475 } 476 } 477 478 /* 479 * Check "prefix" from top node 480 * if DPCM-BE case 481 */ 482 if (!is_cpu && gtype == GRAPH_DPCM) { 483 struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, idx); 484 struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx); 485 struct device_node *rport = of_get_parent(ep); 486 struct device_node *rports = of_get_parent(rport); 487 488 if (of_node_name_eq(rports, "ports")) 489 snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); 490 snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix"); 491 492 of_node_put(rport); 493 of_node_put(rports); 494 } 495 496 if (is_cpu) { 497 struct snd_soc_dai_link_component *cpus = dlc; 498 struct snd_soc_dai_link_component *platforms = snd_soc_link_to_platform(dai_link, idx); 499 500 simple_util_canonicalize_cpu(cpus, is_single_links); 501 simple_util_canonicalize_platform(platforms, cpus); 502 } 503 504 return 0; 505 } 506 507 static int graph_parse_node(struct simple_util_priv *priv, 508 enum graph_type gtype, 509 struct device_node *port, 510 struct link_info *li, int is_cpu) 511 { 512 struct device_node *ep; 513 int ret = 0; 514 515 if (graph_lnk_is_multi(port)) { 516 int idx; 517 518 of_node_get(port); 519 520 for (idx = 0;; idx++) { 521 ep = graph_get_next_multi_ep(&port); 522 if (!ep) 523 break; 524 525 ret = __graph_parse_node(priv, gtype, ep, 526 li, is_cpu, idx); 527 of_node_put(ep); 528 if (ret < 0) 529 break; 530 } 531 } else { 532 /* Single CPU / Codec */ 533 ep = port_to_endpoint(port); 534 ret = __graph_parse_node(priv, gtype, ep, li, is_cpu, 0); 535 of_node_put(ep); 536 } 537 538 return ret; 539 } 540 541 static void graph_parse_daifmt(struct device_node *node, 542 unsigned int *daifmt, unsigned int *bit_frame) 543 { 544 unsigned int fmt; 545 546 /* 547 * see also above "daifmt" explanation 548 * and samples. 549 */ 550 551 /* 552 * ports { 553 * (A) 554 * port { 555 * (B) 556 * endpoint { 557 * (C) 558 * }; 559 * }; 560 * }; 561 * }; 562 */ 563 564 /* 565 * clock_provider: 566 * 567 * It can be judged it is provider 568 * if (A) or (B) or (C) has bitclock-master / frame-master flag. 569 * 570 * use "or" 571 */ 572 *bit_frame |= snd_soc_daifmt_parse_clock_provider_as_bitmap(node, NULL); 573 574 #define update_daifmt(name) \ 575 if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) && \ 576 (fmt & SND_SOC_DAIFMT_##name##_MASK)) \ 577 *daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK 578 579 /* 580 * format 581 * 582 * This function is called by (C) -> (B) -> (A) order. 583 * Set if applicable part was not yet set. 584 */ 585 fmt = snd_soc_daifmt_parse_format(node, NULL); 586 update_daifmt(FORMAT); 587 update_daifmt(CLOCK); 588 update_daifmt(INV); 589 } 590 591 static void graph_link_init(struct simple_util_priv *priv, 592 struct device_node *port, 593 struct link_info *li, 594 int is_cpu_node) 595 { 596 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 597 struct device_node *ep; 598 struct device_node *ports; 599 unsigned int daifmt = 0, daiclk = 0; 600 unsigned int bit_frame = 0; 601 602 if (graph_lnk_is_multi(port)) { 603 of_node_get(port); 604 ep = graph_get_next_multi_ep(&port); 605 port = of_get_parent(ep); 606 } else { 607 ep = port_to_endpoint(port); 608 } 609 610 ports = of_get_parent(port); 611 612 /* 613 * ports { 614 * (A) 615 * port { 616 * (B) 617 * endpoint { 618 * (C) 619 * }; 620 * }; 621 * }; 622 * }; 623 */ 624 graph_parse_daifmt(ep, &daifmt, &bit_frame); /* (C) */ 625 graph_parse_daifmt(port, &daifmt, &bit_frame); /* (B) */ 626 if (of_node_name_eq(ports, "ports")) 627 graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */ 628 629 /* 630 * convert bit_frame 631 * We need to flip clock_provider if it was CPU node, 632 * because it is Codec base. 633 */ 634 daiclk = snd_soc_daifmt_clock_provider_from_bitmap(bit_frame); 635 if (is_cpu_node) 636 daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk); 637 638 dai_link->dai_fmt = daifmt | daiclk; 639 dai_link->init = simple_util_dai_init; 640 dai_link->ops = &graph_ops; 641 if (priv->ops) 642 dai_link->ops = priv->ops; 643 } 644 645 int audio_graph2_link_normal(struct simple_util_priv *priv, 646 struct device_node *lnk, 647 struct link_info *li) 648 { 649 struct device_node *cpu_port = lnk; 650 struct device_node *cpu_ep = port_to_endpoint(cpu_port); 651 struct device_node *codec_port = of_graph_get_remote_port(cpu_ep); 652 int ret; 653 654 /* 655 * call Codec first. 656 * see 657 * __graph_parse_node() :: DAI Naming 658 */ 659 ret = graph_parse_node(priv, GRAPH_NORMAL, codec_port, li, 0); 660 if (ret < 0) 661 goto err; 662 663 /* 664 * call CPU, and set DAI Name 665 */ 666 ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_port, li, 1); 667 if (ret < 0) 668 goto err; 669 670 graph_link_init(priv, cpu_port, li, 1); 671 err: 672 of_node_put(codec_port); 673 of_node_put(cpu_ep); 674 675 return ret; 676 } 677 EXPORT_SYMBOL_GPL(audio_graph2_link_normal); 678 679 int audio_graph2_link_dpcm(struct simple_util_priv *priv, 680 struct device_node *lnk, 681 struct link_info *li) 682 { 683 struct device_node *ep = port_to_endpoint(lnk); 684 struct device_node *rep = of_graph_get_remote_endpoint(ep); 685 struct device_node *rport = of_graph_get_remote_port(ep); 686 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 687 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 688 int is_cpu = graph_util_is_ports0(lnk); 689 int ret; 690 691 if (is_cpu) { 692 /* 693 * dpcm { 694 * // Front-End 695 * ports@0 { 696 * => lnk: port@0 { ep: { ... = rep }; }; 697 * ... 698 * }; 699 * // Back-End 700 * ports@0 { 701 * ... 702 * }; 703 * }; 704 * 705 * CPU { 706 * rports: ports { 707 * rport: port@0 { rep: { ... = ep } }; 708 * } 709 * } 710 */ 711 /* 712 * setup CPU here, Codec is already set as dummy. 713 * see 714 * simple_util_init_priv() 715 */ 716 dai_link->dynamic = 1; 717 dai_link->dpcm_merged_format = 1; 718 719 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 1); 720 if (ret) 721 goto err; 722 } else { 723 /* 724 * dpcm { 725 * // Front-End 726 * ports@0 { 727 * ... 728 * }; 729 * // Back-End 730 * ports@0 { 731 * => lnk: port@0 { ep: { ... = rep; }; }; 732 * ... 733 * }; 734 * }; 735 * 736 * Codec { 737 * rports: ports { 738 * rport: port@0 { rep: { ... = ep; }; }; 739 * } 740 * } 741 */ 742 /* 743 * setup Codec here, CPU is already set as dummy. 744 * see 745 * simple_util_init_priv() 746 */ 747 748 /* BE settings */ 749 dai_link->no_pcm = 1; 750 dai_link->be_hw_params_fixup = simple_util_be_hw_params_fixup; 751 752 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 0); 753 if (ret < 0) 754 goto err; 755 } 756 757 graph_parse_convert(ep, dai_props); /* at node of <dpcm> */ 758 graph_parse_convert(rep, dai_props); /* at node of <CPU/Codec> */ 759 760 snd_soc_dai_link_set_capabilities(dai_link); 761 762 graph_link_init(priv, rport, li, is_cpu); 763 err: 764 of_node_put(ep); 765 of_node_put(rep); 766 of_node_put(rport); 767 768 return ret; 769 } 770 EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm); 771 772 int audio_graph2_link_c2c(struct simple_util_priv *priv, 773 struct device_node *lnk, 774 struct link_info *li) 775 { 776 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 777 struct device_node *port0, *port1, *ports; 778 struct device_node *codec0_port, *codec1_port; 779 struct device_node *ep0, *ep1; 780 u32 val = 0; 781 int ret = -EINVAL; 782 783 /* 784 * codec2codec { 785 * ports { 786 * rate = <48000>; 787 * => lnk: port@0 { c2c0_ep: { ... = codec0_ep; }; }; 788 * port@1 { c2c1_ep: { ... = codec1_ep; }; }; 789 * }; 790 * }; 791 * 792 * Codec { 793 * ports { 794 * port@0 { codec0_ep: ... }; }; 795 * port@1 { codec1_ep: ... }; }; 796 * }; 797 * }; 798 */ 799 of_node_get(lnk); 800 port0 = lnk; 801 ports = of_get_parent(port0); 802 port1 = of_get_next_child(ports, lnk); 803 804 /* 805 * Card2 can use original Codec2Codec settings if DT has. 806 * It will use default settings if no settings on DT. 807 * see 808 * simple_util_init_for_codec2codec() 809 * 810 * Add more settings here if needed 811 */ 812 of_property_read_u32(ports, "rate", &val); 813 if (val) { 814 struct device *dev = simple_priv_to_dev(priv); 815 struct snd_soc_pcm_stream *c2c_conf; 816 817 c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL); 818 if (!c2c_conf) 819 goto err1; 820 821 c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ 822 c2c_conf->rates = SNDRV_PCM_RATE_8000_384000; 823 c2c_conf->rate_min = 824 c2c_conf->rate_max = val; 825 c2c_conf->channels_min = 826 c2c_conf->channels_max = 2; /* update ME */ 827 828 dai_link->c2c_params = c2c_conf; 829 dai_link->num_c2c_params = 1; 830 } 831 832 ep0 = port_to_endpoint(port0); 833 ep1 = port_to_endpoint(port1); 834 835 codec0_port = of_graph_get_remote_port(ep0); 836 codec1_port = of_graph_get_remote_port(ep1); 837 838 /* 839 * call Codec first. 840 * see 841 * __graph_parse_node() :: DAI Naming 842 */ 843 ret = graph_parse_node(priv, GRAPH_C2C, codec1_port, li, 0); 844 if (ret < 0) 845 goto err2; 846 847 /* 848 * call CPU, and set DAI Name 849 */ 850 ret = graph_parse_node(priv, GRAPH_C2C, codec0_port, li, 1); 851 if (ret < 0) 852 goto err2; 853 854 graph_link_init(priv, codec0_port, li, 1); 855 err2: 856 of_node_put(ep0); 857 of_node_put(ep1); 858 of_node_put(codec0_port); 859 of_node_put(codec1_port); 860 err1: 861 of_node_put(ports); 862 of_node_put(port0); 863 of_node_put(port1); 864 865 return ret; 866 } 867 EXPORT_SYMBOL_GPL(audio_graph2_link_c2c); 868 869 static int graph_link(struct simple_util_priv *priv, 870 struct graph2_custom_hooks *hooks, 871 enum graph_type gtype, 872 struct device_node *lnk, 873 struct link_info *li) 874 { 875 struct device *dev = simple_priv_to_dev(priv); 876 GRAPH2_CUSTOM func = NULL; 877 int ret = -EINVAL; 878 879 switch (gtype) { 880 case GRAPH_NORMAL: 881 if (hooks && hooks->custom_normal) 882 func = hooks->custom_normal; 883 else 884 func = audio_graph2_link_normal; 885 break; 886 case GRAPH_DPCM: 887 if (hooks && hooks->custom_dpcm) 888 func = hooks->custom_dpcm; 889 else 890 func = audio_graph2_link_dpcm; 891 break; 892 case GRAPH_C2C: 893 if (hooks && hooks->custom_c2c) 894 func = hooks->custom_c2c; 895 else 896 func = audio_graph2_link_c2c; 897 break; 898 default: 899 break; 900 } 901 902 if (!func) { 903 dev_err(dev, "non supported gtype (%d)\n", gtype); 904 goto err; 905 } 906 907 ret = func(priv, lnk, li); 908 if (ret < 0) 909 goto err; 910 911 li->link++; 912 err: 913 return ret; 914 } 915 916 static int graph_counter(struct device_node *lnk) 917 { 918 /* 919 * Multi CPU / Codec 920 * 921 * multi { 922 * ports { 923 * => lnk: port@0 { ... }; 924 * port@1 { ... }; 925 * port@2 { ... }; 926 * ... 927 * }; 928 * }; 929 * 930 * ignore first lnk part 931 */ 932 if (graph_lnk_is_multi(lnk)) 933 return of_graph_get_endpoint_count(of_get_parent(lnk)) - 1; 934 /* 935 * Single CPU / Codec 936 */ 937 else 938 return 1; 939 } 940 941 static int graph_count_normal(struct simple_util_priv *priv, 942 struct device_node *lnk, 943 struct link_info *li) 944 { 945 struct device_node *cpu_port = lnk; 946 struct device_node *cpu_ep = port_to_endpoint(cpu_port); 947 struct device_node *codec_port = of_graph_get_remote_port(cpu_ep); 948 949 /* 950 * CPU { 951 * => lnk: port { endpoint { .. }; }; 952 * }; 953 */ 954 /* 955 * DON'T REMOVE platforms 956 * see 957 * simple-card.c :: simple_count_noml() 958 */ 959 li->num[li->link].cpus = 960 li->num[li->link].platforms = graph_counter(cpu_port); 961 962 li->num[li->link].codecs = graph_counter(codec_port); 963 964 of_node_put(cpu_ep); 965 of_node_put(codec_port); 966 967 return 0; 968 } 969 970 static int graph_count_dpcm(struct simple_util_priv *priv, 971 struct device_node *lnk, 972 struct link_info *li) 973 { 974 struct device_node *ep = port_to_endpoint(lnk); 975 struct device_node *rport = of_graph_get_remote_port(ep); 976 977 /* 978 * dpcm { 979 * // Front-End 980 * ports@0 { 981 * => lnk: port@0 { endpoint { ... }; }; 982 * ... 983 * }; 984 * // Back-End 985 * ports@1 { 986 * => lnk: port@0 { endpoint { ... }; }; 987 * ... 988 * }; 989 * }; 990 */ 991 992 if (graph_util_is_ports0(lnk)) { 993 /* 994 * DON'T REMOVE platforms 995 * see 996 * simple-card.c :: simple_count_noml() 997 */ 998 li->num[li->link].cpus = graph_counter(rport); /* FE */ 999 li->num[li->link].platforms = graph_counter(rport); 1000 } else { 1001 li->num[li->link].codecs = graph_counter(rport); /* BE */ 1002 } 1003 1004 of_node_put(ep); 1005 of_node_put(rport); 1006 1007 return 0; 1008 } 1009 1010 static int graph_count_c2c(struct simple_util_priv *priv, 1011 struct device_node *lnk, 1012 struct link_info *li) 1013 { 1014 struct device_node *ports = of_get_parent(lnk); 1015 struct device_node *port0 = lnk; 1016 struct device_node *port1 = of_get_next_child(ports, lnk); 1017 struct device_node *ep0 = port_to_endpoint(port0); 1018 struct device_node *ep1 = port_to_endpoint(port1); 1019 struct device_node *codec0 = of_graph_get_remote_port(ep0); 1020 struct device_node *codec1 = of_graph_get_remote_port(ep1); 1021 1022 of_node_get(lnk); 1023 1024 /* 1025 * codec2codec { 1026 * ports { 1027 * => lnk: port@0 { endpoint { ... }; }; 1028 * port@1 { endpoint { ... }; }; 1029 * }; 1030 * }; 1031 */ 1032 /* 1033 * DON'T REMOVE platforms 1034 * see 1035 * simple-card.c :: simple_count_noml() 1036 */ 1037 li->num[li->link].cpus = 1038 li->num[li->link].platforms = graph_counter(codec0); 1039 1040 li->num[li->link].codecs = graph_counter(codec1); 1041 1042 of_node_put(ports); 1043 of_node_put(port1); 1044 of_node_put(ep0); 1045 of_node_put(ep1); 1046 of_node_put(codec0); 1047 of_node_put(codec1); 1048 1049 return 0; 1050 } 1051 1052 static int graph_count(struct simple_util_priv *priv, 1053 struct graph2_custom_hooks *hooks, 1054 enum graph_type gtype, 1055 struct device_node *lnk, 1056 struct link_info *li) 1057 { 1058 struct device *dev = simple_priv_to_dev(priv); 1059 GRAPH2_CUSTOM func = NULL; 1060 int ret = -EINVAL; 1061 1062 if (li->link >= SNDRV_MAX_LINKS) { 1063 dev_err(dev, "too many links\n"); 1064 return ret; 1065 } 1066 1067 switch (gtype) { 1068 case GRAPH_NORMAL: 1069 func = graph_count_normal; 1070 break; 1071 case GRAPH_DPCM: 1072 func = graph_count_dpcm; 1073 break; 1074 case GRAPH_C2C: 1075 func = graph_count_c2c; 1076 break; 1077 default: 1078 break; 1079 } 1080 1081 if (!func) { 1082 dev_err(dev, "non supported gtype (%d)\n", gtype); 1083 goto err; 1084 } 1085 1086 ret = func(priv, lnk, li); 1087 if (ret < 0) 1088 goto err; 1089 1090 li->link++; 1091 err: 1092 return ret; 1093 } 1094 1095 static int graph_for_each_link(struct simple_util_priv *priv, 1096 struct graph2_custom_hooks *hooks, 1097 struct link_info *li, 1098 int (*func)(struct simple_util_priv *priv, 1099 struct graph2_custom_hooks *hooks, 1100 enum graph_type gtype, 1101 struct device_node *lnk, 1102 struct link_info *li)) 1103 { 1104 struct of_phandle_iterator it; 1105 struct device *dev = simple_priv_to_dev(priv); 1106 struct device_node *node = dev->of_node; 1107 struct device_node *lnk; 1108 enum graph_type gtype; 1109 int rc, ret; 1110 1111 /* loop for all listed CPU port */ 1112 of_for_each_phandle(&it, rc, node, "links", NULL, 0) { 1113 lnk = it.node; 1114 1115 gtype = graph_get_type(priv, lnk); 1116 1117 ret = func(priv, hooks, gtype, lnk, li); 1118 if (ret < 0) 1119 return ret; 1120 } 1121 1122 return 0; 1123 } 1124 1125 int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev, 1126 struct graph2_custom_hooks *hooks) 1127 { 1128 struct snd_soc_card *card = simple_priv_to_card(priv); 1129 struct link_info *li; 1130 int ret; 1131 1132 li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); 1133 if (!li) 1134 return -ENOMEM; 1135 1136 card->probe = graph_util_card_probe; 1137 card->owner = THIS_MODULE; 1138 card->dev = dev; 1139 1140 if ((hooks) && (hooks)->hook_pre) { 1141 ret = (hooks)->hook_pre(priv); 1142 if (ret < 0) 1143 goto err; 1144 } 1145 1146 ret = graph_for_each_link(priv, hooks, li, graph_count); 1147 if (!li->link) 1148 ret = -EINVAL; 1149 if (ret < 0) 1150 goto err; 1151 1152 ret = simple_util_init_priv(priv, li); 1153 if (ret < 0) 1154 goto err; 1155 1156 priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW); 1157 if (IS_ERR(priv->pa_gpio)) { 1158 ret = PTR_ERR(priv->pa_gpio); 1159 dev_err(dev, "failed to get amplifier gpio: %d\n", ret); 1160 goto err; 1161 } 1162 1163 ret = simple_util_parse_widgets(card, NULL); 1164 if (ret < 0) 1165 goto err; 1166 1167 ret = simple_util_parse_routing(card, NULL); 1168 if (ret < 0) 1169 goto err; 1170 1171 memset(li, 0, sizeof(*li)); 1172 ret = graph_for_each_link(priv, hooks, li, graph_link); 1173 if (ret < 0) 1174 goto err; 1175 1176 ret = simple_util_parse_card_name(card, NULL); 1177 if (ret < 0) 1178 goto err; 1179 1180 snd_soc_card_set_drvdata(card, priv); 1181 1182 if ((hooks) && (hooks)->hook_post) { 1183 ret = (hooks)->hook_post(priv); 1184 if (ret < 0) 1185 goto err; 1186 } 1187 1188 simple_util_debug_info(priv); 1189 1190 ret = devm_snd_soc_register_card(dev, card); 1191 err: 1192 devm_kfree(dev, li); 1193 1194 if (ret < 0) 1195 dev_err_probe(dev, ret, "parse error\n"); 1196 1197 return ret; 1198 } 1199 EXPORT_SYMBOL_GPL(audio_graph2_parse_of); 1200 1201 static int graph_probe(struct platform_device *pdev) 1202 { 1203 struct simple_util_priv *priv; 1204 struct device *dev = &pdev->dev; 1205 1206 /* Allocate the private data and the DAI link array */ 1207 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1208 if (!priv) 1209 return -ENOMEM; 1210 1211 return audio_graph2_parse_of(priv, dev, NULL); 1212 } 1213 1214 static const struct of_device_id graph_of_match[] = { 1215 { .compatible = "audio-graph-card2", }, 1216 {}, 1217 }; 1218 MODULE_DEVICE_TABLE(of, graph_of_match); 1219 1220 static struct platform_driver graph_card = { 1221 .driver = { 1222 .name = "asoc-audio-graph-card2", 1223 .pm = &snd_soc_pm_ops, 1224 .of_match_table = graph_of_match, 1225 }, 1226 .probe = graph_probe, 1227 .remove_new = simple_util_remove, 1228 }; 1229 module_platform_driver(graph_card); 1230 1231 MODULE_ALIAS("platform:asoc-audio-graph-card2"); 1232 MODULE_LICENSE("GPL v2"); 1233 MODULE_DESCRIPTION("ASoC Audio Graph Card2"); 1234 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 1235