* [PATCH v3 00/17] ASoC: add OF graph base simple-card
@ 2016-11-11 1:16 Kuninori Morimoto
2016-11-11 1:17 ` [PATCH v3 01/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name Kuninori Morimoto
` (16 more replies)
0 siblings, 17 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:16 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
Hi Rob, Mark
These are v3 of OF graph base simple-card patch-set.
1) - 5) : soc-core prepare for OF graph base simple-card
6) - 10) : OF graph new feature
11) - 17) : OF graph base simple-card (depends on above 2 patch-set)
>> Mark
I could success to apply 1) - 5) on your topic/core and topic/simple, both.
Please let me know if you can't do it.
*** BLURB HERE ***
Kuninori Morimoto (17):
1) ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name
2) ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets
3) ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing
4) ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix
5) ASoC: soc-core: snd_soc_get_dai_name() become non static
6) of_graph: add of_graph_get_remote_endpoint()
7) of_graph: add of_graph_get_port_parent()
8) of_graph: add of_graph_get_top_port()
9) of_graph: add for_each_of_port() / for_each_of_endpoint_in_port()
10) of_graph: add of_graph_get_port/endpoint_count()
11) ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
12) ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card()
13) ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name
14) ASoC: add simple-graph-card document
15) ASoC: add simple-graph-card support
16) ASoC: add simple-graph-scu-card document
17) ASoC: add simple-graph-scu-card support
.../bindings/sound/simple-graph-card.txt | 65 +++
.../bindings/sound/simple-graph-scu-card.txt | 65 +++
drivers/of/base.c | 160 ++++++-
include/linux/of_graph.h | 54 +++
include/sound/simple_card_utils.h | 19 +
include/sound/soc.h | 32 +-
sound/soc/generic/Kconfig | 15 +
sound/soc/generic/Makefile | 4 +
sound/soc/generic/simple-card-utils.c | 98 ++++-
sound/soc/generic/simple-card.c | 2 +-
sound/soc/generic/simple-graph-card.c | 462 +++++++++++++++++++++
sound/soc/generic/simple-graph-scu-card.c | 417 +++++++++++++++++++
sound/soc/generic/simple-scu-card.c | 2 +-
sound/soc/soc-core.c | 41 +-
14 files changed, 1401 insertions(+), 35 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-card.txt
create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
create mode 100644 sound/soc/generic/simple-graph-card.c
create mode 100644 sound/soc/generic/simple-graph-scu-card.c
--
1.9.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 01/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
@ 2016-11-11 1:17 ` Kuninori Morimoto
2016-11-11 1:18 ` [PATCH v3 02/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets Kuninori Morimoto
` (15 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:17 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
include/sound/soc.h | 7 +++++--
sound/soc/soc-core.c | 11 ++++++-----
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 91a8a03..7fff456 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1642,8 +1642,11 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
int snd_soc_util_init(void);
void snd_soc_util_exit(void);
-int snd_soc_of_parse_card_name(struct snd_soc_card *card,
- const char *propname);
+#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_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 c0bbcd9..088a158 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3424,10 +3424,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(struct snd_soc_card *card,
- const char *propname)
+int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
+ struct device_node *np,
+ const char *propname)
{
- struct device_node *np;
int ret;
if (!card->dev) {
@@ -3435,7 +3435,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
return -EINVAL;
}
- np = card->dev->of_node;
+ if (!np)
+ np = card->dev->of_node;
ret = of_property_read_string_index(np, propname, 0, &card->name);
/*
@@ -3452,7 +3453,7 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
return 0;
}
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name_from_node);
static const struct snd_soc_dapm_widget simple_widgets[] = {
SND_SOC_DAPM_MIC("Microphone", NULL),
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 02/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
2016-11-11 1:17 ` [PATCH v3 01/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name Kuninori Morimoto
@ 2016-11-11 1:18 ` Kuninori Morimoto
2016-11-11 1:18 ` [PATCH v3 03/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing Kuninori Morimoto
` (14 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:18 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
include/sound/soc.h | 8 ++++++--
sound/soc/soc-core.c | 9 ++++++---
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 7fff456..a091c66 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1647,8 +1647,12 @@ 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);
-int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
- 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_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 088a158..e56ea42 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3462,14 +3462,17 @@ 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(struct snd_soc_card *card,
+int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
+ struct device_node *np,
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,
@@ -3540,7 +3543,7 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
return 0;
}
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets_from_node);
static int snd_soc_of_get_slot_mask(struct device_node *np,
const char *prop_name,
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 03/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
2016-11-11 1:17 ` [PATCH v3 01/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name Kuninori Morimoto
2016-11-11 1:18 ` [PATCH v3 02/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets Kuninori Morimoto
@ 2016-11-11 1:18 ` Kuninori Morimoto
2016-11-11 1:19 ` [PATCH v3 04/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix Kuninori Morimoto
` (13 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:18 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
include/sound/soc.h | 9 +++++++--
sound/soc/soc-core.c | 9 ++++++---
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index a091c66..f276f69 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1662,8 +1662,13 @@ 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);
-int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
- 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);
+
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 e56ea42..79a1045 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3619,14 +3619,17 @@ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix);
-int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
+int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
+ struct device_node *np,
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,
@@ -3673,7 +3676,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
return 0;
}
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing_from_node);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
const char *prefix,
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 04/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (2 preceding siblings ...)
2016-11-11 1:18 ` [PATCH v3 03/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing Kuninori Morimoto
@ 2016-11-11 1:19 ` Kuninori Morimoto
2016-11-11 1:19 ` [PATCH v3 05/17] ASoC: soc-core: snd_soc_get_dai_name() become non static Kuninori Morimoto
` (12 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:19 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
include/sound/soc.h | 6 +++++-
sound/soc/soc-core.c | 9 ++++++---
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index f276f69..60ac25d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1658,7 +1658,11 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
unsigned int *rx_mask,
unsigned int *slots,
unsigned int *slot_width);
-void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
+#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,
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 79a1045..8371488 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3599,15 +3599,18 @@ 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(struct snd_soc_card *card,
+void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
+ struct device_node *np,
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 */
@@ -3617,7 +3620,7 @@ void snd_soc_of_parse_audio_prefix(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);
+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,
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 05/17] ASoC: soc-core: snd_soc_get_dai_name() become non static
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (3 preceding siblings ...)
2016-11-11 1:19 ` [PATCH v3 04/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix Kuninori Morimoto
@ 2016-11-11 1:19 ` Kuninori Morimoto
2016-11-11 1:19 ` [PATCH v3 06/17] of_graph: add of_graph_get_remote_endpoint() Kuninori Morimoto
` (11 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:19 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
snd_soc_get_dai_name() is used from snd_soc_of_get_dai_name(),
and it is assuming that DT is using "sound-dai" / "#sound-dai-cells".
But graph base DT is using "remote-endpoint". This patch makes
snd_soc_get_dai_name() non static for graph support.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
include/sound/soc.h | 2 ++
sound/soc/soc-core.c | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 60ac25d..218e3fb 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1677,6 +1677,8 @@ 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_name(struct of_phandle_args *args,
+ const char **dai_name);
int snd_soc_of_get_dai_name(struct device_node *of_node,
const char **dai_name);
int snd_soc_of_get_dai_link_codecs(struct device *dev,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 8371488..6f911f4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3794,7 +3794,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
-static int snd_soc_get_dai_name(struct of_phandle_args *args,
+int snd_soc_get_dai_name(struct of_phandle_args *args,
const char **dai_name)
{
struct snd_soc_component *pos;
@@ -3846,6 +3846,7 @@ static int snd_soc_get_dai_name(struct of_phandle_args *args,
mutex_unlock(&client_mutex);
return ret;
}
+EXPORT_SYMBOL_GPL(snd_soc_get_dai_name);
int snd_soc_of_get_dai_name(struct device_node *of_node,
const char **dai_name)
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 06/17] of_graph: add of_graph_get_remote_endpoint()
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (4 preceding siblings ...)
2016-11-11 1:19 ` [PATCH v3 05/17] ASoC: soc-core: snd_soc_get_dai_name() become non static Kuninori Morimoto
@ 2016-11-11 1:19 ` Kuninori Morimoto
2016-11-11 1:20 ` [PATCH v3 07/17] of_graph: add of_graph_get_port_parent() Kuninori Morimoto
` (10 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:19 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
It should use same method to get same result.
To getting remote-endpoint node,
let's use of_graph_get_remote_endpoint()
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
drivers/of/base.c | 18 ++++++++++++++++--
include/linux/of_graph.h | 8 ++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d687e6d..810acf4 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2425,6 +2425,20 @@ struct device_node *of_graph_get_endpoint_by_regs(
EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
/**
+ * of_graph_get_remote_endpoint() - get remote endpoint node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote endpoint node associated with remote endpoint node linked
+ * to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
+{
+ /* Get remote endpoint node. */
+ return of_parse_phandle(node, "remote-endpoint", 0);
+}
+EXPORT_SYMBOL(of_graph_get_remote_endpoint);
+
+/**
* of_graph_get_remote_port_parent() - get remote port's parent node
* @node: pointer to a local endpoint device_node
*
@@ -2438,7 +2452,7 @@ struct device_node *of_graph_get_remote_port_parent(
unsigned int depth;
/* Get remote endpoint node. */
- np = of_parse_phandle(node, "remote-endpoint", 0);
+ np = of_graph_get_remote_endpoint(node);
/* Walk 3 levels up only if there is 'ports' node. */
for (depth = 3; depth && np; depth--) {
@@ -2462,7 +2476,7 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
struct device_node *np;
/* Get remote endpoint node. */
- np = of_parse_phandle(node, "remote-endpoint", 0);
+ np = of_graph_get_remote_endpoint(node);
if (!np)
return NULL;
return of_get_next_parent(np);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index bb3a5a2..d9d6d9c 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -48,6 +48,8 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
struct device_node *previous);
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_remote_port_parent(
const struct device_node *node);
struct device_node *of_graph_get_remote_port(const struct device_node *node);
@@ -78,6 +80,12 @@ static inline struct device_node *of_graph_get_endpoint_by_regs(
return NULL;
}
+static inline struct device_node *of_graph_get_remote_endpoint(
+ const struct device_node *node)
+{
+ return NULL;
+}
+
static inline struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node)
{
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 07/17] of_graph: add of_graph_get_port_parent()
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (5 preceding siblings ...)
2016-11-11 1:19 ` [PATCH v3 06/17] of_graph: add of_graph_get_remote_endpoint() Kuninori Morimoto
@ 2016-11-11 1:20 ` Kuninori Morimoto
2016-11-11 1:20 ` [PATCH v3 08/17] of_graph: add of_graph_get_top_port() Kuninori Morimoto
` (9 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:20 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
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>
---
v2 -> v3
- no change
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 810acf4..fed0b023 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2439,6 +2439,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
*
@@ -2449,18 +2470,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)
{
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 08/17] of_graph: add of_graph_get_top_port()
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (6 preceding siblings ...)
2016-11-11 1:20 ` [PATCH v3 07/17] of_graph: add of_graph_get_port_parent() Kuninori Morimoto
@ 2016-11-11 1:20 ` Kuninori Morimoto
2016-11-11 1:21 ` [PATCH v3 09/17] of_graph: add for_each_of_port() / for_each_of_endpoint_in_port() Kuninori Morimoto
` (8 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:20 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
driver want to get top level of port[s] node. This patch adds
of_graph_get_top_port() for this purpose
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
drivers/of/base.c | 24 ++++++++++++++++++++++++
include/linux/of_graph.h | 2 ++
2 files changed, 26 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index fed0b023..e49eb28 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2330,6 +2330,30 @@ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
EXPORT_SYMBOL(of_graph_get_port_by_id);
/**
+ * of_graph_get_top_port() - get the top port node
+ * @dev: pointer to the device
+ *
+ * Return: A 'port' node pointer with refcount incremented. The caller
+ * has to use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_top_port(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct device_node *node;
+
+ node = of_get_child_by_name(np, "ports");
+ if (node)
+ return node;
+
+ node = of_get_child_by_name(np, "port");
+ if (node)
+ return node;
+
+ return NULL;
+}
+EXPORT_SYMBOL(of_graph_get_top_port);
+
+/**
* of_graph_get_next_endpoint() - get next endpoint node
* @parent: pointer to the parent device node
* @prev: previous endpoint node, or NULL to get first
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 80ced0c..ee823c6 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -14,6 +14,7 @@
#ifndef __LINUX_OF_GRAPH_H
#define __LINUX_OF_GRAPH_H
+#include <linux/device.h>
#include <linux/types.h>
#include <linux/errno.h>
@@ -44,6 +45,7 @@ struct of_endpoint {
int of_graph_parse_endpoint(const struct device_node *node,
struct of_endpoint *endpoint);
struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
+struct device_node *of_graph_get_top_port(struct device *dev);
struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
struct device_node *previous);
struct device_node *of_graph_get_endpoint_by_regs(
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 09/17] of_graph: add for_each_of_port() / for_each_of_endpoint_in_port()
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (7 preceding siblings ...)
2016-11-11 1:20 ` [PATCH v3 08/17] of_graph: add of_graph_get_top_port() Kuninori Morimoto
@ 2016-11-11 1:21 ` Kuninori Morimoto
2016-11-11 1:21 ` [PATCH v3 10/17] of_graph: add of_graph_get_port/endpoint_count() Kuninori Morimoto
` (7 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:21 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
OF graph is used mainly from V4L2, but ALSA needs to use it. It already
has for_each_endpoint_of_node() which is for-loop for each endpoint.
But, ALSA needs for-loop for each port[s], and for-loop for each
endpoint of inside port[s]. This patch adds for_each_of_port()
and for_each_of_endpoint_in_port() for this purpose.
And it also adds for_each_of_endpoint() which is similar to
for_each_endpoint_of_node(). The difference is it can catch port
handle during for-loop.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
drivers/of/base.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of_graph.h | 29 ++++++++++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index e49eb28..b11f533 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2354,6 +2354,70 @@ struct device_node *of_graph_get_top_port(struct device *dev)
EXPORT_SYMBOL(of_graph_get_top_port);
/**
+ * of_graph_get_next_port() - get next port node
+ * @parent: pointer to the parent device node
+ * @prev: previous endpoint node, or NULL to get first
+ *
+ * Return: An 'endpoint' node pointer with refcount incremented. Refcount
+ * of the passed @prev node is decremented.
+ */
+struct device_node *of_graph_get_next_port(const struct device_node *parent,
+ struct device_node *prev)
+{
+ struct device_node *port;
+ struct device_node *node;
+
+ if (!parent)
+ return NULL;
+
+ node = of_get_child_by_name(parent, "ports");
+ if (node)
+ parent = node;
+
+ /*
+ * Start by locating the port node. If no previous endpoint is specified
+ * search for the first port node, otherwise get the previous endpoint
+ * parent port node.
+ */
+ if (!prev) {
+ port = of_get_child_by_name(parent, "port");
+ if (!port)
+ pr_err("%s(): no port node found in %s\n",
+ __func__, parent->full_name);
+ } else {
+ do {
+ port = of_get_next_child(parent, prev);
+ if (!port)
+ break;
+ } while (of_node_cmp(port->name, "port"));
+ }
+
+ of_node_put(node);
+
+ return port;
+}
+EXPORT_SYMBOL(of_graph_get_next_port);
+
+/**
+ * of_graph_get_next_endpoint_in_port() - get next endpoint node in port
+ * @parent: pointer to the parent device node
+ * @prev: previous endpoint node, or NULL to get first
+ *
+ * Return: An 'endpoint' node pointer with refcount incremented. Refcount
+ * of the passed @prev node is decremented.
+ */
+struct device_node *of_graph_get_next_endpoint_in_port(
+ const struct device_node *port,
+ struct device_node *prev)
+{
+ if (!port)
+ return NULL;
+
+ return of_get_next_child(port, prev);
+}
+EXPORT_SYMBOL(of_graph_get_next_endpoint_in_port);
+
+/**
* of_graph_get_next_endpoint() - get next endpoint node
* @parent: pointer to the parent device node
* @prev: previous endpoint node, or NULL to get first
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index ee823c6..3de036f 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -30,6 +30,16 @@ struct of_endpoint {
const struct device_node *local_node;
};
+#define for_each_of_port(parent, port) \
+ for (port = of_graph_get_next_port(parent, NULL); port != NULL; \
+ port = of_graph_get_next_port(parent, port))
+#define for_each_of_endpoint_in_port(port, ep) \
+ for (ep = of_graph_get_next_endpoint_in_port(port, NULL); ep != NULL; \
+ ep = of_graph_get_next_endpoint_in_port(port, ep))
+#define for_each_of_endpoint(parent, port, ep) \
+ for_each_of_port(parent, port) \
+ for_each_of_endpoint_in_port(port, ep)
+
/**
* for_each_endpoint_of_node - iterate over every endpoint in a device node
* @parent: parent device node containing ports and endpoints
@@ -46,6 +56,11 @@ int of_graph_parse_endpoint(const struct device_node *node,
struct of_endpoint *endpoint);
struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
struct device_node *of_graph_get_top_port(struct device *dev);
+struct device_node *of_graph_get_next_port(const struct device_node *parent,
+ struct device_node *prev);
+struct device_node *of_graph_get_next_endpoint_in_port(
+ const struct device_node *port,
+ struct device_node *prev);
struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
struct device_node *previous);
struct device_node *of_graph_get_endpoint_by_regs(
@@ -70,6 +85,20 @@ static inline struct device_node *of_graph_get_port_by_id(
return NULL;
}
+static inline struct device_node *of_graph_get_next_port(
+ const struct device_node *parent,
+ struct device_node *prev)
+{
+ return NULL;
+}
+
+static inline struct device_node *of_graph_get_next_endpoint_in_port(
+ const struct device_node *port,
+ struct device_node *prev)
+{
+ return NULL;
+}
+
static inline struct device_node *of_graph_get_next_endpoint(
const struct device_node *parent,
struct device_node *previous)
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 10/17] of_graph: add of_graph_get_port/endpoint_count()
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (8 preceding siblings ...)
2016-11-11 1:21 ` [PATCH v3 09/17] of_graph: add for_each_of_port() / for_each_of_endpoint_in_port() Kuninori Morimoto
@ 2016-11-11 1:21 ` Kuninori Morimoto
2016-11-11 1:21 ` [PATCH v3 11/17] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai() Kuninori Morimoto
` (6 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:21 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
OF graph want to count its port/endpoint number, same as
of_get_child_count(). This patch adds these functions.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
drivers/of/base.c | 24 ++++++++++++++++++++++++
include/linux/of_graph.h | 8 ++++++++
2 files changed, 32 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index b11f533..e795d0f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2584,3 +2584,27 @@ 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_port_count(const struct device_node *np)
+{
+ struct device_node *port;
+ int num = 0;
+
+ for_each_of_port(np, port)
+ num++;
+
+ return num;
+}
+EXPORT_SYMBOL(of_graph_get_port_count);
+
+int of_graph_get_endpoint_count(const struct device_node *np)
+{
+ struct device_node *port, *endpoint;
+ int num = 0;
+
+ for_each_of_endpoint(np, port, 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 3de036f..c060a7c 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -54,6 +54,8 @@ struct of_endpoint {
#ifdef CONFIG_OF
int of_graph_parse_endpoint(const struct device_node *node,
struct of_endpoint *endpoint);
+int of_graph_get_port_count(const struct device_node *np);
+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_top_port(struct device *dev);
struct device_node *of_graph_get_next_port(const struct device_node *parent,
@@ -79,6 +81,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)
{
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 11/17] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (9 preceding siblings ...)
2016-11-11 1:21 ` [PATCH v3 10/17] of_graph: add of_graph_get_port/endpoint_count() Kuninori Morimoto
@ 2016-11-11 1:21 ` Kuninori Morimoto
2016-11-11 1:22 ` [PATCH v3 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card() Kuninori Morimoto
` (5 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:21 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
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>
---
v2 -> v3
- no change
include/sound/simple_card_utils.h | 10 +++++++
sound/soc/generic/simple-card-utils.c | 50 +++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index fd641255..4b58954 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -59,6 +59,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 e5b80f5..373ada3 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,55 @@ 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, *port, *endpoint;
+ int i, id;
+
+ if (!ep)
+ 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);
+
+ i = 0;
+ id = -1;
+ for_each_of_port(node, port) {
+ for_each_of_endpoint_in_port(port, endpoint) {
+ if (endpoint == ep)
+ id = i;
+ i++;
+ }
+ }
+ if (id < 0)
+ return -ENODEV;
+
+ /* Get dai->name */
+ if (dai_name) {
+ struct of_phandle_args args;
+ int ret;
+
+ args.np = node;
+ args.args[0] = id;
+ args.args_count = (i > 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)
{
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card()
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (10 preceding siblings ...)
2016-11-11 1:21 ` [PATCH v3 11/17] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai() Kuninori Morimoto
@ 2016-11-11 1:22 ` Kuninori Morimoto
2016-11-11 2:07 ` kbuild test robot
2016-11-11 1:22 ` [PATCH v3 13/17] ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name Kuninori Morimoto
` (4 subsequent siblings)
16 siblings, 1 reply; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:22 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
If CPU/Platform side driver probes successfully, and if it is supporting
both previous normal sound card style and graph style DT, it can call
asoc_simple_card_try_to_probe_graph_card().
It checks graph style DT, and do nothing if it was non graph style DT,
or register new simple-graph-card driver if graph style DT.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
include/sound/simple_card_utils.h | 8 +++++++
sound/soc/generic/simple-card-utils.c | 45 +++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 4b58954..7006150 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -22,6 +22,10 @@ struct asoc_simple_dai {
struct clk *clk;
};
+struct asoc_simple_graph_card_info {
+ int endpoint_num; /* sound endpoint number */
+};
+
int asoc_simple_card_parse_daifmt(struct device *dev,
struct device_node *node,
struct device_node *codec,
@@ -78,4 +82,8 @@ void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
int asoc_simple_card_clean_reference(struct snd_soc_card *card);
+void asoc_simple_card_try_to_probe_graph_card(struct device *dev,
+ struct asoc_simple_graph_card_info *info);
+
+
#endif /* __SIMPLE_CARD_CORE_H */
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 373ada3..85120f5 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
@@ -285,6 +286,50 @@ int asoc_simple_card_clean_reference(struct snd_soc_card *card)
}
EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference);
+void asoc_simple_card_try_to_probe_graph_card(struct device *dev,
+ struct asoc_simple_graph_card_info *info)
+{
+ struct platform_device_info pdevinfo;
+ struct device_node *node;
+ const char *compatible;
+ int ret;
+
+ node = of_graph_get_top_port(dev);
+ if (!node || !info)
+ /*
+ * It doesn't have graph base sound DT, or its infomation.
+ * Do nothing here, It assumes that system has
+ * normal sound card.
+ */
+ return;
+
+ ret = of_property_read_string(node, "compatible", &compatible);
+ if (ret < 0)
+ goto probe_err;
+
+ /*
+ * FIXME
+ *
+ * It should use of_platform_xxx() instead of
+ * platform_device_register_full() ? but there is no solution.
+ * see also
+ * linux/sound/soc/generic/simple-graph-card.c :: asoc_simple_card_probe
+ */
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo.parent = dev;
+ pdevinfo.id = PLATFORM_DEVID_AUTO;
+ pdevinfo.name = compatible;
+ pdevinfo.dma_mask = DMA_BIT_MASK(32);
+ pdevinfo.data = info;
+ pdevinfo.size_data = sizeof(*info);
+ platform_device_register_full(&pdevinfo);
+
+probe_err:
+ of_node_put(node);
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_try_to_probe_graph_card);
+
/* Module information */
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 13/17] ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (11 preceding siblings ...)
2016-11-11 1:22 ` [PATCH v3 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card() Kuninori Morimoto
@ 2016-11-11 1:22 ` Kuninori Morimoto
2016-11-11 1:23 ` [PATCH v3 14/17] ASoC: add simple-graph-card document Kuninori Morimoto
` (3 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:22 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
include/sound/simple_card_utils.h | 1 +
sound/soc/generic/simple-card-utils.c | 3 ++-
sound/soc/generic/simple-card.c | 2 +-
sound/soc/generic/simple-scu-card.c | 2 +-
4 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 7006150..afca6bd 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -36,6 +36,7 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
struct snd_soc_dai_link *dai_link,
const char *fmt, ...);
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
+ struct device_node *node,
char *prefix);
#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 85120f5..604f1f9 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -81,6 +81,7 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
EXPORT_SYMBOL_GPL(asoc_simple_card_set_dailink_name);
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
+ struct device_node *node,
char *prefix)
{
char prop[128];
@@ -89,7 +90,7 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
snprintf(prop, sizeof(prop), "%sname", prefix);
/* Parse the card name from DT */
- ret = snd_soc_of_parse_card_name(card, prop);
+ ret = snd_soc_of_parse_card_name_from_node(card, node, prop);
if (ret < 0)
return ret;
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index f608f8d2..342ff53 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -401,7 +401,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
goto card_parse_end;
}
- ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
+ ret = asoc_simple_card_parse_card_name(&priv->snd_card, NULL, PREFIX);
if (ret < 0)
goto card_parse_end;
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index 348e9a7..a8164a2 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -239,7 +239,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
i++;
}
- ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
+ ret = asoc_simple_card_parse_card_name(&priv->snd_card, NULL, PREFIX);
if (ret < 0)
return ret;
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 14/17] ASoC: add simple-graph-card document
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (12 preceding siblings ...)
2016-11-11 1:22 ` [PATCH v3 13/17] ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name Kuninori Morimoto
@ 2016-11-11 1:23 ` Kuninori Morimoto
2016-11-11 1:24 ` [PATCH v3 15/17] ASoC: add simple-graph-card support Kuninori Morimoto
` (2 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:23 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- Added how to use Simple-Graph-Card, and cleanup
.../bindings/sound/simple-graph-card.txt | 65 ++++++++++++++++++++++
1 file changed, 65 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..11823b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/simple-graph-card.txt
@@ -0,0 +1,65 @@
+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,widgets
+- simple-audio-card,routing
+- simple-audio-card,mclk-fs
+- simple-audio-card,hp-det-gpio
+- simple-audio-card,mic-det-gpio
+- 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,mclk-fs
+- simple-audio-card,dai-tdm-slot-num
+- simple-audio-card,dai-tdm-slot-width
+- clocks / system-clock-frequency
+
+In Simple-Graph-Card, above properties need in CPU side port on DT.
+And it needs to have "compatible" property too.
+In addition, CPU side driver needs to call asoc_simple_card_try_to_probe_graph_card().
+It will probe specified Card driver if it could find "compatible" property on port.
+Otherwise, it will do nothing.
+
+Required properties:
+
+- compatible : "asoc-simple-graph-card";
+
+Example
+
+ak4643: codec@12 {
+ compatible = "asahi-kasei,ak4643";
+ ...
+ port {
+ ak4643_port: endpoint {
+ remote-endpoint = <&rcar_ak4643_port>;
+ clocks = <&audio_clock>;
+ };
+ };
+};
+
+rcar_sound {
+ ...
+ port {
+ compatible = "asoc-simple-graph-card";
+
+ simple-audio-card,format = "left_j";
+ simple-audio-card,bitclock-master = <&ak4643_port>;
+ simple-audio-card,frame-master = <&ak4643_port>;
+
+ rcar_ak4643_port: endpoint {
+ remote-endpoint = <&ak4643_port>;
+ ...
+ };
+ };
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 15/17] ASoC: add simple-graph-card support
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (13 preceding siblings ...)
2016-11-11 1:23 ` [PATCH v3 14/17] ASoC: add simple-graph-card document Kuninori Morimoto
@ 2016-11-11 1:24 ` Kuninori Morimoto
2016-11-11 1:24 ` [PATCH v3 16/17] ASoC: add simple-graph-scu-card document Kuninori Morimoto
2016-11-11 1:25 ` [PATCH v3 17/17] ASoC: add simple-graph-scu-card support Kuninori Morimoto
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:24 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
graph base DT binding are used on V4L2, and ALSA SoC is using different
style of DT. In case of simple case, ALSA SoC supports simple-card
driver.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged somehow.
This patch adds graph base DT binding with simple-card style
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
sound/soc/generic/Kconfig | 7 +
sound/soc/generic/Makefile | 2 +
sound/soc/generic/simple-graph-card.c | 462 ++++++++++++++++++++++++++++++++++
3 files changed, 471 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..a98b13f
--- /dev/null
+++ b/sound/soc/generic/simple-graph-card.c
@@ -0,0 +1,462 @@
+/*
+ * 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 asoc_simple_jack {
+ struct snd_soc_jack jack;
+ struct snd_soc_jack_pin pin;
+ struct snd_soc_jack_gpio gpio;
+};
+
+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;
+ unsigned int mclk_fs;
+ } *dai_props;
+ struct asoc_simple_jack hp_jack;
+ struct asoc_simple_jack mic_jack;
+ struct snd_soc_dai_link *dai_link;
+ unsigned int mclk_fs;
+};
+
+#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,"
+
+#define asoc_simple_card_init_hp(card, node, sjack, prefix) \
+ asoc_simple_card_init_jack(card, node, sjack, 1, prefix)
+#define asoc_simple_card_init_mic(card, node, sjack, prefix) \
+ asoc_simple_card_init_jack(card, node, sjack, 0, prefix)
+static int asoc_simple_card_init_jack(struct snd_soc_card *card,
+ struct device_node *node,
+ struct asoc_simple_jack *sjack,
+ int is_hp, char *prefix)
+{
+ enum of_gpio_flags flags;
+ char prop[128];
+ char *pin_name;
+ char *gpio_name;
+ int mask;
+ int det;
+
+ sjack->gpio.gpio = -ENOENT;
+
+ if (is_hp) {
+ snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
+ pin_name = "Headphones";
+ gpio_name = "Headphone detection";
+ mask = SND_JACK_HEADPHONE;
+ } else {
+ snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
+ pin_name = "Mic Jack";
+ gpio_name = "Mic detection";
+ mask = SND_JACK_MICROPHONE;
+ }
+
+ det = of_get_named_gpio_flags(node, prop, 0, &flags);
+ if (det == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ if (gpio_is_valid(det)) {
+ sjack->pin.pin = pin_name;
+ sjack->pin.mask = mask;
+
+ sjack->gpio.name = gpio_name;
+ sjack->gpio.report = mask;
+ sjack->gpio.gpio = det;
+ sjack->gpio.invert = !!(flags & OF_GPIO_ACTIVE_LOW);
+ sjack->gpio.debounce_time = 150;
+
+ snd_soc_card_jack_new(card, pin_name, mask,
+ &sjack->jack,
+ &sjack->pin, 1);
+
+ snd_soc_jack_add_gpios(&sjack->jack, 1,
+ &sjack->gpio);
+ }
+
+ return 0;
+}
+
+static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack)
+{
+ if (gpio_is_valid(sjack->gpio.gpio))
+ snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio);
+}
+
+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 int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ 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);
+ unsigned int mclk, mclk_fs = 0;
+ int ret = 0;
+
+ if (priv->mclk_fs)
+ mclk_fs = priv->mclk_fs;
+ else if (dai_props->mclk_fs)
+ mclk_fs = dai_props->mclk_fs;
+
+ if (mclk_fs) {
+ mclk = params_rate(params) * mclk_fs;
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+ SND_SOC_CLOCK_IN);
+ if (ret && ret != -ENOTSUPP)
+ goto err;
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+ SND_SOC_CLOCK_OUT);
+ if (ret && ret != -ENOTSUPP)
+ goto err;
+ }
+ return 0;
+err:
+ return ret;
+}
+
+static struct snd_soc_ops asoc_simple_card_ops = {
+ .startup = asoc_simple_card_startup,
+ .shutdown = asoc_simple_card_shutdown,
+ .hw_params = asoc_simple_card_hw_params,
+};
+
+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 device *dev = simple_priv_to_dev(priv);
+ struct device *cpu_dev = dev->parent;
+ struct snd_soc_dai *codec = rtd->codec_dai;
+ struct snd_soc_dai *cpu = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct simple_dai_props *dai_props =
+ simple_priv_to_props(priv, rtd->num);
+ struct device_node *cpu_port = of_graph_get_top_port(cpu_dev);
+ 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;
+
+ ret = asoc_simple_card_init_hp(card, cpu_port, &priv->hp_jack, PREFIX);
+ if (ret < 0)
+ return ret;
+
+ ret = asoc_simple_card_init_mic(card, cpu_port, &priv->hp_jack, PREFIX);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int asoc_simple_card_dai_link_of(struct device_node *cpu_ep,
+ 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_port;
+ struct device_node *cpu_remote_ep;
+ struct device_node *codec_ep;
+ int ret;
+
+ codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+ cpu_remote_ep = of_graph_get_remote_endpoint(codec_ep);
+
+ if (cpu_ep != cpu_remote_ep) {
+ dev_err(dev, "endpoint parse error\n");
+ ret = -EINVAL;
+ goto dai_link_of_err;
+ }
+
+ cpu_port = cpu_ep->parent;
+
+ ret = asoc_simple_card_parse_daifmt(dev, cpu_port, codec_ep,
+ PREFIX, &dai_link->dai_fmt);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ of_property_read_u32(cpu_port, "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;
+
+ 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(cpu_ep, dai_link, cpu_dai);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_parse_clk_codec(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);
+ of_node_put(cpu_remote_ep);
+
+ return ret;
+}
+
+static int asoc_simple_card_parse_of(struct device_node *node,
+ struct simple_card_data *priv)
+{
+ struct device *dev = simple_priv_to_dev(priv);
+ struct device *cpu_dev = dev->parent;
+ struct device_node *top_port = of_graph_get_top_port(cpu_dev);
+ struct snd_soc_card *card = &priv->snd_card;
+ struct device_node *port, *ep;
+ int i = 0, ret;
+
+ if (!node)
+ return -EINVAL;
+
+ for_each_of_port(node, port) {
+ /* The off-codec widgets */
+ if (of_property_read_bool(port, PREFIX "widgets")) {
+ ret = snd_soc_of_parse_audio_simple_widgets_from_node(
+ &priv->snd_card,
+ port, PREFIX "widgets");
+ if (ret)
+ return ret;
+ }
+
+ /* DAPM routes */
+ if (of_property_read_bool(port, PREFIX "routing")) {
+ ret = snd_soc_of_parse_audio_routing_from_node(
+ &priv->snd_card,
+ port, PREFIX "routing");
+ if (ret)
+ return ret;
+ }
+
+ /* Factor to mclk, used in hw_params() */
+ of_property_read_u32(port, PREFIX "mclk-fs", &priv->mclk_fs);
+
+ for_each_of_endpoint_in_port(port, ep) {
+ ret = asoc_simple_card_dai_link_of(ep, priv, i);
+ if (ret < 0) {
+ of_node_put(ep);
+ return ret;
+ }
+ i++;
+ }
+ }
+
+ ret = asoc_simple_card_parse_card_name(card, top_port, PREFIX);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+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;
+ struct device *cpu_dev = pdev->dev.parent;
+ struct device_node *cpu_node = cpu_dev->of_node;
+ struct asoc_simple_graph_card_info *info = pdev->dev.platform_data;
+ int num, ret;
+
+ if (!info)
+ return -EINVAL;
+
+ /* Allocate the private data and the DAI link array */
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ num = info->endpoint_num;
+
+ 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 = priv->dai_link;
+ priv->snd_card.num_links = num;
+
+ ret = asoc_simple_card_parse_of(cpu_node, priv);
+ if (ret < 0) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "parse error %d\n", ret);
+ goto err;
+ }
+
+ /*
+ * FIXME
+ *
+ * This driver is assuming that it will be called from
+ * asoc_simple_card_try_to_probe_graph_card() which
+ * is using platform_device_register_full().
+ * This means it is not came from DT. But this driver itself
+ * will be used as part of ALSA SoC (= sound card).
+ * Because of these background, it might fail in
+ * snd_pcm_lib_malloc_pages() on .hw_params.
+ * Because, noone cares its dma_ops, and result of get_dma_ops()
+ * is based on its architecture.
+ * So, it should call arch_setup_dma_ops() from somewhere,
+ * otherwise, for example, ARM is no problem, but ARM64 will be fail.
+ * But, of_platform_device_xxx() are not good solution today.
+ * This driver calls it by itself here. Please fixme
+ * see also
+ * linux/sound/soc/generic/simple-card-utils.c ::
+ * asoc_simple_card_try_to_probe_graph_card()
+ */
+ of_dma_configure(dev, dev->of_node);
+
+ 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);
+
+ asoc_simple_card_remove_jack(&priv->hp_jack);
+ asoc_simple_card_remove_jack(&priv->mic_jack);
+
+ return asoc_simple_card_clean_reference(&priv->snd_card);
+}
+
+static struct platform_driver asoc_simple_card = {
+ .driver = {
+ .name = "asoc-simple-graph-card",
+ },
+ .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>");
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 16/17] ASoC: add simple-graph-scu-card document
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (14 preceding siblings ...)
2016-11-11 1:24 ` [PATCH v3 15/17] ASoC: add simple-graph-card support Kuninori Morimoto
@ 2016-11-11 1:24 ` Kuninori Morimoto
2016-11-11 1:25 ` [PATCH v3 17/17] ASoC: add simple-graph-scu-card support Kuninori Morimoto
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:24 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- Added how to use Simple-Graph-SCU-Card, and cleaned-up
.../bindings/sound/simple-graph-scu-card.txt | 65 ++++++++++++++++++++++
1 file changed, 65 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
diff --git a/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
new file mode 100644
index 0000000..223096a
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
@@ -0,0 +1,65 @@
+Simple-Graph-SCU-Card:
+
+Simple-Graph-SCU-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-SCU-Card property is same as Simple-Card / Simple-Graph-Card.
+see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
+ ${LINUX}/Documentation/devicetree/bindings/sound/simple-graph-card.txt
+
+Main difference between Simple-Graph-Card and Simple-Graph-SCU-Card is that
+Simple-Graph-SCU-Card can use multi CPU.
+
+Required properties:
+
+- compatible : "asoc-simple-graph-scu-card";
+- simple-audio-card,routing : see simple-card.txt
+
+Example
+
+ak4643: codec@12 {
+ compatible = "asahi-kasei,ak4643";
+ ...
+ port {
+ ak4643_fe: endpoint@0 {
+ remote-endpoint = <&rsnd_fe>;
+ ...
+ };
+ ak4643_be: endpoint@1 {
+ remote-endpoint = <&rsnd_be>;
+ ...
+ };
+ };
+};
+
+rcar_sound {
+ ...
+ ports {
+ compatible = "asoc-simple-graph-scu-card";
+
+ simple-audio-card,name = "graph-sound";
+ simple-audio-card,format = "left_j";
+ simple-audio-card,bitclock-master = <&rsnd_fe>;
+ simple-audio-card,frame-master = <&rsnd_fe>;
+ simple-audio-card,convert-rate = <48000>;
+ simple-audio-card,convert-channels = <2>;
+ simple-audio-card,prefix = "ak4642";
+ simple-audio-card,routing =
+ "ak4642 Playback", "DAI0 Playback",
+ "ak4642 Playback", "DAI1 Playback";
+
+ port@0 {
+ rsnd_fe: endpoint@0 {
+ remote-endpoint = <&ak4643_fe>;
+ ...
+ };
+ };
+ port@1 {
+ rsnd_be: endpoint@1 {
+ remote-endpoint = <&ak4643_be>;
+ ...
+ };
+ };
+ };
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 17/17] ASoC: add simple-graph-scu-card support
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
` (15 preceding siblings ...)
2016-11-11 1:24 ` [PATCH v3 16/17] ASoC: add simple-graph-scu-card document Kuninori Morimoto
@ 2016-11-11 1:25 ` Kuninori Morimoto
16 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-11 1:25 UTC (permalink / raw)
To: Rob Herring, Mark Brown
Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
graph base DT binding are used on V4L2, and ALSA SoC is using different
style of DT. In case of simple case, ALSA SoC supports simple-card
driver.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged somehow.
Sometimes, we would like to use DPCM base simple-card on graph base DT.
This patch adds graph base DT binding of simple-scu-card
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v2 -> v3
- no change
sound/soc/generic/Kconfig | 8 +
sound/soc/generic/Makefile | 2 +
sound/soc/generic/simple-graph-scu-card.c | 417 ++++++++++++++++++++++++++++++
3 files changed, 427 insertions(+)
create mode 100644 sound/soc/generic/simple-graph-scu-card.c
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index efefabd..fc11828 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -21,3 +21,11 @@ config SND_SIMPLE_GRAPH_CARD
select SND_SIMPLE_CARD_UTILS
help
This option enables generic simple Graph sound card support
+
+config SND_SIMPLE_GRAPH_SCU_CARD
+ tristate "ASoC Simple Graph SCU sound card support"
+ depends on OF
+ select SND_SIMPLE_CARD_UTILS
+ help
+ This option enables generic simple Graph SCU sound card support.
+ It supports DPCM of multi CPU single Codec ststem.
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 94eb6f1..fd75b55 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -2,8 +2,10 @@ 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
+snd-soc-simple-graph-scu-card-objs := simple-graph-scu-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
+obj-$(CONFIG_SND_SIMPLE_GRAPH_SCU_CARD) += snd-soc-simple-graph-scu-card.o
diff --git a/sound/soc/generic/simple-graph-scu-card.c b/sound/soc/generic/simple-graph-scu-card.c
new file mode 100644
index 0000000..39a5019
--- /dev/null
+++ b/sound/soc/generic/simple-graph-scu-card.c
@@ -0,0 +1,417 @@
+/*
+ * ASoC simple graph SCU sound card support
+ *
+ * Copyright (C) 2016 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on
+ * ${LINUX}/sound/soc/generic/simple-graph-card.c
+ * ${LINUX}/sound/soc/generic/simple-scu-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 snd_soc_codec_conf codec_conf;
+ struct asoc_simple_dai *dai_props;
+ struct snd_soc_dai_link *dai_link;
+ u32 convert_rate;
+ u32 convert_channels;
+};
+
+#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 asoc_simple_dai *dai_props =
+ simple_priv_to_props(priv, rtd->num);
+
+ return clk_prepare_enable(dai_props->clk);
+}
+
+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 asoc_simple_dai *dai_props =
+ simple_priv_to_props(priv, rtd->num);
+
+ clk_disable_unprepare(dai_props->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 *dai;
+ struct snd_soc_dai_link *dai_link;
+ struct asoc_simple_dai *dai_props;
+ int num = rtd->num;
+
+ dai_link = simple_priv_to_link(priv, num);
+ dai_props = simple_priv_to_props(priv, num);
+ dai = dai_link->dynamic ?
+ rtd->cpu_dai :
+ rtd->codec_dai;
+
+ return asoc_simple_card_init_dai(dai, dai_props);
+}
+
+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 snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ if (priv->convert_rate)
+ rate->min =
+ rate->max = priv->convert_rate;
+
+ if (priv->convert_channels)
+ channels->min =
+ channels->max = priv->convert_channels;
+
+ return 0;
+}
+
+static int asoc_simple_card_dai_link_of(struct device_node *port,
+ struct device_node *ep,
+ struct simple_card_data *priv,
+ unsigned int daifmt,
+ int idx, int is_fe)
+{
+ struct device *dev = simple_priv_to_dev(priv);
+ struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
+ struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
+ int ret;
+
+ if (is_fe) {
+ /* BE is dummy */
+ dai_link->codec_of_node = NULL;
+ dai_link->codec_dai_name = "snd-soc-dummy-dai";
+ dai_link->codec_name = "snd-soc-dummy";
+
+ /* FE settings */
+ dai_link->dynamic = 1;
+ dai_link->dpcm_merged_format = 1;
+
+ ret = asoc_simple_card_parse_graph_cpu(ep, dai_link);
+ if (ret)
+ return ret;
+
+ ret = asoc_simple_card_parse_clk_cpu(ep, dai_link, dai_props);
+ 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;
+
+ /* snd_card.num_links includes Codec */
+ asoc_simple_card_canonicalize_cpu(dai_link,
+ (priv->snd_card.num_links -1) == 1);
+ } else {
+ /* 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;
+
+ ret = asoc_simple_card_parse_graph_codec(ep, dai_link);
+ if (ret < 0)
+ return ret;
+
+ ret = asoc_simple_card_parse_clk_codec(ep, dai_link, dai_props);
+ if (ret < 0)
+ return ret;
+
+ ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+ "be.%s",
+ dai_link->codec_dai_name);
+ if (ret < 0)
+ return ret;
+
+ snd_soc_of_parse_audio_prefix_from_node(&priv->snd_card,
+ port,
+ &priv->codec_conf,
+ dai_link->codec_of_node,
+ PREFIX "prefix");
+ }
+
+ ret = snd_soc_of_parse_tdm_slot(ep,
+ &dai_props->tx_slot_mask,
+ &dai_props->rx_slot_mask,
+ &dai_props->slots,
+ &dai_props->slot_width);
+ if (ret)
+ return ret;
+
+ ret = asoc_simple_card_canonicalize_dailink(dai_link);
+ if (ret < 0)
+ return ret;
+
+ dai_link->dai_fmt = daifmt;
+ 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;
+
+ dev_dbg(dev, "\t%s / %04x / %d\n",
+ dai_link->name,
+ dai_link->dai_fmt,
+ dai_props->sysclk);
+
+ return 0;
+}
+
+static int asoc_simple_card_parse_of(struct device_node *node,
+ struct simple_card_data *priv)
+{
+ struct device *dev = simple_priv_to_dev(priv);
+ struct device *cpu_dev = dev->parent;
+ struct device_node *ports = of_graph_get_top_port(cpu_dev);
+ struct snd_soc_card *card = &priv->snd_card;
+ struct device_node *port, *cpu_ep, *r_cpu_ep, *codec_ep;
+ unsigned int daifmt = 0;
+ int i, ret, done;
+
+ if (!node)
+ return -EINVAL;
+
+ ret = snd_soc_of_parse_audio_routing_from_node(&priv->snd_card,
+ ports, PREFIX "routing");
+ if (ret)
+ return ret;
+
+ /* sampling rate convert */
+ of_property_read_u32(ports, PREFIX "convert-rate",
+ &priv->convert_rate);
+
+ /* channels transfer */
+ of_property_read_u32(ports, PREFIX "convert-channels",
+ &priv->convert_channels);
+
+ /*
+ * it supports multi CPU, single CODEC only here.
+ */
+
+ /* find 1st codec */
+ done = 0;
+ for_each_of_port(node, port) {
+ /* keep for_each for of_node_get/of_node_put */
+ if (done)
+ continue;
+
+ for_each_of_endpoint_in_port(port, cpu_ep) {
+ /* keep for_each for of_node_get/of_node_put */
+ if (done)
+ continue;
+
+ codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+ r_cpu_ep = of_graph_get_remote_endpoint(codec_ep);
+ of_node_put(codec_ep);
+ of_node_put(r_cpu_ep);
+ if (cpu_ep != r_cpu_ep) {
+ ret = -EINVAL;
+ goto parse_of_err;
+ }
+
+ ret = asoc_simple_card_parse_daifmt(dev,
+ ports, codec_ep,
+ PREFIX, &daifmt);
+ if (ret < 0)
+ goto parse_of_err;
+
+ done = 1;
+ }
+ }
+
+ /* Front-End (= CPU) */
+ i = 0;
+ for_each_of_port(node, port) {
+ for_each_of_endpoint_in_port(port, cpu_ep) {
+ ret = asoc_simple_card_dai_link_of(
+ port, cpu_ep, priv, daifmt, i, 1);
+ if (ret < 0)
+ goto parse_of_err;
+ i++;
+ }
+ }
+
+ /* Back-End (= Codec) */
+ done = 0;
+ for_each_of_port(node, port) {
+ /* keep for_each for of_node_get/of_node_put */
+ if (done)
+ continue;
+
+ for_each_of_endpoint_in_port(port, cpu_ep) {
+ /* keep for_each for of_node_get/of_node_put */
+ if (done)
+ continue;
+
+ codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+ r_cpu_ep = of_graph_get_remote_endpoint(codec_ep);
+ of_node_put(codec_ep);
+ of_node_put(r_cpu_ep);
+ if (cpu_ep != r_cpu_ep) {
+ ret = -EINVAL;
+ goto parse_of_err;
+ }
+
+ ret = asoc_simple_card_dai_link_of(
+ port, codec_ep, priv, daifmt, i, 0);
+ if (ret < 0)
+ goto parse_of_err;
+ i++;
+
+ done = 1;
+ }
+ }
+
+ ret = asoc_simple_card_parse_card_name(card, ports, PREFIX);
+ if (ret)
+ return ret;
+
+ dev_dbg(dev, "New card: %s\n",
+ priv->snd_card.name ? priv->snd_card.name : "");
+ dev_dbg(dev, "convert_rate %d\n", priv->convert_rate);
+ dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);
+
+ return 0;
+parse_of_err:
+ of_node_put(port);
+ of_node_put(cpu_ep);
+
+ return ret;
+}
+
+static int asoc_simple_card_probe(struct platform_device *pdev)
+{
+ struct simple_card_data *priv;
+ struct snd_soc_dai_link *dai_link;
+ struct asoc_simple_dai *dai_props;
+ struct device *dev = &pdev->dev;
+ struct device *cpu_dev = pdev->dev.parent;
+ struct device_node *cpu_node = cpu_dev->of_node;
+ struct asoc_simple_graph_card_info *info = pdev->dev.platform_data;
+ int num, ret;
+
+ /* Allocate the private data and the DAI link array */
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* it supports multi CPU, single CODEC only here */
+ num = info->endpoint_num + 1; /* +1 for Codec */
+
+ 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 = priv->dai_link;
+ priv->snd_card.num_links = num;
+ priv->snd_card.codec_conf = &priv->codec_conf;
+ priv->snd_card.num_configs = 1;
+
+ ret = asoc_simple_card_parse_of(cpu_node, priv);
+ if (ret < 0) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "parse error %d\n", ret);
+ goto err;
+ }
+
+ /*
+ * FIXME
+ *
+ * This driver is assuming that it will be called from
+ * asoc_simple_card_try_to_probe_graph_card() which
+ * is using platform_device_register_full().
+ * This means it is not came from DT. But this driver itself
+ * will be used as part of ALSA SoC (= sound card).
+ * Because of these background, it might fail in
+ * snd_pcm_lib_malloc_pages() on .hw_params.
+ * Because, noone cares its dma_ops, and result of get_dma_ops()
+ * is based on its architecture.
+ * So, it should call arch_setup_dma_ops() from somewhere,
+ * otherwise, for example, ARM is no problem, but ARM64 will be fail.
+ * But, of_platform_device_xxx() are not good solution today.
+ * This driver calls it by itself here. Please fixme
+ * see also
+ * linux/sound/soc/generic/simple-card-utils.c ::
+ * asoc_simple_card_try_to_probe_graph_card()
+ */
+ of_dma_configure(dev, dev->of_node);
+
+ 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 struct platform_driver asoc_simple_card = {
+ .driver = {
+ .name = "asoc-simple-graph-scu-card",
+ },
+ .probe = asoc_simple_card_probe,
+ .remove = asoc_simple_card_remove,
+};
+module_platform_driver(asoc_simple_card);
+
+MODULE_ALIAS("platform:asoc-simple-graph-scu-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Simple Graph SCU Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
--
1.9.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card()
2016-11-11 1:22 ` [PATCH v3 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card() Kuninori Morimoto
@ 2016-11-11 2:07 ` kbuild test robot
2016-11-16 2:07 ` Kuninori Morimoto
0 siblings, 1 reply; 20+ messages in thread
From: kbuild test robot @ 2016-11-11 2:07 UTC (permalink / raw)
To: Kuninori Morimoto
Cc: kbuild-all, Rob Herring, Mark Brown, Linux-ALSA, Liam Girdwood,
Simon, Laurent, Guennadi, Grant Likely, Frank Rowand, Linux-DT,
Linux-Kernel
[-- Attachment #1: Type: text/plain, Size: 1737 bytes --]
Hi Kuninori,
[auto build test ERROR on asoc/for-next]
[also build test ERROR on v4.9-rc4 next-20161110]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Kuninori-Morimoto/ASoC-add-OF-graph-base-simple-card/20161111-093231
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
config: x86_64-randconfig-x010-201645 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All error/warnings (new ones prefixed by >>):
sound/soc/generic/simple-card-utils.c: In function 'asoc_simple_card_try_to_probe_graph_card':
>> sound/soc/generic/simple-card-utils.c:297:9: error: implicit declaration of function 'of_graph_get_top_port' [-Werror=implicit-function-declaration]
node = of_graph_get_top_port(dev);
^~~~~~~~~~~~~~~~~~~~~
>> sound/soc/generic/simple-card-utils.c:297:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
node = of_graph_get_top_port(dev);
^
cc1: some warnings being treated as errors
vim +/of_graph_get_top_port +297 sound/soc/generic/simple-card-utils.c
291 {
292 struct platform_device_info pdevinfo;
293 struct device_node *node;
294 const char *compatible;
295 int ret;
296
> 297 node = of_graph_get_top_port(dev);
298 if (!node || !info)
299 /*
300 * It doesn't have graph base sound DT, or its infomation.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23944 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card()
2016-11-11 2:07 ` kbuild test robot
@ 2016-11-16 2:07 ` Kuninori Morimoto
0 siblings, 0 replies; 20+ messages in thread
From: Kuninori Morimoto @ 2016-11-16 2:07 UTC (permalink / raw)
To: Rob Herring, Mark Brown, Linux-ALSA, Liam Girdwood, Simon,
Laurent, Guennadi, Grant Likely, Frank Rowand, Linux-DT,
Linux-Kernel
Hi
> [auto build test ERROR on asoc/for-next]
> [also build test ERROR on v4.9-rc4 next-20161110]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Kuninori-Morimoto/ASoC-add-OF-graph-base-simple-card/20161111-093231
> base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
> config: x86_64-randconfig-x010-201645 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64
>
> All error/warnings (new ones prefixed by >>):
>
> sound/soc/generic/simple-card-utils.c: In function 'asoc_simple_card_try_to_probe_graph_card':
> >> sound/soc/generic/simple-card-utils.c:297:9: error: implicit declaration of function 'of_graph_get_top_port' [-Werror=implicit-function-declaration]
> node = of_graph_get_top_port(dev);
> ^~~~~~~~~~~~~~~~~~~~~
> >> sound/soc/generic/simple-card-utils.c:297:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
> node = of_graph_get_top_port(dev);
> ^
> cc1: some warnings being treated as errors
This patch didn't care about non-OF case.
I will post v4 patch soon
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2016-11-16 2:07 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-11 1:16 [PATCH v3 00/17] ASoC: add OF graph base simple-card Kuninori Morimoto
2016-11-11 1:17 ` [PATCH v3 01/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name Kuninori Morimoto
2016-11-11 1:18 ` [PATCH v3 02/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets Kuninori Morimoto
2016-11-11 1:18 ` [PATCH v3 03/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing Kuninori Morimoto
2016-11-11 1:19 ` [PATCH v3 04/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix Kuninori Morimoto
2016-11-11 1:19 ` [PATCH v3 05/17] ASoC: soc-core: snd_soc_get_dai_name() become non static Kuninori Morimoto
2016-11-11 1:19 ` [PATCH v3 06/17] of_graph: add of_graph_get_remote_endpoint() Kuninori Morimoto
2016-11-11 1:20 ` [PATCH v3 07/17] of_graph: add of_graph_get_port_parent() Kuninori Morimoto
2016-11-11 1:20 ` [PATCH v3 08/17] of_graph: add of_graph_get_top_port() Kuninori Morimoto
2016-11-11 1:21 ` [PATCH v3 09/17] of_graph: add for_each_of_port() / for_each_of_endpoint_in_port() Kuninori Morimoto
2016-11-11 1:21 ` [PATCH v3 10/17] of_graph: add of_graph_get_port/endpoint_count() Kuninori Morimoto
2016-11-11 1:21 ` [PATCH v3 11/17] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai() Kuninori Morimoto
2016-11-11 1:22 ` [PATCH v3 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card() Kuninori Morimoto
2016-11-11 2:07 ` kbuild test robot
2016-11-16 2:07 ` Kuninori Morimoto
2016-11-11 1:22 ` [PATCH v3 13/17] ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name Kuninori Morimoto
2016-11-11 1:23 ` [PATCH v3 14/17] ASoC: add simple-graph-card document Kuninori Morimoto
2016-11-11 1:24 ` [PATCH v3 15/17] ASoC: add simple-graph-card support Kuninori Morimoto
2016-11-11 1:24 ` [PATCH v3 16/17] ASoC: add simple-graph-scu-card document Kuninori Morimoto
2016-11-11 1:25 ` [PATCH v3 17/17] ASoC: add simple-graph-scu-card support Kuninori Morimoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).