Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Mar 24-27, 2025, special US time zones
Register
Loading...
v6.2
   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
  76It has connection part (= X) and list part (= y).
  77links 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
 216enum 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
 230static 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
 267out_put:
 268	of_node_put(np);
 269	return ret;
 270
 271}
 272
 273static 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
 307static int graph_lnk_is_multi(struct device_node *lnk)
 308{
 309	return __graph_get_type(lnk) == GRAPH_MULTI;
 310}
 311
 312static 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
 350static 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
 356static int graph_get_dai_id(struct device_node *ep)
 357{
 358	struct device_node *node;
 359	struct device_node *endpoint;
 360	struct of_endpoint info;
 361	int i, id;
 362	const u32 *reg;
 363	int ret;
 364
 365	/* use driver specified DAI ID if exist */
 366	ret = snd_soc_get_dai_id(ep);
 367	if (ret != -ENOTSUPP)
 368		return ret;
 369
 370	/* use endpoint/port reg if exist */
 371	ret = of_graph_parse_endpoint(ep, &info);
 372	if (ret == 0) {
 373		/*
 374		 * Because it will count port/endpoint if it doesn't have "reg".
 375		 * But, we can't judge whether it has "no reg", or "reg = <0>"
 376		 * only of_graph_parse_endpoint().
 377		 * We need to check "reg" property
 378		 */
 379		if (of_get_property(ep,   "reg", NULL))
 380			return info.id;
 381
 382		node = of_get_parent(ep);
 383		reg = of_get_property(node, "reg", NULL);
 384		of_node_put(node);
 385		if (reg)
 386			return info.port;
 387	}
 388	node = of_graph_get_port_parent(ep);
 389
 390	/*
 391	 * Non HDMI sound case, counting port/endpoint on its DT
 392	 * is enough. Let's count it.
 393	 */
 394	i = 0;
 395	id = -1;
 396	for_each_endpoint_of_node(node, endpoint) {
 397		if (endpoint == ep)
 398			id = i;
 399		i++;
 400	}
 401
 402	of_node_put(node);
 403
 404	if (id < 0)
 405		return -ENODEV;
 406
 407	return id;
 408}
 409
 410static int asoc_simple_parse_dai(struct device_node *ep,
 411				 struct snd_soc_dai_link_component *dlc,
 412				 int *is_single_link)
 413{
 414	struct device_node *node;
 415	struct of_phandle_args args;
 416	int ret;
 417
 418	if (!ep)
 419		return 0;
 420
 421	node = of_graph_get_port_parent(ep);
 422
 423	/* Get dai->name */
 424	args.np		= node;
 425	args.args[0]	= graph_get_dai_id(ep);
 426	args.args_count	= (of_graph_get_endpoint_count(node) > 1);
 427
 428	/*
 429	 * FIXME
 430	 *
 431	 * Here, dlc->dai_name is pointer to CPU/Codec DAI name.
 432	 * If user unbinded CPU or Codec driver, but not for Sound Card,
 433	 * dlc->dai_name is keeping unbinded CPU or Codec
 434	 * driver's pointer.
 435	 *
 436	 * If user re-bind CPU or Codec driver again, ALSA SoC will try
 437	 * to rebind Card via snd_soc_try_rebind_card(), but because of
 438	 * above reason, it might can't bind Sound Card.
 439	 * Because Sound Card is pointing to released dai_name pointer.
 440	 *
 441	 * To avoid this rebind Card issue,
 442	 * 1) It needs to alloc memory to keep dai_name eventhough
 443	 *    CPU or Codec driver was unbinded, or
 444	 * 2) user need to rebind Sound Card everytime
 445	 *    if he unbinded CPU or Codec.
 446	 */
 447	ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
 448	if (ret < 0) {
 449		of_node_put(node);
 450		return ret;
 451	}
 452
 453	dlc->of_node = node;
 454
 455	if (is_single_link)
 456		*is_single_link = of_graph_get_endpoint_count(node) == 1;
 457
 458	return 0;
 459}
 460
 461static void graph_parse_convert(struct device_node *ep,
 462				struct simple_dai_props *props)
 463{
 464	struct device_node *port = of_get_parent(ep);
 465	struct device_node *ports = of_get_parent(port);
 466	struct asoc_simple_data *adata = &props->adata;
 467
 468	if (of_node_name_eq(ports, "ports"))
 469		asoc_simple_parse_convert(ports, NULL, adata);
 470	asoc_simple_parse_convert(port, NULL, adata);
 471	asoc_simple_parse_convert(ep,   NULL, adata);
 472
 473	of_node_put(port);
 474	of_node_put(ports);
 475}
 476
 477static void graph_parse_mclk_fs(struct device_node *ep,
 478				struct simple_dai_props *props)
 479{
 480	struct device_node *port	= of_get_parent(ep);
 481	struct device_node *ports	= of_get_parent(port);
 482
 483	if (of_node_name_eq(ports, "ports"))
 484		of_property_read_u32(ports, "mclk-fs", &props->mclk_fs);
 485	of_property_read_u32(port,	"mclk-fs", &props->mclk_fs);
 486	of_property_read_u32(ep,	"mclk-fs", &props->mclk_fs);
 487
 488	of_node_put(port);
 489	of_node_put(ports);
 490}
 491
 492static int __graph_parse_node(struct asoc_simple_priv *priv,
 493			      enum graph_type gtype,
 494			      struct device_node *ep,
 495			      struct link_info *li,
 496			      int is_cpu, int idx)
 497{
 498	struct device *dev = simple_priv_to_dev(priv);
 499	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
 500	struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
 501	struct snd_soc_dai_link_component *dlc;
 502	struct asoc_simple_dai *dai;
 503	int ret, is_single_links = 0;
 504
 505	if (is_cpu) {
 506		dlc = asoc_link_to_cpu(dai_link, idx);
 507		dai = simple_props_to_dai_cpu(dai_props, idx);
 508	} else {
 509		dlc = asoc_link_to_codec(dai_link, idx);
 510		dai = simple_props_to_dai_codec(dai_props, idx);
 511	}
 512
 513	graph_parse_mclk_fs(ep, dai_props);
 514
 515	ret = asoc_simple_parse_dai(ep, dlc, &is_single_links);
 516	if (ret < 0)
 517		return ret;
 518
 519	ret = asoc_simple_parse_tdm(ep, dai);
 520	if (ret < 0)
 521		return ret;
 522
 523	ret = asoc_simple_parse_tdm_width_map(dev, ep, dai);
 524	if (ret < 0)
 525		return ret;
 526
 527	ret = asoc_simple_parse_clk(dev, ep, dai, dlc);
 528	if (ret < 0)
 529		return ret;
 530
 531	/*
 532	 * set DAI Name
 533	 */
 534	if (!dai_link->name) {
 535		struct snd_soc_dai_link_component *cpus = dlc;
 536		struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx);
 537		char *cpu_multi   = "";
 538		char *codec_multi = "";
 539
 540		if (dai_link->num_cpus > 1)
 541			cpu_multi = "_multi";
 542		if (dai_link->num_codecs > 1)
 543			codec_multi = "_multi";
 544
 545		switch (gtype) {
 546		case GRAPH_NORMAL:
 547			/* run is_cpu only. see audio_graph2_link_normal() */
 548			if (is_cpu)
 549				asoc_simple_set_dailink_name(dev, dai_link, "%s%s-%s%s",
 550							       cpus->dai_name,   cpu_multi,
 551							     codecs->dai_name, codec_multi);
 552			break;
 553		case GRAPH_DPCM:
 554			if (is_cpu)
 555				asoc_simple_set_dailink_name(dev, dai_link, "fe.%pOFP.%s%s",
 556						cpus->of_node, cpus->dai_name, cpu_multi);
 557			else
 558				asoc_simple_set_dailink_name(dev, dai_link, "be.%pOFP.%s%s",
 559						codecs->of_node, codecs->dai_name, codec_multi);
 560			break;
 561		case GRAPH_C2C:
 562			/* run is_cpu only. see audio_graph2_link_c2c() */
 563			if (is_cpu)
 564				asoc_simple_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s",
 565							     cpus->dai_name,   cpu_multi,
 566							     codecs->dai_name, codec_multi);
 567			break;
 568		default:
 569			break;
 570		}
 571	}
 572
 573	/*
 574	 * Check "prefix" from top node
 575	 * if DPCM-BE case
 576	 */
 577	if (!is_cpu && gtype == GRAPH_DPCM) {
 578		struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx);
 579		struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx);
 580		struct device_node *rport  = of_get_parent(ep);
 581		struct device_node *rports = of_get_parent(rport);
 582
 583		if (of_node_name_eq(rports, "ports"))
 584			snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix");
 585		snd_soc_of_parse_node_prefix(rport,  cconf, codecs->of_node, "prefix");
 586
 587		of_node_put(rport);
 588		of_node_put(rports);
 589	}
 590
 591	if (is_cpu) {
 592		struct snd_soc_dai_link_component *cpus = dlc;
 593		struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, idx);
 594
 595		asoc_simple_canonicalize_cpu(cpus, is_single_links);
 596		asoc_simple_canonicalize_platform(platforms, cpus);
 597	}
 598
 599	return 0;
 600}
 601
 602static int graph_parse_node(struct asoc_simple_priv *priv,
 603			    enum graph_type gtype,
 604			    struct device_node *port,
 605			    struct link_info *li, int is_cpu)
 606{
 607	struct device_node *ep;
 608	int ret = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 609
 610	if (graph_lnk_is_multi(port)) {
 611		int idx;
 612
 613		of_node_get(port);
 
 
 
 
 614
 615		for (idx = 0;; idx++) {
 616			ep = graph_get_next_multi_ep(&port);
 617			if (!ep)
 618				break;
 619
 620			ret = __graph_parse_node(priv, gtype, ep,
 621						 li, is_cpu, idx);
 622			of_node_put(ep);
 623			if (ret < 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 624				break;
 
 
 625		}
 626	} else {
 627		/* Single CPU / Codec */
 628		ep = port_to_endpoint(port);
 629		ret = __graph_parse_node(priv, gtype, ep, li, is_cpu, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 630		of_node_put(ep);
 
 
 
 
 
 
 
 
 
 631	}
 632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 633	return ret;
 634}
 635
 
 
 
 
 
 
 
 
 
 
 
 636static void graph_parse_daifmt(struct device_node *node,
 637			       unsigned int *daifmt, unsigned int *bit_frame)
 638{
 639	unsigned int fmt;
 640
 641	/*
 642	 * see also above "daifmt" explanation
 643	 * and samples.
 644	 */
 645
 646	/*
 647	 *	ports {
 648	 * (A)
 649	 *		port {
 650	 * (B)
 651	 *			endpoint {
 652	 * (C)
 653	 *			};
 654	 *		};
 655	 *	};
 656	 * };
 657	 */
 658
 659	/*
 660	 * clock_provider:
 661	 *
 662	 * It can be judged it is provider
 663	 * if (A) or (B) or (C) has bitclock-master / frame-master flag.
 664	 *
 665	 * use "or"
 666	 */
 667	*bit_frame |= snd_soc_daifmt_parse_clock_provider_as_bitmap(node, NULL);
 668
 669#define update_daifmt(name)					\
 670	if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) &&	\
 671		 (fmt & SND_SOC_DAIFMT_##name##_MASK))		\
 672		*daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK
 673
 674	/*
 675	 * format
 676	 *
 677	 * This function is called by (C) -> (B) -> (A) order.
 678	 * Set if applicable part was not yet set.
 679	 */
 680	fmt = snd_soc_daifmt_parse_format(node, NULL);
 681	update_daifmt(FORMAT);
 682	update_daifmt(CLOCK);
 683	update_daifmt(INV);
 684}
 685
 686static void graph_link_init(struct asoc_simple_priv *priv,
 687			    struct device_node *port,
 688			    struct link_info *li,
 689			    int is_cpu_node)
 690{
 691	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
 692	struct device_node *ep;
 693	struct device_node *ports;
 694	unsigned int daifmt = 0, daiclk = 0;
 
 695	unsigned int bit_frame = 0;
 696
 697	if (graph_lnk_is_multi(port)) {
 698		of_node_get(port);
 699		ep = graph_get_next_multi_ep(&port);
 700		port = of_get_parent(ep);
 701	} else {
 702		ep = port_to_endpoint(port);
 703	}
 704
 705	ports = of_get_parent(port);
 706
 707	/*
 708	 *	ports {
 709	 * (A)
 710	 *		port {
 711	 * (B)
 712	 *			endpoint {
 713	 * (C)
 714	 *			};
 715	 *		};
 716	 *	};
 717	 * };
 718	 */
 719	graph_parse_daifmt(ep,    &daifmt, &bit_frame);		/* (C) */
 720	graph_parse_daifmt(port,  &daifmt, &bit_frame);		/* (B) */
 721	if (of_node_name_eq(ports, "ports"))
 722		graph_parse_daifmt(ports, &daifmt, &bit_frame);	/* (A) */
 723
 724	/*
 725	 * convert bit_frame
 726	 * We need to flip clock_provider if it was CPU node,
 727	 * because it is Codec base.
 728	 */
 729	daiclk = snd_soc_daifmt_clock_provider_from_bitmap(bit_frame);
 730	if (is_cpu_node)
 731		daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk);
 732
 
 
 
 
 
 733	dai_link->dai_fmt	= daifmt | daiclk;
 734	dai_link->init		= asoc_simple_dai_init;
 735	dai_link->ops		= &graph_ops;
 736	if (priv->ops)
 737		dai_link->ops	= priv->ops;
 738}
 739
 740int audio_graph2_link_normal(struct asoc_simple_priv *priv,
 741			     struct device_node *lnk,
 742			     struct link_info *li)
 743{
 744	struct device_node *cpu_port = lnk;
 745	struct device_node *cpu_ep = port_to_endpoint(cpu_port);
 746	struct device_node *codec_port = of_graph_get_remote_port(cpu_ep);
 747	int ret;
 748
 749	/*
 750	 * call Codec first.
 751	 * see
 752	 *	__graph_parse_node() :: DAI Naming
 753	 */
 754	ret = graph_parse_node(priv, GRAPH_NORMAL, codec_port, li, 0);
 755	if (ret < 0)
 756		goto err;
 757
 758	/*
 759	 * call CPU, and set DAI Name
 760	 */
 761	ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_port, li, 1);
 762	if (ret < 0)
 763		goto err;
 764
 765	graph_link_init(priv, cpu_port, li, 1);
 766err:
 767	of_node_put(codec_port);
 768	of_node_put(cpu_ep);
 769
 770	return ret;
 771}
 772EXPORT_SYMBOL_GPL(audio_graph2_link_normal);
 773
 774int audio_graph2_link_dpcm(struct asoc_simple_priv *priv,
 775			   struct device_node *lnk,
 776			   struct link_info *li)
 777{
 778	struct device_node *ep = port_to_endpoint(lnk);
 779	struct device_node *rep = of_graph_get_remote_endpoint(ep);
 780	struct device_node *rport = of_graph_get_remote_port(ep);
 781	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
 782	struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
 783	int is_cpu = asoc_graph_is_ports0(lnk);
 784	int ret;
 785
 786	if (is_cpu) {
 787		/*
 788		 * dpcm {
 789		 *	// Front-End
 790		 *	ports@0 {
 791		 * =>		lnk: port@0 { ep: { ... = rep }; };
 792		 *		 ...
 793		 *	};
 794		 *	// Back-End
 795		 *	ports@0 {
 796		 *		 ...
 797		 *	};
 798		 * };
 799		 *
 800		 * CPU {
 801		 *	rports: ports {
 802		 *		rport: port@0 { rep: { ... = ep } };
 803		 *	}
 804		 * }
 805		 */
 806		/*
 807		 * setup CPU here, Codec is already set as dummy.
 808		 * see
 809		 *	asoc_simple_init_priv()
 810		 */
 811		dai_link->dynamic		= 1;
 812		dai_link->dpcm_merged_format	= 1;
 813
 814		ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 1);
 815		if (ret)
 816			goto err;
 817	} else {
 818		/*
 819		 * dpcm {
 820		 *	// Front-End
 821		 *	ports@0 {
 822		 *		 ...
 823		 *	};
 824		 *	// Back-End
 825		 *	ports@0 {
 826		 * =>		lnk: port@0 { ep: { ... = rep; }; };
 827		 *		 ...
 828		 *	};
 829		 * };
 830		 *
 831		 * Codec {
 832		 *	rports: ports {
 833		 *		rport: port@0 { rep: { ... = ep; }; };
 834		 *	}
 835		 * }
 836		 */
 837		/*
 838		 * setup Codec here, CPU is already set as dummy.
 839		 * see
 840		 *	asoc_simple_init_priv()
 841		 */
 842
 843		/* BE settings */
 844		dai_link->no_pcm		= 1;
 845		dai_link->be_hw_params_fixup	= asoc_simple_be_hw_params_fixup;
 846
 847		ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 0);
 848		if (ret < 0)
 849			goto err;
 850	}
 851
 852	graph_parse_convert(ep,  dai_props); /* at node of <dpcm> */
 853	graph_parse_convert(rep, dai_props); /* at node of <CPU/Codec> */
 854
 855	snd_soc_dai_link_set_capabilities(dai_link);
 856
 857	graph_link_init(priv, rport, li, is_cpu);
 858err:
 859	of_node_put(ep);
 860	of_node_put(rep);
 861	of_node_put(rport);
 862
 863	return ret;
 864}
 865EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm);
 866
 867int audio_graph2_link_c2c(struct asoc_simple_priv *priv,
 868			  struct device_node *lnk,
 869			  struct link_info *li)
 870{
 871	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
 872	struct device_node *port0, *port1, *ports;
 873	struct device_node *codec0_port, *codec1_port;
 874	struct device_node *ep0, *ep1;
 875	u32 val = 0;
 876	int ret = -EINVAL;
 877
 878	/*
 879	 * codec2codec {
 880	 *	ports {
 881	 *		rate = <48000>;
 882	 * =>	lnk:	port@0 { c2c0_ep: { ... = codec0_ep; }; };
 883	 *		port@1 { c2c1_ep: { ... = codec1_ep; }; };
 884	 *	};
 885	 * };
 886	 *
 887	 * Codec {
 888	 *	ports {
 889	 *		port@0 { codec0_ep: ... }; };
 890	 *		port@1 { codec1_ep: ... }; };
 891	 *	};
 892	 * };
 893	 */
 894	of_node_get(lnk);
 895	port0 = lnk;
 896	ports = of_get_parent(port0);
 897	port1 = of_get_next_child(ports, lnk);
 898
 899	/*
 900	 * Card2 can use original Codec2Codec settings if DT has.
 901	 * It will use default settings if no settings on DT.
 902	 * see
 903	 *	asoc_simple_init_for_codec2codec()
 904	 *
 905	 * Add more settings here if needed
 906	 */
 907	of_property_read_u32(ports, "rate", &val);
 908	if (val) {
 909		struct device *dev = simple_priv_to_dev(priv);
 910		struct snd_soc_pcm_stream *c2c_conf;
 911
 912		c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL);
 913		if (!c2c_conf)
 914			goto err1;
 915
 916		c2c_conf->formats	= SNDRV_PCM_FMTBIT_S32_LE; /* update ME */
 917		c2c_conf->rates		= SNDRV_PCM_RATE_8000_384000;
 918		c2c_conf->rate_min	=
 919		c2c_conf->rate_max	= val;
 920		c2c_conf->channels_min	=
 921		c2c_conf->channels_max	= 2; /* update ME */
 922
 923		dai_link->params	= c2c_conf;
 924		dai_link->num_params	= 1;
 925	}
 926
 927	ep0 = port_to_endpoint(port0);
 928	ep1 = port_to_endpoint(port1);
 929
 930	codec0_port = of_graph_get_remote_port(ep0);
 931	codec1_port = of_graph_get_remote_port(ep1);
 932
 933	/*
 934	 * call Codec first.
 935	 * see
 936	 *	__graph_parse_node() :: DAI Naming
 937	 */
 938	ret = graph_parse_node(priv, GRAPH_C2C, codec1_port, li, 0);
 939	if (ret < 0)
 940		goto err2;
 941
 942	/*
 943	 * call CPU, and set DAI Name
 944	 */
 945	ret = graph_parse_node(priv, GRAPH_C2C, codec0_port, li, 1);
 946	if (ret < 0)
 947		goto err2;
 948
 949	graph_link_init(priv, codec0_port, li, 1);
 950err2:
 951	of_node_put(ep0);
 952	of_node_put(ep1);
 953	of_node_put(codec0_port);
 954	of_node_put(codec1_port);
 955err1:
 956	of_node_put(ports);
 957	of_node_put(port0);
 958	of_node_put(port1);
 959
 960	return ret;
 961}
 962EXPORT_SYMBOL_GPL(audio_graph2_link_c2c);
 963
 964static int graph_link(struct asoc_simple_priv *priv,
 965		      struct graph2_custom_hooks *hooks,
 966		      enum graph_type gtype,
 967		      struct device_node *lnk,
 968		      struct link_info *li)
 969{
 970	struct device *dev = simple_priv_to_dev(priv);
 971	GRAPH2_CUSTOM func = NULL;
 972	int ret = -EINVAL;
 973
 974	switch (gtype) {
 975	case GRAPH_NORMAL:
 976		if (hooks && hooks->custom_normal)
 977			func = hooks->custom_normal;
 978		else
 979			func = audio_graph2_link_normal;
 980		break;
 981	case GRAPH_DPCM:
 982		if (hooks && hooks->custom_dpcm)
 983			func = hooks->custom_dpcm;
 984		else
 985			func = audio_graph2_link_dpcm;
 986		break;
 987	case GRAPH_C2C:
 988		if (hooks && hooks->custom_c2c)
 989			func = hooks->custom_c2c;
 990		else
 991			func = audio_graph2_link_c2c;
 992		break;
 993	default:
 994		break;
 995	}
 996
 997	if (!func) {
 998		dev_err(dev, "non supported gtype (%d)\n", gtype);
 999		goto err;
1000	}
1001
1002	ret = func(priv, lnk, li);
1003	if (ret < 0)
1004		goto err;
1005
1006	li->link++;
1007err:
1008	return ret;
1009}
1010
1011static int graph_counter(struct device_node *lnk)
1012{
1013	/*
1014	 * Multi CPU / Codec
1015	 *
1016	 * multi {
1017	 *	ports {
1018	 * =>		lnk:	port@0 { ... };
1019	 *			port@1 { ... };
1020	 *			port@2 { ... };
1021	 *			...
1022	 *	};
1023	 * };
1024	 *
1025	 * ignore first lnk part
1026	 */
1027	if (graph_lnk_is_multi(lnk))
1028		return of_graph_get_endpoint_count(of_get_parent(lnk)) - 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1029	/*
1030	 * Single CPU / Codec
1031	 */
1032	else
1033		return 1;
1034}
1035
1036static int graph_count_normal(struct asoc_simple_priv *priv,
1037			      struct device_node *lnk,
1038			      struct link_info *li)
1039{
1040	struct device_node *cpu_port = lnk;
1041	struct device_node *cpu_ep = port_to_endpoint(cpu_port);
1042	struct device_node *codec_port = of_graph_get_remote_port(cpu_ep);
1043
1044	/*
1045	 *	CPU {
1046	 * =>		lnk: port { endpoint { .. }; };
1047	 *	};
1048	 */
 
 
 
 
 
1049	li->num[li->link].cpus		=
1050	li->num[li->link].platforms	= graph_counter(cpu_port);
 
1051	li->num[li->link].codecs	= graph_counter(codec_port);
1052
1053	of_node_put(cpu_ep);
1054	of_node_put(codec_port);
1055
1056	return 0;
1057}
1058
1059static int graph_count_dpcm(struct asoc_simple_priv *priv,
1060			    struct device_node *lnk,
1061			    struct link_info *li)
1062{
1063	struct device_node *ep = port_to_endpoint(lnk);
1064	struct device_node *rport = of_graph_get_remote_port(ep);
1065
1066	/*
1067	 * dpcm {
1068	 *	// Front-End
1069	 *	ports@0 {
1070	 * =>		lnk: port@0 { endpoint { ... }; };
1071	 *		 ...
1072	 *	};
1073	 *	// Back-End
1074	 *	ports@1 {
1075	 * =>		lnk: port@0 { endpoint { ... }; };
1076	 *		 ...
1077	 *	};
1078	 * };
1079	 */
1080
1081	if (asoc_graph_is_ports0(lnk)) {
 
 
 
 
 
1082		li->num[li->link].cpus		= graph_counter(rport); /* FE */
1083		li->num[li->link].platforms	= graph_counter(rport);
1084	} else {
1085		li->num[li->link].codecs	= graph_counter(rport); /* BE */
1086	}
1087
1088	of_node_put(ep);
1089	of_node_put(rport);
1090
1091	return 0;
1092}
1093
1094static int graph_count_c2c(struct asoc_simple_priv *priv,
1095			   struct device_node *lnk,
1096			   struct link_info *li)
1097{
1098	struct device_node *ports = of_get_parent(lnk);
1099	struct device_node *port0 = lnk;
1100	struct device_node *port1 = of_get_next_child(ports, lnk);
1101	struct device_node *ep0 = port_to_endpoint(port0);
1102	struct device_node *ep1 = port_to_endpoint(port1);
1103	struct device_node *codec0 = of_graph_get_remote_port(ep0);
1104	struct device_node *codec1 = of_graph_get_remote_port(ep1);
1105
1106	of_node_get(lnk);
1107
1108	/*
1109	 * codec2codec {
1110	 *	ports {
1111	 * =>	lnk:	port@0 { endpoint { ... }; };
1112	 *		port@1 { endpoint { ... }; };
1113	 *	};
1114	 * };
1115	 */
 
 
 
 
 
1116	li->num[li->link].cpus		=
1117	li->num[li->link].platforms	= graph_counter(codec0);
 
1118	li->num[li->link].codecs	= graph_counter(codec1);
1119
1120	of_node_put(ports);
1121	of_node_put(port1);
1122	of_node_put(ep0);
1123	of_node_put(ep1);
1124	of_node_put(codec0);
1125	of_node_put(codec1);
1126
1127	return 0;
1128}
1129
1130static int graph_count(struct asoc_simple_priv *priv,
1131		       struct graph2_custom_hooks *hooks,
1132		       enum graph_type gtype,
1133		       struct device_node *lnk,
1134		       struct link_info *li)
1135{
1136	struct device *dev = simple_priv_to_dev(priv);
1137	GRAPH2_CUSTOM func = NULL;
1138	int ret = -EINVAL;
1139
1140	if (li->link >= SNDRV_MAX_LINKS) {
1141		dev_err(dev, "too many links\n");
1142		return ret;
1143	}
1144
1145	switch (gtype) {
1146	case GRAPH_NORMAL:
1147		func = graph_count_normal;
1148		break;
1149	case GRAPH_DPCM:
1150		func = graph_count_dpcm;
1151		break;
1152	case GRAPH_C2C:
1153		func = graph_count_c2c;
1154		break;
1155	default:
1156		break;
1157	}
1158
1159	if (!func) {
1160		dev_err(dev, "non supported gtype (%d)\n", gtype);
1161		goto err;
1162	}
1163
1164	ret = func(priv, lnk, li);
1165	if (ret < 0)
1166		goto err;
1167
1168	li->link++;
1169err:
1170	return ret;
1171}
1172
1173static int graph_for_each_link(struct asoc_simple_priv *priv,
1174			       struct graph2_custom_hooks *hooks,
1175			       struct link_info *li,
1176			       int (*func)(struct asoc_simple_priv *priv,
1177					   struct graph2_custom_hooks *hooks,
1178					   enum graph_type gtype,
1179					   struct device_node *lnk,
1180					   struct link_info *li))
1181{
1182	struct of_phandle_iterator it;
1183	struct device *dev = simple_priv_to_dev(priv);
1184	struct device_node *node = dev->of_node;
1185	struct device_node *lnk;
1186	enum graph_type gtype;
1187	int rc, ret;
1188
1189	/* loop for all listed CPU port */
1190	of_for_each_phandle(&it, rc, node, "links", NULL, 0) {
1191		lnk = it.node;
1192
1193		gtype = graph_get_type(priv, lnk);
1194
1195		ret = func(priv, hooks, gtype, lnk, li);
1196		if (ret < 0)
1197			return ret;
1198	}
1199
1200	return 0;
1201}
1202
1203int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev,
1204			  struct graph2_custom_hooks *hooks)
1205{
1206	struct snd_soc_card *card = simple_priv_to_card(priv);
1207	struct link_info *li;
1208	int ret;
1209
1210	li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL);
1211	if (!li)
1212		return -ENOMEM;
1213
1214	card->probe	= asoc_graph_card_probe;
1215	card->owner	= THIS_MODULE;
1216	card->dev	= dev;
1217
1218	if ((hooks) && (hooks)->hook_pre) {
1219		ret = (hooks)->hook_pre(priv);
1220		if (ret < 0)
1221			goto err;
1222	}
1223
1224	ret = graph_for_each_link(priv, hooks, li, graph_count);
1225	if (!li->link)
1226		ret = -EINVAL;
1227	if (ret < 0)
1228		goto err;
1229
1230	ret = asoc_simple_init_priv(priv, li);
1231	if (ret < 0)
1232		goto err;
1233
1234	priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
1235	if (IS_ERR(priv->pa_gpio)) {
1236		ret = PTR_ERR(priv->pa_gpio);
1237		dev_err(dev, "failed to get amplifier gpio: %d\n", ret);
1238		goto err;
1239	}
1240
1241	ret = asoc_simple_parse_widgets(card, NULL);
1242	if (ret < 0)
1243		goto err;
1244
1245	ret = asoc_simple_parse_routing(card, NULL);
1246	if (ret < 0)
1247		goto err;
1248
1249	memset(li, 0, sizeof(*li));
1250	ret = graph_for_each_link(priv, hooks, li, graph_link);
1251	if (ret < 0)
1252		goto err;
1253
1254	ret = asoc_simple_parse_card_name(card, NULL);
1255	if (ret < 0)
1256		goto err;
1257
1258	snd_soc_card_set_drvdata(card, priv);
1259
1260	if ((hooks) && (hooks)->hook_post) {
1261		ret = (hooks)->hook_post(priv);
1262		if (ret < 0)
1263			goto err;
1264	}
1265
1266	asoc_simple_debug_info(priv);
1267
1268	ret = devm_snd_soc_register_card(dev, card);
1269err:
1270	devm_kfree(dev, li);
1271
1272	if (ret < 0)
1273		dev_err_probe(dev, ret, "parse error\n");
1274
1275	return ret;
1276}
1277EXPORT_SYMBOL_GPL(audio_graph2_parse_of);
1278
1279static int graph_probe(struct platform_device *pdev)
1280{
1281	struct asoc_simple_priv *priv;
1282	struct device *dev = &pdev->dev;
1283
1284	/* Allocate the private data and the DAI link array */
1285	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1286	if (!priv)
1287		return -ENOMEM;
1288
1289	return audio_graph2_parse_of(priv, dev, NULL);
1290}
1291
1292static const struct of_device_id graph_of_match[] = {
1293	{ .compatible = "audio-graph-card2", },
1294	{},
1295};
1296MODULE_DEVICE_TABLE(of, graph_of_match);
1297
1298static struct platform_driver graph_card = {
1299	.driver = {
1300		.name = "asoc-audio-graph-card2",
1301		.pm = &snd_soc_pm_ops,
1302		.of_match_table = graph_of_match,
1303	},
1304	.probe	= graph_probe,
1305	.remove	= asoc_simple_remove,
1306};
1307module_platform_driver(graph_card);
1308
1309MODULE_ALIAS("platform:asoc-audio-graph-card2");
1310MODULE_LICENSE("GPL v2");
1311MODULE_DESCRIPTION("ASoC Audio Graph Card2");
1312MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
v6.9.4
   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
  85It 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
 225enum 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
 239static 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
 276out_put:
 277	of_node_put(np);
 278	return ret;
 279
 280}
 281
 282static 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
 316static int graph_lnk_is_multi(struct device_node *lnk)
 317{
 318	return __graph_get_type(lnk) == GRAPH_MULTI;
 319}
 320
 321static 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
 359static 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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 365static 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
 381static 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
 396static 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
 506static 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);
 597mcodec_err:
 598		of_node_put(mcodec_port);
 599		of_node_put(mcpu_ep_n);
 600		of_node_put(mcodec_ep_n);
 601	}
 602mcpu_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
 613static 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
 675multi_err:
 676	return ret;
 677}
 678
 679static 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
 692static 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
 703static 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
 753static 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
 813int 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);
 839err:
 840	of_node_put(codec_port);
 841	of_node_put(cpu_ep);
 842
 843	return ret;
 844}
 845EXPORT_SYMBOL_GPL(audio_graph2_link_normal);
 846
 847int 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);
 931err:
 932	of_node_put(ep);
 933	of_node_put(rep);
 934	of_node_put(rport);
 935
 936	return ret;
 937}
 938EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm);
 939
 940int 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);
1023err2:
1024	of_node_put(ep0);
1025	of_node_put(ep1);
1026	of_node_put(codec0_port);
1027	of_node_put(codec1_port);
1028err1:
1029	of_node_put(ports);
1030	of_node_put(port0);
1031	of_node_put(port1);
1032
1033	return ret;
1034}
1035EXPORT_SYMBOL_GPL(audio_graph2_link_c2c);
1036
1037static 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++;
1080err:
1081	return ret;
1082}
1083
1084static 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
1125static 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
1154static 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
1194static 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, 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	of_node_get(lnk);
1207
1208	/*
1209	 * codec2codec {
1210	 *	ports {
1211	 * =>	lnk:	port@0 { endpoint { ... }; };
1212	 *		port@1 { endpoint { ... }; };
1213	 *	};
1214	 * };
1215	 */
1216	/*
1217	 * DON'T REMOVE platforms
1218	 * see
1219	 *	simple-card.c :: simple_count_noml()
1220	 */
1221	li->num[li->link].cpus		=
1222	li->num[li->link].platforms	= graph_counter(codec0);
1223
1224	li->num[li->link].codecs	= graph_counter(codec1);
1225
1226	of_node_put(ports);
1227	of_node_put(port1);
1228	of_node_put(ep0);
1229	of_node_put(ep1);
1230	of_node_put(codec0);
1231	of_node_put(codec1);
1232
1233	return 0;
1234}
1235
1236static int graph_count(struct simple_util_priv *priv,
1237		       struct graph2_custom_hooks *hooks,
1238		       enum graph_type gtype,
1239		       struct device_node *lnk,
1240		       struct link_info *li)
1241{
1242	struct device *dev = simple_priv_to_dev(priv);
1243	GRAPH2_CUSTOM func = NULL;
1244	int ret = -EINVAL;
1245
1246	if (li->link >= SNDRV_MAX_LINKS) {
1247		dev_err(dev, "too many links\n");
1248		return ret;
1249	}
1250
1251	switch (gtype) {
1252	case GRAPH_NORMAL:
1253		func = graph_count_normal;
1254		break;
1255	case GRAPH_DPCM:
1256		func = graph_count_dpcm;
1257		break;
1258	case GRAPH_C2C:
1259		func = graph_count_c2c;
1260		break;
1261	default:
1262		break;
1263	}
1264
1265	if (!func) {
1266		dev_err(dev, "non supported gtype (%d)\n", gtype);
1267		goto err;
1268	}
1269
1270	ret = func(priv, lnk, li);
1271	if (ret < 0)
1272		goto err;
1273
1274	li->link++;
1275err:
1276	return ret;
1277}
1278
1279static int graph_for_each_link(struct simple_util_priv *priv,
1280			       struct graph2_custom_hooks *hooks,
1281			       struct link_info *li,
1282			       int (*func)(struct simple_util_priv *priv,
1283					   struct graph2_custom_hooks *hooks,
1284					   enum graph_type gtype,
1285					   struct device_node *lnk,
1286					   struct link_info *li))
1287{
1288	struct of_phandle_iterator it;
1289	struct device *dev = simple_priv_to_dev(priv);
1290	struct device_node *node = dev->of_node;
1291	struct device_node *lnk;
1292	enum graph_type gtype;
1293	int rc, ret;
1294
1295	/* loop for all listed CPU port */
1296	of_for_each_phandle(&it, rc, node, "links", NULL, 0) {
1297		lnk = it.node;
1298
1299		gtype = graph_get_type(priv, lnk);
1300
1301		ret = func(priv, hooks, gtype, lnk, li);
1302		if (ret < 0)
1303			return ret;
1304	}
1305
1306	return 0;
1307}
1308
1309int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev,
1310			  struct graph2_custom_hooks *hooks)
1311{
1312	struct snd_soc_card *card = simple_priv_to_card(priv);
1313	struct link_info *li;
1314	int ret;
1315
1316	li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL);
1317	if (!li)
1318		return -ENOMEM;
1319
1320	card->probe	= graph_util_card_probe;
1321	card->owner	= THIS_MODULE;
1322	card->dev	= dev;
1323
1324	if ((hooks) && (hooks)->hook_pre) {
1325		ret = (hooks)->hook_pre(priv);
1326		if (ret < 0)
1327			goto err;
1328	}
1329
1330	ret = graph_for_each_link(priv, hooks, li, graph_count);
1331	if (!li->link)
1332		ret = -EINVAL;
1333	if (ret < 0)
1334		goto err;
1335
1336	ret = simple_util_init_priv(priv, li);
1337	if (ret < 0)
1338		goto err;
1339
1340	priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
1341	if (IS_ERR(priv->pa_gpio)) {
1342		ret = PTR_ERR(priv->pa_gpio);
1343		dev_err(dev, "failed to get amplifier gpio: %d\n", ret);
1344		goto err;
1345	}
1346
1347	ret = simple_util_parse_widgets(card, NULL);
1348	if (ret < 0)
1349		goto err;
1350
1351	ret = simple_util_parse_routing(card, NULL);
1352	if (ret < 0)
1353		goto err;
1354
1355	memset(li, 0, sizeof(*li));
1356	ret = graph_for_each_link(priv, hooks, li, graph_link);
1357	if (ret < 0)
1358		goto err;
1359
1360	ret = simple_util_parse_card_name(card, NULL);
1361	if (ret < 0)
1362		goto err;
1363
1364	snd_soc_card_set_drvdata(card, priv);
1365
1366	if ((hooks) && (hooks)->hook_post) {
1367		ret = (hooks)->hook_post(priv);
1368		if (ret < 0)
1369			goto err;
1370	}
1371
1372	simple_util_debug_info(priv);
1373
1374	ret = devm_snd_soc_register_card(dev, card);
1375err:
1376	devm_kfree(dev, li);
1377
1378	if (ret < 0)
1379		dev_err_probe(dev, ret, "parse error\n");
1380
1381	return ret;
1382}
1383EXPORT_SYMBOL_GPL(audio_graph2_parse_of);
1384
1385static int graph_probe(struct platform_device *pdev)
1386{
1387	struct simple_util_priv *priv;
1388	struct device *dev = &pdev->dev;
1389
1390	/* Allocate the private data and the DAI link array */
1391	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1392	if (!priv)
1393		return -ENOMEM;
1394
1395	return audio_graph2_parse_of(priv, dev, NULL);
1396}
1397
1398static const struct of_device_id graph_of_match[] = {
1399	{ .compatible = "audio-graph-card2", },
1400	{},
1401};
1402MODULE_DEVICE_TABLE(of, graph_of_match);
1403
1404static struct platform_driver graph_card = {
1405	.driver = {
1406		.name = "asoc-audio-graph-card2",
1407		.pm = &snd_soc_pm_ops,
1408		.of_match_table = graph_of_match,
1409	},
1410	.probe	= graph_probe,
1411	.remove_new = simple_util_remove,
1412};
1413module_platform_driver(graph_card);
1414
1415MODULE_ALIAS("platform:asoc-audio-graph-card2");
1416MODULE_LICENSE("GPL v2");
1417MODULE_DESCRIPTION("ASoC Audio Graph Card2");
1418MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");