Skip to contentSkip to conversation

Implement generic ASoC HDMI codec and use it in tda998x

RFC PATCH Superseded Jyri Sarha 9 participants 21 messages Sep 18, 2015 – Sep 24, 2015 4 messages not in the archive

Subsystems (6)

v4 of 9 Superseded Latest is v9 →

lore
Share & tools
lore

Jyri Sarha

author
#0 lore raw

v4 cover Implement generic ASoC HDMI codec and use it in tda998x

Changes since RFC v3,
ASoC side:
- Add "ALSA: pcm: add IEC958 channel status helper for hw_params"
- Add "tda998x: Improve tda998x_configure_audio() audio related pdata"
- use snd_pcm_create_iec958_consumer_hw_params() to construct the stream header
- Remove set_clk() callback from hdmi-codec. It is not needed for now.
- Refer to stream header in AIF as specified in HDMI standard
- Set current_stream to NULL only after video side audio_shutdown() has been called. Avoid potential race if video side attempts to abort audio at the same time.
- No need to have video side device pointer in the hdmi codec's pdata as it is found from dev->parent.
- Fix hdmi-codec enum: DAI_ID_I2C > DAI_ID_I2S
- Improve audio_startup API comment
- Make improved checkpatch happy
- BUG_ON > WARN_ON
- put */ ending the block comment to a separate line

DRM side:
- Fix tda998x get_eld() locking
- Change tda998x audio parameters in pdata to more generic, that can be readily used in tda998x_audio_config()
- Rename and restructure audio port related private data members to be more descriptive
- Require audio configuration trough ASoC hdmi-codec if HDMI audio is configured trough DT binding.

DTS:
- Increase McASP fifo usage form 1 to 32

The binding for tda998x is taken from Jean Francois' patch series[1] on the same subject. The implementation of the of-node parsing has some minor changes from my self.

Here is what I think at least could or should still be done, but non of that stuff does not sounds critical right now.

Missing from tda998x driver side
- hdmi_codec_ops audio_startup() implementation for audio abort support
- multi channel audio support (I would need specs and preferably some HW to test for this).

Missing from ASoC side generic implementation:
- channel_allocation handling is completely left for the video side driver, see if ASoC side could help in any way
- snd_soc_jack functionality to handle hdmi cable plug/unplug events

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/095596.html

Best regards,
Jyri

Jean-Francois Moine (1):
drm/i2c: tda998x: Add support of a DT graph of ports

Jyri Sarha (7):
ASoC: hdmi: Remove obsolete dummy HDMI codec
ALSA: pcm: add IEC958 channel status helper for hw_params
ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing drm/i2c: tda998x: Improve tda998x_configure_audio() audio related
pdata
drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality
ARM: dts: am335x-boneblack: Add HDMI audio support

 .../devicetree/bindings/drm/i2c/tda998x.txt        |  51 +++
 arch/arm/boot/dts/am335x-boneblack.dts             |  90 ++++-
 drivers/gpu/drm/armada/armada_drv.c                |  25 +-
 drivers/gpu/drm/i2c/Kconfig                        |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c                  | 319 +++++++++++++---
 include/drm/i2c/tda998x.h                          |  24 +-
 include/sound/hdmi-codec.h                         | 104 ++++++
 include/sound/pcm_iec958.h                         |   2 +
 sound/core/pcm_iec958.c                            |  52 ++-
 sound/soc/codecs/Kconfig                           |   4 +-
 sound/soc/codecs/Makefile                          |   4 +-
 sound/soc/codecs/hdmi-codec.c                      | 404 +++++++++++++++++++++
 sound/soc/codecs/hdmi.c                            | 109 ------
 13 files changed, 985 insertions(+), 204 deletions(-)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c
 delete mode 100644 sound/soc/codecs/hdmi.c
Signature · 1 line
1.9.1

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw

RFC PATCH v4 1/8 ASoC: hdmi: Remove obsolete dummy HDMI codec

The hdmi stub codec has not been used since refactoring of OMAP HDMI audio support.

---
 sound/soc/codecs/Kconfig  |   4 --
 sound/soc/codecs/Makefile |   2 -
 sound/soc/codecs/hdmi.c   | 109 ----------------------------------------------
 3 files changed, 115 deletions(-)
 delete mode 100644 sound/soc/codecs/hdmi.c
sound/soc/codecs/Kconfig +0 -4
index 0c9733e..0142396 100644
@@ -79,7 +79,6 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_MAX9877 if I2C
 	select SND_SOC_MC13783 if MFD_MC13XXX
 	select SND_SOC_ML26124 if I2C
-	select SND_SOC_HDMI_CODEC
 	select SND_SOC_PCM1681 if I2C
 	select SND_SOC_PCM1792A if SPI_MASTER
 	select SND_SOC_PCM3008
@@ -442,9 +441,6 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
 	tristate
 
-config SND_SOC_HDMI_CODEC
-       tristate "HDMI stub CODEC"
-
 config SND_SOC_ES8328
 	tristate "Everest Semi ES8328 CODEC"
 
sound/soc/codecs/Makefile +0 -2
index 4a32077..7d7cc1b 100644
@@ -72,7 +72,6 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
-snd-soc-hdmi-codec-objs := hdmi.o
 snd-soc-pcm1681-objs := pcm1681.o
 snd-soc-pcm1792a-codec-objs := pcm1792a.o
 snd-soc-pcm3008-objs := pcm3008.o
@@ -264,7 +263,6 @@ obj-$(CONFIG_SND_SOC_MAX98925)	+= snd-soc-max98925.o
 obj-$(CONFIG_SND_SOC_MAX9850)	+= snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MC13783)	+= snd-soc-mc13783.o
 obj-$(CONFIG_SND_SOC_ML26124)	+= snd-soc-ml26124.o
-obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)	+= snd-soc-pcm1681.o
 obj-$(CONFIG_SND_SOC_PCM1792A)	+= snd-soc-pcm1792a-codec.o
 obj-$(CONFIG_SND_SOC_PCM3008)	+= snd-soc-pcm3008.o
sound/soc/codecs/hdmi.c deleted +0 -109

109 lines not on this page · raw message

Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#3 lore raw

RFC PATCH v4 2/8 ALSA: pcm: add IEC958 channel status helper for hw_params

In reply to a message not in the archive

Add IEC958 channel status helper that gets the audio properties from snd_pcm_hw_params instead of snd_pcm_runtime. This is needed to produce the channel status bits already in audio stream configuration phase.

---
 include/sound/pcm_iec958.h |  2 ++
 sound/core/pcm_iec958.c    | 52 +++++++++++++++++++++++++++++++---------------
 2 files changed, 37 insertions(+), 17 deletions(-)
include/sound/pcm_iec958.h +2 -0
index 0eed397..36f023a 100644
@@ -6,4 +6,6 @@
 int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
 	size_t len);
 
+int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
+					     u8 *cs, size_t len);
 #endif
sound/core/pcm_iec958.c +35 -17

76 lines not on this page · raw message

Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): a7b69fb075b0ae993846cfb65abb20ecab5c9805.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org

#5 lore raw

Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

Quoted 9 lines · Jyri Sarha

Add IEC958 channel status helper that gets the audio properties from snd_pcm_hw_params instead of snd_pcm_runtime. This is needed to produce the channel status bits already in audio stream configuration phase.

---
 include/sound/pcm_iec958.h |  2 ++
 sound/core/pcm_iec958.c    | 52 +++++++++++++++++++++++++++++++---------------

This is core ALSA code, you need to CC Takashi (added him, not cutting context).

Quoted 100 lines
 2 files changed, 37 insertions(+), 17 deletions(-)
include/sound/pcm_iec958.h +2 -0
index 0eed397..36f023a 100644
@@ -6,4 +6,6 @@
 int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
 	size_t len);
 
+int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
+					     u8 *cs, size_t len);
 #endif
sound/core/pcm_iec958.c +35 -17
index 36b2d7a..c9f8b66 100644
@@ -9,30 +9,18 @@
 #include <linux/types.h>
 #include <sound/asoundef.h>
 #include <sound/pcm.h>
+#include <sound/pcm_params.h>
 #include <sound/pcm_iec958.h>
 
-/**
- * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
- * @runtime: pcm runtime structure with ->rate filled in
- * @cs: channel status buffer, at least four bytes
- * @len: length of channel status buffer
- *
- * Create the consumer format channel status data in @cs of maximum size
- * @len corresponding to the parameters of the PCM runtime @runtime.
- *
- * Drivers may wish to tweak the contents of the buffer after creation.
- *
- * Returns: length of buffer, or negative error code if something failed.
- */
-int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
-	size_t len)
+static int create_iec958_consumer(uint rate, uint sample_width,
+				  u8 *cs, size_t len)
 {
 	unsigned int fs, ws;
 
 	if (len < 4)
 		return -EINVAL;
 
-	switch (runtime->rate) {
+	switch (rate) {
 	case 32000:
 		fs = IEC958_AES3_CON_FS_32000;
 		break;
@@ -59,7 +47,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
 	}
 
 	if (len > 4) {
-		switch (snd_pcm_format_width(runtime->format)) {
+		switch (sample_width) {
 		case 16:
 			ws = IEC958_AES4_CON_WORDLEN_20_16;
 			break;
@@ -92,4 +80,34 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
 
 	return len;
 }
+
+/**
+ * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
+ * @runtime: pcm runtime structure with ->rate filled in
+ * @cs: channel status buffer, at least four bytes
+ * @len: length of channel status buffer
+ *
+ * Create the consumer format channel status data in @cs of maximum size
+ * @len corresponding to the parameters of the PCM runtime @runtime.
+ *
+ * Drivers may wish to tweak the contents of the buffer after creation.
+ *
+ * Returns: length of buffer, or negative error code if something failed.
+ */
+int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
+	size_t len)
+{
+	return create_iec958_consumer(runtime->rate,
+				      snd_pcm_format_width(runtime->format),
+				      cs, len);
+}
 EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
+
+
+int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
+					     u8 *cs, size_t len)
+{
+	return create_iec958_consumer(params_rate(params), params_width(params),
+				      cs, len);
+}
+EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params);
Signature · 1 line
1.9.1
#6 lore raw

Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

In reply to Jyri Sarha
Quoted 4 lines · Jyri Sarha

Add IEC958 channel status helper that gets the audio properties from snd_pcm_hw_params instead of snd_pcm_runtime. This is needed to produce the channel status bits already in audio stream configuration phase.

What is the reason for doing this early?

ALSA documentation (which may be out of date) says that the hw_params callback can be called multiple times during stream setup. Do we want to be repeatedly programming the HDMI infoframe with different settings, potentially confusing the attached device, or would it be better to do it slightly later (in the prepare callback) after the parameters have been fully negotiated?

Signature · 6 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#7 lore raw

Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

Quoted 8 lines · Russell King - ARM Linux
Quoted 4 lines · Jyri Sarha

Add IEC958 channel status helper that gets the audio properties from snd_pcm_hw_params instead of snd_pcm_runtime. This is needed to produce the channel status bits already in audio stream configuration phase.

What is the reason for doing this early?

After some thinking, there is no good reason. It makes the codec bit more complicated, but that is not a good reason. I'll change that and use the prepare callback.

This patch can be dropped.

Quoted 7 lines

ALSA documentation (which may be out of date) says that the hw_params callback can be called multiple times during stream setup. Do we want to be repeatedly programming the HDMI infoframe with different settings, potentially confusing the attached device, or would it be better to do it slightly later (in the prepare callback) after the parameters have been fully negotiated?

If it is possible that hw_params() can be called multiple times, at least it does not happen very often. I wonder if it would ever happen again after a successful hw_params() call. But there is no downside in using prepare callback. I was just too much following the way ASoC codecs usually do the thing by writing everything to iron as the callbacks come in.

Best regards,
Jyri

#8 lore raw

Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

Quoted 11 lines · Jyri Sarha
Quoted 6 lines · Russell King - ARM Linux

ALSA documentation (which may be out of date) says that the hw_params callback can be called multiple times during stream setup. Do we want to be repeatedly programming the HDMI infoframe with different settings, potentially confusing the attached device, or would it be better to do it slightly later (in the prepare callback) after the parameters have been fully negotiated?

If it is possible that hw_params() can be called multiple times, at least it does not happen very often. I wonder if it would ever happen again after a successful hw_params() call.

It is certainly allowed, and it happens regularly when using OSS emulation. AFAIK PulseAudio does something similar when enumerating devices.

Quoted 1 line

But there is no downside in using prepare callback.

The prepare callback also can be called multiple times. This certainly happens when the stream is stopped/restarted multiple times.

If something does not need to be done again when a stream is restarted, then it should be done in the hw_params callback.

Regards,
Clemens

author
#9 lore raw

Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params

Quoted 6 lines · Clemens Ladisch
Quoted 1 line
Quoted 1 line

But there is no downside in using prepare callback.

The prepare callback also can be called multiple times. This certainly happens when the stream is stopped/restarted multiple times.

If something does not need to be done again when a stream is restarted, then it should be done in the hw_params callback.

Oh, forgot about that. This would suggest to keep the stream header configuration in the hw_params().

Thanks,
Jyri

#10 lore raw

RFC PATCH v4 4/8 drm/i2c: tda998x: Add support of a DT graph of ports

In reply to a message not in the archive

From: Jean-Francois Moine <[email protected]>

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.

---
 .../devicetree/bindings/drm/i2c/tda998x.txt        | 51 ++++++++++++
 drivers/gpu/drm/i2c/tda998x_drv.c                  | 90 +++++++++++++++++++---
 include/sound/tda998x.h                            |  8 ++
 3 files changed, 140 insertions(+), 9 deletions(-)
 create mode 100644 include/sound/tda998x.h
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +51 -0
index e9e4bce..35f6a80 100644
@@ -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>;
+			};
+		};
 	};
drivers/gpu/drm/i2c/tda998x_drv.c +81 -9

123 lines not on this page · raw message

include/sound/tda998x.h new file +8 -0
new file mode 100644
index 0000000..bef1da7
@@ -0,0 +1,8 @@
+#ifndef SND_TDA998X_H
+#define SND_TDA998X_H
+
+struct tda998x_audio {
+	u8 ports[2];			/* AP value */
+	u8 port_types[2];		/* AFMT_xxx */
+};
+#endif
Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): e9ebb04f781fef7cff99190d301fb64805b97d39.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org

#12 lore raw

Re: [PATCH RFC v4 4/8] drm/i2c: tda998x: Add support of a DT graph of ports

Quoted 29 lines · Jyri Sarha

From: Jean-Francois Moine <[email protected]>

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.

---
 .../devicetree/bindings/drm/i2c/tda998x.txt        | 51 ++++++++++++
 drivers/gpu/drm/i2c/tda998x_drv.c                  | 90 +++++++++++++++++++---
 include/sound/tda998x.h                            |  8 ++
 3 files changed, 140 insertions(+), 9 deletions(-)
 create mode 100644 include/sound/tda998x.h
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +2 -0
index e9e4bce..35f6a80 100644
@@ -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.
+

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 30

Quoted 10 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +10 -0
+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"

Why do you need this if there is no other choice? The port number should define which one is video.

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 36

Quoted 6 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +6 -0
+
+	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>.

I'm failing to decode how this value works. In any case, I would keep this as a vendor specific property rather than abusing reg.

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 45

Quoted 9 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +9 -0
+
+    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)

reg is 32-bits.

Quoted 8 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +2 -0
+
+[1] Documentation/devicetree/bindings/graph.txt
 
 Example:
 
@@ -26,4 +55,26 @@ Example:
 		interrupts = <27 2>;		/* falling edge */
 		pinctrl-0 = <&pmx_camera>;

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Example: · line 66

Quoted 10 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +9 -0
 		pinctrl-names = "default";
+
+		port@230145 {
+			port-type = "rgb";
+			reg = <0x230145>;
+			hdmi_0: endpoint {
+				remote-endpoint = <&lcd0_0>;
+			};
+		};
+		port@3 {			/* AP1 = I2S */

Is 3 significant? What happened to 0-2?

Quoted 153 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +13 -0
+			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>;
+			};
+		};
 	};
drivers/gpu/drm/i2c/tda998x_drv.c +81 -9
index 424228b..0952eac 100644
@@ -27,6 +27,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/i2c/tda998x.h>
+#include <sound/tda998x.h>
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
@@ -47,6 +48,8 @@ struct tda998x_priv {
 	wait_queue_head_t wq_edid;
 	volatile int wq_edid_wait;
 	struct drm_encoder *encoder;
+
+	struct tda998x_audio audio;
 };
 
 #define to_tda998x_priv(x)  ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv)
@@ -774,6 +777,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)
@@ -1230,9 +1235,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;
 	unsigned short cec_addr;
@@ -1337,15 +1390,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;
include/sound/tda998x.h new file +0 -0
new file mode 100644
index 0000000..bef1da7

include/sound/tda998x.h line 8

Quoted 8 lines
include/sound/tda998x.h new file +8 -0
@@ -0,0 +1,8 @@
+#ifndef SND_TDA998X_H
+#define SND_TDA998X_H
+
+struct tda998x_audio {
+	u8 ports[2];			/* AP value */
+	u8 port_types[2];		/* AFMT_xxx */
+};
+#endif

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#13 lore raw

Re: [PATCH RFC v4 4/8] drm/i2c: tda998x: Add support of a DT graph of ports

Quoted 11 lines · On Mon, 21 Sep 2015 10:19:18 -0500 Rob Herring <[email protected]> wrote:
Quoted 10 lines · Jyri Sarha

From: Jean-Francois Moine <[email protected]>

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.

Quoted 3 lines
Quoted 3 lines

---

	[snip]
Quoted 15 lines
Quoted 15 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +7 -0
index e9e4bce..35f6a80 100644
@@ -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].
+
Quoted 8 lines

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 30

Quoted 5 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +5 -0
+    Video port.
+	There may be only one video port.
+	This one must contain the following property:
+
+	- port-type: must be "rgb"  

Why do you need this if there is no other choice? The port number should define which one is video.

There is no specific port number.
One of the ports is video and two other ones are audio.

Quoted 9 lines

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 36

Quoted 6 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +6 -0
+
+	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>.  

I'm failing to decode how this value works. In any case, I would keep this as a vendor specific property rather than abusing reg.

This has been explained in
https://lkml.org/lkml/2014/1/20/86

Quoted 11 lines

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 45

Quoted 9 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +9 -0
+
+    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)  

reg is 32-bits.

This port has only 8 significant bits as explained in
https://lkml.org/lkml/2015/1/7/362

Quoted 5 lines
Quoted 5 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +2 -0
+
+[1] Documentation/devicetree/bindings/graph.txt
 
 Example:
 
Quoted 15 lines

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Example: · line 66

Quoted 13 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +9 -0
@@ -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 */  

Is 3 significant? What happened to 0-2?

The value after @ is the 'reg' value (= value of the port register).

Quoted 6 lines
Quoted 6 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +6 -0
+			port-type = "i2s";
+			reg = <0x03>;
+			tda998x_i2s: endpoint {
+				remote-endpoint = <&audio1_i2s>;
+			};
+		};
Signature · 6 lines
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
maintainer
#14 lore raw

Re: [PATCH RFC v4 4/8] drm/i2c: tda998x: Add support of a DT graph of ports

Quoted 42 lines · Jean-Francois Moine
Quoted 11 lines · On Mon, 21 Sep 2015 10:19:18 -0500 Rob Herring <[email protected]> wrote:
Quoted 10 lines · Jyri Sarha

From: Jean-Francois Moine <[email protected]>

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.

Quoted 3 lines
Quoted 3 lines

---

        [snip]
Quoted 15 lines
Quoted 15 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +7 -0
index e9e4bce..35f6a80 100644
@@ -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].
+
Quoted 8 lines

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 30

Quoted 5 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +5 -0
+    Video port.
+   There may be only one video port.
+   This one must contain the following property:
+
+   - port-type: must be "rgb"

Why do you need this if there is no other choice? The port number should define which one is video.

Quoted 2 lines

There is no specific port number.
One of the ports is video and two other ones are audio.

I saying you should define the port numbering in the binding. Port 0 is video, Port 1 is i2s, etc.

Quoted 11 lines
Quoted 10 lines

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 36

Quoted 7 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +6 -0
+
+   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>.

I'm failing to decode how this value works. In any case, I would keep this as a vendor specific property rather than abusing reg.

Quoted 2 lines

This has been explained in
https://lkml.org/lkml/2014/1/20/86

Okay, so that explains how it works, but still it should not be in reg.

Quoted 13 lines
Quoted 12 lines

Documentation/devicetree/bindings/drm/i2c/tda998x.txt Optional properties: · line 45

Quoted 10 lines
Documentation/devicetree/bindings/drm/i2c/tda998x.txt +9 -0
+
+    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)

reg is 32-bits.

Quoted 2 lines

This port has only 8 significant bits as explained in
https://lkml.org/lkml/2015/1/7/362

Maybe only 8-bits are used, but the size of the data in the DTB is 32-bits unless you add 8-bit annotation. Again, reg is not appropriate to use here.

Rob
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#15 lore raw

RFC PATCH v4 6/8 drm/i2c: tda998x: Improve tda998x_configure_audio() audio related pdata

In reply to a message not in the archive

Declare struct tda998x_audio_params in include/drm/i2c/tda998x.h and use it in pdata and for tda998x_configure_audio() parameters. Also updates tda998x_write_aif() to use hdmi_audio_infoframe_pack() and friends.

---
 drivers/gpu/drm/armada/armada_drv.c |  25 ++++++--
 drivers/gpu/drm/i2c/tda998x_drv.c   | 123 ++++++++++++++++++++----------------
 include/drm/i2c/tda998x.h           |  23 ++++---
 3 files changed, 102 insertions(+), 69 deletions(-)
drivers/gpu/drm/armada/armada_drv.c +21 -4
index 225034b..d500840 100644
@@ -20,6 +20,7 @@
 
 #ifdef CONFIG_DRM_ARMADA_TDA1998X
 #include <drm/i2c/tda998x.h>
+#include <sound/asoundef.h>
 #include "armada_slave.h"
 
 static struct tda998x_encoder_params params = {
@@ -35,10 +36,26 @@ static struct tda998x_encoder_params params = {
 	.swap_d = 5,
 	.swap_e = 0,
 	.swap_f = 1,
-	.audio_cfg = BIT(2),
-	.audio_frame[1] = 1,
-	.audio_format = AFMT_SPDIF,
-	.audio_sample_rate = 44100,
+	.audio = {
+		.config = BIT(2),
+		.format = AFMT_SPDIF,
+		.sample_width = 24,
+		.sample_rate = 44100,
+		.cea = {
+			.channels = 2,
+			.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM,
+			.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM,
+			.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
+		},
+		.status = {
+			IEC958_AES0_CON_NOT_COPYRIGHT,
+			IEC958_AES1_CON_GENERAL,
+			IEC958_AES2_CON_SOURCE_UNSPEC |
+			IEC958_AES2_CON_CHANNEL_UNSPEC,
+			IEC958_AES3_CON_CLOCK_1000PPM |
+			IEC958_AES3_CON_FS_NOTID,
+		},
+	}
 };
 
 static const struct armada_drm_slave_config tda19988_config = {
drivers/gpu/drm/i2c/tda998x_drv.c +68 -55

212 lines not on this page · raw message

include/drm/i2c/tda998x.h +13 -10
index 3e419d9..dfe7829 100644
@@ -1,6 +1,18 @@
 #ifndef __DRM_I2C_TDA998X_H__
 #define __DRM_I2C_TDA998X_H__
 
+struct tda998x_audio_params {
+	u8 config;
+	enum {
+		AFMT_SPDIF,
+		AFMT_I2S
+	} format;
+	unsigned sample_width;
+	unsigned sample_rate;
+	struct hdmi_audio_infoframe cea;
+	u8 status[4];
+};
+
 struct tda998x_encoder_params {
 	u8 swap_b:3;
 	u8 mirr_b:1;
@@ -15,16 +27,7 @@ struct tda998x_encoder_params {
 	u8 swap_e:3;
 	u8 mirr_e:1;
 
-	u8 audio_cfg;
-	u8 audio_clk_cfg;
-	u8 audio_frame[6];
-
-	enum {
-		AFMT_SPDIF,
-		AFMT_I2S
-	} audio_format;
-
-	unsigned audio_sample_rate;
+	struct tda998x_audio_params audio;
 };
 
 #endif
Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author
#16 lore raw

RFC PATCH v4 3/8 ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

In reply to Jyri Sarha

The hdmi-codec is a platform device driver to be registered from drivers of external HDMI encoders with I2S and/or spdif interface. The driver in turn registers an ASoC codec for the HDMI encoder's audio functionality.

The structures and definitions in the API header are mostly redundant copies of similar structures in ASoC headers. This is on purpose to avoid direct dependencies to ASoC structures in video side driver.

---
 include/sound/hdmi-codec.h    | 104 +++++++++++
 sound/soc/codecs/Kconfig      |   6 +
 sound/soc/codecs/Makefile     |   2 +
 sound/soc/codecs/hdmi-codec.c | 404 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 516 insertions(+)
 create mode 100644 include/sound/hdmi-codec.h
 create mode 100644 sound/soc/codecs/hdmi-codec.c
include/sound/hdmi-codec.h new file +104 -0
new file mode 100644
index 0000000..15fe70f
@@ -0,0 +1,104 @@
+/*
+ * hdmi-codec.h - HDMI Codec driver API
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Jyri Sarha <[email protected]>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __HDMI_CODEC_H__
+#define __HDMI_CODEC_H__
+
+#include <linux/hdmi.h>
+#include <drm/drm_edid.h>
+#include <sound/asoundef.h>
+#include <uapi/sound/asound.h>
+
+/*
+ * Protocol between ASoC cpu-dai and HDMI-encoder
+ */
+struct hdmi_codec_daifmt {
+	enum {
+		HDMI_I2S,
+		HDMI_RIGHT_J,
+		HDMI_LEFT_J,
+		HDMI_DSP_A,
+		HDMI_DSP_B,
+		HDMI_AC97,
+		HDMI_SPDIF,
+	} fmt;
+	int bit_clk_inv:1;
+	int frame_clk_inv:1;
+	int bit_clk_master:1;
+	int frame_clk_master:1;
+};
+
+/*
+ * HDMI audio parameters
+ */
+struct hdmi_codec_params {
+	struct hdmi_audio_infoframe cea;
+	struct snd_aes_iec958 iec;
+	int sample_rate;
+	int sample_width;
+	int channels;
+};
+
+struct hdmi_codec_ops {
+	/*
+	 * Called when ASoC starts an audio stream setup. The call
+	 * provides an audio abort callback for stoping an ongoing
+	 * stream from video side driver if the HDMI audio becomes
+	 * unavailable.
+	 * Optional
+	 */
+	int (*audio_startup)(struct device *dev,
+			     void (*abort_cb)(struct device *dev));
+
+	/*
+	 * Configures HDMI-encoder for audio stream.
+	 * Mandatory
+	 */
+	int (*hw_params)(struct device *dev,
+			 struct hdmi_codec_daifmt *fmt,
+			 struct hdmi_codec_params *hparms);
+
+	/*
+	 * Shuts down the audio stream.
+	 * Mandatory
+	 */
+	void (*audio_shutdown)(struct device *dev);
+
+	/*
+	 * Mute/unmute HDMI audio stream.
+	 * Optional
+	 */
+	int (*digital_mute)(struct device *dev, bool enable);
+
+	/*
+	 * Provides EDID-Like-Data from connected HDMI device.
+	 * Optional
+	 */
+	int (*get_eld)(struct device *dev, uint8_t *buf, size_t len);
+};
+
+/* HDMI codec initalization data */
+struct hdmi_codec_pdata {
+	const struct hdmi_codec_ops *ops;
+	uint i2s:1;
+	uint spdif:1;
+	int max_i2s_channels;
+};
+
+#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
+
+#endif /* __HDMI_CODEC_H__ */
sound/soc/codecs/Kconfig +6 -0
index 0142396..1e6c7e7 100644
@@ -79,6 +79,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_MAX9877 if I2C
 	select SND_SOC_MC13783 if MFD_MC13XXX
 	select SND_SOC_ML26124 if I2C
+	select SND_SOC_HDMI_CODEC
 	select SND_SOC_PCM1681 if I2C
 	select SND_SOC_PCM1792A if SPI_MASTER
 	select SND_SOC_PCM3008
@@ -441,6 +442,11 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
 	tristate
 
+config SND_SOC_HDMI_CODEC
+       tristate
+       select SND_PCM_ELD
+       select SND_PCM_IEC958
+
 config SND_SOC_ES8328
 	tristate "Everest Semi ES8328 CODEC"
 
sound/soc/codecs/Makefile +2 -0
index 7d7cc1b..068d483 100644
@@ -72,6 +72,7 @@ snd-soc-max98925-objs := max98925.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
+snd-soc-hdmi-codec-objs := hdmi-codec.o
 snd-soc-pcm1681-objs := pcm1681.o
 snd-soc-pcm1792a-codec-objs := pcm1792a.o
 snd-soc-pcm3008-objs := pcm3008.o
@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_MAX98925)	+= snd-soc-max98925.o
 obj-$(CONFIG_SND_SOC_MAX9850)	+= snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MC13783)	+= snd-soc-mc13783.o
 obj-$(CONFIG_SND_SOC_ML26124)	+= snd-soc-ml26124.o
+obj-$(CONFIG_SND_SOC_HDMI_CODEC)	+= snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)	+= snd-soc-pcm1681.o
 obj-$(CONFIG_SND_SOC_PCM1792A)	+= snd-soc-pcm1792a-codec.o
 obj-$(CONFIG_SND_SOC_PCM3008)	+= snd-soc-pcm3008.o
sound/soc/codecs/hdmi-codec.c new file +404 -0

404 lines not on this page · raw message

Signature · 1 line
1.9.1

A message that is not in the archive (sent off-list or not yet received): 6fe9ab5dff972e6f228259d6818f3f481a11577d.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org

#18 lore raw

Re: [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

sound/soc/codecs/hdmi-codec.c line 293

Quoted 11 lines · Jyri Sarha
sound/soc/codecs/hdmi-codec.c new file +11 -0
+#define SPDIF_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
+
+#define I2S_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+			 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE |\
+			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
+			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)

I'm not sure how abstracted this I2S and S/PDIF DAI business is - it doesn't feel like something that's going to be a property of all HDMI devices, and the specific sets of formats above cause me to raise a bit of an eyebrow. Should this be an interface where the HDMI chip registers multiple interfaces if it has them instead of automatically getting this split as is?

We can probably skip more specific constraint stuff I guess on the basis that things tend to support the full range of HDMI functionality, or at least that can be added later?

Otherwise this looks mostly OK on a first pass, thanks for working on it.

#19 lore raw

Re: [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

Quoted 11 lines · Mark Brown
Quoted 10 lines · Jyri Sarha
sound/soc/codecs/hdmi-codec.c new file +10 -0
+#define SPDIF_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
+
+#define I2S_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+			 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE |\
+			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
Quoted 8 lines

sound/soc/codecs/hdmi-codec.c line 293

Quoted 1 line
sound/soc/codecs/hdmi-codec.c new file +1 -0
+			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)

I'm not sure how abstracted this I2S and S/PDIF DAI business is - it doesn't feel like something that's going to be a property of all HDMI devices, and the specific sets of formats above cause me to raise a bit of an eyebrow. Should this be an interface where the HDMI chip registers multiple interfaces if it has them instead of automatically getting this split as is?

The inclusion of the 32-bit formats does raise an eyebrow here too. Audio transmission across the HDMI link is S/PDIF, supporting up to 24-bit uncompressed audio (aka L-PCM).

The device may accept 32 bit I2S, but it would have to be truncated to 24 bit before transmitting it to the sink. This should be mentioned somewhere.

Signature · 6 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#20 lore raw

Re: [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

Quoted 21 lines · Russell King - ARM Linux
Quoted 11 lines · Mark Brown
Quoted 10 lines · Jyri Sarha
sound/soc/codecs/hdmi-codec.c new file +10 -0
+#define SPDIF_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
+
+#define I2S_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
+			 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE |\
+			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
+			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
Quoted 8 lines

sound/soc/codecs/hdmi-codec.c line 293

Quoted 1 line
sound/soc/codecs/hdmi-codec.c new file +1 -0
+			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)

I'm not sure how abstracted this I2S and S/PDIF DAI business is - it doesn't feel like something that's going to be a property of all HDMI devices, and the specific sets of formats above cause me to raise a bit of an eyebrow. Should this be an interface where the HDMI chip registers multiple interfaces if it has them instead of automatically getting this split as is?

Quoted 8 lines

The inclusion of the 32-bit formats does raise an eyebrow here too. Audio transmission across the HDMI link is S/PDIF, supporting up to 24-bit uncompressed audio (aka L-PCM).

The device may accept 32 bit I2S, but it would have to be truncated to 24 bit before transmitting it to the sink. This should be mentioned somewhere.

There is ".sig_bits = 24" in hdmi_i2s_dai, but I can add an explicit comment about it.

We needed 32bit format in practice until Peter got 24_LE properly working with McASP. I just thought the may still be some platforms out there that can not produce 24bit i2s samples for some reason, but work just fine with 32bit samples. Those platforms would be limited to less than 24bit precision without 32bit formats. But as said, it is not critical to us any more and I can drop the 32bit formats as well.

BR,
Jyri

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

maintainer
#21 lore raw

Re: [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders

Quoted 9 lines · Jyri Sarha
Quoted 3 lines · Russell King - ARM Linux

The device may accept 32 bit I2S, but it would have to be truncated to 24 bit before transmitting it to the sink. This should be mentioned somewhere.

There is ".sig_bits = 24" in hdmi_i2s_dai, but I can add an explicit comment about it.

Quoted 6 lines

We needed 32bit format in practice until Peter got 24_LE properly working with McASP. I just thought the may still be some platforms out there that can not produce 24bit i2s samples for some reason, but work just fine with 32bit samples. Those platforms would be limited to less than 24bit precision without 32bit formats. But as said, it is not critical to us any more and I can drop the 32bit formats as well.

Yes, this is currently a bit messy - we should really be able to allow S24_LE and S32 to interoperate better without drivers having to know about it since physically they are essentially compatible in memory. I'm pretty much OK with it for now since even with that framework support it should be harmless.

author
#22 lore raw

RFC PATCH v4 5/8 drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing

In reply to Jyri Sarha

Move struct tda998x_audio definition to tda998x_drv.c and remove include/sound/tda998x.h. There is no external use for struct tda998x_audio.

Fix graph parsing to allow ports to be inside a separate "ports"-node as specified in Documentation/devicetree/bindings/graph.txt.

---
 drivers/gpu/drm/i2c/tda998x_drv.c | 59 +++++++++++++++++++++------------------
 include/sound/tda998x.h           |  8 ------
 2 files changed, 32 insertions(+), 35 deletions(-)
 delete mode 100644 include/sound/tda998x.h
drivers/gpu/drm/i2c/tda998x_drv.c +32 -27
index 0952eac..4dc2dc0 100644
@@ -27,10 +27,14 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/i2c/tda998x.h>
-#include <sound/tda998x.h>
 
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
+struct tda998x_audio {
+	u8 ports[2];			/* AP value */
+	u8 port_types[2];		/* AFMT_xxx */
+};
+
 struct tda998x_priv {
 	struct i2c_client *cec;
 	struct i2c_client *hdmi;
@@ -1240,9 +1244,10 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
 {
 	struct device_node *of_port;
 	const char *port_type;
-	int ret, audio_index, reg, afmt;
+	int ret, audio_index, reg, afmt, rgb_initialized;
 
 	audio_index = 0;
+	rgb_initialized = 0;
 	for_each_child_of_node(np, of_port) {
 		if (!of_port->name
 		 || of_node_cmp(of_port->name, "port") != 0)
@@ -1252,11 +1257,17 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
 		if (ret < 0)
 			continue;
 		ret = of_property_read_u32(of_port, "reg", &reg);
+		if (ret < 0) {
+			dev_err(&priv->hdmi->dev, "missing reg for %s\n",
+				port_type);
+			return ret;
+		}
 		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;
+				rgb_initialized = 1;
 			}
 			continue;
 		}
@@ -1266,11 +1277,6 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
 			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;
@@ -1279,13 +1285,13 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
 		priv->audio.port_types[audio_index] = afmt;
 		audio_index++;
 	}
-	return 0;
+	return rgb_initialized;
 }
 
 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;
+	struct device_node *ports;
 	u32 video;
 	int rev_lo, rev_hi, ret;
 	unsigned short cec_addr;
@@ -1392,24 +1398,15 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 
 	/* 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 {
-
+		ports = of_get_child_by_name(np, "ports");
+		if (!ports)
+			ports = of_node_get(np);
+		/* graph of ports */
+		ret = tda998x_parse_ports(priv, ports);
+		of_node_put(ports);
+		if (ret < 0)
+			goto fail;
+		if (ret == 0) {
 			/* optional video properties */
 			ret = of_property_read_u32(np, "video-ports", &video);
 			if (ret == 0) {
@@ -1418,6 +1415,14 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 				priv->vip_cntrl_2 = video;
 			}
 		}
+		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;
+		}
 	}
 
 	return 0;
include/sound/tda998x.h deleted +0 -8
deleted file mode 100644
index bef1da7..0000000
@@ -1,8 +0,0 @@
-#ifndef SND_TDA998X_H
-#define SND_TDA998X_H
-
-struct tda998x_audio {
-	u8 ports[2];			/* AP value */
-	u8 port_types[2];		/* AFMT_xxx */
-};
-#endif
Signature · 6 lines
1.9.1

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#23 lore raw

RFC PATCH v4 7/8 drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality

In reply to Jyri Sarha

Register ASoC HDMI codec for audio functionality. This is an initial ASoC audio implementation for tda998x driver and it does not use all the features provided by hdmi-codec.

HDMI audio info-frame and audio stream header is generated by the ASoC HDMI codec. The codec also applies constraints for available sample-rates.

Implementation of audio_startup for hdmi_codec_ops would enable tda998x driver to abort ongoing playback if the HDMI cable is unplugged or re-plugged to a device without audio capability.

---
 drivers/gpu/drm/i2c/Kconfig       |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 181 +++++++++++++++++++++++++++++++-------
 include/drm/i2c/tda998x.h         |   1 +
 3 files changed, 150 insertions(+), 33 deletions(-)
drivers/gpu/drm/i2c/Kconfig +1 -0
index 22c7ed6..088f278 100644
@@ -28,6 +28,7 @@ config DRM_I2C_SIL164
 config DRM_I2C_NXP_TDA998X
 	tristate "NXP Semiconductors TDA998X HDMI encoder"
 	default m if DRM_TILCDC
+	select SND_SOC_HDMI_CODEC if SND_SOC
 	help
 	  Support for NXP Semiconductors TDA998X HDMI encoders.
 
drivers/gpu/drm/i2c/tda998x_drv.c +148 -33

254 lines not on this page · raw message

include/drm/i2c/tda998x.h +1 -0
index dfe7829..5a0cabb 100644
@@ -4,6 +4,7 @@
 struct tda998x_audio_params {
 	u8 config;
 	enum {
+		AFMT_UNUSED = 0,
 		AFMT_SPDIF,
 		AFMT_I2S
 	} format;
Signature · 1 line
1.9.1
author
#24 lore raw

RFC PATCH v4 8/8 ARM: dts: am335x-boneblack: Add HDMI audio support

In reply to Jyri Sarha

Add HDMI audio support. Adds mcasp0_pins, clk_mcasp0_fixed, clk_mcasp0, mcasp0, sound node, and updates the tda19988 node to follow the new binding.

---
 arch/arm/boot/dts/am335x-boneblack.dts | 90 ++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 4 deletions(-)
arch/arm/boot/dts/am335x-boneblack.dts +86 -4
index eadbba3..05347dc 100644
@@ -64,6 +64,16 @@
 			0x1b0 0x03      /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
 		>;
 	};
+
+	mcasp0_pins: mcasp0_pins {
+		pinctrl-single,pins = <
+			0x1ac (PIN_INPUT_PULLUP | MUX_MODE0)	/* mcasp0_ahclkx.mcasp0_ahclkx */
+			0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2 */
+			0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0)	/* mcasp0_fsx.mcasp0_fsx */
+			0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mcasp0_aclkx.mcasp0_aclkx */
+			0x06c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a11.GPIO1_27 */
+		>;
+	};
 };
 
 &lcdc {
@@ -76,17 +86,89 @@
 };
 
 &i2c0 {
-	tda19988 {
+	tda19988: tda19988 {
 		compatible = "nxp,tda998x";
 		reg = <0x70>;
+
+		#sound-dai-cells = <0>;
+
 		pinctrl-names = "default", "off";
 		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
 		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
 
-		port {
-			hdmi_0: endpoint@0 {
-				remote-endpoint = <&lcdc_0>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				port-type = "rgb";
+				reg = <0x230145>;
+				hdmi_0: endpoint@0 {
+					remote-endpoint = <&lcdc_0>;
+				};
 			};
+			port@1 {
+				port-type = "i2s";
+				reg = <0x03>;
+				tda19988_i2s: endpoint {
+					remote-endpoint = <&mcasp0_i2s>;
+				};
+			};
+		};
+	};
+};
+
+&rtc {
+	system-power-controller;
+};
+
+&mcasp0	{
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcasp0_pins>;
+	status = "okay";
+	op-mode = <0>;	/* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
+			0 0 1 0
+		>;
+	tx-num-evt = <32>;
+	rx-num-evt = <32>;
+
+	port {
+		mcasp0_i2s: endpoint {
+			remote-endpoint = <&tda19988_i2s>;
+		};
+	};
+};
+
+/ {
+	clk_mcasp0_fixed: clk_mcasp0_fixed {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24576000>;
+	};
+
+	clk_mcasp0: clk_mcasp0 {
+		#clock-cells = <0>;
+		compatible = "gpio-gate-clock";
+		clocks = <&clk_mcasp0_fixed>;
+		enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "TI BeagleBone Black";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+
+		dailink0_master: simple-audio-card,cpu {
+			sound-dai = <&mcasp0>;
+			clocks = <&clk_mcasp0>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&tda19988>;
 		};
 	};
 };
Signature · 6 lines
1.9.1

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel