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