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