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@2 { 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@1 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; 98 (y) port@2 { 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_tdm_width_map(dev, ep, dai); 507 if (ret < 0) 508 return ret; 509 510 ret = asoc_simple_parse_clk(dev, ep, dai, dlc); 511 if (ret < 0) 512 return ret; 513 514 /* 515 * set DAI Name 516 */ 517 if (!dai_link->name) { 518 struct snd_soc_dai_link_component *cpus = dlc; 519 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx); 520 char *cpu_multi = ""; 521 char *codec_multi = ""; 522 523 if (dai_link->num_cpus > 1) 524 cpu_multi = "_multi"; 525 if (dai_link->num_codecs > 1) 526 codec_multi = "_multi"; 527 528 switch (gtype) { 529 case GRAPH_NORMAL: 530 /* run is_cpu only. see audio_graph2_link_normal() */ 531 if (is_cpu) 532 asoc_simple_set_dailink_name(dev, dai_link, "%s%s-%s%s", 533 cpus->dai_name, cpu_multi, 534 codecs->dai_name, codec_multi); 535 break; 536 case GRAPH_DPCM: 537 if (is_cpu) 538 asoc_simple_set_dailink_name(dev, dai_link, "fe.%pOFP.%s%s", 539 cpus->of_node, cpus->dai_name, cpu_multi); 540 else 541 asoc_simple_set_dailink_name(dev, dai_link, "be.%pOFP.%s%s", 542 codecs->of_node, codecs->dai_name, codec_multi); 543 break; 544 case GRAPH_C2C: 545 /* run is_cpu only. see audio_graph2_link_c2c() */ 546 if (is_cpu) 547 asoc_simple_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s", 548 cpus->dai_name, cpu_multi, 549 codecs->dai_name, codec_multi); 550 break; 551 default: 552 break; 553 } 554 } 555 556 /* 557 * Check "prefix" from top node 558 * if DPCM-BE case 559 */ 560 if (!is_cpu && gtype == GRAPH_DPCM) { 561 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx); 562 struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx); 563 struct device_node *rport = of_get_parent(ep); 564 struct device_node *rports = of_get_parent(rport); 565 566 if (of_node_name_eq(rports, "ports")) 567 snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); 568 snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix"); 569 570 of_node_put(rport); 571 of_node_put(rports); 572 } 573 574 if (is_cpu) { 575 struct snd_soc_dai_link_component *cpus = dlc; 576 struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, idx); 577 578 asoc_simple_canonicalize_cpu(cpus, is_single_links); 579 asoc_simple_canonicalize_platform(platforms, cpus); 580 } 581 582 return 0; 583 } 584 585 static int graph_parse_node(struct asoc_simple_priv *priv, 586 enum graph_type gtype, 587 struct device_node *port, 588 struct link_info *li, int is_cpu) 589 { 590 struct device_node *ep; 591 int ret = 0; 592 593 if (graph_lnk_is_multi(port)) { 594 int idx; 595 596 of_node_get(port); 597 598 for (idx = 0;; idx++) { 599 ep = graph_get_next_multi_ep(&port); 600 if (!ep) 601 break; 602 603 ret = __graph_parse_node(priv, gtype, ep, 604 li, is_cpu, idx); 605 of_node_put(ep); 606 if (ret < 0) 607 break; 608 } 609 } else { 610 /* Single CPU / Codec */ 611 ep = port_to_endpoint(port); 612 ret = __graph_parse_node(priv, gtype, ep, li, is_cpu, 0); 613 of_node_put(ep); 614 } 615 616 return ret; 617 } 618 619 static void graph_parse_daifmt(struct device_node *node, 620 unsigned int *daifmt, unsigned int *bit_frame) 621 { 622 unsigned int fmt; 623 624 /* 625 * see also above "daifmt" explanation 626 * and samples. 627 */ 628 629 /* 630 * ports { 631 * (A) 632 * port { 633 * (B) 634 * endpoint { 635 * (C) 636 * }; 637 * }; 638 * }; 639 * }; 640 */ 641 642 /* 643 * clock_provider: 644 * 645 * It can be judged it is provider 646 * if (A) or (B) or (C) has bitclock-master / frame-master flag. 647 * 648 * use "or" 649 */ 650 *bit_frame |= snd_soc_daifmt_parse_clock_provider_as_bitmap(node, NULL); 651 652 #define update_daifmt(name) \ 653 if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) && \ 654 (fmt & SND_SOC_DAIFMT_##name##_MASK)) \ 655 *daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK 656 657 /* 658 * format 659 * 660 * This function is called by (C) -> (B) -> (A) order. 661 * Set if applicable part was not yet set. 662 */ 663 fmt = snd_soc_daifmt_parse_format(node, NULL); 664 update_daifmt(FORMAT); 665 update_daifmt(CLOCK); 666 update_daifmt(INV); 667 } 668 669 static void graph_link_init(struct asoc_simple_priv *priv, 670 struct device_node *port, 671 struct link_info *li, 672 int is_cpu_node) 673 { 674 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 675 struct device_node *ep; 676 struct device_node *ports; 677 unsigned int daifmt = 0, daiclk = 0; 678 unsigned int bit_frame = 0; 679 680 if (graph_lnk_is_multi(port)) { 681 of_node_get(port); 682 ep = graph_get_next_multi_ep(&port); 683 port = of_get_parent(ep); 684 } else { 685 ep = port_to_endpoint(port); 686 } 687 688 ports = of_get_parent(port); 689 690 /* 691 * ports { 692 * (A) 693 * port { 694 * (B) 695 * endpoint { 696 * (C) 697 * }; 698 * }; 699 * }; 700 * }; 701 */ 702 graph_parse_daifmt(ep, &daifmt, &bit_frame); /* (C) */ 703 graph_parse_daifmt(port, &daifmt, &bit_frame); /* (B) */ 704 if (of_node_name_eq(ports, "ports")) 705 graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */ 706 707 /* 708 * convert bit_frame 709 * We need to flip clock_provider if it was CPU node, 710 * because it is Codec base. 711 */ 712 daiclk = snd_soc_daifmt_clock_provider_from_bitmap(bit_frame); 713 if (is_cpu_node) 714 daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk); 715 716 dai_link->dai_fmt = daifmt | daiclk; 717 dai_link->init = asoc_simple_dai_init; 718 dai_link->ops = &graph_ops; 719 if (priv->ops) 720 dai_link->ops = priv->ops; 721 } 722 723 int audio_graph2_link_normal(struct asoc_simple_priv *priv, 724 struct device_node *lnk, 725 struct link_info *li) 726 { 727 struct device_node *cpu_port = lnk; 728 struct device_node *cpu_ep = port_to_endpoint(cpu_port); 729 struct device_node *codec_port = of_graph_get_remote_port(cpu_ep); 730 int ret; 731 732 /* 733 * call Codec first. 734 * see 735 * __graph_parse_node() :: DAI Naming 736 */ 737 ret = graph_parse_node(priv, GRAPH_NORMAL, codec_port, li, 0); 738 if (ret < 0) 739 goto err; 740 741 /* 742 * call CPU, and set DAI Name 743 */ 744 ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_port, li, 1); 745 if (ret < 0) 746 goto err; 747 748 graph_link_init(priv, cpu_port, li, 1); 749 err: 750 of_node_put(codec_port); 751 of_node_put(cpu_ep); 752 753 return ret; 754 } 755 EXPORT_SYMBOL_GPL(audio_graph2_link_normal); 756 757 int audio_graph2_link_dpcm(struct asoc_simple_priv *priv, 758 struct device_node *lnk, 759 struct link_info *li) 760 { 761 struct device_node *ep = port_to_endpoint(lnk); 762 struct device_node *rep = of_graph_get_remote_endpoint(ep); 763 struct device_node *rport = of_graph_get_remote_port(ep); 764 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 765 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 766 int is_cpu = asoc_graph_is_ports0(lnk); 767 int ret; 768 769 if (is_cpu) { 770 /* 771 * dpcm { 772 * // Front-End 773 * ports@0 { 774 * => lnk: port@0 { ep: { ... = rep }; }; 775 * ... 776 * }; 777 * // Back-End 778 * ports@0 { 779 * ... 780 * }; 781 * }; 782 * 783 * CPU { 784 * rports: ports { 785 * rport: port@0 { rep: { ... = ep } }; 786 * } 787 * } 788 */ 789 /* 790 * setup CPU here, Codec is already set as dummy. 791 * see 792 * asoc_simple_init_priv() 793 */ 794 dai_link->dynamic = 1; 795 dai_link->dpcm_merged_format = 1; 796 797 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 1); 798 if (ret) 799 goto err; 800 } else { 801 /* 802 * dpcm { 803 * // Front-End 804 * ports@0 { 805 * ... 806 * }; 807 * // Back-End 808 * ports@0 { 809 * => lnk: port@0 { ep: { ... = rep; }; }; 810 * ... 811 * }; 812 * }; 813 * 814 * Codec { 815 * rports: ports { 816 * rport: port@0 { rep: { ... = ep; }; }; 817 * } 818 * } 819 */ 820 /* 821 * setup Codec here, CPU is already set as dummy. 822 * see 823 * asoc_simple_init_priv() 824 */ 825 826 /* BE settings */ 827 dai_link->no_pcm = 1; 828 dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup; 829 830 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 0); 831 if (ret < 0) 832 goto err; 833 } 834 835 graph_parse_convert(rep, dai_props); 836 837 snd_soc_dai_link_set_capabilities(dai_link); 838 839 graph_link_init(priv, rport, li, is_cpu); 840 err: 841 of_node_put(ep); 842 of_node_put(rep); 843 of_node_put(rport); 844 845 return ret; 846 } 847 EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm); 848 849 int audio_graph2_link_c2c(struct asoc_simple_priv *priv, 850 struct device_node *lnk, 851 struct link_info *li) 852 { 853 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 854 struct device_node *port0, *port1, *ports; 855 struct device_node *codec0_port, *codec1_port; 856 struct device_node *ep0, *ep1; 857 u32 val = 0; 858 int ret = -EINVAL; 859 860 /* 861 * codec2codec { 862 * ports { 863 * rate = <48000>; 864 * => lnk: port@0 { c2c0_ep: { ... = codec0_ep; }; }; 865 * port@1 { c2c1_ep: { ... = codec1_ep; }; }; 866 * }; 867 * }; 868 * 869 * Codec { 870 * ports { 871 * port@0 { codec0_ep: ... }; }; 872 * port@1 { codec1_ep: ... }; }; 873 * }; 874 * }; 875 */ 876 of_node_get(lnk); 877 port0 = lnk; 878 ports = of_get_parent(port0); 879 port1 = of_get_next_child(ports, lnk); 880 881 /* 882 * Card2 can use original Codec2Codec settings if DT has. 883 * It will use default settings if no settings on DT. 884 * see 885 * asoc_simple_init_for_codec2codec() 886 * 887 * Add more settings here if needed 888 */ 889 of_property_read_u32(ports, "rate", &val); 890 if (val) { 891 struct device *dev = simple_priv_to_dev(priv); 892 struct snd_soc_pcm_stream *c2c_conf; 893 894 c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL); 895 if (!c2c_conf) 896 goto err1; 897 898 c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ 899 c2c_conf->rates = SNDRV_PCM_RATE_8000_384000; 900 c2c_conf->rate_min = 901 c2c_conf->rate_max = val; 902 c2c_conf->channels_min = 903 c2c_conf->channels_max = 2; /* update ME */ 904 905 dai_link->params = c2c_conf; 906 dai_link->num_params = 1; 907 } 908 909 ep0 = port_to_endpoint(port0); 910 ep1 = port_to_endpoint(port1); 911 912 codec0_port = of_graph_get_remote_port(ep0); 913 codec1_port = of_graph_get_remote_port(ep1); 914 915 /* 916 * call Codec first. 917 * see 918 * __graph_parse_node() :: DAI Naming 919 */ 920 ret = graph_parse_node(priv, GRAPH_C2C, codec1_port, li, 0); 921 if (ret < 0) 922 goto err2; 923 924 /* 925 * call CPU, and set DAI Name 926 */ 927 ret = graph_parse_node(priv, GRAPH_C2C, codec0_port, li, 1); 928 if (ret < 0) 929 goto err2; 930 931 graph_link_init(priv, codec0_port, li, 1); 932 err2: 933 of_node_put(ep0); 934 of_node_put(ep1); 935 of_node_put(codec0_port); 936 of_node_put(codec1_port); 937 err1: 938 of_node_put(ports); 939 of_node_put(port0); 940 of_node_put(port1); 941 942 return ret; 943 } 944 EXPORT_SYMBOL_GPL(audio_graph2_link_c2c); 945 946 static int graph_link(struct asoc_simple_priv *priv, 947 struct graph2_custom_hooks *hooks, 948 enum graph_type gtype, 949 struct device_node *lnk, 950 struct link_info *li) 951 { 952 struct device *dev = simple_priv_to_dev(priv); 953 GRAPH2_CUSTOM func = NULL; 954 int ret = -EINVAL; 955 956 switch (gtype) { 957 case GRAPH_NORMAL: 958 if (hooks && hooks->custom_normal) 959 func = hooks->custom_normal; 960 else 961 func = audio_graph2_link_normal; 962 break; 963 case GRAPH_DPCM: 964 if (hooks && hooks->custom_dpcm) 965 func = hooks->custom_dpcm; 966 else 967 func = audio_graph2_link_dpcm; 968 break; 969 case GRAPH_C2C: 970 if (hooks && hooks->custom_c2c) 971 func = hooks->custom_c2c; 972 else 973 func = audio_graph2_link_c2c; 974 break; 975 default: 976 break; 977 } 978 979 if (!func) { 980 dev_err(dev, "non supported gtype (%d)\n", gtype); 981 goto err; 982 } 983 984 ret = func(priv, lnk, li); 985 if (ret < 0) 986 goto err; 987 988 li->link++; 989 err: 990 return ret; 991 } 992 993 static int graph_counter(struct device_node *lnk) 994 { 995 /* 996 * Multi CPU / Codec 997 * 998 * multi { 999 * ports { 1000 * => lnk: port@0 { ... }; 1001 * port@1 { ... }; 1002 * port@2 { ... }; 1003 * ... 1004 * }; 1005 * }; 1006 * 1007 * ignore first lnk part 1008 */ 1009 if (graph_lnk_is_multi(lnk)) 1010 return of_graph_get_endpoint_count(of_get_parent(lnk)) - 1; 1011 /* 1012 * Single CPU / Codec 1013 */ 1014 else 1015 return 1; 1016 } 1017 1018 static int graph_count_normal(struct asoc_simple_priv *priv, 1019 struct device_node *lnk, 1020 struct link_info *li) 1021 { 1022 struct device_node *cpu_port = lnk; 1023 struct device_node *cpu_ep = port_to_endpoint(cpu_port); 1024 struct device_node *codec_port = of_graph_get_remote_port(cpu_ep); 1025 1026 /* 1027 * CPU { 1028 * => lnk: port { endpoint { .. }; }; 1029 * }; 1030 */ 1031 li->num[li->link].cpus = 1032 li->num[li->link].platforms = graph_counter(cpu_port); 1033 li->num[li->link].codecs = graph_counter(codec_port); 1034 1035 of_node_put(cpu_ep); 1036 of_node_put(codec_port); 1037 1038 return 0; 1039 } 1040 1041 static int graph_count_dpcm(struct asoc_simple_priv *priv, 1042 struct device_node *lnk, 1043 struct link_info *li) 1044 { 1045 struct device_node *ep = port_to_endpoint(lnk); 1046 struct device_node *rport = of_graph_get_remote_port(ep); 1047 1048 /* 1049 * dpcm { 1050 * // Front-End 1051 * ports@0 { 1052 * => lnk: port@0 { endpoint { ... }; }; 1053 * ... 1054 * }; 1055 * // Back-End 1056 * ports@1 { 1057 * => lnk: port@0 { endpoint { ... }; }; 1058 * ... 1059 * }; 1060 * }; 1061 */ 1062 1063 if (asoc_graph_is_ports0(lnk)) { 1064 li->num[li->link].cpus = graph_counter(rport); /* FE */ 1065 li->num[li->link].platforms = graph_counter(rport); 1066 } else { 1067 li->num[li->link].codecs = graph_counter(rport); /* BE */ 1068 } 1069 1070 of_node_put(ep); 1071 of_node_put(rport); 1072 1073 return 0; 1074 } 1075 1076 static int graph_count_c2c(struct asoc_simple_priv *priv, 1077 struct device_node *lnk, 1078 struct link_info *li) 1079 { 1080 struct device_node *ports = of_get_parent(lnk); 1081 struct device_node *port0 = lnk; 1082 struct device_node *port1 = of_get_next_child(ports, lnk); 1083 struct device_node *ep0 = port_to_endpoint(port0); 1084 struct device_node *ep1 = port_to_endpoint(port1); 1085 struct device_node *codec0 = of_graph_get_remote_port(ep0); 1086 struct device_node *codec1 = of_graph_get_remote_port(ep1); 1087 1088 of_node_get(lnk); 1089 1090 /* 1091 * codec2codec { 1092 * ports { 1093 * => lnk: port@0 { endpoint { ... }; }; 1094 * port@1 { endpoint { ... }; }; 1095 * }; 1096 * }; 1097 */ 1098 li->num[li->link].cpus = 1099 li->num[li->link].platforms = graph_counter(codec0); 1100 li->num[li->link].codecs = graph_counter(codec1); 1101 1102 of_node_put(ports); 1103 of_node_put(port1); 1104 of_node_put(ep0); 1105 of_node_put(ep1); 1106 of_node_put(codec0); 1107 of_node_put(codec1); 1108 1109 return 0; 1110 } 1111 1112 static int graph_count(struct asoc_simple_priv *priv, 1113 struct graph2_custom_hooks *hooks, 1114 enum graph_type gtype, 1115 struct device_node *lnk, 1116 struct link_info *li) 1117 { 1118 struct device *dev = simple_priv_to_dev(priv); 1119 GRAPH2_CUSTOM func = NULL; 1120 int ret = -EINVAL; 1121 1122 if (li->link >= SNDRV_MAX_LINKS) { 1123 dev_err(dev, "too many links\n"); 1124 return ret; 1125 } 1126 1127 switch (gtype) { 1128 case GRAPH_NORMAL: 1129 func = graph_count_normal; 1130 break; 1131 case GRAPH_DPCM: 1132 func = graph_count_dpcm; 1133 break; 1134 case GRAPH_C2C: 1135 func = graph_count_c2c; 1136 break; 1137 default: 1138 break; 1139 } 1140 1141 if (!func) { 1142 dev_err(dev, "non supported gtype (%d)\n", gtype); 1143 goto err; 1144 } 1145 1146 ret = func(priv, lnk, li); 1147 if (ret < 0) 1148 goto err; 1149 1150 li->link++; 1151 err: 1152 return ret; 1153 } 1154 1155 static int graph_for_each_link(struct asoc_simple_priv *priv, 1156 struct graph2_custom_hooks *hooks, 1157 struct link_info *li, 1158 int (*func)(struct asoc_simple_priv *priv, 1159 struct graph2_custom_hooks *hooks, 1160 enum graph_type gtype, 1161 struct device_node *lnk, 1162 struct link_info *li)) 1163 { 1164 struct of_phandle_iterator it; 1165 struct device *dev = simple_priv_to_dev(priv); 1166 struct device_node *node = dev->of_node; 1167 struct device_node *lnk; 1168 enum graph_type gtype; 1169 int rc, ret; 1170 1171 /* loop for all listed CPU port */ 1172 of_for_each_phandle(&it, rc, node, "links", NULL, 0) { 1173 lnk = it.node; 1174 1175 gtype = graph_get_type(priv, lnk); 1176 1177 ret = func(priv, hooks, gtype, lnk, li); 1178 if (ret < 0) 1179 return ret; 1180 } 1181 1182 return 0; 1183 } 1184 1185 int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev, 1186 struct graph2_custom_hooks *hooks) 1187 { 1188 struct snd_soc_card *card = simple_priv_to_card(priv); 1189 struct link_info *li; 1190 int ret; 1191 1192 li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); 1193 if (!li) 1194 return -ENOMEM; 1195 1196 card->probe = asoc_graph_card_probe; 1197 card->owner = THIS_MODULE; 1198 card->dev = dev; 1199 1200 if ((hooks) && (hooks)->hook_pre) { 1201 ret = (hooks)->hook_pre(priv); 1202 if (ret < 0) 1203 goto err; 1204 } 1205 1206 ret = graph_for_each_link(priv, hooks, li, graph_count); 1207 if (!li->link) 1208 ret = -EINVAL; 1209 if (ret < 0) 1210 goto err; 1211 1212 ret = asoc_simple_init_priv(priv, li); 1213 if (ret < 0) 1214 goto err; 1215 1216 priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW); 1217 if (IS_ERR(priv->pa_gpio)) { 1218 ret = PTR_ERR(priv->pa_gpio); 1219 dev_err(dev, "failed to get amplifier gpio: %d\n", ret); 1220 goto err; 1221 } 1222 1223 ret = asoc_simple_parse_widgets(card, NULL); 1224 if (ret < 0) 1225 goto err; 1226 1227 ret = asoc_simple_parse_routing(card, NULL); 1228 if (ret < 0) 1229 goto err; 1230 1231 memset(li, 0, sizeof(*li)); 1232 ret = graph_for_each_link(priv, hooks, li, graph_link); 1233 if (ret < 0) 1234 goto err; 1235 1236 ret = asoc_simple_parse_card_name(card, NULL); 1237 if (ret < 0) 1238 goto err; 1239 1240 snd_soc_card_set_drvdata(card, priv); 1241 1242 if ((hooks) && (hooks)->hook_post) { 1243 ret = (hooks)->hook_post(priv); 1244 if (ret < 0) 1245 goto err; 1246 } 1247 1248 asoc_simple_debug_info(priv); 1249 1250 ret = devm_snd_soc_register_card(dev, card); 1251 err: 1252 devm_kfree(dev, li); 1253 1254 if (ret < 0) 1255 dev_err_probe(dev, ret, "parse error\n"); 1256 1257 if (ret == 0) 1258 dev_warn(dev, "Audio Graph Card2 is still under Experimental stage\n"); 1259 1260 return ret; 1261 } 1262 EXPORT_SYMBOL_GPL(audio_graph2_parse_of); 1263 1264 static int graph_probe(struct platform_device *pdev) 1265 { 1266 struct asoc_simple_priv *priv; 1267 struct device *dev = &pdev->dev; 1268 1269 /* Allocate the private data and the DAI link array */ 1270 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1271 if (!priv) 1272 return -ENOMEM; 1273 1274 return audio_graph2_parse_of(priv, dev, NULL); 1275 } 1276 1277 static const struct of_device_id graph_of_match[] = { 1278 { .compatible = "audio-graph-card2", }, 1279 {}, 1280 }; 1281 MODULE_DEVICE_TABLE(of, graph_of_match); 1282 1283 static struct platform_driver graph_card = { 1284 .driver = { 1285 .name = "asoc-audio-graph-card2", 1286 .pm = &snd_soc_pm_ops, 1287 .of_match_table = graph_of_match, 1288 }, 1289 .probe = graph_probe, 1290 .remove = asoc_simple_remove, 1291 }; 1292 module_platform_driver(graph_card); 1293 1294 MODULE_ALIAS("platform:asoc-audio-graph-card2"); 1295 MODULE_LICENSE("GPL v2"); 1296 MODULE_DESCRIPTION("ASoC Audio Graph Card2"); 1297 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 1298