* [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
2015-09-18 11:06 [PATCH RFC v4 0/8] Implement generic ASoC HDMI codec and use it in tda998x Jyri Sarha
@ 2015-09-18 11:06 ` Jyri Sarha
[not found] ` <6fe9ab5dff972e6f228259d6818f3f481a11577d.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
[not found] ` <cover.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
` (3 subsequent siblings)
4 siblings, 1 reply; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel, airlied, linux-omap, devicetree, bcousson, alsa-devel
Cc: peter.ujfalusi, moinejf, tony, broonie, Jyri Sarha,
liam.r.girdwood, tomi.valkeinen, rmk+kernel
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.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
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
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
new file mode 100644
index 0000000..15fe70f
--- /dev/null
+++ b/include/sound/hdmi-codec.h
@@ -0,0 +1,104 @@
+/*
+ * hdmi-codec.h - HDMI Codec driver API
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Jyri Sarha <jsarha@ti.com>
+ *
+ * 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__ */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0142396..1e6c7e7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -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"
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 7d7cc1b..068d483 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -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
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
new file mode 100644
index 0000000..687332d
--- /dev/null
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -0,0 +1,404 @@
+/*
+ * ALSA SoC codec for HDMI encoder drivers
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Jyri Sarha <jsarha@ti.com>
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/string.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/pcm_drm_eld.h>
+#include <sound/hdmi-codec.h>
+#include <sound/pcm_iec958.h>
+
+#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
+
+struct hdmi_codec_priv {
+ struct hdmi_codec_pdata hcd;
+ struct snd_soc_dai_driver *daidrv;
+ 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];
+};
+
+static const struct snd_soc_dapm_widget hdmi_widgets[] = {
+ SND_SOC_DAPM_OUTPUT("TX"),
+};
+
+static const struct snd_soc_dapm_route hdmi_routes[] = {
+ { "TX", NULL, "Playback" },
+};
+
+enum {
+ DAI_ID_I2S = 0,
+ DAI_ID_SPDIF,
+};
+
+static void hdmi_codec_abort(struct device *dev)
+{
+ struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s()\n", __func__);
+
+ mutex_lock(&hcp->current_stream_lock);
+ if (hcp->current_stream && hcp->current_stream->runtime &&
+ snd_pcm_running(hcp->current_stream)) {
+ dev_info(dev, "HDMI audio playback aborted\n");
+ snd_pcm_stream_lock_irq(hcp->current_stream);
+ snd_pcm_stop(hcp->current_stream, SNDRV_PCM_STATE_DISCONNECTED);
+ snd_pcm_stream_unlock_irq(hcp->current_stream);
+ }
+ mutex_unlock(&hcp->current_stream_lock);
+}
+
+static int hdmi_codec_new_stream(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+ int ret = 0;
+
+ mutex_lock(&hcp->current_stream_lock);
+ if (!hcp->current_stream) {
+ hcp->current_stream = substream;
+ } else if (hcp->current_stream != substream) {
+ dev_err(dai->dev, "Only one simultaneous stream supported!\n");
+ ret = -EINVAL;
+ }
+ mutex_unlock(&hcp->current_stream_lock);
+
+ return ret;
+}
+
+static int hdmi_codec_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+ int ret = 0;
+
+ dev_dbg(dai->dev, "%s()\n", __func__);
+
+ ret = hdmi_codec_new_stream(substream, dai);
+ if (ret)
+ return ret;
+
+ if (hcp->hcd.ops->audio_startup) {
+ ret = hcp->hcd.ops->audio_startup(dai->dev->parent,
+ hdmi_codec_abort);
+ if (ret) {
+ mutex_lock(&hcp->current_stream_lock);
+ hcp->current_stream = NULL;
+ mutex_unlock(&hcp->current_stream_lock);
+ return ret;
+ }
+ }
+
+ if (hcp->hcd.ops->get_eld) {
+ ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->eld,
+ sizeof(hcp->eld));
+
+ if (!ret) {
+ ret = snd_pcm_hw_constraint_eld(substream->runtime,
+ hcp->eld);
+ if (ret)
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+
+ dev_dbg(dai->dev, "%s()\n", __func__);
+
+ WARN_ON(hcp->current_stream != substream);
+
+ hcp->hcd.ops->audio_shutdown(dai->dev->parent);
+
+ mutex_lock(&hcp->current_stream_lock);
+ hcp->current_stream = NULL;
+ mutex_unlock(&hcp->current_stream_lock);
+}
+
+static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+ struct hdmi_codec_params hp = {
+ .iec = {
+ .status = { 0 },
+ .subcode = { 0 },
+ .pad = 0,
+ .dig_subframe = { 0 },
+ }
+ };
+ int ret;
+
+ dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
+ params_width(params), params_rate(params),
+ params_channels(params));
+
+ ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status,
+ sizeof(hp.iec.status));
+ if (ret < 0) {
+ dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = hdmi_codec_new_stream(substream, dai);
+ if (ret)
+ return ret;
+
+ hdmi_audio_infoframe_init(&hp.cea);
+ hp.cea.channels = params_channels(params);
+ hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
+ hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
+ hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
+
+ hp.sample_width = params_width(params);
+ hp.sample_rate = params_rate(params);
+ hp.channels = params_channels(params);
+
+ return hcp->hcd.ops->hw_params(dai->dev->parent, &hcp->daifmt[dai->id],
+ &hp);
+}
+
+static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
+ unsigned int fmt)
+{
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+ struct hdmi_codec_daifmt cf = { 0 };
+ int ret = 0;
+
+ dev_dbg(dai->dev, "%s()\n", __func__);
+
+ if (dai->id == DAI_ID_SPDIF) {
+ cf.fmt = HDMI_SPDIF;
+ } else {
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ cf.bit_clk_master = 1;
+ cf.frame_clk_master = 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ cf.frame_clk_master = 1;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ cf.bit_clk_master = 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ cf.frame_clk_inv = 1;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ cf.bit_clk_inv = 1;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ cf.frame_clk_inv = 1;
+ cf.bit_clk_inv = 1;
+ break;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ cf.fmt = HDMI_I2S;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ cf.fmt = HDMI_DSP_A;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ cf.fmt = HDMI_DSP_B;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ cf.fmt = HDMI_RIGHT_J;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ cf.fmt = HDMI_LEFT_J;
+ break;
+ case SND_SOC_DAIFMT_AC97:
+ cf.fmt = HDMI_AC97;
+ break;
+ default:
+ dev_err(dai->dev, "Invalid DAI interface format\n");
+ return -EINVAL;
+ }
+ }
+
+ hcp->daifmt[dai->id] = cf;
+
+ return ret;
+}
+
+static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+
+ dev_dbg(dai->dev, "%s()\n", __func__);
+
+ if (hcp->hcd.ops->digital_mute)
+ return hcp->hcd.ops->digital_mute(dai->dev->parent, mute);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops hdmi_dai_ops = {
+ .startup = hdmi_codec_startup,
+ .shutdown = hdmi_codec_shutdown,
+ .hw_params = hdmi_codec_hw_params,
+ .set_fmt = hdmi_codec_set_fmt,
+ .digital_mute = hdmi_codec_digital_mute,
+};
+
+
+#define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
+ SNDRV_PCM_RATE_192000)
+
+#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)
+
+static struct snd_soc_dai_driver hdmi_i2s_dai = {
+ .name = "i2s-hifi",
+ .id = DAI_ID_I2S,
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = HDMI_RATES,
+ .formats = I2S_FORMATS,
+ .sig_bits = 24,
+ },
+ .ops = &hdmi_dai_ops,
+};
+
+static const struct snd_soc_dai_driver hdmi_spdif_dai = {
+ .name = "spdif-hifi",
+ .id = DAI_ID_SPDIF,
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = HDMI_RATES,
+ .formats = SPDIF_FORMATS,
+ },
+ .ops = &hdmi_dai_ops,
+};
+
+static struct snd_soc_codec_driver hdmi_codec = {
+ .dapm_widgets = hdmi_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
+ .dapm_routes = hdmi_routes,
+ .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
+};
+
+static int hdmi_codec_probe(struct platform_device *pdev)
+{
+ struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ struct hdmi_codec_priv *hcp;
+ int dai_count, i = 0;
+ int ret;
+
+ dev_dbg(dev, "%s()\n", __func__);
+
+ if (!hcd) {
+ dev_err(dev, "%s: No plalform data\n", __func__);
+ return -EINVAL;
+ }
+
+ dai_count = hcd->i2s + hcd->spdif;
+ if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params ||
+ !hcd->ops->audio_shutdown) {
+ dev_err(dev, "%s: Invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL);
+ if (!hcp)
+ return -ENOMEM;
+
+ hcp->hcd = *hcd;
+ mutex_init(&hcp->current_stream_lock);
+
+ hcp->daidrv = devm_kzalloc(dev, dai_count * sizeof(*hcp->daidrv),
+ GFP_KERNEL);
+ if (!hcp->daidrv)
+ return -ENOMEM;
+
+ if (hcd->i2s) {
+ hcp->daidrv[i] = hdmi_i2s_dai;
+ hcp->daidrv[i].playback.channels_max =
+ hcd->max_i2s_channels;
+ i++;
+ }
+
+ if (hcd->spdif)
+ hcp->daidrv[i] = hdmi_spdif_dai;
+
+ ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
+ dai_count);
+ if (ret) {
+ dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ dev_set_drvdata(dev, hcp);
+ return 0;
+}
+
+static int hdmi_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver hdmi_codec_driver = {
+ .driver = {
+ .name = HDMI_CODEC_DRV_NAME,
+ },
+ .probe = hdmi_codec_probe,
+ .remove = hdmi_codec_remove,
+};
+
+module_platform_driver(hdmi_codec_driver);
+
+MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
+MODULE_DESCRIPTION("HDMI Audio Codec Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME);
--
1.9.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
[parent not found: <cover.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>]
* [PATCH RFC v4 1/8] ASoC: hdmi: Remove obsolete dummy HDMI codec
[not found] ` <cover.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
@ 2015-09-18 11:06 ` Jyri Sarha
2015-09-18 11:06 ` [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params Jyri Sarha
` (2 subsequent siblings)
3 siblings, 0 replies; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, airlied-cv59FeDIM0c,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
bcousson-rdvid1DuHRBWk0Htik3J/w,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: tony-4v6yS6AI5VpBDgjK7y7TUQ, broonie-DgEjT+Ai2ygdnm+yROfE0A,
liam.r.girdwood-VuQAYsv1563Yd54FQh9/CA,
peter.ujfalusi-l0cyMroinI0, tomi.valkeinen-l0cyMroinI0,
moinejf-GANU6spQydw, rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ,
Jyri Sarha
The hdmi stub codec has not been used since refactoring of OMAP HDMI
audio support.
Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
---
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
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0c9733e..0142396 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -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"
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4a32077..7d7cc1b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -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
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c
deleted file mode 100644
index bd42ad3..0000000
--- a/sound/soc/codecs/hdmi.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * ALSA SoC codec driver for HDMI audio codecs.
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Ricardo Neri <ricardo.neri-l0cyMroinI0@public.gmane.org>
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-
-#define DRV_NAME "hdmi-audio-codec"
-
-static const struct snd_soc_dapm_widget hdmi_widgets[] = {
- SND_SOC_DAPM_INPUT("RX"),
- SND_SOC_DAPM_OUTPUT("TX"),
-};
-
-static const struct snd_soc_dapm_route hdmi_routes[] = {
- { "Capture", NULL, "RX" },
- { "TX", NULL, "Playback" },
-};
-
-static struct snd_soc_dai_driver hdmi_codec_dai = {
- .name = "hdmi-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
- .sig_bits = 24,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
- },
-
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id hdmi_audio_codec_ids[] = {
- { .compatible = "linux,hdmi-audio", },
- { }
-};
-MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
-#endif
-
-static struct snd_soc_codec_driver hdmi_codec = {
- .dapm_widgets = hdmi_widgets,
- .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
- .dapm_routes = hdmi_routes,
- .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
- .ignore_pmdown_time = true,
-};
-
-static int hdmi_codec_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev, &hdmi_codec,
- &hdmi_codec_dai, 1);
-}
-
-static int hdmi_codec_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver hdmi_codec_driver = {
- .driver = {
- .name = DRV_NAME,
- .of_match_table = of_match_ptr(hdmi_audio_codec_ids),
- },
-
- .probe = hdmi_codec_probe,
- .remove = hdmi_codec_remove,
-};
-
-module_platform_driver(hdmi_codec_driver);
-
-MODULE_AUTHOR("Ricardo Neri <ricardo.neri-l0cyMroinI0@public.gmane.org>");
-MODULE_DESCRIPTION("ASoC generic HDMI codec driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params
[not found] ` <cover.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
2015-09-18 11:06 ` [PATCH RFC v4 1/8] ASoC: hdmi: Remove obsolete dummy HDMI codec Jyri Sarha
@ 2015-09-18 11:06 ` Jyri Sarha
[not found] ` <a7b69fb075b0ae993846cfb65abb20ecab5c9805.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
2015-09-21 9:37 ` Russell King - ARM Linux
2015-09-18 11:06 ` [PATCH RFC v4 4/8] drm/i2c: tda998x: Add support of a DT graph of ports Jyri Sarha
2015-09-18 11:06 ` [PATCH RFC v4 6/8] drm/i2c: tda998x: Improve tda998x_configure_audio() audio related pdata Jyri Sarha
3 siblings, 2 replies; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, airlied-cv59FeDIM0c,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
bcousson-rdvid1DuHRBWk0Htik3J/w,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: tony-4v6yS6AI5VpBDgjK7y7TUQ, broonie-DgEjT+Ai2ygdnm+yROfE0A,
liam.r.girdwood-VuQAYsv1563Yd54FQh9/CA,
peter.ujfalusi-l0cyMroinI0, tomi.valkeinen-l0cyMroinI0,
moinejf-GANU6spQydw, rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ,
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.
Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
---
include/sound/pcm_iec958.h | 2 ++
sound/core/pcm_iec958.c | 52 +++++++++++++++++++++++++++++++---------------
2 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/include/sound/pcm_iec958.h b/include/sound/pcm_iec958.h
index 0eed397..36f023a 100644
--- a/include/sound/pcm_iec958.h
+++ b/include/sound/pcm_iec958.h
@@ -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
diff --git a/sound/core/pcm_iec958.c b/sound/core/pcm_iec958.c
index 36b2d7a..c9f8b66 100644
--- a/sound/core/pcm_iec958.c
+++ b/sound/core/pcm_iec958.c
@@ -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);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 25+ messages in thread
[parent not found: <a7b69fb075b0ae993846cfb65abb20ecab5c9805.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>]
* Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params
[not found] ` <a7b69fb075b0ae993846cfb65abb20ecab5c9805.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
@ 2015-09-19 17:46 ` Mark Brown
0 siblings, 0 replies; 25+ messages in thread
From: Mark Brown @ 2015-09-19 17:46 UTC (permalink / raw)
To: Jyri Sarha
Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, airlied-cv59FeDIM0c,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
bcousson-rdvid1DuHRBWk0Htik3J/w,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, tony-4v6yS6AI5VpBDgjK7y7TUQ,
liam.r.girdwood-VuQAYsv1563Yd54FQh9/CA,
peter.ujfalusi-l0cyMroinI0, tomi.valkeinen-l0cyMroinI0,
moinejf-GANU6spQydw, rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ,
tiwai-l3A5Bk7waGM
[-- Attachment #1: Type: text/plain, Size: 4003 bytes --]
On Fri, Sep 18, 2015 at 02:06:39PM +0300, Jyri Sarha wrote:
> 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.
>
> Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
> ---
> 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).
> 2 files changed, 37 insertions(+), 17 deletions(-)
>
> diff --git a/include/sound/pcm_iec958.h b/include/sound/pcm_iec958.h
> index 0eed397..36f023a 100644
> --- a/include/sound/pcm_iec958.h
> +++ b/include/sound/pcm_iec958.h
> @@ -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
> diff --git a/sound/core/pcm_iec958.c b/sound/core/pcm_iec958.c
> index 36b2d7a..c9f8b66 100644
> --- a/sound/core/pcm_iec958.c
> +++ b/sound/core/pcm_iec958.c
> @@ -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);
> --
> 1.9.1
>
>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params
2015-09-18 11:06 ` [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params Jyri Sarha
[not found] ` <a7b69fb075b0ae993846cfb65abb20ecab5c9805.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
@ 2015-09-21 9:37 ` Russell King - ARM Linux
2015-09-21 14:39 ` Jyri Sarha
1 sibling, 1 reply; 25+ messages in thread
From: Russell King - ARM Linux @ 2015-09-21 9:37 UTC (permalink / raw)
To: Jyri Sarha
Cc: devicetree, alsa-devel, peter.ujfalusi, tomi.valkeinen, dri-devel,
liam.r.girdwood, tony, broonie, bcousson, linux-omap
On Fri, Sep 18, 2015 at 02:06:39PM +0300, Jyri Sarha wrote:
> 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?
--
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params
2015-09-21 9:37 ` Russell King - ARM Linux
@ 2015-09-21 14:39 ` Jyri Sarha
2015-09-21 15:08 ` Clemens Ladisch
0 siblings, 1 reply; 25+ messages in thread
From: Jyri Sarha @ 2015-09-21 14:39 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: devicetree, alsa-devel, peter.ujfalusi, moinejf, airlied,
tomi.valkeinen, Takashi Iwai, dri-devel, liam.r.girdwood, tony,
broonie, bcousson, linux-omap
On 09/21/15 12:37, Russell King - ARM Linux wrote:
> On Fri, Sep 18, 2015 at 02:06:39PM +0300, Jyri Sarha wrote:
>> 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.
> 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
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params
2015-09-21 14:39 ` Jyri Sarha
@ 2015-09-21 15:08 ` Clemens Ladisch
2015-09-21 17:25 ` Jyri Sarha
0 siblings, 1 reply; 25+ messages in thread
From: Clemens Ladisch @ 2015-09-21 15:08 UTC (permalink / raw)
To: Jyri Sarha, Russell King - ARM Linux
Cc: devicetree, alsa-devel, liam.r.girdwood, moinejf, airlied,
broonie, dri-devel, peter.ujfalusi, Takashi Iwai, tony,
tomi.valkeinen, bcousson, linux-omap
Jyri Sarha wrote:
> On 09/21/15 12:37, Russell King - ARM Linux wrote:
>> 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.
> 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
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params
2015-09-21 15:08 ` Clemens Ladisch
@ 2015-09-21 17:25 ` Jyri Sarha
0 siblings, 0 replies; 25+ messages in thread
From: Jyri Sarha @ 2015-09-21 17:25 UTC (permalink / raw)
To: Clemens Ladisch, Russell King - ARM Linux
Cc: devicetree, alsa-devel, liam.r.girdwood, moinejf, airlied,
broonie, dri-devel, peter.ujfalusi, Takashi Iwai, tony,
tomi.valkeinen, bcousson, linux-omap
On 09/21/15 18:08, Clemens Ladisch wrote:
>> >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
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH RFC v4 4/8] drm/i2c: tda998x: Add support of a DT graph of ports
[not found] ` <cover.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
2015-09-18 11:06 ` [PATCH RFC v4 1/8] ASoC: hdmi: Remove obsolete dummy HDMI codec Jyri Sarha
2015-09-18 11:06 ` [PATCH RFC v4 2/8] ALSA: pcm: add IEC958 channel status helper for hw_params Jyri Sarha
@ 2015-09-18 11:06 ` Jyri Sarha
[not found] ` <e9ebb04f781fef7cff99190d301fb64805b97d39.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
2015-09-18 11:06 ` [PATCH RFC v4 6/8] drm/i2c: tda998x: Improve tda998x_configure_audio() audio related pdata Jyri Sarha
3 siblings, 1 reply; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, airlied-cv59FeDIM0c,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
bcousson-rdvid1DuHRBWk0Htik3J/w,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: tony-4v6yS6AI5VpBDgjK7y7TUQ, broonie-DgEjT+Ai2ygdnm+yROfE0A,
liam.r.girdwood-VuQAYsv1563Yd54FQh9/CA,
peter.ujfalusi-l0cyMroinI0, tomi.valkeinen-l0cyMroinI0,
moinejf-GANU6spQydw, rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ,
Jyri Sarha
From: Jean-Francois Moine <moinejf-GANU6spQydw@public.gmane.org>
Two kinds of ports may be declared in a DT graph of ports: video and audio.
This patch accepts the port value from a video port as an alternative
to the video-ports property.
It also accepts audio ports in the case the transmitter is not used as
a slave encoder.
The new file include/sound/tda998x.h prepares to the definition of
a tda998x CODEC.
Signed-off-by: Jean-Francois Moine <moinejf-GANU6spQydw@public.gmane.org>
Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
---
.../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
diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
index e9e4bce..35f6a80 100644
--- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
+++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
@@ -16,6 +16,35 @@ Optional properties:
- video-ports: 24 bits value which defines how the video controller
output is wired to the TDA998x input - default: <0x230145>
+ This property is not used when ports are defined.
+
+Optional nodes:
+
+ - port: up to three ports.
+ The ports are defined according to [1].
+
+ Video port.
+ There may be only one video port.
+ This one must contain the following property:
+
+ - port-type: must be "rgb"
+
+ and may contain the optional property:
+
+ - reg: 24 bits value which defines how the video controller
+ output is wired to the TDA998x input (video pins)
+ When absent, the default value is <0x230145>.
+
+ Audio ports.
+ There may be one or two audio ports.
+ These ones must contain the following properties:
+
+ - port-type: must be "i2s" or "spdif"
+
+ - reg: 8 bits value which defines how the audio controller
+ output is wired to the TDA998x input (audio pins)
+
+[1] Documentation/devicetree/bindings/graph.txt
Example:
@@ -26,4 +55,26 @@ Example:
interrupts = <27 2>; /* falling edge */
pinctrl-0 = <&pmx_camera>;
pinctrl-names = "default";
+
+ port@230145 {
+ port-type = "rgb";
+ reg = <0x230145>;
+ hdmi_0: endpoint {
+ remote-endpoint = <&lcd0_0>;
+ };
+ };
+ port@3 { /* AP1 = I2S */
+ port-type = "i2s";
+ reg = <0x03>;
+ tda998x_i2s: endpoint {
+ remote-endpoint = <&audio1_i2s>;
+ };
+ };
+ port@4 { /* AP2 = S/PDIF */
+ port-type = "spdif";
+ reg = <0x04>;
+ tda998x_spdif: endpoint {
+ remote-endpoint = <&audio1_spdif1>;
+ };
+ };
};
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 424228b..0952eac 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -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", ®);
+ 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;
diff --git a/include/sound/tda998x.h b/include/sound/tda998x.h
new file mode 100644
index 0000000..bef1da7
--- /dev/null
+++ b/include/sound/tda998x.h
@@ -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
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH RFC v4 6/8] drm/i2c: tda998x: Improve tda998x_configure_audio() audio related pdata
[not found] ` <cover.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
` (2 preceding siblings ...)
2015-09-18 11:06 ` [PATCH RFC v4 4/8] drm/i2c: tda998x: Add support of a DT graph of ports Jyri Sarha
@ 2015-09-18 11:06 ` Jyri Sarha
3 siblings, 0 replies; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, airlied-cv59FeDIM0c,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
bcousson-rdvid1DuHRBWk0Htik3J/w,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: tony-4v6yS6AI5VpBDgjK7y7TUQ, broonie-DgEjT+Ai2ygdnm+yROfE0A,
liam.r.girdwood-VuQAYsv1563Yd54FQh9/CA,
peter.ujfalusi-l0cyMroinI0, tomi.valkeinen-l0cyMroinI0,
moinejf-GANU6spQydw, rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ,
Jyri Sarha
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.
Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
---
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(-)
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 225034b..d500840 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -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 = {
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 4dc2dc0..2fc6399 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -47,7 +47,7 @@ struct tda998x_priv {
u8 vip_cntrl_0;
u8 vip_cntrl_1;
u8 vip_cntrl_2;
- struct tda998x_encoder_params params;
+ struct tda998x_audio_params audio_params;
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
@@ -597,15 +597,6 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
return IRQ_HANDLED;
}
-static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes)
-{
- int sum = 0;
-
- while (bytes--)
- sum -= *buf++;
- return sum;
-}
-
#define HB(x) (x)
#define PB(x) (HB(2) + 1 + (x))
@@ -618,24 +609,22 @@ tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr,
reg_set(priv, REG_DIP_IF_FLAGS, bit);
}
-static void
-tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p)
+static int tda998x_write_aif(struct tda998x_priv *priv,
+ struct hdmi_audio_infoframe *cea)
{
- u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1];
-
- memset(buf, 0, sizeof(buf));
- buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO;
- buf[HB(1)] = 0x01;
- buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE;
- buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */
- buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */
- buf[PB(4)] = p->audio_frame[4];
- buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */
+ uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+ int len;
- buf[PB(0)] = tda998x_cksum(buf, sizeof(buf));
+ len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf));
+ if (len < 0) {
+ dev_err(&priv->hdmi->dev,
+ "Failed to pack audio infoframe: %d\n", len);
+ return len;
+ }
- tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf,
- sizeof(buf));
+ /* Write the audio information packet */
+ tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len);
+ return 0;
}
static void
@@ -670,19 +659,20 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, bool on)
}
}
-static void
+static int
tda998x_configure_audio(struct tda998x_priv *priv,
- struct drm_display_mode *mode, struct tda998x_encoder_params *p)
+ struct tda998x_audio_params *params,
+ unsigned mode_clock)
{
uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv;
uint32_t n;
/* Enable audio ports */
- reg_write(priv, REG_ENA_AP, p->audio_cfg);
- reg_write(priv, REG_ENA_ACLK, p->audio_clk_cfg);
+ reg_write(priv, REG_ENA_AP, params->config);
+ reg_write(priv, REG_ENA_ACLK, params->format == AFMT_SPDIF ? 0 : 1);
/* Set audio input source */
- switch (p->audio_format) {
+ switch (params->format) {
case AFMT_SPDIF:
reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF);
clksel_aip = AIP_CLKSEL_AIP_SPDIF;
@@ -694,12 +684,25 @@ tda998x_configure_audio(struct tda998x_priv *priv,
reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_I2S);
clksel_aip = AIP_CLKSEL_AIP_I2S;
clksel_fs = AIP_CLKSEL_FS_ACLK;
- cts_n = CTS_N_M(3) | CTS_N_K(3);
+ switch (params->sample_width) {
+ case 16:
+ cts_n = CTS_N_M(3) | CTS_N_K(1);
+ break;
+ case 18:
+ case 20:
+ case 24:
+ cts_n = CTS_N_M(3) | CTS_N_K(2);
+ break;
+ default:
+ case 32:
+ cts_n = CTS_N_M(3) | CTS_N_K(3);
+ break;
+ }
break;
default:
BUG();
- return;
+ return -EINVAL;
}
reg_write(priv, REG_AIP_CLKSEL, clksel_aip);
@@ -715,11 +718,11 @@ tda998x_configure_audio(struct tda998x_priv *priv,
* assume 100MHz requires larger divider.
*/
adiv = AUDIO_DIV_SERCLK_8;
- if (mode->clock > 100000)
+ if (mode_clock > 100000)
adiv++; /* AUDIO_DIV_SERCLK_16 */
/* S/PDIF asks for a larger divider */
- if (p->audio_format == AFMT_SPDIF)
+ if (params->format == AFMT_SPDIF)
adiv++; /* AUDIO_DIV_SERCLK_16 or _32 */
reg_write(priv, REG_AUDIO_DIV, adiv);
@@ -728,7 +731,7 @@ tda998x_configure_audio(struct tda998x_priv *priv,
* This is the approximate value of N, which happens to be
* the recommended values for non-coherent clocks.
*/
- n = 128 * p->audio_sample_rate / 1000;
+ n = 128 * params->sample_rate / 1000;
/* Write the CTS and N values */
buf[0] = 0x44;
@@ -747,19 +750,13 @@ tda998x_configure_audio(struct tda998x_priv *priv,
reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS);
/* Write the channel status */
- buf[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
- buf[1] = 0x00;
- buf[2] = IEC958_AES3_CON_FS_NOTID;
- buf[3] = IEC958_AES4_CON_ORIGFS_NOTID |
- IEC958_AES4_CON_MAX_WORDLEN_24;
- reg_write_range(priv, REG_CH_STAT_B(0), buf, 4);
+ reg_write_range(priv, REG_CH_STAT_B(0), params->status, 4);
tda998x_audio_mute(priv, true);
msleep(20);
tda998x_audio_mute(priv, false);
- /* Write the audio information packet */
- tda998x_write_aif(priv, p);
+ return tda998x_write_aif(priv, ¶ms->cea);
}
/* DRM encoder functions */
@@ -780,9 +777,7 @@ static void tda998x_encoder_set_config(struct tda998x_priv *priv,
VIP_CNTRL_2_SWAP_F(p->swap_f) |
(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;
+ priv->audio_params = p->audio;
}
static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
@@ -1033,9 +1028,11 @@ tda998x_encoder_mode_set(struct tda998x_priv *priv,
tda998x_write_avi(priv, adjusted_mode);
- if (priv->params.audio_cfg)
- tda998x_configure_audio(priv, adjusted_mode,
- &priv->params);
+ if (priv->audio_params.config) {
+ tda998x_configure_audio(priv,
+ &priv->audio_params,
+ adjusted_mode->clock);
+ }
}
}
@@ -1416,12 +1413,28 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
}
}
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;
+ struct tda998x_audio_params params = {
+ .config = priv->audio.ports[0],
+ .format = priv->audio.port_types[0],
+ .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,
+ },
+ };
+
+ priv->audio_params = params;
}
}
diff --git a/include/drm/i2c/tda998x.h b/include/drm/i2c/tda998x.h
index 3e419d9..dfe7829 100644
--- a/include/drm/i2c/tda998x.h
+++ b/include/drm/i2c/tda998x.h
@@ -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
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH RFC v4 5/8] drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing
2015-09-18 11:06 [PATCH RFC v4 0/8] Implement generic ASoC HDMI codec and use it in tda998x Jyri Sarha
2015-09-18 11:06 ` [PATCH RFC v4 3/8] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders Jyri Sarha
[not found] ` <cover.1442572860.git.jsarha-l0cyMroinI0@public.gmane.org>
@ 2015-09-18 11:06 ` Jyri Sarha
2015-09-18 11:06 ` [PATCH RFC v4 7/8] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality Jyri Sarha
2015-09-18 11:06 ` [PATCH RFC v4 8/8] ARM: dts: am335x-boneblack: Add HDMI audio support Jyri Sarha
4 siblings, 0 replies; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel, airlied, linux-omap, devicetree, bcousson, alsa-devel
Cc: peter.ujfalusi, tony, broonie, Jyri Sarha, liam.r.girdwood,
tomi.valkeinen, rmk+kernel
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.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
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
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 0952eac..4dc2dc0 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -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", ®);
+ 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;
diff --git a/include/sound/tda998x.h b/include/sound/tda998x.h
deleted file mode 100644
index bef1da7..0000000
--- a/include/sound/tda998x.h
+++ /dev/null
@@ -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
--
1.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH RFC v4 7/8] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality
2015-09-18 11:06 [PATCH RFC v4 0/8] Implement generic ASoC HDMI codec and use it in tda998x Jyri Sarha
` (2 preceding siblings ...)
2015-09-18 11:06 ` [PATCH RFC v4 5/8] drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing Jyri Sarha
@ 2015-09-18 11:06 ` Jyri Sarha
2015-09-18 11:06 ` [PATCH RFC v4 8/8] ARM: dts: am335x-boneblack: Add HDMI audio support Jyri Sarha
4 siblings, 0 replies; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel, airlied, linux-omap, devicetree, bcousson, alsa-devel
Cc: peter.ujfalusi, moinejf, tony, broonie, Jyri Sarha,
liam.r.girdwood, tomi.valkeinen, rmk+kernel
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.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
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(-)
diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed6..088f278 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -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.
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 2fc6399..1a9bbf2 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/irq.h>
#include <sound/asoundef.h>
+#include <sound/hdmi-codec.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
@@ -30,9 +31,9 @@
#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_audio_port {
+ u8 format; /* AFMT_xxx */
+ u8 config; /* AP value */
};
struct tda998x_priv {
@@ -49,11 +50,13 @@ struct tda998x_priv {
u8 vip_cntrl_2;
struct tda998x_audio_params audio_params;
+ struct platform_device *audio_pdev;
+
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
- struct tda998x_audio audio;
+ struct tda998x_audio_port audio_port[2];
};
#define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv)
@@ -701,7 +704,7 @@ tda998x_configure_audio(struct tda998x_priv *priv,
break;
default:
- BUG();
+ dev_err(&priv->hdmi->dev, "Unsupported I2S format\n");
return -EINVAL;
}
@@ -1028,7 +1031,7 @@ tda998x_encoder_mode_set(struct tda998x_priv *priv,
tda998x_write_avi(priv, adjusted_mode);
- if (priv->audio_params.config) {
+ if (priv->audio_params.format != AFMT_UNUSED) {
tda998x_configure_audio(priv,
&priv->audio_params,
adjusted_mode->clock);
@@ -1124,6 +1127,8 @@ tda998x_encoder_get_modes(struct tda998x_priv *priv,
drm_mode_connector_update_edid_property(connector, edid);
n = drm_add_edid_modes(connector, edid);
priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid);
+ drm_edid_to_eld(connector, edid);
+
kfree(edid);
return n;
@@ -1160,6 +1165,9 @@ static void tda998x_destroy(struct tda998x_priv *priv)
}
i2c_unregister_device(priv->cec);
+
+ if (priv->audio_pdev)
+ platform_device_unregister(priv->audio_pdev);
}
/* Slave encoder support */
@@ -1234,6 +1242,133 @@ static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = {
.set_property = tda998x_encoder_set_property,
};
+static int tda998x_audio_hw_params(struct device *dev,
+ struct hdmi_codec_daifmt *daifmt,
+ struct hdmi_codec_params *params)
+{
+ struct tda998x_priv *priv = dev_get_drvdata(dev);
+ int i, ret;
+ struct tda998x_audio_params audio = {
+ .sample_width = params->sample_width,
+ .sample_rate = params->sample_rate,
+ .cea = params->cea,
+ };
+
+ if (!priv->encoder->crtc)
+ return -ENODEV;
+
+ memcpy(audio.status, params->iec.status,
+ min(sizeof(audio.status), sizeof(params->iec.status)));
+
+ switch (daifmt->fmt) {
+ case HDMI_I2S:
+ if (daifmt->bit_clk_inv || daifmt->frame_clk_inv ||
+ daifmt->bit_clk_master || daifmt->frame_clk_master) {
+ dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
+ daifmt->bit_clk_inv, daifmt->frame_clk_inv,
+ daifmt->bit_clk_master,
+ daifmt->frame_clk_master);
+ return -EINVAL;
+ }
+ for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++)
+ if (priv->audio_port[i].format == AFMT_I2S)
+ audio.config = priv->audio_port[i].config;
+ audio.format = AFMT_I2S;
+ break;
+ case HDMI_SPDIF:
+ for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++)
+ if (priv->audio_port[i].format == AFMT_SPDIF)
+ audio.config = priv->audio_port[i].config;
+ audio.format = AFMT_SPDIF;
+ break;
+ default:
+ dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt);
+ return -EINVAL;
+ }
+
+ if (audio.config == 0) {
+ dev_err(dev, "%s: No audio configutation found\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = tda998x_configure_audio(priv,
+ &audio,
+ priv->encoder->crtc->hwmode.clock);
+
+ return ret;
+}
+
+static void tda998x_audio_shutdown(struct device *dev)
+{
+ struct tda998x_priv *priv = dev_get_drvdata(dev);
+
+ reg_write(priv, REG_ENA_AP, 0);
+}
+
+int tda998x_audio_digital_mute(struct device *dev, bool enable)
+{
+ struct tda998x_priv *priv = dev_get_drvdata(dev);
+
+ tda998x_audio_mute(priv, enable);
+
+ return 0;
+}
+
+static int tda998x_audio_get_eld(struct device *dev, uint8_t *buf, size_t len)
+{
+ struct tda998x_priv *priv = dev_get_drvdata(dev);
+ struct drm_mode_config *config = &priv->encoder->dev->mode_config;
+ struct drm_connector *connector;
+ int ret = -ENODEV;
+
+ mutex_lock(&config->mutex);
+ list_for_each_entry(connector, &config->connector_list, head) {
+ if (priv->encoder == connector->encoder) {
+ memcpy(buf, connector->eld,
+ min(sizeof(connector->eld), len));
+ ret = 0;
+ }
+ }
+ mutex_unlock(&config->mutex);
+
+ return ret;
+}
+
+static const struct hdmi_codec_ops audio_codec_ops = {
+ .hw_params = tda998x_audio_hw_params,
+ .audio_shutdown = tda998x_audio_shutdown,
+ .digital_mute = tda998x_audio_digital_mute,
+ .get_eld = tda998x_audio_get_eld,
+};
+
+static int tda998x_audio_codec_init(struct tda998x_priv *priv,
+ struct device *dev)
+{
+ struct hdmi_codec_pdata codec_data = {
+ .ops = &audio_codec_ops,
+ .max_i2s_channels = 2,
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) {
+ if (priv->audio_port[i].format == AFMT_I2S &&
+ priv->audio_port[i].config != 0)
+ codec_data.i2s = 1;
+ if (priv->audio_port[i].format == AFMT_SPDIF &&
+ priv->audio_port[i].config != 0)
+ codec_data.spdif = 1;
+ }
+
+ priv->audio_pdev = platform_device_register_data(
+ dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
+ &codec_data, sizeof(codec_data));
+
+ if (IS_ERR(priv->audio_pdev))
+ return PTR_ERR(priv->audio_pdev);
+
+ return 0;
+}
+
/* I2C driver functions */
static int tda998x_parse_ports(struct tda998x_priv *priv,
@@ -1274,12 +1409,12 @@ static int tda998x_parse_ports(struct tda998x_priv *priv,
afmt = AFMT_SPDIF;
else
continue;
- if (audio_index >= ARRAY_SIZE(priv->audio.ports)) {
+ if (audio_index >= ARRAY_SIZE(priv->audio_port)) {
dev_err(&priv->hdmi->dev, "too many audio ports\n");
break;
}
- priv->audio.ports[audio_index] = reg;
- priv->audio.port_types[audio_index] = afmt;
+ priv->audio_port[audio_index].format = afmt;
+ priv->audio_port[audio_index].config = reg;
audio_index++;
}
return rgb_initialized;
@@ -1412,30 +1547,8 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
priv->vip_cntrl_2 = video;
}
}
- if (priv->audio.ports[0]) {
- struct tda998x_audio_params params = {
- .config = priv->audio.ports[0],
- .format = priv->audio.port_types[0],
- .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,
- },
- };
-
- priv->audio_params = params;
- }
+ if (priv->audio_port[0].format != AFMT_UNUSED)
+ tda998x_audio_codec_init(priv, &client->dev);
}
return 0;
@@ -1468,6 +1581,8 @@ static int tda998x_encoder_init(struct i2c_client *client,
return ret;
}
+ dev_set_drvdata(&client->dev, priv);
+
encoder_slave->slave_priv = priv;
encoder_slave->slave_funcs = &tda998x_encoder_slave_funcs;
diff --git a/include/drm/i2c/tda998x.h b/include/drm/i2c/tda998x.h
index dfe7829..5a0cabb 100644
--- a/include/drm/i2c/tda998x.h
+++ b/include/drm/i2c/tda998x.h
@@ -4,6 +4,7 @@
struct tda998x_audio_params {
u8 config;
enum {
+ AFMT_UNUSED = 0,
AFMT_SPDIF,
AFMT_I2S
} format;
--
1.9.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH RFC v4 8/8] ARM: dts: am335x-boneblack: Add HDMI audio support
2015-09-18 11:06 [PATCH RFC v4 0/8] Implement generic ASoC HDMI codec and use it in tda998x Jyri Sarha
` (3 preceding siblings ...)
2015-09-18 11:06 ` [PATCH RFC v4 7/8] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality Jyri Sarha
@ 2015-09-18 11:06 ` Jyri Sarha
4 siblings, 0 replies; 25+ messages in thread
From: Jyri Sarha @ 2015-09-18 11:06 UTC (permalink / raw)
To: dri-devel, airlied, linux-omap, devicetree, bcousson, alsa-devel
Cc: peter.ujfalusi, tony, broonie, Jyri Sarha, liam.r.girdwood,
tomi.valkeinen, rmk+kernel
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.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
arch/arm/boot/dts/am335x-boneblack.dts | 90 ++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
index eadbba3..05347dc 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -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>;
};
};
};
--
1.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 25+ messages in thread