alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S
@ 2015-05-29 13:31 Jun Nie
  2015-05-29 13:31 ` [PATCH v3 1/6] dt: Add documentation for the ZTE SPDIF controller Jun Nie
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Jun Nie @ 2015-05-29 13:31 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun, Jun Nie

Changes vs v2:
  - remove pcm dma driver and merge the related call into DAI driver
  - Add zx HDMI codec with direct HDMI function call
  - Other typo and minor fix

Jun Nie (6):
  dt: Add documentation for the ZTE SPDIF controller
  dt: Add documentation for the ZTE I2S controller
  dt: Add doc for the ZTE HDMI audio codec binding
  ASoC: zx: Add zx296702 SPDIF support
  ASoC: zx: Add ZTE zx296702 I2S DAI driver
  ASoC: zx: add zx296702 hdmi codec

 .../devicetree/bindings/sound/zte,zx-hdmi.txt      |  10 +
 .../devicetree/bindings/sound/zte,zx-i2s.txt       |  44 +++
 .../devicetree/bindings/sound/zte,zx-spdif.txt     |  28 ++
 include/sound/zx_hdmi_audio.h                      |   7 +
 sound/soc/Kconfig                                  |   1 +
 sound/soc/Makefile                                 |   1 +
 sound/soc/codecs/Kconfig                           |   3 +
 sound/soc/codecs/Makefile                          |   1 +
 sound/soc/codecs/zx296702_hdmi.c                   | 121 ++++++
 sound/soc/zte/Kconfig                              |  17 +
 sound/soc/zte/Makefile                             |   2 +
 sound/soc/zte/zx296702-i2s.c                       | 437 +++++++++++++++++++++
 sound/soc/zte/zx296702-spdif.c                     | 370 +++++++++++++++++
 13 files changed, 1042 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/zte,zx-hdmi.txt
 create mode 100644 Documentation/devicetree/bindings/sound/zte,zx-i2s.txt
 create mode 100644 Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
 create mode 100644 include/sound/zx_hdmi_audio.h
 create mode 100644 sound/soc/codecs/zx296702_hdmi.c
 create mode 100644 sound/soc/zte/Kconfig
 create mode 100644 sound/soc/zte/Makefile
 create mode 100644 sound/soc/zte/zx296702-i2s.c
 create mode 100644 sound/soc/zte/zx296702-spdif.c

-- 
1.9.1

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

* [PATCH v3 1/6] dt: Add documentation for the ZTE SPDIF controller
  2015-05-29 13:31 [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S Jun Nie
@ 2015-05-29 13:31 ` Jun Nie
  2015-05-29 13:31 ` [PATCH v3 2/6] dt: Add documentation for the ZTE I2S controller Jun Nie
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Jun Nie @ 2015-05-29 13:31 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun, Jun Nie

This patch adds the devicetree documentation for the ZTE
zx296702 SPDIF audio controller.

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 .../devicetree/bindings/sound/zte,zx-spdif.txt     | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/zte,zx-spdif.txt

diff --git a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
new file mode 100644
index 0000000..989544e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
@@ -0,0 +1,28 @@
+ZTE ZX296702 SPDIF controller
+
+Required properties:
+ - compatible : Must be "zte,zx296702-spdif"
+ - reg : Must contain SPDIF core's registers location and length
+ - clocks : Pairs of phandle and specifier referencing the controller's clocks.
+ - clock-names: "tx" for the clock to the SPDIF interface.
+ - dmas: Pairs of phandle and specifier for the DMA channel that is used by
+   the core. The core expects one dma channel for transmit.
+ - dma-names : Must be "tx"
+
+For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
+please check:
+	* resource-names.txt
+	* clock/clock-bindings.txt
+	* dma/dma.txt
+
+Example:
+	spdif0: spdif0@0b004000 {
+		compatible = "zte,zx296702-spdif";
+		reg = <0x0b004000 0x1000>;
+		clocks = <&lsp0clk ZX296702_SPDIF0_DIV>;
+		clock-names = "tx";
+		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+		dmas = <&dma 4>;
+		dma-names = "tx";
+		status = "okay";
+	};
-- 
1.9.1

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

* [PATCH v3 2/6] dt: Add documentation for the ZTE I2S controller
  2015-05-29 13:31 [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S Jun Nie
  2015-05-29 13:31 ` [PATCH v3 1/6] dt: Add documentation for the ZTE SPDIF controller Jun Nie
@ 2015-05-29 13:31 ` Jun Nie
  2015-05-29 13:31 ` [PATCH v3 3/6] dt: Add doc for the ZTE HDMI audio codec binding Jun Nie
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Jun Nie @ 2015-05-29 13:31 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun, Jun Nie

This patch adds the devicetree documentation for the ZTE
zx296702 I2S audio controller.

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 .../devicetree/bindings/sound/zte,zx-i2s.txt       | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/zte,zx-i2s.txt

diff --git a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt
new file mode 100644
index 0000000..7e5aa6f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt
@@ -0,0 +1,44 @@
+ZTE ZX296702 I2S controller
+
+Required properties:
+ - compatible : Must be "zte,zx296702-i2s"
+ - reg : Must contain I2S core's registers location and length
+ - clocks : Pairs of phandle and specifier referencing the controller's clocks.
+ - clock-names: "tx" for the clock to the I2S interface.
+ - dmas: Pairs of phandle and specifier for the DMA channel that is used by
+   the core. The core expects two dma channels for transmit.
+ - dma-names : Must be "tx" and "rx"
+
+For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
+please check:
+	* resource-names.txt
+	* clock/clock-bindings.txt
+	* dma/dma.txt
+
+Example:
+	i2s0: i2s0@0b005000 {
+		#sound-dai-cells = <0>;
+		compatible = "zte,zx296702-i2s";
+		reg = <0x0b005000 0x1000>;
+		clocks = <&lsp0clk ZX296702_I2S0_DIV>;
+		clock-names = "tx";
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+		dmas = <&dma 5>, <&dma 6>;
+		dma-names = "tx", "rx";
+		status = "okay";
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "zx296702_snd";
+		simple-audio-card,format = "left_j";
+		simple-audio-card,bitclock-master = <&sndcodec>;
+		simple-audio-card,frame-master = <&sndcodec>;
+		sndcpu: simple-audio-card,cpu {
+			sound-dai = <&i2s0>;
+		};
+
+		sndcodec: simple-audio-card,codec {
+			sound-dai = <&acodec>;
+		};
+	};
-- 
1.9.1

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

* [PATCH v3 3/6] dt: Add doc for the ZTE HDMI audio codec binding
  2015-05-29 13:31 [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S Jun Nie
  2015-05-29 13:31 ` [PATCH v3 1/6] dt: Add documentation for the ZTE SPDIF controller Jun Nie
  2015-05-29 13:31 ` [PATCH v3 2/6] dt: Add documentation for the ZTE I2S controller Jun Nie
@ 2015-05-29 13:31 ` Jun Nie
  2015-05-29 13:31 ` [PATCH v3 4/6] ASoC: zx: Add zx296702 SPDIF support Jun Nie
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Jun Nie @ 2015-05-29 13:31 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun, Jun Nie

This patch adds the devicetree documentation for the ZTE
zx296702 HDMI audio codec binding.

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 Documentation/devicetree/bindings/sound/zte,zx-hdmi.txt | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/zte,zx-hdmi.txt

diff --git a/Documentation/devicetree/bindings/sound/zte,zx-hdmi.txt b/Documentation/devicetree/bindings/sound/zte,zx-hdmi.txt
new file mode 100644
index 0000000..624d75d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/zte,zx-hdmi.txt
@@ -0,0 +1,10 @@
+ZTE HDMI ASoC codec binding
+
+Required properties:
+ - compatible : Must be "zte,hdmi-audio"
+
+Example:
+	acodec: acodec {
+		#sound-dai-cells = <0>;
+		compatible = "zte,hdmi-audio";
+	};
-- 
1.9.1

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

* [PATCH v3 4/6] ASoC: zx: Add zx296702 SPDIF support
  2015-05-29 13:31 [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S Jun Nie
                   ` (2 preceding siblings ...)
  2015-05-29 13:31 ` [PATCH v3 3/6] dt: Add doc for the ZTE HDMI audio codec binding Jun Nie
@ 2015-05-29 13:31 ` Jun Nie
  2015-05-29 14:03   ` Lars-Peter Clausen
  2015-05-29 13:31 ` [PATCH v3 5/6] ASoC: zx: Add ZTE zx296702 I2S DAI driver Jun Nie
  2015-05-29 13:31 ` [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec Jun Nie
  5 siblings, 1 reply; 19+ messages in thread
From: Jun Nie @ 2015-05-29 13:31 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun, Jun Nie

Add driver for zx296702 SPDIF controller

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 sound/soc/Kconfig              |   1 +
 sound/soc/Makefile             |   1 +
 sound/soc/zte/Kconfig          |   8 +
 sound/soc/zte/Makefile         |   1 +
 sound/soc/zte/zx296702-spdif.c | 370 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 381 insertions(+)
 create mode 100644 sound/soc/zte/Kconfig
 create mode 100644 sound/soc/zte/Makefile
 create mode 100644 sound/soc/zte/zx296702-spdif.c

diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 3ba52da..e2828e1 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -57,6 +57,7 @@ source "sound/soc/tegra/Kconfig"
 source "sound/soc/txx9/Kconfig"
 source "sound/soc/ux500/Kconfig"
 source "sound/soc/xtensa/Kconfig"
+source "sound/soc/zte/Kconfig"
 
 # Supported codecs
 source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 974ba70..57bf32d 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_SND_SOC)	+= tegra/
 obj-$(CONFIG_SND_SOC)	+= txx9/
 obj-$(CONFIG_SND_SOC)	+= ux500/
 obj-$(CONFIG_SND_SOC)	+= xtensa/
+obj-$(CONFIG_SND_SOC)	+= zte/
diff --git a/sound/soc/zte/Kconfig b/sound/soc/zte/Kconfig
new file mode 100644
index 0000000..4f05573
--- /dev/null
+++ b/sound/soc/zte/Kconfig
@@ -0,0 +1,8 @@
+config ZX296702_SPDIF
+	tristate "ZX296702 spdif"
+	depends on SOC_ZX296702 || COMPILE_TEST
+	depends on COMMON_CLK
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Say Y or M if you want to add support for codecs attached to the
+	  zx296702 spdif interface
diff --git a/sound/soc/zte/Makefile b/sound/soc/zte/Makefile
new file mode 100644
index 0000000..fb3a4a0
--- /dev/null
+++ b/sound/soc/zte/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ZX296702_SPDIF)	+= zx296702-spdif.o
diff --git a/sound/soc/zte/zx296702-spdif.c b/sound/soc/zte/zx296702-spdif.c
new file mode 100644
index 0000000..f108f39
--- /dev/null
+++ b/sound/soc/zte/zx296702-spdif.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2015 Linaro
+ *
+ * Author: Jun Nie <jun.nie@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <sound/asoundef.h>
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#define ZX_CTRL				0x04
+#define ZX_FIFOCTRL			0x08
+#define ZX_INT_STATUS			0x10
+#define ZX_INT_MASK			0x14
+#define ZX_DATA				0x18
+#define ZX_VALID_BIT			0x1c
+#define ZX_CH_STA_1			0x20
+#define ZX_CH_STA_2			0x24
+#define ZX_CH_STA_3			0x28
+#define ZX_CH_STA_4			0x2c
+#define ZX_CH_STA_5			0x30
+#define ZX_CH_STA_6			0x34
+
+#define ZX_CTRL_MODA_16			(0 << 6)
+#define ZX_CTRL_MODA_18			BIT(6)
+#define ZX_CTRL_MODA_20			(2 << 6)
+#define ZX_CTRL_MODA_24			(3 << 6)
+#define ZX_CTRL_MODA_MASK		(3 << 6)
+
+#define ZX_CTRL_ENB			BIT(4)
+#define ZX_CTRL_DNB			(0 << 4)
+#define ZX_CTRL_ENB_MASK		BIT(4)
+
+#define ZX_CTRL_TX_OPEN			BIT(0)
+#define ZX_CTRL_TX_CLOSE		(0 << 0)
+#define ZX_CTRL_TX_MASK			BIT(0)
+
+#define ZX_CTRL_OPEN			(ZX_CTRL_TX_OPEN | ZX_CTRL_ENB)
+#define ZX_CTRL_CLOSE			(ZX_CTRL_TX_CLOSE | ZX_CTRL_DNB)
+
+#define ZX_CTRL_DOUBLE_TRACK		(0 << 8)
+#define ZX_CTRL_LEFT_TRACK		BIT(8)
+#define ZX_CTRL_RIGHT_TRACK		(2 << 8)
+#define ZX_CTRL_TRACK_MASK		(3 << 8)
+
+#define ZX_FIFOCTRL_TXTH_MASK		(0x1f << 8)
+#define ZX_FIFOCTRL_TXTH(x)		(x << 8)
+#define ZX_FIFOCTRL_TX_DMA_EN		BIT(2)
+#define ZX_FIFOCTRL_TX_DMA_DIS		(0 << 2)
+#define ZX_FIFOCTRL_TX_DMA_EN_MASK	BIT(2)
+#define ZX_FIFOCTRL_TX_FIFO_RST		BIT(0)
+#define ZX_FIFOCTRL_TX_FIFO_RST_MASK	BIT(0)
+
+#define ZX_VALID_DOUBLE_TRACK		(0 << 0)
+#define ZX_VALID_LEFT_TRACK		BIT(1)
+#define ZX_VALID_RIGHT_TRACK		(2 << 0)
+#define ZX_VALID_TRACK_MASK		(3 << 0)
+
+#define ZX_SPDIF_CLK_RAT		(4 * 32)
+
+struct zx_spdif_info {
+	struct snd_dmaengine_dai_dma_data	dma_data;
+	struct clk				*dai_clk;
+	void __iomem				*reg_base;
+	resource_size_t				mapbase;
+};
+
+static int zx_spdif_dai_probe(struct snd_soc_dai *dai)
+{
+	struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev);
+
+	snd_soc_dai_set_drvdata(dai, zx_spdif);
+	zx_spdif->dma_data.addr = zx_spdif->mapbase + ZX_DATA;
+	zx_spdif->dma_data.maxburst = 8;
+	snd_soc_dai_init_dma_data(dai, &zx_spdif->dma_data, NULL);
+	return 0;
+}
+
+static int zx_spdif_chanstats(void __iomem *base, unsigned int rate)
+{
+	u32 cstas1;
+
+	switch (rate) {
+	case 22050:
+		cstas1 = IEC958_AES3_CON_FS_22050;
+		break;
+	case 24000:
+		cstas1 = IEC958_AES3_CON_FS_24000;
+		break;
+	case 32000:
+		cstas1 = IEC958_AES3_CON_FS_32000;
+		break;
+	case 44100:
+		cstas1 = IEC958_AES3_CON_FS_44100;
+		break;
+	case 48000:
+		cstas1 = IEC958_AES3_CON_FS_48000;
+		break;
+	case 88200:
+		cstas1 = IEC958_AES3_CON_FS_88200;
+		break;
+	case 96000:
+		cstas1 = IEC958_AES3_CON_FS_96000;
+		break;
+	case 176400:
+		cstas1 = IEC958_AES3_CON_FS_176400;
+		break;
+	case 192000:
+		cstas1 = IEC958_AES3_CON_FS_192000;
+		break;
+	default:
+		return -EINVAL;
+	}
+	cstas1 = cstas1 << 24;
+	cstas1 |= IEC958_AES0_CON_NOT_COPYRIGHT;
+
+	writel_relaxed(cstas1, base + ZX_CH_STA_1);
+	return 0;
+}
+
+static int zx_spdif_hw_params(struct snd_pcm_substream *substream,
+			      struct snd_pcm_hw_params *params,
+			      struct snd_soc_dai *socdai)
+{
+	struct zx_spdif_info *zx_spdif = dev_get_drvdata(socdai->dev);
+	struct zx_spdif_info *spdif = snd_soc_dai_get_drvdata(socdai);
+	struct snd_dmaengine_dai_dma_data *dma_data = &zx_spdif->dma_data;
+	u32 val, ch_num, rate;
+	int ret;
+
+	dma_data = snd_soc_dai_get_dma_data(socdai, substream);
+	dma_data->addr_width = params_width(params) >> 3;
+
+	val = readl_relaxed(zx_spdif->reg_base + ZX_CTRL);
+	val &= ~ZX_CTRL_MODA_MASK;
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		val |= ZX_CTRL_MODA_16;
+		break;
+
+	case SNDRV_PCM_FORMAT_S18_3LE:
+		val |= ZX_CTRL_MODA_18;
+		break;
+
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		val |= ZX_CTRL_MODA_20;
+		break;
+
+	case SNDRV_PCM_FORMAT_S24_LE:
+		val |= ZX_CTRL_MODA_24;
+		break;
+	default:
+		dev_err(socdai->dev, "Format not support!\n");
+		return -EINVAL;
+	}
+
+	ch_num = params_channels(params);
+	if (ch_num == 2)
+		val |= ZX_CTRL_DOUBLE_TRACK;
+	else
+		val |= ZX_CTRL_LEFT_TRACK;
+	writel_relaxed(val, zx_spdif->reg_base + ZX_CTRL);
+
+	val = readl_relaxed(zx_spdif->reg_base + ZX_VALID_BIT);
+	val &= ~ZX_VALID_TRACK_MASK;
+	if (ch_num == 2)
+		val |= ZX_VALID_DOUBLE_TRACK;
+	else
+		val |= ZX_VALID_RIGHT_TRACK;
+	writel_relaxed(val, zx_spdif->reg_base + ZX_VALID_BIT);
+
+	rate = params_rate(params);
+	ret = zx_spdif_chanstats(zx_spdif->reg_base, rate);
+	if (ret)
+		return ret;
+	ret = clk_set_rate(spdif->dai_clk, rate * ch_num * ZX_SPDIF_CLK_RAT);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void zx_spdif_cfg_tx(void __iomem *base, int on)
+{
+	u32 val;
+
+	val = readl_relaxed(base + ZX_CTRL);
+	val &= ~(ZX_CTRL_ENB_MASK | ZX_CTRL_TX_MASK);
+	val |= on ? ZX_CTRL_OPEN : ZX_CTRL_CLOSE;
+	writel_relaxed(val, base + ZX_CTRL);
+
+	val = readl_relaxed(base + ZX_FIFOCTRL);
+	val &= ~ZX_FIFOCTRL_TX_DMA_EN_MASK;
+	if (on)
+		val |= ZX_FIFOCTRL_TX_DMA_EN;
+	writel_relaxed(val, base + ZX_FIFOCTRL);
+}
+
+static int zx_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+			    struct snd_soc_dai *dai)
+{
+	u32 val;
+	struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev);
+	int  ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		val = readl_relaxed(zx_spdif->reg_base + ZX_FIFOCTRL);
+		val |= ZX_FIFOCTRL_TX_FIFO_RST;
+		writel_relaxed(val, zx_spdif->reg_base + ZX_FIFOCTRL);
+	/* fall thru */
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		zx_spdif_cfg_tx(zx_spdif->reg_base, true);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		zx_spdif_cfg_tx(zx_spdif->reg_base, false);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int zx_spdif_startup(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev);
+
+	return clk_prepare_enable(zx_spdif->dai_clk);
+}
+
+static void zx_spdif_shutdown(struct snd_pcm_substream *substream,
+			      struct snd_soc_dai *dai)
+{
+	struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev);
+
+	clk_disable_unprepare(zx_spdif->dai_clk);
+}
+
+#define ZX_RATES \
+	(SNDRV_PCM_RATE_22050 | 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 ZX_FORMAT \
+	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE \
+	| SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops zx_spdif_dai_ops = {
+	.trigger	= zx_spdif_trigger,
+	.startup	= zx_spdif_startup,
+	.shutdown	= zx_spdif_shutdown,
+	.hw_params	= zx_spdif_hw_params,
+};
+
+static struct snd_soc_dai_driver zx_spdif_dai = {
+	.name = "spdif",
+	.id = 0,
+	.probe = zx_spdif_dai_probe,
+	.playback = {
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = ZX_RATES,
+		.formats = ZX_FORMAT,
+	},
+	.ops = &zx_spdif_dai_ops,
+};
+
+static const struct snd_soc_component_driver zx_spdif_component = {
+	.name	= "spdif",
+};
+
+static void zx_spdif_dev_init(void __iomem *base)
+{
+	u32 val;
+
+	writel_relaxed(0, base + ZX_CTRL);
+	writel_relaxed(0, base + ZX_INT_MASK);
+	writel_relaxed(0xf, base + ZX_INT_STATUS);
+	writel_relaxed(0x1, base + ZX_FIFOCTRL);
+
+	val = readl_relaxed(base + ZX_FIFOCTRL);
+	val &= ~(ZX_FIFOCTRL_TXTH_MASK | ZX_FIFOCTRL_TX_FIFO_RST_MASK);
+	val |= ZX_FIFOCTRL_TXTH(8);
+	writel_relaxed(val, base + ZX_FIFOCTRL);
+}
+
+static int zx_spdif_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct zx_spdif_info *zx_spdif;
+	int ret;
+
+	zx_spdif =  kzalloc(sizeof(*zx_spdif), GFP_KERNEL);
+	if (!zx_spdif)
+		return -ENOMEM;
+
+	zx_spdif->dai_clk = devm_clk_get(&pdev->dev, "tx");
+	if (IS_ERR(zx_spdif->dai_clk)) {
+		dev_err(&pdev->dev, "Fail to get clk\n");
+		return PTR_ERR(zx_spdif->dai_clk);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	zx_spdif->mapbase = res->start;
+	zx_spdif->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (!zx_spdif->reg_base) {
+		dev_err(&pdev->dev, "ioremap failed!\n");
+		return -EIO;
+	}
+
+	zx_spdif_dev_init(zx_spdif->reg_base);
+	platform_set_drvdata(pdev, zx_spdif);
+
+	ret = snd_soc_register_component(&pdev->dev, &zx_spdif_component,
+					 &zx_spdif_dai, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret)
+		dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);
+
+	return ret;
+}
+
+static const struct of_device_id zx_spdif_dt_ids[] = {
+	{ .compatible = "zte,zx296702-spdif", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, zx_spdif_dt_ids);
+
+static struct platform_driver spdif_driver = {
+	.probe = zx_spdif_probe,
+	.driver = {
+		.name = "zx-spdif",
+		.owner = THIS_MODULE,
+		.of_match_table = zx_spdif_dt_ids,
+	},
+};
+
+module_platform_driver(spdif_driver);
+
+MODULE_AUTHOR("Jun Nie <jun.nie@linaro.org>");
+MODULE_DESCRIPTION("ZTE SPDIF SoC DAI");
+MODULE_LICENSE("GPL");
-- 
1.9.1

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

* [PATCH v3 5/6] ASoC: zx: Add ZTE zx296702 I2S DAI driver
  2015-05-29 13:31 [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S Jun Nie
                   ` (3 preceding siblings ...)
  2015-05-29 13:31 ` [PATCH v3 4/6] ASoC: zx: Add zx296702 SPDIF support Jun Nie
@ 2015-05-29 13:31 ` Jun Nie
  2015-06-03 16:02   ` Mark Brown
  2015-05-29 13:31 ` [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec Jun Nie
  5 siblings, 1 reply; 19+ messages in thread
From: Jun Nie @ 2015-05-29 13:31 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun, Jun Nie

Add ZTE zx296702 I2S interface DAI driver

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 sound/soc/zte/Kconfig        |   9 +
 sound/soc/zte/Makefile       |   1 +
 sound/soc/zte/zx296702-i2s.c | 437 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 447 insertions(+)
 create mode 100644 sound/soc/zte/zx296702-i2s.c

diff --git a/sound/soc/zte/Kconfig b/sound/soc/zte/Kconfig
index 4f05573..c47eb25 100644
--- a/sound/soc/zte/Kconfig
+++ b/sound/soc/zte/Kconfig
@@ -6,3 +6,12 @@ config ZX296702_SPDIF
 	help
 	  Say Y or M if you want to add support for codecs attached to the
 	  zx296702 spdif interface
+
+config ZX296702_I2S
+	tristate "ZX296702 i2s"
+	depends on SOC_ZX296702 || COMPILE_TEST
+	depends on COMMON_CLK
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Say Y or M if you want to add support for codecs attached to the
+	  zx296702 i2s interface
diff --git a/sound/soc/zte/Makefile b/sound/soc/zte/Makefile
index fb3a4a0..254ed2c 100644
--- a/sound/soc/zte/Makefile
+++ b/sound/soc/zte/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_ZX296702_SPDIF)	+= zx296702-spdif.o
+obj-$(CONFIG_ZX296702_I2S)	+= zx296702-i2s.o
diff --git a/sound/soc/zte/zx296702-i2s.c b/sound/soc/zte/zx296702-i2s.c
new file mode 100644
index 0000000..cf6005c
--- /dev/null
+++ b/sound/soc/zte/zx296702-i2s.c
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2015 Linaro
+ *
+ * Author: Jun Nie <jun.nie@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define ZX_I2S_PROCESS_CTRL	0x04
+#define ZX_I2S_TIMING_CTRL	0x08
+#define	ZX_I2S_FIFO_CTRL	0x0C
+#define	ZX_I2S_FIFO_STATUS	0x10
+#define ZX_I2S_INT_EN		0x14
+#define ZX_I2S_INT_STATUS	0x18
+#define ZX_I2S_DATA		0x1C
+#define ZX_I2S_FRAME_CNTR	0x20
+
+#define I2S_DEAGULT_FIFO_THRES	(0x10)
+#define I2S_MAX_FIFO_THRES	(0x20)
+
+#define ZX_I2S_PROCESS_TX_EN	(1 << 0)
+#define ZX_I2S_PROCESS_TX_DIS	(0 << 0)
+#define ZX_I2S_PROCESS_RX_EN	(1 << 1)
+#define ZX_I2S_PROCESS_RX_DIS	(0 << 1)
+#define ZX_I2S_PROCESS_I2S_EN	(1 << 2)
+#define ZX_I2S_PROCESS_I2S_DIS	(0 << 2)
+
+#define ZX_I2S_TIMING_MAST		(1 << 0)
+#define ZX_I2S_TIMING_SLAVE		(0 << 0)
+#define ZX_I2S_TIMING_MS_MASK		(1 << 0)
+#define ZX_I2S_TIMING_LOOP		(1 << 1)
+#define ZX_I2S_TIMING_NOR		(0 << 1)
+#define ZX_I2S_TIMING_LOOP_MASK		(1 << 1)
+#define ZX_I2S_TIMING_PTNR		(1 << 2)
+#define ZX_I2S_TIMING_NTPR		(0 << 2)
+#define ZX_I2S_TIMING_PHASE_MASK	(1 << 2)
+#define ZX_I2S_TIMING_TDM		(1 << 3)
+#define ZX_I2S_TIMING_I2S		(0 << 3)
+#define ZX_I2S_TIMING_TIMING_MASK	(1 << 3)
+#define ZX_I2S_TIMING_LONG_SYNC		(1 << 4)
+#define ZX_I2S_TIMING_SHORT_SYNC	(0 << 4)
+#define ZX_I2S_TIMING_SYNC_MASK		(1 << 4)
+#define ZX_I2S_TIMING_TEAK_EN		(1 << 5)
+#define ZX_I2S_TIMING_TEAK_DIS		(0 << 5)
+#define ZX_I2S_TIMING_TEAK_MASK		(1 << 5)
+#define ZX_I2S_TIMING_STD_I2S		(0 << 6)
+#define ZX_I2S_TIMING_MSB_JUSTIF	(1 << 6)
+#define ZX_I2S_TIMING_LSB_JUSTIF	(2 << 6)
+#define ZX_I2S_TIMING_ALIGN_MASK	(3 << 6)
+#define ZX_I2S_TIMING_CHN_MASK		(7 << 8)
+#define ZX_I2S_TIMING_CHN(x)		((x - 1) << 8)
+#define ZX_I2S_TIMING_LANE_MASK		(3 << 11)
+#define ZX_I2S_TIMING_LANE(x)		((x - 1) << 11)
+#define ZX_I2S_TIMING_TSCFG_MASK	(7 << 13)
+#define ZX_I2S_TIMING_TSCFG(x)		(x << 13)
+#define ZX_I2S_TIMING_TS_WIDTH_MASK	(0x1f << 16)
+#define ZX_I2S_TIMING_TS_WIDTH(x)	((x - 1) << 16)
+#define ZX_I2S_TIMING_DATA_SIZE_MASK	(0x1f << 21)
+#define ZX_I2S_TIMING_DATA_SIZE(x)	((x - 1) << 21)
+#define ZX_I2S_TIMING_CFG_ERR_MASK	(1 << 31)
+
+#define ZX_I2S_FIFO_CTRL_TX_RST		(1 << 0)
+#define ZX_I2S_FIFO_CTRL_TX_RST_MASK	(1 << 0)
+#define ZX_I2S_FIFO_CTRL_RX_RST		(1 << 1)
+#define ZX_I2S_FIFO_CTRL_RX_RST_MASK	(1 << 1)
+#define ZX_I2S_FIFO_CTRL_TX_DMA_EN	(1 << 4)
+#define ZX_I2S_FIFO_CTRL_TX_DMA_DIS	(0 << 4)
+#define ZX_I2S_FIFO_CTRL_TX_DMA_MASK	(1 << 4)
+#define ZX_I2S_FIFO_CTRL_RX_DMA_EN	(1 << 5)
+#define ZX_I2S_FIFO_CTRL_RX_DMA_DIS	(0 << 5)
+#define ZX_I2S_FIFO_CTRL_RX_DMA_MASK	(1 << 5)
+#define ZX_I2S_FIFO_CTRL_TX_THRES_MASK	(0x1F << 8)
+#define ZX_I2S_FIFO_CTRL_RX_THRES_MASK	(0x1F << 16)
+
+#define CLK_RAT (32 * 4)
+
+struct zx_i2s_info {
+	struct snd_dmaengine_dai_dma_data	dma_playback;
+	struct snd_dmaengine_dai_dma_data	dma_capture;
+	struct clk				*dai_clk;
+	void __iomem				*reg_base;
+	int					master;
+	resource_size_t				mapbase;
+};
+
+static void zx_i2s_tx_en(void __iomem *base, bool on)
+{
+	unsigned long val;
+
+	val = readl_relaxed(base + ZX_I2S_PROCESS_CTRL);
+	if (on)
+		val |= ZX_I2S_PROCESS_TX_EN | ZX_I2S_PROCESS_I2S_EN;
+	else
+		val &= ~(ZX_I2S_PROCESS_TX_EN | ZX_I2S_PROCESS_I2S_EN);
+	writel_relaxed(val, base + ZX_I2S_PROCESS_CTRL);
+}
+
+static void zx_i2s_rx_en(void __iomem *base, bool on)
+{
+	unsigned long val;
+
+	val = readl_relaxed(base + ZX_I2S_PROCESS_CTRL);
+	if (on)
+		val |= ZX_I2S_PROCESS_RX_EN | ZX_I2S_PROCESS_I2S_EN;
+	else
+		val &= ~(ZX_I2S_PROCESS_RX_EN | ZX_I2S_PROCESS_I2S_EN);
+	writel_relaxed(val, base + ZX_I2S_PROCESS_CTRL);
+}
+
+static void zx_i2s_tx_dma_en(void __iomem *base, bool on)
+{
+	unsigned long val;
+
+	val = readl_relaxed(base + ZX_I2S_FIFO_CTRL);
+	val |= ZX_I2S_FIFO_CTRL_TX_RST | (I2S_DEAGULT_FIFO_THRES << 8);
+	if (on)
+		val |= ZX_I2S_FIFO_CTRL_TX_DMA_EN;
+	else
+		val &= ~ZX_I2S_FIFO_CTRL_TX_DMA_EN;
+	writel_relaxed(val, base + ZX_I2S_FIFO_CTRL);
+}
+
+static void zx_i2s_rx_dma_en(void __iomem *base, bool on)
+{
+	unsigned long val;
+
+	val = readl_relaxed(base + ZX_I2S_FIFO_CTRL);
+	val |= ZX_I2S_FIFO_CTRL_RX_RST | (I2S_DEAGULT_FIFO_THRES << 16);
+	if (on)
+		val |= ZX_I2S_FIFO_CTRL_RX_DMA_EN;
+	else
+		val &= ~ZX_I2S_FIFO_CTRL_RX_DMA_EN;
+	writel_relaxed(val, base + ZX_I2S_FIFO_CTRL);
+}
+
+#define ZX_I2S_RATES \
+	(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
+	 SNDRV_PCM_RATE_22050 | 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 ZX_I2S_FMTBIT \
+	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
+	SNDRV_PCM_FMTBIT_S32_LE)
+
+static int zx_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+	struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev);
+
+	snd_soc_dai_set_drvdata(dai, zx_i2s);
+	zx_i2s->dma_playback.addr = zx_i2s->mapbase + ZX_I2S_DATA;
+	zx_i2s->dma_playback.maxburst = 16;
+	zx_i2s->dma_capture.addr = zx_i2s->mapbase + ZX_I2S_DATA;
+	zx_i2s->dma_capture.maxburst = 16;
+	snd_soc_dai_init_dma_data(dai, &zx_i2s->dma_playback,
+				  &zx_i2s->dma_capture);
+	return 0;
+}
+
+static int zx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+	struct zx_i2s_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
+	unsigned long val;
+
+	val = readl_relaxed(i2s->reg_base + ZX_I2S_TIMING_CTRL);
+	val &= ~(ZX_I2S_TIMING_TIMING_MASK | ZX_I2S_TIMING_ALIGN_MASK |
+			ZX_I2S_TIMING_TEAK_MASK | ZX_I2S_TIMING_SYNC_MASK |
+			ZX_I2S_TIMING_MS_MASK);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_STD_I2S);
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_MSB_JUSTIF);
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_LSB_JUSTIF);
+		break;
+	default:
+		dev_err(cpu_dai->dev, "Unknown i2s timeing\n");
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		i2s->master = 1;
+		val |= ZX_I2S_TIMING_MAST;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		i2s->master = 0;
+		val |= ZX_I2S_TIMING_SLAVE;
+		break;
+	default:
+		dev_err(cpu_dai->dev, "Unknown master/slave format\n");
+		return -EINVAL;
+	}
+
+	writel_relaxed(val, i2s->reg_base + ZX_I2S_TIMING_CTRL);
+	return 0;
+}
+
+static int zx_i2s_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *socdai)
+{
+	struct zx_i2s_info *i2s = snd_soc_dai_get_drvdata(socdai);
+	struct snd_dmaengine_dai_dma_data *dma_data;
+	unsigned int lane, ch_num, len, ret = 0;
+	unsigned long val, format;
+	unsigned long chn_cfg;
+
+	dma_data = snd_soc_dai_get_dma_data(socdai, substream);
+	dma_data->addr_width = params_width(params) >> 3;
+
+	val = readl_relaxed(i2s->reg_base + ZX_I2S_TIMING_CTRL);
+	val &= ~(ZX_I2S_TIMING_TS_WIDTH_MASK | ZX_I2S_TIMING_DATA_SIZE_MASK |
+		ZX_I2S_TIMING_LANE_MASK | ZX_I2S_TIMING_CHN_MASK |
+		ZX_I2S_TIMING_TSCFG_MASK);
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		format = 0;
+		len = 16;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		format = 1;
+		len = 24;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		format = 2;
+		len = 32;
+		break;
+	default:
+		dev_err(socdai->dev, "Unknown data format\n");
+		return -EINVAL;
+	}
+	val |= ZX_I2S_TIMING_TS_WIDTH(len) | ZX_I2S_TIMING_DATA_SIZE(len);
+
+	ch_num = params_channels(params);
+	switch (ch_num) {
+	case 1:
+		lane = 1;
+		chn_cfg = 2;
+		break;
+	case 2:
+	case 4:
+	case 6:
+	case 8:
+		lane = ch_num / 2;
+		chn_cfg = 3;
+		break;
+	default:
+		dev_err(socdai->dev, "Not support channel num %d\n", ch_num);
+		return -EINVAL;
+	}
+	val |= ZX_I2S_TIMING_LANE(lane);
+	val |= ZX_I2S_TIMING_TSCFG(chn_cfg);
+	val |= ZX_I2S_TIMING_CHN(ch_num);
+	writel_relaxed(val, i2s->reg_base + ZX_I2S_TIMING_CTRL);
+
+	if (i2s->master)
+		ret = clk_set_rate(i2s->dai_clk,
+				   params_rate(params) * ch_num * CLK_RAT);
+	return ret;
+}
+
+static int zx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *dai)
+{
+	struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev);
+	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		if (capture)
+			zx_i2s_rx_dma_en(zx_i2s->reg_base, true);
+		else
+			zx_i2s_tx_dma_en(zx_i2s->reg_base, true);
+	/* fall thru */
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (capture)
+			zx_i2s_rx_en(zx_i2s->reg_base, true);
+		else
+			zx_i2s_tx_en(zx_i2s->reg_base, true);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		if (capture)
+			zx_i2s_rx_dma_en(zx_i2s->reg_base, false);
+		else
+			zx_i2s_tx_dma_en(zx_i2s->reg_base, false);
+	/* fall thru */
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (capture)
+			zx_i2s_rx_en(zx_i2s->reg_base, false);
+		else
+			zx_i2s_tx_en(zx_i2s->reg_base, false);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int zx_i2s_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev);
+
+	return clk_prepare_enable(zx_i2s->dai_clk);
+}
+
+static void zx_i2s_shutdown(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct zx_i2s_info *zx_i2s = dev_get_drvdata(dai->dev);
+
+	clk_disable_unprepare(zx_i2s->dai_clk);
+}
+
+static struct snd_soc_dai_ops zx_i2s_dai_ops = {
+	.trigger	= zx_i2s_trigger,
+	.hw_params	= zx_i2s_hw_params,
+	.set_fmt	= zx_i2s_set_fmt,
+	.startup	= zx_i2s_startup,
+	.shutdown	= zx_i2s_shutdown,
+};
+
+static const struct snd_soc_component_driver zx_i2s_component = {
+	.name			= "zx-i2s",
+};
+
+struct snd_soc_dai_driver zx_i2s_dai = {
+	.name	= "zx-i2s-dai",
+	.id	= 0,
+	.probe	= zx_i2s_dai_probe,
+	.playback   = {
+		.channels_min	= 1,
+		.channels_max	= 8,
+		.rates		= ZX_I2S_RATES,
+		.formats	= ZX_I2S_FMTBIT,
+	},
+	.capture = {
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rates		= ZX_I2S_RATES,
+		.formats	= ZX_I2S_FMTBIT,
+	},
+	.ops	= &zx_i2s_dai_ops,
+};
+
+static int zx_i2s_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct zx_i2s_info *zx_i2s;
+	int ret;
+
+	zx_i2s =  kzalloc(sizeof(*zx_i2s), GFP_KERNEL);
+	if (!zx_i2s)
+		return -ENOMEM;
+
+	zx_i2s->dai_clk = devm_clk_get(&pdev->dev, "tx");
+	if (IS_ERR(zx_i2s->dai_clk)) {
+		dev_err(&pdev->dev, "Fail to get clk\n");
+		return PTR_ERR(zx_i2s->dai_clk);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	zx_i2s->mapbase = res->start;
+	zx_i2s->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (!zx_i2s->reg_base) {
+		dev_err(&pdev->dev, "ioremap failed!\n");
+		return -EIO;
+	}
+
+	writel_relaxed(0, zx_i2s->reg_base + ZX_I2S_FIFO_CTRL);
+	platform_set_drvdata(pdev, zx_i2s);
+
+	ret = snd_soc_register_component(&pdev->dev, &zx_i2s_component,
+					 &zx_i2s_dai, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret)
+		dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);
+
+	return ret;
+}
+
+static const struct of_device_id zx_i2s_dt_ids[] = {
+	{ .compatible = "zte,zx296702-i2s", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, zx_i2s_dt_ids);
+
+static struct platform_driver i2s_driver = {
+	.probe = zx_i2s_probe,
+	.driver = {
+		.name = "zx-i2s",
+		.owner = THIS_MODULE,
+		.of_match_table = zx_i2s_dt_ids,
+	},
+};
+
+module_platform_driver(i2s_driver);
+
+MODULE_AUTHOR("Jun Nie <jun.nie@linaro.org>");
+MODULE_DESCRIPTION("ZTE I2S SoC DAI");
+MODULE_LICENSE("GPL");
-- 
1.9.1

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

* [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-05-29 13:31 [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S Jun Nie
                   ` (4 preceding siblings ...)
  2015-05-29 13:31 ` [PATCH v3 5/6] ASoC: zx: Add ZTE zx296702 I2S DAI driver Jun Nie
@ 2015-05-29 13:31 ` Jun Nie
  2015-05-29 14:10   ` Lars-Peter Clausen
  2015-06-03 17:58   ` Mark Brown
  5 siblings, 2 replies; 19+ messages in thread
From: Jun Nie @ 2015-05-29 13:31 UTC (permalink / raw)
  To: broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun, Jun Nie

Add zx296702 hdmi codec to enable SPDIF and I2S output
via HDMI. The SPDIF/I2S route is exclusive with current
software config and need specify which is valid in
defconfig.

Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
 include/sound/zx_hdmi_audio.h    |   7 +++
 sound/soc/codecs/Kconfig         |   3 +
 sound/soc/codecs/Makefile        |   1 +
 sound/soc/codecs/zx296702_hdmi.c | 121 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 132 insertions(+)
 create mode 100644 include/sound/zx_hdmi_audio.h
 create mode 100644 sound/soc/codecs/zx296702_hdmi.c

diff --git a/include/sound/zx_hdmi_audio.h b/include/sound/zx_hdmi_audio.h
new file mode 100644
index 0000000..7eb0e81
--- /dev/null
+++ b/include/sound/zx_hdmi_audio.h
@@ -0,0 +1,7 @@
+#ifndef __ZX_HDMI_AUDIO_H__
+#define __ZX_HDMI_AUDIO_H__
+
+int zx_hdmi_audio_cfg(int audio_codec, int audio_way,
+		      u32 sample_rate, u32 sample_len);
+void zx_hdmi_audio_en(int on);
+#endif /* __ZX_HDMI_AUDIO_H__ */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 061c465..1ba34ca 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -844,6 +844,9 @@ config SND_SOC_WM9712
 config SND_SOC_WM9713
 	tristate
 
+config SND_SOC_ZX_HDMI
+	tristate
+
 # Amp
 config SND_SOC_LM4857
 	tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index abe2d7e..b6c4630 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -357,6 +357,7 @@ obj-$(CONFIG_SND_SOC_WM9712)	+= snd-soc-wm9712.o
 obj-$(CONFIG_SND_SOC_WM9713)	+= snd-soc-wm9713.o
 obj-$(CONFIG_SND_SOC_WM_ADSP)	+= snd-soc-wm-adsp.o
 obj-$(CONFIG_SND_SOC_WM_HUBS)	+= snd-soc-wm-hubs.o
+obj-$(CONFIG_SND_SOC_ZX_HDMI)	+= zx296702_hdmi.o
 
 # Amp
 obj-$(CONFIG_SND_SOC_MAX9877)	+= snd-soc-max9877.o
diff --git a/sound/soc/codecs/zx296702_hdmi.c b/sound/soc/codecs/zx296702_hdmi.c
new file mode 100644
index 0000000..b256e54
--- /dev/null
+++ b/sound/soc/codecs/zx296702_hdmi.c
@@ -0,0 +1,121 @@
+/*
+ * ALSA SoC codec driver for HDMI audio codecs.
+ * Copyright (C) 2015 Linaro
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/zx_hdmi_audio.h>
+
+#define DRV_NAME "zx-hdmi-codec"
+
+static int zx_hw_params(struct snd_pcm_substream *substream,
+			struct snd_pcm_hw_params *params,
+			struct snd_soc_dai *dai)
+{
+#ifdef CONFIG_ZX_HDMI_SND_SPDIF
+	zx_hdmi_audio_cfg(1, 0, params_rate(params),
+#endif
+#ifdef CONFIG_ZX_HDMI_SND_I2S
+	zx_hdmi_audio_cfg(1, 1, params_rate(params),
+#endif
+			  params_physical_width(params));
+	return 0;
+}
+
+static int zx_trigger(struct snd_pcm_substream *substream, int cmd,
+		      struct snd_soc_dai *dai)
+{
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+#ifdef CONFIG_ZX_HDMI_SND_SPDIF
+		zx_hdmi_audio_en(1);
+#endif
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+#ifdef CONFIG_ZX_HDMI_SND_SPDIF
+		/* Mute HDMI before disabling spdif */
+		zx_hdmi_audio_en(0);
+#endif
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops zx_dai_ops = {
+	.trigger	= zx_trigger,
+	.hw_params	= zx_hw_params,
+};
+
+static struct snd_soc_dai_driver zx_hdmi_codec_dai = {
+	.name = "zx-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,
+	},
+	.ops = &zx_dai_ops,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id zx_hdmi_audio_codec_ids[] = {
+	{ .compatible = "zte,hdmi-audio", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, zx_hdmi_audio_codec_ids);
+#endif
+
+static struct snd_soc_codec_driver zx_hdmi_codec = {
+};
+
+static int zx_hdmi_codec_probe(struct platform_device *pdev)
+{
+	return snd_soc_register_codec(&pdev->dev, &zx_hdmi_codec,
+			&zx_hdmi_codec_dai, 1);
+}
+
+static int zx_hdmi_codec_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_codec(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver zx_hdmi_codec_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+		.of_match_table = of_match_ptr(zx_hdmi_audio_codec_ids),
+	},
+
+	.probe		= zx_hdmi_codec_probe,
+	.remove		= zx_hdmi_codec_remove,
+};
+
+module_platform_driver(zx_hdmi_codec_driver);
+
+MODULE_AUTHOR("Jun Nie <jun.nie@linaro.org>");
+MODULE_DESCRIPTION("ZX296702 ASoC HDMI codec driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
-- 
1.9.1

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

* Re: [PATCH v3 4/6] ASoC: zx: Add zx296702 SPDIF support
  2015-05-29 13:31 ` [PATCH v3 4/6] ASoC: zx: Add zx296702 SPDIF support Jun Nie
@ 2015-05-29 14:03   ` Lars-Peter Clausen
  0 siblings, 0 replies; 19+ messages in thread
From: Lars-Peter Clausen @ 2015-05-29 14:03 UTC (permalink / raw)
  To: Jun Nie, broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun

On 05/29/2015 03:31 PM, Jun Nie wrote:
[...]
> +static int zx_spdif_probe(struct platform_device *pdev)
> +{
> +	struct resource *res;
> +	struct zx_spdif_info *zx_spdif;
> +	int ret;
> +
> +	zx_spdif =  kzalloc(sizeof(*zx_spdif), GFP_KERNEL);

extra space and devm_

> +	if (!zx_spdif)
> +		return -ENOMEM;
> +
> +	zx_spdif->dai_clk = devm_clk_get(&pdev->dev, "tx");
> +	if (IS_ERR(zx_spdif->dai_clk)) {
> +		dev_err(&pdev->dev, "Fail to get clk\n");
> +		return PTR_ERR(zx_spdif->dai_clk);
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	zx_spdif->mapbase = res->start;
> +	zx_spdif->reg_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (!zx_spdif->reg_base) {
> +		dev_err(&pdev->dev, "ioremap failed!\n");
> +		return -EIO;
> +	}
> +
> +	zx_spdif_dev_init(zx_spdif->reg_base);
> +	platform_set_drvdata(pdev, zx_spdif);
> +
> +	ret = snd_soc_register_component(&pdev->dev, &zx_spdif_component,
> +					 &zx_spdif_dai, 1);

devm_

> +	if (ret) {
> +		dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
> +	if (ret)
> +		dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);
> +
> +	return ret;

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

* Re: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-05-29 13:31 ` [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec Jun Nie
@ 2015-05-29 14:10   ` Lars-Peter Clausen
  2015-05-29 15:18     ` Mark Brown
  2015-06-03 17:58   ` Mark Brown
  1 sibling, 1 reply; 19+ messages in thread
From: Lars-Peter Clausen @ 2015-05-29 14:10 UTC (permalink / raw)
  To: Jun Nie, broonie, lgirdwood; +Cc: alsa-devel, shawn.guo, wan.zhijun

On 05/29/2015 03:31 PM, Jun Nie wrote:
> Add zx296702 hdmi codec to enable SPDIF and I2S output
> via HDMI. The SPDIF/I2S route is exclusive with current
> software config and need specify which is valid in
> defconfig.

That's an issue, the hardware configuration should not depend on kernel 
configuration setting. This makes it impossible to run the same kernel on 
platforms with conflicting settings. It should be possible to configure this 
dynamically at boot time based on platform_data/devicetree, etc.

But is this device real hardware anyway?

>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
>   include/sound/zx_hdmi_audio.h    |   7 +++
>   sound/soc/codecs/Kconfig         |   3 +
>   sound/soc/codecs/Makefile        |   1 +
>   sound/soc/codecs/zx296702_hdmi.c | 121 +++++++++++++++++++++++++++++++++++++++
>   4 files changed, 132 insertions(+)
>   create mode 100644 include/sound/zx_hdmi_audio.h
>   create mode 100644 sound/soc/codecs/zx296702_hdmi.c
>
> diff --git a/include/sound/zx_hdmi_audio.h b/include/sound/zx_hdmi_audio.h
> new file mode 100644
> index 0000000..7eb0e81
> --- /dev/null
> +++ b/include/sound/zx_hdmi_audio.h
> @@ -0,0 +1,7 @@
> +#ifndef __ZX_HDMI_AUDIO_H__
> +#define __ZX_HDMI_AUDIO_H__
> +
> +int zx_hdmi_audio_cfg(int audio_codec, int audio_way,
> +		      u32 sample_rate, u32 sample_len);
> +void zx_hdmi_audio_en(int on);

Where is the implementation for these functions? The fact that they seem to 
operate on global state indicates that something is wrong wit this API.

> +#endif /* __ZX_HDMI_AUDIO_H__ */

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

* Re: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-05-29 14:10   ` Lars-Peter Clausen
@ 2015-05-29 15:18     ` Mark Brown
  2015-06-01  1:42       ` Jun Nie
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Brown @ 2015-05-29 15:18 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Jun Nie, shawn.guo, wan.zhijun, lgirdwood, alsa-devel


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

On Fri, May 29, 2015 at 04:10:54PM +0200, Lars-Peter Clausen wrote:
> On 05/29/2015 03:31 PM, Jun Nie wrote:

> >Add zx296702 hdmi codec to enable SPDIF and I2S output
> >via HDMI. The SPDIF/I2S route is exclusive with current
> >software config and need specify which is valid in
> >defconfig.

> That's an issue, the hardware configuration should not depend on kernel
> configuration setting. This makes it impossible to run the same kernel on
> platforms with conflicting settings. It should be possible to configure this
> dynamically at boot time based on platform_data/devicetree, etc.

> But is this device real hardware anyway?

See previous discussions - the SoC has an internal HDMI encoder
connected to a S/PDIF IP which can also be brought out directly as that.
The solution suggested in the previous discussions was to represent the
HDMI IP as a CODEC and connect the S/PDIF IP up to it with a machine
driver, I've not looked at this patch yet though.

[-- Attachment #1.2: Digital signature --]
[-- 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: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-05-29 15:18     ` Mark Brown
@ 2015-06-01  1:42       ` Jun Nie
  2015-06-02 18:13         ` Mark Brown
  0 siblings, 1 reply; 19+ messages in thread
From: Jun Nie @ 2015-06-01  1:42 UTC (permalink / raw)
  To: Mark Brown
  Cc: alsa-devel, Lars-Peter Clausen, wan.zhijun, Liam Girdwood, Shawn Guo

2015-05-29 23:18 GMT+08:00 Mark Brown <broonie@kernel.org>:
> On Fri, May 29, 2015 at 04:10:54PM +0200, Lars-Peter Clausen wrote:
>> On 05/29/2015 03:31 PM, Jun Nie wrote:
>
>> >Add zx296702 hdmi codec to enable SPDIF and I2S output
>> >via HDMI. The SPDIF/I2S route is exclusive with current
>> >software config and need specify which is valid in
>> >defconfig.
>
>> That's an issue, the hardware configuration should not depend on kernel
>> configuration setting. This makes it impossible to run the same kernel on
>> platforms with conflicting settings. It should be possible to configure this
>> dynamically at boot time based on platform_data/devicetree, etc.
>
>> But is this device real hardware anyway?
It is a ready hardware with HDMI audio configured either from internal
SPDIF or I2S interface. Because DAI and CODEC are totally independent
in ASoC design, so CODEC does not know what DAI interface is active. I
guess I can add a dts property to indicate that from machine dts
config.
>
> See previous discussions - the SoC has an internal HDMI encoder
> connected to a S/PDIF IP which can also be brought out directly as that.
> The solution suggested in the previous discussions was to represent the
> HDMI IP as a CODEC and connect the S/PDIF IP up to it with a machine
> driver, I've not looked at this patch yet though.

So I need implement dai link in machine audio card driver, while not
use simple card and device tree initialization. In this way, I surely
can embed HDMI audio codec in HDMI driver. Is that right?

I had try to initialize audio all from dts, so need a HDMI codec dt
node to connect with DAI. However, I cannot find a way to create an
independent HDMI CODEC dt node because it is brought up from HDMI
driver. If my above understanding is correct, a machine level DAI link
shall resolve this issue with dropping simple card and DAI link in
dts. Thanks for your comments!

BTW: HDMI driver is far from mature, so you did not see HDMI function
implementation in this patch serial.

Jun

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

* Re: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-06-01  1:42       ` Jun Nie
@ 2015-06-02 18:13         ` Mark Brown
  2015-06-03  1:47           ` Jun Nie
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Brown @ 2015-06-02 18:13 UTC (permalink / raw)
  To: Jun Nie
  Cc: alsa-devel, Lars-Peter Clausen, wan.zhijun, Liam Girdwood, Shawn Guo


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

On Mon, Jun 01, 2015 at 09:42:34AM +0800, Jun Nie wrote:

> So I need implement dai link in machine audio card driver, while not
> use simple card and device tree initialization. In this way, I surely
> can embed HDMI audio codec in HDMI driver. Is that right?

I'm sorry, I don't entirely follow what you're saying here.

> I had try to initialize audio all from dts, so need a HDMI codec dt
> node to connect with DAI. However, I cannot find a way to create an
> independent HDMI CODEC dt node because it is brought up from HDMI
> driver. If my above understanding is correct, a machine level DAI link
> shall resolve this issue with dropping simple card and DAI link in
> dts. Thanks for your comments!

If the HDMI encoder is simple I'd expect it to be possible to use it
with simple-card.  If it isn't then we can look at why.

> BTW: HDMI driver is far from mature, so you did not see HDMI function
> implementation in this patch serial.

Sure, no problem.

[-- Attachment #1.2: Digital signature --]
[-- 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: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-06-02 18:13         ` Mark Brown
@ 2015-06-03  1:47           ` Jun Nie
  2015-06-03 11:01             ` Mark Brown
  0 siblings, 1 reply; 19+ messages in thread
From: Jun Nie @ 2015-06-03  1:47 UTC (permalink / raw)
  To: Mark Brown
  Cc: alsa-devel, Lars-Peter Clausen, wan.zhijun, Liam Girdwood, Shawn Guo

2015-06-03 2:13 GMT+08:00 Mark Brown <broonie@kernel.org>:
> On Mon, Jun 01, 2015 at 09:42:34AM +0800, Jun Nie wrote:
>
>> So I need implement dai link in machine audio card driver, while not
>> use simple card and device tree initialization. In this way, I surely
>> can embed HDMI audio codec in HDMI driver. Is that right?
>
> I'm sorry, I don't entirely follow what you're saying here.
I am guessing you suggest me to implement a ASoC board driver, like
sound/soc/omap/omap3pandora.c. I can link HDMI codec with DAI with
snd_soc_dai_link structure to avoid specify the connection in dts.

>
>> I had try to initialize audio all from dts, so need a HDMI codec dt
>> node to connect with DAI. However, I cannot find a way to create an
>> independent HDMI CODEC dt node because it is brought up from HDMI
>> driver. If my above understanding is correct, a machine level DAI link
>> shall resolve this issue with dropping simple card and DAI link in
>> dts. Thanks for your comments!
>
> If the HDMI encoder is simple I'd expect it to be possible to use it
> with simple-card.  If it isn't then we can look at why.

Most of devices is initialized from devicetree if not all on my board.
So I need fill CODEC/DAI dt node for imple-card in dts. I experience
the difficulty that I cannot create HDMI CODEC dt node. Because HDMI
CODEC shall be part of HDMI driver and be brought up with direct call
to snd_soc_register_codec in HDMI driver probe function per my
understanding. Then I do not have an independent dt node for HDMI
CODEC, thus cannot link the CODEC to DAI with dts information. Do you
see any chance to connect a DAI to an embedded CODEC of HDMI video
device? Thank you!

>
>> BTW: HDMI driver is far from mature, so you did not see HDMI function
>> implementation in this patch serial.
>
> Sure, no problem.

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

* Re: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-06-03  1:47           ` Jun Nie
@ 2015-06-03 11:01             ` Mark Brown
  2015-06-03 12:40               ` Jun Nie
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Brown @ 2015-06-03 11:01 UTC (permalink / raw)
  To: Jun Nie
  Cc: alsa-devel, Lars-Peter Clausen, wan.zhijun, Liam Girdwood, Shawn Guo


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

On Wed, Jun 03, 2015 at 09:47:46AM +0800, Jun Nie wrote:
> 2015-06-03 2:13 GMT+08:00 Mark Brown <broonie@kernel.org>:
> > On Mon, Jun 01, 2015 at 09:42:34AM +0800, Jun Nie wrote:

> >> So I need implement dai link in machine audio card driver, while not
> >> use simple card and device tree initialization. In this way, I surely
> >> can embed HDMI audio codec in HDMI driver. Is that right?

> > I'm sorry, I don't entirely follow what you're saying here.

> I am guessing you suggest me to implement a ASoC board driver, like
> sound/soc/omap/omap3pandora.c. I can link HDMI codec with DAI with
> snd_soc_dai_link structure to avoid specify the connection in dts.

You can do that if you like, but it's also fine to show the link between
the S/PDIF and HDMI IPs in DT if you like.

> >> I had try to initialize audio all from dts, so need a HDMI codec dt
> >> node to connect with DAI. However, I cannot find a way to create an
> >> independent HDMI CODEC dt node because it is brought up from HDMI
> >> driver. If my above understanding is correct, a machine level DAI link
> >> shall resolve this issue with dropping simple card and DAI link in
> >> dts. Thanks for your comments!

> > If the HDMI encoder is simple I'd expect it to be possible to use it
> > with simple-card.  If it isn't then we can look at why.

> Most of devices is initialized from devicetree if not all on my board.
> So I need fill CODEC/DAI dt node for imple-card in dts. I experience
> the difficulty that I cannot create HDMI CODEC dt node. Because HDMI
> CODEC shall be part of HDMI driver and be brought up with direct call
> to snd_soc_register_codec in HDMI driver probe function per my
> understanding. Then I do not have an independent dt node for HDMI
> CODEC, thus cannot link the CODEC to DAI with dts information. Do you
> see any chance to connect a DAI to an embedded CODEC of HDMI video
> device? Thank you!

Are you saying that the HDMI IP doesn't appear in DT at all?  If the
HDMI IP appears in DT it should be possible to reference it.

[-- Attachment #1.2: Digital signature --]
[-- 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: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-06-03 11:01             ` Mark Brown
@ 2015-06-03 12:40               ` Jun Nie
  2015-06-03 15:09                 ` Mark Brown
  0 siblings, 1 reply; 19+ messages in thread
From: Jun Nie @ 2015-06-03 12:40 UTC (permalink / raw)
  To: Mark Brown
  Cc: alsa-devel, Lars-Peter Clausen, wan.zhijun, Liam Girdwood, Shawn Guo

2015-06-03 19:01 GMT+08:00 Mark Brown <broonie@kernel.org>:
> On Wed, Jun 03, 2015 at 09:47:46AM +0800, Jun Nie wrote:
>> 2015-06-03 2:13 GMT+08:00 Mark Brown <broonie@kernel.org>:
>> > On Mon, Jun 01, 2015 at 09:42:34AM +0800, Jun Nie wrote:
>
>> >> So I need implement dai link in machine audio card driver, while not
>> >> use simple card and device tree initialization. In this way, I surely
>> >> can embed HDMI audio codec in HDMI driver. Is that right?
>
>> > I'm sorry, I don't entirely follow what you're saying here.
>
>> I am guessing you suggest me to implement a ASoC board driver, like
>> sound/soc/omap/omap3pandora.c. I can link HDMI codec with DAI with
>> snd_soc_dai_link structure to avoid specify the connection in dts.
>
> You can do that if you like, but it's also fine to show the link between
> the S/PDIF and HDMI IPs in DT if you like.
>
>> >> I had try to initialize audio all from dts, so need a HDMI codec dt
>> >> node to connect with DAI. However, I cannot find a way to create an
>> >> independent HDMI CODEC dt node because it is brought up from HDMI
>> >> driver. If my above understanding is correct, a machine level DAI link
>> >> shall resolve this issue with dropping simple card and DAI link in
>> >> dts. Thanks for your comments!
>
>> > If the HDMI encoder is simple I'd expect it to be possible to use it
>> > with simple-card.  If it isn't then we can look at why.
>
>> Most of devices is initialized from devicetree if not all on my board.
>> So I need fill CODEC/DAI dt node for imple-card in dts. I experience
>> the difficulty that I cannot create HDMI CODEC dt node. Because HDMI
>> CODEC shall be part of HDMI driver and be brought up with direct call
>> to snd_soc_register_codec in HDMI driver probe function per my
>> understanding. Then I do not have an independent dt node for HDMI
>> CODEC, thus cannot link the CODEC to DAI with dts information. Do you
>> see any chance to connect a DAI to an embedded CODEC of HDMI video
>> device? Thank you!
>
> Are you saying that the HDMI IP doesn't appear in DT at all?  If the
> HDMI IP appears in DT it should be possible to reference it.
Thanks for confirmation. Seems I have much to learn in DT. Will create
a CODEC device in HDMI display driver and feed HDMI device to simple
card as below to have a try. Thanks!
Do you think other patches are OK to merge except the two HDMI patches?

hdmi: hdmi@0x12340000 {
        compatible = "zte,zx296702-hdmi";
        reg = <0x12340000 0x1000>;
     };

sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "zx296702_snd";
        simple-audio-card,cpu {
                sound-dai = <&spdif0>;
        };

        simple-audio-card,codec {
                sound-dai = <&hdmi>;
        };
};

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

* Re: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-06-03 12:40               ` Jun Nie
@ 2015-06-03 15:09                 ` Mark Brown
  0 siblings, 0 replies; 19+ messages in thread
From: Mark Brown @ 2015-06-03 15:09 UTC (permalink / raw)
  To: Jun Nie
  Cc: alsa-devel, Lars-Peter Clausen, wan.zhijun, Liam Girdwood, Shawn Guo


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

On Wed, Jun 03, 2015 at 08:40:31PM +0800, Jun Nie wrote:
> 2015-06-03 19:01 GMT+08:00 Mark Brown <broonie@kernel.org>:

> > Are you saying that the HDMI IP doesn't appear in DT at all?  If the
> > HDMI IP appears in DT it should be possible to reference it.

> Thanks for confirmation. Seems I have much to learn in DT. Will create
> a CODEC device in HDMI display driver and feed HDMI device to simple
> card as below to have a try. Thanks!
> Do you think other patches are OK to merge except the two HDMI patches?

Lars had some comments on the S/PDIF driver.  I didn't look at the I2S
driver yet, I'll try to do that today.

[-- Attachment #1.2: Digital signature --]
[-- 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: [PATCH v3 5/6] ASoC: zx: Add ZTE zx296702 I2S DAI driver
  2015-05-29 13:31 ` [PATCH v3 5/6] ASoC: zx: Add ZTE zx296702 I2S DAI driver Jun Nie
@ 2015-06-03 16:02   ` Mark Brown
  0 siblings, 0 replies; 19+ messages in thread
From: Mark Brown @ 2015-06-03 16:02 UTC (permalink / raw)
  To: Jun Nie; +Cc: alsa-devel, shawn.guo, wan.zhijun, lgirdwood


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

On Fri, May 29, 2015 at 09:31:20PM +0800, Jun Nie wrote:
> Add ZTE zx296702 I2S interface DAI driver

This looks good but the Kconfig and Makefile changes depend on the
previous patch.

[-- Attachment #1.2: Digital signature --]
[-- 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: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-05-29 13:31 ` [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec Jun Nie
  2015-05-29 14:10   ` Lars-Peter Clausen
@ 2015-06-03 17:58   ` Mark Brown
  2015-06-04  3:35     ` Jun Nie
  1 sibling, 1 reply; 19+ messages in thread
From: Mark Brown @ 2015-06-03 17:58 UTC (permalink / raw)
  To: Jun Nie; +Cc: alsa-devel, shawn.guo, wan.zhijun, lgirdwood


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

On Fri, May 29, 2015 at 09:31:21PM +0800, Jun Nie wrote:

> +int zx_hdmi_audio_cfg(int audio_codec, int audio_way,
> +		      u32 sample_rate, u32 sample_len);
> +void zx_hdmi_audio_en(int on);

It's a bit hard to review this properly without knowing what these
functions do.

> +static int zx_hw_params(struct snd_pcm_substream *substream,
> +			struct snd_pcm_hw_params *params,
> +			struct snd_soc_dai *dai)
> +{
> +#ifdef CONFIG_ZX_HDMI_SND_SPDIF
> +	zx_hdmi_audio_cfg(1, 0, params_rate(params),
> +#endif
> +#ifdef CONFIG_ZX_HDMI_SND_I2S
> +	zx_hdmi_audio_cfg(1, 1, params_rate(params),
> +#endif
> +			  params_physical_width(params));
> +	return 0;
> +}

The magic numbers aren't great and it does seem a bit odd to call both
I2S and S/PDIF versions always - but I guess this will be restructured
following our discussion in the other thread anyway.

[-- Attachment #1.2: Digital signature --]
[-- 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: [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec
  2015-06-03 17:58   ` Mark Brown
@ 2015-06-04  3:35     ` Jun Nie
  0 siblings, 0 replies; 19+ messages in thread
From: Jun Nie @ 2015-06-04  3:35 UTC (permalink / raw)
  To: Mark Brown; +Cc: Jason Liu, alsa-devel, Shawn Guo, wan.zhijun, Liam Girdwood

2015-06-04 1:58 GMT+08:00 Mark Brown <broonie@kernel.org>:
> On Fri, May 29, 2015 at 09:31:21PM +0800, Jun Nie wrote:
>
>> +int zx_hdmi_audio_cfg(int audio_codec, int audio_way,
>> +                   u32 sample_rate, u32 sample_len);
>> +void zx_hdmi_audio_en(int on);
>
> It's a bit hard to review this properly without knowing what these
> functions do.
>
>> +static int zx_hw_params(struct snd_pcm_substream *substream,
>> +                     struct snd_pcm_hw_params *params,
>> +                     struct snd_soc_dai *dai)
>> +{
>> +#ifdef CONFIG_ZX_HDMI_SND_SPDIF
>> +     zx_hdmi_audio_cfg(1, 0, params_rate(params),
>> +#endif
>> +#ifdef CONFIG_ZX_HDMI_SND_I2S
>> +     zx_hdmi_audio_cfg(1, 1, params_rate(params),
>> +#endif
>> +                       params_physical_width(params));
>> +     return 0;
>> +}
>
> The magic numbers aren't great and it does seem a bit odd to call both
> I2S and S/PDIF versions always - but I guess this will be restructured
> following our discussion in the other thread anyway.

Yes, HDMI audio will be moved into video driver side and I will add a
DT property to indicate active HDMI I2S or SPDIF from machine dts.

Will post patches with taking Lars's comments with dropping HDMI stuff.

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

end of thread, other threads:[~2015-06-04  3:35 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-29 13:31 [PATCH v3 0/6] Support ZTE zx296702 SPDIF/I2S Jun Nie
2015-05-29 13:31 ` [PATCH v3 1/6] dt: Add documentation for the ZTE SPDIF controller Jun Nie
2015-05-29 13:31 ` [PATCH v3 2/6] dt: Add documentation for the ZTE I2S controller Jun Nie
2015-05-29 13:31 ` [PATCH v3 3/6] dt: Add doc for the ZTE HDMI audio codec binding Jun Nie
2015-05-29 13:31 ` [PATCH v3 4/6] ASoC: zx: Add zx296702 SPDIF support Jun Nie
2015-05-29 14:03   ` Lars-Peter Clausen
2015-05-29 13:31 ` [PATCH v3 5/6] ASoC: zx: Add ZTE zx296702 I2S DAI driver Jun Nie
2015-06-03 16:02   ` Mark Brown
2015-05-29 13:31 ` [PATCH v3 6/6] ASoC: zx: add zx296702 hdmi codec Jun Nie
2015-05-29 14:10   ` Lars-Peter Clausen
2015-05-29 15:18     ` Mark Brown
2015-06-01  1:42       ` Jun Nie
2015-06-02 18:13         ` Mark Brown
2015-06-03  1:47           ` Jun Nie
2015-06-03 11:01             ` Mark Brown
2015-06-03 12:40               ` Jun Nie
2015-06-03 15:09                 ` Mark Brown
2015-06-03 17:58   ` Mark Brown
2015-06-04  3:35     ` Jun Nie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).