[alsa-devel] [PATCH 00/10] ASoC: add OF-graph base simple-card
Hi Mark, Rob
These are OF-graph base simple-card patch-set.
Unfortunately, OF-graph DT binding idea for ALSA SoC was rejected many times before. 1st OF-graph idea doesn't have card node, but because of ML discussion, latest idea can have it. OTOH, Mark doesn't like big-patch-set. Thus, some of already accepted preparation patches for OF-graph simple-card was no longer needed. 1) - 4) remove these.
This patch set is based on my previous this patch
---------------- Date Thu, 19 Jan 2017 15:31:07 +0900 Subject [PATCH 0/6] of_graph_get_remote_endpoint() ----------------
1) - 4) : remove soc-core OF-graph adjust feature which is no longer needed 5) - 6) : add useful new of-graph functions 7) - 10) : add OF-graph base simple-card
Kuninori Morimoto (10): 1) ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_routing 2) ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_prefix 3) ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_simple_widgets 4) ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_card_name 5) of_graph: add of_graph_get_port_parent() 6) of_graph: add of_graph_get_endpoint_count() 7) ASoC: add snd_soc_get_dai_id() 8) ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai() 9) ASoC: add simple-graph-card document 10) ASoC: add simple-graph-card support
.../bindings/sound/simple-graph-card.txt | 137 ++++++++++ drivers/of/base.c | 42 ++- include/linux/of_graph.h | 14 + include/sound/simple_card_utils.h | 10 + include/sound/soc.h | 31 +-- sound/soc/generic/Kconfig | 7 + sound/soc/generic/Makefile | 2 + sound/soc/generic/simple-card-utils.c | 36 +++ sound/soc/generic/simple-graph-card.c | 303 +++++++++++++++++++++ sound/soc/soc-core.c | 61 +++-- 10 files changed, 588 insertions(+), 55 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-card.txt create mode 100644 sound/soc/generic/simple-graph-card.c
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Because prototype of OF-graph sound card support didn't have Sound Card node, commit 7364c8dc255232db33bcd1c5b19eb8f34cf6108a ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit 7364c8dc255232db33bcd1c5b19eb8f34cf6108a.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 9 ++------- sound/soc/soc-core.c | 9 +++------ 2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index b86168a..c7b0a5c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1671,13 +1671,8 @@ void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, struct snd_soc_codec_conf *codec_conf, struct device_node *of_node, const char *propname); - -#define snd_soc_of_parse_audio_routing(card, propname) \ - snd_soc_of_parse_audio_routing_from_node(card, NULL, propname) -int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname); - +int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, + const char *propname); unsigned int snd_soc_of_parse_daifmt(struct device_node *np, const char *prefix, struct device_node **bitclkmaster, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index baa1afa..dcaca32 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3690,17 +3690,14 @@ void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix_from_node);
-int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card, - struct device_node *np, +int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, const char *propname) { + struct device_node *np = card->dev->of_node; int num_routes; struct snd_soc_dapm_route *routes; int i, ret;
- if (!np) - np = card->dev->of_node; - num_routes = of_property_count_strings(np, propname); if (num_routes < 0 || num_routes & 1) { dev_err(card->dev, @@ -3747,7 +3744,7 @@ int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
return 0; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np, const char *prefix,
The patch
ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_routing
has been applied to the asoc tree at
git://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 2bc644af610f28d05812f224636a95a57c2631d1 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 27 Jan 2017 06:36:50 +0000 Subject: [PATCH] ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_routing
Because prototype of OF-graph sound card support didn't have Sound Card node, commit 7364c8dc255232db33bcd1c5b19eb8f34cf6108a ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit 7364c8dc255232db33bcd1c5b19eb8f34cf6108a.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- include/sound/soc.h | 9 ++------- sound/soc/soc-core.c | 9 +++------ 2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 2b502f6cc6d0..838e03778b58 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1668,13 +1668,8 @@ void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, struct snd_soc_codec_conf *codec_conf, struct device_node *of_node, const char *propname); - -#define snd_soc_of_parse_audio_routing(card, propname) \ - snd_soc_of_parse_audio_routing_from_node(card, NULL, propname) -int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname); - +int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, + const char *propname); unsigned int snd_soc_of_parse_daifmt(struct device_node *np, const char *prefix, struct device_node **bitclkmaster, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f1901bb1466e..e30984fd649b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3690,17 +3690,14 @@ void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix_from_node);
-int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card, - struct device_node *np, +int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, const char *propname) { + struct device_node *np = card->dev->of_node; int num_routes; struct snd_soc_dapm_route *routes; int i, ret;
- if (!np) - np = card->dev->of_node; - num_routes = of_property_count_strings(np, propname); if (num_routes < 0 || num_routes & 1) { dev_err(card->dev, @@ -3747,7 +3744,7 @@ int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
return 0; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np, const char *prefix,
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Because prototype of OF-graph sound card support didn't have Sound Card node, commit b6defcca0a604129155ae472b116a2e1688d8995 ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit b6defcca0a604129155ae472b116a2e1688d8995.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 6 +----- sound/soc/soc-core.c | 9 +++------ 2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index c7b0a5c..b544206 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1663,11 +1663,7 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, unsigned int *rx_mask, unsigned int *slots, unsigned int *slot_width); -#define snd_soc_of_parse_audio_prefix(card, codec_conf, of_node, propname) \ - snd_soc_of_parse_audio_prefix_from_node(card, NULL, codec_conf, \ - of_node, propname) -void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, - struct device_node *np, +void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card, struct snd_soc_codec_conf *codec_conf, struct device_node *of_node, const char *propname); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index dcaca32..acc52c6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3667,18 +3667,15 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
-void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, - struct device_node *np, +void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card, struct snd_soc_codec_conf *codec_conf, struct device_node *of_node, const char *propname) { + struct device_node *np = card->dev->of_node; const char *str; int ret;
- if (!np) - np = card->dev->of_node; - ret = of_property_read_string(np, propname, &str); if (ret < 0) { /* no prefix is not error */ @@ -3688,7 +3685,7 @@ void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, codec_conf->of_node = of_node; codec_conf->name_prefix = str; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix);
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, const char *propname)
The patch
ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_prefix
has been applied to the asoc tree at
git://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 440a3006f154a3aca4badf72841c61ac93a72110 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 27 Jan 2017 06:37:16 +0000 Subject: [PATCH] ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_prefix
Because prototype of OF-graph sound card support didn't have Sound Card node, commit b6defcca0a604129155ae472b116a2e1688d8995 ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit b6defcca0a604129155ae472b116a2e1688d8995.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- include/sound/soc.h | 6 +----- sound/soc/soc-core.c | 9 +++------ 2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 4dccc4f63f5e..34bd033443dc 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1656,11 +1656,7 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, unsigned int *rx_mask, unsigned int *slots, unsigned int *slot_width); -#define snd_soc_of_parse_audio_prefix(card, codec_conf, of_node, propname) \ - snd_soc_of_parse_audio_prefix_from_node(card, NULL, codec_conf, \ - of_node, propname) -void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, - struct device_node *np, +void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card, struct snd_soc_codec_conf *codec_conf, struct device_node *of_node, const char *propname); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 656a981f6eb1..4ff2448f6023 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3664,18 +3664,15 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
-void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, - struct device_node *np, +void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card, struct snd_soc_codec_conf *codec_conf, struct device_node *of_node, const char *propname) { + struct device_node *np = card->dev->of_node; const char *str; int ret;
- if (!np) - np = card->dev->of_node; - ret = of_property_read_string(np, propname, &str); if (ret < 0) { /* no prefix is not error */ @@ -3685,7 +3682,7 @@ void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card, codec_conf->of_node = of_node; codec_conf->name_prefix = str; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix);
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, const char *propname)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Because prototype of OF-graph sound card support didn't have Sound Card node, commit 1ef5bcd57be5c8b31286b7b47828064be25f266b ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit 1ef5bcd57be5c8b31286b7b47828064be25f266b.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 8 ++------ sound/soc/soc-core.c | 9 +++------ 2 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index b544206..eb9fc7a 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1652,12 +1652,8 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform( int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, struct device_node *np, const char *propname); -#define snd_soc_of_parse_audio_simple_widgets(card, propname)\ - snd_soc_of_parse_audio_simple_widgets_from_node(card, NULL, propname) -int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname); - +int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, + const char *propname); int snd_soc_of_parse_tdm_slot(struct device_node *np, unsigned int *tx_mask, unsigned int *rx_mask, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index acc52c6..921bc9b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3530,17 +3530,14 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, SND_SOC_DAPM_SPK("Speaker", NULL), };
-int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card, - struct device_node *np, +int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, const char *propname) { + struct device_node *np = card->dev->of_node; struct snd_soc_dapm_widget *widgets; const char *template, *wname; int i, j, num_widgets, ret;
- if (!np) - np = card->dev->of_node; - num_widgets = of_property_count_strings(np, propname); if (num_widgets < 0) { dev_err(card->dev, @@ -3611,7 +3608,7 @@ int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
return 0; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
static int snd_soc_of_get_slot_mask(struct device_node *np, const char *prop_name,
The patch
ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_simple_widgets
has been applied to the asoc tree at
git://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 21efde50ca9cba9230d1b1ea54aadbf6d96c4157 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 27 Jan 2017 06:37:34 +0000 Subject: [PATCH] ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_audio_simple_widgets
Because prototype of OF-graph sound card support didn't have Sound Card node, commit 1ef5bcd57be5c8b31286b7b47828064be25f266b ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit 1ef5bcd57be5c8b31286b7b47828064be25f266b.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- include/sound/soc.h | 8 ++------ sound/soc/soc-core.c | 9 +++------ 2 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 838e03778b58..4dccc4f63f5e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1649,12 +1649,8 @@ void snd_soc_util_exit(void); int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, struct device_node *np, const char *propname); -#define snd_soc_of_parse_audio_simple_widgets(card, propname)\ - snd_soc_of_parse_audio_simple_widgets_from_node(card, NULL, propname) -int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname); - +int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, + const char *propname); int snd_soc_of_parse_tdm_slot(struct device_node *np, unsigned int *tx_mask, unsigned int *rx_mask, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index e30984fd649b..656a981f6eb1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3530,17 +3530,14 @@ static const struct snd_soc_dapm_widget simple_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), };
-int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card, - struct device_node *np, +int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, const char *propname) { + struct device_node *np = card->dev->of_node; struct snd_soc_dapm_widget *widgets; const char *template, *wname; int i, j, num_widgets, ret;
- if (!np) - np = card->dev->of_node; - num_widgets = of_property_count_strings(np, propname); if (num_widgets < 0) { dev_err(card->dev, @@ -3611,7 +3608,7 @@ int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
return 0; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
static int snd_soc_of_get_slot_mask(struct device_node *np, const char *prop_name,
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Because prototype of OF-graph sound card support didn't have Sound Card node, commit 8f5ebb1bee15b5720741a98414767bb86f6c2b23 ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit 8f5ebb1bee15b5720741a98414767bb86f6c2b23.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 7 ++----- sound/soc/soc-core.c | 11 +++++------ 2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index eb9fc7a..e2ea305 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1647,11 +1647,8 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform( int snd_soc_util_init(void); void snd_soc_util_exit(void);
-#define snd_soc_of_parse_card_name(card, propname) \ - snd_soc_of_parse_card_name_from_node(card, NULL, propname) -int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname); +int snd_soc_of_parse_card_name(struct snd_soc_card *card, + const char *propname); int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, const char *propname); int snd_soc_of_parse_tdm_slot(struct device_node *np, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 921bc9b..737765e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3492,10 +3492,10 @@ void snd_soc_unregister_codec(struct device *dev) EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
/* Retrieve a card's name from device tree */ -int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname) +int snd_soc_of_parse_card_name(struct snd_soc_card *card, + const char *propname) { + struct device_node *np; int ret;
if (!card->dev) { @@ -3503,8 +3503,7 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, return -EINVAL; }
- if (!np) - np = card->dev->of_node; + np = card->dev->of_node;
ret = of_property_read_string_index(np, propname, 0, &card->name); /* @@ -3521,7 +3520,7 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
return 0; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
static const struct snd_soc_dapm_widget simple_widgets[] = { SND_SOC_DAPM_MIC("Microphone", NULL),
The patch
ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_card_name
has been applied to the asoc tree at
git://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 b07609cecaac6681a2fca3eebc1bae7b00282620 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Fri, 27 Jan 2017 06:37:51 +0000 Subject: [PATCH] ASoC: soc-core: remove OF adjusting for snd_soc_of_parse_card_name
Because prototype of OF-graph sound card support didn't have Sound Card node, commit 8f5ebb1bee15b5720741a98414767bb86f6c2b23 ("ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name") adjusted to it on each functions.
But final discussion result of ALSA SoC / OF-graph ML, OF-graph sound card has node. Thus, this commit became no longer needed.
This reverts commit 8f5ebb1bee15b5720741a98414767bb86f6c2b23.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- include/sound/soc.h | 7 ++----- sound/soc/soc-core.c | 11 +++++------ 2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 34bd033443dc..6ecabeb8d31d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1644,11 +1644,8 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform( int snd_soc_util_init(void); void snd_soc_util_exit(void);
-#define snd_soc_of_parse_card_name(card, propname) \ - snd_soc_of_parse_card_name_from_node(card, NULL, propname) -int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname); +int snd_soc_of_parse_card_name(struct snd_soc_card *card, + const char *propname); int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, const char *propname); int snd_soc_of_parse_tdm_slot(struct device_node *np, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4ff2448f6023..ebaebc7c9699 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3492,10 +3492,10 @@ void snd_soc_unregister_codec(struct device *dev) EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
/* Retrieve a card's name from device tree */ -int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, - struct device_node *np, - const char *propname) +int snd_soc_of_parse_card_name(struct snd_soc_card *card, + const char *propname) { + struct device_node *np; int ret;
if (!card->dev) { @@ -3503,8 +3503,7 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, return -EINVAL; }
- if (!np) - np = card->dev->of_node; + np = card->dev->of_node;
ret = of_property_read_string_index(np, propname, 0, &card->name); /* @@ -3521,7 +3520,7 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
return 0; } -EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name_from_node); +EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
static const struct snd_soc_dapm_widget simple_widgets[] = { SND_SOC_DAPM_MIC("Microphone", NULL),
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Linux kernel already has of_graph_get_remote_port_parent(), but, sometimes we want to get own port parent. This patch adds of_graph_get_port_parent()
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- drivers/of/base.c | 30 ++++++++++++++++++++++-------- include/linux/of_graph.h | 7 +++++++ 2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c index 5391a9b5..b5bf79f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2440,6 +2440,27 @@ struct device_node *of_graph_get_remote_endpoint(const struct device_node *node) EXPORT_SYMBOL(of_graph_get_remote_endpoint);
/** + * of_graph_get_port_parent() - get port's parent node + * @node: pointer to a local endpoint device_node + * + * Return: device node associated with endpoint node linked + * to @node. Use of_node_put() on it when done. + */ +struct device_node *of_graph_get_port_parent(struct device_node *node) +{ + unsigned int depth; + + /* Walk 3 levels up only if there is 'ports' node. */ + for (depth = 3; depth && node; depth--) { + node = of_get_next_parent(node); + if (depth == 2 && of_node_cmp(node->name, "ports")) + break; + } + return node; +} +EXPORT_SYMBOL(of_graph_get_port_parent); + +/** * of_graph_get_remote_port_parent() - get remote port's parent node * @node: pointer to a local endpoint device_node * @@ -2450,18 +2471,11 @@ struct device_node *of_graph_get_remote_port_parent( const struct device_node *node) { struct device_node *np; - unsigned int depth;
/* Get remote endpoint node. */ np = of_graph_get_remote_endpoint(node);
- /* Walk 3 levels up only if there is 'ports' node. */ - for (depth = 3; depth && np; depth--) { - np = of_get_next_parent(np); - if (depth == 2 && of_node_cmp(np->name, "ports")) - break; - } - return np; + return of_graph_get_port_parent(np); } EXPORT_SYMBOL(of_graph_get_remote_port_parent);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h index d9d6d9c..80ced0c 100644 --- a/include/linux/of_graph.h +++ b/include/linux/of_graph.h @@ -50,6 +50,7 @@ struct device_node *of_graph_get_endpoint_by_regs( const struct device_node *parent, int port_reg, int reg); struct device_node *of_graph_get_remote_endpoint( const struct device_node *node); +struct device_node *of_graph_get_port_parent(struct device_node *node); struct device_node *of_graph_get_remote_port_parent( const struct device_node *node); struct device_node *of_graph_get_remote_port(const struct device_node *node); @@ -86,6 +87,12 @@ static inline struct device_node *of_graph_get_remote_endpoint( return NULL; }
+static inline struct device_node *of_graph_get_port_parent( + struct device_node *node) +{ + return NULL; +} + static inline struct device_node *of_graph_get_remote_port_parent( const struct device_node *node) {
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
OF graph want to count its endpoint number, same as of_get_child_count(). This patch adds of_graph_get_endpoint_count()
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- drivers/of/base.c | 12 ++++++++++++ include/linux/of_graph.h | 7 +++++++ 2 files changed, 19 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c index b5bf79f..199d3be 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2497,3 +2497,15 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node) return of_get_next_parent(np); } EXPORT_SYMBOL(of_graph_get_remote_port); + +int of_graph_get_endpoint_count(const struct device_node *np) +{ + struct device_node *endpoint; + int num = 0; + + for_each_endpoint_of_node(np, endpoint) + num++; + + return num; +} +EXPORT_SYMBOL(of_graph_get_endpoint_count); diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h index 80ced0c..40d6fd0 100644 --- a/include/linux/of_graph.h +++ b/include/linux/of_graph.h @@ -43,6 +43,7 @@ struct of_endpoint { #ifdef CONFIG_OF int of_graph_parse_endpoint(const struct device_node *node, struct of_endpoint *endpoint); +int of_graph_get_endpoint_count(const struct device_node *np); struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id); struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, struct device_node *previous); @@ -62,6 +63,12 @@ static inline int of_graph_parse_endpoint(const struct device_node *node, return -ENOSYS; }
+static inline int of_graph_get_endpoint_count(const struct device_node *np, + char *type) +{ + return 0; +} + static inline struct device_node *of_graph_get_port_by_id( struct device_node *node, u32 id) {
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
ALSA SoC needs to know connected DAI ID for probing. On OF-graph case, basically we can check DT port location.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 1 + sound/soc/soc-core.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h index e2ea305..67616d1 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1666,6 +1666,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, const char *prefix, struct device_node **bitclkmaster, struct device_node **framemaster); +int snd_soc_get_dai_id(struct device_node *ep); int snd_soc_get_dai_name(struct of_phandle_args *args, const char **dai_name); int snd_soc_of_get_dai_name(struct device_node *of_node, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 737765e..49ff615 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -34,6 +34,7 @@ #include <linux/ctype.h> #include <linux/slab.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <sound/core.h> #include <sound/jack.h> #include <sound/pcm.h> @@ -3852,6 +3853,28 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
+int snd_soc_get_dai_id(struct device_node *ep) +{ + struct device_node *node; + struct device_node *endpoint; + int i, id; + + node = of_graph_get_port_parent(ep); + + i = 0; + id = -1; + for_each_endpoint_of_node(node, endpoint) { + if (endpoint == ep) + id = i; + i++; + } + if (id < 0) + return -ENODEV; + + return id; +} +EXPORT_SYMBOL_GPL(snd_soc_get_dai_id); + int snd_soc_get_dai_name(struct of_phandle_args *args, const char **dai_name) {
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
simple-card already has asoc_simple_card_parse_dai(), but graph base parsing needs graph specific version of it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/simple_card_utils.h | 10 ++++++++++ sound/soc/generic/simple-card-utils.c | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index af58d23..efab584 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -60,6 +60,16 @@ int asoc_simple_card_parse_dai(struct device_node *node, const char *cells_name, int *is_single_links);
+#define asoc_simple_card_parse_graph_cpu(ep, dai_link) \ + asoc_simple_card_parse_graph_dai(ep, &dai_link->cpu_of_node, \ + &dai_link->cpu_dai_name) +#define asoc_simple_card_parse_graph_codec(ep, dai_link) \ + asoc_simple_card_parse_graph_dai(ep, &dai_link->codec_of_node, \ + &dai_link->codec_dai_name) +int asoc_simple_card_parse_graph_dai(struct device_node *ep, + struct device_node **endpoint_np, + const char **dai_name); + int asoc_simple_card_init_dai(struct snd_soc_dai *dai, struct asoc_simple_dai *simple_dai);
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 4924575..eb03030 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -10,6 +10,7 @@ #include <linux/clk.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <sound/simple_card_utils.h>
int asoc_simple_card_parse_daifmt(struct device *dev, @@ -164,6 +165,41 @@ int asoc_simple_card_parse_dai(struct device_node *node, } EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
+int asoc_simple_card_parse_graph_dai(struct device_node *ep, + struct device_node **dai_of_node, + const char **dai_name) +{ + struct device_node *node; + struct of_phandle_args args; + int ret; + + if (!ep) + return 0; + if (!dai_name) + return 0; + + /* + * of_graph_get_port_parent() will call + * of_node_put(). So, call of_node_get() here + */ + of_node_get(ep); + node = of_graph_get_port_parent(ep); + + /* Get dai->name */ + args.np = node; + args.args[0] = snd_soc_get_dai_id(ep); + args.args_count = (of_graph_get_endpoint_count(node) > 1); + + ret = snd_soc_get_dai_name(&args, dai_name); + if (ret < 0) + return ret; + + *dai_of_node = node; + + return 0; +} +EXPORT_SYMBOL_GPL(asoc_simple_card_parse_graph_dai); + int asoc_simple_card_init_dai(struct snd_soc_dai *dai, struct asoc_simple_dai *simple_dai) {
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- .../bindings/sound/simple-graph-card.txt | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-card.txt
diff --git a/Documentation/devicetree/bindings/sound/simple-graph-card.txt b/Documentation/devicetree/bindings/sound/simple-graph-card.txt new file mode 100644 index 0000000..5fa7b74 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/simple-graph-card.txt @@ -0,0 +1,137 @@ +Simple-Graph-Card: + +Simple-Graph-Card specifies audio DAI connections of SoC <-> codec. +It is based on common bindings for device graphs. +see ${LINUX}/Documentation/devicetree/bindings/graph.txt + +Basically, Simple-Graph-Card property is same as Simple-Card. +see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt + +Below are same as Simple-Card. + +- simple-audio-card,name +- simple-audio-card,format +- simple-audio-card,frame-master +- simple-audio-card,bitclock-master +- simple-audio-card,bitclock-inversion +- simple-audio-card,frame-inversion +- simple-audio-card,dai-tdm-slot-num +- simple-audio-card,dai-tdm-slot-width +- clocks / system-clock-frequency + +These should be implemented +- simple-audio-card,widgets +- simple-audio-card,routing +- simple-audio-card,mclk-fs +- simple-audio-card,hp-det-gpio +- simple-audio-card,mic-det-gpio + +Required properties: + +- compatible : "asoc-simple-graph-card"; +- dais : list of CPU DAI port{s} + +Example: Single DAI case + + sound_card: sound { + compatible = "asoc-simple-graph-card"; + + dais = <&cpu_port>; + }; + + codec { + ... + port { + codec_endpoint: endpoint { + remote-endpoint = <&cpu_endpoint>; + }; + }; + }; + + cpu { + ... + cpu_port: port@0 { + cpu_endpoint: endpoint { + remote-endpoint = <&codec_endpoint>; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&cpu_endpoint>; + simple-audio-card,frame-master = <&cpu_endpoint>; + ... + }; + }; + }; + +Example: Multi DAI case + + sound_card: sound { + compatible = "asoc-simple-graph-card"; + + dais = <&cpu_port0 + &cpu_port1 + &cpu_port2>; + }; + + codec0 { + ... + port { + codec0_endpoint: endpoint { + remote-endpoint = <&cpu_endpoint0>; + }; + }; + }; + + codec1 { + ... + port { + codec1_endpoint: endpoint { + remote-endpoint = <&cpu_endpoint1>; + }; + }; + }; + + codec2 { + ... + port { + codec2_endpoint: endpoint { + remote-endpoint = <&cpu_endpoint2>; + }; + }; + }; + + cpu { + ... + ports { + cpu_port0: port@0 { + cpu_endpoint0: endpoint { + remote-endpoint = <&codec0_endpoint>; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&cpu_endpoint0>; + simple-audio-card,frame-master = <&cpu_endpoint0>; + ... + }; + }; + cpu_port1: port@1 { + cpu_endpoint1: endpoint { + remote-endpoint = <&codec1_endpoint>; + + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&cpu_endpoint1>; + simple-audio-card,frame-master = <&cpu_endpoint1>; + ... + }; + }; + cpu_port2: port@2 { + cpu_endpoint2: endpoint { + remote-endpoint = <&codec2_endpoint>; + + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&cpu_endpoint2>; + simple-audio-card,frame-master = <&cpu_endpoint2>; + ... + }; + }; + }; + }; +
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
OF-graph base DT binding are used on V4L2, and ALSA SoC is using different style of DT today. Now ALSA SoC supports simple-card driver for generic/simple sound card. In the future, V4L2 / ALSA will support HDMI, and then, DT bindings between V4L2 / ALSA should be merged. This patch adds OF-graph base DT binding with simple-card style
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/Kconfig | 7 + sound/soc/generic/Makefile | 2 + sound/soc/generic/simple-graph-card.c | 303 ++++++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+) create mode 100644 sound/soc/generic/simple-graph-card.c
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index d023959..efefabd 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -14,3 +14,10 @@ config SND_SIMPLE_SCU_CARD help This option enables generic simple SCU sound card support. It supports DPCM of multi CPU single Codec system. + +config SND_SIMPLE_GRAPH_CARD + tristate "ASoC Simple Graph sound card support" + depends on OF + select SND_SIMPLE_CARD_UTILS + help + This option enables generic simple Graph sound card support diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index ee750f3..94eb6f1 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile @@ -1,7 +1,9 @@ snd-soc-simple-card-utils-objs := simple-card-utils.o snd-soc-simple-card-objs := simple-card.o snd-soc-simple-scu-card-objs := simple-scu-card.o +snd-soc-simple-graph-card-objs := simple-graph-card.o
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o obj-$(CONFIG_SND_SIMPLE_SCU_CARD) += snd-soc-simple-scu-card.o +obj-$(CONFIG_SND_SIMPLE_GRAPH_CARD) += snd-soc-simple-graph-card.o diff --git a/sound/soc/generic/simple-graph-card.c b/sound/soc/generic/simple-graph-card.c new file mode 100644 index 0000000..700717b --- /dev/null +++ b/sound/soc/generic/simple-graph-card.c @@ -0,0 +1,303 @@ +/* + * ASoC simple graph sound card support + * + * Copyright (C) 2016 Renesas Solutions Corp. + * Kuninori Morimoto kuninori.morimoto.gx@renesas.com + * + * based on ${LINUX}/sound/soc/generic/simple-card.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/gpio.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/of_graph.h> +#include <linux/platform_device.h> +#include <linux/string.h> +#include <sound/jack.h> +#include <sound/simple_card_utils.h> + +struct simple_card_data { + struct snd_soc_card snd_card; + struct simple_dai_props { + struct asoc_simple_dai cpu_dai; + struct asoc_simple_dai codec_dai; + } *dai_props; + struct snd_soc_dai_link *dai_link; +}; + +#define simple_priv_to_dev(priv) ((priv)->snd_card.dev) +#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) +#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) + +#define PREFIX "simple-audio-card," + +static int asoc_simple_card_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + 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); + int ret; + + ret = clk_prepare_enable(dai_props->cpu_dai.clk); + if (ret) + return ret; + + ret = clk_prepare_enable(dai_props->codec_dai.clk); + if (ret) + clk_disable_unprepare(dai_props->cpu_dai.clk); + + return ret; +} + +static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + 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); + + clk_disable_unprepare(dai_props->cpu_dai.clk); + + clk_disable_unprepare(dai_props->codec_dai.clk); +} + +static struct snd_soc_ops asoc_simple_card_ops = { + .startup = asoc_simple_card_startup, + .shutdown = asoc_simple_card_shutdown, +}; + +static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *codec = rtd->codec_dai; + struct snd_soc_dai *cpu = rtd->cpu_dai; + struct simple_dai_props *dai_props = + simple_priv_to_props(priv, rtd->num); + int ret; + + ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai); + if (ret < 0) + return ret; + + ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai); + if (ret < 0) + return ret; + + return 0; +} + +static int asoc_simple_card_dai_link_of(struct device_node *cpu_port, + struct simple_card_data *priv, + int idx) +{ + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); + struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai; + struct asoc_simple_dai *codec_dai = &dai_props->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); + struct device_node *rcpu_ep = of_graph_get_remote_endpoint(codec_ep); + int ret; + + if (rcpu_ep != cpu_ep) { + dev_err(dev, "remote-endpoint missmatch (%s/%s/%s)\n", + cpu_ep->name, codec_ep->name, rcpu_ep->name); + return -EINVAL; + } + + ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, + PREFIX, &dai_link->dai_fmt); + if (ret < 0) + goto dai_link_of_err; + + /* + * we need to consider "mclk-fs" around here + * see simple-card + */ + + ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link); + if (ret < 0) + goto dai_link_of_err; + + ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link); + if (ret < 0) + goto dai_link_of_err; + + ret = snd_soc_of_parse_tdm_slot(cpu_ep, + &cpu_dai->tx_slot_mask, + &cpu_dai->rx_slot_mask, + &cpu_dai->slots, + &cpu_dai->slot_width); + if (ret < 0) + goto dai_link_of_err; + + ret = snd_soc_of_parse_tdm_slot(codec_ep, + &codec_dai->tx_slot_mask, + &codec_dai->rx_slot_mask, + &codec_dai->slots, + &codec_dai->slot_width); + if (ret < 0) + goto dai_link_of_err; + + ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai); + if (ret < 0) + goto dai_link_of_err; + + ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai); + if (ret < 0) + goto dai_link_of_err; + + ret = asoc_simple_card_canonicalize_dailink(dai_link); + if (ret < 0) + goto dai_link_of_err; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "%s-%s", + dai_link->cpu_dai_name, + dai_link->codec_dai_name); + if (ret < 0) + goto dai_link_of_err; + + dai_link->ops = &asoc_simple_card_ops; + dai_link->init = asoc_simple_card_dai_init; + + dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); + dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt); + dev_dbg(dev, "\tcpu : %s / %d\n", + dai_link->cpu_dai_name, + dai_props->cpu_dai.sysclk); + dev_dbg(dev, "\tcodec : %s / %d\n", + dai_link->codec_dai_name, + dai_props->codec_dai.sysclk); + + asoc_simple_card_canonicalize_cpu(dai_link, + priv->snd_card.num_links == 1); + +dai_link_of_err: + of_node_put(codec_ep); + + return ret; +} + +static int asoc_simple_card_parse_of(struct device *dev, + struct simple_card_data *priv) +{ + struct device_node *node = dev->of_node; + struct snd_soc_card *card = &priv->snd_card; + struct device_node *np; + int idx = 0; + int ret; + + /* + * we need to consider "widgets", "routing", "mclk-fs" around here + * see simple-card + */ + + while ((np = of_parse_phandle(node, "dais", idx))) { + ret = asoc_simple_card_dai_link_of(np, priv, idx++); + if (ret < 0) + return ret; + } + + return asoc_simple_card_parse_card_name(card, PREFIX); +} + +static int asoc_simple_get_dais_count(struct device *dev) +{ + struct device_node *node = dev->of_node; + int count = 0; + + if (of_get_property(node, "dais", NULL)) { + while (of_parse_phandle(node, "dais", count)) + count++; + } else { + count = 1; + } + + return count; +} + +static int asoc_simple_card_probe(struct platform_device *pdev) +{ + struct simple_card_data *priv; + struct snd_soc_dai_link *dai_link; + struct simple_dai_props *dai_props; + struct device *dev = &pdev->dev; + int num, ret; + + /* Allocate the private data and the DAI link array */ + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + num = asoc_simple_get_dais_count(dev); + + dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL); + dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); + if (!dai_props || !dai_link) + return -ENOMEM; + + priv->dai_props = dai_props; + priv->dai_link = dai_link; + + /* Init snd_soc_card */ + priv->snd_card.owner = THIS_MODULE; + priv->snd_card.dev = dev; + priv->snd_card.dai_link = dai_link; + priv->snd_card.num_links = num; + + ret = asoc_simple_card_parse_of(dev, priv); + if (ret < 0) { + if (ret != -EPROBE_DEFER) + dev_err(dev, "parse error %d\n", ret); + goto err; + } + + snd_soc_card_set_drvdata(&priv->snd_card, priv); + + ret = devm_snd_soc_register_card(dev, &priv->snd_card); + if (ret >= 0) + return ret; +err: + asoc_simple_card_clean_reference(&priv->snd_card); + + return ret; +} + +static int asoc_simple_card_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct simple_card_data *priv = snd_soc_card_get_drvdata(card); + + return asoc_simple_card_clean_reference(&priv->snd_card); +} + +static const struct of_device_id asoc_simple_of_match[] = { + { .compatible = "asoc-simple-graph-card", }, + {}, +}; +MODULE_DEVICE_TABLE(of, asoc_simple_of_match); + +static struct platform_driver asoc_simple_card = { + .driver = { + .name = "asoc-simple-graph-card", + .of_match_table = asoc_simple_of_match, + }, + .probe = asoc_simple_card_probe, + .remove = asoc_simple_card_remove, +}; +module_platform_driver(asoc_simple_card); + +MODULE_ALIAS("platform:asoc-simple-graph-card"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ASoC Simple Graph Sound Card"); +MODULE_AUTHOR("Kuninori Morimoto kuninori.morimoto.gx@renesas.com");
participants (2)
-
Kuninori Morimoto
-
Mark Brown