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