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