All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2 0/6] ASoC: Add mediatek HDMI codec support
@ 2016-01-04 19:09 Philipp Zabel
  2016-01-04 19:09 ` [RFC v2 1/6] drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver Philipp Zabel
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: Philipp Zabel @ 2016-01-04 19:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Philipp Zabel, Arnaud Pouliquen,
	Liam Girdwood, Jyri Sarha, Cawa Cheng, Mark Brown,
	linux-mediatek, Daniel Kurtz, kernel, Matthias Brugger

Hi,

this time we add an interface for Jyri's generic hdmi-codec driver [1] to
the mediatek hdmi bridge driver. In place of a separate machine driver,
the existing mt8173-rt5650-rt5676 driver is extended to link to the
hdmi-codec instance provided by the hdmi bridge driver.

The alsa jack support, previously implemented by the custom mediatek hdmi
codec and machine drivers, is bolted on top of hdmi-codec using Russell's
HDMI notifier prototype. It's all still a bit rough, but I could use some
feedback at this point. Have we achieved consensus to go forward with the
hdmi-codec approach? Is it ok to use an alsa jack for HDMI HPD status
reporting?

The mediatek drm patches apply on top of
https://patchwork.kernel.org/patch/7949021/ ("drm/mediatek: Add HDMI support")
the asoc patches depend on these two patches:
https://patchwork.kernel.org/patch/7215121/ ("ALSA: pcm: add IEC958 channel status helper for hw_params")
[1] https://patchwork.kernel.org/patch/7215271/ ("ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders")

best regards
Philipp

Koro Chen (1):
  ASoC: mediatek: Add HDMI dai-links in the machine driver

Philipp Zabel (5):
  drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver
  ASoC: mediatek: address dai link array entries by enum
  video: rmk's HDMI notification prototype
  drm/mediatek: hdmi: issue notifications
  ASoC: hdmi-codec: Use HDMI notifications to add jack support

 .../bindings/sound/mt8173-rt5650-rt5676.txt        |   5 +-
 drivers/gpu/drm/mediatek/Kconfig                   |   1 +
 drivers/gpu/drm/mediatek/mtk_cec.c                 |   5 +
 drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c        | 192 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_hdmi.c                |  26 +++
 drivers/gpu/drm/mediatek/mtk_hdmi.h                |   4 +
 drivers/video/Makefile                             |   2 +-
 drivers/video/hdmi-not.c                           |  61 +++++++
 include/linux/hdmi-not.h                           |  39 +++++
 include/sound/hdmi-codec.h                         |   6 +
 sound/soc/codecs/hdmi-codec.c                      |  72 +++++++-
 sound/soc/mediatek/mt8173-rt5650-rt5676.c          |  66 ++++++-
 12 files changed, 470 insertions(+), 9 deletions(-)
 create mode 100644 drivers/video/hdmi-not.c
 create mode 100644 include/linux/hdmi-not.h

-- 
2.6.2

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

* [RFC v2 1/6] drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver
  2016-01-04 19:09 [RFC v2 0/6] ASoC: Add mediatek HDMI codec support Philipp Zabel
@ 2016-01-04 19:09 ` Philipp Zabel
  2016-01-04 22:29   ` Russell King - ARM Linux
       [not found] ` <1451934551-21333-1-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 19+ messages in thread
From: Philipp Zabel @ 2016-01-04 19:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Philipp Zabel, Arnaud Pouliquen,
	Liam Girdwood, Jyri Sarha, Cawa Cheng, Mark Brown,
	linux-mediatek, Daniel Kurtz, kernel, Matthias Brugger

Add the interface needed by Jyri's generic hdmi-codec driver [1] to start
or stop audio playback and to retrieve ELD (EDID like data) to limit the
supported audio formats to the HDMI sink capabilities.

[1] https://patchwork.kernel.org/patch/7215271/ ("ASoC: hdmi-codec: Add
    hdmi-codec for external HDMI-encoders")

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/gpu/drm/mediatek/Kconfig            |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c | 189 ++++++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_hdmi.c         |  26 ++++
 drivers/gpu/drm/mediatek/mtk_hdmi.h         |   4 +
 4 files changed, 220 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 829ab66..93b7ca9 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -17,6 +17,7 @@ config DRM_MEDIATEK
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
+	select SND_SOC_HDMI_CODEC if SND_SOC
 	select GENERIC_PHY
 	help
 	  DRM/KMS HDMI driver for Mediatek SoCs
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c
index 5c1ec96..1a07ef3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c
@@ -26,6 +26,7 @@
 #include <linux/of_graph.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <sound/hdmi-codec.h>
 #include "mtk_cec.h"
 #include "mtk_hdmi.h"
 #include "mtk_hdmi_hw.h"
@@ -437,6 +438,192 @@ static irqreturn_t hdmi_flt_n_5v_irq_thread(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+/*
+ * HDMI audio codec callbacks
+ */
+
+static int mtk_hdmi_audio_hw_params(struct device *dev,
+				    struct hdmi_codec_daifmt *daifmt,
+				    struct hdmi_codec_params *params)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	struct hdmi_audio_param hdmi_params;
+	unsigned int chan = params->cea.channels;
+
+	dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+		params->sample_rate, params->sample_width, chan);
+
+	if (!hdmi->bridge.encoder || !hdmi->bridge.encoder->crtc)
+		return -ENODEV;
+
+	switch (chan) {
+	case 2:
+		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
+		break;
+	case 4:
+		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
+		break;
+	case 6:
+		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
+		break;
+	case 8:
+		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
+		break;
+	default:
+		dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
+		return -EINVAL;
+	}
+
+	switch (params->sample_rate) {
+	case 32000:
+		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_32000;
+		hdmi_params.iec_frame_fs = HDMI_IEC_32K;
+		/* channel status byte 3: fs and clock accuracy */
+		hdmi_params.hdmi_l_channel_state[3] = 0x3;
+		break;
+	case 44100:
+		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_44100;
+		hdmi_params.iec_frame_fs = HDMI_IEC_44K;
+		/* channel status byte 3: fs and clock accuracy */
+		hdmi_params.hdmi_l_channel_state[3] = 0;
+		break;
+	case 48000:
+		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
+		hdmi_params.iec_frame_fs = HDMI_IEC_48K;
+		/* channel status byte 3: fs and clock accuracy */
+		hdmi_params.hdmi_l_channel_state[3] = 0x2;
+		break;
+	case 88200:
+		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_88200;
+		hdmi_params.iec_frame_fs = HDMI_IEC_88K;
+		/* channel status byte 3: fs and clock accuracy */
+		hdmi_params.hdmi_l_channel_state[3] = 0x8;
+		break;
+	case 96000:
+		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_96000;
+		hdmi_params.iec_frame_fs = HDMI_IEC_96K;
+		/* channel status byte 3: fs and clock accuracy */
+		hdmi_params.hdmi_l_channel_state[3] = 0xa;
+		break;
+	case 176400:
+		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_176400;
+		hdmi_params.iec_frame_fs = HDMI_IEC_176K;
+		/* channel status byte 3: fs and clock accuracy */
+		hdmi_params.hdmi_l_channel_state[3] = 0xc;
+		break;
+	case 192000:
+		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_192000;
+		hdmi_params.iec_frame_fs = HDMI_IEC_192K;
+		/* channel status byte 3: fs and clock accuracy */
+		hdmi_params.hdmi_l_channel_state[3] = 0xe;
+		break;
+	default:
+		dev_err(hdmi->dev, "rate[%d] not supported!\n",
+			params->sample_rate);
+		return -EINVAL;
+	}
+
+	switch (daifmt->fmt) {
+	case HDMI_I2S:
+		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+		hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
+		hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+		hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
+		break;
+	default:
+		dev_err(hdmi->dev, "%s: Invalid format %d\n", __func__,
+			daifmt->fmt);
+		return -EINVAL;
+	}
+
+	/* channel status */
+	/* byte 0: no copyright is asserted, mode 0 */
+	hdmi_params.hdmi_l_channel_state[0] = 1 << 2;
+	/* byte 1: category code */
+	hdmi_params.hdmi_l_channel_state[1] = 0;
+	/* byte 2: source/channel number don't take into account */
+	hdmi_params.hdmi_l_channel_state[2] = 0;
+	/* byte 4: word length 16bits */
+	hdmi_params.hdmi_l_channel_state[4] = 0x2;
+	memcpy(hdmi_params.hdmi_r_channel_state,
+	       hdmi_params.hdmi_l_channel_state,
+	       sizeof(hdmi_params.hdmi_l_channel_state));
+
+	mtk_hdmi_audio_set_param(hdmi, &hdmi_params);
+
+	return 0;
+}
+
+static int mtk_hdmi_audio_startup(struct device *dev,
+				  void (*abort_cb)(struct device *dev))
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	mtk_hdmi_audio_enable(hdmi);
+
+	return 0;
+}
+
+static void mtk_hdmi_audio_shutdown(struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	mtk_hdmi_audio_disable(hdmi);
+}
+
+int mtk_hdmi_audio_digital_mute(struct device *dev, bool enable)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "%s(%d)\n", __func__, enable);
+
+	mtk_hdmi_hw_aud_mute(hdmi, enable);
+
+	return 0;
+}
+
+static int mtk_hdmi_audio_get_eld(struct device *dev, uint8_t *buf, size_t len)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	memcpy(buf, hdmi->conn.eld, min(sizeof(hdmi->conn.eld), len));
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
+	.hw_params = mtk_hdmi_audio_hw_params,
+	.audio_startup = mtk_hdmi_audio_startup,
+	.audio_shutdown = mtk_hdmi_audio_shutdown,
+	.digital_mute = mtk_hdmi_audio_digital_mute,
+	.get_eld = mtk_hdmi_audio_get_eld,
+};
+
+static void mtk_hdmi_register_audio_driver(struct device *dev)
+{
+	struct hdmi_codec_pdata codec_data = {
+		.ops = &mtk_hdmi_audio_codec_ops,
+		.max_i2s_channels = 2,
+		.i2s = 1,
+	};
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO, &codec_data,
+					     sizeof(codec_data));
+	if (IS_ERR(pdev))
+		return;
+
+	DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
+}
+
 static int mtk_drm_hdmi_probe(struct platform_device *pdev)
 {
 	struct mtk_hdmi *hdmi;
@@ -485,6 +672,8 @@ static int mtk_drm_hdmi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	mtk_hdmi_register_audio_driver(dev);
+
 	hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs;
 	hdmi->bridge.of_node = pdev->dev.of_node;
 	ret = drm_bridge_add(&hdmi->bridge);
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 342beab..535a4d7 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -441,6 +441,32 @@ void mtk_hdmi_power_off(struct mtk_hdmi *hdmi)
 	mtk_hdmi_hw_make_reg_writable(hdmi, false);
 }
 
+void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
+{
+	mtk_hdmi_aud_enable_packet(hdmi, true);
+	hdmi->audio_enable = true;
+}
+
+void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi)
+{
+	mtk_hdmi_aud_enable_packet(hdmi, false);
+	hdmi->audio_enable = false;
+}
+
+int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi,
+			     struct hdmi_audio_param *param)
+{
+	if (!hdmi->audio_enable) {
+		dev_err(hdmi->dev, "hdmi audio is in disable state!\n");
+		return -EINVAL;
+	}
+	dev_info(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
+		 param->aud_codec, param->aud_input_type,
+		 param->aud_input_chan_type, param->aud_hdmi_fs);
+	memcpy(&hdmi->aud_param, param, sizeof(*param));
+	return mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
+}
+
 int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
 				     struct drm_display_mode *mode)
 {
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h
index c072bcc..12e5614 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.h
@@ -211,6 +211,10 @@ int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
 				     struct drm_display_mode *mode);
 void mtk_hdmi_power_on(struct mtk_hdmi *hdmi);
 void mtk_hdmi_power_off(struct mtk_hdmi *hdmi);
+void mtk_hdmi_audio_enable(struct mtk_hdmi *hctx);
+void mtk_hdmi_audio_disable(struct mtk_hdmi *hctx);
+int mtk_hdmi_audio_set_param(struct mtk_hdmi *hctx,
+			     struct hdmi_audio_param *param);
 #if defined(CONFIG_DEBUG_FS)
 int mtk_drm_hdmi_debugfs_init(struct mtk_hdmi *hdmi);
 void mtk_drm_hdmi_debugfs_exit(struct mtk_hdmi *hdmi);
-- 
2.6.2

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

* [RFC v2 2/6] ASoC: mediatek: address dai link array entries by enum
       [not found] ` <1451934551-21333-1-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2016-01-04 19:09   ` Philipp Zabel
  2016-01-04 19:15     ` [RFC v2 3/6] ASoC: mediatek: Add HDMI dai-links in the machine driver Philipp Zabel
  2016-03-05 12:24     ` Applied "ASoC: mediatek: address dai link array entries by enum" to the asoc tree Mark Brown
  2016-01-04 19:19   ` [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support Philipp Zabel
  1 sibling, 2 replies; 19+ messages in thread
From: Philipp Zabel @ 2016-01-04 19:09 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Philipp Zabel, Arnaud Pouliquen,
	Liam Girdwood, Jyri Sarha, Cawa Cheng, Mark Brown,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Matthias Brugger

This should be more robust to future changes than adressing
array entries by index number.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 sound/soc/mediatek/mt8173-rt5650-rt5676.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
index 50ba538..5c4c58c 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -131,10 +131,17 @@ static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = {
 	},
 };
 
+enum {
+	DAI_LINK_PLAYBACK,
+	DAI_LINK_CAPTURE,
+	DAI_LINK_CODEC_I2S,
+	DAI_LINK_INTERCODEC
+};
+
 /* Digital audio interface glue - connects codec <---> CPU */
 static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 	/* Front End DAI links */
-	{
+	[DAI_LINK_PLAYBACK] = {
 		.name = "rt5650_rt5676 Playback",
 		.stream_name = "rt5650_rt5676 Playback",
 		.cpu_dai_name = "DL1",
@@ -144,7 +151,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 		.dynamic = 1,
 		.dpcm_playback = 1,
 	},
-	{
+	[DAI_LINK_CAPTURE] = {
 		.name = "rt5650_rt5676 Capture",
 		.stream_name = "rt5650_rt5676 Capture",
 		.cpu_dai_name = "VUL",
@@ -156,7 +163,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 	},
 
 	/* Back End DAI links */
-	{
+	[DAI_LINK_CODEC_I2S] = {
 		.name = "Codec",
 		.cpu_dai_name = "I2S",
 		.no_pcm = 1,
@@ -170,7 +177,8 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 		.dpcm_playback = 1,
 		.dpcm_capture = 1,
 	},
-	{ /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
+	/* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
+	[DAI_LINK_INTERCODEC] = {
 		.name = "rt5650_rt5676 intercodec",
 		.stream_name = "rt5650_rt5676 intercodec",
 		.cpu_dai_name = "snd-soc-dummy-dai",
@@ -240,7 +248,7 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	mt8173_rt5650_rt5676_codec_conf[0].of_node =
 		mt8173_rt5650_rt5676_codecs[1].of_node;
 
-	mt8173_rt5650_rt5676_dais[3].codec_of_node =
+	mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codec_of_node =
 		mt8173_rt5650_rt5676_codecs[1].of_node;
 
 	card->dev = &pdev->dev;
-- 
2.6.2

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

* Re: [RFC v2 0/6] ASoC: Add mediatek HDMI codec support
  2016-01-04 19:09 [RFC v2 0/6] ASoC: Add mediatek HDMI codec support Philipp Zabel
  2016-01-04 19:09 ` [RFC v2 1/6] drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver Philipp Zabel
       [not found] ` <1451934551-21333-1-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2016-01-04 19:11 ` Russell King - ARM Linux
  2016-01-04 19:18 ` [RFC v2 4/6] video: rmk's HDMI notification prototype Philipp Zabel
  2016-01-04 19:18 ` [RFC v2 5/6] drm/mediatek: hdmi: issue notifications Philipp Zabel
  4 siblings, 0 replies; 19+ messages in thread
From: Russell King - ARM Linux @ 2016-01-04 19:11 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Arnaud Pouliquen, Koro Chen, Jyri Sarha, Liam Girdwood,
	Mark Brown, linux-mediatek, Daniel Kurtz, kernel,
	Matthias Brugger, Cawa Cheng

On Mon, Jan 04, 2016 at 08:09:05PM +0100, Philipp Zabel wrote:
>   video: rmk's HDMI notification prototype

It should be noted that I have a new (cleaned up) version of this
patch, so I'd prefer if _this_ one doesn't get merged.

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [RFC v2 3/6] ASoC: mediatek: Add HDMI dai-links in the machine driver
  2016-01-04 19:09   ` [RFC v2 2/6] ASoC: mediatek: address dai link array entries by enum Philipp Zabel
@ 2016-01-04 19:15     ` Philipp Zabel
  2016-01-05 12:46       ` Mark Brown
  2016-03-05 12:24     ` Applied "ASoC: mediatek: address dai link array entries by enum" to the asoc tree Mark Brown
  1 sibling, 1 reply; 19+ messages in thread
From: Philipp Zabel @ 2016-01-04 19:15 UTC (permalink / raw)
  To: alsa-devel
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Philipp Zabel, Arnaud Pouliquen,
	Liam Girdwood, Jyri Sarha, Cawa Cheng, Mark Brown,
	linux-mediatek, Daniel Kurtz, kernel, Matthias Brugger

From: Koro Chen <koro.chen@mediatek.com>

This creates pcmC0D2p for the HDMI playback in the same card.

Signed-off-by: Koro Chen <koro.chen@mediatek.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 .../bindings/sound/mt8173-rt5650-rt5676.txt        |  5 ++-
 sound/soc/mediatek/mt8173-rt5650-rt5676.c          | 48 ++++++++++++++++++++++
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt
index f205ce9..ac28cdb 100644
--- a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt
+++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt
@@ -1,15 +1,16 @@
-MT8173 with RT5650 RT5676 CODECS
+MT8173 with RT5650 RT5676 CODECS and HDMI via I2S
 
 Required properties:
 - compatible : "mediatek,mt8173-rt5650-rt5676"
 - mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs
+			and of the hdmi encoder node
 - mediatek,platform: the phandle of MT8173 ASoC platform
 
 Example:
 
 	sound {
 		compatible = "mediatek,mt8173-rt5650-rt5676";
-		mediatek,audio-codec = <&rt5650 &rt5676>;
+		mediatek,audio-codec = <&rt5650 &rt5676 &hdmi0>;
 		mediatek,platform = <&afe>;
 	};
 
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
index 5c4c58c..def9d95 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <sound/soc.h>
+#include <sound/hdmi-codec.h>
 #include <sound/jack.h>
 #include "../codecs/rt5645.h"
 #include "../codecs/rt5677.h"
@@ -131,10 +132,31 @@ static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = {
 	},
 };
 
+static struct snd_soc_jack mt8173_hdmi_card_jack;
+
+static int mt8173_hdmi_init(struct snd_soc_pcm_runtime *runtime)
+{
+	struct snd_soc_card *card = runtime->card;
+	struct snd_soc_codec *codec = runtime->codec;
+	int ret;
+
+	/* enable jack detection */
+	ret = snd_soc_card_jack_new(card, "HDMI Jack", SND_JACK_LINEOUT,
+				    &mt8173_hdmi_card_jack, NULL, 0);
+	if (ret) {
+		dev_err(card->dev, "Can't new HDMI Jack %d\n", ret);
+		return ret;
+	}
+
+	return hdmi_codec_set_jack_detect(codec, &mt8173_hdmi_card_jack);
+}
+
 enum {
 	DAI_LINK_PLAYBACK,
 	DAI_LINK_CAPTURE,
+	DAI_LINK_HDMI,
 	DAI_LINK_CODEC_I2S,
+	DAI_LINK_HDMI_I2S,
 	DAI_LINK_INTERCODEC
 };
 
@@ -161,6 +183,16 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 		.dynamic = 1,
 		.dpcm_capture = 1,
 	},
+	[DAI_LINK_HDMI] = {
+		.name = "HDMI",
+		.stream_name = "HDMI PCM",
+		.cpu_dai_name = "HDMI",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+	},
 
 	/* Back End DAI links */
 	[DAI_LINK_CODEC_I2S] = {
@@ -177,6 +209,14 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 		.dpcm_playback = 1,
 		.dpcm_capture = 1,
 	},
+	[DAI_LINK_HDMI_I2S] = {
+		.name = "HDMI BE",
+		.cpu_dai_name = "HDMIO",
+		.no_pcm = 1,
+		.codec_dai_name = "i2s-hifi",
+		.dpcm_playback = 1,
+		.init = mt8173_hdmi_init,
+	},
 	/* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
 	[DAI_LINK_INTERCODEC] = {
 		.name = "rt5650_rt5676 intercodec",
@@ -251,6 +291,14 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codec_of_node =
 		mt8173_rt5650_rt5676_codecs[1].of_node;
 
+	mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codec_of_node =
+		of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 2);
+	if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codec_of_node) {
+		dev_err(&pdev->dev,
+			"Property 'audio-codec' missing or invalid\n");
+		return -EINVAL;
+	}
+
 	card->dev = &pdev->dev;
 	platform_set_drvdata(pdev, card);
 
-- 
2.6.2

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

* [RFC v2 4/6] video: rmk's HDMI notification prototype
  2016-01-04 19:09 [RFC v2 0/6] ASoC: Add mediatek HDMI codec support Philipp Zabel
                   ` (2 preceding siblings ...)
  2016-01-04 19:11 ` [RFC v2 0/6] ASoC: Add mediatek HDMI codec support Russell King - ARM Linux
@ 2016-01-04 19:18 ` Philipp Zabel
  2016-01-04 19:18 ` [RFC v2 5/6] drm/mediatek: hdmi: issue notifications Philipp Zabel
  4 siblings, 0 replies; 19+ messages in thread
From: Philipp Zabel @ 2016-01-04 19:18 UTC (permalink / raw)
  To: alsa-devel
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Philipp Zabel, Arnaud Pouliquen,
	Liam Girdwood, Jyri Sarha, Cawa Cheng, Mark Brown,
	linux-mediatek, Daniel Kurtz, kernel, Matthias Brugger

This is extracted from Russell's food for thought HDMI notification
prototype [1]. I've put it into drivers/video for the time being because
my kernels don't have drivers/cec yet.

The current use case for the notifications on MediaTek MT8173 is to
let the (dis)connection notifications control an ALSA jack object.

No Signed-off-by yet since this is not my code, and up for discussion.

[1] https://patchwork.kernel.org/patch/7339011/
---
 drivers/video/Makefile   |  2 +-
 drivers/video/hdmi-not.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/hdmi-not.h | 39 +++++++++++++++++++++++++++++++
 3 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 drivers/video/hdmi-not.c
 create mode 100644 include/linux/hdmi-not.h

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 9ad3c17..bf25760 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,5 +1,5 @@
 obj-$(CONFIG_VGASTATE)            += vgastate.o
-obj-$(CONFIG_HDMI)                += hdmi.o
+obj-$(CONFIG_HDMI)                += hdmi.o hdmi-not.o
 
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
diff --git a/drivers/video/hdmi-not.c b/drivers/video/hdmi-not.c
new file mode 100644
index 0000000..ba3be8a
--- /dev/null
+++ b/drivers/video/hdmi-not.c
@@ -0,0 +1,61 @@
+#include <linux/export.h>
+#include <linux/hdmi-not.h>
+#include <linux/notifier.h>
+#include <linux/string.h>
+
+static BLOCKING_NOTIFIER_HEAD(hdmi_notifier);
+
+int hdmi_register_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&hdmi_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(hdmi_register_notifier);
+
+int hdmi_unregister_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&hdmi_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(hdmi_unregister_notifier);
+
+void hdmi_event_connect(struct device *dev)
+{
+	struct hdmi_event_base base;
+
+	base.source = dev;
+
+	blocking_notifier_call_chain(&hdmi_notifier, HDMI_CONNECTED, &base);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_connect);
+
+void hdmi_event_disconnect(struct device *dev)
+{
+	struct hdmi_event_base base;
+
+	base.source = dev;
+
+	blocking_notifier_call_chain(&hdmi_notifier, HDMI_DISCONNECTED, &base);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_disconnect);
+
+void hdmi_event_new_edid(struct device *dev, const void *edid, size_t size)
+{
+	struct hdmi_event_new_edid new_edid;
+
+	new_edid.base.source = dev;
+	new_edid.edid = edid;
+	new_edid.size = size;
+
+	blocking_notifier_call_chain(&hdmi_notifier, HDMI_NEW_EDID, &new_edid);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_new_edid);
+
+void hdmi_event_new_eld(struct device *dev, const void *eld)
+{
+	struct hdmi_event_new_eld new_eld;
+
+	new_eld.base.source = dev;
+	memcpy(new_eld.eld, eld, sizeof(new_eld.eld));
+
+	blocking_notifier_call_chain(&hdmi_notifier, HDMI_NEW_ELD, &new_eld);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_new_eld);
diff --git a/include/linux/hdmi-not.h b/include/linux/hdmi-not.h
new file mode 100644
index 0000000..940ece45
--- /dev/null
+++ b/include/linux/hdmi-not.h
@@ -0,0 +1,39 @@
+#include <linux/types.h>
+
+enum {
+	HDMI_CONNECTED,
+	HDMI_DISCONNECTED,
+	HDMI_NEW_EDID,
+	HDMI_NEW_ELD,
+};
+
+struct hdmi_event_base {
+	struct device *source;
+};
+
+struct hdmi_event_new_edid {
+	struct hdmi_event_base base;
+	const void *edid;
+	size_t size;
+};
+
+struct hdmi_event_new_eld {
+	struct hdmi_event_base base;
+	unsigned char eld[128];
+};
+
+union hdmi_event {
+	struct hdmi_event_base base;
+	struct hdmi_event_new_edid edid;
+	struct hdmi_event_new_eld eld;
+};
+
+struct notifier_block;
+
+int hdmi_register_notifier(struct notifier_block *nb);
+int hdmi_unregister_notifier(struct notifier_block *nb);
+
+void hdmi_event_connect(struct device *dev);
+void hdmi_event_disconnect(struct device *dev);
+void hdmi_event_new_edid(struct device *dev, const void *edid, size_t size);
+void hdmi_event_new_eld(struct device *dev, const void *eld);
-- 
2.6.2

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

* [RFC v2 5/6] drm/mediatek: hdmi: issue notifications
  2016-01-04 19:09 [RFC v2 0/6] ASoC: Add mediatek HDMI codec support Philipp Zabel
                   ` (3 preceding siblings ...)
  2016-01-04 19:18 ` [RFC v2 4/6] video: rmk's HDMI notification prototype Philipp Zabel
@ 2016-01-04 19:18 ` Philipp Zabel
  4 siblings, 0 replies; 19+ messages in thread
From: Philipp Zabel @ 2016-01-04 19:18 UTC (permalink / raw)
  To: alsa-devel
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Philipp Zabel, Arnaud Pouliquen,
	Liam Girdwood, Jyri Sarha, Cawa Cheng, Mark Brown,
	linux-mediatek, Daniel Kurtz, kernel, Matthias Brugger

Issue hot-plug detection, EDID update, and ELD update notifications
from the CEC and HDMI drivers.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/gpu/drm/mediatek/mtk_cec.c          | 5 +++++
 drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
index cba3647..7c4ee7a 100644
--- a/drivers/gpu/drm/mediatek/mtk_cec.c
+++ b/drivers/gpu/drm/mediatek/mtk_cec.c
@@ -13,6 +13,7 @@
  */
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/hdmi-not.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
@@ -160,6 +161,10 @@ static irqreturn_t mtk_cec_htplg_isr_thread(int irq, void *arg)
 	if (cec->hpd != hpd) {
 		dev_info(dev, "hotplug event!,cur hpd = %d, hpd = %d\n",
 			 cec->hpd, hpd);
+		if (hpd)
+			hdmi_event_connect(cec->hdmi_dev);
+		else
+			hdmi_event_disconnect(cec->hdmi_dev);
 		cec->hpd = hpd;
 		if (cec->hpd_event)
 			cec->hpd_event(hpd, cec->hdmi_dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c
index 1a07ef3..06544ee 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_hdmi_drv.c
@@ -17,6 +17,7 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <linux/clk.h>
+#include <linux/hdmi-not.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
@@ -122,9 +123,11 @@ static int mtk_hdmi_conn_get_modes(struct drm_connector *conn)
 	hdmi->dvi_mode = !drm_detect_hdmi_monitor(edid);
 
 	drm_mode_connector_update_edid_property(conn, edid);
+	hdmi_event_new_edid(hdmi->dev, edid, sizeof(*edid));
 
 	ret = drm_add_edid_modes(conn, edid);
 	drm_edid_to_eld(conn, edid);
+	hdmi_event_new_eld(hdmi->dev, conn->eld);
 	kfree(edid);
 	return ret;
 }
-- 
2.6.2

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

* [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support
       [not found] ` <1451934551-21333-1-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  2016-01-04 19:09   ` [RFC v2 2/6] ASoC: mediatek: address dai link array entries by enum Philipp Zabel
@ 2016-01-04 19:19   ` Philipp Zabel
  2016-01-07 17:09     ` Jyri Sarha
  1 sibling, 1 reply; 19+ messages in thread
From: Philipp Zabel @ 2016-01-04 19:19 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Philipp Zabel, Arnaud Pouliquen,
	Liam Girdwood, Jyri Sarha, Cawa Cheng, Mark Brown,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Matthias Brugger

Use HDMI connection / disconnection notifications to update an ALSA
jack object. Also make a copy of the ELD block after every change.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 include/sound/hdmi-codec.h    |  6 ++++
 sound/soc/codecs/hdmi-codec.c | 72 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index 15fe70f..8b6219d 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -99,6 +99,12 @@ struct hdmi_codec_pdata {
 	int max_i2s_channels;
 };
 
+struct snd_soc_codec;
+struct snd_soc_jack;
+
+int hdmi_codec_set_jack_detect(struct snd_soc_codec *codec,
+			       struct snd_soc_jack *jack);
+
 #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
 
 #endif /* __HDMI_CODEC_H__ */
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 687332d..41f28ab 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -12,9 +12,12 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
  * General Public License for more details.
  */
+#include <linux/hdmi-not.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/string.h>
 #include <sound/core.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -27,11 +30,15 @@
 struct hdmi_codec_priv {
 	struct hdmi_codec_pdata hcd;
 	struct snd_soc_dai_driver *daidrv;
+	struct snd_soc_jack *jack;
 	struct hdmi_codec_daifmt daifmt[2];
 	struct mutex current_stream_lock;
 	struct snd_pcm_substream *current_stream;
 	struct snd_pcm_hw_constraint_list ratec;
 	uint8_t eld[MAX_ELD_BYTES];
+	struct device *dev;
+	struct notifier_block nb;
+	unsigned int jack_status;
 };
 
 static const struct snd_soc_dapm_widget hdmi_widgets[] = {
@@ -326,6 +333,63 @@ static struct snd_soc_codec_driver hdmi_codec = {
 	.num_dapm_routes = ARRAY_SIZE(hdmi_routes),
 };
 
+static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
+				   unsigned int jack_status)
+{
+	if (!hcp->jack)
+		return;
+
+	if (jack_status != hcp->jack_status) {
+		snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
+		hcp->jack_status = jack_status;
+	}
+}
+
+static int hdmi_codec_notify(struct notifier_block *nb, unsigned long event,
+			     void *data)
+{
+	struct hdmi_codec_priv *hcp = container_of(nb, struct hdmi_codec_priv,
+						   nb);
+	union hdmi_event *event_block = data;
+	int ret;
+
+	if (hcp->dev->parent != event_block->base.source)
+		return NOTIFY_OK;
+
+	if (!hcp->jack)
+		return NOTIFY_OK;
+
+	switch (event) {
+	case HDMI_CONNECTED:
+		hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
+		break;
+	case HDMI_DISCONNECTED:
+		hdmi_codec_jack_report(hcp, 0);
+		break;
+	case HDMI_NEW_ELD:
+		if (hcp->hcd.ops->get_eld)
+			ret = hcp->hcd.ops->get_eld(hcp->dev->parent, hcp->eld,
+						    sizeof(hcp->eld));
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+int hdmi_codec_set_jack_detect(struct snd_soc_codec *codec,
+			       struct snd_soc_jack *jack)
+{
+	struct hdmi_codec_priv *hcp = snd_soc_codec_get_drvdata(codec);
+
+	hcp->jack = jack;
+	hcp->nb.notifier_call = hdmi_codec_notify;
+
+	hdmi_register_notifier(&hcp->nb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hdmi_codec_set_jack_detect);
+
 static int hdmi_codec_probe(struct platform_device *pdev)
 {
 	struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
@@ -370,6 +434,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
 	if (hcd->spdif)
 		hcp->daidrv[i] = hdmi_spdif_dai;
 
+	dev_set_drvdata(dev, hcp);
+
 	ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
 				     dai_count);
 	if (ret) {
@@ -378,12 +444,16 @@ static int hdmi_codec_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dev_set_drvdata(dev, hcp);
+	hcp->dev = dev;
+
 	return 0;
 }
 
 static int hdmi_codec_remove(struct platform_device *pdev)
 {
+	struct hdmi_codec_priv *hcp = platform_get_drvdata(pdev);
+
+	hdmi_unregister_notifier(&hcp->nb);
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
-- 
2.6.2

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

* Re: [RFC v2 1/6] drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver
  2016-01-04 19:09 ` [RFC v2 1/6] drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver Philipp Zabel
@ 2016-01-04 22:29   ` Russell King - ARM Linux
  2016-01-05 14:56     ` Philipp Zabel
  0 siblings, 1 reply; 19+ messages in thread
From: Russell King - ARM Linux @ 2016-01-04 22:29 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Arnaud Pouliquen, Koro Chen, Jyri Sarha, Liam Girdwood,
	Mark Brown, linux-mediatek, Daniel Kurtz, kernel,
	Matthias Brugger, Cawa Cheng

On Mon, Jan 04, 2016 at 08:09:06PM +0100, Philipp Zabel wrote:
> Add the interface needed by Jyri's generic hdmi-codec driver [1] to start
> or stop audio playback and to retrieve ELD (EDID like data) to limit the
> supported audio formats to the HDMI sink capabilities.

Some of this makes me rather suspicious.

> +	switch (params->sample_rate) {
> +	case 32000:
> +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_32000;
> +		hdmi_params.iec_frame_fs = HDMI_IEC_32K;
> +		/* channel status byte 3: fs and clock accuracy */
> +		hdmi_params.hdmi_l_channel_state[3] = 0x3;
> +		break;
> +	case 44100:
> +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_44100;
> +		hdmi_params.iec_frame_fs = HDMI_IEC_44K;
> +		/* channel status byte 3: fs and clock accuracy */
> +		hdmi_params.hdmi_l_channel_state[3] = 0;
> +		break;
> +	case 48000:
> +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
> +		hdmi_params.iec_frame_fs = HDMI_IEC_48K;
> +		/* channel status byte 3: fs and clock accuracy */
> +		hdmi_params.hdmi_l_channel_state[3] = 0x2;
> +		break;
> +	case 88200:
> +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_88200;
> +		hdmi_params.iec_frame_fs = HDMI_IEC_88K;
> +		/* channel status byte 3: fs and clock accuracy */
> +		hdmi_params.hdmi_l_channel_state[3] = 0x8;
> +		break;
> +	case 96000:
> +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_96000;
> +		hdmi_params.iec_frame_fs = HDMI_IEC_96K;
> +		/* channel status byte 3: fs and clock accuracy */
> +		hdmi_params.hdmi_l_channel_state[3] = 0xa;
> +		break;
> +	case 176400:
> +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_176400;
> +		hdmi_params.iec_frame_fs = HDMI_IEC_176K;
> +		/* channel status byte 3: fs and clock accuracy */
> +		hdmi_params.hdmi_l_channel_state[3] = 0xc;
> +		break;
> +	case 192000:
> +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_192000;
> +		hdmi_params.iec_frame_fs = HDMI_IEC_192K;
> +		/* channel status byte 3: fs and clock accuracy */
> +		hdmi_params.hdmi_l_channel_state[3] = 0xe;

For exmaple, all the above.  The HDMI standards say that the audio info
frame "shall" always set the sample frequency to "refer to stream" for
L-PCM and IEC61937 compressed audio.  The above looks like it violates
the HDMI specification as I'm willing to bet that hdmi_params.aud_hdmi_fs
gets passed over into the audio info frame.

Many of the fields in the audio info frame are supposed to be set as
"refer to stream".  I'd suggest ensuring that you're compliant with
these.

The second thing is that "hdmi_params.hdmi_l_channel_state" looks like
it's the IEC958 bytes.  These must be correct for some of the higher
end HDMI receivers (eg, Yamaha RX-V677) to correctly process the audio.

> +		break;
> +	default:
> +		dev_err(hdmi->dev, "rate[%d] not supported!\n",
> +			params->sample_rate);
> +		return -EINVAL;
> +	}
> +
> +	switch (daifmt->fmt) {
> +	case HDMI_I2S:
> +		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +		hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +		hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
> +		hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +		hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
> +		break;
> +	default:
> +		dev_err(hdmi->dev, "%s: Invalid format %d\n", __func__,
> +			daifmt->fmt);
> +		return -EINVAL;
> +	}
> +
> +	/* channel status */
> +	/* byte 0: no copyright is asserted, mode 0 */
> +	hdmi_params.hdmi_l_channel_state[0] = 1 << 2;
> +	/* byte 1: category code */
> +	hdmi_params.hdmi_l_channel_state[1] = 0;
> +	/* byte 2: source/channel number don't take into account */
> +	hdmi_params.hdmi_l_channel_state[2] = 0;
> +	/* byte 4: word length 16bits */
> +	hdmi_params.hdmi_l_channel_state[4] = 0x2;
> +	memcpy(hdmi_params.hdmi_r_channel_state,
> +	       hdmi_params.hdmi_l_channel_state,
> +	       sizeof(hdmi_params.hdmi_l_channel_state));

Hmm, yes, it is the IEC958 channel status bytes.  We have a helper
for this - snd_pcm_create_iec958_consumer().

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [RFC v2 3/6] ASoC: mediatek: Add HDMI dai-links in the machine driver
  2016-01-04 19:15     ` [RFC v2 3/6] ASoC: mediatek: Add HDMI dai-links in the machine driver Philipp Zabel
@ 2016-01-05 12:46       ` Mark Brown
  2016-01-07 10:06         ` Philipp Zabel
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Brown @ 2016-01-05 12:46 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Russell King - ARM Linux, Arnaud Pouliquen, Koro Chen,
	Jyri Sarha, Liam Girdwood, linux-mediatek, Daniel Kurtz, kernel,
	Matthias Brugger, Cawa Cheng


[-- Attachment #1.1: Type: text/plain, Size: 479 bytes --]

On Mon, Jan 04, 2016 at 08:15:44PM +0100, Philipp Zabel wrote:
> From: Koro Chen <koro.chen@mediatek.com>
> 
> This creates pcmC0D2p for the HDMI playback in the same card.
> 
> Signed-off-by: Koro Chen <koro.chen@mediatek.com>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

Please don't send new patches in reply to the middle of an existing
series, it makes it very hard to tell what's going on.  If you need to
send a new version resend the whole series.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [RFC v2 1/6] drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver
  2016-01-04 22:29   ` Russell King - ARM Linux
@ 2016-01-05 14:56     ` Philipp Zabel
  0 siblings, 0 replies; 19+ messages in thread
From: Philipp Zabel @ 2016-01-05 14:56 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Arnaud Pouliquen, Koro Chen, Jyri Sarha, Liam Girdwood,
	Mark Brown, linux-mediatek, Daniel Kurtz, kernel,
	Matthias Brugger, Cawa Cheng

Hi Russell,

Am Montag, den 04.01.2016, 22:29 +0000 schrieb Russell King - ARM Linux:
> On Mon, Jan 04, 2016 at 08:09:06PM +0100, Philipp Zabel wrote:
> > Add the interface needed by Jyri's generic hdmi-codec driver [1] to start
> > or stop audio playback and to retrieve ELD (EDID like data) to limit the
> > supported audio formats to the HDMI sink capabilities.
> 
> Some of this makes me rather suspicious.

Thanks for being suspicious, then.

> > +	switch (params->sample_rate) {
> > +	case 32000:
> > +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_32000;
> > +		hdmi_params.iec_frame_fs = HDMI_IEC_32K;
> > +		/* channel status byte 3: fs and clock accuracy */
> > +		hdmi_params.hdmi_l_channel_state[3] = 0x3;
> > +		break;
> > +	case 44100:
> > +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_44100;
> > +		hdmi_params.iec_frame_fs = HDMI_IEC_44K;
> > +		/* channel status byte 3: fs and clock accuracy */
> > +		hdmi_params.hdmi_l_channel_state[3] = 0;
> > +		break;
> > +	case 48000:
> > +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
> > +		hdmi_params.iec_frame_fs = HDMI_IEC_48K;
> > +		/* channel status byte 3: fs and clock accuracy */
> > +		hdmi_params.hdmi_l_channel_state[3] = 0x2;
> > +		break;
> > +	case 88200:
> > +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_88200;
> > +		hdmi_params.iec_frame_fs = HDMI_IEC_88K;
> > +		/* channel status byte 3: fs and clock accuracy */
> > +		hdmi_params.hdmi_l_channel_state[3] = 0x8;
> > +		break;
> > +	case 96000:
> > +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_96000;
> > +		hdmi_params.iec_frame_fs = HDMI_IEC_96K;
> > +		/* channel status byte 3: fs and clock accuracy */
> > +		hdmi_params.hdmi_l_channel_state[3] = 0xa;
> > +		break;
> > +	case 176400:
> > +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_176400;
> > +		hdmi_params.iec_frame_fs = HDMI_IEC_176K;
> > +		/* channel status byte 3: fs and clock accuracy */
> > +		hdmi_params.hdmi_l_channel_state[3] = 0xc;
> > +		break;
> > +	case 192000:
> > +		hdmi_params.aud_hdmi_fs = HDMI_AUDIO_SAMPLE_FREQUENCY_192000;
> > +		hdmi_params.iec_frame_fs = HDMI_IEC_192K;
> > +		/* channel status byte 3: fs and clock accuracy */
> > +		hdmi_params.hdmi_l_channel_state[3] = 0xe;
> 
> For exmaple, all the above.  The HDMI standards say that the audio info
> frame "shall" always set the sample frequency to "refer to stream" for
> L-PCM and IEC61937 compressed audio.  The above looks like it violates
> the HDMI specification as I'm willing to bet that hdmi_params.aud_hdmi_fs
> gets passed over into the audio info frame.
>
> Many of the fields in the audio info frame are supposed to be set as
> "refer to stream".  I'd suggest ensuring that you're compliant with
> these.

The audio inforame is generated using

        struct hdmi_audio_infoframe frame;
        hdmi_audio_infoframe_init(&frame);
        frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
        frame.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
        frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
        frame.channels =
            mtk_hdmi_aud_get_chnl_count(
            hdmi->aud_param.aud_input_chan_type);
        hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));

later. aud_hdmi_fs/iec_frame_fs are used to select the values written to
the N/CTS register. Instead of those I could just pass the sample_rate
down to the lower layers.

> The second thing is that "hdmi_params.hdmi_l_channel_state" looks like
> it's the IEC958 bytes.  These must be correct for some of the higher
> end HDMI receivers (eg, Yamaha RX-V677) to correctly process the audio.

I think you are right. These values are written to 24-byte register sets
"L_STATUS" and "R_STATUS" (padded with zeroes) as well as to the 5-byte
register set "I2S_C_STA" for the first five bytes.

> > +		break;
> > +	default:
> > +		dev_err(hdmi->dev, "rate[%d] not supported!\n",
> > +			params->sample_rate);
> > +		return -EINVAL;
> > +	}
> > +
> > +	switch (daifmt->fmt) {
> > +	case HDMI_I2S:
> > +		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> > +		hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> > +		hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
> > +		hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> > +		hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
> > +		break;
> > +	default:
> > +		dev_err(hdmi->dev, "%s: Invalid format %d\n", __func__,
> > +			daifmt->fmt);
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* channel status */
> > +	/* byte 0: no copyright is asserted, mode 0 */
> > +	hdmi_params.hdmi_l_channel_state[0] = 1 << 2;
> > +	/* byte 1: category code */
> > +	hdmi_params.hdmi_l_channel_state[1] = 0;
> > +	/* byte 2: source/channel number don't take into account */
> > +	hdmi_params.hdmi_l_channel_state[2] = 0;
> > +	/* byte 4: word length 16bits */
> > +	hdmi_params.hdmi_l_channel_state[4] = 0x2;
> > +	memcpy(hdmi_params.hdmi_r_channel_state,
> > +	       hdmi_params.hdmi_l_channel_state,
> > +	       sizeof(hdmi_params.hdmi_l_channel_state));
> 
> Hmm, yes, it is the IEC958 channel status bytes.  We have a helper
> for this - snd_pcm_create_iec958_consumer().

hdmi-codec already calls snd_pcm_create_iec958_consumer and provides the
result via params->iec.state, so I'll try to just use that.

regards
Philipp

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

* Re: [RFC v2 3/6] ASoC: mediatek: Add HDMI dai-links in the machine driver
  2016-01-05 12:46       ` Mark Brown
@ 2016-01-07 10:06         ` Philipp Zabel
  0 siblings, 0 replies; 19+ messages in thread
From: Philipp Zabel @ 2016-01-07 10:06 UTC (permalink / raw)
  To: Mark Brown
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Russell King - ARM Linux, Arnaud Pouliquen, Koro Chen,
	Jyri Sarha, Liam Girdwood, linux-mediatek, Daniel Kurtz, kernel,
	Matthias Brugger, Cawa Cheng

Am Dienstag, den 05.01.2016, 12:46 +0000 schrieb Mark Brown:
> On Mon, Jan 04, 2016 at 08:15:44PM +0100, Philipp Zabel wrote:
> > From: Koro Chen <koro.chen@mediatek.com>
> > 
> > This creates pcmC0D2p for the HDMI playback in the same card.
> > 
> > Signed-off-by: Koro Chen <koro.chen@mediatek.com>
> > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> 
> Please don't send new patches in reply to the middle of an existing
> series, it makes it very hard to tell what's going on.  If you need to
> send a new version resend the whole series.

Sorry, I had to manually restart an aborted git send-email and
accidentally chose the wrong --in-reply-to Message-Id for this patch.
It's all just one series.

regards
Philipp

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

* Re: [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support
  2016-01-04 19:19   ` [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support Philipp Zabel
@ 2016-01-07 17:09     ` Jyri Sarha
  2016-01-08  8:43       ` Philipp Zabel
  0 siblings, 1 reply; 19+ messages in thread
From: Jyri Sarha @ 2016-01-07 17:09 UTC (permalink / raw)
  To: Philipp Zabel, alsa-devel
  Cc: Jean-Francois Moine, Koro Chen, Lars-Peter Clausen,
	Russell King - ARM Linux, Arnaud Pouliquen, Liam Girdwood,
	Daniel Kurtz, Cawa Cheng, Mark Brown, linux-mediatek, kernel,
	Matthias Brugger

On 01/04/16 21:19, Philipp Zabel wrote:
> Use HDMI connection / disconnection notifications to update an ALSA
> jack object. Also make a copy of the ELD block after every change.
>

The jack part looks good to me AFAIU, but I think we should just update 
the local ELD copy with data given in the ELD notification. It then 
depends on the implementation details whether the get_eld() callback is 
needed at all or if it should be called once at the probe time.

Then it is a separate issue to check if the currently played stream is 
still supported after an ELD update, and to decide what to do about it 
if it is not.

Best regards,
Jyri

> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
>   include/sound/hdmi-codec.h    |  6 ++++
>   sound/soc/codecs/hdmi-codec.c | 72 ++++++++++++++++++++++++++++++++++++++++++-
>   2 files changed, 77 insertions(+), 1 deletion(-)
>
> diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
> index 15fe70f..8b6219d 100644
> --- a/include/sound/hdmi-codec.h
> +++ b/include/sound/hdmi-codec.h
> @@ -99,6 +99,12 @@ struct hdmi_codec_pdata {
>   	int max_i2s_channels;
>   };
>
> +struct snd_soc_codec;
> +struct snd_soc_jack;
> +
> +int hdmi_codec_set_jack_detect(struct snd_soc_codec *codec,
> +			       struct snd_soc_jack *jack);
> +
>   #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
>
>   #endif /* __HDMI_CODEC_H__ */
> diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
> index 687332d..41f28ab 100644
> --- a/sound/soc/codecs/hdmi-codec.c
> +++ b/sound/soc/codecs/hdmi-codec.c
> @@ -12,9 +12,12 @@
>    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
>    * General Public License for more details.
>    */
> +#include <linux/hdmi-not.h>
>   #include <linux/module.h>
> +#include <linux/notifier.h>
>   #include <linux/string.h>
>   #include <sound/core.h>
> +#include <sound/jack.h>
>   #include <sound/pcm.h>
>   #include <sound/pcm_params.h>
>   #include <sound/soc.h>
> @@ -27,11 +30,15 @@
>   struct hdmi_codec_priv {
>   	struct hdmi_codec_pdata hcd;
>   	struct snd_soc_dai_driver *daidrv;
> +	struct snd_soc_jack *jack;
>   	struct hdmi_codec_daifmt daifmt[2];
>   	struct mutex current_stream_lock;
>   	struct snd_pcm_substream *current_stream;
>   	struct snd_pcm_hw_constraint_list ratec;
>   	uint8_t eld[MAX_ELD_BYTES];
> +	struct device *dev;
> +	struct notifier_block nb;
> +	unsigned int jack_status;
>   };
>
>   static const struct snd_soc_dapm_widget hdmi_widgets[] = {
> @@ -326,6 +333,63 @@ static struct snd_soc_codec_driver hdmi_codec = {
>   	.num_dapm_routes = ARRAY_SIZE(hdmi_routes),
>   };
>
> +static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
> +				   unsigned int jack_status)
> +{
> +	if (!hcp->jack)
> +		return;
> +
> +	if (jack_status != hcp->jack_status) {
> +		snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
> +		hcp->jack_status = jack_status;
> +	}
> +}
> +
> +static int hdmi_codec_notify(struct notifier_block *nb, unsigned long event,
> +			     void *data)
> +{
> +	struct hdmi_codec_priv *hcp = container_of(nb, struct hdmi_codec_priv,
> +						   nb);
> +	union hdmi_event *event_block = data;
> +	int ret;
> +
> +	if (hcp->dev->parent != event_block->base.source)
> +		return NOTIFY_OK;
> +
> +	if (!hcp->jack)
> +		return NOTIFY_OK;
> +
> +	switch (event) {
> +	case HDMI_CONNECTED:
> +		hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
> +		break;
> +	case HDMI_DISCONNECTED:
> +		hdmi_codec_jack_report(hcp, 0);
> +		break;
> +	case HDMI_NEW_ELD:
> +		if (hcp->hcd.ops->get_eld)
> +			ret = hcp->hcd.ops->get_eld(hcp->dev->parent, hcp->eld,
> +						    sizeof(hcp->eld));
> +		break;
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +
> +int hdmi_codec_set_jack_detect(struct snd_soc_codec *codec,
> +			       struct snd_soc_jack *jack)
> +{
> +	struct hdmi_codec_priv *hcp = snd_soc_codec_get_drvdata(codec);
> +
> +	hcp->jack = jack;
> +	hcp->nb.notifier_call = hdmi_codec_notify;
> +
> +	hdmi_register_notifier(&hcp->nb);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(hdmi_codec_set_jack_detect);
> +
>   static int hdmi_codec_probe(struct platform_device *pdev)
>   {
>   	struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
> @@ -370,6 +434,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
>   	if (hcd->spdif)
>   		hcp->daidrv[i] = hdmi_spdif_dai;
>
> +	dev_set_drvdata(dev, hcp);
> +
>   	ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
>   				     dai_count);
>   	if (ret) {
> @@ -378,12 +444,16 @@ static int hdmi_codec_probe(struct platform_device *pdev)
>   		return ret;
>   	}
>
> -	dev_set_drvdata(dev, hcp);
> +	hcp->dev = dev;
> +
>   	return 0;
>   }
>
>   static int hdmi_codec_remove(struct platform_device *pdev)
>   {
> +	struct hdmi_codec_priv *hcp = platform_get_drvdata(pdev);
> +
> +	hdmi_unregister_notifier(&hcp->nb);
>   	snd_soc_unregister_codec(&pdev->dev);
>   	return 0;
>   }
>

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

* Re: [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support
  2016-01-07 17:09     ` Jyri Sarha
@ 2016-01-08  8:43       ` Philipp Zabel
  2016-01-08  9:57         ` Jyri Sarha
  0 siblings, 1 reply; 19+ messages in thread
From: Philipp Zabel @ 2016-01-08  8:43 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Russell King - ARM Linux, Arnaud Pouliquen, Koro Chen,
	Daniel Kurtz, Liam Girdwood, Mark Brown, linux-mediatek, kernel,
	Matthias Brugger, Cawa Cheng

Hi Jyri,

Am Donnerstag, den 07.01.2016, 19:09 +0200 schrieb Jyri Sarha:
> On 01/04/16 21:19, Philipp Zabel wrote:
> > Use HDMI connection / disconnection notifications to update an ALSA
> > jack object. Also make a copy of the ELD block after every change.
> >
> 
> The jack part looks good to me AFAIU, 

If this is in principle an acceptable idea, this leaves the issue that
the jack has an initial state and right now we can't query it but
instead would have to wait for the first HDMI_(DIS)CONNECTED
notification before it can be set. Would it make sense to add an
is_connected callback to the hdmi_codec_ops or does this rather belong
somewhere else?

> but I think we should just update 
> the local ELD copy with data given in the ELD notification. It then 
> depends on the implementation details whether the get_eld() callback is 
> needed at all or if it should be called once at the probe time.

Thanks, that sounds reasonable.

> Then it is a separate issue to check if the currently played stream is 
> still supported after an ELD update, and to decide what to do about it 
> if it is not.
[...]

Possibly the HDMI driver itself should just mute if the format is not
supported, and userspace should be notified?

regards
Philipp

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

* Re: [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support
  2016-01-08  8:43       ` Philipp Zabel
@ 2016-01-08  9:57         ` Jyri Sarha
  2016-01-08 10:46           ` Russell King - ARM Linux
  0 siblings, 1 reply; 19+ messages in thread
From: Jyri Sarha @ 2016-01-08  9:57 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Russell King - ARM Linux, Arnaud Pouliquen, Koro Chen,
	Daniel Kurtz, Liam Girdwood, Mark Brown, linux-mediatek, kernel,
	Matthias Brugger, Cawa Cheng

On 01/08/16 10:43, Philipp Zabel wrote:
> Hi Jyri,
>
> Am Donnerstag, den 07.01.2016, 19:09 +0200 schrieb Jyri Sarha:
>> On 01/04/16 21:19, Philipp Zabel wrote:
>>> Use HDMI connection / disconnection notifications to update an ALSA
>>> jack object. Also make a copy of the ELD block after every change.
>>>
>>
>> The jack part looks good to me AFAIU,
>
> If this is in principle an acceptable idea, this leaves the issue that
> the jack has an initial state and right now we can't query it but
> instead would have to wait for the first HDMI_(DIS)CONNECTED
> notification before it can be set. Would it make sense to add an
> is_connected callback to the hdmi_codec_ops or does this rather belong
> somewhere else?
>

To me it would feel best if the hdmi notification would send the current 
edid, eld, and connection state when the hdmi notification is 
registered. But then again, I may not see the full picture.

BTW, if we are going this way, the hdmi notification should be 
registered always in probe phase. I don't think the 
hdmi_codec_set_jack_detect() should be needed at all. Simple simple 
flags in struct hdmi_codec_pdata that tells if the jack detection is 
supported should do. Hmm, I am not sure if we need even that.

>> but I think we should just update
>> the local ELD copy with data given in the ELD notification. It then
>> depends on the implementation details whether the get_eld() callback is
>> needed at all or if it should be called once at the probe time.
>
> Thanks, that sounds reasonable.
>
>> Then it is a separate issue to check if the currently played stream is
>> still supported after an ELD update, and to decide what to do about it
>> if it is not.
> [...]
>
> Possibly the HDMI driver itself should just mute if the format is not
> supported, and userspace should be notified?
>

Another option would be simply aborting the playback. However having a 
mute control, that is forced to mute if the current stream is not 
supported, is an interesting idea. That would provide a way to notify 
the userspace without intrusively killing the stream.

Cheers,
Jyri

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

* Re: [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support
  2016-01-08  9:57         ` Jyri Sarha
@ 2016-01-08 10:46           ` Russell King - ARM Linux
  2016-01-08 10:52             ` Takashi Iwai
  2016-01-08 12:55             ` Mark Brown
  0 siblings, 2 replies; 19+ messages in thread
From: Russell King - ARM Linux @ 2016-01-08 10:46 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen, kernel,
	Arnaud Pouliquen, Koro Chen, Daniel Kurtz, Liam Girdwood,
	Mark Brown, linux-mediatek, Philipp Zabel, Matthias Brugger,
	Cawa Cheng

On Fri, Jan 08, 2016 at 11:57:11AM +0200, Jyri Sarha wrote:
> On 01/08/16 10:43, Philipp Zabel wrote:
> >Possibly the HDMI driver itself should just mute if the format is not
> >supported, and userspace should be notified?
> 
> Another option would be simply aborting the playback. However having a mute
> control, that is forced to mute if the current stream is not supported, is
> an interesting idea. That would provide a way to notify the userspace
> without intrusively killing the stream.

Firstly, remember that the sequence you'll likely see is:

- disconnect
- connect
- new edid
- new eld

The disconnect/connect cycle is HDMI protocol for "please re-read
the EDID" and is used (eg) by AV receivers to signal a change.  When
they change from HDMI pass-through mode in standby, to being powered
on, they typically switch from passing the displays EDID through
unmodified, to a modified version with their audio capabilities
included - and vice versa when they're placed back into standby.

The kernel's audio driver doesn't have any knowledge about the kind
of audio being passed through it: while it knows the alleged sample
rate, bits per sample, and number of channels, these are PCM details,
and not compressed audio details.  Compressed audio is normally sent
with the kernel driver configured for 16 bit, 2 channel and an
appropriate sample rate, with the IEC958 channel status data setup
by the application (via libasound) to indicate non-audio amongst
other details.  Therefore, the kernel driver doesn't know a
nature of the compressed audio stream, and can't "mute" the stream
if the ELD indicates that the compressed audio stream has gone
away.

Given that, I'd like to throw in here another detail: iirc, i915's
HDMI exports the ELD to userspace via a control called "ELD" - see
eld_bytes_ctl in sound/pci/hda/patch_hdmi.c.  This allows userspace
to monitor, and read the ELD including which compressed audio formats
are supported.  I'm not currently aware of anything that makes use of
this, but as there is this precedent for exporting this information,
maybe it should become a standard way, so that video playback
applications can then select an appropriate audio stream depending on
the current properties of the connected device?

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support
  2016-01-08 10:46           ` Russell King - ARM Linux
@ 2016-01-08 10:52             ` Takashi Iwai
  2016-01-08 12:55             ` Mark Brown
  1 sibling, 0 replies; 19+ messages in thread
From: Takashi Iwai @ 2016-01-08 10:52 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen,
	Philipp Zabel, Arnaud Pouliquen, Koro Chen, Jyri Sarha,
	Liam Girdwood, Mark Brown, linux-mediatek, Daniel Kurtz, kernel,
	Matthias Brugger, Cawa Cheng

On Fri, 08 Jan 2016 11:46:23 +0100,
Russell King - ARM Linux wrote:
> 
> Given that, I'd like to throw in here another detail: iirc, i915's
> HDMI exports the ELD to userspace via a control called "ELD" - see
> eld_bytes_ctl in sound/pci/hda/patch_hdmi.c.  This allows userspace
> to monitor, and read the ELD including which compressed audio formats
> are supported.  I'm not currently aware of anything that makes use of
> this, but as there is this precedent for exporting this information,
> maybe it should become a standard way, so that video playback
> applications can then select an appropriate audio stream depending on
> the current properties of the connected device?

Right, the ELD ctl elements were introduced exactly for such a
purpose.  Though, I'm not sure currently which user-space app is
actually referring to this information, too.  But certainly it's a
good thing to have for other drivers.


Takashi

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

* Re: [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support
  2016-01-08 10:46           ` Russell King - ARM Linux
  2016-01-08 10:52             ` Takashi Iwai
@ 2016-01-08 12:55             ` Mark Brown
  1 sibling, 0 replies; 19+ messages in thread
From: Mark Brown @ 2016-01-08 12:55 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Jean-Francois Moine, alsa-devel, Lars-Peter Clausen, kernel,
	Arnaud Pouliquen, Koro Chen, Jyri Sarha, Liam Girdwood,
	linux-mediatek, Daniel Kurtz, Philipp Zabel, Matthias Brugger,
	Cawa Cheng


[-- Attachment #1.1: Type: text/plain, Size: 709 bytes --]

On Fri, Jan 08, 2016 at 10:46:23AM +0000, Russell King - ARM Linux wrote:

> Given that, I'd like to throw in here another detail: iirc, i915's
> HDMI exports the ELD to userspace via a control called "ELD" - see
> eld_bytes_ctl in sound/pci/hda/patch_hdmi.c.  This allows userspace
> to monitor, and read the ELD including which compressed audio formats
> are supported.  I'm not currently aware of anything that makes use of
> this, but as there is this precedent for exporting this information,
> maybe it should become a standard way, so that video playback
> applications can then select an appropriate audio stream depending on
> the current properties of the connected device?

That makes sense to me.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Applied "ASoC: mediatek: address dai link array entries by enum" to the asoc tree
  2016-01-04 19:09   ` [RFC v2 2/6] ASoC: mediatek: address dai link array entries by enum Philipp Zabel
  2016-01-04 19:15     ` [RFC v2 3/6] ASoC: mediatek: Add HDMI dai-links in the machine driver Philipp Zabel
@ 2016-03-05 12:24     ` Mark Brown
  1 sibling, 0 replies; 19+ messages in thread
From: Mark Brown @ 2016-03-05 12:24 UTC (permalink / raw)
  To: Philipp Zabel, Mark Brown; +Cc: alsa-devel

The patch

   ASoC: mediatek: address dai link array entries by enum

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 05f5afd3f0d915537b67d3cfcb464e6836a65caf Mon Sep 17 00:00:00 2001
From: Philipp Zabel <p.zabel@pengutronix.de>
Date: Wed, 2 Mar 2016 15:49:06 +0100
Subject: [PATCH] ASoC: mediatek: address dai link array entries by enum

This should be more robust to future changes than adressing
array entries by index number.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/mediatek/mt8173-rt5650-rt5676.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
index 50ba538eccb3..5c4c58c69c51 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -131,10 +131,17 @@ static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = {
 	},
 };
 
+enum {
+	DAI_LINK_PLAYBACK,
+	DAI_LINK_CAPTURE,
+	DAI_LINK_CODEC_I2S,
+	DAI_LINK_INTERCODEC
+};
+
 /* Digital audio interface glue - connects codec <---> CPU */
 static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 	/* Front End DAI links */
-	{
+	[DAI_LINK_PLAYBACK] = {
 		.name = "rt5650_rt5676 Playback",
 		.stream_name = "rt5650_rt5676 Playback",
 		.cpu_dai_name = "DL1",
@@ -144,7 +151,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 		.dynamic = 1,
 		.dpcm_playback = 1,
 	},
-	{
+	[DAI_LINK_CAPTURE] = {
 		.name = "rt5650_rt5676 Capture",
 		.stream_name = "rt5650_rt5676 Capture",
 		.cpu_dai_name = "VUL",
@@ -156,7 +163,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 	},
 
 	/* Back End DAI links */
-	{
+	[DAI_LINK_CODEC_I2S] = {
 		.name = "Codec",
 		.cpu_dai_name = "I2S",
 		.no_pcm = 1,
@@ -170,7 +177,8 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
 		.dpcm_playback = 1,
 		.dpcm_capture = 1,
 	},
-	{ /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
+	/* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
+	[DAI_LINK_INTERCODEC] = {
 		.name = "rt5650_rt5676 intercodec",
 		.stream_name = "rt5650_rt5676 intercodec",
 		.cpu_dai_name = "snd-soc-dummy-dai",
@@ -240,7 +248,7 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	mt8173_rt5650_rt5676_codec_conf[0].of_node =
 		mt8173_rt5650_rt5676_codecs[1].of_node;
 
-	mt8173_rt5650_rt5676_dais[3].codec_of_node =
+	mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codec_of_node =
 		mt8173_rt5650_rt5676_codecs[1].of_node;
 
 	card->dev = &pdev->dev;
-- 
2.7.0

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

end of thread, other threads:[~2016-03-05 12:24 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-04 19:09 [RFC v2 0/6] ASoC: Add mediatek HDMI codec support Philipp Zabel
2016-01-04 19:09 ` [RFC v2 1/6] drm/mediatek: hdmi: Add audio interface to the hdmi-codec driver Philipp Zabel
2016-01-04 22:29   ` Russell King - ARM Linux
2016-01-05 14:56     ` Philipp Zabel
     [not found] ` <1451934551-21333-1-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2016-01-04 19:09   ` [RFC v2 2/6] ASoC: mediatek: address dai link array entries by enum Philipp Zabel
2016-01-04 19:15     ` [RFC v2 3/6] ASoC: mediatek: Add HDMI dai-links in the machine driver Philipp Zabel
2016-01-05 12:46       ` Mark Brown
2016-01-07 10:06         ` Philipp Zabel
2016-03-05 12:24     ` Applied "ASoC: mediatek: address dai link array entries by enum" to the asoc tree Mark Brown
2016-01-04 19:19   ` [RFC v2 6/6] ASoC: hdmi-codec: Use HDMI notifications to add jack support Philipp Zabel
2016-01-07 17:09     ` Jyri Sarha
2016-01-08  8:43       ` Philipp Zabel
2016-01-08  9:57         ` Jyri Sarha
2016-01-08 10:46           ` Russell King - ARM Linux
2016-01-08 10:52             ` Takashi Iwai
2016-01-08 12:55             ` Mark Brown
2016-01-04 19:11 ` [RFC v2 0/6] ASoC: Add mediatek HDMI codec support Russell King - ARM Linux
2016-01-04 19:18 ` [RFC v2 4/6] video: rmk's HDMI notification prototype Philipp Zabel
2016-01-04 19:18 ` [RFC v2 5/6] drm/mediatek: hdmi: issue notifications Philipp Zabel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.