Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85ee1f42 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next

parents 51fa6a8f 82885913
Loading
Loading
Loading
Loading
+124 −0
Original line number Diff line number Diff line
Audio Graph Card:

Audio Graph Card specifies audio DAI connections of SoC <-> codec.
It is based on common bindings for device graphs.
see ${LINUX}/Documentation/devicetree/bindings/graph.txt

Basically, Audio Graph Card property is same as Simple Card.
see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt

Below are same as Simple-Card.

- label
- dai-format
- frame-master
- bitclock-master
- bitclock-inversion
- frame-inversion
- dai-tdm-slot-num
- dai-tdm-slot-width
- clocks / system-clock-frequency

Required properties:

- compatible				: "audio-graph-card";
- dais					: list of CPU DAI port{s}

Example: Single DAI case

	sound_card {
		compatible = "audio-graph-card";

		dais = <&cpu_port>;
	};

	dai-controller {
		...
		cpu_port: port {
			cpu_endpoint: endpoint {
				remote-endpoint = <&codec_endpoint>;

				dai-format = "left_j";
				...
			};
		};
	};

	audio-codec {
		...
		port {
			codec_endpoint: endpoint {
				remote-endpoint = <&cpu_endpoint>;
			};
		};
	};

Example: Multi DAI case

	sound-card {
		compatible = "audio-graph-card";

		label = "sound-card";

		dais = <&cpu_port0
			&cpu_port1
			&cpu_port2>;
	};

	audio-codec@0 {
		...
		port {
			codec0_endpoint: endpoint {
				remote-endpoint = <&cpu_endpoint0>;
			};
		};
	};

	audio-codec@1 {
		...
		port {
			codec1_endpoint: endpoint {
				remote-endpoint = <&cpu_endpoint1>;
			};
		};
	};

	audio-codec@2 {
		...
		port {
			codec2_endpoint: endpoint {
				remote-endpoint = <&cpu_endpoint2>;
			};
		};
	};

	dai-controller {
		...
		ports {
			cpu_port0: port@0 {
				cpu_endpoint0: endpoint {
					remote-endpoint = <&codec0_endpoint>;

					dai-format = "left_j";
					...
				};
			};
			cpu_port1: port@1 {
				cpu_endpoint1: endpoint {
					remote-endpoint = <&codec1_endpoint>;

					dai-format = "i2s";
					...
				};
			};
			cpu_port2: port@2 {
				cpu_endpoint2: endpoint {
					remote-endpoint = <&codec2_endpoint>;

					dai-format = "i2s";
					...
				};
			};
		};
	};
+117 −0
Original line number Diff line number Diff line
Audio-Graph-SCU-Card:

Audio-Graph-SCU-Card is "Audio-Graph-Card" + "ALSA DPCM".

It is based on common bindings for device graphs.
see ${LINUX}/Documentation/devicetree/bindings/graph.txt

Basically, Audio-Graph-SCU-Card property is same as
Simple-Card / Simple-SCU-Card / Audio-Graph-Card.
see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
    ${LINUX}/Documentation/devicetree/bindings/sound/simple-scu-card.txt
    ${LINUX}/Documentation/devicetree/bindings/sound/audio-graph-card.txt

Below are same as Simple-Card / Audio-Graph-Card.

- label
- dai-format
- frame-master
- bitclock-master
- bitclock-inversion
- frame-inversion
- dai-tdm-slot-num
- dai-tdm-slot-width
- clocks / system-clock-frequency

Below are same as Simple-SCU-Card.

- convert-rate
- convert-channels
- prefix
- routing

Required properties:

- compatible				: "audio-graph-scu-card";
- dais					: list of CPU DAI port{s}

Example 1. Sampling Rate Conversion

	sound_card {
		compatible = "audio-graph-scu-card";

		label = "sound-card";
		prefix = "codec";
		routing = "codec Playback", "DAI0 Playback",
			"codec Playback", "DAI1 Playback";
		convert-rate = <48000>;

		dais = <&cpu_port>;
	};

	audio-codec {
		...

		port {
			codec_endpoint: endpoint {
				remote-endpoint = <&cpu_endpoint>;
			};
		};
	};

	dai-controller {
		...
		cpu_port: port {
			cpu_endpoint: endpoint {
				remote-endpoint = <&codec_endpoint>;

				dai-format = "left_j";
				...
			};
		};
	};

Example 2. 2 CPU 1 Codec (Mixing)

	sound_card {
		compatible = "audio-graph-scu-card";

		label = "sound-card";
		prefix = "codec";
		routing = "codec Playback", "DAI0 Playback",
			"codec Playback", "DAI1 Playback";
		convert-rate = <48000>;

		dais = <&cpu_port0
			&cpu_port1>;
	};

	audio-codec {
		...

		port {
			codec_endpoint: endpoint {
				remote-endpoint = <&cpu_endpoint0>;
			};
		};
	};

	dai-controller {
		...
		ports {
			cpu_port0: port {
				cpu_endpoint0: endpoint {
					remote-endpoint = <&codec_endpoint>;

					dai-format = "left_j";
					...
				};
			};
			cpu_port1: port {
				cpu_endpoint1: endpoint {
					dai-format = "left_j";
					...
				};
			};
		};
	};
+22 −15
Original line number Diff line number Diff line
@@ -83,11 +83,11 @@ SRC can convert [xx]Hz to [yy]Hz. Then, it has below 2 modes
**     Asynchronous mode
------------------

You need to use "renesas,rsrc-card" sound card for it.
You need to use "simple-scu-audio-card" sound card for it.
example)

	sound {
		compatible = "renesas,rsrc-card";
		compatible = "simple-scu-audio-card";
		...
		/*
		 * SRC Asynchronous mode setting
@@ -97,12 +97,12 @@ example)
		 * Inputed 48kHz data will be converted to
		 * system specified Hz
		 */
		convert-rate = <48000>;
		simple-audio-card,convert-rate = <48000>;
		...
		cpu {
		simple-audio-card,cpu {
			sound-dai = <&rcar_sound>;
		};
		codec {
		simple-audio-card,codec {
			...
		};
	};
@@ -141,23 +141,23 @@ For more detail information, see below
	${LINUX}/sound/soc/sh/rcar/ctu.c
	 - comment of header

You need to use "renesas,rsrc-card" sound card for it.
You need to use "simple-scu-audio-card" sound card for it.
example)

	sound {
		compatible = "renesas,rsrc-card";
		compatible = "simple-scu-audio-card";
		...
		/*
		 * CTU setting
		 * All input data will be converted to 2ch
		 * as output data
		 */
		convert-channels = <2>;
		simple-audio-card,convert-channels = <2>;
		...
		cpu {
		simple-audio-card,cpu {
			sound-dai = <&rcar_sound>;
		};
		codec {
		simple-audio-card,codec {
			...
		};
	};
@@ -190,22 +190,22 @@ and these sounds will be merged by MIX.
	aplay -D plughw:0,0 xxxx.wav &
	aplay -D plughw:0,1 yyyy.wav

You need to use "renesas,rsrc-card" sound card for it.
You need to use "simple-scu-audio-card" sound card for it.
Ex)
	[MEM] -> [SRC1] -> [CTU02] -+-> [MIX0] -> [DVC0] -> [SSI0]
	                            |
	[MEM] -> [SRC2] -> [CTU03] -+

	sound {
		compatible = "renesas,rsrc-card";
		compatible = "simple-scu-audio-card";
		...
		cpu@0 {
		simple-audio-card,cpu@0 {
			sound-dai = <&rcar_sound 0>;
		};
		cpu@1 {
		simple-audio-card,cpu@1 {
			sound-dai = <&rcar_sound 1>;
		};
		codec {
		simple-audio-card,codec {
			...
		};
	};
@@ -368,6 +368,10 @@ Required properties:
				  see below for detail.
- #sound-dai-cells		: it must be 0 if your system is using single DAI
				  it must be 1 if your system is using multi  DAI
- clocks			: References to SSI/SRC/MIX/CTU/DVC/AUDIO_CLK clocks.
- clock-names			: List of necessary clock names.
				  "ssi-all", "ssi.X", "src.X", "mix.X", "ctu.X",
				  "dvc.X", "clk_a", "clk_b", "clk_c", "clk_i"

Optional properties:
- #clock-cells			: it must be 0 if your system has audio_clkout
@@ -375,6 +379,9 @@ Optional properties:
- clock-frequency		: for all audio_clkout0/1/2/3
- clkout-lr-asynchronous	: boolean property. it indicates that audio_clkoutn
				  is asynchronizes with lr-clock.
- resets			: References to SSI resets.
- reset-names			: List of valid reset names.
				  "ssi-all", "ssi.X"

SSI subnode properties:
- interrupts			: Should contain SSI interrupt for PIO transfer
+25 −42
Original line number Diff line number Diff line
ASoC simple SCU Sound Card
ASoC Simple SCU Sound Card

Simple-Card specifies audio DAI connections of SoC <-> codec.
Simple SCU Sound Card is "Simple Sound Card" + "ALSA DPCM".
For example, you can use this driver if you want to exchange sampling rate convert,
Mixing, etc...

Required properties:

- compatible				: "simple-scu-audio-card"
					  "renesas,rsrc-card"

Optional properties:

- simple-audio-card,name		: User specified audio sound card name, one string
					  property.
- simple-audio-card,cpu			: CPU   sub-node
- simple-audio-card,codec		: CODEC sub-node
- simple-audio-card,name		: see simple-audio-card.txt
- simple-audio-card,cpu			: see simple-audio-card.txt
- simple-audio-card,codec		: see simple-audio-card.txt

Optional subnode properties:

- simple-audio-card,format		: CPU/CODEC common audio format.
					  "i2s", "right_j", "left_j" , "dsp_a"
					  "dsp_b", "ac97", "pdm", "msb", "lsb"
- simple-audio-card,frame-master	: Indicates dai-link frame master.
					  phandle to a cpu or codec subnode.
- simple-audio-card,bitclock-master	: Indicates dai-link bit clock master.
					  phandle to a cpu or codec subnode.
- simple-audio-card,bitclock-inversion	: bool property. Add this if the
					  dai-link uses bit clock inversion.
- simple-audio-card,frame-inversion	: bool property. Add this if the
					  dai-link uses frame clock inversion.
- simple-audio-card,format		: see simple-audio-card.txt
- simple-audio-card,frame-master	: see simple-audio-card.txt
- simple-audio-card,bitclock-master	: see simple-audio-card.txt
- simple-audio-card,bitclock-inversion	: see simple-audio-card.txt
- simple-audio-card,frame-inversion	: see simple-audio-card.txt
- simple-audio-card,convert-rate	: platform specified sampling rate convert
- simple-audio-card,convert-channels	: platform specified converted channel size (2 - 8 ch)
- simple-audio-card,prefix		: see audio-routing
- simple-audio-card,prefix		: see routing
- simple-audio-card,routing		: A list of the connections between audio components.
					  Each entry is a pair of strings, the first being the connection's sink,
					  the second being the connection's source. Valid names for sources.
@@ -38,32 +32,23 @@ Optional subnode properties:

Required CPU/CODEC subnodes properties:

- sound-dai				: phandle and port of CPU/CODEC
- sound-dai				: see simple-audio-card.txt

Optional CPU/CODEC subnodes properties:

- clocks / system-clock-frequency	: specify subnode's clock if needed.
					  it can be specified via "clocks" if system has
					  clock node (= common clock), or "system-clock-frequency"
					  (if system doens't support common clock)
					  If a clock is specified, it is
					  enabled with clk_prepare_enable()
					  in dai startup() and disabled with
					  clk_disable_unprepare() in dai
					  shutdown().
- clocks / system-clock-frequency	: see simple-audio-card.txt

Example 1. Sampling Rate Covert
Example 1. Sampling Rate Conversion

sound {
	compatible = "simple-scu-audio-card";

	simple-audio-card,name = "rsnd-ak4643";
	simple-audio-card,format = "left_j";
	simple-audio-card,format = "left_j";
	simple-audio-card,bitclock-master = <&sndcodec>;
	simple-audio-card,frame-master = <&sndcodec>;

	simple-audio-card,convert-rate = <48000>; /* see audio_clk_a */
	simple-audio-card,convert-rate = <48000>;

	simple-audio-card,prefix = "ak4642";
	simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
@@ -79,20 +64,18 @@ sound {
	};
};

Example 2. 2 CPU 1 Codec
Example 2. 2 CPU 1 Codec (Mixing)

sound {
	compatible = "renesas,rsrc-card";

	card-name = "rsnd-ak4643";
	format = "left_j";
	bitclock-master = <&dpcmcpu>;
	frame-master = <&dpcmcpu>;
	compatible = "simple-scu-audio-card";

	convert-rate = <48000>;  /* see audio_clk_a */
	simple-audio-card,name = "rsnd-ak4643";
	simple-audio-card,format = "left_j";
	simple-audio-card,bitclock-master = <&dpcmcpu>;
	simple-audio-card,frame-master = <&dpcmcpu>;

	audio-prefix = "ak4642";
	audio-routing = "ak4642 Playback", "DAI0 Playback",
	simple-audio-card,prefix = "ak4642";
	simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
			"ak4642 Playback", "DAI1 Playback";

	dpcmcpu: cpu@0 {
+52 −10
Original line number Diff line number Diff line
@@ -1601,6 +1601,7 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it,

	return 0;
}
EXPORT_SYMBOL_GPL(of_phandle_iterator_init);

int of_phandle_iterator_next(struct of_phandle_iterator *it)
{
@@ -1670,6 +1671,7 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it)

	return -EINVAL;
}
EXPORT_SYMBOL_GPL(of_phandle_iterator_next);

int of_phandle_iterator_args(struct of_phandle_iterator *it,
			     uint32_t *args,
@@ -2484,6 +2486,41 @@ struct device_node *of_graph_get_endpoint_by_regs(
}
EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);

/**
 * of_graph_get_remote_endpoint() - get remote endpoint node
 * @node: pointer to a local endpoint device_node
 *
 * Return: Remote endpoint node associated with remote endpoint node linked
 *	   to @node. Use of_node_put() on it when done.
 */
struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
{
	/* Get remote endpoint node. */
	return of_parse_phandle(node, "remote-endpoint", 0);
}
EXPORT_SYMBOL(of_graph_get_remote_endpoint);

/**
 * of_graph_get_port_parent() - get port's parent node
 * @node: pointer to a local endpoint device_node
 *
 * Return: device node associated with endpoint node linked
 *	   to @node. Use of_node_put() on it when done.
 */
struct device_node *of_graph_get_port_parent(struct device_node *node)
{
	unsigned int depth;

	/* Walk 3 levels up only if there is 'ports' node. */
	for (depth = 3; depth && node; depth--) {
		node = of_get_next_parent(node);
		if (depth == 2 && of_node_cmp(node->name, "ports"))
			break;
	}
	return node;
}
EXPORT_SYMBOL(of_graph_get_port_parent);

/**
 * of_graph_get_remote_port_parent() - get remote port's parent node
 * @node: pointer to a local endpoint device_node
@@ -2495,18 +2532,11 @@ struct device_node *of_graph_get_remote_port_parent(
			       const struct device_node *node)
{
	struct device_node *np;
	unsigned int depth;

	/* Get remote endpoint node. */
	np = of_parse_phandle(node, "remote-endpoint", 0);
	np = of_graph_get_remote_endpoint(node);

	/* Walk 3 levels up only if there is 'ports' node. */
	for (depth = 3; depth && np; depth--) {
		np = of_get_next_parent(np);
		if (depth == 2 && of_node_cmp(np->name, "ports"))
			break;
	}
	return np;
	return of_graph_get_port_parent(np);
}
EXPORT_SYMBOL(of_graph_get_remote_port_parent);

@@ -2522,13 +2552,25 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
	struct device_node *np;

	/* Get remote endpoint node. */
	np = of_parse_phandle(node, "remote-endpoint", 0);
	np = of_graph_get_remote_endpoint(node);
	if (!np)
		return NULL;
	return of_get_next_parent(np);
}
EXPORT_SYMBOL(of_graph_get_remote_port);

int of_graph_get_endpoint_count(const struct device_node *np)
{
	struct device_node *endpoint;
	int num = 0;

	for_each_endpoint_of_node(np, endpoint)
		num++;

	return num;
}
EXPORT_SYMBOL(of_graph_get_endpoint_count);

/**
 * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
 * @node: pointer to parent device_node containing graph port/endpoint
Loading