* [PATCH v4 1/9] of_graph: add of_graph_get_remote_endpoint()
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
@ 2017-03-13 5:52 ` Kuninori Morimoto
2017-03-13 5:52 ` [PATCH v4 2/9] of_graph: add of_graph_get_port_parent() Kuninori Morimoto
` (7 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:52 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
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>
---
v3 -> v4
- 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 d7c4629..3fad47f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2455,6 +2455,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
*
@@ -2468,7 +2482,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--) {
@@ -2492,7 +2506,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 abdb02e..0c9473a 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);
@@ -80,6 +82,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] 26+ messages in thread
* [PATCH v4 2/9] of_graph: add of_graph_get_port_parent()
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
2017-03-13 5:52 ` [PATCH v4 1/9] of_graph: add of_graph_get_remote_endpoint() Kuninori Morimoto
@ 2017-03-13 5:52 ` Kuninori Morimoto
2017-03-13 5:52 ` [PATCH v4 3/9] of_graph: add of_graph_get_endpoint_count() Kuninori Morimoto
` (6 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:52 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
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>
---
v3 -> v4
- 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 3fad47f..eac37014 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2469,6 +2469,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
*
@@ -2479,18 +2500,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 0c9473a..9db632d 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);
@@ -88,6 +89,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] 26+ messages in thread
* [PATCH v4 3/9] of_graph: add of_graph_get_endpoint_count()
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
2017-03-13 5:52 ` [PATCH v4 1/9] of_graph: add of_graph_get_remote_endpoint() Kuninori Morimoto
2017-03-13 5:52 ` [PATCH v4 2/9] of_graph: add of_graph_get_port_parent() Kuninori Morimoto
@ 2017-03-13 5:52 ` Kuninori Morimoto
[not found] ` <871su1iv4n.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
2017-03-13 5:53 ` [PATCH v4 4/9] ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name Kuninori Morimoto
` (5 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:52 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
OF graph want to count its endpoint number, same as
of_get_child_count(). This patch adds of_graph_get_endpoint_count()
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v3 -> v4
- no change
drivers/of/base.c | 12 ++++++++++++
include/linux/of_graph.h | 6 ++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index eac37014..812edb9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2527,6 +2527,18 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
}
EXPORT_SYMBOL(of_graph_get_remote_port);
+int of_graph_get_endpoint_count(const struct device_node *np)
+{
+ struct device_node *endpoint;
+ int num = 0;
+
+ for_each_endpoint_of_node(np, endpoint)
+ num++;
+
+ return num;
+}
+EXPORT_SYMBOL(of_graph_get_endpoint_count);
+
/**
* of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
* @node: pointer to parent device_node containing graph port/endpoint
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 9db632d..3e058f0 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -43,6 +43,7 @@ struct of_endpoint {
#ifdef CONFIG_OF
int of_graph_parse_endpoint(const struct device_node *node,
struct of_endpoint *endpoint);
+int of_graph_get_endpoint_count(const struct device_node *np);
struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
struct device_node *previous);
@@ -64,6 +65,11 @@ 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)
+{
+ 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] 26+ messages in thread
* [PATCH v4 4/9] ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
` (2 preceding siblings ...)
2017-03-13 5:52 ` [PATCH v4 3/9] of_graph: add of_graph_get_endpoint_count() Kuninori Morimoto
@ 2017-03-13 5:53 ` Kuninori Morimoto
2017-03-20 19:20 ` Rob Herring
2017-03-13 5:53 ` [PATCH v4 5/9] ASoC: soc-core: enable "dai-name" on snd_soc_of_parse_daifmt() Kuninori Morimoto
` (4 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:53 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Current asoc_simple_card_parse_card_name() detect [prefix]name,
but in generally, we uses "label" for user visible names.
This patch expand it to [prefix]label.
This patch also update simple-xx-card.txt which is using this feature
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v3 -> v4
- new patch to expand name/labal
.../devicetree/bindings/sound/simple-card.txt | 1 +
.../devicetree/bindings/sound/simple-scu-card.txt | 1 +
sound/soc/generic/simple-card-utils.c | 18 ++++++++++++++----
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index c7a9393..f34a810 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -8,6 +8,7 @@ Required properties:
Optional properties:
+- simple-audio-card,label : see simple-audio-card,name
- simple-audio-card,name : User specified audio sound card name, one string
property.
- simple-audio-card,widgets : Please refer to widgets.txt.
diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
index d6fe47e..01eb56e 100644
--- a/Documentation/devicetree/bindings/sound/simple-scu-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
@@ -9,6 +9,7 @@ Required properties:
Optional properties:
+- simple-audio-card,label : see simple-audio-card,name
- simple-audio-card,name : User specified audio sound card name, one string
property.
- simple-audio-card,cpu : CPU sub-node
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 4924575..4dfd9a2 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -82,14 +82,24 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
char *prefix)
{
char prop[128];
+ char *names[] = {
+ "label", "name"
+ };
+ int i;
int ret;
- snprintf(prop, sizeof(prop), "%sname", prefix);
+ if (!prefix)
+ prefix = "";
/* Parse the card name from DT */
- ret = snd_soc_of_parse_card_name(card, prop);
- if (ret < 0)
- return ret;
+ for (i = 0; i < ARRAY_SIZE(names); i++) {
+ snprintf(prop, sizeof(prop), "%s%s", prefix, names[i]);
+ ret = snd_soc_of_parse_card_name(card, prop);
+ if (ret < 0)
+ return ret;
+ if (card->name)
+ break;
+ }
if (!card->name && card->dai_link)
card->name = card->dai_link->name;
--
1.9.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v4 4/9] ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name
2017-03-13 5:53 ` [PATCH v4 4/9] ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name Kuninori Morimoto
@ 2017-03-20 19:20 ` Rob Herring
0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2017-03-20 19:20 UTC (permalink / raw)
To: Kuninori Morimoto; +Cc: Linux-DT, Linux-ALSA, Mark Brown, Simon
On Mon, Mar 13, 2017 at 05:53:12AM +0000, Kuninori Morimoto wrote:
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
>
> Current asoc_simple_card_parse_card_name() detect [prefix]name,
> but in generally, we uses "label" for user visible names.
> This patch expand it to [prefix]label.
> This patch also update simple-xx-card.txt which is using this feature
>
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> ---
> v3 -> v4
>
> - new patch to expand name/labal
>
> .../devicetree/bindings/sound/simple-card.txt | 1 +
> .../devicetree/bindings/sound/simple-scu-card.txt | 1 +
> sound/soc/generic/simple-card-utils.c | 18 ++++++++++++++----
> 3 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
> index c7a9393..f34a810 100644
> --- a/Documentation/devicetree/bindings/sound/simple-card.txt
> +++ b/Documentation/devicetree/bindings/sound/simple-card.txt
> @@ -8,6 +8,7 @@ Required properties:
>
> Optional properties:
>
> +- simple-audio-card,label : see simple-audio-card,name
Just "label". That's a standard property name.
> - simple-audio-card,name : User specified audio sound card name, one string
> property.
> - simple-audio-card,widgets : Please refer to widgets.txt.
> diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
> index d6fe47e..01eb56e 100644
> --- a/Documentation/devicetree/bindings/sound/simple-scu-card.txt
> +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
> @@ -9,6 +9,7 @@ Required properties:
>
> Optional properties:
>
> +- simple-audio-card,label : see simple-audio-card,name
Ditto.
> - simple-audio-card,name : User specified audio sound card name, one string
> property.
> - simple-audio-card,cpu : CPU sub-node
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v4 5/9] ASoC: soc-core: enable "dai-name" on snd_soc_of_parse_daifmt()
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
` (3 preceding siblings ...)
2017-03-13 5:53 ` [PATCH v4 4/9] ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name Kuninori Morimoto
@ 2017-03-13 5:53 ` Kuninori Morimoto
2017-03-20 19:30 ` Rob Herring
[not found] ` <8760jdivfm.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
` (3 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:53 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Current snd_soc_of_parse_daifmt() detects [prefix]format, but
"format" was unclear. This patch expand it to [prefix]dai-format, too
This patch update simple-xx-card.txt which uses this feature
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v3 -> v4
- expand format
Documentation/devicetree/bindings/sound/simple-card.txt | 2 +-
Documentation/devicetree/bindings/sound/simple-scu-card.txt | 3 ++-
sound/soc/soc-core.c | 9 +++++++--
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index f34a810..6e8a8a3 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -48,7 +48,7 @@ Required dai-link subnodes:
Optional dai-link subnode properties:
-- format : CPU/CODEC common audio format.
+- dai-format / format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
- frame-master : Indicates dai-link frame master.
diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
index 01eb56e..47b4677 100644
--- a/Documentation/devicetree/bindings/sound/simple-scu-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
@@ -17,9 +17,10 @@ Optional properties:
Optional subnode properties:
-- simple-audio-card,format : CPU/CODEC common audio format.
+- simple-audio-card,dai-format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
+- simple-audio-card,format : see simple-audio-card,dai-format
- simple-audio-card,frame-master : Indicates dai-link frame master.
phandle to a cpu or codec subnode.
- simple-audio-card,bitclock-master : Indicates dai-link bit clock master.
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6dca408..175ade0 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3951,11 +3951,16 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
prefix = "";
/*
- * check "[prefix]format = xxx"
+ * check "[prefix]dai-format = xxx"
+ * or "[prefix]format = xxx"
* SND_SOC_DAIFMT_FORMAT_MASK area
*/
- snprintf(prop, sizeof(prop), "%sformat", prefix);
+ snprintf(prop, sizeof(prop), "%sdai-format", prefix);
ret = of_property_read_string(np, prop, &str);
+ if (ret < 0) {
+ snprintf(prop, sizeof(prop), "%sformat", prefix);
+ ret = of_property_read_string(np, prop, &str);
+ }
if (ret == 0) {
for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
if (strcmp(str, of_fmt_table[i].name) == 0) {
--
1.9.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v4 5/9] ASoC: soc-core: enable "dai-name" on snd_soc_of_parse_daifmt()
2017-03-13 5:53 ` [PATCH v4 5/9] ASoC: soc-core: enable "dai-name" on snd_soc_of_parse_daifmt() Kuninori Morimoto
@ 2017-03-20 19:30 ` Rob Herring
0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2017-03-20 19:30 UTC (permalink / raw)
To: Kuninori Morimoto; +Cc: Linux-DT, Linux-ALSA, Mark Brown, Simon
On Mon, Mar 13, 2017 at 05:53:30AM +0000, Kuninori Morimoto wrote:
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
>
> Current snd_soc_of_parse_daifmt() detects [prefix]format, but
> "format" was unclear. This patch expand it to [prefix]dai-format, too
> This patch update simple-xx-card.txt which uses this feature
>
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> ---
> v3 -> v4
>
> - expand format
>
> Documentation/devicetree/bindings/sound/simple-card.txt | 2 +-
> Documentation/devicetree/bindings/sound/simple-scu-card.txt | 3 ++-
> sound/soc/soc-core.c | 9 +++++++--
> 3 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
> index f34a810..6e8a8a3 100644
> --- a/Documentation/devicetree/bindings/sound/simple-card.txt
> +++ b/Documentation/devicetree/bindings/sound/simple-card.txt
> @@ -48,7 +48,7 @@ Required dai-link subnodes:
>
> Optional dai-link subnode properties:
>
> -- format : CPU/CODEC common audio format.
> +- dai-format / format : CPU/CODEC common audio format.
> "i2s", "right_j", "left_j" , "dsp_a"
> "dsp_b", "ac97", "pdm", "msb", "lsb"
> - frame-master : Indicates dai-link frame master.
> diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
> index 01eb56e..47b4677 100644
> --- a/Documentation/devicetree/bindings/sound/simple-scu-card.txt
> +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
> @@ -17,9 +17,10 @@ Optional properties:
>
> Optional subnode properties:
>
> -- simple-audio-card,format : CPU/CODEC common audio format.
> +- simple-audio-card,dai-format : CPU/CODEC common audio format.
This one should not be added.
> "i2s", "right_j", "left_j" , "dsp_a"
> "dsp_b", "ac97", "pdm", "msb", "lsb"
> +- simple-audio-card,format : see simple-audio-card,dai-format
> - simple-audio-card,frame-master : Indicates dai-link frame master.
> phandle to a cpu or codec subnode.
> - simple-audio-card,bitclock-master : Indicates dai-link bit clock master.
^ permalink raw reply [flat|nested] 26+ messages in thread
[parent not found: <8760jdivfm.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>]
* [PATCH v4 6/9] ASoC: add snd_soc_get_dai_id()
[not found] ` <8760jdivfm.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
@ 2017-03-13 5:53 ` Kuninori Morimoto
[not found] ` <87wpbthgir.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:53 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
ALSA SoC needs to know connected DAI ID for probing.
On OF-graph case, basically we can check DT port location.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v3 -> v4
- no change
include/sound/soc.h | 1 +
sound/soc/soc-core.c | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index cdfb55f..ab4639e 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1664,6 +1664,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
const char *prefix,
struct device_node **bitclkmaster,
struct device_node **framemaster);
+int snd_soc_get_dai_id(struct device_node *ep);
int snd_soc_get_dai_name(struct of_phandle_args *args,
const char **dai_name);
int snd_soc_of_get_dai_name(struct device_node *of_node,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 175ade0..c91010d 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -34,6 +34,7 @@
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/dmi.h>
#include <sound/core.h>
#include <sound/jack.h>
@@ -4040,6 +4041,28 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
+int snd_soc_get_dai_id(struct device_node *ep)
+{
+ struct device_node *node;
+ struct device_node *endpoint;
+ int i, id;
+
+ node = of_graph_get_port_parent(ep);
+
+ i = 0;
+ id = -1;
+ for_each_endpoint_of_node(node, endpoint) {
+ if (endpoint == ep)
+ id = i;
+ i++;
+ }
+ if (id < 0)
+ return -ENODEV;
+
+ return id;
+}
+EXPORT_SYMBOL_GPL(snd_soc_get_dai_id);
+
int snd_soc_get_dai_name(struct of_phandle_args *args,
const char **dai_name)
{
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 7/9] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
` (5 preceding siblings ...)
[not found] ` <8760jdivfm.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
@ 2017-03-13 5:54 ` Kuninori Morimoto
[not found] ` <87vardhgia.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
2017-03-13 5:54 ` [PATCH v4 8/9] ASoC: add audio-graph-card document Kuninori Morimoto
2017-03-13 5:54 ` [PATCH v4 9/9] ASoC: add audio-graph-card support Kuninori Morimoto
8 siblings, 1 reply; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:54 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
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>
---
v3 -> v4
- no change
include/sound/simple_card_utils.h | 10 ++++++++++
sound/soc/generic/simple-card-utils.c | 36 +++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index af58d23..efab584 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -60,6 +60,16 @@ int asoc_simple_card_parse_dai(struct device_node *node,
const char *cells_name,
int *is_single_links);
+#define asoc_simple_card_parse_graph_cpu(ep, dai_link) \
+ asoc_simple_card_parse_graph_dai(ep, &dai_link->cpu_of_node, \
+ &dai_link->cpu_dai_name)
+#define asoc_simple_card_parse_graph_codec(ep, dai_link) \
+ asoc_simple_card_parse_graph_dai(ep, &dai_link->codec_of_node, \
+ &dai_link->codec_dai_name)
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+ struct device_node **endpoint_np,
+ const char **dai_name);
+
int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
struct asoc_simple_dai *simple_dai);
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 4dfd9a2..67c3fa4 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,
@@ -174,6 +175,41 @@ int asoc_simple_card_parse_dai(struct device_node *node,
}
EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+ struct device_node **dai_of_node,
+ const char **dai_name)
+{
+ struct device_node *node;
+ struct of_phandle_args args;
+ int ret;
+
+ if (!ep)
+ return 0;
+ if (!dai_name)
+ return 0;
+
+ /*
+ * of_graph_get_port_parent() will call
+ * of_node_put(). So, call of_node_get() here
+ */
+ of_node_get(ep);
+ node = of_graph_get_port_parent(ep);
+
+ /* Get dai->name */
+ args.np = node;
+ args.args[0] = snd_soc_get_dai_id(ep);
+ args.args_count = (of_graph_get_endpoint_count(node) > 1);
+
+ ret = snd_soc_get_dai_name(&args, dai_name);
+ if (ret < 0)
+ return ret;
+
+ *dai_of_node = node;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_parse_graph_dai);
+
int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
struct asoc_simple_dai *simple_dai)
{
--
1.9.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 8/9] ASoC: add audio-graph-card document
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
` (6 preceding siblings ...)
2017-03-13 5:54 ` [PATCH v4 7/9] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai() Kuninori Morimoto
@ 2017-03-13 5:54 ` Kuninori Morimoto
[not found] ` <87tw6xhghs.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
2017-03-13 5:54 ` [PATCH v4 9/9] ASoC: add audio-graph-card support Kuninori Morimoto
8 siblings, 1 reply; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:54 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
"Audio Graph Card" = "Simple Card" + "OF-graph"
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v3 -> v4
- remove prefix
- asoc-audio-graph-card -> audio-graph-card
- dai-controller -> audio-codec
.../devicetree/bindings/sound/audio-graph-card.txt | 124 +++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/audio-graph-card.txt
diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card.txt b/Documentation/devicetree/bindings/sound/audio-graph-card.txt
new file mode 100644
index 0000000..bac4b1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/audio-graph-card.txt
@@ -0,0 +1,124 @@
+Audio Graph Card:
+
+Audio 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, Audio Graph Card property is same as Simple Card.
+see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
+
+Below are same as Simple-Card.
+
+- label
+- dai-format
+- frame-master
+- bitclock-master
+- bitclock-inversion
+- frame-inversion
+- dai-tdm-slot-num
+- dai-tdm-slot-width
+- clocks / system-clock-frequency
+
+Required properties:
+
+- compatible : "audio-graph-card";
+- dais : list of CPU DAI port{s}
+
+Example: Single DAI case
+
+ sound_card {
+ compatible = "audio-graph-card";
+
+ dais = <&cpu_port>;
+ };
+
+ dai-controller {
+ ...
+ cpu_port: port {
+ cpu_endpoint: endpoint {
+ remote-endpoint = <&codec_endpoint>;
+
+ dai-format = "left_j";
+ ...
+ };
+ };
+ };
+
+ audio-codec {
+ ...
+ port {
+ codec_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint>;
+ };
+ };
+ };
+
+Example: Multi DAI case
+
+ sound-card {
+ compatible = "audio-graph-card";
+
+ label = "sound-card";
+
+ dais = <&cpu_port0
+ &cpu_port1
+ &cpu_port2>;
+ };
+
+ audio-codec@0 {
+ ...
+ port {
+ codec0_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint0>;
+ };
+ };
+ };
+
+ audio-codec@1 {
+ ...
+ port {
+ codec1_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint1>;
+ };
+ };
+ };
+
+ audio-codec@2 {
+ ...
+ port {
+ codec2_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint2>;
+ };
+ };
+ };
+
+ dai-controller {
+ ...
+ ports {
+ cpu_port0: port@0 {
+ cpu_endpoint0: endpoint {
+ remote-endpoint = <&codec0_endpoint>;
+
+ dai-format = "left_j";
+ ...
+ };
+ };
+ cpu_port1: port@1 {
+ cpu_endpoint1: endpoint {
+ remote-endpoint = <&codec1_endpoint>;
+
+ dai-format = "i2s";
+ ...
+ };
+ };
+ cpu_port2: port@2 {
+ cpu_endpoint2: endpoint {
+ remote-endpoint = <&codec2_endpoint>;
+
+ dai-format = "i2s";
+ ...
+ };
+ };
+ };
+ };
+
--
1.9.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 9/9] ASoC: add audio-graph-card support
2017-03-13 5:46 [PATCH v4 0/9] ASoC: add OF-graph base simple-card Kuninori Morimoto
` (7 preceding siblings ...)
2017-03-13 5:54 ` [PATCH v4 8/9] ASoC: add audio-graph-card document Kuninori Morimoto
@ 2017-03-13 5:54 ` Kuninori Morimoto
2017-03-20 20:32 ` Rob Herring
8 siblings, 1 reply; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-13 5:54 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-DT, Linux-ALSA, Simon
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
OF-graph base DT binding are used on V4L2, and ALSA SoC is using
different style of DT today. Now ALSA SoC supports simple-card driver
for generic/simple sound card.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged.
This patch adds new Audio Graph Card which is OF-graph base of
simple-card
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v3 -> v4
- use "label"
- use "dai-format"
- don't use prefix
sound/soc/generic/Kconfig | 8 +
sound/soc/generic/Makefile | 2 +
sound/soc/generic/audio-graph-card.c | 301 +++++++++++++++++++++++++++++++++++
3 files changed, 311 insertions(+)
create mode 100644 sound/soc/generic/audio-graph-card.c
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index d023959..121a48e 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -14,3 +14,11 @@ 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_AUDIO_GRAPH_CARD
+ tristate "ASoC Audio Graph sound card support"
+ depends on OF
+ select SND_SIMPLE_CARD_UTILS
+ help
+ This option enables generic simple simple sound card support
+ with OF-graph DT bindings.
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index ee750f3..670068f 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-audio-graph-card-objs := audio-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_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
new file mode 100644
index 0000000..07afdfa
--- /dev/null
+++ b/sound/soc/generic/audio-graph-card.c
@@ -0,0 +1,301 @@
+/*
+ * ASoC audio 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 graph_card_data {
+ struct snd_soc_card snd_card;
+ struct graph_dai_props {
+ struct asoc_simple_dai cpu_dai;
+ struct asoc_simple_dai codec_dai;
+ } *dai_props;
+ struct snd_soc_dai_link *dai_link;
+};
+
+#define graph_priv_to_dev(priv) ((priv)->snd_card.dev)
+#define graph_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
+#define graph_priv_to_props(priv, i) ((priv)->dai_props + (i))
+
+static int asoc_graph_card_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct graph_dai_props *dai_props =
+ graph_priv_to_props(priv, rtd->num);
+ 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_graph_card_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct graph_dai_props *dai_props =
+ graph_priv_to_props(priv, rtd->num);
+
+ clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+ clk_disable_unprepare(dai_props->codec_dai.clk);
+}
+
+static struct snd_soc_ops asoc_graph_card_ops = {
+ .startup = asoc_graph_card_startup,
+ .shutdown = asoc_graph_card_shutdown,
+};
+
+static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *codec = rtd->codec_dai;
+ struct snd_soc_dai *cpu = rtd->cpu_dai;
+ struct graph_dai_props *dai_props =
+ graph_priv_to_props(priv, rtd->num);
+ int ret;
+
+ ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
+ if (ret < 0)
+ return ret;
+
+ ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
+ struct graph_card_data *priv,
+ int idx)
+{
+ struct device *dev = graph_priv_to_dev(priv);
+ struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, idx);
+ struct graph_dai_props *dai_props = graph_priv_to_props(priv, idx);
+ struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
+ struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
+ struct device_node *cpu_ep = of_get_next_child(cpu_port, NULL);
+ struct device_node *codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+ struct device_node *rcpu_ep = of_graph_get_remote_endpoint(codec_ep);
+ int ret;
+
+ if (rcpu_ep != cpu_ep) {
+ dev_err(dev, "remote-endpoint missmatch (%s/%s/%s)\n",
+ cpu_ep->name, codec_ep->name, rcpu_ep->name);
+ return -EINVAL;
+ }
+
+ ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
+ NULL, &dai_link->dai_fmt);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ /*
+ * we need to consider "mclk-fs" around here
+ * see simple-card
+ */
+
+ ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = snd_soc_of_parse_tdm_slot(cpu_ep,
+ &cpu_dai->tx_slot_mask,
+ &cpu_dai->rx_slot_mask,
+ &cpu_dai->slots,
+ &cpu_dai->slot_width);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = snd_soc_of_parse_tdm_slot(codec_ep,
+ &codec_dai->tx_slot_mask,
+ &codec_dai->rx_slot_mask,
+ &codec_dai->slots,
+ &codec_dai->slot_width);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_canonicalize_dailink(dai_link);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+ "%s-%s",
+ dai_link->cpu_dai_name,
+ dai_link->codec_dai_name);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ dai_link->ops = &asoc_graph_card_ops;
+ dai_link->init = asoc_graph_card_dai_init;
+
+ dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
+ dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
+ dev_dbg(dev, "\tcpu : %s / %d\n",
+ dai_link->cpu_dai_name,
+ dai_props->cpu_dai.sysclk);
+ dev_dbg(dev, "\tcodec : %s / %d\n",
+ dai_link->codec_dai_name,
+ dai_props->codec_dai.sysclk);
+
+ asoc_simple_card_canonicalize_cpu(dai_link,
+ priv->snd_card.num_links == 1);
+
+dai_link_of_err:
+ of_node_put(codec_ep);
+
+ return ret;
+}
+
+static int asoc_graph_card_parse_of(struct device *dev,
+ struct graph_card_data *priv)
+{
+ struct device_node *node = dev->of_node;
+ struct snd_soc_card *card = &priv->snd_card;
+ struct device_node *np;
+ int idx = 0;
+ int ret;
+
+ /*
+ * we need to consider "widgets", "routing", "mclk-fs" around here
+ * see simple-card
+ */
+
+ while ((np = of_parse_phandle(node, "dais", idx))) {
+ ret = asoc_graph_card_dai_link_of(np, priv, idx++);
+ if (ret < 0)
+ return ret;
+ }
+
+ return asoc_simple_card_parse_card_name(card, NULL);
+}
+
+static int asoc_graph_get_dais_count(struct device *dev)
+{
+ struct device_node *node = dev->of_node;
+ int count = 0;
+
+ if (of_get_property(node, "dais", NULL)) {
+ while (of_parse_phandle(node, "dais", count))
+ count++;
+ } else {
+ count = 1;
+ }
+
+ return count;
+}
+
+static int asoc_graph_card_probe(struct platform_device *pdev)
+{
+ struct graph_card_data *priv;
+ struct snd_soc_dai_link *dai_link;
+ struct graph_dai_props *dai_props;
+ struct device *dev = &pdev->dev;
+ int num, ret;
+
+ /* Allocate the private data and the DAI link array */
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ num = asoc_graph_get_dais_count(dev);
+
+ dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
+ dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL);
+ if (!dai_props || !dai_link)
+ return -ENOMEM;
+
+ priv->dai_props = dai_props;
+ priv->dai_link = dai_link;
+
+ /* Init snd_soc_card */
+ priv->snd_card.owner = THIS_MODULE;
+ priv->snd_card.dev = dev;
+ priv->snd_card.dai_link = dai_link;
+ priv->snd_card.num_links = num;
+
+ ret = asoc_graph_card_parse_of(dev, priv);
+ if (ret < 0) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "parse error %d\n", ret);
+ goto err;
+ }
+
+ snd_soc_card_set_drvdata(&priv->snd_card, priv);
+
+ ret = devm_snd_soc_register_card(dev, &priv->snd_card);
+ if (ret >= 0)
+ return ret;
+err:
+ asoc_simple_card_clean_reference(&priv->snd_card);
+
+ return ret;
+}
+
+static int asoc_graph_card_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct graph_card_data *priv = snd_soc_card_get_drvdata(card);
+
+ return asoc_simple_card_clean_reference(&priv->snd_card);
+}
+
+static const struct of_device_id asoc_graph_of_match[] = {
+ { .compatible = "audio-graph-card", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, asoc_graph_of_match);
+
+static struct platform_driver asoc_graph_card = {
+ .driver = {
+ .name = "asoc-audio-graph-card",
+ .of_match_table = asoc_graph_of_match,
+ },
+ .probe = asoc_graph_card_probe,
+ .remove = asoc_graph_card_remove,
+};
+module_platform_driver(asoc_graph_card);
+
+MODULE_ALIAS("platform:asoc-audio-graph-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Audio Graph Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
--
1.9.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v4 9/9] ASoC: add audio-graph-card support
2017-03-13 5:54 ` [PATCH v4 9/9] ASoC: add audio-graph-card support Kuninori Morimoto
@ 2017-03-20 20:32 ` Rob Herring
2017-03-21 2:08 ` Kuninori Morimoto
0 siblings, 1 reply; 26+ messages in thread
From: Rob Herring @ 2017-03-20 20:32 UTC (permalink / raw)
To: Kuninori Morimoto; +Cc: Linux-DT, Linux-ALSA, Mark Brown, Simon
On Mon, Mar 13, 2017 at 12:54 AM, Kuninori Morimoto
<kuninori.morimoto.gx@renesas.com> wrote:
>
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
>
> OF-graph base DT binding are used on V4L2, and ALSA SoC is using
> different style of DT today. Now ALSA SoC supports simple-card driver
> for generic/simple sound card.
> In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
> between V4L2 / ALSA should be merged.
> This patch adds new Audio Graph Card which is OF-graph base of
> simple-card
>
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> ---
> v3 -> v4
>
> - use "label"
> - use "dai-format"
> - don't use prefix
>
> sound/soc/generic/Kconfig | 8 +
> sound/soc/generic/Makefile | 2 +
> sound/soc/generic/audio-graph-card.c | 301 +++++++++++++++++++++++++++++++++++
> 3 files changed, 311 insertions(+)
> create mode 100644 sound/soc/generic/audio-graph-card.c
>
> diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
> index d023959..121a48e 100644
> --- a/sound/soc/generic/Kconfig
> +++ b/sound/soc/generic/Kconfig
> @@ -14,3 +14,11 @@ 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_AUDIO_GRAPH_CARD
> + tristate "ASoC Audio Graph sound card support"
> + depends on OF
> + select SND_SIMPLE_CARD_UTILS
> + help
> + This option enables generic simple simple sound card support
> + with OF-graph DT bindings.
> diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
> index ee750f3..670068f 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-audio-graph-card-objs := audio-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_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o
> diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
> new file mode 100644
> index 0000000..07afdfa
> --- /dev/null
> +++ b/sound/soc/generic/audio-graph-card.c
> @@ -0,0 +1,301 @@
> +/*
> + * ASoC audio 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 graph_card_data {
> + struct snd_soc_card snd_card;
> + struct graph_dai_props {
> + struct asoc_simple_dai cpu_dai;
> + struct asoc_simple_dai codec_dai;
> + } *dai_props;
> + struct snd_soc_dai_link *dai_link;
> +};
> +
> +#define graph_priv_to_dev(priv) ((priv)->snd_card.dev)
> +#define graph_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
> +#define graph_priv_to_props(priv, i) ((priv)->dai_props + (i))
> +
> +static int asoc_graph_card_startup(struct snd_pcm_substream *substream)
> +{
> + struct snd_soc_pcm_runtime *rtd = substream->private_data;
> + struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
> + struct graph_dai_props *dai_props =
> + graph_priv_to_props(priv, rtd->num);
> + 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_graph_card_shutdown(struct snd_pcm_substream *substream)
> +{
> + struct snd_soc_pcm_runtime *rtd = substream->private_data;
> + struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
> + struct graph_dai_props *dai_props =
> + graph_priv_to_props(priv, rtd->num);
> +
> + clk_disable_unprepare(dai_props->cpu_dai.clk);
> +
> + clk_disable_unprepare(dai_props->codec_dai.clk);
> +}
> +
> +static struct snd_soc_ops asoc_graph_card_ops = {
> + .startup = asoc_graph_card_startup,
> + .shutdown = asoc_graph_card_shutdown,
> +};
> +
> +static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd)
> +{
> + struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
> + struct snd_soc_dai *codec = rtd->codec_dai;
> + struct snd_soc_dai *cpu = rtd->cpu_dai;
> + struct graph_dai_props *dai_props =
> + graph_priv_to_props(priv, rtd->num);
> + int ret;
> +
> + ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
> + if (ret < 0)
> + return ret;
> +
> + ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
> + struct graph_card_data *priv,
> + int idx)
> +{
> + struct device *dev = graph_priv_to_dev(priv);
> + struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, idx);
> + struct graph_dai_props *dai_props = graph_priv_to_props(priv, idx);
> + struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
> + struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
> + struct device_node *cpu_ep = of_get_next_child(cpu_port, NULL);
> + struct device_node *codec_ep = of_graph_get_remote_endpoint(cpu_ep);
> + struct device_node *rcpu_ep = of_graph_get_remote_endpoint(codec_ep);
> + int ret;
> +
> + if (rcpu_ep != cpu_ep) {
> + dev_err(dev, "remote-endpoint missmatch (%s/%s/%s)\n",
> + cpu_ep->name, codec_ep->name, rcpu_ep->name);
> + return -EINVAL;
> + }
We should have this check in dtc rather than the kernel.
> +
> + ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
> + NULL, &dai_link->dai_fmt);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + /*
> + * we need to consider "mclk-fs" around here
> + * see simple-card
> + */
> +
> + ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + ret = snd_soc_of_parse_tdm_slot(cpu_ep,
> + &cpu_dai->tx_slot_mask,
> + &cpu_dai->rx_slot_mask,
> + &cpu_dai->slots,
> + &cpu_dai->slot_width);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + ret = snd_soc_of_parse_tdm_slot(codec_ep,
> + &codec_dai->tx_slot_mask,
> + &codec_dai->rx_slot_mask,
> + &codec_dai->slots,
> + &codec_dai->slot_width);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + ret = asoc_simple_card_canonicalize_dailink(dai_link);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + ret = asoc_simple_card_set_dailink_name(dev, dai_link,
> + "%s-%s",
> + dai_link->cpu_dai_name,
> + dai_link->codec_dai_name);
> + if (ret < 0)
> + goto dai_link_of_err;
> +
> + dai_link->ops = &asoc_graph_card_ops;
> + dai_link->init = asoc_graph_card_dai_init;
> +
> + dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
> + dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
> + dev_dbg(dev, "\tcpu : %s / %d\n",
> + dai_link->cpu_dai_name,
> + dai_props->cpu_dai.sysclk);
> + dev_dbg(dev, "\tcodec : %s / %d\n",
> + dai_link->codec_dai_name,
> + dai_props->codec_dai.sysclk);
> +
> + asoc_simple_card_canonicalize_cpu(dai_link,
> + priv->snd_card.num_links == 1);
> +
> +dai_link_of_err:
> + of_node_put(codec_ep);
> +
> + return ret;
> +}
> +
> +static int asoc_graph_card_parse_of(struct device *dev,
> + struct graph_card_data *priv)
> +{
> + struct device_node *node = dev->of_node;
> + struct snd_soc_card *card = &priv->snd_card;
> + struct device_node *np;
> + int idx = 0;
> + int ret;
> +
> + /*
> + * we need to consider "widgets", "routing", "mclk-fs" around here
> + * see simple-card
> + */
> +
> + while ((np = of_parse_phandle(node, "dais", idx))) {
of_for_each_phandle
> + ret = asoc_graph_card_dai_link_of(np, priv, idx++);
> + if (ret < 0)
> + return ret;
> + }
> +
> + return asoc_simple_card_parse_card_name(card, NULL);
> +}
> +
> +static int asoc_graph_get_dais_count(struct device *dev)
> +{
> + struct device_node *node = dev->of_node;
> + int count = 0;
> +
> + if (of_get_property(node, "dais", NULL)) {
> + while (of_parse_phandle(node, "dais", count))
of_for_each_phandle
> + count++;
> + } else {
> + count = 1;
This should be an error or 0, right?
> + }
> +
> + return count;
> +}
> +
> +static int asoc_graph_card_probe(struct platform_device *pdev)
> +{
> + struct graph_card_data *priv;
> + struct snd_soc_dai_link *dai_link;
> + struct graph_dai_props *dai_props;
> + struct device *dev = &pdev->dev;
> + int num, ret;
> +
> + /* Allocate the private data and the DAI link array */
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + num = asoc_graph_get_dais_count(dev);
> +
> + dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
> + dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL);
> + if (!dai_props || !dai_link)
> + return -ENOMEM;
> +
> + priv->dai_props = dai_props;
> + priv->dai_link = dai_link;
> +
> + /* Init snd_soc_card */
> + priv->snd_card.owner = THIS_MODULE;
> + priv->snd_card.dev = dev;
> + priv->snd_card.dai_link = dai_link;
> + priv->snd_card.num_links = num;
> +
> + ret = asoc_graph_card_parse_of(dev, priv);
> + if (ret < 0) {
> + if (ret != -EPROBE_DEFER)
> + dev_err(dev, "parse error %d\n", ret);
> + goto err;
> + }
> +
> + snd_soc_card_set_drvdata(&priv->snd_card, priv);
> +
> + ret = devm_snd_soc_register_card(dev, &priv->snd_card);
> + if (ret >= 0)
> + return ret;
> +err:
> + asoc_simple_card_clean_reference(&priv->snd_card);
> +
> + return ret;
> +}
> +
> +static int asoc_graph_card_remove(struct platform_device *pdev)
> +{
> + struct snd_soc_card *card = platform_get_drvdata(pdev);
> + struct graph_card_data *priv = snd_soc_card_get_drvdata(card);
> +
> + return asoc_simple_card_clean_reference(&priv->snd_card);
> +}
> +
> +static const struct of_device_id asoc_graph_of_match[] = {
> + { .compatible = "audio-graph-card", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, asoc_graph_of_match);
> +
> +static struct platform_driver asoc_graph_card = {
> + .driver = {
> + .name = "asoc-audio-graph-card",
> + .of_match_table = asoc_graph_of_match,
> + },
> + .probe = asoc_graph_card_probe,
> + .remove = asoc_graph_card_remove,
> +};
> +module_platform_driver(asoc_graph_card);
> +
> +MODULE_ALIAS("platform:asoc-audio-graph-card");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("ASoC Audio Graph Sound Card");
> +MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 9/9] ASoC: add audio-graph-card support
2017-03-20 20:32 ` Rob Herring
@ 2017-03-21 2:08 ` Kuninori Morimoto
0 siblings, 0 replies; 26+ messages in thread
From: Kuninori Morimoto @ 2017-03-21 2:08 UTC (permalink / raw)
To: Rob Herring; +Cc: Linux-DT, Linux-ALSA, Mark Brown, Simon
Hi Rob
Thank you for your review
> > + if (rcpu_ep != cpu_ep) {
> > + dev_err(dev, "remote-endpoint missmatch (%s/%s/%s)\n",
> > + cpu_ep->name, codec_ep->name, rcpu_ep->name);
> > + return -EINVAL;
> > + }
>
> We should have this check in dtc rather than the kernel.
We can remove this if dtc could support it
> > + while ((np = of_parse_phandle(node, "dais", idx))) {
>
> of_for_each_phandle
(snip)
> > + if (of_get_property(node, "dais", NULL)) {
> > + while (of_parse_phandle(node, "dais", count))
>
> of_for_each_phandle
Thanks. will use it
> > + count++;
> > + } else {
> > + count = 1;
>
> This should be an error or 0, right?
Yes, thanks. will do
Best regards
---
Kuninori Morimoto
^ permalink raw reply [flat|nested] 26+ messages in thread