linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v10 1/9] ASoC: kirkwood: dynamically build the DAI array
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
@ 2015-01-19 17:15 ` Jean-Francois Moine
  2015-01-19 17:38 ` [PATCH v10 2/9] ASoC: kirkwood: check the DAI type from the DAI name Jean-Francois Moine
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-19 17:15 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

This patch prepares the driver to the creation of the DAIs from a graph
of ports.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 sound/soc/kirkwood/kirkwood-i2s.c | 108 ++++++++++++++------------------------
 sound/soc/kirkwood/kirkwood.h     |   1 +
 2 files changed, 40 insertions(+), 69 deletions(-)

diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index def7d82..62d9c12 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -438,49 +438,8 @@ static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
 	.set_fmt        = kirkwood_i2s_set_fmt,
 };
 
-static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = {
-    {
-	.name = "i2s",
-	.id = 0,
-	.playback = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-				SNDRV_PCM_RATE_96000,
-		.formats = KIRKWOOD_I2S_FORMATS,
-	},
-	.capture = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-				SNDRV_PCM_RATE_96000,
-		.formats = KIRKWOOD_I2S_FORMATS,
-	},
-	.ops = &kirkwood_i2s_dai_ops,
-    },
-    {
-	.name = "spdif",
-	.id = 1,
-	.playback = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-				SNDRV_PCM_RATE_96000,
-		.formats = KIRKWOOD_SPDIF_FORMATS,
-	},
-	.capture = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-				SNDRV_PCM_RATE_96000,
-		.formats = KIRKWOOD_SPDIF_FORMATS,
-	},
-	.ops = &kirkwood_i2s_dai_ops,
-    },
-};
-
-static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
-    {
+/* DAI sample for I2S and external clock */
+static struct snd_soc_dai_driver kirkwood_i2s_dai_i2s_ext = {
 	.name = "i2s",
 	.id = 0,
 	.playback = {
@@ -500,42 +459,52 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
 		.formats = KIRKWOOD_I2S_FORMATS,
 	},
 	.ops = &kirkwood_i2s_dai_ops,
-    },
-    {
-	.name = "spdif",
-	.id = 1,
-	.playback = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_CONTINUOUS,
-		.rate_min = 5512,
-		.rate_max = 192000,
-		.formats = KIRKWOOD_SPDIF_FORMATS,
-	},
-	.capture = {
-		.channels_min = 1,
-		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_CONTINUOUS,
-		.rate_min = 5512,
-		.rate_max = 192000,
-		.formats = KIRKWOOD_SPDIF_FORMATS,
-	},
-	.ops = &kirkwood_i2s_dai_ops,
-    },
 };
 
 static const struct snd_soc_component_driver kirkwood_i2s_component = {
 	.name		= DRV_NAME,
 };
 
+/* create the DAIs */
+static int kirkwood_i2s_create_dais(struct kirkwood_dma_data *priv)
+{
+	int i, ndai, dai[2];
+
+	ndai = 2;
+	dai[0] = 0;		/* i2s(0) - spdif(1) */
+	dai[1] = 1;
+	for (i = 0; i < ndai; i++) {
+		memcpy(&priv->dais[i], &kirkwood_i2s_dai_i2s_ext,
+				sizeof(priv->dais[0]));
+		priv->dais[i].id = i;
+		if (dai[i] == 1) {
+			priv->dais[i].name = "spdif";
+			priv->dais[i].playback.formats =
+						KIRKWOOD_SPDIF_FORMATS;
+			priv->dais[i].capture.formats =
+						KIRKWOOD_SPDIF_FORMATS;
+		}
+		if (IS_ERR(priv->extclk)) {
+			priv->dais[i].playback.rates =
+						SNDRV_PCM_RATE_44100 |
+						SNDRV_PCM_RATE_48000 |
+						SNDRV_PCM_RATE_96000;
+			priv->dais[i].capture.rates =
+						SNDRV_PCM_RATE_44100 |
+						SNDRV_PCM_RATE_48000 |
+						SNDRV_PCM_RATE_96000;
+		}
+	}
+	return ndai;
+}
+
 static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 {
 	struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
-	struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai;
 	struct kirkwood_dma_data *priv;
 	struct resource *mem;
 	struct device_node *np = pdev->dev.of_node;
-	int err;
+	int err, ndais;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
@@ -585,7 +554,6 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 		} else {
 			dev_info(&pdev->dev, "found external clock\n");
 			clk_prepare_enable(priv->extclk);
-			soc_dai = kirkwood_i2s_dai_extclk;
 		}
 	}
 
@@ -602,8 +570,10 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
 	}
 
+	ndais = kirkwood_i2s_create_dais(priv);
+
 	err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
-					 soc_dai, 2);
+					 priv->dais, ndais);
 	if (err) {
 		dev_err(&pdev->dev, "snd_soc_register_component failed\n");
 		goto err_component;
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
index 90e32a7..a24d2c2 100644
--- a/sound/soc/kirkwood/kirkwood.h
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -135,6 +135,7 @@ struct kirkwood_dma_data {
 	void __iomem *io;
 	struct clk *clk;
 	struct clk *extclk;
+	struct snd_soc_dai_driver dais[2];
 	uint32_t ctl_play;
 	uint32_t ctl_rec;
 	struct snd_pcm_substream *substream_play;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 2/9] ASoC: kirkwood: check the DAI type from the DAI name
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
  2015-01-19 17:15 ` [PATCH v10 1/9] ASoC: kirkwood: dynamically build the DAI array Jean-Francois Moine
@ 2015-01-19 17:38 ` Jean-Francois Moine
  2015-01-19 18:50 ` [PATCH v10 3/9] ASoC: kirkwood: accept the DAI definitions from a graph of ports Jean-Francois Moine
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-19 17:38 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

When the DAIs are created from a graph of ports, their types are not tied
to their ID.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 sound/soc/kirkwood/kirkwood-i2s.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 62d9c12..357f963 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -263,7 +263,7 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_START:
 		/* configure */
 		ctl = priv->ctl_play;
-		if (dai->id == 0)
+		if (dai->name[0] == 'i')
 			ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN;	/* i2s */
 		else
 			ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN;	/* spdif */
@@ -331,7 +331,7 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_START:
 		/* configure */
 		ctl = priv->ctl_rec;
-		if (dai->id == 0)
+		if (dai->name[0] == 'i')
 			ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN;	/* i2s */
 		else
 			ctl &= ~KIRKWOOD_RECCTL_I2S_EN;		/* spdif */
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 3/9] ASoC: kirkwood: accept the DAI definitions from a graph of ports
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
  2015-01-19 17:15 ` [PATCH v10 1/9] ASoC: kirkwood: dynamically build the DAI array Jean-Francois Moine
  2015-01-19 17:38 ` [PATCH v10 2/9] ASoC: kirkwood: check the DAI type from the DAI name Jean-Francois Moine
@ 2015-01-19 18:50 ` Jean-Francois Moine
  2015-01-20  9:27 ` [PATCH v10 4/9] drm/i2c: tda998x: Add support of a DT " Jean-Francois Moine
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-19 18:50 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

By default, both output ports 0 (I2S) and 1 (S/PDIF) are defined.
A graph of port permits to define only the really connected ports of
the board and to identify the remote ends.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 .../devicetree/bindings/sound/mvebu-audio.txt      | 30 ++++++++++++++++
 sound/soc/kirkwood/kirkwood-i2s.c                  | 41 ++++++++++++++++++----
 sound/soc/kirkwood/kirkwood.h                      |  3 +-
 3 files changed, 67 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/mvebu-audio.txt b/Documentation/devicetree/bindings/sound/mvebu-audio.txt
index cb8c07c..ae81bf1 100644
--- a/Documentation/devicetree/bindings/sound/mvebu-audio.txt
+++ b/Documentation/devicetree/bindings/sound/mvebu-audio.txt
@@ -23,6 +23,19 @@ Required properties:
 	"internal" for the internal clock
 	"extclk" for the external clock
 
+Optional nodes:
+
+- port: one or two ports.
+  Each port must contain the following property:
+
+  - port-type: must be "i2s" or "spdif"
+
+  and the following node:
+
+  - endpoint: reference of the remote endpoint - see [1]
+
+[1] Documentation/devicetree/bindings/graph.txt
+
 Example:
 
 i2s1: audio-controller@b4000 {
@@ -31,4 +44,21 @@ i2s1: audio-controller@b4000 {
 	interrupts = <21>, <22>;
 	clocks = <&gate_clk 13>;
 	clock-names = "internal";
+
+	port@0 {
+		port-type = "spdif";
+		audio1_spdif0: endpoint@0 {
+			remote-endpoint = <&spdif_out>;
+		};
+		audio1_spdif1: endpoint@1 {
+			remote-endpoint = <&tda998x_spdif>;
+		};
+	};
+	port@1 {
+		port-type = "i2s";
+		audio1_i2s: endpoint {
+			remote-endpoint = <&tda998x_i2s>;
+		};
+	};
+
 };
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 357f963..8e62bb8 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -466,13 +466,42 @@ static const struct snd_soc_component_driver kirkwood_i2s_component = {
 };
 
 /* create the DAIs */
-static int kirkwood_i2s_create_dais(struct kirkwood_dma_data *priv)
+static int kirkwood_i2s_create_dais(struct device_node *np,
+				struct kirkwood_dma_data *priv)
 {
-	int i, ndai, dai[2];
+	struct device_node *of_port;
+	const char *name;
+	int i, ret, ndai, dai[2];
 
-	ndai = 2;
-	dai[0] = 0;		/* i2s(0) - spdif(1) */
-	dai[1] = 1;
+	ndai = 0;
+	if (np) {
+		for_each_child_of_node(np, of_port) {
+			if (!of_port->name ||
+			     of_node_cmp(of_port->name, "port") != 0)
+				continue;
+			ret = of_property_read_string(of_port,
+						"port-type",
+						&name);
+			if (ret)
+				continue;
+			if (strcmp(name, "i2s") == 0) {
+				dai[ndai] = 0;
+			} else if (strcmp(name, "spdif") == 0) {
+				dai[ndai] = 1;
+			} else {
+				continue;
+			}
+			if (++ndai >= 2)
+				break;
+		}
+	}
+	if (ndai == 0) {		/* no DT or no port */
+		ndai = 2;
+		dai[0] = 0;		/* i2s(0) - spdif(1) */
+		dai[1] = 1;
+	} else {
+		priv->is_graph = 1;	/* graph of the ports */
+	}
 	for (i = 0; i < ndai; i++) {
 		memcpy(&priv->dais[i], &kirkwood_i2s_dai_i2s_ext,
 				sizeof(priv->dais[0]));
@@ -570,7 +599,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
 	}
 
-	ndais = kirkwood_i2s_create_dais(priv);
+	ndais = kirkwood_i2s_create_dais(np, priv);
 
 	err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
 					 priv->dais, ndais);
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
index a24d2c2..b4cbefe 100644
--- a/sound/soc/kirkwood/kirkwood.h
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -141,7 +141,8 @@ struct kirkwood_dma_data {
 	struct snd_pcm_substream *substream_play;
 	struct snd_pcm_substream *substream_rec;
 	int irq;
-	int burst;
+	short burst;
+	short is_graph;
 };
 
 extern struct snd_soc_platform_driver kirkwood_soc_platform;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 4/9] drm/i2c: tda998x: Add support of a DT graph of ports
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (2 preceding siblings ...)
  2015-01-19 18:50 ` [PATCH v10 3/9] ASoC: kirkwood: accept the DAI definitions from a graph of ports Jean-Francois Moine
@ 2015-01-20  9:27 ` Jean-Francois Moine
  2015-01-20 11:16 ` [PATCH v10 5/9] drm/i2c: tda998x: Change drvdata for audio extension Jean-Francois Moine
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-20  9:27 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

Two kinds of ports may be declared in a DT graph of ports: video and audio.
This patch accepts the port value from a video port as an alternative
to the video-ports property.
It also accepts audio ports in the case the transmitter is not used as
a slave encoder.
The new file include/sound/tda998x.h prepares to the definition of
a tda998x CODEC.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 .../devicetree/bindings/drm/i2c/tda998x.txt        | 51 +++++++++++++
 drivers/gpu/drm/i2c/tda998x_drv.c                  | 88 +++++++++++++++++++---
 include/sound/tda998x.h                            |  8 ++
 3 files changed, 138 insertions(+), 9 deletions(-)
 create mode 100644 include/sound/tda998x.h

diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
index e9e4bce..35f6a80 100644
--- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
+++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
@@ -16,6 +16,35 @@ Optional properties:
 
   - video-ports: 24 bits value which defines how the video controller
 	output is wired to the TDA998x input - default: <0x230145>
+	This property is not used when ports are defined.
+
+Optional nodes:
+
+  - port: up to three ports.
+	The ports are defined according to [1].
+
+    Video port.
+	There may be only one video port.
+	This one must contain the following property:
+
+	- port-type: must be "rgb"
+
+	and may contain the optional property:
+
+	- reg: 24 bits value which defines how the video controller
+		output is wired to the TDA998x input (video pins)
+		When absent, the default value is <0x230145>.
+
+    Audio ports.
+	There may be one or two audio ports.
+	These ones must contain the following properties:
+
+	- port-type: must be "i2s" or "spdif"
+
+	- reg: 8 bits value which defines how the audio controller
+		output is wired to the TDA998x input (audio pins)
+
+[1] Documentation/devicetree/bindings/graph.txt
 
 Example:
 
@@ -26,4 +55,26 @@ Example:
 		interrupts = <27 2>;		/* falling edge */
 		pinctrl-0 = <&pmx_camera>;
 		pinctrl-names = "default";
+
+		port@230145 {
+			port-type = "rgb";
+			reg = <0x230145>;
+			hdmi_0: endpoint {
+				remote-endpoint = <&lcd0_0>;
+			};
+		};
+		port@3 {			/* AP1 = I2S */
+			port-type = "i2s";
+			reg = <0x03>;
+			tda998x_i2s: endpoint {
+				remote-endpoint = <&audio1_i2s>;
+			};
+		};
+		port@4 {			 /* AP2 = S/PDIF */
+			port-type = "spdif";
+			reg = <0x04>;
+			tda998x_spdif: endpoint {
+				remote-endpoint = <&audio1_spdif1>;
+			};
+		};
 	};
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index d476279..cf245ce 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -26,6 +26,7 @@
 #include <drm/drm_encoder_slave.h>
 #include <drm/drm_edid.h>
 #include <drm/i2c/tda998x.h>
+#include <sound/tda998x.h>
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
@@ -44,6 +45,8 @@ struct tda998x_priv {
 	wait_queue_head_t wq_edid;
 	volatile int wq_edid_wait;
 	struct drm_encoder *encoder;
+
+	struct tda998x_audio_s audio;
 };
 
 #define to_tda998x_priv(x)  ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv)
@@ -1250,9 +1253,57 @@ static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = {
 
 /* I2C driver functions */
 
+static int tda998x_parse_ports(struct tda998x_priv *priv,
+				struct device_node *np)
+{
+	struct device_node *of_port;
+	const char *port_type;
+	int ret, audio_index, reg, afmt;
+
+	audio_index = 0;
+	for_each_child_of_node(np, of_port) {
+		if (!of_port->name
+		 || of_node_cmp(of_port->name, "port") != 0)
+			continue;
+		ret = of_property_read_string(of_port, "port-type",
+					&port_type);
+		if (ret < 0)
+			continue;
+		ret = of_property_read_u32(of_port, "reg", &reg);
+		if (strcmp(port_type, "rgb") == 0) {
+			if (!ret) {		/* video reg is optional */
+				priv->vip_cntrl_0 = reg >> 16;
+				priv->vip_cntrl_1 = reg >> 8;
+				priv->vip_cntrl_2 = reg;
+			}
+			continue;
+		}
+		if (strcmp(port_type, "i2s") == 0)
+			afmt = AFMT_I2S;
+		else if (strcmp(port_type, "spdif") == 0)
+			afmt = AFMT_SPDIF;
+		else
+			continue;
+		if (ret < 0) {
+			dev_err(&priv->hdmi->dev, "missing reg for %s\n",
+				port_type);
+			return ret;
+		}
+		if (audio_index >= ARRAY_SIZE(priv->audio.ports)) {
+			dev_err(&priv->hdmi->dev, "too many audio ports\n");
+			break;
+		}
+		priv->audio.ports[audio_index] = reg;
+		priv->audio.port_types[audio_index] = afmt;
+		audio_index++;
+	}
+	return 0;
+}
+
 static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 {
 	struct device_node *np = client->dev.of_node;
+	struct device_node *of_port;
 	u32 video;
 	int rev_lo, rev_hi, ret;
 
@@ -1351,15 +1402,34 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 	/* enable EDID read irq: */
 	reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
 
-	if (!np)
-		return 0;		/* non-DT */
-
-	/* get the optional video properties */
-	ret = of_property_read_u32(np, "video-ports", &video);
-	if (ret == 0) {
-		priv->vip_cntrl_0 = video >> 16;
-		priv->vip_cntrl_1 = video >> 8;
-		priv->vip_cntrl_2 = video;
+	/* get the device tree parameters */
+	if (np) {
+		of_port = of_get_child_by_name(np, "port");
+		if (of_port) {				/* graph of ports */
+			of_node_put(of_port);
+			ret = tda998x_parse_ports(priv, np);
+			if (ret < 0)
+				goto fail;
+
+			/* initialize the default audio configuration */
+			if (priv->audio.ports[0]) {
+				priv->params.audio_cfg = priv->audio.ports[0];
+				priv->params.audio_format =
+						priv->audio.port_types[0];
+				priv->params.audio_clk_cfg =
+					priv->params.audio_format ==
+							AFMT_SPDIF ? 0 : 1;
+			}
+		} else {
+
+			/* optional video properties */
+			ret = of_property_read_u32(np, "video-ports", &video);
+			if (ret == 0) {
+				priv->vip_cntrl_0 = video >> 16;
+				priv->vip_cntrl_1 = video >> 8;
+				priv->vip_cntrl_2 = video;
+			}
+		}
 	}
 
 	return 0;
diff --git a/include/sound/tda998x.h b/include/sound/tda998x.h
new file mode 100644
index 0000000..487a809
--- /dev/null
+++ b/include/sound/tda998x.h
@@ -0,0 +1,8 @@
+#ifndef SND_TDA998X_H
+#define SND_TDA998X_H
+
+struct tda998x_audio_s {
+	u8 ports[2];			/* AP value */
+	u8 port_types[2];		/* AFMT_xxx */
+};
+#endif
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 5/9] drm/i2c: tda998x: Change drvdata for audio extension
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (3 preceding siblings ...)
  2015-01-20  9:27 ` [PATCH v10 4/9] drm/i2c: tda998x: Add support of a DT " Jean-Francois Moine
@ 2015-01-20 11:16 ` Jean-Francois Moine
  2015-01-20 15:38 ` [PATCH v10 6/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-20 11:16 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

The device drvdata is used for component bind, but points to the
encoder/connector structure which is hidden from the slave encoder.
For audio extension, the slave encoder private data must be accessible,
so, this patch changes drvdata to the slave encoder private data and
sets it in case of slave encoder use.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index cf245ce..b35f35f 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1465,6 +1465,8 @@ static int tda998x_encoder_init(struct i2c_client *client,
 	encoder_slave->slave_priv = priv;
 	encoder_slave->slave_funcs = &tda998x_encoder_slave_funcs;
 
+	dev_set_drvdata(&client->dev, priv);
+
 	return 0;
 }
 
@@ -1591,7 +1593,7 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
 	if (!priv)
 		return -ENOMEM;
 
-	dev_set_drvdata(dev, priv);
+	dev_set_drvdata(dev, &priv->base);
 
 	priv->base.encoder = &priv->encoder;
 	priv->connector.interlace_allowed = 1;
@@ -1641,7 +1643,9 @@ err_encoder:
 static void tda998x_unbind(struct device *dev, struct device *master,
 			   void *data)
 {
-	struct tda998x_priv2 *priv = dev_get_drvdata(dev);
+	struct tda998x_priv *priv_s = dev_get_drvdata(dev);
+	struct tda998x_priv2 *priv =
+			container_of(priv_s, struct tda998x_priv2, base);
 
 	drm_connector_cleanup(&priv->connector);
 	drm_encoder_cleanup(&priv->encoder);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 6/9] ASoC: tda998x: add a codec to the HDMI transmitter
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (4 preceding siblings ...)
  2015-01-20 11:16 ` [PATCH v10 5/9] drm/i2c: tda998x: Change drvdata for audio extension Jean-Francois Moine
@ 2015-01-20 15:38 ` Jean-Francois Moine
  2015-01-20 16:50 ` [PATCH v10 7/9] drm/i2c: tda998x: set cts_n according to the sample width Jean-Francois Moine
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-20 15:38 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

The tda998x CODEC maintains the audio format and rate constraints according
to the HDMI device parameters (EDID) and sets dynamically the input ports
in the TDA998x I2C driver on start/stop audio streaming.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 124 +++++++++++++++++++++++++++
 include/sound/tda998x.h           |  22 +++++
 sound/soc/codecs/Kconfig          |   5 ++
 sound/soc/codecs/Makefile         |   2 +
 sound/soc/codecs/tda998x.c        | 174 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 327 insertions(+)
 create mode 100644 sound/soc/codecs/tda998x.c

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index b35f35f..a2cfc11 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/irq.h>
 #include <sound/asoundef.h>
+#include <linux/platform_device.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
@@ -730,6 +731,104 @@ tda998x_configure_audio(struct tda998x_priv *priv,
 	tda998x_write_aif(priv, p);
 }
 
+#if IS_ENABLED(CONFIG_SND_SOC_TDA998X)
+/* tda998x audio codec interface */
+
+/* return the audio parameters */
+static int tda998x_get_audio_var(struct device *dev,
+				struct tda998x_audio_s **tda998x_audio)
+{
+	struct tda998x_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv->encoder->crtc
+	 || !priv->is_hdmi_sink)
+		return -ENODEV;
+
+	*tda998x_audio = &priv->audio;
+	return 0;
+}
+
+/* switch the audio port and initialize the audio parameters for streaming */
+static int tda998x_set_audio_input(struct device *dev,
+				int port_index,
+				unsigned sample_rate)
+{
+	struct tda998x_priv *priv = dev_get_drvdata(dev);
+	struct tda998x_encoder_params *p = &priv->params;
+
+	if (!priv->encoder->crtc)
+		return -ENODEV;
+
+	/* if no port, just disable the audio port */
+	if (port_index == PORT_NONE) {
+		reg_write(priv, REG_ENA_AP, 0);
+		return 0;
+	}
+
+	/* if same audio parameters, just enable the audio port */
+	if (p->audio_cfg == priv->audio.ports[port_index] &&
+	    p->audio_sample_rate == sample_rate) {
+		reg_write(priv, REG_ENA_AP, p->audio_cfg);
+		return 0;
+	}
+
+	p->audio_format = priv->audio.port_types[port_index];
+	p->audio_clk_cfg = p->audio_format == AFMT_SPDIF ? 0 : 1;
+	p->audio_cfg = priv->audio.ports[port_index];
+	p->audio_sample_rate = sample_rate;
+	tda998x_configure_audio(priv, &priv->encoder->crtc->hwmode, p);
+	return 0;
+}
+
+/* get the audio capabilities from the EDID */
+static void tda998x_get_audio_caps(struct tda998x_priv *priv,
+				struct drm_connector *connector)
+{
+	u8 *eld = connector->eld;
+	u8 *sad;
+	int sad_count;
+	unsigned eld_ver, mnl;
+	u8 max_channels, rate_mask, fmt;
+
+	/* adjust the hw params from the ELD (EDID) */
+	eld_ver = eld[DRM_ELD_VER] >> DRM_ELD_VER_SHIFT;
+	if (eld_ver != 2 && eld_ver != 31)
+		return;
+
+	mnl = drm_eld_mnl(eld);
+	if (mnl > 16)
+		return;
+
+	sad_count = drm_eld_sad_count(eld);
+	sad = eld + DRM_ELD_CEA_SAD(mnl, 0);
+
+	/* Start from the basic audio settings */
+	max_channels = 1;
+	rate_mask = 0;
+	fmt = 0;
+	while (sad_count--) {
+		switch (sad[0] & 0x78) {
+		case 0x08:			/* SAD uncompressed audio */
+			if ((sad[0] & 7) > max_channels)
+				max_channels = sad[0] & 7;
+			rate_mask |= sad[1];
+			fmt |= sad[2] & 0x07;
+			break;
+		}
+		sad += 3;
+	}
+
+	priv->audio.cea_sad.channels = max_channels;
+	priv->audio.cea_sad.freq = rate_mask;
+	priv->audio.cea_sad.format = fmt;
+}
+
+static struct tda998x_ops_s tda998x_codec_ops = {
+	.get_audio_var = tda998x_get_audio_var,
+	.set_audio_input = tda998x_set_audio_input,
+};
+#endif /* SND_SOC */
+
 /* DRM encoder functions */
 
 static void tda998x_encoder_set_config(struct tda998x_priv *priv,
@@ -749,6 +848,8 @@ static void tda998x_encoder_set_config(struct tda998x_priv *priv,
 			    (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
 
 	priv->params = *p;
+	priv->audio.port_types[0] = p->audio_format;
+	priv->audio.ports[0] = p->audio_cfg;
 }
 
 static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
@@ -1142,6 +1243,14 @@ tda998x_encoder_get_modes(struct tda998x_priv *priv,
 		drm_mode_connector_update_edid_property(connector, edid);
 		n = drm_add_edid_modes(connector, edid);
 		priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid);
+
+#if IS_ENABLED(CONFIG_SND_SOC_TDA998X)
+		/* set the audio parameters from the EDID */
+		if (priv->is_hdmi_sink) {
+			drm_edid_to_eld(connector, edid);
+			tda998x_get_audio_caps(priv, connector);
+		}
+#endif
 		kfree(edid);
 	}
 
@@ -1176,6 +1285,11 @@ static void tda998x_destroy(struct tda998x_priv *priv)
 	if (priv->hdmi->irq)
 		free_irq(priv->hdmi->irq, priv);
 
+#if IS_ENABLED(CONFIG_SND_SOC_TDA998X)
+	if (priv->audio.ports[0])
+		tda9998x_codec_unregister(&priv->hdmi->dev);
+#endif
+
 	i2c_unregister_device(priv->cec);
 }
 
@@ -1311,6 +1425,9 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 	priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1);
 	priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5);
 
+	priv->params.audio_frame[1] = 1;		/* channels - 1 */
+	priv->params.audio_sample_rate = 48000;		/* 48kHz */
+
 	priv->current_page = 0xff;
 	priv->hdmi = client;
 	priv->cec = i2c_new_dummy(client->adapter, 0x34);
@@ -1419,6 +1536,13 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 				priv->params.audio_clk_cfg =
 					priv->params.audio_format ==
 							AFMT_SPDIF ? 0 : 1;
+
+#if IS_ENABLED(CONFIG_SND_SOC_TDA998X)
+				/* and create the audio CODEC */
+				tda9998x_codec_register(&client->dev,
+							&priv->audio,
+							&tda998x_codec_ops);
+#endif
 			}
 		} else {
 
diff --git a/include/sound/tda998x.h b/include/sound/tda998x.h
index 487a809..b4b747b 100644
--- a/include/sound/tda998x.h
+++ b/include/sound/tda998x.h
@@ -1,8 +1,30 @@
 #ifndef SND_TDA998X_H
 #define SND_TDA998X_H
 
+#include <drm/drm_edid.h>
+
+/* port index for audio stream stop */
+#define PORT_NONE (-1)
+
 struct tda998x_audio_s {
 	u8 ports[2];			/* AP value */
 	u8 port_types[2];		/* AFMT_xxx */
+#if IS_ENABLED(CONFIG_SND_SOC_TDA998X)
+	struct cea_sad cea_sad;		/* Short Audio Descriptor */
+	void *codec_priv;
+#endif
 };
+
+struct tda998x_ops_s {
+	int (*get_audio_var)(struct device *dev,
+			struct tda998x_audio_s **tda998x_audio);
+	int (*set_audio_input)(struct device *dev,
+			int port_index,
+			unsigned sample_rate);
+};
+
+int tda9998x_codec_register(struct device *dev,
+			struct tda998x_audio_s *tda998x_audio_i,
+			struct tda998x_ops_s *tda998x_ops);
+void tda9998x_codec_unregister(struct device *dev);
 #endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 8349f98..d3b1db0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -102,6 +102,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
 	select SND_SOC_TAS2552 if I2C
 	select SND_SOC_TAS5086 if I2C
+	select SND_SOC_TDA998X if DRM_I2C_NXP_TDA998X
 	select SND_SOC_TFA9879 if I2C
 	select SND_SOC_TLV320AIC23_I2C if I2C
 	select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
@@ -600,6 +601,10 @@ config SND_SOC_TAS5086
 	tristate "Texas Instruments TAS5086 speaker amplifier"
 	depends on I2C
 
+config SND_SOC_TDA998X
+	def_tristate y
+	depends on DRM_I2C_NXP_TDA998X
+
 config SND_SOC_TFA9879
 	tristate "NXP Semiconductors TFA9879 amplifier"
 	depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index bbdfd1e..44b4fda 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -104,6 +104,7 @@ snd-soc-sta350-objs := sta350.o
 snd-soc-sta529-objs := sta529.o
 snd-soc-stac9766-objs := stac9766.o
 snd-soc-tas5086-objs := tas5086.o
+snd-soc-tda998x-objs := tda998x.o
 snd-soc-tfa9879-objs := tfa9879.o
 snd-soc-tlv320aic23-objs := tlv320aic23.o
 snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
@@ -282,6 +283,7 @@ obj-$(CONFIG_SND_SOC_STA529)   += snd-soc-sta529.o
 obj-$(CONFIG_SND_SOC_STAC9766)	+= snd-soc-stac9766.o
 obj-$(CONFIG_SND_SOC_TAS2552)	+= snd-soc-tas2552.o
 obj-$(CONFIG_SND_SOC_TAS5086)	+= snd-soc-tas5086.o
+obj-$(CONFIG_SND_SOC_TDA998X)	+= snd-soc-tda998x.o
 obj-$(CONFIG_SND_SOC_TFA9879)	+= snd-soc-tfa9879.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23)	+= snd-soc-tlv320aic23.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C)	+= snd-soc-tlv320aic23-i2c.o
diff --git a/sound/soc/codecs/tda998x.c b/sound/soc/codecs/tda998x.c
new file mode 100644
index 0000000..0a186e7
--- /dev/null
+++ b/sound/soc/codecs/tda998x.c
@@ -0,0 +1,174 @@
+/*
+ * ALSA SoC TDA998x CODEC
+ *
+ * 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 <linux/module.h>
+#include <sound/soc.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <sound/pcm_params.h>
+#include <drm/i2c/tda998x.h>
+#include <sound/tda998x.h>
+
+/* functions in tda998x_drv */
+static struct tda998x_ops_s *tda998x_ops;
+
+static int tda998x_codec_startup(struct snd_pcm_substream *substream,
+			struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct tda998x_audio_s *tda998x_audio;
+	struct snd_pcm_hw_constraint_list *rate_constraints;
+#define SAD_FMT_16 0x01		/* format values in the sad */
+#define SAD_FMT_20 0x02
+#define SAD_FMT_24 0x04
+	u64 formats;
+	int ret;
+	static const u32 hdmi_rates[] = {
+		32000, 44100, 48000, 88200, 96000, 176400, 192000
+	};
+
+	/* get the audio variables */
+	ret = tda998x_ops->get_audio_var(dai->dev, &tda998x_audio);
+	if (ret < 0)
+		return ret;			/* no screen */
+
+	/* convert the EDID values to audio constraints */
+	rate_constraints = tda998x_audio->codec_priv;
+	rate_constraints->list = hdmi_rates;
+	rate_constraints->count = ARRAY_SIZE(hdmi_rates);
+	rate_constraints->mask = tda998x_audio->cea_sad.freq;
+	snd_pcm_hw_constraint_list(runtime, 0,
+				   SNDRV_PCM_HW_PARAM_RATE,
+				   rate_constraints);
+
+	formats = 0;
+	if (tda998x_audio->cea_sad.format & SAD_FMT_16)
+		formats |= SNDRV_PCM_FMTBIT_S16_LE;
+	if (tda998x_audio->cea_sad.format & SAD_FMT_20)
+		formats |= SNDRV_PCM_FMTBIT_S20_3LE;
+	if (tda998x_audio->cea_sad.format & SAD_FMT_24)
+		formats |= SNDRV_PCM_FMTBIT_S24_LE |
+			   SNDRV_PCM_FMTBIT_S24_3LE |
+			   SNDRV_PCM_FMTBIT_S32_LE;
+	snd_pcm_hw_constraint_mask64(runtime,
+				SNDRV_PCM_HW_PARAM_FORMAT,
+				formats);
+
+	snd_pcm_hw_constraint_minmax(runtime,
+				SNDRV_PCM_HW_PARAM_CHANNELS,
+				1, tda998x_audio->cea_sad.channels + 1);
+	return 0;
+}
+
+/* ask the HDMI transmitter to activate the audio input port */
+static int tda998x_codec_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *params,
+				   struct snd_soc_dai *dai)
+{
+	return tda998x_ops->set_audio_input(dai->dev, dai->id,
+					params_rate(params));
+}
+
+static void tda998x_codec_shutdown(struct snd_pcm_substream *substream,
+				   struct snd_soc_dai *dai)
+{
+	tda998x_ops->set_audio_input(dai->dev, PORT_NONE, 0);
+}
+
+static const struct snd_soc_dai_ops tda998x_codec_ops = {
+	.startup = tda998x_codec_startup,
+	.hw_params = tda998x_codec_hw_params,
+	.shutdown = tda998x_codec_shutdown,
+};
+
+#define TDA998X_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
+			SNDRV_PCM_FMTBIT_S20_3LE | \
+			SNDRV_PCM_FMTBIT_S24_LE | \
+			SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver tda998x_dai_i2s = {
+	.name = "i2s-hifi",
+	.playback = {
+		.stream_name	= "HDMI I2S Playback",
+		.channels_min	= 1,
+		.channels_max	= 8,
+		.rates		= SNDRV_PCM_RATE_CONTINUOUS,
+		.rate_min	= 5512,
+		.rate_max	= 192000,
+		.formats	= TDA998X_FORMATS,
+	},
+	.ops = &tda998x_codec_ops,
+};
+
+static const struct snd_soc_dapm_widget tda998x_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("hdmi-out"),
+};
+static const struct snd_soc_dapm_route tda998x_routes[] = {
+	{ "hdmi-out", NULL, "HDMI I2S Playback" },
+	{ "hdmi-out", NULL, "HDMI SPDIF Playback" },
+};
+
+static struct snd_soc_codec_driver tda998x_codec_drv = {
+	.dapm_widgets = tda998x_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tda998x_widgets),
+	.dapm_routes = tda998x_routes,
+	.num_dapm_routes = ARRAY_SIZE(tda998x_routes),
+	.ignore_pmdown_time = true,
+};
+
+int tda9998x_codec_register(struct device *dev,
+			struct tda998x_audio_s *tda998x_audio,
+			struct tda998x_ops_s *tda998x_ops_i)
+{
+	struct snd_pcm_hw_constraint_list *codec_priv;
+	struct snd_soc_dai_driver *dais, *p_dai;
+	int i, ndais;
+
+	tda998x_ops = tda998x_ops_i;
+
+	codec_priv = devm_kzalloc(dev, sizeof(*codec_priv), GFP_KERNEL);
+	if (!codec_priv)
+		return -ENOMEM;
+	tda998x_audio->codec_priv = codec_priv;
+
+	/* build the DAIs */
+	for (ndais = 0; ndais < ARRAY_SIZE(tda998x_audio->ports); ndais++) {
+		if (!tda998x_audio->ports[ndais])
+			break;
+	}
+	dais = devm_kzalloc(dev, sizeof(*dais) * ndais, GFP_KERNEL);
+	if (!dais)
+		return -ENOMEM;
+	for (i = 0, p_dai = dais; i < ndais ; i++, p_dai++) {
+		memcpy(p_dai, &tda998x_dai_i2s, sizeof(*p_dai));
+		p_dai->id = i;
+		if (tda998x_audio->port_types[i] == AFMT_SPDIF) {
+			p_dai->name = "spdif-hifi";
+			p_dai->playback.stream_name = "HDMI SPDIF Playback";
+			p_dai->playback.channels_max = 2;
+			p_dai->playback.rate_min = 22050;
+		}
+	}
+
+	return snd_soc_register_codec(dev,
+				&tda998x_codec_drv,
+				dais, ndais);
+}
+EXPORT_SYMBOL(tda9998x_codec_register);
+
+void tda9998x_codec_unregister(struct device *dev)
+{
+	snd_soc_unregister_codec(dev);
+}
+EXPORT_SYMBOL(tda9998x_codec_unregister);
+
+MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
+MODULE_DESCRIPTION("TDA998X CODEC");
+MODULE_LICENSE("GPL");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 7/9] drm/i2c: tda998x: set cts_n according to the sample width
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (5 preceding siblings ...)
  2015-01-20 15:38 ` [PATCH v10 6/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
@ 2015-01-20 16:50 ` Jean-Francois Moine
  2015-01-20 18:47 ` [PATCH v10 8/9] ASoC: core: export snd_soc_get_dai_name Jean-Francois Moine
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-20 16:50 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

With I2S input, the CTS_N predivider depends on the audio sample width.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 21 ++++++++++++++++++---
 include/sound/tda998x.h           |  4 +++-
 sound/soc/codecs/tda998x.c        |  5 +++--
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index a2cfc11..adf34e0 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -28,6 +28,7 @@
 #include <drm/drm_edid.h>
 #include <drm/i2c/tda998x.h>
 #include <sound/tda998x.h>
+#include <sound/pcm.h>
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
@@ -663,7 +664,17 @@ tda998x_configure_audio(struct tda998x_priv *priv,
 		reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_I2S);
 		clksel_aip = AIP_CLKSEL_AIP_I2S;
 		clksel_fs = AIP_CLKSEL_FS_ACLK;
-		cts_n = CTS_N_M(3) | CTS_N_K(3);
+
+		/* with I2S input, the CTS_N predivider depends on
+		 * the sample width */
+		switch (priv->audio.sample_format) {
+		case SNDRV_PCM_FORMAT_S16_LE:
+			cts_n = CTS_N_M(3) | CTS_N_K(1);
+			break;
+		default:
+			cts_n = CTS_N_M(3) | CTS_N_K(3);
+			break;
+		}
 		break;
 
 	default:
@@ -751,7 +762,8 @@ static int tda998x_get_audio_var(struct device *dev,
 /* switch the audio port and initialize the audio parameters for streaming */
 static int tda998x_set_audio_input(struct device *dev,
 				int port_index,
-				unsigned sample_rate)
+				unsigned sample_rate,
+				int sample_format)
 {
 	struct tda998x_priv *priv = dev_get_drvdata(dev);
 	struct tda998x_encoder_params *p = &priv->params;
@@ -767,7 +779,8 @@ static int tda998x_set_audio_input(struct device *dev,
 
 	/* if same audio parameters, just enable the audio port */
 	if (p->audio_cfg == priv->audio.ports[port_index] &&
-	    p->audio_sample_rate == sample_rate) {
+	    p->audio_sample_rate == sample_rate &&
+	    priv->audio.sample_format == sample_format) {
 		reg_write(priv, REG_ENA_AP, p->audio_cfg);
 		return 0;
 	}
@@ -776,6 +789,7 @@ static int tda998x_set_audio_input(struct device *dev,
 	p->audio_clk_cfg = p->audio_format == AFMT_SPDIF ? 0 : 1;
 	p->audio_cfg = priv->audio.ports[port_index];
 	p->audio_sample_rate = sample_rate;
+	priv->audio.sample_format = sample_format;
 	tda998x_configure_audio(priv, &priv->encoder->crtc->hwmode, p);
 	return 0;
 }
@@ -1427,6 +1441,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 
 	priv->params.audio_frame[1] = 1;		/* channels - 1 */
 	priv->params.audio_sample_rate = 48000;		/* 48kHz */
+	priv->audio.sample_format = SNDRV_PCM_FORMAT_S24_LE;
 
 	priv->current_page = 0xff;
 	priv->hdmi = client;
diff --git a/include/sound/tda998x.h b/include/sound/tda998x.h
index b4b747b..a870c40 100644
--- a/include/sound/tda998x.h
+++ b/include/sound/tda998x.h
@@ -9,6 +9,7 @@
 struct tda998x_audio_s {
 	u8 ports[2];			/* AP value */
 	u8 port_types[2];		/* AFMT_xxx */
+	int sample_format;
 #if IS_ENABLED(CONFIG_SND_SOC_TDA998X)
 	struct cea_sad cea_sad;		/* Short Audio Descriptor */
 	void *codec_priv;
@@ -20,7 +21,8 @@ struct tda998x_ops_s {
 			struct tda998x_audio_s **tda998x_audio);
 	int (*set_audio_input)(struct device *dev,
 			int port_index,
-			unsigned sample_rate);
+			unsigned sample_rate,
+			int sample_format);
 };
 
 int tda9998x_codec_register(struct device *dev,
diff --git a/sound/soc/codecs/tda998x.c b/sound/soc/codecs/tda998x.c
index 0a186e7..fece8d2 100644
--- a/sound/soc/codecs/tda998x.c
+++ b/sound/soc/codecs/tda998x.c
@@ -73,13 +73,14 @@ static int tda998x_codec_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_soc_dai *dai)
 {
 	return tda998x_ops->set_audio_input(dai->dev, dai->id,
-					params_rate(params));
+					params_rate(params),
+					params_format(params));
 }
 
 static void tda998x_codec_shutdown(struct snd_pcm_substream *substream,
 				   struct snd_soc_dai *dai)
 {
-	tda998x_ops->set_audio_input(dai->dev, PORT_NONE, 0);
+	tda998x_ops->set_audio_input(dai->dev, PORT_NONE, 0, 0);
 }
 
 static const struct snd_soc_dai_ops tda998x_codec_ops = {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 8/9] ASoC: core: export snd_soc_get_dai_name
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (6 preceding siblings ...)
  2015-01-20 16:50 ` [PATCH v10 7/9] drm/i2c: tda998x: set cts_n according to the sample width Jean-Francois Moine
@ 2015-01-20 18:47 ` Jean-Francois Moine
  2015-01-20 19:16 ` [PATCH v10 9/9] ASoC: add generic dt-card support Jean-Francois Moine
  2015-04-27 11:33 ` [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jyri Sarha
  9 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-20 18:47 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

snd_soc_get_dai_name() may be used to define a sound card with
a different syntax from the one of the simple-card.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 include/sound/soc.h  | 2 ++
 sound/soc/soc-core.c | 5 +++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index edd4a0a..7e783d6 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1502,6 +1502,8 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
 int snd_soc_of_get_dai_link_codecs(struct device *dev,
 				   struct device_node *of_node,
 				   struct snd_soc_dai_link *dai_link);
+int snd_soc_get_dai_name(struct of_phandle_args *args,
+			 const char **dai_name);
 
 #include <sound/soc-dai.h>
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ededb97..6a782ca 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3418,8 +3418,8 @@ 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,
-				const char **dai_name)
+int snd_soc_get_dai_name(struct of_phandle_args *args,
+			 const char **dai_name)
 {
 	struct snd_soc_component *pos;
 	int ret = -EPROBE_DEFER;
@@ -3465,6 +3465,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)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 9/9] ASoC: add generic dt-card support
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (7 preceding siblings ...)
  2015-01-20 18:47 ` [PATCH v10 8/9] ASoC: core: export snd_soc_get_dai_name Jean-Francois Moine
@ 2015-01-20 19:16 ` Jean-Francois Moine
  2015-01-21 13:50   ` Mark Brown
  2015-04-27 11:33 ` [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jyri Sarha
  9 siblings, 1 reply; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-20 19:16 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

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 <moinejf@free.fr>
---
 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 0000000..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 <linux/module.h>
+#include <sound/soc.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+/* 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",
+					&name);
+	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, of_port) {
+		if (!asoc_dt_card_is_audio_port(of_port))
+			continue;
+
+		link->platform_of_node =
+			link->cpu_of_node = of_cpu;
+		args.args[0] = ilink;
+		ret = snd_soc_get_dai_name(&args, &link->cpu_dai_name);
+		if (ret) {
+			dev_err(dev, "no CPU DAI name for link %d!\n",
+				ilink);
+			continue;
+		}
+
+		/* count the number of codecs of this DAI link */
+		ncodecs = 0;
+		for_each_child_of_node(of_port, of_endpoint) {
+			if (of_parse_phandle(of_endpoint,
+					"remote-endpoint", 0))
+				ncodecs++;
+		}
+		if (ncodecs == 0)
+			continue;
+		component = devm_kzalloc(dev,
+					 sizeof(*component) * ncodecs,
+					 GFP_KERNEL);
+		if (!component)
+			return -ENOMEM;
+		link->codecs = component;
+
+		icodec = 0;
+		args2.args_count = 1;
+		for_each_child_of_node(of_port, of_endpoint) {
+			of_remote_endpoint = of_parse_phandle(of_endpoint,
+						"remote-endpoint", 0);
+			if (!of_remote_endpoint)
+				continue;
+			component->of_node = of_codec =
+					of_remote_endpoint->parent->parent;
+			args2.np = of_codec;
+			args2.args[0] = asoc_dt_card_get_dai_number(of_codec,
+							of_remote_endpoint);
+			ret = snd_soc_get_dai_name(&args2,
+						   &component->dai_name);
+			if (ret) {
+				if (ret == -EPROBE_DEFER) {
+					card->num_links = ilink + 1;
+					link->num_codecs = icodec;
+					return ret;
+				}
+				dev_err(dev,
+					"no CODEC DAI name for link %d\n",
+					ilink);
+				continue;
+			}
+			of_node_get(of_codec);
+
+			icodec++;
+			if (icodec >= ncodecs)
+				break;
+			component++;
+		}
+		if (icodec == 0)
+			continue;
+		link->num_codecs = icodec;
+
+		ilink++;
+		if (ilink >= nlinks)
+			break;
+		link++;
+	}
+	card->num_links = ilink;
+
+	return ilink;
+}
+
+static void asoc_dt_card_unref(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct snd_soc_dai_link *link;
+	int nlinks, ncodecs;
+
+	if (card) {
+		for (nlinks = 0, link = card->dai_link;
+		     nlinks < card->num_links;
+		     nlinks++, link++) {
+			for (ncodecs = 0;
+			     ncodecs < link->num_codecs;
+			     ncodecs++)
+				of_node_put(card->dai_link->codecs[ncodecs].of_node);
+		}
+	}
+}
+
+/*
+ * The platform data contains the pointer to the device node
+ * which starts the description of the graph of the audio ports,
+ * This device node is usually the audio controller.
+ */
+static int asoc_dt_card_probe(struct platform_device *pdev)
+{
+	struct device_node **p_np = pdev->dev.platform_data;
+	struct device_node *of_cpu = *p_np;
+	struct snd_soc_card *card;
+	struct snd_soc_dai_link *link;
+	char *name;
+	int ret, i;
+
+	card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
+	if (!card)
+		return -ENOMEM;
+	ret = asoc_dt_card_of_parse_graph(&pdev->dev, of_cpu, card);
+	if (ret < 0)
+		goto err;
+
+	/* fill the remaining values of the card */
+	card->owner = THIS_MODULE;
+	card->dev = &pdev->dev;
+	card->name = "DT-card";
+	for (i = 0, link = card->dai_link;
+	     i < card->num_links;
+	     i++, link++) {
+		name = devm_kzalloc(&pdev->dev,
+				strlen(link->cpu_dai_name) +
+					strlen(link->codecs[0].dai_name) +
+					2,
+				GFP_KERNEL);
+		if (!name) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		sprintf(name, "%s-%s", link->cpu_dai_name,
+					link->codecs[0].dai_name);
+		link->name = link->stream_name = name;
+	}
+
+	card->dai_link->dai_fmt =
+		snd_soc_of_parse_daifmt(of_cpu, "dt-audio-card,",
+					NULL, NULL) &
+			~SND_SOC_DAIFMT_MASTER_MASK;
+
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+	if (ret >= 0)
+		return ret;
+
+err:
+	asoc_dt_card_unref(pdev);
+	return ret;
+}
+
+static int asoc_dt_card_remove(struct platform_device *pdev)
+{
+	asoc_dt_card_unref(pdev);
+	snd_soc_unregister_card(platform_get_drvdata(pdev));
+	return 0;
+}
+
+static struct platform_driver asoc_dt_card = {
+	.driver = {
+		.name = "asoc-dt-card",
+	},
+	.probe = asoc_dt_card_probe,
+	.remove = asoc_dt_card_remove,
+};
+
+module_platform_driver(asoc_dt_card);
+
+MODULE_ALIAS("platform:asoc-dt-card");
+MODULE_DESCRIPTION("ASoC DT Sound Card");
+MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
+MODULE_LICENSE("GPL");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter
@ 2015-01-20 19:35 Jean-Francois Moine
  2015-01-19 17:15 ` [PATCH v10 1/9] ASoC: kirkwood: dynamically build the DAI array Jean-Francois Moine
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-01-20 19:35 UTC (permalink / raw)
  To: Mark Brown, Russell King - ARM Linux
  Cc: Dave Airlie, Andrew Jackson, Jyri Sarha, alsa-devel, devicetree,
	dri-devel, linux-kernel

Based on broonie/ASoC

v10:
	- add the generic dt-card
	- define the audio ports from a DT graph of ports (Russell King)
	- reuse HDMI constants (Andrew Jackson - Jyri Sarha)
	- alloc rate_constraints in codec (Jyri Sarha)
	- fix bad number of channels (Jyri Sarha)
	- correct codec generation from config (Russell King - Jyri Sarha)
	- no module init/exit (Russell King)
v9:
	- back to a TDA998x specific CODEC
	- more comments
	- change magic values to constants
v8:
	- change some comments about the patches
v7:
	- remove the change of the K predivider (Jyri Sarha)
	- add S24_3LE and S32_LE as possible audio formats (Jyri Sarha)
	- don't move the struct priv2 definition and use the
	  slave encoder private data as the device private data
	  (Russell King)
	- remove the useless request_module (Russell King/Mark Brown)
	- don't lock the HDMI module (Russell King)
	- use platform_device_unregister to remove the codec
	  (Russell King)
v6:
	- extend the HDMI CODEC instead of using a specific CODEC
v5:
	- use the TDA998x private data instead of a specific area
	  for the CODEC interface
	- the CODEC is TDA998x specific (Mark Brown)
v4:
	- remove all the TDA998x specific stuff from the CODEC
	- move the EDID scan from the CODEC to the TDA998x
	- move the CODEC to sound/soc (Mark Brown)
	- update the audio_sample_rate from the EDID (Andrew Jackson)
v3: fix bad rate (Andrew Jackson)
v2: check double stream start (Mark Brown)

Jean-Francois Moine (9):
  ASoC: kirkwood: dynamically build the DAI array
  ASoC: kirkwood: check the DAI type from the DAI name
  ASoC: kirkwood: accept the DAI definitions from a graph of ports
  drm/i2c: tda998x: Add support of a DT graph of ports
  drm/i2c: tda998x: Change drvdata for audio extension
  ASoC: tda998x: add a codec to the HDMI transmitter
  drm/i2c: tda998x: set cts_n according to the sample width
  ASoC: core: export snd_soc_get_dai_name
  ASoC: add generic dt-card support

 .../devicetree/bindings/drm/i2c/tda998x.txt        |  51 ++++
 .../devicetree/bindings/sound/mvebu-audio.txt      |  30 +++
 drivers/gpu/drm/i2c/tda998x_drv.c                  | 237 +++++++++++++++++-
 include/sound/soc.h                                |   2 +
 include/sound/tda998x.h                            |  32 +++
 sound/soc/codecs/Kconfig                           |   5 +
 sound/soc/codecs/Makefile                          |   2 +
 sound/soc/codecs/tda998x.c                         | 175 +++++++++++++
 sound/soc/generic/Kconfig                          |   2 +
 sound/soc/generic/Makefile                         |   2 +
 sound/soc/generic/dt-card.c                        | 275 +++++++++++++++++++++
 sound/soc/kirkwood/kirkwood-i2s.c                  | 141 ++++++-----
 sound/soc/kirkwood/kirkwood.h                      |   4 +-
 sound/soc/soc-core.c                               |   5 +-
 14 files changed, 877 insertions(+), 86 deletions(-)
 create mode 100644 include/sound/tda998x.h
 create mode 100644 sound/soc/codecs/tda998x.c
 create mode 100644 sound/soc/generic/dt-card.c

-- 
2.1.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v10 9/9] ASoC: add generic dt-card support
  2015-01-20 19:16 ` [PATCH v10 9/9] ASoC: add generic dt-card support Jean-Francois Moine
@ 2015-01-21 13:50   ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2015-01-21 13:50 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Russell King - ARM Linux, Dave Airlie, Andrew Jackson,
	Jyri Sarha, alsa-devel, devicetree, dri-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1258 bytes --]

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.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter
  2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
                   ` (8 preceding siblings ...)
  2015-01-20 19:16 ` [PATCH v10 9/9] ASoC: add generic dt-card support Jean-Francois Moine
@ 2015-04-27 11:33 ` Jyri Sarha
  2015-04-27 18:25   ` Jean-Francois Moine
  9 siblings, 1 reply; 14+ messages in thread
From: Jyri Sarha @ 2015-04-27 11:33 UTC (permalink / raw)
  To: Jean-Francois Moine; +Cc: alsa-devel, dri-devel, linux-kernel

Hi,
Have you done anything about the tda998x audio support lately?

I was thinking of taking a shot at this now that I finally seem to have 
some time for it. However, if you are just about to send another series 
I'll wait for that first and see what makes the most sense after that.

My plan is to do something really simple first. No graph bindings or 
anything fancy like that. Just a minimal dt-binding to for audio pin 
configuration and use simple-card for the rest. I still try to make it 
possible to support spdif and i2s at the same time, but I can not test 
it as I do not have such HW.

I also try to make the ASoC part as generic as possible, so that it 
could be reused by other HDMI encoders with spdif or i2s interface.

Best regards,
Jyri

On 01/20/15 21:35, Jean-Francois Moine wrote:
> Based on broonie/ASoC
>
> v10:
> 	- add the generic dt-card
> 	- define the audio ports from a DT graph of ports (Russell King)
> 	- reuse HDMI constants (Andrew Jackson - Jyri Sarha)
> 	- alloc rate_constraints in codec (Jyri Sarha)
> 	- fix bad number of channels (Jyri Sarha)
> 	- correct codec generation from config (Russell King - Jyri Sarha)
> 	- no module init/exit (Russell King)
> v9:
> 	- back to a TDA998x specific CODEC
> 	- more comments
> 	- change magic values to constants
> v8:
> 	- change some comments about the patches
> v7:
> 	- remove the change of the K predivider (Jyri Sarha)
> 	- add S24_3LE and S32_LE as possible audio formats (Jyri Sarha)
> 	- don't move the struct priv2 definition and use the
> 	  slave encoder private data as the device private data
> 	  (Russell King)
> 	- remove the useless request_module (Russell King/Mark Brown)
> 	- don't lock the HDMI module (Russell King)
> 	- use platform_device_unregister to remove the codec
> 	  (Russell King)
> v6:
> 	- extend the HDMI CODEC instead of using a specific CODEC
> v5:
> 	- use the TDA998x private data instead of a specific area
> 	  for the CODEC interface
> 	- the CODEC is TDA998x specific (Mark Brown)
> v4:
> 	- remove all the TDA998x specific stuff from the CODEC
> 	- move the EDID scan from the CODEC to the TDA998x
> 	- move the CODEC to sound/soc (Mark Brown)
> 	- update the audio_sample_rate from the EDID (Andrew Jackson)
> v3: fix bad rate (Andrew Jackson)
> v2: check double stream start (Mark Brown)
>
> Jean-Francois Moine (9):
>    ASoC: kirkwood: dynamically build the DAI array
>    ASoC: kirkwood: check the DAI type from the DAI name
>    ASoC: kirkwood: accept the DAI definitions from a graph of ports
>    drm/i2c: tda998x: Add support of a DT graph of ports
>    drm/i2c: tda998x: Change drvdata for audio extension
>    ASoC: tda998x: add a codec to the HDMI transmitter
>    drm/i2c: tda998x: set cts_n according to the sample width
>    ASoC: core: export snd_soc_get_dai_name
>    ASoC: add generic dt-card support
>
>   .../devicetree/bindings/drm/i2c/tda998x.txt        |  51 ++++
>   .../devicetree/bindings/sound/mvebu-audio.txt      |  30 +++
>   drivers/gpu/drm/i2c/tda998x_drv.c                  | 237 +++++++++++++++++-
>   include/sound/soc.h                                |   2 +
>   include/sound/tda998x.h                            |  32 +++
>   sound/soc/codecs/Kconfig                           |   5 +
>   sound/soc/codecs/Makefile                          |   2 +
>   sound/soc/codecs/tda998x.c                         | 175 +++++++++++++
>   sound/soc/generic/Kconfig                          |   2 +
>   sound/soc/generic/Makefile                         |   2 +
>   sound/soc/generic/dt-card.c                        | 275 +++++++++++++++++++++
>   sound/soc/kirkwood/kirkwood-i2s.c                  | 141 ++++++-----
>   sound/soc/kirkwood/kirkwood.h                      |   4 +-
>   sound/soc/soc-core.c                               |   5 +-
>   14 files changed, 877 insertions(+), 86 deletions(-)
>   create mode 100644 include/sound/tda998x.h
>   create mode 100644 sound/soc/codecs/tda998x.c
>   create mode 100644 sound/soc/generic/dt-card.c
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter
  2015-04-27 11:33 ` [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jyri Sarha
@ 2015-04-27 18:25   ` Jean-Francois Moine
  2015-04-28  7:10     ` Jean-Francois Moine
  0 siblings, 1 reply; 14+ messages in thread
From: Jean-Francois Moine @ 2015-04-27 18:25 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: alsa-devel, dri-devel, linux-kernel

On Mon, 27 Apr 2015 14:33:45 +0300
Jyri Sarha <jsarha@ti.com> wrote:

> Have you done anything about the tda998x audio support lately?
> 
> I was thinking of taking a shot at this now that I finally seem to have 
> some time for it. However, if you are just about to send another series 
> I'll wait for that first and see what makes the most sense after that.
> 
> My plan is to do something really simple first. No graph bindings or 
> anything fancy like that. Just a minimal dt-binding to for audio pin 
> configuration and use simple-card for the rest. I still try to make it 
> possible to support spdif and i2s at the same time, but I can not test 
> it as I do not have such HW.
> 
> I also try to make the ASoC part as generic as possible, so that it 
> could be reused by other HDMI encoders with spdif or i2s interface.

Hi Jyri,

I was busy on an other work, so, I did not advance on the tda998x.

If you look at the patch series, it contains 3 independant parts:
- dynamic building of the DAIs in the kirkwood audio controller,
- audio CODEC of the tda998x
- DT card based on audio graph

It seems that only the last part raised a problem.
Otherwise, the simple card works fine with the 2 first parts.

I am merging my patches in 4.1-rc1, and, as soon as I get an image on
my screen :), I will resubmit a patch series but about the tda998x
codec only.

Using i2s and s/pdif at the same time with the simple card asks for a
patch as the one I submitted in february 2014 (ASoC: simple-card: DT
fix and multi DAI links extension). As I am using my DT card, I will
not resubmit it. Eventually, the kirkwood patches are not critical.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter
  2015-04-27 18:25   ` Jean-Francois Moine
@ 2015-04-28  7:10     ` Jean-Francois Moine
  0 siblings, 0 replies; 14+ messages in thread
From: Jean-Francois Moine @ 2015-04-28  7:10 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: alsa-devel, linux-kernel, dri-devel

On Mon, 27 Apr 2015 20:25:02 +0200
Jean-Francois Moine <moinejf@free.fr> wrote:

> Using i2s and s/pdif at the same time with the simple card asks for a
> patch as the one I submitted in february 2014 (ASoC: simple-card: DT
> fix and multi DAI links extension).

Sorry, the patch was "ASoC: simple-card: Add multi-CODEC support"
submitted in january 2015:

http://mailman.alsa-project.org/pipermail/alsa-devel/2015-January/085855.html

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-04-28  7:08 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-20 19:35 [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
2015-01-19 17:15 ` [PATCH v10 1/9] ASoC: kirkwood: dynamically build the DAI array Jean-Francois Moine
2015-01-19 17:38 ` [PATCH v10 2/9] ASoC: kirkwood: check the DAI type from the DAI name Jean-Francois Moine
2015-01-19 18:50 ` [PATCH v10 3/9] ASoC: kirkwood: accept the DAI definitions from a graph of ports Jean-Francois Moine
2015-01-20  9:27 ` [PATCH v10 4/9] drm/i2c: tda998x: Add support of a DT " Jean-Francois Moine
2015-01-20 11:16 ` [PATCH v10 5/9] drm/i2c: tda998x: Change drvdata for audio extension Jean-Francois Moine
2015-01-20 15:38 ` [PATCH v10 6/9] ASoC: tda998x: add a codec to the HDMI transmitter Jean-Francois Moine
2015-01-20 16:50 ` [PATCH v10 7/9] drm/i2c: tda998x: set cts_n according to the sample width Jean-Francois Moine
2015-01-20 18:47 ` [PATCH v10 8/9] ASoC: core: export snd_soc_get_dai_name Jean-Francois Moine
2015-01-20 19:16 ` [PATCH v10 9/9] ASoC: add generic dt-card support Jean-Francois Moine
2015-01-21 13:50   ` Mark Brown
2015-04-27 11:33 ` [PATCH v10 0/9] ASoC: tda998x: add a codec to the HDMI transmitter Jyri Sarha
2015-04-27 18:25   ` Jean-Francois Moine
2015-04-28  7:10     ` Jean-Francois Moine

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).