Skip to contentSkip to conversation

Implement ASoC HDMI codec library

RFC PATCH Superseded Jyri Sarha 2 participants 5 messages May 13, 2015 – May 15, 2015

Subsystems (4)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Jyri Sarha

author
#0 lore raw

cover Implement ASoC HDMI codec library

This is on early RFC and should not be merged yet. The idea is just to share my ideas early on as there has been a lot of development going on around HDMI audio.

The I2S DAI of the ASoC side patch is usable already, the spdif support has not been tested and the EDID SADs handling should use Russel's DRM ELD helper when it is ready.

The tda998x patch is just to demonstrate the usage of the HDMI-codec-lib. At least the audio related DT-bindings are missing completely and the configuration is hard coded to work on Beaglebone-Black.

Jean-Francois, would you consider trying the generic ASoC patch with your HW, as I can not test the spdif functionality with mine?

The library could also be implemented as a separate platform driver, but then adding a pointer for private data to struct snd_soc_dai_driver, snd_soc_codec, or to snd_soc_component would be of great help.

These patches, my tilcdc refactoring[1], and my latest BCLK fixes for davinci-mcasp diver [2], can found in a branch that produces a working HDMI audio on Beaglebone-Black here:

https://github.com/jsarha/linux.git linux-master-bbb-hdmi-20150512

[1] http://lists.freedesktop.org/archives/dri-devel/2015-May/082537.html
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-April/090974.html

Jyri Sarha (2):
ASoC: hdmi-codec-lib: Add hdmi-codec-lib for external HDMI-encoders drm/i2c: tda998x: HACK Implement primitive HDMI audio with ASoC
hdmi-code-lib

 drivers/gpu/drm/i2c/Kconfig       |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 238 +++++++++++++++++
 include/sound/hdmi-codec-lib.h    | 105 ++++++++
 sound/soc/codecs/Kconfig          |   4 +
 sound/soc/codecs/Makefile         |   2 +
 sound/soc/codecs/hdmi-codec-lib.c | 536 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 886 insertions(+)
 create mode 100644 include/sound/hdmi-codec-lib.h
 create mode 100644 sound/soc/codecs/hdmi-codec-lib.c
Signature · 1 line
1.9.1
author
#1 lore raw

RFC PATCH 1/2 ASoC: hdmi-codec-lib: Add hdmi-codec-lib for external HDMI-encoders

The hdmi-codec-lib is a library for registering an ASoC codec under an external HDMI encoder driver with I2S and/or spdif interface.

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-lib.h    | 105 ++++++++
 sound/soc/codecs/Kconfig          |   4 +
 sound/soc/codecs/Makefile         |   2 +
 sound/soc/codecs/hdmi-codec-lib.c | 536 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 647 insertions(+)
 create mode 100644 include/sound/hdmi-codec-lib.h
 create mode 100644 sound/soc/codecs/hdmi-codec-lib.c
include/sound/hdmi-codec-lib.h new file +105 -0
new file mode 100644
index 0000000..9acf9f7
@@ -0,0 +1,105 @@
+/*
+ * hdmi-codec-lib.h - HDMI codec library 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_LIB_H__
+#define __HDMI_CODEC_LIB_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 {
+	/* For runtime clock configuration from ASoC machine driver.
+	 * A direct forward from set_sysclk in struct snd_soc_dai_ops.
+	 * Optional */
+	int (*set_clk)(struct device *dev, int clk_id, int freq);
+
+	/* Called when ASoC starts an audio stream setup. The call
+	 * provides an audio abort callback for stoping an ongoing
+	 * stream 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 short audio descriptors from connected HDMI device.
+	 * Optional */
+	int (*get_sads)(struct device *dev, struct cea_sad **sads);
+};
+
+/* HDMI codec initalization data */
+struct hdmi_codec_data {
+	struct device *dev; /* The HDMI encoder registering the codec */
+	const struct hdmi_codec_ops *ops;
+	uint i2s:1;
+	uint spdif:1;
+	int max_i2s_channels;
+};
+
+/* Has to be the first member of the hdmi endcoder's drvdata */
+struct hdmi_codec_drvdata {
+	void *codec_data;
+};
+
+int asoc_hdmi_codec_register(struct hdmi_codec_data *data);
+void asoc_hdmi_codec_unregister(struct device *dev);
+
+#endif /* __HDMI_CODEC_LIB_H__ */
sound/soc/codecs/Kconfig +4 -0
index 061c465..05fabf4 100644
@@ -77,6 +77,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_MC13783 if MFD_MC13XXX
 	select SND_SOC_ML26124 if I2C
 	select SND_SOC_HDMI_CODEC
+	select SND_SOC_HDMI_CODEC_LIB
 	select SND_SOC_PCM1681 if I2C
 	select SND_SOC_PCM1792A if SPI_MASTER
 	select SND_SOC_PCM3008
@@ -433,6 +434,9 @@ config SND_SOC_DMIC
 config SND_SOC_HDMI_CODEC
        tristate "HDMI stub CODEC"
 
+config SND_SOC_HDMI_CODEC_LIB
+       tristate "lib for HDMI encoders with i2s or spdif interface"
+
 config SND_SOC_ES8328
 	tristate "Everest Semi ES8328 CODEC"
 
sound/soc/codecs/Makefile +2 -0
index abe2d7e..ed1c15d 100644
@@ -70,6 +70,7 @@ 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-hdmi-codec-lib-objs := hdmi-codec-lib.o
 snd-soc-pcm1681-objs := pcm1681.o
 snd-soc-pcm1792a-codec-objs := pcm1792a.o
 snd-soc-pcm3008-objs := pcm3008.o
@@ -255,6 +256,7 @@ 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_HDMI_CODEC_LIB)	+= snd-soc-hdmi-codec-lib.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-lib.c new file +536 -0

536 lines not on this page · raw message

Signature · 6 lines
1.9.1

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

RFC PATCH 2/2 drm/i2c: tda998x: HACK Implement primitive HDMI audio with ASoC hdmi-code-lib

In reply to Jyri Sarha

This patch is to demonstrate how to use the ASoC hdmi-codec-lib to implement ASoC codec API in tda998x driver.

I do not have proper documentation for tda998x family chips so I lack the necessary information for making a proper binding for audio part of the chip. The configuration is hard coded to work on Beaglebone-Black.

---
 drivers/gpu/drm/i2c/Kconfig       |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 238 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 239 insertions(+)
drivers/gpu/drm/i2c/Kconfig +1 -0
index 22c7ed6..92302e9 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_LIB if SND_SOC
 	help
 	  Support for NXP Semiconductors TDA998X HDMI encoders.
 
drivers/gpu/drm/i2c/tda998x_drv.c +238 -0

286 lines not on this page · raw message

Signature · 1 line
1.9.1
#3 lore raw
In reply to Jyri Sarha
Quoted 2 lines · On Wed, 13 May 2015 12:23:45 +0300 Jyri Sarha <[email protected]> wrote:

Jean-Francois, would you consider trying the generic ASoC patch with your HW, as I can not test the spdif functionality with mine?

Hi Jyri,

I am not sure to need all the stuff you coded.

My tda998x CODEC is quite empty and it works fine in my system. If you look at my last patch request ([PATCH v12 6/6] ASoC: tda998x:
add a codec to the HDMI transmitter -
http://mailman.alsa-project.org/pipermail/alsa-devel/2015-May/091758.html),
the code is much smaller than yours and does not ask for a structure constraint (+/* Has to be the first member of the hdmi endcoder's drvdata */).

So, I'd rather see a real hdmi codec library, i.e. a set of common functions as Russell's DRM ELD helper, each specific hdmi codec being free about the mechanism used for the exchanges with the hdmi transmitter.

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
author
#4 lore raw
Quoted 10 lines · Jean-Francois Moine
Quoted 2 lines · On Wed, 13 May 2015 12:23:45 +0300 Jyri Sarha <[email protected]> wrote:

Jean-Francois, would you consider trying the generic ASoC patch with your HW, as I can not test the spdif functionality with mine?

Hi Jyri,

I am not sure to need all the stuff you coded.

You do not need to use all of the stuff on the ASoC side. At minimum you could just implement hw_params() and audio_shutdown() for struct hdmi_codec_ops and just use the hw_params() parameters you need. With such and implementation the tda998x side would not look too different from what you are having now.

Quoted 3 lines

My tda998x CODEC is quite empty and it works fine in my system. If you look at my last patch request ([PATCH v12 6/6] ASoC: tda998x:
add a codec to the HDMI transmitter -

The idea for my lib is to work for all external HDMI encoders with i2s and/or spdif interface. And avoid the need to create a new HW specific ASoC module and API for each HDMI encoder.

Quoted 5 lines

http://mailman.alsa-project.org/pipermail/alsa-devel/2015-May/091758.html),
the code is much smaller than yours and does not ask for a structure constraint (+/* Has to be the first member of the hdmi endcoder's drvdata */).

If that is generally considered annoying, I can get around it by adding a private_data member to struct snd_soc_dai (Mark, is that Ok?).

With the above change it is simply a matter of choice whether the library is actually a platform driver.

Quoted 5 lines

So, I'd rather see a real hdmi codec library, i.e. a set of common functions as Russell's DRM ELD helper, each specific hdmi codec being free about the mechanism used for the exchanges with the hdmi transmitter.

Well, this is a real library and these are common functions for all HDMI encoder fitting the description. If we want to avoid each encoder from adding their own module to ASoC side and implementing their own API, we need something similar to what I wrote.

I am happy to do what ever changes are considered necessary, but I think I my idea in general is sound.

Of course another option would be just to implement the ASoC component within the video side driver and use the ASoC structures directly.

Best regards,
Jyri