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, *parent_np; 233 enum graph_type ret; 234 235 /* 236 * target { 237 * ports { 238 * => lnk: port@0 { ... }; 239 * port@1 { ... }; 240 * }; 241 * }; 242 */ 243 np = of_get_parent(lnk); 244 if (of_node_name_eq(np, "ports")) { 245 parent_np = of_get_parent(np); 246 of_node_put(np); 247 np = parent_np; 248 } 249 250 if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) { 251 ret = GRAPH_MULTI; 252 goto out_put; 253 } 254 255 if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) { 256 ret = GRAPH_DPCM; 257 goto out_put; 258 } 259 260 if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) { 261 ret = GRAPH_C2C; 262 goto out_put; 263 } 264 265 ret = GRAPH_NORMAL; 266 267 out_put: 268 of_node_put(np); 269 return ret; 270 271 } 272 273 static enum graph_type graph_get_type(struct asoc_simple_priv *priv, 274 struct device_node *lnk) 275 { 276 enum graph_type type = __graph_get_type(lnk); 277 278 /* GRAPH_MULTI here means GRAPH_NORMAL */ 279 if (type == GRAPH_MULTI) 280 type = GRAPH_NORMAL; 281 282 #ifdef DEBUG 283 { 284 struct device *dev = simple_priv_to_dev(priv); 285 const char *str = "Normal"; 286 287 switch (type) { 288 case GRAPH_DPCM: 289 if (asoc_graph_is_ports0(lnk)) 290 str = "DPCM Front-End"; 291 else 292 str = "DPCM Back-End"; 293 break; 294 case GRAPH_C2C: 295 str = "Codec2Codec"; 296 break; 297 default: 298 break; 299 } 300 301 dev_dbg(dev, "%pOF (%s)", lnk, str); 302 } 303 #endif 304 return type; 305 } 306 307 static int graph_lnk_is_multi(struct device_node *lnk) 308 { 309 return __graph_get_type(lnk) == GRAPH_MULTI; 310 } 311 312 static struct device_node *graph_get_next_multi_ep(struct device_node **port) 313 { 314 struct device_node *ports = of_get_parent(*port); 315 struct device_node *ep = NULL; 316 struct device_node *rep = NULL; 317 318 /* 319 * multi { 320 * ports { 321 * => lnk: port@0 { ... }; 322 * port@1 { ep { ... = rep0 } }; 323 * port@2 { ep { ... = rep1 } }; 324 * ... 325 * }; 326 * }; 327 * 328 * xxx { 329 * port@0 { rep0 }; 330 * port@1 { rep1 }; 331 * }; 332 */ 333 do { 334 *port = of_get_next_child(ports, *port); 335 if (!*port) 336 break; 337 } while (!of_node_name_eq(*port, "port")); 338 339 if (*port) { 340 ep = port_to_endpoint(*port); 341 rep = of_graph_get_remote_endpoint(ep); 342 } 343 344 of_node_put(ep); 345 of_node_put(ports); 346 347 return rep; 348 } 349 350 static const struct snd_soc_ops graph_ops = { 351 .startup = asoc_simple_startup, 352 .shutdown = asoc_simple_shutdown, 353 .hw_params = asoc_simple_hw_params, 354 }; 355 356 static void graph_parse_convert(struct device_node *ep, 357 struct simple_dai_props *props) 358 { 359 struct device_node *port = of_get_parent(ep); 360 struct device_node *ports = of_get_parent(port); 361 struct asoc_simple_data *adata = &props->adata; 362 363 if (of_node_name_eq(ports, "ports")) 364 asoc_simple_parse_convert(ports, NULL, adata); 365 asoc_simple_parse_convert(port, NULL, adata); 366 asoc_simple_parse_convert(ep, NULL, adata); 367 368 of_node_put(port); 369 of_node_put(ports); 370 } 371 372 static void graph_parse_mclk_fs(struct device_node *ep, 373 struct simple_dai_props *props) 374 { 375 struct device_node *port = of_get_parent(ep); 376 struct device_node *ports = of_get_parent(port); 377 378 if (of_node_name_eq(ports, "ports")) 379 of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); 380 of_property_read_u32(port, "mclk-fs", &props->mclk_fs); 381 of_property_read_u32(ep, "mclk-fs", &props->mclk_fs); 382 383 of_node_put(port); 384 of_node_put(ports); 385 } 386 387 static int __graph_parse_node(struct asoc_simple_priv *priv, 388 enum graph_type gtype, 389 struct device_node *ep, 390 struct link_info *li, 391 int is_cpu, int idx) 392 { 393 struct device *dev = simple_priv_to_dev(priv); 394 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 395 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 396 struct snd_soc_dai_link_component *dlc; 397 struct asoc_simple_dai *dai; 398 int ret, is_single_links = 0; 399 400 if (is_cpu) { 401 dlc = asoc_link_to_cpu(dai_link, idx); 402 dai = simple_props_to_dai_cpu(dai_props, idx); 403 } else { 404 dlc = asoc_link_to_codec(dai_link, idx); 405 dai = simple_props_to_dai_codec(dai_props, idx); 406 } 407 408 graph_parse_mclk_fs(ep, dai_props); 409 410 ret = asoc_graph_parse_dai(ep, dlc, &is_single_links); 411 if (ret < 0) 412 return ret; 413 414 ret = asoc_simple_parse_tdm(ep, dai); 415 if (ret < 0) 416 return ret; 417 418 ret = asoc_simple_parse_tdm_width_map(dev, ep, dai); 419 if (ret < 0) 420 return ret; 421 422 ret = asoc_simple_parse_clk(dev, ep, dai, dlc); 423 if (ret < 0) 424 return ret; 425 426 /* 427 * set DAI Name 428 */ 429 if (!dai_link->name) { 430 struct snd_soc_dai_link_component *cpus = dlc; 431 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx); 432 char *cpu_multi = ""; 433 char *codec_multi = ""; 434 435 if (dai_link->num_cpus > 1) 436 cpu_multi = "_multi"; 437 if (dai_link->num_codecs > 1) 438 codec_multi = "_multi"; 439 440 switch (gtype) { 441 case GRAPH_NORMAL: 442 /* run is_cpu only. see audio_graph2_link_normal() */ 443 if (is_cpu) 444 asoc_simple_set_dailink_name(dev, dai_link, "%s%s-%s%s", 445 cpus->dai_name, cpu_multi, 446 codecs->dai_name, codec_multi); 447 break; 448 case GRAPH_DPCM: 449 if (is_cpu) 450 asoc_simple_set_dailink_name(dev, dai_link, "fe.%pOFP.%s%s", 451 cpus->of_node, cpus->dai_name, cpu_multi); 452 else 453 asoc_simple_set_dailink_name(dev, dai_link, "be.%pOFP.%s%s", 454 codecs->of_node, codecs->dai_name, codec_multi); 455 break; 456 case GRAPH_C2C: 457 /* run is_cpu only. see audio_graph2_link_c2c() */ 458 if (is_cpu) 459 asoc_simple_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s", 460 cpus->dai_name, cpu_multi, 461 codecs->dai_name, codec_multi); 462 break; 463 default: 464 break; 465 } 466 } 467 468 /* 469 * Check "prefix" from top node 470 * if DPCM-BE case 471 */ 472 if (!is_cpu && gtype == GRAPH_DPCM) { 473 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx); 474 struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx); 475 struct device_node *rport = of_get_parent(ep); 476 struct device_node *rports = of_get_parent(rport); 477 478 if (of_node_name_eq(rports, "ports")) 479 snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); 480 snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix"); 481 482 of_node_put(rport); 483 of_node_put(rports); 484 } 485 486 if (is_cpu) { 487 struct snd_soc_dai_link_component *cpus = dlc; 488 struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, idx); 489 490 asoc_simple_canonicalize_cpu(cpus, is_single_links); 491 asoc_simple_canonicalize_platform(platforms, cpus); 492 } 493 494 return 0; 495 } 496 497 static int graph_parse_node(struct asoc_simple_priv *priv, 498 enum graph_type gtype, 499 struct device_node *port, 500 struct link_info *li, int is_cpu) 501 { 502 struct device_node *ep; 503 int ret = 0; 504 505 if (graph_lnk_is_multi(port)) { 506 int idx; 507 508 of_node_get(port); 509 510 for (idx = 0;; idx++) { 511 ep = graph_get_next_multi_ep(&port); 512 if (!ep) 513 break; 514 515 ret = __graph_parse_node(priv, gtype, ep, 516 li, is_cpu, idx); 517 of_node_put(ep); 518 if (ret < 0) 519 break; 520 } 521 } else { 522 /* Single CPU / Codec */ 523 ep = port_to_endpoint(port); 524 ret = __graph_parse_node(priv, gtype, ep, li, is_cpu, 0); 525 of_node_put(ep); 526 } 527 528 return ret; 529 } 530 531 static void graph_parse_daifmt(struct device_node *node, 532 unsigned int *daifmt, unsigned int *bit_frame) 533 { 534 unsigned int fmt; 535 536 /* 537 * see also above "daifmt" explanation 538 * and samples. 539 */ 540 541 /* 542 * ports { 543 * (A) 544 * port { 545 * (B) 546 * endpoint { 547 * (C) 548 * }; 549 * }; 550 * }; 551 * }; 552 */ 553 554 /* 555 * clock_provider: 556 * 557 * It can be judged it is provider 558 * if (A) or (B) or (C) has bitclock-master / frame-master flag. 559 * 560 * use "or" 561 */ 562 *bit_frame |= snd_soc_daifmt_parse_clock_provider_as_bitmap(node, NULL); 563 564 #define update_daifmt(name) \ 565 if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) && \ 566 (fmt & SND_SOC_DAIFMT_##name##_MASK)) \ 567 *daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK 568 569 /* 570 * format 571 * 572 * This function is called by (C) -> (B) -> (A) order. 573 * Set if applicable part was not yet set. 574 */ 575 fmt = snd_soc_daifmt_parse_format(node, NULL); 576 update_daifmt(FORMAT); 577 update_daifmt(CLOCK); 578 update_daifmt(INV); 579 } 580 581 static void graph_link_init(struct asoc_simple_priv *priv, 582 struct device_node *port, 583 struct link_info *li, 584 int is_cpu_node) 585 { 586 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 587 struct device_node *ep; 588 struct device_node *ports; 589 unsigned int daifmt = 0, daiclk = 0; 590 unsigned int bit_frame = 0; 591 592 if (graph_lnk_is_multi(port)) { 593 of_node_get(port); 594 ep = graph_get_next_multi_ep(&port); 595 port = of_get_parent(ep); 596 } else { 597 ep = port_to_endpoint(port); 598 } 599 600 ports = of_get_parent(port); 601 602 /* 603 * ports { 604 * (A) 605 * port { 606 * (B) 607 * endpoint { 608 * (C) 609 * }; 610 * }; 611 * }; 612 * }; 613 */ 614 graph_parse_daifmt(ep, &daifmt, &bit_frame); /* (C) */ 615 graph_parse_daifmt(port, &daifmt, &bit_frame); /* (B) */ 616 if (of_node_name_eq(ports, "ports")) 617 graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */ 618 619 /* 620 * convert bit_frame 621 * We need to flip clock_provider if it was CPU node, 622 * because it is Codec base. 623 */ 624 daiclk = snd_soc_daifmt_clock_provider_from_bitmap(bit_frame); 625 if (is_cpu_node) 626 daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk); 627 628 dai_link->dai_fmt = daifmt | daiclk; 629 dai_link->init = asoc_simple_dai_init; 630 dai_link->ops = &graph_ops; 631 if (priv->ops) 632 dai_link->ops = priv->ops; 633 } 634 635 int audio_graph2_link_normal(struct asoc_simple_priv *priv, 636 struct device_node *lnk, 637 struct link_info *li) 638 { 639 struct device_node *cpu_port = lnk; 640 struct device_node *cpu_ep = port_to_endpoint(cpu_port); 641 struct device_node *codec_port = of_graph_get_remote_port(cpu_ep); 642 int ret; 643 644 /* 645 * call Codec first. 646 * see 647 * __graph_parse_node() :: DAI Naming 648 */ 649 ret = graph_parse_node(priv, GRAPH_NORMAL, codec_port, li, 0); 650 if (ret < 0) 651 goto err; 652 653 /* 654 * call CPU, and set DAI Name 655 */ 656 ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_port, li, 1); 657 if (ret < 0) 658 goto err; 659 660 graph_link_init(priv, cpu_port, li, 1); 661 err: 662 of_node_put(codec_port); 663 of_node_put(cpu_ep); 664 665 return ret; 666 } 667 EXPORT_SYMBOL_GPL(audio_graph2_link_normal); 668 669 int audio_graph2_link_dpcm(struct asoc_simple_priv *priv, 670 struct device_node *lnk, 671 struct link_info *li) 672 { 673 struct device_node *ep = port_to_endpoint(lnk); 674 struct device_node *rep = of_graph_get_remote_endpoint(ep); 675 struct device_node *rport = of_graph_get_remote_port(ep); 676 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 677 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 678 int is_cpu = asoc_graph_is_ports0(lnk); 679 int ret; 680 681 if (is_cpu) { 682 /* 683 * dpcm { 684 * // Front-End 685 * ports@0 { 686 * => lnk: port@0 { ep: { ... = rep }; }; 687 * ... 688 * }; 689 * // Back-End 690 * ports@0 { 691 * ... 692 * }; 693 * }; 694 * 695 * CPU { 696 * rports: ports { 697 * rport: port@0 { rep: { ... = ep } }; 698 * } 699 * } 700 */ 701 /* 702 * setup CPU here, Codec is already set as dummy. 703 * see 704 * asoc_simple_init_priv() 705 */ 706 dai_link->dynamic = 1; 707 dai_link->dpcm_merged_format = 1; 708 709 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 1); 710 if (ret) 711 goto err; 712 } else { 713 /* 714 * dpcm { 715 * // Front-End 716 * ports@0 { 717 * ... 718 * }; 719 * // Back-End 720 * ports@0 { 721 * => lnk: port@0 { ep: { ... = rep; }; }; 722 * ... 723 * }; 724 * }; 725 * 726 * Codec { 727 * rports: ports { 728 * rport: port@0 { rep: { ... = ep; }; }; 729 * } 730 * } 731 */ 732 /* 733 * setup Codec here, CPU is already set as dummy. 734 * see 735 * asoc_simple_init_priv() 736 */ 737 738 /* BE settings */ 739 dai_link->no_pcm = 1; 740 dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup; 741 742 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 0); 743 if (ret < 0) 744 goto err; 745 } 746 747 graph_parse_convert(ep, dai_props); /* at node of <dpcm> */ 748 graph_parse_convert(rep, dai_props); /* at node of <CPU/Codec> */ 749 750 snd_soc_dai_link_set_capabilities(dai_link); 751 752 graph_link_init(priv, rport, li, is_cpu); 753 err: 754 of_node_put(ep); 755 of_node_put(rep); 756 of_node_put(rport); 757 758 return ret; 759 } 760 EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm); 761 762 int audio_graph2_link_c2c(struct asoc_simple_priv *priv, 763 struct device_node *lnk, 764 struct link_info *li) 765 { 766 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 767 struct device_node *port0, *port1, *ports; 768 struct device_node *codec0_port, *codec1_port; 769 struct device_node *ep0, *ep1; 770 u32 val = 0; 771 int ret = -EINVAL; 772 773 /* 774 * codec2codec { 775 * ports { 776 * rate = <48000>; 777 * => lnk: port@0 { c2c0_ep: { ... = codec0_ep; }; }; 778 * port@1 { c2c1_ep: { ... = codec1_ep; }; }; 779 * }; 780 * }; 781 * 782 * Codec { 783 * ports { 784 * port@0 { codec0_ep: ... }; }; 785 * port@1 { codec1_ep: ... }; }; 786 * }; 787 * }; 788 */ 789 of_node_get(lnk); 790 port0 = lnk; 791 ports = of_get_parent(port0); 792 port1 = of_get_next_child(ports, lnk); 793 794 /* 795 * Card2 can use original Codec2Codec settings if DT has. 796 * It will use default settings if no settings on DT. 797 * see 798 * asoc_simple_init_for_codec2codec() 799 * 800 * Add more settings here if needed 801 */ 802 of_property_read_u32(ports, "rate", &val); 803 if (val) { 804 struct device *dev = simple_priv_to_dev(priv); 805 struct snd_soc_pcm_stream *c2c_conf; 806 807 c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL); 808 if (!c2c_conf) 809 goto err1; 810 811 c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ 812 c2c_conf->rates = SNDRV_PCM_RATE_8000_384000; 813 c2c_conf->rate_min = 814 c2c_conf->rate_max = val; 815 c2c_conf->channels_min = 816 c2c_conf->channels_max = 2; /* update ME */ 817 818 dai_link->c2c_params = c2c_conf; 819 dai_link->num_c2c_params = 1; 820 } 821 822 ep0 = port_to_endpoint(port0); 823 ep1 = port_to_endpoint(port1); 824 825 codec0_port = of_graph_get_remote_port(ep0); 826 codec1_port = of_graph_get_remote_port(ep1); 827 828 /* 829 * call Codec first. 830 * see 831 * __graph_parse_node() :: DAI Naming 832 */ 833 ret = graph_parse_node(priv, GRAPH_C2C, codec1_port, li, 0); 834 if (ret < 0) 835 goto err2; 836 837 /* 838 * call CPU, and set DAI Name 839 */ 840 ret = graph_parse_node(priv, GRAPH_C2C, codec0_port, li, 1); 841 if (ret < 0) 842 goto err2; 843 844 graph_link_init(priv, codec0_port, li, 1); 845 err2: 846 of_node_put(ep0); 847 of_node_put(ep1); 848 of_node_put(codec0_port); 849 of_node_put(codec1_port); 850 err1: 851 of_node_put(ports); 852 of_node_put(port0); 853 of_node_put(port1); 854 855 return ret; 856 } 857 EXPORT_SYMBOL_GPL(audio_graph2_link_c2c); 858 859 static int graph_link(struct asoc_simple_priv *priv, 860 struct graph2_custom_hooks *hooks, 861 enum graph_type gtype, 862 struct device_node *lnk, 863 struct link_info *li) 864 { 865 struct device *dev = simple_priv_to_dev(priv); 866 GRAPH2_CUSTOM func = NULL; 867 int ret = -EINVAL; 868 869 switch (gtype) { 870 case GRAPH_NORMAL: 871 if (hooks && hooks->custom_normal) 872 func = hooks->custom_normal; 873 else 874 func = audio_graph2_link_normal; 875 break; 876 case GRAPH_DPCM: 877 if (hooks && hooks->custom_dpcm) 878 func = hooks->custom_dpcm; 879 else 880 func = audio_graph2_link_dpcm; 881 break; 882 case GRAPH_C2C: 883 if (hooks && hooks->custom_c2c) 884 func = hooks->custom_c2c; 885 else 886 func = audio_graph2_link_c2c; 887 break; 888 default: 889 break; 890 } 891 892 if (!func) { 893 dev_err(dev, "non supported gtype (%d)\n", gtype); 894 goto err; 895 } 896 897 ret = func(priv, lnk, li); 898 if (ret < 0) 899 goto err; 900 901 li->link++; 902 err: 903 return ret; 904 } 905 906 static int graph_counter(struct device_node *lnk) 907 { 908 /* 909 * Multi CPU / Codec 910 * 911 * multi { 912 * ports { 913 * => lnk: port@0 { ... }; 914 * port@1 { ... }; 915 * port@2 { ... }; 916 * ... 917 * }; 918 * }; 919 * 920 * ignore first lnk part 921 */ 922 if (graph_lnk_is_multi(lnk)) 923 return of_graph_get_endpoint_count(of_get_parent(lnk)) - 1; 924 /* 925 * Single CPU / Codec 926 */ 927 else 928 return 1; 929 } 930 931 static int graph_count_normal(struct asoc_simple_priv *priv, 932 struct device_node *lnk, 933 struct link_info *li) 934 { 935 struct device_node *cpu_port = lnk; 936 struct device_node *cpu_ep = port_to_endpoint(cpu_port); 937 struct device_node *codec_port = of_graph_get_remote_port(cpu_ep); 938 939 /* 940 * CPU { 941 * => lnk: port { endpoint { .. }; }; 942 * }; 943 */ 944 /* 945 * DON'T REMOVE platforms 946 * see 947 * simple-card.c :: simple_count_noml() 948 */ 949 li->num[li->link].cpus = 950 li->num[li->link].platforms = graph_counter(cpu_port); 951 952 li->num[li->link].codecs = graph_counter(codec_port); 953 954 of_node_put(cpu_ep); 955 of_node_put(codec_port); 956 957 return 0; 958 } 959 960 static int graph_count_dpcm(struct asoc_simple_priv *priv, 961 struct device_node *lnk, 962 struct link_info *li) 963 { 964 struct device_node *ep = port_to_endpoint(lnk); 965 struct device_node *rport = of_graph_get_remote_port(ep); 966 967 /* 968 * dpcm { 969 * // Front-End 970 * ports@0 { 971 * => lnk: port@0 { endpoint { ... }; }; 972 * ... 973 * }; 974 * // Back-End 975 * ports@1 { 976 * => lnk: port@0 { endpoint { ... }; }; 977 * ... 978 * }; 979 * }; 980 */ 981 982 if (asoc_graph_is_ports0(lnk)) { 983 /* 984 * DON'T REMOVE platforms 985 * see 986 * simple-card.c :: simple_count_noml() 987 */ 988 li->num[li->link].cpus = graph_counter(rport); /* FE */ 989 li->num[li->link].platforms = graph_counter(rport); 990 } else { 991 li->num[li->link].codecs = graph_counter(rport); /* BE */ 992 } 993 994 of_node_put(ep); 995 of_node_put(rport); 996 997 return 0; 998 } 999 1000 static int graph_count_c2c(struct asoc_simple_priv *priv, 1001 struct device_node *lnk, 1002 struct link_info *li) 1003 { 1004 struct device_node *ports = of_get_parent(lnk); 1005 struct device_node *port0 = lnk; 1006 struct device_node *port1 = of_get_next_child(ports, lnk); 1007 struct device_node *ep0 = port_to_endpoint(port0); 1008 struct device_node *ep1 = port_to_endpoint(port1); 1009 struct device_node *codec0 = of_graph_get_remote_port(ep0); 1010 struct device_node *codec1 = of_graph_get_remote_port(ep1); 1011 1012 of_node_get(lnk); 1013 1014 /* 1015 * codec2codec { 1016 * ports { 1017 * => lnk: port@0 { endpoint { ... }; }; 1018 * port@1 { endpoint { ... }; }; 1019 * }; 1020 * }; 1021 */ 1022 /* 1023 * DON'T REMOVE platforms 1024 * see 1025 * simple-card.c :: simple_count_noml() 1026 */ 1027 li->num[li->link].cpus = 1028 li->num[li->link].platforms = graph_counter(codec0); 1029 1030 li->num[li->link].codecs = graph_counter(codec1); 1031 1032 of_node_put(ports); 1033 of_node_put(port1); 1034 of_node_put(ep0); 1035 of_node_put(ep1); 1036 of_node_put(codec0); 1037 of_node_put(codec1); 1038 1039 return 0; 1040 } 1041 1042 static int graph_count(struct asoc_simple_priv *priv, 1043 struct graph2_custom_hooks *hooks, 1044 enum graph_type gtype, 1045 struct device_node *lnk, 1046 struct link_info *li) 1047 { 1048 struct device *dev = simple_priv_to_dev(priv); 1049 GRAPH2_CUSTOM func = NULL; 1050 int ret = -EINVAL; 1051 1052 if (li->link >= SNDRV_MAX_LINKS) { 1053 dev_err(dev, "too many links\n"); 1054 return ret; 1055 } 1056 1057 switch (gtype) { 1058 case GRAPH_NORMAL: 1059 func = graph_count_normal; 1060 break; 1061 case GRAPH_DPCM: 1062 func = graph_count_dpcm; 1063 break; 1064 case GRAPH_C2C: 1065 func = graph_count_c2c; 1066 break; 1067 default: 1068 break; 1069 } 1070 1071 if (!func) { 1072 dev_err(dev, "non supported gtype (%d)\n", gtype); 1073 goto err; 1074 } 1075 1076 ret = func(priv, lnk, li); 1077 if (ret < 0) 1078 goto err; 1079 1080 li->link++; 1081 err: 1082 return ret; 1083 } 1084 1085 static int graph_for_each_link(struct asoc_simple_priv *priv, 1086 struct graph2_custom_hooks *hooks, 1087 struct link_info *li, 1088 int (*func)(struct asoc_simple_priv *priv, 1089 struct graph2_custom_hooks *hooks, 1090 enum graph_type gtype, 1091 struct device_node *lnk, 1092 struct link_info *li)) 1093 { 1094 struct of_phandle_iterator it; 1095 struct device *dev = simple_priv_to_dev(priv); 1096 struct device_node *node = dev->of_node; 1097 struct device_node *lnk; 1098 enum graph_type gtype; 1099 int rc, ret; 1100 1101 /* loop for all listed CPU port */ 1102 of_for_each_phandle(&it, rc, node, "links", NULL, 0) { 1103 lnk = it.node; 1104 1105 gtype = graph_get_type(priv, lnk); 1106 1107 ret = func(priv, hooks, gtype, lnk, li); 1108 if (ret < 0) 1109 return ret; 1110 } 1111 1112 return 0; 1113 } 1114 1115 int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev, 1116 struct graph2_custom_hooks *hooks) 1117 { 1118 struct snd_soc_card *card = simple_priv_to_card(priv); 1119 struct link_info *li; 1120 int ret; 1121 1122 li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); 1123 if (!li) 1124 return -ENOMEM; 1125 1126 card->probe = asoc_graph_card_probe; 1127 card->owner = THIS_MODULE; 1128 card->dev = dev; 1129 1130 if ((hooks) && (hooks)->hook_pre) { 1131 ret = (hooks)->hook_pre(priv); 1132 if (ret < 0) 1133 goto err; 1134 } 1135 1136 ret = graph_for_each_link(priv, hooks, li, graph_count); 1137 if (!li->link) 1138 ret = -EINVAL; 1139 if (ret < 0) 1140 goto err; 1141 1142 ret = asoc_simple_init_priv(priv, li); 1143 if (ret < 0) 1144 goto err; 1145 1146 priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW); 1147 if (IS_ERR(priv->pa_gpio)) { 1148 ret = PTR_ERR(priv->pa_gpio); 1149 dev_err(dev, "failed to get amplifier gpio: %d\n", ret); 1150 goto err; 1151 } 1152 1153 ret = asoc_simple_parse_widgets(card, NULL); 1154 if (ret < 0) 1155 goto err; 1156 1157 ret = asoc_simple_parse_routing(card, NULL); 1158 if (ret < 0) 1159 goto err; 1160 1161 memset(li, 0, sizeof(*li)); 1162 ret = graph_for_each_link(priv, hooks, li, graph_link); 1163 if (ret < 0) 1164 goto err; 1165 1166 ret = asoc_simple_parse_card_name(card, NULL); 1167 if (ret < 0) 1168 goto err; 1169 1170 snd_soc_card_set_drvdata(card, priv); 1171 1172 if ((hooks) && (hooks)->hook_post) { 1173 ret = (hooks)->hook_post(priv); 1174 if (ret < 0) 1175 goto err; 1176 } 1177 1178 asoc_simple_debug_info(priv); 1179 1180 ret = devm_snd_soc_register_card(dev, card); 1181 err: 1182 devm_kfree(dev, li); 1183 1184 if (ret < 0) 1185 dev_err_probe(dev, ret, "parse error\n"); 1186 1187 return ret; 1188 } 1189 EXPORT_SYMBOL_GPL(audio_graph2_parse_of); 1190 1191 static int graph_probe(struct platform_device *pdev) 1192 { 1193 struct asoc_simple_priv *priv; 1194 struct device *dev = &pdev->dev; 1195 1196 /* Allocate the private data and the DAI link array */ 1197 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1198 if (!priv) 1199 return -ENOMEM; 1200 1201 return audio_graph2_parse_of(priv, dev, NULL); 1202 } 1203 1204 static const struct of_device_id graph_of_match[] = { 1205 { .compatible = "audio-graph-card2", }, 1206 {}, 1207 }; 1208 MODULE_DEVICE_TABLE(of, graph_of_match); 1209 1210 static struct platform_driver graph_card = { 1211 .driver = { 1212 .name = "asoc-audio-graph-card2", 1213 .pm = &snd_soc_pm_ops, 1214 .of_match_table = graph_of_match, 1215 }, 1216 .probe = graph_probe, 1217 .remove = asoc_simple_remove, 1218 }; 1219 module_platform_driver(graph_card); 1220 1221 MODULE_ALIAS("platform:asoc-audio-graph-card2"); 1222 MODULE_LICENSE("GPL v2"); 1223 MODULE_DESCRIPTION("ASoC Audio Graph Card2"); 1224 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 1225