summaryrefslogtreecommitdiff
path: root/sound/soc/generic
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/generic')
-rw-r--r--sound/soc/generic/audio-graph-card.c97
-rw-r--r--sound/soc/generic/audio-graph-card2-custom-sample.dtsi702
-rw-r--r--sound/soc/generic/audio-graph-card2-custom-sample1.dtsi396
-rw-r--r--sound/soc/generic/audio-graph-card2-custom-sample2.dtsi382
-rw-r--r--sound/soc/generic/audio-graph-card2.c95
-rw-r--r--sound/soc/generic/simple-card-utils.c189
-rw-r--r--sound/soc/generic/simple-card.c132
-rw-r--r--sound/soc/generic/test-component.c11
8 files changed, 1082 insertions, 922 deletions
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 7c422535b01a..a8a3bad3df00 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -20,6 +20,13 @@
#define DPCM_SELECTABLE 1
+#define graph_ret(priv, ret) _graph_ret(priv, __func__, ret)
+static inline int _graph_ret(struct simple_util_priv *priv,
+ const char *func, int ret)
+{
+ return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func);
+}
+
#define ep_to_port(ep) of_get_parent(ep)
static struct device_node *port_to_ports(struct device_node *port)
{
@@ -111,19 +118,17 @@ static int graph_parse_node(struct simple_util_priv *priv,
dai = simple_props_to_dai_codec(dai_props, 0);
}
- ret = graph_util_parse_dai(dev, ep, dlc, cpu);
+ ret = graph_util_parse_dai(priv, ep, dlc, cpu);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_parse_tdm(ep, dai);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_parse_clk(dev, ep, dai, dlc);
- if (ret < 0)
- return ret;
-
- return 0;
+end:
+ return graph_ret(priv, ret);
}
static int graph_link_init(struct simple_util_priv *priv,
@@ -148,7 +153,7 @@ static int graph_link_init(struct simple_util_priv *priv,
ret = simple_util_parse_daifmt(dev, ep_cpu, ep_codec,
NULL, &dai_link->dai_fmt);
if (ret < 0)
- return ret;
+ goto end;
graph_util_parse_link_direction(top, &playback_only, &capture_only);
graph_util_parse_link_direction(port_cpu, &playback_only, &capture_only);
@@ -183,7 +188,9 @@ static int graph_link_init(struct simple_util_priv *priv,
if (priv->ops)
dai_link->ops = priv->ops;
- return simple_util_set_dailink_name(dev, dai_link, name);
+ ret = simple_util_set_dailink_name(priv, dai_link, name);
+end:
+ return graph_ret(priv, ret);
}
static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
@@ -215,7 +222,7 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
ret = graph_parse_node(priv, cpu_ep, li, &is_single_links);
if (ret)
- return ret;
+ goto end;
snprintf(dai_name, sizeof(dai_name),
"fe.%pOFP.%s", cpus->of_node, cpus->dai_name);
@@ -248,7 +255,7 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
ret = graph_parse_node(priv, codec_ep, li, NULL);
if (ret < 0)
- return ret;
+ goto end;
snprintf(dai_name, sizeof(dai_name),
"be.%pOFP.%s", codecs->of_node, codecs->dai_name);
@@ -267,8 +274,8 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name);
li->link++;
-
- return ret;
+end:
+ return graph_ret(priv, ret);
}
static int graph_dai_link_of(struct simple_util_priv *priv,
@@ -288,11 +295,11 @@ static int graph_dai_link_of(struct simple_util_priv *priv,
ret = graph_parse_node(priv, cpu_ep, li, &is_single_links);
if (ret < 0)
- return ret;
+ goto end;
ret = graph_parse_node(priv, codec_ep, li, NULL);
if (ret < 0)
- return ret;
+ goto end;
snprintf(dai_name, sizeof(dai_name),
"%s-%s", cpus->dai_name, codecs->dai_name);
@@ -302,11 +309,11 @@ static int graph_dai_link_of(struct simple_util_priv *priv,
ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name);
if (ret < 0)
- return ret;
+ goto end;
li->link++;
-
- return 0;
+end:
+ return graph_ret(priv, ret);
}
static inline bool parse_as_dpcm_link(struct simple_util_priv *priv,
@@ -383,13 +390,13 @@ static int __graph_for_each_link(struct simple_util_priv *priv,
}
if (ret < 0)
- return ret;
+ goto end;
codec_port_old = codec_port;
}
}
-
- return 0;
+end:
+ return graph_ret(priv, ret);
}
static int graph_for_each_link(struct simple_util_priv *priv,
@@ -422,7 +429,7 @@ static int graph_for_each_link(struct simple_util_priv *priv,
break;
}
- return ret;
+ return graph_ret(priv, ret);
}
static int graph_count_noml(struct simple_util_priv *priv,
@@ -431,11 +438,10 @@ static int graph_count_noml(struct simple_util_priv *priv,
struct link_info *li)
{
struct device *dev = simple_priv_to_dev(priv);
+ int ret = -EINVAL;
- if (li->link >= SNDRV_MAX_LINKS) {
- dev_err(dev, "too many links\n");
- return -EINVAL;
- }
+ if (li->link >= SNDRV_MAX_LINKS)
+ goto end;
/*
* DON'T REMOVE platforms
@@ -450,8 +456,9 @@ static int graph_count_noml(struct simple_util_priv *priv,
li->link += 1; /* 1xCPU-Codec */
dev_dbg(dev, "Count As Normal\n");
-
- return 0;
+ ret = 0;
+end:
+ return graph_ret(priv, ret);
}
static int graph_count_dpcm(struct simple_util_priv *priv,
@@ -460,11 +467,10 @@ static int graph_count_dpcm(struct simple_util_priv *priv,
struct link_info *li)
{
struct device *dev = simple_priv_to_dev(priv);
+ int ret = -EINVAL;
- if (li->link >= SNDRV_MAX_LINKS) {
- dev_err(dev, "too many links\n");
- return -EINVAL;
- }
+ if (li->link >= SNDRV_MAX_LINKS)
+ goto end;
if (li->cpu) {
/*
@@ -483,8 +489,9 @@ static int graph_count_dpcm(struct simple_util_priv *priv,
}
dev_dbg(dev, "Count As DPCM\n");
-
- return 0;
+ ret = 0;
+end:
+ return graph_ret(priv, ret);
}
static int graph_get_dais_count(struct simple_util_priv *priv,
@@ -544,40 +551,41 @@ static int graph_get_dais_count(struct simple_util_priv *priv,
int audio_graph_parse_of(struct simple_util_priv *priv, struct device *dev)
{
struct snd_soc_card *card = simple_priv_to_card(priv);
- int ret;
+ int ret = -ENOMEM;
struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL);
if (!li)
- return -ENOMEM;
+ goto end;
card->owner = THIS_MODULE;
card->dev = dev;
ret = graph_get_dais_count(priv, li);
if (ret < 0)
- return ret;
+ goto end;
+ ret = -EINVAL;
if (!li->link)
- return -EINVAL;
+ goto end;
ret = simple_util_init_priv(priv, li);
if (ret < 0)
- return ret;
+ goto end;
priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
if (IS_ERR(priv->pa_gpio)) {
ret = PTR_ERR(priv->pa_gpio);
dev_err(dev, "failed to get amplifier gpio: %d\n", ret);
- return ret;
+ goto end;
}
ret = simple_util_parse_widgets(card, NULL);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_parse_routing(card, NULL);
if (ret < 0)
- return ret;
+ goto end;
memset(li, 0, sizeof(*li));
ret = graph_for_each_link(priv, li,
@@ -586,7 +594,7 @@ int audio_graph_parse_of(struct simple_util_priv *priv, struct device *dev)
if (ret < 0)
goto err;
- ret = simple_util_parse_card_name(card, NULL);
+ ret = simple_util_parse_card_name(priv, NULL);
if (ret < 0)
goto err;
@@ -599,10 +607,9 @@ int audio_graph_parse_of(struct simple_util_priv *priv, struct device *dev)
goto err;
return 0;
-
err:
simple_util_clean_reference(card);
-
+end:
return dev_err_probe(dev, ret, "parse error\n");
}
EXPORT_SYMBOL_GPL(audio_graph_parse_of);
diff --git a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample.dtsi
deleted file mode 100644
index 9efd31206c9b..000000000000
--- a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi
+++ /dev/null
@@ -1,702 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * audio-graph-card2-custom-sample.dtsi
- *
- * Copyright (C) 2020 Renesas Electronics Corp.
- * Copyright (C) 2020 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This sample indicates how to use audio-graph-card2 and its
- * custom driver. "audio-graph-card2-custom-sample" is the custome driver
- * which is using audio-graph-card2.
- *
- * You can easily use this sample by adding below line on your DT file,
- * and add new CONFIG to your .config.
- *
- * #include "../../../../../sound/soc/generic/audio-graph-card2-custom-sample.dtsi"
- *
- * CONFIG_SND_AUDIO_GRAPH_CARD2
- * CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE
- * CONFIG_SND_TEST_COMPONENT
- *
- *
- * You can indicate more detail each device behavior as debug if you modify
- * "compatible" on each test-component. see below
- *
- * test_cpu {
- * - compatible = "test-cpu";
- * + compatible = "test-cpu-verbose";
- * ...
- * };
- *
- * test_codec {
- * - compatible = "test-codec";
- * + compatible = "test-codec-verbose";
- * ...
- * };
- *
- *
- * Below sample doesn't use "format" property,
- * because test-component driver (test-cpu/test-codec) is supporting
- * snd_soc_dai_ops :: .auto_selectable_formats.
- * see
- * snd_soc_runtime_get_dai_fmt()
- * linux/sound/soc/generic/test-component.c :: test_dai_formats
- */
-/ {
- /*
- * @ : used at links
- *
- * [Normal]
- * cpu0 <-@-----------------> codec0
- *
- * [Semi-Multi]
- *
- * CPU:Codec = 1:N
- *
- * +-+
- * cpu7 <-@------->| |-> codec12
- * | |-> codec13
- * +-+
- *
- * [Multi-CPU/Codec-0]
- * +-+ +-+
- * cpu1 <--| |<-@--------->| |-> codec1
- * cpu2 <--| | | |-> codec2
- * +-+ +-+
- *
- * [Multi-CPU/Codec-1]
- *
- * +-+ +-+
- * | |<-@--------->| |
- * | | | |
- * cpu8 <--| |<----------->| |-> codec14
- * cpu9 <--| |<---+------->| |-> codec15
- * +-+ \------>| |-> codec16
- * +-+
- *
- * [Multi-CPU/Codec-2]
- *
- * +-+ +-+
- * | |<-@--------->| |
- * | | | |
- * cpu10 <-| |<----------->| |-> codec17
- * cpu11 <-| |<-----+----->| |-> codec18
- * cpu12 <-| |<----/ +-+
- * +-+
- *
- * [DPCM]
- *
- * CPU3/CPU4 are converting rate to 44100
- *
- * FE BE
- * ****
- * cpu3 <-@--* *--@-> codec3
- * cpu4 <-@--* * (44.1kHz)
- * ****
- *
- * [DPCM-Multi]
- *
- * --NOTE--
- * Multi-FE is not supported by ASoC.
- *
- * FE BE
- * **** +-+
- * cpu5 <-@--* *--@-> | | -> codec4
- * cpu6 <-@--* * | | -> codec5
- * **** +-+
- *
- * [Codec2Codec]
- * +-@-> codec6
- * |
- * +---> codec7
- *
- * [Codec2Codec-Multi]
- *
- * --NOTE--
- * Multi connect N:M is not supported by ASoC.
- *
- * +-+
- * +-@->| |-> codec8
- * | | |-> codec9
- * | +-+
- * | +-+
- * +--->| |-> codec10
- * | |-> codec11
- * +-+
- */
- audio-graph-card2-custom-sample {
- /*
- * You can use audio-graph-card2 directly by using
- *
- * compatible = "audio-graph-card2";
- */
- compatible = "audio-graph-card2-custom-sample";
-
- /* for [DPCM] */
- /* BE FE */
- routing = "TC DAI3 Playback", "DAI3 Playback",
- "TC DAI3 Playback", "DAI4 Playback",
- "DAI3 Capture", "TC DAI3 Capture",
- "DAI4 Capture", "TC DAI3 Capture",
- /* for [DPCM-Multi] */
- /* BE FE */
- "TC DAI4 Playback", "DAI5 Playback",
- "TC DAI5 Playback", "DAI5 Playback",
- "TC DAI4 Playback", "DAI6 Playback",
- "TC DAI5 Playback", "DAI6 Playback",
- "DAI5 Capture", "TC DAI4 Capture",
- "DAI5 Capture", "TC DAI5 Capture",
- "DAI6 Capture", "TC DAI4 Capture",
- "DAI6 Capture", "TC DAI5 Capture",
- /* for [Codec2Codec] */
- "TC OUT", "TC DAI7 Playback",
- "TC DAI6 Capture", "TC IN",
- /* for [Codec2Codec-Multi] */
- "TC OUT", "TC DAI10 Playback",
- "TC DAI8 Capture", "TC IN",
- "TC OUT", "TC DAI11 Playback",
- "TC DAI9 Capture", "TC IN";
-
- links = <
- /*
- * [Normal]: cpu side only
- * cpu0/codec0
- */
- &cpu0
-
- /*
- * [Semi-Multi]
- * cpu7/codec12/codec13
- */
- &sm0
-
- /*
- * [Multi-CPU/Codec-0]: cpu side only
- * cpu1/cpu2/codec1/codec2
- */
- &mcpu0
-
- /*
- * [Multi-CPU/Codec-1]: cpu side only
- * cpu8/cpu9/codec14/codec15/codec16
- *
- * Because it will reach to the maximum of sound minor number,
- * disable it so far.
- * If you want to try it, please disable some other one instead.
- */
- //&mcpu1
-
- /*
- * [Multi-CPU/Codec-2]: cpu side only
- * cpu10/cpu11/cpu12/codec17/codec18
- *
- * Because it will reach to the maximum of sound minor number,
- * disable it so far.
- * If you want to try it, please disable some other one instead.
- */
- //&mcpu2
-
- /*
- * [DPCM]: both FE / BE
- * cpu3/cpu4/codec3
- */
- &fe00 &fe01 &be0
-
- /*
- * [DPCM-Multi]: both FE / BE
- * cpu5/cpu6/codec4/codec5
- */
- &fe10 &fe11 &be1
-
- /*
- * [Codec2Codec]: cpu side only
- * codec6/codec7
- */
- &c2c
-
- /*
- * [Codec2Codec-Multi]: cpu side only
- * codec8/codec9/codec10/codec11
- */
- &c2c_m
- >;
-
- multi {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /*
- * [Multi-CPU-0]
- *
- * +---+ +---+
- * cpu1 <--|A X|<-@------->|x a|-> codec1
- * cpu2 <--|B | | b|-> codec2
- * +---+ +---+
- */
- ports@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- mcpu0: port@0 { reg = <0>; mcpu00_ep: endpoint { remote-endpoint = <&mcodec00_ep>; };};/* (X) to pair */
- port@1 { reg = <1>; mcpu01_ep: endpoint { remote-endpoint = <&cpu1_ep>; };};/* (A) Multi Element */
- port@2 { reg = <2>; mcpu02_ep: endpoint { remote-endpoint = <&cpu2_ep>; };};/* (B) Multi Element */
- };
-
- /*
- * [Multi-Codec-0]
- *
- * +---+ +---+
- * cpu1 <--|A X|<-@------->|x a|-> codec1
- * cpu2 <--|B | | b|-> codec2
- * +---+ +---+
- */
- ports@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 { reg = <0>; mcodec00_ep: endpoint { remote-endpoint = <&mcpu00_ep>; };};/* (x) to pair */
- port@1 { reg = <1>; mcodec01_ep: endpoint { remote-endpoint = <&codec1_ep>; };};/* (a) Multi Element */
- port@2 { reg = <2>; mcodec02_ep: endpoint { remote-endpoint = <&codec2_ep>; };};/* (b) Multi Element */
- };
-
- /*
- * [DPCM-Multi]::BE
- *
- * FE BE
- * **** +---+
- * cpu5 <-@--* *-----@--->|x a|-> codec4
- * cpu6 <-@--* * | b|-> codec5
- * **** +---+
- */
- ports@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 { reg = <0>; mbe_ep: endpoint { remote-endpoint = <&be10_ep>; };};/* (x) to pair */
- port@1 { reg = <1>; mbe1_ep: endpoint { remote-endpoint = <&codec4_ep>; };};/* (a) Multi Element */
- port@2 { reg = <2>; mbe2_ep: endpoint { remote-endpoint = <&codec5_ep>; };};/* (b) Multi Element */
- };
-
- /*
- * [Codec2Codec-Multi]::CPU
- *
- * +---+
- * +-@->|X A|-> codec8
- * | | B|-> codec9
- * | +---+
- * | +---+
- * +--->|x a|-> codec10
- * | b|-> codec11
- * +---+
- */
- ports@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 { reg = <0>; mc2c0_ep: endpoint { remote-endpoint = <&c2cmf_ep>; };};/* (X) to pair */
- port@1 { reg = <1>; mc2c00_ep: endpoint { remote-endpoint = <&codec8_ep>; };};/* (A) Multi Element */
- port@2 { reg = <2>; mc2c01_ep: endpoint { remote-endpoint = <&codec9_ep>; };};/* (B) Multi Element */
- };
-
- /*
- * [Codec2Codec-Multi]::Codec
- *
- * +---+
- * +-@->|X A|-> codec8
- * | | B|-> codec9
- * | +---+
- * | +---+
- * +--->|x a|-> codec10
- * | b|-> codec11
- * +---+
- */
- ports@4 {
- reg = <4>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 { reg = <0>; mc2c1_ep: endpoint { remote-endpoint = <&c2cmb_ep>; };};/* (x) to pair */
- port@1 { reg = <1>; mc2c10_ep: endpoint { remote-endpoint = <&codec10_ep>; };};/* (a) Multi Element */
- port@2 { reg = <2>; mc2c11_ep: endpoint { remote-endpoint = <&codec11_ep>; };};/* (b) Multi Element */
- };
-
- /*
- * [Semi-Multi]
- *
- * +---+
- * cpu7 <-@------->|X A|-> codec12
- * | B|-> codec13
- * +---+
- */
- ports@5 {
- reg = <5>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 { reg = <0>; smcodec0_ep: endpoint { remote-endpoint = <&cpu7_ep>; };};/* (X) to pair */
- port@1 { reg = <1>; smcodec1_ep: endpoint { remote-endpoint = <&codec12_ep>; };};/* (A) Multi Element */
- port@2 { reg = <2>; smcodec2_ep: endpoint { remote-endpoint = <&codec13_ep>; };};/* (B) Multi Element */
- };
-
- /*
- * [Multi-CPU-1]
- *
- * +---+ +---+
- * | X|<-@------->|x |
- * | | | |
- * cpu8 <--|A 1|<--------->|3 a|-> codec14
- * cpu9 <--|B 2|<---+----->|4 b|-> codec15
- * +---+ \---->|5 c|-> codec16
- * +---+
- */
- ports@6 {
- reg = <6>;
- #address-cells = <1>;
- #size-cells = <0>;
- mcpu1: port@0 { reg = <0>; mcpu10_ep: endpoint { remote-endpoint = <&mcodec10_ep>; };}; /* (X) to pair */
- port@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- mcpu11_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu8_ep>; }; /* (A) Multi Element */
- mcpu11_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec11_ep_0>; }; /* (1) connected Codec */
- };
- port@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- mcpu12_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu9_ep>; }; /* (B) Multi Element */
- mcpu12_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec12_ep_0>; }; /* (2) connected Codec */
- mcpu12_ep_1: endpoint@2 { reg = <2>; remote-endpoint = <&mcodec13_ep_0>; }; /* (2) connected Codec */
- };
- };
-
- /*
- * [Multi-Codec-1]
- *
- * +---+ +---+
- * | X|<-@------->|x |
- * | | | |
- * cpu8 <--|A 1|<--------->|3 a|-> codec14
- * cpu9 <--|B 2|<---+----->|4 b|-> codec15
- * +---+ \---->|5 c|-> codec16
- * +---+
- */
- ports@7 {
- reg = <7>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 { reg = <0>; mcodec10_ep: endpoint { remote-endpoint = <&mcpu10_ep>; };}; /* (x) to pair */
- port@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- mcodec11_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec14_ep>; }; /* (a) Multi Element */
- mcodec11_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu11_ep_0>; }; /* (3) connected CPU */
- };
- port@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- mcodec12_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec15_ep>; }; /* (b) Multi Element */
- mcodec12_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu12_ep_0>; }; /* (4) connected CPU */
- };
- port@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- mcodec13_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec16_ep>; }; /* (c) Multi Element */
- mcodec13_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu12_ep_1>; }; /* (5) connected CPU */
- };
- };
-
- /*
- * [Multi-CPU-2]
- *
- * +---+ +---+
- * | X|<-@------->|x |
- * | | | |
- * cpu10 <-|A 1|<--------->|4 a|-> codec17
- * cpu11 <-|B 2|<-----+--->|5 b|-> codec18
- * cpu12 <-|C 3|<----/ +---+
- * +---+
- */
- ports@8 {
- reg = <8>;
- #address-cells = <1>;
- #size-cells = <0>;
- mcpu2: port@0 { reg = <0>; mcpu20_ep: endpoint { remote-endpoint = <&mcodec20_ep>; };}; /* (X) to pair */
- port@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- mcpu21_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu10_ep>; }; /* (A) Multi Element */
- mcpu21_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec21_ep_0>; }; /* (1) connected Codec */
- };
- port@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- mcpu22_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu11_ep>; }; /* (B) Multi Element */
- mcpu22_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec22_ep_0>; }; /* (2) connected Codec */
- };
- port@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- mcpu23_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu12_ep>; }; /* (C) Multi Element */
- mcpu23_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec22_ep_1>; }; /* (3) connected Codec */
- };
- };
-
- /*
- * [Multi-Codec-2]
- *
- * +---+ +---+
- * | X|<-@------->|x |
- * | | | |
- * cpu10 <-|A 1|<--------->|4 a|-> codec17
- * cpu11 <-|B 2|<-----+--->|5 b|-> codec18
- * cpu12 <-|C 3|<----/ +---+
- * +---+
- */
- ports@9 {
- reg = <9>;
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 { reg = <0>; mcodec20_ep: endpoint { remote-endpoint = <&mcpu20_ep>; };}; /* (x) to pair */
- port@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- mcodec21_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec17_ep>; }; /* (a) Multi Element */
- mcodec21_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu21_ep_0>; }; /* (4) connected CPU */
- };
- port@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- mcodec22_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec18_ep>; }; /* (b) Multi Element */
- mcodec22_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu22_ep_0>; }; /* (5) connected CPU */
- mcodec22_ep_1: endpoint@2 { reg = <2>; remote-endpoint = <&mcpu23_ep_0>; }; /* (5) connected CPU */
- };
- };
- };
-
- dpcm {
- #address-cells = <1>;
- #size-cells = <0>;
-
- ports@0 {
- reg = <0>;
-
- #address-cells = <1>;
- #size-cells = <0>;
- /*
- * [DPCM]::FE
- *
- * FE BE
- * ****
- * cpu3 <-@(fe00)--* *--(be0)@--> codec3
- * cpu4 <-@(fe01)--* * (44.1kHz)
- * ****
- */
- fe00: port@0 { reg = <0>; fe00_ep: endpoint { remote-endpoint = <&cpu3_ep>; }; };
- fe01: port@1 { reg = <1>; fe01_ep: endpoint { remote-endpoint = <&cpu4_ep>; }; };
-
- /*
- * [DPCM-Multi]::FE
- *
- * FE BE
- * **** +-+
- * cpu5 <-@(fe10)--* *---(be1)@-->| |-> codec4
- * cpu6 <-@(fe11)--* * | |-> codec5
- * **** +-+
- */
- fe10: port@2 { reg = <2>; fe10_ep: endpoint { remote-endpoint = <&cpu5_ep>; }; };
- fe11: port@3 { reg = <3>; fe11_ep: endpoint { remote-endpoint = <&cpu6_ep>; }; };
- };
-
- ports@1 {
- reg = <1>;
-
- #address-cells = <1>;
- #size-cells = <0>;
- /*
- * [DPCM]::BE
- *
- * FE BE
- * ****
- * cpu3 <-@(fe00)--* *--(be0)@--> codec3
- * cpu4 <-@(fe01)--* * (44.1kHz)
- * ****
- */
- be0: port@0 { reg = <0>; be00_ep: endpoint { remote-endpoint = <&codec3_ep>; }; };
-
- /*
- * [DPCM-Multi]::BE
- *
- * FE BE
- * **** +-+
- * cpu5 <-@(fe10)--* *---(be1)@-->| |-> codec4
- * cpu6 <-@(fe11)--* * | |-> codec5
- * **** +-+
- */
- be1: port@1 { reg = <1>; be10_ep: endpoint { remote-endpoint = <&mbe_ep>; }; };
- };
- };
-
- codec2codec {
- #address-cells = <1>;
- #size-cells = <0>;
- /*
- * [Codec2Codec]
- *
- * +-@(c2c)-> codec6
- * |
- * +--------> codec7
- */
- ports@0 {
- reg = <0>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* use default settings */
- c2c: port@0 { reg = <0>; c2cf_ep: endpoint { remote-endpoint = <&codec6_ep>; }; };
- port@1 { reg = <1>; c2cb_ep: endpoint { remote-endpoint = <&codec7_ep>; }; };
- };
-
- /*
- * [Codec2Codec-Multi]
- *
- * +-+
- * +-@(c2c_m)-->| |-> codec8
- * | | |-> codec9
- * | +-+
- * | +-+
- * +----------->| |-> codec10
- * | |-> codec11
- * +-+
- */
- ports@1 {
- reg = <1>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* use original settings */
- rate = <48000>;
- c2c_m: port@0 { reg = <0>; c2cmf_ep: endpoint { remote-endpoint = <&mc2c0_ep>; }; };
- port@1 { reg = <1>; c2cmb_ep: endpoint { remote-endpoint = <&mc2c1_ep>; }; };
- };
- };
- };
-
- test_cpu {
- /*
- * update compatible to indicate more detail behaviour
- * if you want. see test-compatible for more detail.
- *
- * ex)
- * - compatible = "test-cpu";
- * + compatible = "test-cpu-verbose";
- */
- compatible = "test-cpu";
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- bitclock-master;
- frame-master;
- /* [Normal] */
- cpu0: port@0 { reg = <0>; cpu0_ep: endpoint { remote-endpoint = <&codec0_ep>; }; };
-
- /* [Multi-CPU-0] */
- port@1 { reg = <1>; cpu1_ep: endpoint { remote-endpoint = <&mcpu01_ep>; }; };
- port@2 { reg = <2>; cpu2_ep: endpoint { remote-endpoint = <&mcpu02_ep>; }; };
-
- /* [DPCM]::FE */
- port@3 { reg = <3>; cpu3_ep: endpoint { remote-endpoint = <&fe00_ep>; }; };
- port@4 { reg = <4>; cpu4_ep: endpoint { remote-endpoint = <&fe01_ep>; }; };
-
- /* [DPCM-Multi]::FE */
- port@5 { reg = <5>; cpu5_ep: endpoint { remote-endpoint = <&fe10_ep>; }; };
- port@6 { reg = <6>; cpu6_ep: endpoint { remote-endpoint = <&fe11_ep>; }; };
-
- /* [Semi-Multi] */
- sm0: port@7 { reg = <7>; cpu7_ep: endpoint { remote-endpoint = <&smcodec0_ep>; }; };
-
- /* [Multi-CPU-1] */
- port@8 { reg = <8>; cpu8_ep: endpoint { remote-endpoint = <&mcpu11_ep>; }; };
- port@9 { reg = <9>; cpu9_ep: endpoint { remote-endpoint = <&mcpu12_ep>; }; };
- /* [Multi-CPU-2] */
- port@a { reg = <10>; cpu10_ep: endpoint { remote-endpoint = <&mcpu21_ep>; }; };
- port@b { reg = <11>; cpu11_ep: endpoint { remote-endpoint = <&mcpu22_ep>; }; };
- port@c { reg = <12>; cpu12_ep: endpoint { remote-endpoint = <&mcpu23_ep>; }; };
- };
- };
-
- test_codec {
- /*
- * update compatible to indicate more detail behaviour
- * if you want. see test-compatible for more detail.
- *
- * ex)
- * - compatible = "test-codec";
- * + compatible = "test-codec-verbose";
- */
- compatible = "test-codec";
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /*
- * prefix can be added to *component*,
- * see audio-graph-card2::routing
- */
- prefix = "TC";
-
- /* [Normal] */
- port@0 { reg = <0>; codec0_ep: endpoint { remote-endpoint = <&cpu0_ep>; }; };
-
- /* [Multi-Codec-0] */
- port@1 { reg = <1>; codec1_ep: endpoint { remote-endpoint = <&mcodec01_ep>; }; };
- port@2 { reg = <2>; codec2_ep: endpoint { remote-endpoint = <&mcodec02_ep>; }; };
-
- /* [DPCM]::BE */
- port@3 {
- convert-rate = <44100>;
- reg = <3>; codec3_ep: endpoint { remote-endpoint = <&be00_ep>; };
- };
-
- /* [DPCM-Multi]::BE */
- port@4 { reg = <4>; codec4_ep: endpoint { remote-endpoint = <&mbe1_ep>; }; };
- port@5 { reg = <5>; codec5_ep: endpoint { remote-endpoint = <&mbe2_ep>; }; };
-
- /* [Codec2Codec] */
- port@6 { bitclock-master;
- frame-master;
- reg = <6>; codec6_ep: endpoint { remote-endpoint = <&c2cf_ep>; }; };
- port@7 { reg = <7>; codec7_ep: endpoint { remote-endpoint = <&c2cb_ep>; }; };
-
- /* [Codec2Codec-Multi] */
- port@8 { bitclock-master;
- frame-master;
- reg = <8>; codec8_ep: endpoint { remote-endpoint = <&mc2c00_ep>; }; };
- port@9 { reg = <9>; codec9_ep: endpoint { remote-endpoint = <&mc2c01_ep>; }; };
- port@a { reg = <10>; codec10_ep: endpoint { remote-endpoint = <&mc2c10_ep>; }; };
- port@b { reg = <11>; codec11_ep: endpoint { remote-endpoint = <&mc2c11_ep>; }; };
-
- /* [Semi-Multi] */
- port@c { reg = <12>; codec12_ep: endpoint { remote-endpoint = <&smcodec1_ep>; }; };
- port@d { reg = <13>; codec13_ep: endpoint { remote-endpoint = <&smcodec2_ep>; }; };
-
- /* [Multi-Codec-1] */
- port@e { reg = <14>; codec14_ep: endpoint { remote-endpoint = <&mcodec11_ep>; }; };
- port@f { reg = <15>; codec15_ep: endpoint { remote-endpoint = <&mcodec12_ep>; }; };
- port@10 { reg = <16>; codec16_ep: endpoint { remote-endpoint = <&mcodec13_ep>; }; };
- /* [Multi-Codec-2] */
- port@11 { reg = <17>; codec17_ep: endpoint { remote-endpoint = <&mcodec21_ep>; }; };
- port@12 { reg = <18>; codec18_ep: endpoint { remote-endpoint = <&mcodec22_ep>; }; };
- };
- };
-};
diff --git a/sound/soc/generic/audio-graph-card2-custom-sample1.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample1.dtsi
new file mode 100644
index 000000000000..12d40e05de46
--- /dev/null
+++ b/sound/soc/generic/audio-graph-card2-custom-sample1.dtsi
@@ -0,0 +1,396 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * audio-graph-card2-custom-sample1.dtsi
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ * Copyright (C) 2020 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This sample indicates how to use audio-graph-card2 and its
+ * custom driver. "audio-graph-card2-custom-sample" is the custome driver
+ * which is using audio-graph-card2.
+ *
+ * You can easily use this sample by adding below line on your DT file,
+ * and add new CONFIG to your .config.
+ *
+ * #include "../../../../../sound/soc/generic/audio-graph-card2-custom-sample1.dtsi"
+ *
+ * CONFIG_SND_AUDIO_GRAPH_CARD2
+ * CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE
+ * CONFIG_SND_TEST_COMPONENT
+ *
+ *
+ * You can indicate more detail each device behavior as debug if you modify
+ * "compatible" on each test-component. see below
+ *
+ * test_cpu {
+ * - compatible = "test-cpu";
+ * + compatible = "test-cpu-verbose";
+ * ...
+ * };
+ *
+ * test_codec {
+ * - compatible = "test-codec";
+ * + compatible = "test-codec-verbose";
+ * ...
+ * };
+ *
+ *
+ * Below sample doesn't use "format" property,
+ * because test-component driver (test-cpu/test-codec) is supporting
+ * snd_soc_dai_ops :: .auto_selectable_formats.
+ * see
+ * snd_soc_runtime_get_dai_fmt()
+ * linux/sound/soc/generic/test-component.c :: test_dai_formats
+ */
+/ {
+ audio-graph-card2-custom-sample-1 {
+ /*
+ * You can use audio-graph-card2 directly by using
+ *
+ * compatible = "audio-graph-card2";
+ */
+ compatible = "audio-graph-card2-custom-sample";
+ label = "card2-custom-sample-1";
+
+ /*
+ * @ : used at links
+ */
+ links = <
+ /*
+ *
+ * [Normal]
+ *
+ * <cpu1_0>
+ * cpu1_0 <-@-----> codec1_0
+ */
+ &cpu1_0 /* CPU side only */
+
+ /*
+ * [Semi-Multi]
+ *
+ * CPU:Codec = 1:N
+ *
+ * <sm> +-+
+ * cpu1_1 <--@---->| |-> codec1_1
+ * | |-> codec1_2
+ * +-+
+ */
+ &sm /* CPU side only */
+
+ /*
+ * [Multi-CPU/Codec-A]
+ *
+ * +-+ <mcpuA> +-+
+ * cpu1_2 <-| |<---@------>| |-> codec1_3
+ * cpu1_3 <-| | | |-> codec1_4
+ * +-+ +-+
+ */
+ &mcpuA /* CPU side only */
+
+ /*
+ * [Multi-CPU/Codec-B]
+ *
+ * +-+ <mcpuB> +-+
+ * | |<---@------>| |
+ * | | | |
+ * cpu1_4 <-| |<---------->| |-> codec1_5
+ * cpu1_5 <-| |<---+------>| |-> codec1_6
+ * +-+ \----->| |-> codec1_7
+ * +-+
+ */
+ &mcpuB /* CPU side only */
+
+ /*
+ * [Multi-CPU/Codec-C]
+ *
+ * +-+ <mcpuC> +-+
+ * | |<---@------>| |
+ * | | | |
+ * cpu1_6 <-| |<---------->| |-> codec1_8
+ * cpu1_7 <-| |<-----+---->| |-> codec1_9
+ * cpu1_8 <-| |<----/ +-+
+ * +-+
+ */
+ &mcpuC /* CPU side only */
+ >;
+
+ multi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * [Semi-Multi]
+ *
+ * <sm> +---+
+ * cpu1_1 <---@--->|X A|-> codec1_1
+ * | B|-> codec1_2
+ * +---+
+ */
+ ports@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 { reg = <0>; smcodec_ep: endpoint { remote-endpoint = <&cpu1_1_ep>; };};/* (X) to pair */
+ port@1 { reg = <1>; smcodec_A_ep: endpoint { remote-endpoint = <&codec1_1_ep>; };};/* (A) Multi Element */
+ port@2 { reg = <2>; smcodec_B_ep: endpoint { remote-endpoint = <&codec1_2_ep>; };};/* (B) Multi Element */
+ };
+
+ /*
+ * [Multi-CPU-A]
+ *
+ * +---+ <mcpuA> +---+
+ * cpu1_2 <-|A X|<---@---->|x a|-> codec1_3
+ * cpu1_3 <-|B | | b|-> codec1_4
+ * +---+ +---+
+ */
+ ports@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mcpuA: port@0 { reg = <0>; mcpu_A_ep: endpoint { remote-endpoint = <&mcodec_A_ep>; };}; /* (X) to pair */
+ port@1 { reg = <1>; mcpu_AA_ep: endpoint { remote-endpoint = <&cpu1_2_ep>; };}; /* (A) Multi Element */
+ port@2 { reg = <2>; mcpu_AB_ep: endpoint { remote-endpoint = <&cpu1_3_ep>; };}; /* (B) Multi Element */
+ };
+
+ /*
+ * [Multi-Codec-A]
+ *
+ * +---+ <mcpuA> +---+
+ * cpu1_2 <-|A X|<-@------>|x a|-> codec1_3
+ * cpu1_3 <-|B | | b|-> codec1_4
+ * +---+ +---+
+ */
+ ports@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 { reg = <0>; mcodec_A_ep: endpoint { remote-endpoint = <&mcpu_A_ep>; };}; /* (x) to pair */
+ port@1 { reg = <1>; mcodec_Aa_ep: endpoint { remote-endpoint = <&codec1_3_ep>; };}; /* (a) Multi Element */
+ port@2 { reg = <2>; mcodec_Ab_ep: endpoint { remote-endpoint = <&codec1_4_ep>; };}; /* (b) Multi Element */
+ };
+
+ /*
+ * [Multi-CPU-B]
+ *
+ * +---+ <mcpuB> +---+
+ * | X|<---@---->|x |
+ * | | | |
+ * cpu1_4 <-|A 1|<-------->|3 a|-> codec1_5
+ * cpu1_5 <-|B 2|<---+---->|4 b|-> codec1_6
+ * +---+ \--->|5 c|-> codec1_7
+ * +---+
+ */
+ ports@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mcpuB: port@0 {
+ reg = <0>;
+ mcpu_BX_ep: endpoint { remote-endpoint = <&mcodec_Bx_ep>; }; /* (X) to pair */
+ };
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ mcpu_BA_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_4_ep>; }; /* (A) Multi Element */
+ mcpu_B1_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_B3_ep>; }; /* (1) connected Codec */
+ };
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ mcpu_BB_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_5_ep>; }; /* (B) Multi Element */
+ mcpu_B2_0_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_B4_ep>; }; /* (2) connected Codec */
+ mcpu_B2_1_ep: endpoint@2 { reg = <2>; remote-endpoint = <&mcodec_B5_ep>; }; /* (2) connected Codec */
+ };
+ };
+
+ /*
+ * [Multi-Codec-B]
+ *
+ * +---+ <mcpuB> +---+
+ * | X|<-@------>|x |
+ * | | | |
+ * cpu1_4 <-|A 1|<-------->|3 a|-> codec1_5
+ * cpu1_5 <-|B 2|<---+---->|4 b|-> codec1_6
+ * +---+ \--->|5 c|-> codec1_7
+ * +---+
+ */
+ ports@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ mcodec_Bx_ep: endpoint { remote-endpoint = <&mcpu_BX_ep>; }; /* (x) to pair */
+ };
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ mcodec_Ba_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_5_ep>;}; /* (a) Multi Element */
+ mcodec_B3_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_B1_ep>; }; /* (3) connected CPU */
+ };
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ mcodec_Bb_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_6_ep>; }; /* (b) Multi Element */
+ mcodec_B4_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_B2_0_ep>;}; /* (4) connected CPU */
+ };
+ port@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ mcodec_Bc_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_7_ep>; }; /* (c) Multi Element */
+ mcodec_B5_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_B2_1_ep>;}; /* (5) connected CPU */
+ };
+ };
+
+ /*
+ * [Multi-CPU-C]
+ *
+ * +---+ <mcpuC> +---+
+ * | X|<-@------>|x |
+ * | | | |
+ * cpu1_6 <-|A 1|<-------->|4 a|-> codec1_8
+ * cpu1_7 <-|B 2|<-----+-->|5 b|-> codec1_9
+ * cpu1_8 <-|C 3|<----/ +---+
+ * +---+
+ */
+ ports@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mcpuC: port@0 {
+ reg = <0>;
+ mcpu_CX_ep: endpoint { remote-endpoint = <&mcodec_Cx_ep>; }; /* (X) to pair */
+ };
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ mcpu_CA_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_6_ep>; }; /* (A) Multi Element */
+ mcpu_C1_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_C4_ep>; }; /* (1) connected Codec */
+ };
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ mcpu_CB_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_7_ep>; }; /* (B) Multi Element */
+ mcpu_C2_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_C5_0_ep>; }; /* (2) connected Codec */
+ };
+ port@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ mcpu_CC_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_8_ep>; }; /* (C) Multi Element */
+ mcpu_C3_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_C5_1_ep>; }; /* (3) connected Codec */
+ };
+ };
+
+ /*
+ * [Multi-Codec-C]
+ *
+ * +---+ <mcpuC> +---+
+ * | X|<-@------>|x |
+ * | | | |
+ * cpu1_6 <-|A 1|<-------->|4 a|-> codec1_8
+ * cpu1_7 <-|B 2|<-----+-->|5 b|-> codec1_9
+ * cpu1_8 <-|C 3|<----/ +---+
+ * +---+
+ */
+ ports@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ mcodec_Cx_ep: endpoint { remote-endpoint = <&mcpu_CX_ep>; }; /* (x) to pair */
+ };
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ mcodec_Ca_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_8_ep>;}; /* (a) Multi Element */
+ mcodec_C4_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_C1_ep>; }; /* (4) connected CPU */
+ };
+ port@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ mcodec_Cb_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_9_ep>;}; /* (b) Multi Element */
+ mcodec_C5_0_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_C2_ep>; }; /* (5) connected CPU */
+ mcodec_C5_1_ep: endpoint@2 { reg = <2>; remote-endpoint = <&mcpu_C3_ep>; }; /* (5) connected CPU */
+ };
+ };
+ };
+ };
+
+ test_cpu_1 {
+ /*
+ * update compatible to indicate more detail behaviour
+ * if you want. see test-compatible for more detail.
+ *
+ * ex)
+ * - compatible = "test-cpu";
+ * + compatible = "test-cpu-verbose";
+ */
+ compatible = "test-cpu";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bitclock-master;
+ frame-master;
+
+ /* [Normal] */
+ cpu1_0: port@0 { reg = <0>; cpu1_0_ep: endpoint { remote-endpoint = <&codec1_0_ep>;}; };
+ /* [Semi-Multi] */
+ sm: port@1 { reg = <1>; cpu1_1_ep: endpoint { remote-endpoint = <&smcodec_ep>; }; };
+ /* [Multi-CPU-A] */
+ port@2 { reg = <2>; cpu1_2_ep: endpoint { remote-endpoint = <&mcpu_AA_ep>; }; };
+ port@3 { reg = <3>; cpu1_3_ep: endpoint { remote-endpoint = <&mcpu_AB_ep>; }; };
+ /* [Multi-CPU-B] */
+ port@4 { reg = <4>; cpu1_4_ep: endpoint { remote-endpoint = <&mcpu_BA_ep>; }; };
+ port@5 { reg = <5>; cpu1_5_ep: endpoint { remote-endpoint = <&mcpu_BB_ep>; }; };
+ /* [Multi-CPU-C] */
+ port@6 { reg = <6>; cpu1_6_ep: endpoint { remote-endpoint = <&mcpu_CA_ep>; }; };
+ port@7 { reg = <7>; cpu1_7_ep: endpoint { remote-endpoint = <&mcpu_CB_ep>; }; };
+ port@8 { reg = <8>; cpu1_8_ep: endpoint { remote-endpoint = <&mcpu_CC_ep>; }; };
+ };
+ };
+
+ test_codec_1 {
+ /*
+ * update compatible to indicate more detail behaviour
+ * if you want. see test-compatible for more detail.
+ *
+ * ex)
+ * - compatible = "test-codec";
+ * + compatible = "test-codec-verbose";
+ */
+ compatible = "test-codec";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* [Normal] */
+ port@0 { reg = <0>; codec1_0_ep: endpoint { remote-endpoint = <&cpu1_0_ep>; }; };
+ /* [Semi-Multi] */
+ port@1 { reg = <1>; codec1_1_ep: endpoint { remote-endpoint = <&smcodec_A_ep>; }; };
+ port@2 { reg = <2>; codec1_2_ep: endpoint { remote-endpoint = <&smcodec_B_ep>; }; };
+ /* [Multi-Codec-0] */
+ port@3 { reg = <3>; codec1_3_ep: endpoint { remote-endpoint = <&mcodec_Aa_ep>; }; };
+ port@4 { reg = <4>; codec1_4_ep: endpoint { remote-endpoint = <&mcodec_Ab_ep>; }; };
+ /* [Multi-Codec-1] */
+ port@5 { reg = <5>; codec1_5_ep: endpoint { remote-endpoint = <&mcodec_Ba_ep>; }; };
+ port@6 { reg = <6>; codec1_6_ep: endpoint { remote-endpoint = <&mcodec_Bb_ep>; }; };
+ port@7 { reg = <7>; codec1_7_ep: endpoint { remote-endpoint = <&mcodec_Bc_ep>; }; };
+ /* [Multi-Codec-2] */
+ port@8 { reg = <8>; codec1_8_ep: endpoint { remote-endpoint = <&mcodec_Ca_ep>; }; };
+ port@9 { reg = <9>; codec1_9_ep: endpoint { remote-endpoint = <&mcodec_Cb_ep>; }; };
+ };
+ };
+};
diff --git a/sound/soc/generic/audio-graph-card2-custom-sample2.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample2.dtsi
new file mode 100644
index 000000000000..1fb061a10ab1
--- /dev/null
+++ b/sound/soc/generic/audio-graph-card2-custom-sample2.dtsi
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * audio-graph-card2-custom-sample2.dtsi
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ * Copyright (C) 2020 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This sample indicates how to use audio-graph-card2 and its
+ * custom driver. "audio-graph-card2-custom-sample" is the custome driver
+ * which is using audio-graph-card2.
+ *
+ * You can easily use this sample by adding below line on your DT file,
+ * and add new CONFIG to your .config.
+ *
+ * #include "../../../../../sound/soc/generic/audio-graph-card2-custom-sample2.dtsi"
+ *
+ * CONFIG_SND_AUDIO_GRAPH_CARD2
+ * CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE
+ * CONFIG_SND_TEST_COMPONENT
+ *
+ *
+ * You can indicate more detail each device behavior as debug if you modify
+ * "compatible" on each test-component. see below
+ *
+ * test_cpu {
+ * - compatible = "test-cpu";
+ * + compatible = "test-cpu-verbose";
+ * ...
+ * };
+ *
+ * test_codec {
+ * - compatible = "test-codec";
+ * + compatible = "test-codec-verbose";
+ * ...
+ * };
+ *
+ *
+ * Below sample doesn't use "format" property,
+ * because test-component driver (test-cpu/test-codec) is supporting
+ * snd_soc_dai_ops :: .auto_selectable_formats.
+ * see
+ * snd_soc_runtime_get_dai_fmt()
+ * linux/sound/soc/generic/test-component.c :: test_dai_formats
+ */
+/ {
+ audio-graph-card2-custom-sample-2 {
+ /*
+ * You can use audio-graph-card2 directly by using
+ *
+ * compatible = "audio-graph-card2";
+ */
+ compatible = "audio-graph-card2-custom-sample";
+ label = "card2-custom-sample-2";
+
+ /* for [DPCM] */
+ /* BE FE */
+ routing = "TC DAI0 Playback", "DAI0 Playback",
+ "TC DAI0 Playback", "DAI1 Playback",
+ "DAI0 Capture", "TC DAI0 Capture",
+ "DAI1 Capture", "TC DAI0 Capture",
+ /* for [DPCM-Multi] */
+ /* BE FE */
+ "TC DAI1 Playback", "DAI2 Playback",
+ "TC DAI2 Playback", "DAI2 Playback",
+ "TC DAI1 Playback", "DAI3 Playback",
+ "TC DAI2 Playback", "DAI3 Playback",
+ "DAI2 Capture", "TC DAI1 Capture",
+ "DAI2 Capture", "TC DAI2 Capture",
+ "DAI3 Capture", "TC DAI1 Capture",
+ "DAI3 Capture", "TC DAI2 Capture",
+ /* for [Codec2Codec] */
+ "TC OUT", "TC DAI4 Playback",
+ "TC DAI3 Capture", "TC IN",
+ /* for [Codec2Codec-Multi] */
+ "TC OUT", "TC DAI7 Playback",
+ "TC DAI5 Capture", "TC IN",
+ "TC OUT", "TC DAI8 Playback",
+ "TC DAI6 Capture", "TC IN";
+
+ /*
+ * @ : used at links
+ */
+ links = <
+ /*
+ * [DPCM]
+ *
+ * cpu20/cpu21 are converting rate to 44.1kHz
+ *
+ * FE BE
+ * <feA> **** <beA>
+ * cpu2_0 <----@---* *------@---> codec2_0 (44.1kHz)
+ * cpu2_1 <----@---* *
+ * <feB> ****
+ */
+ &feA &feB &beA /* both FE / BE */
+
+ /*
+ * [DPCM-Multi]
+ *
+ * FE BE
+ * <feC> **** <beB> +-+
+ * cpu2_2 <----@---* *------@---> | | -> codec2_1
+ * cpu2_3 <----@---* * | | -> codec2_2
+ * <feD> **** +-+
+ */
+ &feC &feD &beB /* both FE / BE*/
+
+ /*
+ * [Codec2Codec]
+ *
+ * <c2c>
+ * +-@-> codec2_3
+ * |
+ * +---> codec2_4
+ */
+ &c2c /* CPU side only */
+
+ /*
+ * [Codec2Codec-Multi]
+ *
+ * --NOTE--
+ * Multi connect N:M is not supported by ASoC.
+ *
+ * <c2c_m> +-+
+ * +---@-->| |-> codec2_5
+ * | | |-> codec2_6
+ * | +-+
+ * | +-+
+ * +------>| |-> codec2_7
+ * | |-> codec2_8
+ * +-+
+ */
+ &c2c_m /* CPU side only */
+ >;
+
+ multi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * [DPCM-Multi]::BE
+ *
+ * FE BE
+ * <feC> **** <beB> +---+
+ * cpu2_2 <----@---* *------@---> |x a| -> codec2_1
+ * cpu2_3 <----@---* * | b| -> codec2_2
+ * <feD> **** +---+
+ */
+ ports@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 { reg = <0>; mbe_x_ep: endpoint { remote-endpoint = <&beB_ep>; };};/* (x) to pair */
+ port@1 { reg = <1>; mbe_a_ep: endpoint { remote-endpoint = <&codec2_1_ep>; };};/* (a) Multi Element */
+ port@2 { reg = <2>; mbe_b_ep: endpoint { remote-endpoint = <&codec2_2_ep>; };};/* (b) Multi Element */
+ };
+
+ /*
+ * [Codec2Codec-Multi]::CPU
+ *
+ * <c2c_m> c2cmf +---+
+ * +---@---------->|X A|-> codec2_5
+ * | | B|-> codec2_6
+ * | +---+
+ * | c2cmb +---+
+ * +-------------->|x a|-> codec2_7
+ * | b|-> codec2_8
+ * +---+
+ */
+ ports@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 { reg = <0>; mc2c0X_ep: endpoint { remote-endpoint = <&c2cmf_ep>; };};/* (X) to pair */
+ port@1 { reg = <1>; mc2c0A_ep: endpoint { remote-endpoint = <&codec2_5_ep>; };};/* (A) Multi Element */
+ port@2 { reg = <2>; mc2c0B_ep: endpoint { remote-endpoint = <&codec2_6_ep>; };};/* (B) Multi Element */
+ };
+
+ /*
+ * [Codec2Codec-Multi]::Codec
+ *
+ * <c2c_m> c2cmf +---+
+ * +---@---------->|X A|-> codec2_5
+ * | | B|-> codec2_6
+ * | +---+
+ * | c2cmb +---+
+ * +-------------->|x a|-> codec2_7
+ * | b|-> codec2_8
+ * +---+
+ */
+ ports@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 { reg = <0>; mc2c1x_ep: endpoint { remote-endpoint = <&c2cmb_ep>; };};/* (x) to pair */
+ port@1 { reg = <1>; mc2c1a_ep: endpoint { remote-endpoint = <&codec2_7_ep>; };};/* (a) Multi Element */
+ port@2 { reg = <2>; mc2c1b_ep: endpoint { remote-endpoint = <&codec2_8_ep>; };};/* (b) Multi Element */
+ };
+ };
+
+ dpcm {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* FE part */
+ ports@0 {
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /*
+ * [DPCM]::FE
+ *
+ * FE BE
+ * <feA> **** <beA>
+ * cpu2_0 <----@---* *------@---> codec2_0 (44.1kHz)
+ * cpu2_1 <----@---* *
+ * <feB> ****
+ */
+ feA: port@0 { reg = <0>; feA_ep: endpoint { remote-endpoint = <&cpu2_0_ep>; }; };
+ feB: port@1 { reg = <1>; feB_ep: endpoint { remote-endpoint = <&cpu2_1_ep>; }; };
+
+ /*
+ * [DPCM-Multi]::FE
+ *
+ * FE BE
+ * <feC> **** <beB> +-+
+ * cpu2_2 <----@---* *------@---> | | -> codec2_1
+ * cpu2_3 <----@---* * | | -> codec2_2
+ * <feD> **** +-+
+ */
+ feC: port@2 { reg = <2>; feC_ep: endpoint { remote-endpoint = <&cpu2_2_ep>; }; };
+ feD: port@3 { reg = <3>; feD_ep: endpoint { remote-endpoint = <&cpu2_3_ep>; }; };
+ };
+
+ /* BE part */
+ ports@1 {
+ reg = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /*
+ * [DPCM]::BE
+ *
+ * FE BE
+ * <feA> **** <beA>
+ * cpu2_0 <----@---* *------@---> codec2_0 (44.1kHz)
+ * cpu2_1 <----@---* *
+ * <feB> ****
+ */
+ beA: port@0 { reg = <0>; beA_ep: endpoint { remote-endpoint = <&codec2_0_ep>; }; };
+
+ /*
+ * [DPCM-Multi]::BE
+ *
+ * FE BE
+ * <feC> **** <beB> +-------+
+ * cpu2_2 <----@---* *------@---> |mbe_x | -> codec2_1
+ * cpu2_3 <----@---* * | | -> codec2_2
+ * <feD> **** +-------+
+ */
+ beB: port@1 { reg = <1>; beB_ep: endpoint { remote-endpoint = <&mbe_x_ep>; }; };
+ };
+ };
+
+ codec2codec {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /*
+ * [Codec2Codec]
+ *
+ * <c2c>
+ * +-@--> codec2_3
+ * |
+ * +----> codec2_4
+ */
+ ports@0 {
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* use default settings */
+ c2c: port@0 { reg = <0>; c2cf_ep: endpoint { remote-endpoint = <&codec2_3_ep>; }; };
+ port@1 { reg = <1>; c2cb_ep: endpoint { remote-endpoint = <&codec2_4_ep>; }; };
+ };
+
+ /*
+ * [Codec2Codec-Multi]
+ *
+ * <c2c_m> c2cmf +--------+
+ * +---@---------->|mc2c0X |-> codec2_5
+ * | | |-> codec2_6
+ * | +--------+
+ * | c2cmb +--------+
+ * +-------------->|mc2c1x |-> codec2_7
+ * | |-> codec2_8
+ * +--------+
+ */
+ ports@1 {
+ reg = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* use original settings */
+ rate = <48000>;
+ c2c_m: port@0 { reg = <0>; c2cmf_ep: endpoint { remote-endpoint = <&mc2c0X_ep>; }; };
+ port@1 { reg = <1>; c2cmb_ep: endpoint { remote-endpoint = <&mc2c1x_ep>; }; };
+ };
+ };
+ };
+
+ test_cpu_2 {
+ /*
+ * update compatible to indicate more detail behaviour
+ * if you want. see test-compatible for more detail.
+ *
+ * ex)
+ * - compatible = "test-cpu";
+ * + compatible = "test-cpu-verbose";
+ */
+ compatible = "test-cpu";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bitclock-master;
+ frame-master;
+
+ /* [DPCM]::FE */
+ port@0 { reg = <0>; cpu2_0_ep: endpoint { remote-endpoint = <&feA_ep>; };};
+ port@1 { reg = <1>; cpu2_1_ep: endpoint { remote-endpoint = <&feB_ep>; };};
+ /* [DPCM-Multi]::FE */
+ port@2 { reg = <2>; cpu2_2_ep: endpoint { remote-endpoint = <&feC_ep>; };};
+ port@3 { reg = <3>; cpu2_3_ep: endpoint { remote-endpoint = <&feD_ep>; };};
+ };
+ };
+
+ test_codec_2 {
+ /*
+ * update compatible to indicate more detail behaviour
+ * if you want. see test-compatible for more detail.
+ *
+ * ex)
+ * - compatible = "test-codec";
+ * + compatible = "test-codec-verbose";
+ */
+ compatible = "test-codec";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * prefix can be added to *component*,
+ * see audio-graph-card2::routing
+ */
+ prefix = "TC";
+
+ /* [DPCM]::BE */
+ port@0 {
+ convert-rate = <44100>;
+ reg = <0>; codec2_0_ep: endpoint { remote-endpoint = <&beA_ep>; };
+ };
+ /* [DPCM-Multi]::BE */
+ port@1 { reg = <1>; codec2_1_ep: endpoint { remote-endpoint = <&mbe_a_ep>; };};
+ port@2 { reg = <2>; codec2_2_ep: endpoint { remote-endpoint = <&mbe_b_ep>; };};
+ /* [Codec2Codec] */
+ port@3 { bitclock-master;
+ frame-master;
+ reg = <3>; codec2_3_ep: endpoint { remote-endpoint = <&c2cf_ep>; };};
+ port@4 { reg = <4>; codec2_4_ep: endpoint { remote-endpoint = <&c2cb_ep>; };};
+ /* [Codec2Codec-Multi] */
+ port@5 { bitclock-master;
+ frame-master;
+ reg = <5>; codec2_5_ep: endpoint { remote-endpoint = <&mc2c0A_ep>; };};
+ port@6 { reg = <6>; codec2_6_ep: endpoint { remote-endpoint = <&mc2c0B_ep>; };};
+ port@7 { reg = <7>; codec2_7_ep: endpoint { remote-endpoint = <&mc2c1a_ep>; };};
+ port@8 { reg = <8>; codec2_8_ep: endpoint { remote-endpoint = <&mc2c1b_ep>; };};
+ };
+ };
+};
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c
index ee94b256b770..5dcc78c551a2 100644
--- a/sound/soc/generic/audio-graph-card2.c
+++ b/sound/soc/generic/audio-graph-card2.c
@@ -234,6 +234,13 @@ enum graph_type {
#define GRAPH_NODENAME_DPCM "dpcm"
#define GRAPH_NODENAME_C2C "codec2codec"
+#define graph_ret(priv, ret) _graph_ret(priv, __func__, ret)
+static inline int _graph_ret(struct simple_util_priv *priv,
+ const char *func, int ret)
+{
+ return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func);
+}
+
#define ep_to_port(ep) of_get_parent(ep)
static struct device_node *port_to_ports(struct device_node *port)
{
@@ -409,21 +416,21 @@ static int __graph_parse_node(struct simple_util_priv *priv,
dai = simple_props_to_dai_codec(dai_props, idx);
}
- ret = graph_util_parse_dai(dev, ep, dlc, &is_single_links);
+ ret = graph_util_parse_dai(priv, ep, dlc, &is_single_links);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_parse_tdm(ep, dai);
if (ret < 0)
- return ret;
+ goto end;
- ret = simple_util_parse_tdm_width_map(dev, ep, dai);
+ ret = simple_util_parse_tdm_width_map(priv, ep, dai);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_parse_clk(dev, ep, dai, dlc);
if (ret < 0)
- return ret;
+ goto end;
/*
* set DAI Name
@@ -443,22 +450,22 @@ static int __graph_parse_node(struct simple_util_priv *priv,
case GRAPH_NORMAL:
/* run is_cpu only. see audio_graph2_link_normal() */
if (is_cpu)
- simple_util_set_dailink_name(dev, dai_link, "%s%s-%s%s",
+ simple_util_set_dailink_name(priv, dai_link, "%s%s-%s%s",
cpus->dai_name, cpu_multi,
codecs->dai_name, codec_multi);
break;
case GRAPH_DPCM:
if (is_cpu)
- simple_util_set_dailink_name(dev, dai_link, "fe.%pOFP.%s%s",
+ simple_util_set_dailink_name(priv, dai_link, "fe.%pOFP.%s%s",
cpus->of_node, cpus->dai_name, cpu_multi);
else
- simple_util_set_dailink_name(dev, dai_link, "be.%pOFP.%s%s",
+ simple_util_set_dailink_name(priv, dai_link, "be.%pOFP.%s%s",
codecs->of_node, codecs->dai_name, codec_multi);
break;
case GRAPH_C2C:
/* run is_cpu only. see audio_graph2_link_c2c() */
if (is_cpu)
- simple_util_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s",
+ simple_util_set_dailink_name(priv, dai_link, "c2c.%s%s-%s%s",
cpus->dai_name, cpu_multi,
codecs->dai_name, codec_multi);
break;
@@ -488,11 +495,12 @@ static int __graph_parse_node(struct simple_util_priv *priv,
simple_util_canonicalize_cpu(cpus, is_single_links);
simple_util_canonicalize_platform(platforms, cpus);
}
-
- return 0;
+end:
+ return graph_ret(priv, ret);
}
-static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link,
+static int 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)
{
@@ -534,10 +542,10 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link,
struct device_node *mcodec_port_top __free(device_node) = ep_to_port(mcodec_ep_top);
struct device_node *mcodec_ports __free(device_node) = port_to_ports(mcodec_port_top);
int nm_max = max(dai_link->num_cpus, dai_link->num_codecs);
- int ret = 0;
+ int ret = -EINVAL;
if (cpu_idx > dai_link->num_cpus)
- return -EINVAL;
+ goto end;
for_each_of_graph_port_endpoint(mcpu_port, mcpu_ep_n) {
int codec_idx = 0;
@@ -578,8 +586,8 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link,
if (ret < 0)
break;
}
-
- return ret;
+end:
+ return graph_ret(priv, ret);
}
static int graph_parse_node_multi(struct simple_util_priv *priv,
@@ -633,7 +641,7 @@ static int graph_parse_node_multi(struct simple_util_priv *priv,
/* CPU:Codec = N:M */
if (is_cpu && dai_link->ch_maps) {
- ret = graph_parse_node_multi_nm(dai_link, &nm_idx, idx, port);
+ ret = graph_parse_node_multi_nm(priv, dai_link, &nm_idx, idx, port);
if (ret < 0)
goto multi_err;
}
@@ -643,7 +651,7 @@ static int graph_parse_node_multi(struct simple_util_priv *priv,
ret = -EINVAL;
multi_err:
- return ret;
+ return graph_ret(priv, ret);
}
static int graph_parse_node_single(struct simple_util_priv *priv,
@@ -651,7 +659,7 @@ static int graph_parse_node_single(struct simple_util_priv *priv,
struct device_node *ep,
struct link_info *li, int is_cpu)
{
- return __graph_parse_node(priv, gtype, ep, li, is_cpu, 0);
+ return graph_ret(priv, __graph_parse_node(priv, gtype, ep, li, is_cpu, 0));
}
static int graph_parse_node(struct simple_util_priv *priv,
@@ -660,11 +668,14 @@ static int graph_parse_node(struct simple_util_priv *priv,
struct link_info *li, int is_cpu)
{
struct device_node *port __free(device_node) = ep_to_port(ep);
+ int ret;
if (graph_lnk_is_multi(port))
- return graph_parse_node_multi(priv, gtype, port, li, is_cpu);
+ ret = graph_parse_node_multi(priv, gtype, port, li, is_cpu);
else
- return graph_parse_node_single(priv, gtype, ep, li, is_cpu);
+ ret = graph_parse_node_single(priv, gtype, ep, li, is_cpu);
+
+ return graph_ret(priv, ret);
}
static void graph_parse_daifmt(struct device_node *node, unsigned int *daifmt)
@@ -842,18 +853,19 @@ int audio_graph2_link_normal(struct simple_util_priv *priv,
*/
ret = graph_parse_node(priv, GRAPH_NORMAL, codec_ep, li, 0);
if (ret < 0)
- return ret;
+ goto end;
/*
* call CPU, and set DAI Name
*/
ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_ep, li, 1);
if (ret < 0)
- return ret;
+ goto end;
graph_link_init(priv, lnk, cpu_ep, codec_ep, li, 1);
- return ret;
+end:
+ return graph_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(audio_graph2_link_normal);
@@ -946,7 +958,7 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
graph_link_init(priv, lnk, cpu_ep, codec_ep, li, is_cpu);
- return ret;
+ return graph_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm);
@@ -992,8 +1004,13 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv,
struct snd_soc_pcm_stream *c2c_conf;
c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL);
- if (!c2c_conf)
- return ret;
+ if (!c2c_conf) {
+ /*
+ * Clang doesn't allow to use "goto end" before calling __free(),
+ * because it bypasses the initialization. Use graph_ret() directly.
+ */
+ return graph_ret(priv, -ENOMEM);
+ }
c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */
c2c_conf->rates = SNDRV_PCM_RATE_8000_384000;
@@ -1019,18 +1036,18 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv,
*/
ret = graph_parse_node(priv, GRAPH_C2C, codec1_ep, li, 0);
if (ret < 0)
- return ret;
+ goto end;
/*
* call CPU, and set DAI Name
*/
ret = graph_parse_node(priv, GRAPH_C2C, codec0_ep, li, 1);
if (ret < 0)
- return ret;
+ goto end;
graph_link_init(priv, lnk, codec0_ep, codec1_ep, li, 1);
-
- return ret;
+end:
+ return graph_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(audio_graph2_link_c2c);
@@ -1078,7 +1095,7 @@ static int graph_link(struct simple_util_priv *priv,
li->link++;
err:
- return ret;
+ return graph_ret(priv, ret);
}
static int graph_counter(struct device_node *lnk)
@@ -1249,7 +1266,7 @@ static int graph_count(struct simple_util_priv *priv,
li->link++;
err:
- return ret;
+ return graph_ret(priv, ret);
}
static int graph_for_each_link(struct simple_util_priv *priv,
@@ -1266,7 +1283,7 @@ static int graph_for_each_link(struct simple_util_priv *priv,
struct device_node *node = dev->of_node;
struct device_node *lnk;
enum graph_type gtype;
- int rc, ret;
+ int rc, ret = 0;
/* loop for all listed CPU port */
of_for_each_phandle(&it, rc, node, "links", NULL, 0) {
@@ -1276,10 +1293,10 @@ static int graph_for_each_link(struct simple_util_priv *priv,
ret = func(priv, hooks, gtype, lnk, li);
if (ret < 0)
- return ret;
+ break;
}
- return 0;
+ return graph_ret(priv, ret);
}
int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev,
@@ -1332,7 +1349,7 @@ int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev,
if (ret < 0)
goto err;
- ret = simple_util_parse_card_name(card, NULL);
+ ret = simple_util_parse_card_name(priv, NULL);
if (ret < 0)
goto err;
@@ -1355,7 +1372,7 @@ err:
if (ret < 0)
dev_err_probe(dev, ret, "parse error\n");
- return ret;
+ return graph_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(audio_graph2_parse_of);
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index dd414634b4ac..355f7ec8943c 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -15,6 +15,13 @@
#include <sound/pcm_params.h>
#include <sound/simple_card_utils.h>
+#define simple_ret(priv, ret) _simple_ret(priv, __func__, ret)
+static inline int _simple_ret(struct simple_util_priv *priv,
+ const char *func, int ret)
+{
+ return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func);
+}
+
int simple_util_get_sample_fmt(struct simple_util_data *data)
{
int i;
@@ -133,33 +140,42 @@ int simple_util_parse_daifmt(struct device *dev,
}
EXPORT_SYMBOL_GPL(simple_util_parse_daifmt);
-int simple_util_parse_tdm_width_map(struct device *dev, struct device_node *np,
+int simple_util_parse_tdm_width_map(struct simple_util_priv *priv, struct device_node *np,
struct simple_util_dai *dai)
{
+ struct device *dev = simple_priv_to_dev(priv);
int n, i, ret;
u32 *p;
+ /*
+ * NOTE
+ *
+ * Clang doesn't allow to use "goto end" before calling __free(),
+ * because it bypasses the initialization. Use simple_ret() directly.
+ */
+
n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32));
if (n <= 0)
return 0;
+
if (n % 3) {
dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n");
- return -EINVAL;
+ return simple_ret(priv, -EINVAL); /* see NOTE */
}
+ ret = -ENOMEM;
dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL);
if (!dai->tdm_width_map)
- return -ENOMEM;
+ return simple_ret(priv, ret); /* see NOTE */
- u32 *array_values __free(kfree) = kcalloc(n, sizeof(*array_values),
- GFP_KERNEL);
+ u32 *array_values __free(kfree) = kcalloc(n, sizeof(*array_values), GFP_KERNEL);
if (!array_values)
- return -ENOMEM;
+ goto end;
ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n);
if (ret < 0) {
dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret);
- return ret;
+ goto end;
}
p = array_values;
@@ -170,15 +186,17 @@ int simple_util_parse_tdm_width_map(struct device *dev, struct device_node *np,
}
dai->n_tdm_widths = i;
-
- return 0;
+ ret = 0;
+end:
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(simple_util_parse_tdm_width_map);
-int simple_util_set_dailink_name(struct device *dev,
+int simple_util_set_dailink_name(struct simple_util_priv *priv,
struct snd_soc_dai_link *dai_link,
const char *fmt, ...)
{
+ struct device *dev = simple_priv_to_dev(priv);
va_list ap;
char *name = NULL;
int ret = -ENOMEM;
@@ -194,13 +212,14 @@ int simple_util_set_dailink_name(struct device *dev,
dai_link->stream_name = name;
}
- return ret;
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(simple_util_set_dailink_name);
-int simple_util_parse_card_name(struct snd_soc_card *card,
+int simple_util_parse_card_name(struct simple_util_priv *priv,
char *prefix)
{
+ struct snd_soc_card *card = simple_priv_to_card(priv);
int ret;
if (!prefix)
@@ -214,13 +233,13 @@ int simple_util_parse_card_name(struct snd_soc_card *card,
snprintf(prop, sizeof(prop), "%sname", prefix);
ret = snd_soc_of_parse_card_name(card, prop);
if (ret < 0)
- return ret;
+ goto end;
}
if (!card->name && card->dai_link)
card->name = card->dai_link->name;
-
- return 0;
+end:
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(simple_util_parse_card_name);
@@ -348,7 +367,8 @@ cpu_err:
break;
simple_clk_disable(dai);
}
- return ret;
+
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(simple_util_startup);
@@ -379,16 +399,19 @@ void simple_util_shutdown(struct snd_pcm_substream *substream)
}
EXPORT_SYMBOL_GPL(simple_util_shutdown);
-static int simple_set_clk_rate(struct device *dev,
- struct simple_util_dai *simple_dai,
- unsigned long rate)
+static int simple_set_clk_rate(struct simple_util_priv *priv,
+ struct simple_util_dai *simple_dai,
+ unsigned long rate)
{
+ struct device *dev = simple_priv_to_dev(priv);
+ int ret = -EINVAL;
+
if (!simple_dai)
return 0;
if (simple_dai->clk_fixed && rate != simple_dai->sysclk) {
dev_err(dev, "dai %s invalid clock rate %lu\n", simple_dai->name, rate);
- return -EINVAL;
+ goto end;
}
if (!simple_dai->clk)
@@ -397,12 +420,15 @@ static int simple_set_clk_rate(struct device *dev,
if (clk_get_rate(simple_dai->clk) == rate)
return 0;
- return clk_set_rate(simple_dai->clk, rate);
+ ret = clk_set_rate(simple_dai->clk, rate);
+end:
+ return simple_ret(priv, ret);
}
-static int simple_set_tdm(struct snd_soc_dai *dai,
- struct simple_util_dai *simple_dai,
- struct snd_pcm_hw_params *params)
+static int simple_set_tdm(struct simple_util_priv *priv,
+ struct snd_soc_dai *dai,
+ struct simple_util_dai *simple_dai,
+ struct snd_pcm_hw_params *params)
{
int sample_bits = params_width(params);
int slot_width, slot_count;
@@ -430,12 +456,8 @@ static int simple_set_tdm(struct snd_soc_dai *dai,
simple_dai->rx_slot_mask,
slot_count,
slot_width);
- if (ret && ret != -ENOTSUPP) {
- dev_err(dai->dev, "simple-card: set_tdm_slot error: %d\n", ret);
- return ret;
- }
- return 0;
+ return simple_ret(priv, ret);
}
int simple_util_hw_params(struct snd_pcm_substream *substream,
@@ -457,15 +479,15 @@ int simple_util_hw_params(struct snd_pcm_substream *substream,
mclk = params_rate(params) * mclk_fs;
for_each_prop_dai_codec(props, i, pdai) {
- ret = simple_set_clk_rate(rtd->dev, pdai, mclk);
+ ret = simple_set_clk_rate(priv, pdai, mclk);
if (ret < 0)
- return ret;
+ goto end;
}
for_each_prop_dai_cpu(props, i, pdai) {
- ret = simple_set_clk_rate(rtd->dev, pdai, mclk);
+ ret = simple_set_clk_rate(priv, pdai, mclk);
if (ret < 0)
- return ret;
+ goto end;
}
/* Ensure sysclk is set on all components in case any
@@ -476,39 +498,40 @@ int simple_util_hw_params(struct snd_pcm_substream *substream,
ret = snd_soc_component_set_sysclk(component, 0, 0,
mclk, SND_SOC_CLOCK_IN);
if (ret && ret != -ENOTSUPP)
- return ret;
+ goto end;
}
for_each_rtd_codec_dais(rtd, i, sdai) {
pdai = simple_props_to_dai_codec(props, i);
ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
if (ret && ret != -ENOTSUPP)
- return ret;
+ goto end;
}
for_each_rtd_cpu_dais(rtd, i, sdai) {
pdai = simple_props_to_dai_cpu(props, i);
ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
if (ret && ret != -ENOTSUPP)
- return ret;
+ goto end;
}
}
for_each_prop_dai_codec(props, i, pdai) {
sdai = snd_soc_rtd_to_codec(rtd, i);
- ret = simple_set_tdm(sdai, pdai, params);
+ ret = simple_set_tdm(priv, sdai, pdai, params);
if (ret < 0)
- return ret;
+ goto end;
}
for_each_prop_dai_cpu(props, i, pdai) {
sdai = snd_soc_rtd_to_cpu(rtd, i);
- ret = simple_set_tdm(sdai, pdai, params);
+ ret = simple_set_tdm(priv, sdai, pdai, params);
if (ret < 0)
- return ret;
+ goto end;
}
-
- return 0;
+ ret = 0;
+end:
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(simple_util_hw_params);
@@ -536,7 +559,8 @@ int simple_util_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
}
EXPORT_SYMBOL_GPL(simple_util_be_hw_params_fixup);
-static int simple_init_dai(struct snd_soc_dai *dai, struct simple_util_dai *simple_dai)
+static int simple_init_dai(struct simple_util_priv *priv,
+ struct snd_soc_dai *dai, struct simple_util_dai *simple_dai)
{
int ret;
@@ -548,7 +572,7 @@ static int simple_init_dai(struct snd_soc_dai *dai, struct simple_util_dai *simp
simple_dai->clk_direction);
if (ret && ret != -ENOTSUPP) {
dev_err(dai->dev, "simple-card: set_sysclk error\n");
- return ret;
+ goto end;
}
}
@@ -560,11 +584,12 @@ static int simple_init_dai(struct snd_soc_dai *dai, struct simple_util_dai *simp
simple_dai->slot_width);
if (ret && ret != -ENOTSUPP) {
dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
- return ret;
+ goto end;
}
}
-
- return 0;
+ ret = 0;
+end:
+ return simple_ret(priv, ret);
}
static inline int simple_component_is_codec(struct snd_soc_component *component)
@@ -572,7 +597,8 @@ static inline int simple_component_is_codec(struct snd_soc_component *component)
return component->driver->endianness;
}
-static int simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd,
+static int simple_init_for_codec2codec(struct simple_util_priv *priv,
+ struct snd_soc_pcm_runtime *rtd,
struct simple_dai_props *dai_props)
{
struct snd_soc_dai_link *dai_link = rtd->dai_link;
@@ -604,12 +630,13 @@ static int simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd,
if (ret < 0) {
dev_err(rtd->dev, "simple-card: no valid dai_link params\n");
- return ret;
+ goto end;
}
+ ret = -ENOMEM;
c2c_params = devm_kzalloc(rtd->dev, sizeof(*c2c_params), GFP_KERNEL);
if (!c2c_params)
- return -ENOMEM;
+ goto end;
c2c_params->formats = hw.formats;
c2c_params->rates = hw.rates;
@@ -621,7 +648,9 @@ static int simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd,
dai_link->c2c_params = c2c_params;
dai_link->num_c2c_params = 1;
- return 0;
+ ret = 0;
+end:
+ return simple_ret(priv, ret);
}
int simple_util_dai_init(struct snd_soc_pcm_runtime *rtd)
@@ -632,21 +661,19 @@ int simple_util_dai_init(struct snd_soc_pcm_runtime *rtd)
int i, ret;
for_each_prop_dai_codec(props, i, dai) {
- ret = simple_init_dai(snd_soc_rtd_to_codec(rtd, i), dai);
+ ret = simple_init_dai(priv, snd_soc_rtd_to_codec(rtd, i), dai);
if (ret < 0)
- return ret;
+ goto end;
}
for_each_prop_dai_cpu(props, i, dai) {
- ret = simple_init_dai(snd_soc_rtd_to_cpu(rtd, i), dai);
+ ret = simple_init_dai(priv, snd_soc_rtd_to_cpu(rtd, i), dai);
if (ret < 0)
- return ret;
+ goto end;
}
- ret = simple_init_for_codec2codec(rtd, props);
- if (ret < 0)
- return ret;
-
- return 0;
+ ret = simple_init_for_codec2codec(priv, rtd, props);
+end:
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(simple_util_dai_init);
@@ -831,7 +858,7 @@ int simple_util_init_aux_jacks(struct simple_util_priv *priv, char *prefix)
priv->aux_jacks = devm_kcalloc(card->dev, num,
sizeof(struct snd_soc_jack), GFP_KERNEL);
if (!priv->aux_jacks)
- return -ENOMEM;
+ return simple_ret(priv, -ENOMEM);
for_each_card_auxs(card, component) {
char id[128];
@@ -992,13 +1019,11 @@ int graph_util_card_probe(struct snd_soc_card *card)
ret = simple_util_init_hp(card, &priv->hp_jack, NULL);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_init_mic(card, &priv->mic_jack, NULL);
- if (ret < 0)
- return ret;
-
- return 0;
+end:
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(graph_util_card_probe);
@@ -1074,9 +1099,11 @@ static int graph_get_dai_id(struct device_node *ep)
return id;
}
-int graph_util_parse_dai(struct device *dev, struct device_node *ep,
+int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
struct snd_soc_dai_link_component *dlc, int *is_single_link)
{
+ struct device *dev = simple_priv_to_dev(priv);
+ struct device_node *node;
struct of_phandle_args args = {};
struct snd_soc_dai *dai;
int ret;
@@ -1084,7 +1111,7 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep,
if (!ep)
return 0;
- struct device_node *node __free(device_node) = of_graph_get_port_parent(ep);
+ node = of_graph_get_port_parent(ep);
/*
* Try to find from DAI node
@@ -1092,10 +1119,16 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep,
args.np = ep;
dai = snd_soc_get_dai_via_args(&args);
if (dai) {
- dlc->dai_name = snd_soc_dai_name_get(dai);
- dlc->dai_args = snd_soc_copy_dai_args(dev, &args);
- if (!dlc->dai_args)
- return -ENOMEM;
+ const char *dai_name = snd_soc_dai_name_get(dai);
+ const struct of_phandle_args *dai_args = snd_soc_copy_dai_args(dev, &args);
+
+ ret = -ENOMEM;
+ if (!dai_args)
+ goto err;
+
+ dlc->of_node = node;
+ dlc->dai_name = dai_name;
+ dlc->dai_args = dai_args;
goto parse_dai_end;
}
@@ -1126,13 +1159,17 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep,
*/
ret = snd_soc_get_dlc(&args, dlc);
if (ret < 0)
- return ret;
+ goto err;
parse_dai_end:
if (is_single_link)
*is_single_link = of_graph_get_endpoint_count(node) == 1;
+ ret = 0;
+err:
+ if (ret < 0)
+ of_node_put(node);
- return 0;
+ return simple_ret(priv, ret);
}
EXPORT_SYMBOL_GPL(graph_util_parse_dai);
@@ -1142,9 +1179,9 @@ void graph_util_parse_link_direction(struct device_node *np,
bool is_playback_only = of_property_read_bool(np, "playback-only");
bool is_capture_only = of_property_read_bool(np, "capture-only");
- if (is_playback_only)
+ if (playback_only)
*playback_only = is_playback_only;
- if (is_capture_only)
+ if (capture_only)
*capture_only = is_capture_only;
}
EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index afe7e79ffdbd..5af6d1b308f2 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -29,7 +29,16 @@ static const struct snd_soc_ops simple_ops = {
.hw_params = simple_util_hw_params,
};
-static int simple_parse_platform(struct device_node *node, struct snd_soc_dai_link_component *dlc)
+#define simple_ret(priv, ret) _simple_ret(priv, __func__, ret)
+static inline int _simple_ret(struct simple_util_priv *priv,
+ const char *func, int ret)
+{
+ return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func);
+}
+
+static int simple_parse_platform(struct simple_util_priv *priv,
+ struct device_node *node,
+ struct snd_soc_dai_link_component *dlc)
{
struct of_phandle_args args;
int ret;
@@ -43,7 +52,7 @@ static int simple_parse_platform(struct device_node *node, struct snd_soc_dai_li
*/
ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args);
if (ret)
- return ret;
+ return simple_ret(priv, ret);
/* dai_name is not required and may not exist for plat component */
@@ -52,11 +61,12 @@ static int simple_parse_platform(struct device_node *node, struct snd_soc_dai_li
return 0;
}
-static int simple_parse_dai(struct device *dev,
+static int simple_parse_dai(struct simple_util_priv *priv,
struct device_node *node,
struct snd_soc_dai_link_component *dlc,
int *is_single_link)
{
+ struct device *dev = simple_priv_to_dev(priv);
struct of_phandle_args args;
struct snd_soc_dai *dai;
int ret;
@@ -70,17 +80,18 @@ static int simple_parse_dai(struct device *dev,
*/
ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args);
if (ret)
- return ret;
+ goto end;
/*
* Try to find from DAI args
*/
dai = snd_soc_get_dai_via_args(&args);
if (dai) {
+ ret = -ENOMEM;
dlc->dai_name = snd_soc_dai_name_get(dai);
dlc->dai_args = snd_soc_copy_dai_args(dev, &args);
if (!dlc->dai_args)
- return -ENOMEM;
+ goto end;
goto parse_dai_end;
}
@@ -106,13 +117,14 @@ static int simple_parse_dai(struct device *dev,
*/
ret = snd_soc_get_dlc(&args, dlc);
if (ret < 0)
- return ret;
+ goto end;
parse_dai_end:
if (is_single_link)
*is_single_link = !args.args_count;
-
- return 0;
+ ret = 0;
+end:
+ return simple_ret(priv, ret);
}
static void simple_parse_convert(struct device *dev,
@@ -149,19 +161,17 @@ static int simple_parse_node(struct simple_util_priv *priv,
dai = simple_props_to_dai_codec(dai_props, 0);
}
- ret = simple_parse_dai(dev, np, dlc, cpu);
+ ret = simple_parse_dai(priv, np, dlc, cpu);
if (ret)
- return ret;
+ goto end;
ret = simple_util_parse_clk(dev, np, dai, dlc);
if (ret)
- return ret;
+ goto end;
ret = simple_util_parse_tdm(np, dai);
- if (ret)
- return ret;
-
- return 0;
+end:
+ return simple_ret(priv, ret);
}
static int simple_link_init(struct simple_util_priv *priv,
@@ -183,7 +193,7 @@ static int simple_link_init(struct simple_util_priv *priv,
ret = simple_util_parse_daifmt(dev, node, codec,
prefix, &dai_link->dai_fmt);
if (ret < 0)
- return ret;
+ goto end;
graph_util_parse_link_direction(top, &playback_only, &capture_only);
graph_util_parse_link_direction(node, &playback_only, &capture_only);
@@ -213,7 +223,9 @@ static int simple_link_init(struct simple_util_priv *priv,
dai_link->init = simple_util_dai_init;
dai_link->ops = &simple_ops;
- return simple_util_set_dailink_name(dev, dai_link, name);
+ ret = simple_util_set_dailink_name(priv, dai_link, name);
+end:
+ return simple_ret(priv, ret);
}
static int simple_dai_link_of_dpcm(struct simple_util_priv *priv,
@@ -290,7 +302,7 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv,
out_put_node:
li->link++;
- return ret;
+ return simple_ret(priv, ret);
}
static int simple_dai_link_of(struct simple_util_priv *priv,
@@ -330,7 +342,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv,
if (ret < 0)
goto dai_link_of_err;
- ret = simple_parse_platform(plat, platforms);
+ ret = simple_parse_platform(priv, plat, platforms);
if (ret < 0)
goto dai_link_of_err;
@@ -345,7 +357,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv,
dai_link_of_err:
li->link++;
- return ret;
+ return simple_ret(priv, ret);
}
static int __simple_for_each_link(struct simple_util_priv *priv,
@@ -443,10 +455,10 @@ static int __simple_for_each_link(struct simple_util_priv *priv,
node = of_get_next_child(top, node);
} while (!is_top && node);
- error:
+error:
of_node_put(node);
- return ret;
+ return simple_ret(priv, ret);
}
static int simple_for_each_link(struct simple_util_priv *priv,
@@ -479,7 +491,7 @@ static int simple_for_each_link(struct simple_util_priv *priv,
break;
}
- return ret;
+ return simple_ret(priv, ret);
}
static void simple_depopulate_aux(void *data)
@@ -500,9 +512,11 @@ static int simple_populate_aux(struct simple_util_priv *priv)
ret = of_platform_populate(node, NULL, NULL, dev);
if (ret)
- return ret;
+ goto end;
- return devm_add_action_or_reset(dev, simple_depopulate_aux, priv);
+ ret = devm_add_action_or_reset(dev, simple_depopulate_aux, priv);
+end:
+ return simple_ret(priv, ret);
}
static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li)
@@ -512,15 +526,15 @@ static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li)
ret = simple_util_parse_widgets(card, PREFIX);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_parse_routing(card, PREFIX);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_parse_pin_switches(card, PREFIX);
if (ret < 0)
- return ret;
+ goto end;
/* Single/Muti DAI link(s) & New style of DT node */
memset(li, 0, sizeof(*li));
@@ -528,19 +542,19 @@ static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li)
simple_dai_link_of,
simple_dai_link_of_dpcm);
if (ret < 0)
- return ret;
+ goto end;
- ret = simple_util_parse_card_name(card, PREFIX);
+ ret = simple_util_parse_card_name(priv, PREFIX);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_populate_aux(priv);
if (ret < 0)
- return ret;
+ goto end;
ret = snd_soc_of_parse_aux_devs(card, PREFIX "aux-devs");
-
- return ret;
+end:
+ return simple_ret(priv, ret);
}
static int simple_count_noml(struct simple_util_priv *priv,
@@ -548,12 +562,10 @@ static int simple_count_noml(struct simple_util_priv *priv,
struct device_node *codec,
struct link_info *li, bool is_top)
{
- if (li->link >= SNDRV_MAX_LINKS) {
- struct device *dev = simple_priv_to_dev(priv);
+ int ret = -EINVAL;
- dev_err(dev, "too many links\n");
- return -EINVAL;
- }
+ if (li->link >= SNDRV_MAX_LINKS)
+ goto end;
/*
* DON'T REMOVE platforms
@@ -575,8 +587,9 @@ static int simple_count_noml(struct simple_util_priv *priv,
li->num[li->link].codecs = 1;
li->link += 1;
-
- return 0;
+ ret = 0;
+end:
+ return simple_ret(priv, ret);
}
static int simple_count_dpcm(struct simple_util_priv *priv,
@@ -584,12 +597,10 @@ static int simple_count_dpcm(struct simple_util_priv *priv,
struct device_node *codec,
struct link_info *li, bool is_top)
{
- if (li->link >= SNDRV_MAX_LINKS) {
- struct device *dev = simple_priv_to_dev(priv);
+ int ret = -EINVAL;
- dev_err(dev, "too many links\n");
- return -EINVAL;
- }
+ if (li->link >= SNDRV_MAX_LINKS)
+ goto end;
if (li->cpu) {
/*
@@ -606,8 +617,9 @@ static int simple_count_dpcm(struct simple_util_priv *priv,
li->link++; /* dummy-Codec */
}
-
- return 0;
+ ret = 0;
+end:
+ return simple_ret(priv, ret);
}
static int simple_get_dais_count(struct simple_util_priv *priv,
@@ -683,17 +695,15 @@ static int simple_soc_probe(struct snd_soc_card *card)
ret = simple_util_init_hp(card, &priv->hp_jack, PREFIX);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_init_mic(card, &priv->mic_jack, PREFIX);
if (ret < 0)
- return ret;
+ goto end;
ret = simple_util_init_aux_jacks(priv, PREFIX);
- if (ret < 0)
- return ret;
-
- return 0;
+end:
+ return simple_ret(priv, ret);
}
static int simple_probe(struct platform_device *pdev)
@@ -715,20 +725,22 @@ static int simple_probe(struct platform_device *pdev)
card->probe = simple_soc_probe;
card->driver_name = "simple-card";
+ ret = -ENOMEM;
struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL);
if (!li)
- return -ENOMEM;
+ goto end;
ret = simple_get_dais_count(priv, li);
if (ret < 0)
- return ret;
+ goto end;
+ ret = -EINVAL;
if (!li->link)
- return -EINVAL;
+ goto end;
ret = simple_util_init_priv(priv, li);
if (ret < 0)
- return ret;
+ goto end;
if (np && of_device_is_available(np)) {
@@ -795,8 +807,8 @@ static int simple_probe(struct platform_device *pdev)
return 0;
err:
simple_util_clean_reference(card);
-
- return ret;
+end:
+ return dev_err_probe(dev, ret, "parse error\n");
}
static const struct of_device_id simple_of_match[] = {
diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c
index 5430d25deaef..89b995987e2d 100644
--- a/sound/soc/generic/test-component.c
+++ b/sound/soc/generic/test-component.c
@@ -140,6 +140,15 @@ static int test_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0;
}
+static int test_dai_set_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int slot_width)
+{
+ dev_info(dai->dev, "set tdm slot: tx_mask=0x%08X, rx_mask=0x%08X, slots=%d, slot_width=%d\n",
+ tx_mask, rx_mask, slots, slot_width);
+ return 0;
+}
+
static int test_dai_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
{
mile_stone(dai);
@@ -203,6 +212,7 @@ static const u64 test_dai_formats =
static const struct snd_soc_dai_ops test_ops = {
.set_fmt = test_dai_set_fmt,
+ .set_tdm_slot = test_dai_set_tdm_slot,
.startup = test_dai_startup,
.shutdown = test_dai_shutdown,
.auto_selectable_formats = &test_dai_formats,
@@ -214,6 +224,7 @@ static const struct snd_soc_dai_ops test_verbose_ops = {
.set_pll = test_dai_set_pll,
.set_clkdiv = test_dai_set_clkdiv,
.set_fmt = test_dai_set_fmt,
+ .set_tdm_slot = test_dai_set_tdm_slot,
.mute_stream = test_dai_mute_stream,
.startup = test_dai_startup,
.shutdown = test_dai_shutdown,