[alsa-devel] [PATCH] ASoC: merge audio-graph-scu / simple-scu-card
Hi Mark
I'm posting these 2 series ASoC: merge audio-graph-scu into audio-graph ASoC: merge simple-scu-card into simple-card
This time, I merged these into this patch-set. Previous patch-set included "remove xx-suc-card" patch, too. But, I think postpone it to next version is more safety for us. So, I dropped it.
As you know, I and Tony discussed about DAI ID method. It is included to this patch-set, too
I post 3 series.
0*) for DAI ID fixup 1*) for merging audio-graph-scu to audio-graph 2*) for merging simple-card-scu to simple-card
Kuninori Morimoto (11): 01) ASoC: simple-card-utils: fixup asoc_simple_card_get_dai_id() ID method 11) ASoC: audio-graph-card: merge audio-graph-scu-card on Doc 12) ASoC: audio-graph-card: merge audio-graph-scu-card 13) ASoC: audio-graph-card: tidyup mclk-fs method 14) ASoC: audio-graph-card: tidyup convert_rate/channel method 15) ASoC: audio-graph-card: tidyup prefix for snd_soc_codec_conf 21) ASoC: simple-card: merge simple-scu-card on Doc 22) ASoC: simple-card: merge simple-scu-card 23) ASoC: simple-card: tidyup mclk-fs method 24) ASoC: simple-card: tidyup convert_rate/channel method 25) ASoC: simple-card: tidyup prefix for snd_soc_codec_conf
Documentation/devicetree/bindings/sound/audio-graph-card.txt | 205 ++++++++++++++++++++++++++++++++ Documentation/devicetree/bindings/sound/simple-card.txt | 137 +++++++++++++++++++++ sound/soc/generic/Kconfig | 2 + sound/soc/generic/audio-graph-card.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------- sound/soc/generic/simple-card-utils.c | 32 ++++- sound/soc/generic/simple-card.c | 342 +++++++++++++++++++++++++++++++++++++++++++--------- 6 files changed, 1005 insertions(+), 116 deletions(-)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
commit b6f3fc005a2c8 ("ASoC: simple-card-utils: fixup asoc_simple_card_get_dai_id() counting") fixuped getting DAI ID method. It will get DAI ID from OF graph "port", but, we want to consider about "endpoint", too. And, we also want to keep compatibility.
This patch fixup it as
if (driver has specified DAI ID) use it as DAI ID else if (OF graph endpoint has reg) use it as DAI ID else if (OF graph port has reg) use it as DAI ID else use endpoint count as DAI ID
Fixes: commit b6f3fc005a2c8 ("ASoC: simple-card-utils: fixup asoc_simple_card_get_dai_id() counting") Reported-by: Tony Lindgren tony@atomide.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Tested-by: Tony Lindgren tony@atomide.com --- sound/soc/generic/simple-card-utils.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 17d8aee..b807a47 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -269,22 +269,46 @@ EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
static int asoc_simple_card_get_dai_id(struct device_node *ep) { + struct device_node *node; + struct device_node *endpoint; struct of_endpoint info; + int i, id; int ret;
+ /* use driver specified DAI ID if exist */ ret = snd_soc_get_dai_id(ep); if (ret != -ENOTSUPP) return ret;
+ /* use endpoint/port reg if exist */ + ret = of_graph_parse_endpoint(ep, &info); + if (ret == 0) { + if (info.id) + return info.id; + if (info.port) + return info.port; + } + + node = of_graph_get_port_parent(ep); + /* * Non HDMI sound case, counting port/endpoint on its DT * is enough. Let's count it. */ - ret = of_graph_parse_endpoint(ep, &info); - if (ret) - return -ENXIO; + i = 0; + id = -1; + for_each_endpoint_of_node(node, endpoint) { + if (endpoint == ep) + id = i; + i++; + } + + of_node_put(node); + + if (id < 0) + return -ENODEV;
- return info.port; + return id; }
int asoc_simple_card_parse_graph_dai(struct device_node *ep,
Hi Mark
These are for audio-graph merging
Kuninori Morimoto (5): ASoC: audio-graph-card: merge audio-graph-scu-card on Doc ASoC: audio-graph-card: merge audio-graph-scu-card ASoC: audio-graph-card: tidyup mclk-fs method ASoC: audio-graph-card: tidyup convert_rate/channel method ASoC: audio-graph-card: tidyup prefix for snd_soc_codec_conf
.../devicetree/bindings/sound/audio-graph-card.txt | 205 +++++++++++ sound/soc/generic/Kconfig | 1 + sound/soc/generic/audio-graph-card.c | 403 ++++++++++++++++++--- 3 files changed, 551 insertions(+), 58 deletions(-)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
audio-graph-card and audio-graph-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card.
We couldn't use normal sound and DPCM sound in same sound card by audio-graph-card. This patch merges both feature into it on Documentation. Now we can use both feature on same driver.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- .../devicetree/bindings/sound/audio-graph-card.txt | 205 +++++++++++++++++++++ 1 file changed, 205 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card.txt b/Documentation/devicetree/bindings/sound/audio-graph-card.txt index 7e63e53..26968261 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-card.txt +++ b/Documentation/devicetree/bindings/sound/audio-graph-card.txt @@ -32,7 +32,9 @@ Required properties: Optional properties: - pa-gpios: GPIO used to control external amplifier.
+----------------------- Example: Single DAI case +-----------------------
sound_card { compatible = "audio-graph-card"; @@ -61,7 +63,9 @@ Example: Single DAI case }; };
+----------------------- Example: Multi DAI case +-----------------------
sound-card { compatible = "audio-graph-card"; @@ -130,3 +134,204 @@ Example: Multi DAI case }; };
+ +----------------------- +Example: Sampling Rate Conversion +----------------------- + + sound_card { + compatible = "audio-graph-card"; + + label = "sound-card"; + prefix = "codec"; + routing = "codec Playback", "DAI0 Playback", + "DAI0 Capture", "codec Capture"; + 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 CPU 1 Codec (Mixing) +----------------------- + + sound_card { + compatible = "audio-graph-card"; + + label = "sound-card"; + routing = "codec Playback", "DAI0 Playback", + "codec Playback", "DAI1 Playback", + "DAI0 Capture", "codec Capture"; + + dais = <&cpu_port>; + }; + + audio-codec { + ... + + audio-graph-card,prefix = "codec"; + audio-graph-card,convert-rate = <48000>; + port { + reg = <0>; + codec_endpoint0: endpoint@0 { + remote-endpoint = <&cpu_endpoint0>; + }; + codec_endpoint1: endpoint@1 { + remote-endpoint = <&cpu_endpoint1>; + }; + }; + }; + + dai-controller { + ... + cpu_port: port { + cpu_endpoint0: endpoint@0 { + remote-endpoint = <&codec_endpoint0>; + + dai-format = "left_j"; + ... + }; + cpu_endpoint1: endpoint@1 { + remote-endpoint = <&codec_endpoint1>; + + dai-format = "left_j"; + ... + }; + }; + }; + +----------------------- +Example: Multi DAI with DPCM +----------------------- + + CPU0 ------ ak4613 + CPU1 ------ HDMI + CPU2 ------ PCM3168A-p /* DPCM 1ch/2ch */ + CPU3 --/ /* DPCM 3ch/4ch */ + CPU4 --/ /* DPCM 5ch/6ch */ + CPU5 --/ /* DPCM 7ch/8ch */ + CPU6 ------ PCM3168A-c + + sound_card: sound { + compatible = "audio-graph-card"; + + label = "sound-card"; + + routing = "pcm3168a Playback", "DAI2 Playback", + "pcm3168a Playback", "DAI3 Playback", + "pcm3168a Playback", "DAI4 Playback", + "pcm3168a Playback", "DAI5 Playback"; + + dais = <&snd_port0 /* ak4613 */ + &snd_port1 /* HDMI0 */ + &snd_port2 /* pcm3168a playback */ + &snd_port3 /* pcm3168a capture */ + >; + }; + + ak4613: codec@10 { + ... + port { + ak4613_endpoint: endpoint { + remote-endpoint = <&rsnd_endpoint0>; + }; + }; + }; + + pcm3168a: audio-codec@44 { + ... + audio-graph-card,prefix = "pcm3168a"; + audio-graph-card,convert-channels = <8>; /* TDM Split */ + ports { + port@0 { + reg = <0>; + pcm3168a_endpoint_p1: endpoint@1 { + remote-endpoint = <&rsnd_endpoint2>; + ... + }; + pcm3168a_endpoint_p2: endpoint@2 { + remote-endpoint = <&rsnd_endpoint3>; + ... + }; + pcm3168a_endpoint_p3: endpoint@3 { + remote-endpoint = <&rsnd_endpoint4>; + ... + }; + pcm3168a_endpoint_p4: endpoint@4 { + remote-endpoint = <&rsnd_endpoint5>; + ... + }; + }; + port@1 { + reg = <1>; + pcm3168a_endpoint_c: endpoint { + remote-endpoint = <&rsnd_endpoint6>; + ... + }; + }; + }; + }; + + &sound { + ports { + snd_port0: port@0 { + rsnd_endpoint0: endpoint { + remote-endpoint = <&ak4613_endpoint>; + ... + }; + }; + snd_port1: port@1 { + rsnd_endpoint1: endpoint { + remote-endpoint = <&dw_hdmi0_snd_in>; + ... + }; + }; + snd_port2: port@2 { + #address-cells = <1>; + #size-cells = <0>; + rsnd_endpoint2: endpoint@2 { + remote-endpoint = <&pcm3168a_endpoint_p1>; + ... + }; + rsnd_endpoint3: endpoint@3 { + remote-endpoint = <&pcm3168a_endpoint_p2>; + ... + }; + rsnd_endpoint4: endpoint@4 { + remote-endpoint = <&pcm3168a_endpoint_p3>; + ... + }; + rsnd_endpoint5: endpoint@5 { + remote-endpoint = <&pcm3168a_endpoint_p4>; + ... + }; + }; + snd_port3: port@6 { + rsnd_endpoint6: endpoint { + remote-endpoint = <&pcm3168a_endpoint_c>; + ... + }; + }; + }; + };
The patch
ASoC: audio-graph-card: merge audio-graph-scu-card on Doc
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 91a531e48b20677c1f820f3bbd4237abd8144919 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 14 Dec 2018 11:32:06 +0900 Subject: [PATCH] ASoC: audio-graph-card: merge audio-graph-scu-card on Doc
audio-graph-card and audio-graph-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card.
We couldn't use normal sound and DPCM sound in same sound card by audio-graph-card. This patch merges both feature into it on Documentation. Now we can use both feature on same driver.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- .../bindings/sound/audio-graph-card.txt | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card.txt b/Documentation/devicetree/bindings/sound/audio-graph-card.txt index 7e63e53a901c..269682619a70 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-card.txt +++ b/Documentation/devicetree/bindings/sound/audio-graph-card.txt @@ -32,7 +32,9 @@ Required properties: Optional properties: - pa-gpios: GPIO used to control external amplifier.
+----------------------- Example: Single DAI case +-----------------------
sound_card { compatible = "audio-graph-card"; @@ -61,7 +63,9 @@ Example: Single DAI case }; };
+----------------------- Example: Multi DAI case +-----------------------
sound-card { compatible = "audio-graph-card"; @@ -130,3 +134,204 @@ Example: Multi DAI case }; };
+ +----------------------- +Example: Sampling Rate Conversion +----------------------- + + sound_card { + compatible = "audio-graph-card"; + + label = "sound-card"; + prefix = "codec"; + routing = "codec Playback", "DAI0 Playback", + "DAI0 Capture", "codec Capture"; + 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 CPU 1 Codec (Mixing) +----------------------- + + sound_card { + compatible = "audio-graph-card"; + + label = "sound-card"; + routing = "codec Playback", "DAI0 Playback", + "codec Playback", "DAI1 Playback", + "DAI0 Capture", "codec Capture"; + + dais = <&cpu_port>; + }; + + audio-codec { + ... + + audio-graph-card,prefix = "codec"; + audio-graph-card,convert-rate = <48000>; + port { + reg = <0>; + codec_endpoint0: endpoint@0 { + remote-endpoint = <&cpu_endpoint0>; + }; + codec_endpoint1: endpoint@1 { + remote-endpoint = <&cpu_endpoint1>; + }; + }; + }; + + dai-controller { + ... + cpu_port: port { + cpu_endpoint0: endpoint@0 { + remote-endpoint = <&codec_endpoint0>; + + dai-format = "left_j"; + ... + }; + cpu_endpoint1: endpoint@1 { + remote-endpoint = <&codec_endpoint1>; + + dai-format = "left_j"; + ... + }; + }; + }; + +----------------------- +Example: Multi DAI with DPCM +----------------------- + + CPU0 ------ ak4613 + CPU1 ------ HDMI + CPU2 ------ PCM3168A-p /* DPCM 1ch/2ch */ + CPU3 --/ /* DPCM 3ch/4ch */ + CPU4 --/ /* DPCM 5ch/6ch */ + CPU5 --/ /* DPCM 7ch/8ch */ + CPU6 ------ PCM3168A-c + + sound_card: sound { + compatible = "audio-graph-card"; + + label = "sound-card"; + + routing = "pcm3168a Playback", "DAI2 Playback", + "pcm3168a Playback", "DAI3 Playback", + "pcm3168a Playback", "DAI4 Playback", + "pcm3168a Playback", "DAI5 Playback"; + + dais = <&snd_port0 /* ak4613 */ + &snd_port1 /* HDMI0 */ + &snd_port2 /* pcm3168a playback */ + &snd_port3 /* pcm3168a capture */ + >; + }; + + ak4613: codec@10 { + ... + port { + ak4613_endpoint: endpoint { + remote-endpoint = <&rsnd_endpoint0>; + }; + }; + }; + + pcm3168a: audio-codec@44 { + ... + audio-graph-card,prefix = "pcm3168a"; + audio-graph-card,convert-channels = <8>; /* TDM Split */ + ports { + port@0 { + reg = <0>; + pcm3168a_endpoint_p1: endpoint@1 { + remote-endpoint = <&rsnd_endpoint2>; + ... + }; + pcm3168a_endpoint_p2: endpoint@2 { + remote-endpoint = <&rsnd_endpoint3>; + ... + }; + pcm3168a_endpoint_p3: endpoint@3 { + remote-endpoint = <&rsnd_endpoint4>; + ... + }; + pcm3168a_endpoint_p4: endpoint@4 { + remote-endpoint = <&rsnd_endpoint5>; + ... + }; + }; + port@1 { + reg = <1>; + pcm3168a_endpoint_c: endpoint { + remote-endpoint = <&rsnd_endpoint6>; + ... + }; + }; + }; + }; + + &sound { + ports { + snd_port0: port@0 { + rsnd_endpoint0: endpoint { + remote-endpoint = <&ak4613_endpoint>; + ... + }; + }; + snd_port1: port@1 { + rsnd_endpoint1: endpoint { + remote-endpoint = <&dw_hdmi0_snd_in>; + ... + }; + }; + snd_port2: port@2 { + #address-cells = <1>; + #size-cells = <0>; + rsnd_endpoint2: endpoint@2 { + remote-endpoint = <&pcm3168a_endpoint_p1>; + ... + }; + rsnd_endpoint3: endpoint@3 { + remote-endpoint = <&pcm3168a_endpoint_p2>; + ... + }; + rsnd_endpoint4: endpoint@4 { + remote-endpoint = <&pcm3168a_endpoint_p3>; + ... + }; + rsnd_endpoint5: endpoint@5 { + remote-endpoint = <&pcm3168a_endpoint_p4>; + ... + }; + }; + snd_port3: port@6 { + rsnd_endpoint6: endpoint { + remote-endpoint = <&pcm3168a_endpoint_c>; + ... + }; + }; + }; + };
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
audio-graph-card and audio-graph-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card.
We couldn't use normal sound and DPCM sound in same sound card by audio-graph-card. This patch merges both sound card into it. Now we can use both feature on same driver.
audio-grap-card is now supporting .compatible = "audio-graph-scu-card".
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Tested-by: Tony Lindgren tony@atomide.com --- sound/soc/generic/Kconfig | 1 + sound/soc/generic/audio-graph-card.c | 366 ++++++++++++++++++++++++++++++----- 2 files changed, 320 insertions(+), 47 deletions(-)
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index fa5aff9..53957824 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -22,6 +22,7 @@ config SND_AUDIO_GRAPH_CARD help This option enables generic simple sound card support with OF-graph DT bindings. + It also support DPCM of multi CPU single Codec ststem.
config SND_AUDIO_GRAPH_SCU_CARD tristate "ASoC Audio Graph SCU sound card support" diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 1da9532..8ec09bc 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -27,6 +27,8 @@ struct graph_card_data { struct asoc_simple_dai *codec_dai; struct snd_soc_dai_link_component codecs; /* single codec */ struct snd_soc_dai_link_component platform; + struct asoc_simple_card_data adata; + struct snd_soc_codec_conf *codec_conf; unsigned int mclk_fs; } *dai_props; unsigned int mclk_fs; @@ -34,6 +36,8 @@ struct graph_card_data { struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; + struct asoc_simple_card_data adata; + struct snd_soc_codec_conf *codec_conf; struct gpio_desc *pa_gpio; };
@@ -42,6 +46,8 @@ struct graph_card_data { #define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev) #define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i))
+#define PREFIX "audio-graph-card," + static int asoc_graph_card_outdrv_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -156,7 +162,140 @@ static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd) return 0; }
-static int asoc_graph_card_dai_link_of(struct device_node *cpu_port, +static int asoc_graph_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card); + struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num); + + asoc_simple_card_convert_fixup(&dai_props->adata, params); + + /* overwrite by top level adata if exist */ + asoc_simple_card_convert_fixup(&priv->adata, params); + + return 0; +} + +static int asoc_graph_card_dai_link_of_dpcm(struct device_node *cpu_ep, + struct device_node *codec_ep, + struct graph_card_data *priv, + int *dai_idx, int link_idx, + int *conf_idx, int is_cpu) +{ + struct device *dev = graph_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx); + struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx); + struct snd_soc_card *card = graph_priv_to_card(priv); + struct device_node *ep = is_cpu ? cpu_ep : codec_ep; + struct device_node *node = of_graph_get_port_parent(ep); + struct asoc_simple_dai *dai; + int ret; + + dev_dbg(dev, "link_of DPCM (for %s)\n", is_cpu ? "CPU" : "Codec"); + + if (is_cpu) { + struct snd_soc_dai_link_component *codecs; + + /* BE is dummy */ + codecs = dai_link->codecs; + codecs->of_node = NULL; + codecs->dai_name = "snd-soc-dummy-dai"; + codecs->name = "snd-soc-dummy"; + + /* FE settings */ + dai_link->dynamic = 1; + dai_link->dpcm_merged_format = 1; + + dai = + dai_props->cpu_dai = &priv->dais[(*dai_idx)++]; + + ret = asoc_simple_card_parse_graph_cpu(ep, dai_link); + if (ret) + return ret; + + ret = asoc_simple_card_parse_clk_cpu(dev, ep, dai_link, dai); + if (ret < 0) + return ret; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "fe.%s", + dai_link->cpu_dai_name); + if (ret < 0) + return ret; + + /* card->num_links includes Codec */ + asoc_simple_card_canonicalize_cpu(dai_link, + of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1); + } else { + struct snd_soc_codec_conf *cconf; + + /* FE is dummy */ + dai_link->cpu_of_node = NULL; + dai_link->cpu_dai_name = "snd-soc-dummy-dai"; + dai_link->cpu_name = "snd-soc-dummy"; + + /* BE settings */ + dai_link->no_pcm = 1; + dai_link->be_hw_params_fixup = asoc_graph_card_be_hw_params_fixup; + + dai = + dai_props->codec_dai = &priv->dais[(*dai_idx)++]; + + cconf = + dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++]; + + ret = asoc_simple_card_parse_graph_codec(ep, dai_link); + if (ret < 0) + return ret; + + ret = asoc_simple_card_parse_clk_codec(dev, ep, dai_link, dai); + if (ret < 0) + return ret; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "be.%s", + dai_link->codecs->dai_name); + if (ret < 0) + return ret; + + /* check "prefix" from top node */ + snd_soc_of_parse_audio_prefix(card, cconf, + dai_link->codecs->of_node, + "prefix"); + /* check "prefix" from each node if top doesn't have */ + if (!cconf->of_node) + snd_soc_of_parse_node_prefix(node, cconf, + dai_link->codecs->of_node, + PREFIX "prefix"); + } + + asoc_simple_card_parse_convert(dev, node, PREFIX, &dai_props->adata); + + ret = asoc_simple_card_of_parse_tdm(ep, dai); + if (ret) + return ret; + + ret = asoc_simple_card_canonicalize_dailink(dai_link); + if (ret < 0) + return ret; + + of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs); + + ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, + NULL, &dai_link->dai_fmt); + if (ret < 0) + return ret; + + dai_link->dpcm_playback = 1; + dai_link->dpcm_capture = 1; + dai_link->ops = &asoc_graph_card_ops; + dai_link->init = asoc_graph_card_dai_init; + + return 0; +} + +static int asoc_graph_card_dai_link_of(struct device_node *cpu_ep, + struct device_node *codec_ep, struct graph_card_data *priv, int *dai_idx, int link_idx) { @@ -165,10 +304,10 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port, struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx); struct asoc_simple_dai *cpu_dai; struct asoc_simple_dai *codec_dai; - struct device_node *cpu_ep = of_get_next_child(cpu_port, NULL); - struct device_node *codec_ep = of_graph_get_remote_endpoint(cpu_ep); int ret;
+ dev_dbg(dev, "link_of\n"); + cpu_dai = dai_props->cpu_dai = &priv->dais[(*dai_idx)++]; codec_dai = @@ -177,45 +316,45 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port, ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, NULL, &dai_link->dai_fmt); if (ret < 0) - goto dai_link_of_err; + return ret;
of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs); of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs);
ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link); if (ret < 0) - goto dai_link_of_err; + return ret;
ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link); if (ret < 0) - goto dai_link_of_err; + return ret;
ret = asoc_simple_card_of_parse_tdm(cpu_ep, cpu_dai); if (ret < 0) - goto dai_link_of_err; + return ret;
ret = asoc_simple_card_of_parse_tdm(codec_ep, codec_dai); if (ret < 0) - goto dai_link_of_err; + return ret;
ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai); if (ret < 0) - goto dai_link_of_err; + return ret;
ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai); if (ret < 0) - goto dai_link_of_err; + return ret;
ret = asoc_simple_card_canonicalize_dailink(dai_link); if (ret < 0) - goto dai_link_of_err; + return ret;
ret = asoc_simple_card_set_dailink_name(dev, dai_link, "%s-%s", dai_link->cpu_dai_name, dai_link->codecs->dai_name); if (ret < 0) - goto dai_link_of_err; + return ret;
dai_link->ops = &asoc_graph_card_ops; dai_link->init = asoc_graph_card_dai_init; @@ -223,11 +362,7 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port, asoc_simple_card_canonicalize_cpu(dai_link, of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
-dai_link_of_err: - of_node_put(cpu_ep); - of_node_put(codec_ep); - - return ret; + return 0; }
static int asoc_graph_card_parse_of(struct graph_card_data *priv) @@ -236,8 +371,14 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) struct device *dev = graph_priv_to_dev(priv); struct snd_soc_card *card = graph_priv_to_card(priv); struct device_node *node = dev->of_node; + struct device_node *cpu_port; + struct device_node *cpu_ep = NULL; + struct device_node *codec_ep = NULL; + struct device_node *codec_port = NULL; + struct device_node *codec_port_old = NULL; int rc, ret; - int link_idx, dai_idx; + int link_idx, dai_idx, conf_idx; + int cpu;
ret = asoc_simple_card_of_parse_widgets(card, NULL); if (ret < 0) @@ -247,35 +388,159 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) if (ret < 0) return ret;
+ asoc_simple_card_parse_convert(dev, node, NULL, &priv->adata); + /* Factor to mclk, used in hw_params() */ of_property_read_u32(node, "mclk-fs", &priv->mclk_fs);
- link_idx = 0; - dai_idx = 0; - of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { - ret = asoc_graph_card_dai_link_of(it.node, priv, - &dai_idx, link_idx++); - if (ret < 0) { - of_node_put(it.node); - - return ret; + link_idx = 0; + dai_idx = 0; + conf_idx = 0; + codec_port_old = NULL; + for (cpu = 1; cpu >= 0; cpu--) { + /* + * Detect all CPU first, and Detect all Codec 2nd. + * + * In Normal sound case, all DAIs are detected + * as "CPU-Codec". + * + * In DPCM sound case, + * all CPUs are detected as "CPU-dummy", and + * all Codecs are detected as "dummy-Codec". + * To avoid random sub-device numbering, + * detect "dummy-Codec" in last; + */ + of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { + cpu_port = it.node; + cpu_ep = NULL; + while (1) { + cpu_ep = of_get_next_child(cpu_port, cpu_ep); + if (!cpu_ep) + break; + + codec_ep = of_graph_get_remote_endpoint(cpu_ep); + codec_port = of_get_parent(codec_ep); + + of_node_put(codec_ep); + of_node_put(codec_port); + + dev_dbg(dev, "%pOFf <-> %pOFf\n", cpu_ep, codec_ep); + + if (of_get_child_count(codec_port) > 1) { + /* + * for DPCM sound + */ + if (!cpu) { + if (codec_port_old == codec_port) + continue; + codec_port_old = codec_port; + } + ret = asoc_graph_card_dai_link_of_dpcm( + cpu_ep, codec_ep, priv, + &dai_idx, link_idx++, + &conf_idx, cpu); + } else if (cpu) { + /* + * for Normal sound + */ + ret = asoc_graph_card_dai_link_of( + cpu_ep, codec_ep, priv, + &dai_idx, link_idx++); + } + if (ret < 0) + return ret; + } } }
return asoc_simple_card_parse_card_name(card, NULL); }
-static int asoc_graph_get_dais_count(struct device *dev) +static void asoc_graph_get_dais_count(struct device *dev, + int *link_num, + int *dais_num, + int *ccnf_num) { struct of_phandle_iterator it; struct device_node *node = dev->of_node; - int count = 0; + struct device_node *cpu_port; + struct device_node *cpu_ep; + struct device_node *codec_ep; + struct device_node *codec_port; + struct device_node *codec_port_old; + struct device_node *codec_port_old2; int rc;
- of_for_each_phandle(&it, rc, node, "dais", NULL, 0) - count++; - - return count; + /* + * link_num : number of links. + * CPU-Codec / CPU-dummy / dummy-Codec + * dais_num : number of DAIs + * ccnf_num : number of codec_conf + * same number for "dummy-Codec" + * + * ex1) + * CPU0 --- Codec0 link : 5 + * CPU1 --- Codec1 dais : 7 + * CPU2 -/ ccnf : 1 + * CPU3 --- Codec2 + * + * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec + * => 7 DAIs = 4xCPU + 3xCodec + * => 1 ccnf = 1xdummy-Codec + * + * ex2) + * CPU0 --- Codec0 link : 5 + * CPU1 --- Codec1 dais : 6 + * CPU2 -/ ccnf : 1 + * CPU3 -/ + * + * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec + * => 6 DAIs = 4xCPU + 2xCodec + * => 1 ccnf = 1xdummy-Codec + * + * ex3) + * CPU0 --- Codec0 link : 6 + * CPU1 -/ dais : 6 + * CPU2 --- Codec1 ccnf : 2 + * CPU3 -/ + * + * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec + * => 6 DAIs = 4xCPU + 2xCodec + * => 2 ccnf = 2xdummy-Codec + */ + codec_port_old = NULL; + codec_port_old2 = NULL; + of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { + cpu_port = it.node; + cpu_ep = NULL; + while (1) { + cpu_ep = of_get_next_child(cpu_port, cpu_ep); + if (!cpu_ep) + break; + + codec_ep = of_graph_get_remote_endpoint(cpu_ep); + codec_port = of_get_parent(codec_ep); + + of_node_put(codec_ep); + of_node_put(codec_port); + + (*link_num)++; + (*dais_num)++; + + if (codec_port_old == codec_port) { + if (codec_port_old2 != codec_port_old) { + (*link_num)++; + (*ccnf_num)++; + } + + codec_port_old2 = codec_port_old; + continue; + } + + (*dais_num)++; + codec_port_old = codec_port; + } + } }
static int asoc_graph_soc_card_probe(struct snd_soc_card *card) @@ -302,20 +567,23 @@ static int asoc_graph_card_probe(struct platform_device *pdev) struct asoc_simple_dai *dais; struct device *dev = &pdev->dev; struct snd_soc_card *card; - int num, ret, i; + struct snd_soc_codec_conf *cconf; + int lnum = 0, dnum = 0, cnum = 0; + int ret, i;
/* Allocate the private data and the DAI link array */ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
- num = asoc_graph_get_dais_count(dev); - if (num == 0) + asoc_graph_get_dais_count(dev, &lnum, &dnum, &cnum); + if (!lnum || !dnum) return -EINVAL;
- dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); - dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); - dais = devm_kcalloc(dev, num * 2, sizeof(*dais), GFP_KERNEL); + dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL); + dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL); + dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL); + cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL); if (!dai_props || !dai_link || !dais) return -ENOMEM;
@@ -325,7 +593,7 @@ static int asoc_graph_card_probe(struct platform_device *pdev) * see * soc-core.c :: snd_soc_init_multicodec() */ - for (i = 0; i < num; i++) { + for (i = 0; i < lnum; i++) { dai_link[i].codecs = &dai_props[i].codecs; dai_link[i].num_codecs = 1; dai_link[i].platform = &dai_props[i].platform; @@ -341,16 +609,19 @@ static int asoc_graph_card_probe(struct platform_device *pdev) priv->dai_props = dai_props; priv->dai_link = dai_link; priv->dais = dais; + priv->codec_conf = cconf;
/* Init snd_soc_card */ card = graph_priv_to_card(priv); - card->owner = THIS_MODULE; - card->dev = dev; - card->dai_link = dai_link; - card->num_links = num; - card->dapm_widgets = asoc_graph_card_dapm_widgets; - card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets); - card->probe = asoc_graph_soc_card_probe; + card->owner = THIS_MODULE; + card->dev = dev; + card->dai_link = dai_link; + card->num_links = lnum; + card->dapm_widgets = asoc_graph_card_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets); + card->probe = asoc_graph_soc_card_probe; + card->codec_conf = cconf; + card->num_configs = cnum;
ret = asoc_graph_card_parse_of(priv); if (ret < 0) { @@ -381,6 +652,7 @@ static int asoc_graph_card_remove(struct platform_device *pdev)
static const struct of_device_id asoc_graph_of_match[] = { { .compatible = "audio-graph-card", }, + { .compatible = "audio-graph-scu-card", }, {}, }; MODULE_DEVICE_TABLE(of, asoc_graph_of_match);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current audio-graph-card is handling "mclk-fs" by many way. But, it is not useful and readable. We want to do is that allow having mclk-fs everywere. This patch support it. It will be overwrote if lower node has it.
sound { mclk-fs = <xxx>; // initial };
codec { ports { mclk-fs = <xxx>; // overwrite port { mclk-fs = <xxx>; // overwrite endpoint { mclk-fs = <xxx>; // overwrite }; }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card.c | 52 ++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 17 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 8ec09bc..7e32380 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -31,7 +31,6 @@ struct graph_card_data { struct snd_soc_codec_conf *codec_conf; unsigned int mclk_fs; } *dai_props; - unsigned int mclk_fs; struct asoc_simple_jack hp_jack; struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; @@ -115,9 +114,7 @@ static int asoc_graph_card_hw_params(struct snd_pcm_substream *substream, unsigned int mclk, mclk_fs = 0; int ret = 0;
- if (priv->mclk_fs) - mclk_fs = priv->mclk_fs; - else if (dai_props->mclk_fs) + if (dai_props->mclk_fs) mclk_fs = dai_props->mclk_fs;
if (mclk_fs) { @@ -176,7 +173,8 @@ static int asoc_graph_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; }
-static int asoc_graph_card_dai_link_of_dpcm(struct device_node *cpu_ep, +static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top, + struct device_node *cpu_ep, struct device_node *codec_ep, struct graph_card_data *priv, int *dai_idx, int link_idx, @@ -187,12 +185,21 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *cpu_ep, struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx); struct snd_soc_card *card = graph_priv_to_card(priv); struct device_node *ep = is_cpu ? cpu_ep : codec_ep; + struct device_node *port = of_get_parent(ep); + struct device_node *ports = of_get_parent(port); struct device_node *node = of_graph_get_port_parent(ep); struct asoc_simple_dai *dai; int ret;
dev_dbg(dev, "link_of DPCM (for %s)\n", is_cpu ? "CPU" : "Codec");
+ of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ports, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(port, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs); + of_node_put(ports); + of_node_put(port); + if (is_cpu) { struct snd_soc_dai_link_component *codecs;
@@ -279,8 +286,6 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *cpu_ep, if (ret < 0) return ret;
- of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs); - ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, NULL, &dai_link->dai_fmt); if (ret < 0) @@ -294,7 +299,8 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *cpu_ep, return 0; }
-static int asoc_graph_card_dai_link_of(struct device_node *cpu_ep, +static int asoc_graph_card_dai_link_of(struct device_node *top, + struct device_node *cpu_ep, struct device_node *codec_ep, struct graph_card_data *priv, int *dai_idx, int link_idx) @@ -302,6 +308,10 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_ep, struct device *dev = graph_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx); struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx); + struct device_node *cpu_port = of_get_parent(cpu_ep); + struct device_node *codec_port = of_get_parent(codec_ep); + struct device_node *cpu_ports = of_get_parent(cpu_port); + struct device_node *codec_ports = of_get_parent(codec_port); struct asoc_simple_dai *cpu_dai; struct asoc_simple_dai *codec_dai; int ret; @@ -313,14 +323,24 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_ep, codec_dai = dai_props->codec_dai = &priv->dais[(*dai_idx)++];
+ /* Factor to mclk, used in hw_params() */ + of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(cpu_ports, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(codec_ports, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(cpu_port, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(codec_port, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs); + of_node_put(cpu_port); + of_node_put(cpu_ports); + of_node_put(codec_port); + of_node_put(codec_ports); + ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, NULL, &dai_link->dai_fmt); if (ret < 0) return ret;
- of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs); - ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link); if (ret < 0) return ret; @@ -370,7 +390,8 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) struct of_phandle_iterator it; struct device *dev = graph_priv_to_dev(priv); struct snd_soc_card *card = graph_priv_to_card(priv); - struct device_node *node = dev->of_node; + struct device_node *top = dev->of_node; + struct device_node *node = top; struct device_node *cpu_port; struct device_node *cpu_ep = NULL; struct device_node *codec_ep = NULL; @@ -390,9 +411,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
asoc_simple_card_parse_convert(dev, node, NULL, &priv->adata);
- /* Factor to mclk, used in hw_params() */ - of_property_read_u32(node, "mclk-fs", &priv->mclk_fs); - link_idx = 0; dai_idx = 0; conf_idx = 0; @@ -436,7 +454,7 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) codec_port_old = codec_port; } ret = asoc_graph_card_dai_link_of_dpcm( - cpu_ep, codec_ep, priv, + top, cpu_ep, codec_ep, priv, &dai_idx, link_idx++, &conf_idx, cpu); } else if (cpu) { @@ -444,7 +462,7 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) * for Normal sound */ ret = asoc_graph_card_dai_link_of( - cpu_ep, codec_ep, priv, + top, cpu_ep, codec_ep, priv, &dai_idx, link_idx++); } if (ret < 0)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current audio-graph-card is handling "convert_rate/channel" by many ways. But, it is not useful and readable. We want to do is that allow having it everywere. This patch support it. It will be overwrote if lower node has it.
sound { convert-channels = <xxx>; // initial };
codec { audio-graph-card,convert-channels = <xxx>; // overwrite ports { convert_channels = <xxx>; // overwrite port { convert_channels = <xxx>; // overwrite endpoint { convert_channels = <xxx>; // overwrite }; }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 7e32380..368b8ae 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -35,7 +35,6 @@ struct graph_card_data { struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; - struct asoc_simple_card_data adata; struct snd_soc_codec_conf *codec_conf; struct gpio_desc *pa_gpio; }; @@ -167,9 +166,6 @@ static int asoc_graph_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
asoc_simple_card_convert_fixup(&dai_props->adata, params);
- /* overwrite by top level adata if exist */ - asoc_simple_card_convert_fixup(&priv->adata, params); - return 0; }
@@ -197,6 +193,13 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top, of_property_read_u32(ports, "mclk-fs", &dai_props->mclk_fs); of_property_read_u32(port, "mclk-fs", &dai_props->mclk_fs); of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs); + + asoc_simple_card_parse_convert(dev, top, NULL, &dai_props->adata); + asoc_simple_card_parse_convert(dev, node, PREFIX, &dai_props->adata); + asoc_simple_card_parse_convert(dev, ports, NULL, &dai_props->adata); + asoc_simple_card_parse_convert(dev, port, NULL, &dai_props->adata); + asoc_simple_card_parse_convert(dev, ep, NULL, &dai_props->adata); + of_node_put(ports); of_node_put(port);
@@ -276,8 +279,6 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top, PREFIX "prefix"); }
- asoc_simple_card_parse_convert(dev, node, PREFIX, &dai_props->adata); - ret = asoc_simple_card_of_parse_tdm(ep, dai); if (ret) return ret; @@ -409,8 +410,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) if (ret < 0) return ret;
- asoc_simple_card_parse_convert(dev, node, NULL, &priv->adata); - link_idx = 0; dai_idx = 0; conf_idx = 0;
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current audio-graph-card is handling "prefix" by many ways. But, it is not useful and readable. We want to do is that allow having it everywere. This patch supports it. It will be overwrote if lower node has it.
sound { prefix = "xxx"; // initial };
codec { audio-graph-card,prefix = "xxx"; // overwrite ports { prefix = "xxx"; // overwrite port { prefix = "xxx"; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 368b8ae..0d61445 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -179,12 +179,12 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top, struct device *dev = graph_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx); struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx); - struct snd_soc_card *card = graph_priv_to_card(priv); struct device_node *ep = is_cpu ? cpu_ep : codec_ep; struct device_node *port = of_get_parent(ep); struct device_node *ports = of_get_parent(port); struct device_node *node = of_graph_get_port_parent(ep); struct asoc_simple_dai *dai; + struct snd_soc_dai_link_component *codecs = dai_link->codecs; int ret;
dev_dbg(dev, "link_of DPCM (for %s)\n", is_cpu ? "CPU" : "Codec"); @@ -204,10 +204,8 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top, of_node_put(port);
if (is_cpu) { - struct snd_soc_dai_link_component *codecs;
/* BE is dummy */ - codecs = dai_link->codecs; codecs->of_node = NULL; codecs->dai_name = "snd-soc-dummy-dai"; codecs->name = "snd-soc-dummy"; @@ -264,19 +262,19 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top,
ret = asoc_simple_card_set_dailink_name(dev, dai_link, "be.%s", - dai_link->codecs->dai_name); + codecs->dai_name); if (ret < 0) return ret;
/* check "prefix" from top node */ - snd_soc_of_parse_audio_prefix(card, cconf, - dai_link->codecs->of_node, + snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, "prefix"); - /* check "prefix" from each node if top doesn't have */ - if (!cconf->of_node) - snd_soc_of_parse_node_prefix(node, cconf, - dai_link->codecs->of_node, - PREFIX "prefix"); + snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node, + PREFIX "prefix"); + snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, + "prefix"); + snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node, + "prefix"); }
ret = asoc_simple_card_of_parse_tdm(ep, dai);
The patch
ASoC: audio-graph-card: tidyup prefix for snd_soc_codec_conf
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 66164a4da30dd295a1b60568c02bee37cfd9895a Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 14 Dec 2018 11:32:43 +0900 Subject: [PATCH] ASoC: audio-graph-card: tidyup prefix for snd_soc_codec_conf
Current audio-graph-card is handling "prefix" by many ways. But, it is not useful and readable. We want to do is that allow having it everywere. This patch supports it. It will be overwrote if lower node has it.
sound { prefix = "xxx"; // initial };
codec { audio-graph-card,prefix = "xxx"; // overwrite ports { prefix = "xxx"; // overwrite port { prefix = "xxx"; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/generic/audio-graph-card.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 368b8ae463af..0d6144560a1e 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -179,12 +179,12 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top, struct device *dev = graph_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx); struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx); - struct snd_soc_card *card = graph_priv_to_card(priv); struct device_node *ep = is_cpu ? cpu_ep : codec_ep; struct device_node *port = of_get_parent(ep); struct device_node *ports = of_get_parent(port); struct device_node *node = of_graph_get_port_parent(ep); struct asoc_simple_dai *dai; + struct snd_soc_dai_link_component *codecs = dai_link->codecs; int ret;
dev_dbg(dev, "link_of DPCM (for %s)\n", is_cpu ? "CPU" : "Codec"); @@ -204,10 +204,8 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top, of_node_put(port);
if (is_cpu) { - struct snd_soc_dai_link_component *codecs;
/* BE is dummy */ - codecs = dai_link->codecs; codecs->of_node = NULL; codecs->dai_name = "snd-soc-dummy-dai"; codecs->name = "snd-soc-dummy"; @@ -264,19 +262,19 @@ static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top,
ret = asoc_simple_card_set_dailink_name(dev, dai_link, "be.%s", - dai_link->codecs->dai_name); + codecs->dai_name); if (ret < 0) return ret;
/* check "prefix" from top node */ - snd_soc_of_parse_audio_prefix(card, cconf, - dai_link->codecs->of_node, + snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, "prefix"); - /* check "prefix" from each node if top doesn't have */ - if (!cconf->of_node) - snd_soc_of_parse_node_prefix(node, cconf, - dai_link->codecs->of_node, - PREFIX "prefix"); + snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node, + PREFIX "prefix"); + snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, + "prefix"); + snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node, + "prefix"); }
ret = asoc_simple_card_of_parse_tdm(ep, dai);
Hi Mark
These are for simple-card merging
Kuninori Morimoto (5): ASoC: simple-card: merge simple-scu-card on Doc ASoC: simple-card: merge simple-scu-card ASoC: simple-card: tidyup mclk-fs method ASoC: simple-card: tidyup convert_rate/channel method ASoC: simple-card: tidyup prefix for snd_soc_codec_conf
.../devicetree/bindings/sound/simple-card.txt | 137 +++++++++ sound/soc/generic/Kconfig | 1 + sound/soc/generic/simple-card.c | 342 +++++++++++++++++---- 3 files changed, 426 insertions(+), 54 deletions(-)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
simple-card and simple-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card.
We couldn't use normal sound and DPCM sound in same time by one sound card. This patch merges both sound card into simple-card. Now we can use both feature on same driver.
simple-card is now supporting .compatible = "simple-scu-audio-card".
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- .../devicetree/bindings/sound/simple-card.txt | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index a4c72d0..4629c8f 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -95,7 +95,9 @@ Optional CPU/CODEC subnodes properties: initialization. It is useful for some aCPUs with fixed clocks.
+------------------------------------------- Example 1 - single DAI link: +-------------------------------------------
sound { compatible = "simple-audio-card"; @@ -138,7 +140,9 @@ sh_fsi2: sh_fsi2@ec230000 { interrupts = <0 146 0x4>; };
+------------------------------------------- Example 2 - many DAI links: +-------------------------------------------
sound { compatible = "simple-audio-card"; @@ -176,8 +180,10 @@ sound { }; };
+------------------------------------------- Example 3 - route audio from IMX6 SSI2 through TLV320DAC3100 codec through TPA6130A2 amplifier to headphones: +-------------------------------------------
&i2c0 { codec: tlv320dac3100@18 { @@ -210,3 +216,134 @@ sound { clocks = ... }; }; + +------------------------------------------- +Example 4. Sampling Rate Conversion +------------------------------------------- + +sound { + compatible = "simple-audio-card"; + + simple-audio-card,name = "rsnd-ak4643"; + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&sndcodec>; + simple-audio-card,frame-master = <&sndcodec>; + + simple-audio-card,convert-rate = <48000>; + + simple-audio-card,prefix = "ak4642"; + simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback", + "DAI0 Capture", "ak4642 Capture"; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&ak4643>; + system-clock-frequency = <11289600>; + }; +}; + +------------------------------------------- +Example 5. 2 CPU 1 Codec (Mixing) +------------------------------------------- +sound { + compatible = "simple-audio-card"; + + simple-audio-card,name = "rsnd-ak4643"; + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&dpcmcpu>; + simple-audio-card,frame-master = <&dpcmcpu>; + + simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback", + "ak4642 Playback", "DAI1 Playback"; + + dpcmcpu: cpu@0 { + sound-dai = <&rcar_sound 0>; + }; + + cpu@1 { + sound-dai = <&rcar_sound 1>; + }; + + codec { + prefix = "ak4642"; + sound-dai = <&ak4643>; + clocks = <&audio_clock>; + }; +}; + +------------------------------------------- +Example 6 - many DAI links with DPCM: +------------------------------------------- + +CPU0 ------ ak4613 +CPU1 ------ PCM3168A-p /* DPCM 1ch/2ch */ +CPU2 --/ /* DPCM 3ch/4ch */ +CPU3 --/ /* DPCM 5ch/6ch */ +CPU4 --/ /* DPCM 7ch/8ch */ +CPU5 ------ PCM3168A-c + +sound { + compatible = "simple-audio-card"; + + simple-audio-card,routing = + "pcm3168a Playback", "DAI1 Playback", + "pcm3168a Playback", "DAI2 Playback", + "pcm3168a Playback", "DAI3 Playback", + "pcm3168a Playback", "DAI4 Playback"; + + simple-audio-card,dai-link@0 { + format = "left_j"; + bitclock-master = <&sndcpu0>; + frame-master = <&sndcpu0>; + + sndcpu0: cpu { + sound-dai = <&rcar_sound 0>; + }; + codec { + sound-dai = <&ak4613>; + }; + }; + simple-audio-card,dai-link@1 { + format = "i2s"; + bitclock-master = <&sndcpu1>; + frame-master = <&sndcpu1>; + + convert-channels = <8>; /* TDM Split */ + + sndcpu1: cpu@0 { + sound-dai = <&rcar_sound 1>; + }; + cpu@1 { + sound-dai = <&rcar_sound 2>; + }; + cpu@2 { + sound-dai = <&rcar_sound 3>; + }; + cpu@3 { + sound-dai = <&rcar_sound 4>; + }; + codec { + mclk-fs = <512>; + prefix = "pcm3168a"; + dai-tdm-slot-num = <8>; + sound-dai = <&pcm3168a 0>; + }; + }; + simple-audio-card,dai-link@2 { + format = "i2s"; + bitclock-master = <&sndcpu2>; + frame-master = <&sndcpu2>; + + sndcpu2: cpu { + sound-dai = <&rcar_sound 5>; + }; + codec { + mclk-fs = <512>; + prefix = "pcm3168a"; + sound-dai = <&pcm3168a 1>; + }; + }; +};
The patch
ASoC: simple-card: merge simple-scu-card on Doc
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From c4e8ebb9f2624da8302b6683ecb5ead7108ccb79 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 14 Dec 2018 11:35:05 +0900 Subject: [PATCH] ASoC: simple-card: merge simple-scu-card on Doc
simple-card and simple-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card.
We couldn't use normal sound and DPCM sound in same time by one sound card. This patch merges both sound card into simple-card. Now we can use both feature on same driver.
simple-card is now supporting .compatible = "simple-scu-audio-card".
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- .../devicetree/bindings/sound/simple-card.txt | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index a4c72d09cd45..4629c8f8a6b6 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -95,7 +95,9 @@ Optional CPU/CODEC subnodes properties: initialization. It is useful for some aCPUs with fixed clocks.
+------------------------------------------- Example 1 - single DAI link: +-------------------------------------------
sound { compatible = "simple-audio-card"; @@ -138,7 +140,9 @@ sh_fsi2: sh_fsi2@ec230000 { interrupts = <0 146 0x4>; };
+------------------------------------------- Example 2 - many DAI links: +-------------------------------------------
sound { compatible = "simple-audio-card"; @@ -176,8 +180,10 @@ sound { }; };
+------------------------------------------- Example 3 - route audio from IMX6 SSI2 through TLV320DAC3100 codec through TPA6130A2 amplifier to headphones: +-------------------------------------------
&i2c0 { codec: tlv320dac3100@18 { @@ -210,3 +216,134 @@ sound { clocks = ... }; }; + +------------------------------------------- +Example 4. Sampling Rate Conversion +------------------------------------------- + +sound { + compatible = "simple-audio-card"; + + simple-audio-card,name = "rsnd-ak4643"; + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&sndcodec>; + simple-audio-card,frame-master = <&sndcodec>; + + simple-audio-card,convert-rate = <48000>; + + simple-audio-card,prefix = "ak4642"; + simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback", + "DAI0 Capture", "ak4642 Capture"; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&ak4643>; + system-clock-frequency = <11289600>; + }; +}; + +------------------------------------------- +Example 5. 2 CPU 1 Codec (Mixing) +------------------------------------------- +sound { + compatible = "simple-audio-card"; + + simple-audio-card,name = "rsnd-ak4643"; + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&dpcmcpu>; + simple-audio-card,frame-master = <&dpcmcpu>; + + simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback", + "ak4642 Playback", "DAI1 Playback"; + + dpcmcpu: cpu@0 { + sound-dai = <&rcar_sound 0>; + }; + + cpu@1 { + sound-dai = <&rcar_sound 1>; + }; + + codec { + prefix = "ak4642"; + sound-dai = <&ak4643>; + clocks = <&audio_clock>; + }; +}; + +------------------------------------------- +Example 6 - many DAI links with DPCM: +------------------------------------------- + +CPU0 ------ ak4613 +CPU1 ------ PCM3168A-p /* DPCM 1ch/2ch */ +CPU2 --/ /* DPCM 3ch/4ch */ +CPU3 --/ /* DPCM 5ch/6ch */ +CPU4 --/ /* DPCM 7ch/8ch */ +CPU5 ------ PCM3168A-c + +sound { + compatible = "simple-audio-card"; + + simple-audio-card,routing = + "pcm3168a Playback", "DAI1 Playback", + "pcm3168a Playback", "DAI2 Playback", + "pcm3168a Playback", "DAI3 Playback", + "pcm3168a Playback", "DAI4 Playback"; + + simple-audio-card,dai-link@0 { + format = "left_j"; + bitclock-master = <&sndcpu0>; + frame-master = <&sndcpu0>; + + sndcpu0: cpu { + sound-dai = <&rcar_sound 0>; + }; + codec { + sound-dai = <&ak4613>; + }; + }; + simple-audio-card,dai-link@1 { + format = "i2s"; + bitclock-master = <&sndcpu1>; + frame-master = <&sndcpu1>; + + convert-channels = <8>; /* TDM Split */ + + sndcpu1: cpu@0 { + sound-dai = <&rcar_sound 1>; + }; + cpu@1 { + sound-dai = <&rcar_sound 2>; + }; + cpu@2 { + sound-dai = <&rcar_sound 3>; + }; + cpu@3 { + sound-dai = <&rcar_sound 4>; + }; + codec { + mclk-fs = <512>; + prefix = "pcm3168a"; + dai-tdm-slot-num = <8>; + sound-dai = <&pcm3168a 0>; + }; + }; + simple-audio-card,dai-link@2 { + format = "i2s"; + bitclock-master = <&sndcpu2>; + frame-master = <&sndcpu2>; + + sndcpu2: cpu { + sound-dai = <&rcar_sound 5>; + }; + codec { + mclk-fs = <512>; + prefix = "pcm3168a"; + sound-dai = <&pcm3168a 1>; + }; + }; +};
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
simple-card and simple-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card.
We couldn't use normal sound and DPCM sound in same time by one sound card. This patch merges both sound card into simple-card. Now we can use both feature on same driver.
simple-card is now supporting .compatible = "simple-scu-audio-card".
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/Kconfig | 1 + sound/soc/generic/simple-card.c | 329 ++++++++++++++++++++++++++++++++++------ 2 files changed, 284 insertions(+), 46 deletions(-)
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index 53957824..92c2cf0 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -6,6 +6,7 @@ config SND_SIMPLE_CARD select SND_SIMPLE_CARD_UTILS help This option enables generic simple sound card support + It also support DPCM of multi CPU single Codec ststem.
config SND_SIMPLE_SCU_CARD tristate "ASoC Simple SCU sound card support" diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 93d6816..c93f2e7 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -22,6 +22,8 @@ struct simple_card_data { struct asoc_simple_dai *codec_dai; struct snd_soc_dai_link_component codecs; /* single codec */ struct snd_soc_dai_link_component platform; + struct asoc_simple_card_data adata; + struct snd_soc_codec_conf *codec_conf; unsigned int mclk_fs; } *dai_props; unsigned int mclk_fs; @@ -29,6 +31,8 @@ struct simple_card_data { struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; + struct asoc_simple_card_data adata; + struct snd_soc_codec_conf *codec_conf; };
#define simple_priv_to_card(priv) (&(priv)->snd_card) @@ -74,6 +78,9 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai, unsigned long rate) { + if (!simple_dai) + return 0; + if (!simple_dai->clk) return 0;
@@ -151,6 +158,141 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) return 0; }
+static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num); + + asoc_simple_card_convert_fixup(&dai_props->adata, params); + + /* overwrite by top level adata if exist */ + asoc_simple_card_convert_fixup(&priv->adata, params); + + return 0; +} + +static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, + struct device_node *np, + struct device_node *codec, + struct simple_card_data *priv, + int *dai_idx, int link_idx, + int *conf_idx, int is_fe, + bool is_top_level_node) +{ + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, link_idx); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx); + struct snd_soc_card *card = simple_priv_to_card(priv); + struct asoc_simple_dai *dai; + char *prefix = ""; + int ret; + + /* For single DAI link & old style of DT node */ + if (is_top_level_node) + prefix = PREFIX; + + if (is_fe) { + int is_single_links = 0; + struct snd_soc_dai_link_component *codecs; + + /* BE is dummy */ + codecs = dai_link->codecs; + codecs->of_node = NULL; + codecs->dai_name = "snd-soc-dummy-dai"; + codecs->name = "snd-soc-dummy"; + + /* FE settings */ + dai_link->dynamic = 1; + dai_link->dpcm_merged_format = 1; + + dai = + dai_props->cpu_dai = &priv->dais[(*dai_idx)++]; + + ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL, + &is_single_links); + if (ret) + return ret; + + ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, dai); + if (ret < 0) + return ret; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "fe.%s", + dai_link->cpu_dai_name); + if (ret < 0) + return ret; + + asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); + } else { + struct snd_soc_codec_conf *cconf; + + /* FE is dummy */ + dai_link->cpu_of_node = NULL; + dai_link->cpu_dai_name = "snd-soc-dummy-dai"; + dai_link->cpu_name = "snd-soc-dummy"; + + /* BE settings */ + dai_link->no_pcm = 1; + dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup; + + dai = + dai_props->codec_dai = &priv->dais[(*dai_idx)++]; + + cconf = + dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++]; + + ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL); + if (ret < 0) + return ret; + + ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, dai); + if (ret < 0) + return ret; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "be.%s", + dai_link->codecs->dai_name); + if (ret < 0) + return ret; + + /* check "prefix" from top node */ + snd_soc_of_parse_audio_prefix(card, cconf, + dai_link->codecs->of_node, + PREFIX "prefix"); + /* check "prefix" from each node if top doesn't have */ + if (!cconf->of_node) + snd_soc_of_parse_node_prefix(np, cconf, + dai_link->codecs->of_node, + "prefix"); + } + + asoc_simple_card_parse_convert(dev, node, prefix, &dai_props->adata); + + ret = asoc_simple_card_of_parse_tdm(np, dai); + if (ret) + return ret; + + ret = asoc_simple_card_canonicalize_dailink(dai_link); + if (ret < 0) + return ret; + + of_property_read_u32(np, "mclk-fs", &dai_props->mclk_fs); + + ret = asoc_simple_card_parse_daifmt(dev, node, codec, + prefix, &dai_link->dai_fmt); + if (ret < 0) + return ret; + + dai_link->dpcm_playback = 1; + dai_link->dpcm_capture = 1; + dai_link->ops = &asoc_simple_card_ops; + dai_link->init = asoc_simple_card_dai_init; + + return 0; +} + static int asoc_simple_card_dai_link_of(struct device_node *node, struct simple_card_data *priv, int *dai_idx, int link_idx, @@ -291,63 +433,153 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node, static int asoc_simple_card_parse_of(struct simple_card_data *priv) { struct device *dev = simple_priv_to_dev(priv); + struct device_node *top = dev->of_node; struct snd_soc_card *card = simple_priv_to_card(priv); - struct device_node *dai_link; - struct device_node *node = dev->of_node; - int ret; - int link_idx, dai_idx; - - if (!node) + struct device_node *node; + struct device_node *np; + struct device_node *codec; + bool is_fe; + int ret, loop; + int dai_idx, link_idx, conf_idx; + + if (!top) return -EINVAL;
- dai_link = of_get_child_by_name(node, PREFIX "dai-link"); - ret = asoc_simple_card_of_parse_widgets(card, PREFIX); if (ret < 0) - goto card_parse_end; + return ret;
ret = asoc_simple_card_of_parse_routing(card, PREFIX); if (ret < 0) - goto card_parse_end; + return ret;
/* Factor to mclk, used in hw_params() */ - of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs); + of_property_read_u32(top, PREFIX "mclk-fs", &priv->mclk_fs); + + asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata);
/* Single/Muti DAI link(s) & New style of DT node */ - link_idx = 0; - dai_idx = 0; - if (dai_link) { - struct device_node *np = NULL; - - for_each_child_of_node(node, np) { - dev_dbg(dev, "\tlink %d:\n", link_idx); - ret = asoc_simple_card_dai_link_of(np, priv, - &dai_idx, link_idx++, false); - if (ret < 0) { - of_node_put(np); - goto card_parse_end; + loop = 1; + link_idx = 0; + dai_idx = 0; + conf_idx = 0; + node = of_get_child_by_name(top, PREFIX "dai-link"); + if (!node) { + node = dev->of_node; + loop = 0; + } + + do { + /* DPCM */ + if (of_get_child_count(node) > 2) { + for_each_child_of_node(node, np) { + codec = of_get_child_by_name(node, + loop ? "codec" : + PREFIX "codec"); + if (!codec) + return -ENODEV; + + is_fe = (np != codec); + + ret = asoc_simple_card_dai_link_of_dpcm( + node, np, codec, priv, + &dai_idx, link_idx++, &conf_idx, + is_fe, !loop); } + } else { + ret = asoc_simple_card_dai_link_of( + node, priv, + &dai_idx, link_idx++, !loop); } - } else { - /* For single DAI link & old style of DT node */ - ret = asoc_simple_card_dai_link_of(node, priv, - &dai_idx, link_idx++, true); if (ret < 0) - goto card_parse_end; - } + return ret; + + node = of_get_next_child(top, node); + } while (loop && node);
ret = asoc_simple_card_parse_card_name(card, PREFIX); if (ret < 0) - goto card_parse_end; - - ret = asoc_simple_card_parse_aux_devs(node, priv); + return ret;
-card_parse_end: - of_node_put(dai_link); + ret = asoc_simple_card_parse_aux_devs(top, priv);
return ret; }
+static void asoc_simple_card_get_dais_count(struct device *dev, + int *link_num, + int *dais_num, + int *ccnf_num) +{ + struct device_node *top = dev->of_node; + struct device_node *node; + int loop; + int num; + + /* + * link_num : number of links. + * CPU-Codec / CPU-dummy / dummy-Codec + * dais_num : number of DAIs + * ccnf_num : number of codec_conf + * same number for "dummy-Codec" + * + * ex1) + * CPU0 --- Codec0 link : 5 + * CPU1 --- Codec1 dais : 7 + * CPU2 -/ ccnf : 1 + * CPU3 --- Codec2 + * + * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec + * => 7 DAIs = 4xCPU + 3xCodec + * => 1 ccnf = 1xdummy-Codec + * + * ex2) + * CPU0 --- Codec0 link : 5 + * CPU1 --- Codec1 dais : 6 + * CPU2 -/ ccnf : 1 + * CPU3 -/ + * + * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec + * => 6 DAIs = 4xCPU + 2xCodec + * => 1 ccnf = 1xdummy-Codec + * + * ex3) + * CPU0 --- Codec0 link : 6 + * CPU1 -/ dais : 6 + * CPU2 --- Codec1 ccnf : 2 + * CPU3 -/ + * + * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec + * => 6 DAIs = 4xCPU + 2xCodec + * => 2 ccnf = 2xdummy-Codec + */ + if (!top) { + (*link_num) = 1; + (*dais_num) = 2; + (*ccnf_num) = 0; + return; + } + + loop = 1; + node = of_get_child_by_name(top, PREFIX "dai-link"); + if (!node) { + node = top; + loop = 0; + } + + do { + num = of_get_child_count(node); + (*dais_num) += num; + if (num > 2) { + (*link_num) += num; + (*ccnf_num)++; + } else { + (*link_num)++; + } + node = of_get_next_child(top, node); + } while (loop && node); +} + static int asoc_simple_soc_card_probe(struct snd_soc_card *card) { struct simple_card_data *priv = snd_soc_card_get_drvdata(card); @@ -373,22 +605,23 @@ static int asoc_simple_card_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct snd_soc_card *card; - int num, ret, i; - - /* Get the number of DAI links */ - if (np && of_get_child_by_name(np, PREFIX "dai-link")) - num = of_get_child_count(np); - else - num = 1; + struct snd_soc_codec_conf *cconf; + int lnum = 0, dnum = 0, cnum = 0; + int ret, i;
/* Allocate the private data and the DAI link array */ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
- dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); - dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); - dais = devm_kcalloc(dev, num * 2, sizeof(*dais), GFP_KERNEL); + asoc_simple_card_get_dais_count(dev, &lnum, &dnum, &cnum); + if (!lnum || !dnum) + return -EINVAL; + + dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL); + dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL); + dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL); + cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL); if (!dai_props || !dai_link || !dais) return -ENOMEM;
@@ -398,7 +631,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) * see * soc-core.c :: snd_soc_init_multicodec() */ - for (i = 0; i < num; i++) { + for (i = 0; i < lnum; i++) { dai_link[i].codecs = &dai_props[i].codecs; dai_link[i].num_codecs = 1; dai_link[i].platform = &dai_props[i].platform; @@ -407,13 +640,16 @@ static int asoc_simple_card_probe(struct platform_device *pdev) priv->dai_props = dai_props; priv->dai_link = dai_link; priv->dais = dais; + priv->codec_conf = cconf;
/* Init snd_soc_card */ card = simple_priv_to_card(priv); card->owner = THIS_MODULE; card->dev = dev; card->dai_link = priv->dai_link; - card->num_links = num; + card->num_links = lnum; + card->codec_conf = cconf; + card->num_configs = cnum; card->probe = asoc_simple_soc_card_probe;
if (np && of_device_is_available(np)) { @@ -490,6 +726,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
static const struct of_device_id asoc_simple_of_match[] = { { .compatible = "simple-audio-card", }, + { .compatible = "simple-scu-audio-card", }, {}, }; MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
The patch
ASoC: simple-card: merge simple-scu-card
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From da215354eb55c382d3d5c426ea0e9aa7ef7c10e1 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 14 Dec 2018 11:35:10 +0900 Subject: [PATCH] ASoC: simple-card: merge simple-scu-card
simple-card and simple-scu-card are very similar driver, but the former is supporting normal sound card, the latter is supporting DPCM sound card.
We couldn't use normal sound and DPCM sound in same time by one sound card. This patch merges both sound card into simple-card. Now we can use both feature on same driver.
simple-card is now supporting .compatible = "simple-scu-audio-card".
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/generic/Kconfig | 1 + sound/soc/generic/simple-card.c | 329 +++++++++++++++++++++++++++----- 2 files changed, 284 insertions(+), 46 deletions(-)
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index 5395782424b4..92c2cf06f40a 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -6,6 +6,7 @@ config SND_SIMPLE_CARD select SND_SIMPLE_CARD_UTILS help This option enables generic simple sound card support + It also support DPCM of multi CPU single Codec ststem.
config SND_SIMPLE_SCU_CARD tristate "ASoC Simple SCU sound card support" diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 93d68161f953..c93f2e7dec4b 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -22,6 +22,8 @@ struct simple_card_data { struct asoc_simple_dai *codec_dai; struct snd_soc_dai_link_component codecs; /* single codec */ struct snd_soc_dai_link_component platform; + struct asoc_simple_card_data adata; + struct snd_soc_codec_conf *codec_conf; unsigned int mclk_fs; } *dai_props; unsigned int mclk_fs; @@ -29,6 +31,8 @@ struct simple_card_data { struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; + struct asoc_simple_card_data adata; + struct snd_soc_codec_conf *codec_conf; };
#define simple_priv_to_card(priv) (&(priv)->snd_card) @@ -74,6 +78,9 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai, unsigned long rate) { + if (!simple_dai) + return 0; + if (!simple_dai->clk) return 0;
@@ -151,6 +158,141 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) return 0; }
+static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num); + + asoc_simple_card_convert_fixup(&dai_props->adata, params); + + /* overwrite by top level adata if exist */ + asoc_simple_card_convert_fixup(&priv->adata, params); + + return 0; +} + +static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, + struct device_node *np, + struct device_node *codec, + struct simple_card_data *priv, + int *dai_idx, int link_idx, + int *conf_idx, int is_fe, + bool is_top_level_node) +{ + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, link_idx); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx); + struct snd_soc_card *card = simple_priv_to_card(priv); + struct asoc_simple_dai *dai; + char *prefix = ""; + int ret; + + /* For single DAI link & old style of DT node */ + if (is_top_level_node) + prefix = PREFIX; + + if (is_fe) { + int is_single_links = 0; + struct snd_soc_dai_link_component *codecs; + + /* BE is dummy */ + codecs = dai_link->codecs; + codecs->of_node = NULL; + codecs->dai_name = "snd-soc-dummy-dai"; + codecs->name = "snd-soc-dummy"; + + /* FE settings */ + dai_link->dynamic = 1; + dai_link->dpcm_merged_format = 1; + + dai = + dai_props->cpu_dai = &priv->dais[(*dai_idx)++]; + + ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL, + &is_single_links); + if (ret) + return ret; + + ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, dai); + if (ret < 0) + return ret; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "fe.%s", + dai_link->cpu_dai_name); + if (ret < 0) + return ret; + + asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); + } else { + struct snd_soc_codec_conf *cconf; + + /* FE is dummy */ + dai_link->cpu_of_node = NULL; + dai_link->cpu_dai_name = "snd-soc-dummy-dai"; + dai_link->cpu_name = "snd-soc-dummy"; + + /* BE settings */ + dai_link->no_pcm = 1; + dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup; + + dai = + dai_props->codec_dai = &priv->dais[(*dai_idx)++]; + + cconf = + dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++]; + + ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL); + if (ret < 0) + return ret; + + ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, dai); + if (ret < 0) + return ret; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "be.%s", + dai_link->codecs->dai_name); + if (ret < 0) + return ret; + + /* check "prefix" from top node */ + snd_soc_of_parse_audio_prefix(card, cconf, + dai_link->codecs->of_node, + PREFIX "prefix"); + /* check "prefix" from each node if top doesn't have */ + if (!cconf->of_node) + snd_soc_of_parse_node_prefix(np, cconf, + dai_link->codecs->of_node, + "prefix"); + } + + asoc_simple_card_parse_convert(dev, node, prefix, &dai_props->adata); + + ret = asoc_simple_card_of_parse_tdm(np, dai); + if (ret) + return ret; + + ret = asoc_simple_card_canonicalize_dailink(dai_link); + if (ret < 0) + return ret; + + of_property_read_u32(np, "mclk-fs", &dai_props->mclk_fs); + + ret = asoc_simple_card_parse_daifmt(dev, node, codec, + prefix, &dai_link->dai_fmt); + if (ret < 0) + return ret; + + dai_link->dpcm_playback = 1; + dai_link->dpcm_capture = 1; + dai_link->ops = &asoc_simple_card_ops; + dai_link->init = asoc_simple_card_dai_init; + + return 0; +} + static int asoc_simple_card_dai_link_of(struct device_node *node, struct simple_card_data *priv, int *dai_idx, int link_idx, @@ -291,63 +433,153 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node, static int asoc_simple_card_parse_of(struct simple_card_data *priv) { struct device *dev = simple_priv_to_dev(priv); + struct device_node *top = dev->of_node; struct snd_soc_card *card = simple_priv_to_card(priv); - struct device_node *dai_link; - struct device_node *node = dev->of_node; - int ret; - int link_idx, dai_idx; - - if (!node) + struct device_node *node; + struct device_node *np; + struct device_node *codec; + bool is_fe; + int ret, loop; + int dai_idx, link_idx, conf_idx; + + if (!top) return -EINVAL;
- dai_link = of_get_child_by_name(node, PREFIX "dai-link"); - ret = asoc_simple_card_of_parse_widgets(card, PREFIX); if (ret < 0) - goto card_parse_end; + return ret;
ret = asoc_simple_card_of_parse_routing(card, PREFIX); if (ret < 0) - goto card_parse_end; + return ret;
/* Factor to mclk, used in hw_params() */ - of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs); + of_property_read_u32(top, PREFIX "mclk-fs", &priv->mclk_fs); + + asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata);
/* Single/Muti DAI link(s) & New style of DT node */ - link_idx = 0; - dai_idx = 0; - if (dai_link) { - struct device_node *np = NULL; - - for_each_child_of_node(node, np) { - dev_dbg(dev, "\tlink %d:\n", link_idx); - ret = asoc_simple_card_dai_link_of(np, priv, - &dai_idx, link_idx++, false); - if (ret < 0) { - of_node_put(np); - goto card_parse_end; + loop = 1; + link_idx = 0; + dai_idx = 0; + conf_idx = 0; + node = of_get_child_by_name(top, PREFIX "dai-link"); + if (!node) { + node = dev->of_node; + loop = 0; + } + + do { + /* DPCM */ + if (of_get_child_count(node) > 2) { + for_each_child_of_node(node, np) { + codec = of_get_child_by_name(node, + loop ? "codec" : + PREFIX "codec"); + if (!codec) + return -ENODEV; + + is_fe = (np != codec); + + ret = asoc_simple_card_dai_link_of_dpcm( + node, np, codec, priv, + &dai_idx, link_idx++, &conf_idx, + is_fe, !loop); } + } else { + ret = asoc_simple_card_dai_link_of( + node, priv, + &dai_idx, link_idx++, !loop); } - } else { - /* For single DAI link & old style of DT node */ - ret = asoc_simple_card_dai_link_of(node, priv, - &dai_idx, link_idx++, true); if (ret < 0) - goto card_parse_end; - } + return ret; + + node = of_get_next_child(top, node); + } while (loop && node);
ret = asoc_simple_card_parse_card_name(card, PREFIX); if (ret < 0) - goto card_parse_end; - - ret = asoc_simple_card_parse_aux_devs(node, priv); + return ret;
-card_parse_end: - of_node_put(dai_link); + ret = asoc_simple_card_parse_aux_devs(top, priv);
return ret; }
+static void asoc_simple_card_get_dais_count(struct device *dev, + int *link_num, + int *dais_num, + int *ccnf_num) +{ + struct device_node *top = dev->of_node; + struct device_node *node; + int loop; + int num; + + /* + * link_num : number of links. + * CPU-Codec / CPU-dummy / dummy-Codec + * dais_num : number of DAIs + * ccnf_num : number of codec_conf + * same number for "dummy-Codec" + * + * ex1) + * CPU0 --- Codec0 link : 5 + * CPU1 --- Codec1 dais : 7 + * CPU2 -/ ccnf : 1 + * CPU3 --- Codec2 + * + * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec + * => 7 DAIs = 4xCPU + 3xCodec + * => 1 ccnf = 1xdummy-Codec + * + * ex2) + * CPU0 --- Codec0 link : 5 + * CPU1 --- Codec1 dais : 6 + * CPU2 -/ ccnf : 1 + * CPU3 -/ + * + * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec + * => 6 DAIs = 4xCPU + 2xCodec + * => 1 ccnf = 1xdummy-Codec + * + * ex3) + * CPU0 --- Codec0 link : 6 + * CPU1 -/ dais : 6 + * CPU2 --- Codec1 ccnf : 2 + * CPU3 -/ + * + * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec + * => 6 DAIs = 4xCPU + 2xCodec + * => 2 ccnf = 2xdummy-Codec + */ + if (!top) { + (*link_num) = 1; + (*dais_num) = 2; + (*ccnf_num) = 0; + return; + } + + loop = 1; + node = of_get_child_by_name(top, PREFIX "dai-link"); + if (!node) { + node = top; + loop = 0; + } + + do { + num = of_get_child_count(node); + (*dais_num) += num; + if (num > 2) { + (*link_num) += num; + (*ccnf_num)++; + } else { + (*link_num)++; + } + node = of_get_next_child(top, node); + } while (loop && node); +} + static int asoc_simple_soc_card_probe(struct snd_soc_card *card) { struct simple_card_data *priv = snd_soc_card_get_drvdata(card); @@ -373,22 +605,23 @@ static int asoc_simple_card_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct snd_soc_card *card; - int num, ret, i; - - /* Get the number of DAI links */ - if (np && of_get_child_by_name(np, PREFIX "dai-link")) - num = of_get_child_count(np); - else - num = 1; + struct snd_soc_codec_conf *cconf; + int lnum = 0, dnum = 0, cnum = 0; + int ret, i;
/* Allocate the private data and the DAI link array */ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
- dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); - dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); - dais = devm_kcalloc(dev, num * 2, sizeof(*dais), GFP_KERNEL); + asoc_simple_card_get_dais_count(dev, &lnum, &dnum, &cnum); + if (!lnum || !dnum) + return -EINVAL; + + dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL); + dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL); + dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL); + cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL); if (!dai_props || !dai_link || !dais) return -ENOMEM;
@@ -398,7 +631,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) * see * soc-core.c :: snd_soc_init_multicodec() */ - for (i = 0; i < num; i++) { + for (i = 0; i < lnum; i++) { dai_link[i].codecs = &dai_props[i].codecs; dai_link[i].num_codecs = 1; dai_link[i].platform = &dai_props[i].platform; @@ -407,13 +640,16 @@ static int asoc_simple_card_probe(struct platform_device *pdev) priv->dai_props = dai_props; priv->dai_link = dai_link; priv->dais = dais; + priv->codec_conf = cconf;
/* Init snd_soc_card */ card = simple_priv_to_card(priv); card->owner = THIS_MODULE; card->dev = dev; card->dai_link = priv->dai_link; - card->num_links = num; + card->num_links = lnum; + card->codec_conf = cconf; + card->num_configs = cnum; card->probe = asoc_simple_soc_card_probe;
if (np && of_device_is_available(np)) { @@ -490,6 +726,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
static const struct of_device_id asoc_simple_of_match[] = { { .compatible = "simple-audio-card", }, + { .compatible = "simple-scu-audio-card", }, {}, }; MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current simple-card is handling "mclk-fs" by many way. But, it is not useful and readable. We want to do is that allow having mclk-fs everywere. This patch support it. It will be overwrote if lower node has it.
sound { simple-audio-card,mclk-fs = <xxx>; // for initial
simple-audio-card,dai-link { mclk-fs = <xxx>; // overwrite cpu { mclk-fs = <xxx>; // overwrite }; codec { mclk-fs = <xxx>; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/simple-card.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index c93f2e7..8593d51 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -26,7 +26,6 @@ struct simple_card_data { struct snd_soc_codec_conf *codec_conf; unsigned int mclk_fs; } *dai_props; - unsigned int mclk_fs; struct asoc_simple_jack hp_jack; struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; @@ -102,9 +101,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, unsigned int mclk, mclk_fs = 0; int ret = 0;
- if (priv->mclk_fs) - mclk_fs = priv->mclk_fs; - else if (dai_props->mclk_fs) + if (dai_props->mclk_fs) mclk_fs = dai_props->mclk_fs;
if (mclk_fs) { @@ -172,7 +169,8 @@ static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; }
-static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, +static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top, + struct device_node *node, struct device_node *np, struct device_node *codec, struct simple_card_data *priv, @@ -185,6 +183,7 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx); struct snd_soc_card *card = simple_priv_to_card(priv); struct asoc_simple_dai *dai; + char prop[128]; char *prefix = ""; int ret;
@@ -278,7 +277,10 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, if (ret < 0) return ret;
- of_property_read_u32(np, "mclk-fs", &dai_props->mclk_fs); + snprintf(prop, sizeof(prop), "%smclk-fs", prefix); + of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, prop, &dai_props->mclk_fs); + of_property_read_u32(np, prop, &dai_props->mclk_fs);
ret = asoc_simple_card_parse_daifmt(dev, node, codec, prefix, &dai_link->dai_fmt); @@ -293,7 +295,8 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, return 0; }
-static int asoc_simple_card_dai_link_of(struct device_node *node, +static int asoc_simple_card_dai_link_of(struct device_node *top, + struct device_node *node, struct simple_card_data *priv, int *dai_idx, int link_idx, bool is_top_level_node) @@ -345,7 +348,11 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, if (ret < 0) goto dai_link_of_err;
- of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs); + snprintf(prop, sizeof(prop), "%smclk-fs", prefix); + of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, prop, &dai_props->mclk_fs); + of_property_read_u32(cpu, prop, &dai_props->mclk_fs); + of_property_read_u32(codec, prop, &dai_props->mclk_fs);
ret = asoc_simple_card_parse_cpu(cpu, dai_link, DAI, CELL, &single_cpu); @@ -453,9 +460,6 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) if (ret < 0) return ret;
- /* Factor to mclk, used in hw_params() */ - of_property_read_u32(top, PREFIX "mclk-fs", &priv->mclk_fs); - asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata);
/* Single/Muti DAI link(s) & New style of DT node */ @@ -482,13 +486,13 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) is_fe = (np != codec);
ret = asoc_simple_card_dai_link_of_dpcm( - node, np, codec, priv, + top, node, np, codec, priv, &dai_idx, link_idx++, &conf_idx, is_fe, !loop); } } else { ret = asoc_simple_card_dai_link_of( - node, priv, + top, node, priv, &dai_idx, link_idx++, !loop); } if (ret < 0)
The patch
ASoC: simple-card: tidyup mclk-fs method
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 79e834914d1fa2d078c586094ad347cc05aa428c Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 14 Dec 2018 11:35:15 +0900 Subject: [PATCH] ASoC: simple-card: tidyup mclk-fs method
Current simple-card is handling "mclk-fs" by many way. But, it is not useful and readable. We want to do is that allow having mclk-fs everywere. This patch support it. It will be overwrote if lower node has it.
sound { simple-audio-card,mclk-fs = <xxx>; // for initial
simple-audio-card,dai-link { mclk-fs = <xxx>; // overwrite cpu { mclk-fs = <xxx>; // overwrite }; codec { mclk-fs = <xxx>; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/generic/simple-card.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index c93f2e7dec4b..8593d51e0c6c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -26,7 +26,6 @@ struct simple_card_data { struct snd_soc_codec_conf *codec_conf; unsigned int mclk_fs; } *dai_props; - unsigned int mclk_fs; struct asoc_simple_jack hp_jack; struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; @@ -102,9 +101,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, unsigned int mclk, mclk_fs = 0; int ret = 0;
- if (priv->mclk_fs) - mclk_fs = priv->mclk_fs; - else if (dai_props->mclk_fs) + if (dai_props->mclk_fs) mclk_fs = dai_props->mclk_fs;
if (mclk_fs) { @@ -172,7 +169,8 @@ static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; }
-static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, +static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top, + struct device_node *node, struct device_node *np, struct device_node *codec, struct simple_card_data *priv, @@ -185,6 +183,7 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx); struct snd_soc_card *card = simple_priv_to_card(priv); struct asoc_simple_dai *dai; + char prop[128]; char *prefix = ""; int ret;
@@ -278,7 +277,10 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, if (ret < 0) return ret;
- of_property_read_u32(np, "mclk-fs", &dai_props->mclk_fs); + snprintf(prop, sizeof(prop), "%smclk-fs", prefix); + of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, prop, &dai_props->mclk_fs); + of_property_read_u32(np, prop, &dai_props->mclk_fs);
ret = asoc_simple_card_parse_daifmt(dev, node, codec, prefix, &dai_link->dai_fmt); @@ -293,7 +295,8 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *node, return 0; }
-static int asoc_simple_card_dai_link_of(struct device_node *node, +static int asoc_simple_card_dai_link_of(struct device_node *top, + struct device_node *node, struct simple_card_data *priv, int *dai_idx, int link_idx, bool is_top_level_node) @@ -345,7 +348,11 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, if (ret < 0) goto dai_link_of_err;
- of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs); + snprintf(prop, sizeof(prop), "%smclk-fs", prefix); + of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, prop, &dai_props->mclk_fs); + of_property_read_u32(cpu, prop, &dai_props->mclk_fs); + of_property_read_u32(codec, prop, &dai_props->mclk_fs);
ret = asoc_simple_card_parse_cpu(cpu, dai_link, DAI, CELL, &single_cpu); @@ -453,9 +460,6 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) if (ret < 0) return ret;
- /* Factor to mclk, used in hw_params() */ - of_property_read_u32(top, PREFIX "mclk-fs", &priv->mclk_fs); - asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata);
/* Single/Muti DAI link(s) & New style of DT node */ @@ -482,13 +486,13 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) is_fe = (np != codec);
ret = asoc_simple_card_dai_link_of_dpcm( - node, np, codec, priv, + top, node, np, codec, priv, &dai_idx, link_idx++, &conf_idx, is_fe, !loop); } } else { ret = asoc_simple_card_dai_link_of( - node, priv, + top, node, priv, &dai_idx, link_idx++, !loop); } if (ret < 0)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current simple-card is handling "convert_rate/channel" by many ways. But, it is not useful and readable. We want to do is that allow having it everywere. This patch support it. It will be overwrote if lower node has it.
sound { simple-audio-card,convert_channels = <xxx>; // initial
simple-audio-card,dai-link { convert_channels = <xxx>; // overwrite cpu { convert_channels = <xxx>; // overwrite }; codec { convert_channels = <xxx>; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/simple-card.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 8593d51..fb18e51 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -30,7 +30,6 @@ struct simple_card_data { struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; - struct asoc_simple_card_data adata; struct snd_soc_codec_conf *codec_conf; };
@@ -163,9 +162,6 @@ static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
asoc_simple_card_convert_fixup(&dai_props->adata, params);
- /* overwrite by top level adata if exist */ - asoc_simple_card_convert_fixup(&priv->adata, params); - return 0; }
@@ -267,7 +263,9 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top, "prefix"); }
+ asoc_simple_card_parse_convert(dev, top, PREFIX, &dai_props->adata); asoc_simple_card_parse_convert(dev, node, prefix, &dai_props->adata); + asoc_simple_card_parse_convert(dev, np, NULL, &dai_props->adata);
ret = asoc_simple_card_of_parse_tdm(np, dai); if (ret) @@ -460,8 +458,6 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) if (ret < 0) return ret;
- asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata); - /* Single/Muti DAI link(s) & New style of DT node */ loop = 1; link_idx = 0;
The patch
ASoC: simple-card: tidyup convert_rate/channel method
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From dd82410f7e939f00591c415d62915a89ac2fb8f0 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 14 Dec 2018 11:35:20 +0900 Subject: [PATCH] ASoC: simple-card: tidyup convert_rate/channel method
Current simple-card is handling "convert_rate/channel" by many ways. But, it is not useful and readable. We want to do is that allow having it everywere. This patch support it. It will be overwrote if lower node has it.
sound { simple-audio-card,convert_channels = <xxx>; // initial
simple-audio-card,dai-link { convert_channels = <xxx>; // overwrite cpu { convert_channels = <xxx>; // overwrite }; codec { convert_channels = <xxx>; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/generic/simple-card.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 8593d51e0c6c..fb18e5148aad 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -30,7 +30,6 @@ struct simple_card_data { struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; - struct asoc_simple_card_data adata; struct snd_soc_codec_conf *codec_conf; };
@@ -163,9 +162,6 @@ static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
asoc_simple_card_convert_fixup(&dai_props->adata, params);
- /* overwrite by top level adata if exist */ - asoc_simple_card_convert_fixup(&priv->adata, params); - return 0; }
@@ -267,7 +263,9 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top, "prefix"); }
+ asoc_simple_card_parse_convert(dev, top, PREFIX, &dai_props->adata); asoc_simple_card_parse_convert(dev, node, prefix, &dai_props->adata); + asoc_simple_card_parse_convert(dev, np, NULL, &dai_props->adata);
ret = asoc_simple_card_of_parse_tdm(np, dai); if (ret) @@ -460,8 +458,6 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) if (ret < 0) return ret;
- asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata); - /* Single/Muti DAI link(s) & New style of DT node */ loop = 1; link_idx = 0;
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current simple-card is handling "prefix" by many ways. But, it is not useful and readable. We want to do is that allow having it everywere. This patch supports it. It will be overwrote if lower node has it.
sound { simple-audio-card,prefix = "xxx"; // initial
simple-audio-card,dai-link { prefix = "xxx"; // overwrite cpu { ... }; codec { prefix = "xxx"; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/simple-card.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index fb18e51..37e001c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -177,8 +177,9 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top, struct device *dev = simple_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, link_idx); struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx); - struct snd_soc_card *card = simple_priv_to_card(priv); struct asoc_simple_dai *dai; + struct snd_soc_dai_link_component *codecs = dai_link->codecs; + char prop[128]; char *prefix = ""; int ret; @@ -189,10 +190,8 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top,
if (is_fe) { int is_single_links = 0; - struct snd_soc_dai_link_component *codecs;
/* BE is dummy */ - codecs = dai_link->codecs; codecs->of_node = NULL; codecs->dai_name = "snd-soc-dummy-dai"; codecs->name = "snd-soc-dummy"; @@ -248,19 +247,17 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top,
ret = asoc_simple_card_set_dailink_name(dev, dai_link, "be.%s", - dai_link->codecs->dai_name); + codecs->dai_name); if (ret < 0) return ret;
/* check "prefix" from top node */ - snd_soc_of_parse_audio_prefix(card, cconf, - dai_link->codecs->of_node, + snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, PREFIX "prefix"); - /* check "prefix" from each node if top doesn't have */ - if (!cconf->of_node) - snd_soc_of_parse_node_prefix(np, cconf, - dai_link->codecs->of_node, - "prefix"); + snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node, + "prefix"); + snd_soc_of_parse_node_prefix(np, cconf, codecs->of_node, + "prefix"); }
asoc_simple_card_parse_convert(dev, top, PREFIX, &dai_props->adata);
The patch
ASoC: simple-card: tidyup prefix for snd_soc_codec_conf
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From cfc652a73331c3b465e3f8dd39a3d6b71e6b3a66 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 14 Dec 2018 11:35:24 +0900 Subject: [PATCH] ASoC: simple-card: tidyup prefix for snd_soc_codec_conf
Current simple-card is handling "prefix" by many ways. But, it is not useful and readable. We want to do is that allow having it everywere. This patch supports it. It will be overwrote if lower node has it.
sound { simple-audio-card,prefix = "xxx"; // initial
simple-audio-card,dai-link { prefix = "xxx"; // overwrite cpu { ... }; codec { prefix = "xxx"; // overwrite }; }; };
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/generic/simple-card.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index fb18e5148aad..37e001cf9cd1 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -177,8 +177,9 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top, struct device *dev = simple_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, link_idx); struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx); - struct snd_soc_card *card = simple_priv_to_card(priv); struct asoc_simple_dai *dai; + struct snd_soc_dai_link_component *codecs = dai_link->codecs; + char prop[128]; char *prefix = ""; int ret; @@ -189,10 +190,8 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top,
if (is_fe) { int is_single_links = 0; - struct snd_soc_dai_link_component *codecs;
/* BE is dummy */ - codecs = dai_link->codecs; codecs->of_node = NULL; codecs->dai_name = "snd-soc-dummy-dai"; codecs->name = "snd-soc-dummy"; @@ -248,19 +247,17 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top,
ret = asoc_simple_card_set_dailink_name(dev, dai_link, "be.%s", - dai_link->codecs->dai_name); + codecs->dai_name); if (ret < 0) return ret;
/* check "prefix" from top node */ - snd_soc_of_parse_audio_prefix(card, cconf, - dai_link->codecs->of_node, + snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, PREFIX "prefix"); - /* check "prefix" from each node if top doesn't have */ - if (!cconf->of_node) - snd_soc_of_parse_node_prefix(np, cconf, - dai_link->codecs->of_node, - "prefix"); + snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node, + "prefix"); + snd_soc_of_parse_node_prefix(np, cconf, codecs->of_node, + "prefix"); }
asoc_simple_card_parse_convert(dev, top, PREFIX, &dai_props->adata);
participants (2)
-
Kuninori Morimoto
-
Mark Brown