[PATCH v10 9/9] ASoC: add generic dt-card support

2015-01-21 Thread Mark Brown
On Tue, Jan 20, 2015 at 08:16:25PM +0100, Jean-Francois Moine wrote:
> To create simple cards, the syntax of the simple-card does not follow
> the common binding of the device graphs
> (Documentation/devicetree/bindings/graph.txt).

Please be more specific, I really can't tell what this is supposed to be
doing from the above - in what way is the binding not common and why
would anyone care?  Please also address why this is done as a completely
separate implementation rather than a new revision of simple-card and CC
Morimoto-san so he can review (given that he did simple-card initially).

>  sound/soc/generic/Kconfig   |   2 +
>  sound/soc/generic/Makefile  |   2 +
>  sound/soc/generic/dt-card.c | 275 
> 
>  3 files changed, 279 insertions(+)
>  create mode 100644 sound/soc/generic/dt-card.c

As you know all device tree bindings require binding documents; you must
supply a binding document.  I'm not going to look at any DT patches that
don't include binding documentation.

In general please pay attention to changelogs and documentation when
submitting patches, the harder it is to understand what a patch is
supposed to do or why the harder it is to review.  I keep saying this,
it's really important.
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: 



[PATCH v10 9/9] ASoC: add generic dt-card support

2015-01-20 Thread Jean-Francois Moine
To create simple cards, the syntax of the simple-card does not follow
the common binding of the device graphs
(Documentation/devicetree/bindings/graph.txt).

dt-card devices are created by audio controllers with themselves as the
root of the graph. The sound card is created according to the parameters
found in the tree.

Signed-off-by: Jean-Francois Moine 
---
 sound/soc/generic/Kconfig   |   2 +
 sound/soc/generic/Makefile  |   2 +
 sound/soc/generic/dt-card.c | 275 
 3 files changed, 279 insertions(+)
 create mode 100644 sound/soc/generic/dt-card.c

diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index 610f612..9c5e1e2 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -2,3 +2,5 @@ config SND_SIMPLE_CARD
tristate "ASoC Simple sound card support"
help
  This option enables generic simple sound card support
+config SND_DT_CARD
+   tristate
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 9c3b246..56834a9 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,3 +1,5 @@
 snd-soc-simple-card-objs   := simple-card.o
+snd-soc-dt-card-objs   := dt-card.o

 obj-$(CONFIG_SND_SIMPLE_CARD)  += snd-soc-simple-card.o
+obj-$(CONFIG_SND_DT_CARD)  += snd-soc-dt-card.o
diff --git a/sound/soc/generic/dt-card.c b/sound/soc/generic/dt-card.c
new file mode 100644
index 000..6a5de2f
--- /dev/null
+++ b/sound/soc/generic/dt-card.c
@@ -0,0 +1,275 @@
+/*
+ * ALSA SoC DT based sound card support
+ *
+ * Copyright (C) 2015 Jean-Francois Moine
+ *
+ * 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 
+#include 
+#include 
+#include 
+
+/* check if a node is an audio port */
+static int asoc_dt_card_is_audio_port(struct device_node *of_port)
+{
+   const char *name;
+   int ret;
+
+   if (!of_port->name ||
+   of_node_cmp(of_port->name, "port") != 0)
+   return 0;
+   ret = of_property_read_string(of_port,
+   "port-type",
+   );
+   if (!ret &&
+   (strcmp(name, "i2s") == 0 ||
+strcmp(name, "spdif") == 0))
+   return 1;
+   return 0;
+}
+
+/*
+ * Get the DAI number from the DT by counting the audio ports
+ * of the remote device node (codec).
+ */
+static int asoc_dt_card_get_dai_number(struct device_node *of_codec,
+   struct device_node *of_remote_endpoint)
+{
+   struct device_node *of_port, *of_endpoint;
+   int ndai;
+
+   ndai = 0;
+   for_each_child_of_node(of_codec, of_port) {
+   if (!asoc_dt_card_is_audio_port(of_port))
+   continue;
+   for_each_child_of_node(of_port, of_endpoint) {
+   if (!of_endpoint->name ||
+   of_node_cmp(of_endpoint->name, "endpoint") != 0)
+   continue;
+   if (of_endpoint == of_remote_endpoint) {
+   of_node_put(of_port);
+   of_node_put(of_endpoint);
+   return ndai;
+   }
+   }
+   ndai++;
+   }
+   return 0;   /* should never be reached */
+}
+
+/*
+ * Parse a graph of audio ports
+ * @dev: Card device
+ * @of_cpu: Device node of the audio controller
+ * @card: Card definition
+ *
+ * Builds the DAI links of the card from the DT graph of audio ports
+ * starting from the audio controller.
+ * It does not handle the port groups.
+ * The CODEC device nodes in the DAI links must be dereferenced by the caller.
+ *
+ * Returns the number of DAI links or (< 0) on error
+ */
+static int asoc_dt_card_of_parse_graph(struct device *dev,
+   struct device_node *of_cpu,
+   struct snd_soc_card *card)
+{
+   struct device_node *of_codec, *of_port, *of_endpoint,
+   *of_remote_endpoint;
+   struct snd_soc_dai_link *link;
+   struct snd_soc_dai_link_component *component;
+   struct of_phandle_args args, args2;
+   int ret, ilink, icodec, nlinks, ncodecs;
+
+   /* count the number of DAI links */
+   nlinks = 0;
+   for_each_child_of_node(of_cpu, of_port) {
+   if (asoc_dt_card_is_audio_port(of_port))
+   nlinks++;
+   }
+
+   /* allocate the DAI link array */
+   link = devm_kzalloc(dev, sizeof(*link) * nlinks, GFP_KERNEL);
+   if (!link)
+   return -ENOMEM;
+   card->dai_link = link;
+
+   /* build the DAI links */
+   ilink = 0;
+   args.np = of_cpu;
+   args.args_count = 1;
+   for_each_child_of_node(of_cpu,