Linux Audio

Check our new training course

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