linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).