Linux Audio

Check our new training course

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