linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3 v4] HiKey i2s bindings, driver and dts changes
@ 2017-03-31 22:05 John Stultz
  2017-03-31 22:05 ` [PATCH 1/3 v4] ASoC: add hi6210-i2s DT bindings John Stultz
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: John Stultz @ 2017-03-31 22:05 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Zhangfei Gao, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Wei Xu, Rob Herring, Andy Green,
	Dave Long, Guodong Xu

This patchset provides i2s audio driver and dts changes in order
to enable HDMI audio on the HiKey board.

Its been a few months since I last sent this out, but I wanted
to try to get some thoughts after trying to integrate some of
the feedback I've gotten since then.

Overally, the current i2s driver is somewhat limited, as the SoC
supports three different i2s routes. However, without
documentation this driver was originally developed by Andy Green
with only an old 3.10 era vendor driver for reference, so the
driver only supports one i2s route (S2) which goes to the HDMI
bridge on HiKey.

>From previous feedback, I have reworked the DTS binding a tiny
bit, to allow multi dais to be specified, which will allow other
i2s routes/dai links (such as is available on the LS connector)
to be used once we manage to figure out how to enable them
properly.

Further feedback would be greatly appreciated! Though audio is
not an area of my expertise, so the more specific the better :)

thanks
-john

Cc: Zhangfei Gao <zhangfei.gao@linaro.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Wei Xu <xuwei5@hisilicon.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Andy Green <andy@warmcat.com>
Cc: Dave Long <dave.long@linaro.org>
Cc: Guodong Xu <guodong.xu@linaro.org>

Andy Green (1):
  ASoC: hisilicon: Add hi6210 i2s audio driver

John Stultz (2):
  ASoC: add hi6210-i2s  DT bindings
  arm64: dts: hi6220: Add k3-dma and i2s/hdmi audio support

 .../bindings/sound/hisilicon,hi6210-i2s.txt        |  34 ++
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts     |  16 +
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi          |  26 +
 sound/soc/Kconfig                                  |   1 +
 sound/soc/Makefile                                 |   1 +
 sound/soc/hisilicon/Kconfig                        |   5 +
 sound/soc/hisilicon/Makefile                       |   1 +
 sound/soc/hisilicon/hi6210-i2s.c                   | 628 +++++++++++++++++++++
 sound/soc/hisilicon/hi6210-i2s.h                   | 276 +++++++++
 9 files changed, 988 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt
 create mode 100644 sound/soc/hisilicon/Kconfig
 create mode 100644 sound/soc/hisilicon/Makefile
 create mode 100644 sound/soc/hisilicon/hi6210-i2s.c
 create mode 100644 sound/soc/hisilicon/hi6210-i2s.h

-- 
2.7.4

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

* [PATCH 1/3 v4] ASoC: add hi6210-i2s  DT bindings
  2017-03-31 22:05 [PATCH 0/3 v4] HiKey i2s bindings, driver and dts changes John Stultz
@ 2017-03-31 22:05 ` John Stultz
  2017-04-10 18:13   ` Mark Brown
  2017-03-31 22:06 ` [PATCH 2/3 v4] ASoC: hisilicon: Add hi6210 i2s audio driver John Stultz
  2017-03-31 22:06 ` [PATCH 3/3 v4] arm64: dts: hi6220: Add k3-dma and i2s/hdmi audio support John Stultz
  2 siblings, 1 reply; 8+ messages in thread
From: John Stultz @ 2017-03-31 22:05 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Zhangfei Gao, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Wei Xu, Rob Herring, Andy Green,
	Dave Long, Guodong Xu

Adds DT bindings documentation for the hi6210-i2s driver.

Cc: Zhangfei Gao <zhangfei.gao@linaro.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Wei Xu <xuwei5@hisilicon.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Andy Green <andy@warmcat.com>
Cc: Dave Long <dave.long@linaro.org>
Cc: Guodong Xu <guodong.xu@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
v3:
* Simplified and reworked dt binding
v4:
* Add #sound-dai-cells entry to make it clear multiple
  dais are possible
---
 .../bindings/sound/hisilicon,hi6210-i2s.txt        | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt

diff --git a/Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt b/Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt
new file mode 100644
index 0000000..680bb035
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/hisilicon,hi6210-i2s.txt
@@ -0,0 +1,34 @@
+* Hisilicon 6210 i2s controller
+
+Required properties:
+
+- compatible: should be one of the following:
+   - "hisilicon,hi6210-i2s"
+- reg: physical base address of the i2s controller unit and length of
+   memory mapped region.
+- interrupts: should contain the i2s interrupt.
+- clocks: a list of phandle + clock-specifier pairs, one for each entry
+  in clock-names.
+- clock-names: should contain following:
+   - "dacodec"
+   - "i2s-base"
+- dmas: DMA specifiers for tx dma. See the DMA client binding,
+  Documentation/devicetree/bindings/dma/dma.txt
+- dma-names: should be "tx" and "rx"
+- hisilicon,sysctrl-syscon: phandle to sysctrl syscon
+- #sound-dai-cells: Should be set to 1 (for multi-dai)
+
+Example for the hi6210 i2s controller:
+
+i2s0: i2s@f7118000{
+	compatible = "hisilicon,hi6210-i2s";
+	reg = <0x0 0xf7118000 0x0 0x8000>; /* i2s unit */
+	interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; /* 155 "DigACodec_intr"-32 */
+	clocks = <&sys_ctrl HI6220_DACODEC_PCLK>,
+		 <&sys_ctrl HI6220_BBPPLL0_DIV>;
+	clock-names = "dacodec", "i2s-base";
+	dmas = <&dma0 15 &dma0 14>;
+	dma-names = "rx", "tx";
+	hisilicon,sysctrl-syscon = <&sys_ctrl>;
+	#sound-dai-cells = <1>;
+};
-- 
2.7.4

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

* [PATCH 2/3 v4] ASoC: hisilicon: Add hi6210 i2s audio driver
  2017-03-31 22:05 [PATCH 0/3 v4] HiKey i2s bindings, driver and dts changes John Stultz
  2017-03-31 22:05 ` [PATCH 1/3 v4] ASoC: add hi6210-i2s DT bindings John Stultz
@ 2017-03-31 22:06 ` John Stultz
  2017-04-10 18:39   ` Mark Brown
  2017-03-31 22:06 ` [PATCH 3/3 v4] arm64: dts: hi6220: Add k3-dma and i2s/hdmi audio support John Stultz
  2 siblings, 1 reply; 8+ messages in thread
From: John Stultz @ 2017-03-31 22:06 UTC (permalink / raw)
  To: lkml
  Cc: Andy Green, Zhangfei Gao, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Wei Xu, Rob Herring, Andy Green,
	Dave Long, Guodong Xu, John Stultz

From: Andy Green <andy.green@linaro.org>

Add driver for hi6210 i2s controller found on hi6220 boards.

Cc: Zhangfei Gao <zhangfei.gao@linaro.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Wei Xu <xuwei5@hisilicon.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Andy Green <andy@warmcat.com>
Cc: Dave Long <dave.long@linaro.org>
Cc: Guodong Xu <guodong.xu@linaro.org>
Signed-off-by: Andy Green <andy.green@linaro.org>
[jstultz: Forward ported to mainline, fairly major rework
 based on suggestions from Mark Brown]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
v2:
* Folded in fixes from kbuildbot
* Split i2s and hdmi-card drivers up
* Major rework from MarkB's suggestions
v3:
* Folded in fixes from Guodong
* Simplified and reworked devicetree bindings
* Integrated review feedback from Mark Brown
v4:
* Minor tweak to ensure dai entry is named properly when
  using non-single-link dias
---
 sound/soc/Kconfig                |   1 +
 sound/soc/Makefile               |   1 +
 sound/soc/hisilicon/Kconfig      |   5 +
 sound/soc/hisilicon/Makefile     |   1 +
 sound/soc/hisilicon/hi6210-i2s.c | 628 +++++++++++++++++++++++++++++++++++++++
 sound/soc/hisilicon/hi6210-i2s.h | 276 +++++++++++++++++
 6 files changed, 912 insertions(+)
 create mode 100644 sound/soc/hisilicon/Kconfig
 create mode 100644 sound/soc/hisilicon/Makefile
 create mode 100644 sound/soc/hisilicon/hi6210-i2s.c
 create mode 100644 sound/soc/hisilicon/hi6210-i2s.h

diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 182d92e..9df9658 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/cirrus/Kconfig"
 source "sound/soc/davinci/Kconfig"
 source "sound/soc/dwc/Kconfig"
 source "sound/soc/fsl/Kconfig"
+source "sound/soc/hisilicon/Kconfig"
 source "sound/soc/jz4740/Kconfig"
 source "sound/soc/nuc900/Kconfig"
 source "sound/soc/omap/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 9a30f21..2f6aabb 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SND_SOC)	+= cirrus/
 obj-$(CONFIG_SND_SOC)	+= davinci/
 obj-$(CONFIG_SND_SOC)	+= dwc/
 obj-$(CONFIG_SND_SOC)	+= fsl/
+obj-$(CONFIG_SND_SOC)	+= hisilicon/
 obj-$(CONFIG_SND_SOC)	+= jz4740/
 obj-$(CONFIG_SND_SOC)	+= img/
 obj-$(CONFIG_SND_SOC)	+= intel/
diff --git a/sound/soc/hisilicon/Kconfig b/sound/soc/hisilicon/Kconfig
new file mode 100644
index 0000000..4356d5a
--- /dev/null
+++ b/sound/soc/hisilicon/Kconfig
@@ -0,0 +1,5 @@
+config SND_I2S_HI6210_I2S
+	tristate "Hisilicon I2S controller"
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Hisilicon I2S
diff --git a/sound/soc/hisilicon/Makefile b/sound/soc/hisilicon/Makefile
new file mode 100644
index 0000000..e8095e2
--- /dev/null
+++ b/sound/soc/hisilicon/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SND_I2S_HI6210_I2S) += hi6210-i2s.o
diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c
new file mode 100644
index 0000000..45691b70
--- /dev/null
+++ b/sound/soc/hisilicon/hi6210-i2s.c
@@ -0,0 +1,628 @@
+/*
+ * linux/sound/soc/m8m/hi6210_i2s.c - I2S IP driver
+ *
+ * Copyright (C) 2015 Linaro, Ltd
+ * Author: Andy Green <andy.green@linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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.
+ *
+ * This driver only deals with S2 interface (BT)
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <linux/interrupt.h>
+#include <linux/reset.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/mfd/syscon.h>
+#include <linux/reset-controller.h>
+#include <linux/clk.h>
+
+#include "hi6210-i2s.h"
+
+struct hi6210_i2s {
+	struct device *dev;
+	struct reset_control *rc;
+	struct clk *clk[8];
+	int clocks;
+	struct snd_soc_dai_driver dai;
+	void __iomem *base;
+	struct regmap *sysctrl;
+	phys_addr_t base_phys;
+	struct snd_dmaengine_dai_dma_data dma_data[2];
+	int clk_rate;
+	spinlock_t lock;
+	int rate;
+	int format;
+	u8 bits;
+	u8 channels;
+	u8 id;
+	u8 channel_length;
+	u8 use;
+	u32 master:1;
+	u32 status:1;
+};
+
+#define SC_PERIPH_CLKEN1	0x210
+#define SC_PERIPH_CLKDIS1	0x214
+
+#define SC_PERIPH_CLKEN3	0x230
+#define SC_PERIPH_CLKDIS3	0x234
+
+#define SC_PERIPH_CLKEN12	0x270
+#define SC_PERIPH_CLKDIS12	0x274
+
+#define SC_PERIPH_RSTEN1	0x310
+#define SC_PERIPH_RSTDIS1	0x314
+#define SC_PERIPH_RSTSTAT1	0x318
+
+#define SC_PERIPH_RSTEN2	0x320
+#define SC_PERIPH_RSTDIS2	0x324
+#define SC_PERIPH_RSTSTAT2	0x328
+
+#define SOC_PMCTRL_BBPPLLALIAS	0x48
+
+enum {
+	CLK_DACODEC,
+	CLK_I2S_BASE,
+};
+
+static inline void hi6210_write_reg(struct hi6210_i2s *i2s, int reg, u32 val)
+{
+	writel(val, i2s->base + reg);
+}
+
+static inline u32 hi6210_read_reg(struct hi6210_i2s *i2s, int reg)
+{
+	return readl(i2s->base + reg);
+}
+
+int hi6210_i2s_startup(struct snd_pcm_substream *substream,
+		     struct snd_soc_dai *cpu_dai)
+{
+	struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
+	int ret, n;
+	u32 val;
+
+	/* deassert reset on ABB */
+	regmap_read(i2s->sysctrl, SC_PERIPH_RSTSTAT2, &val);
+	if (val & BIT(4))
+		regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS2, BIT(4));
+
+	for (n = 0; n < i2s->clocks; n++) {
+		ret = clk_prepare_enable(i2s->clk[n]);
+		if (ret) {
+			while (n--)
+				clk_disable_unprepare(i2s->clk[n]);
+			return ret;
+		}
+	}
+
+	ret = clk_set_rate(i2s->clk[CLK_I2S_BASE], 49152000);
+	if (ret) {
+		dev_err(i2s->dev, "%s: setting 49.152MHz base rate failed %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	/* enable clock before frequency division */
+	regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN12, BIT(9));
+
+	/* enable codec working clock / == "codec bus clock" */
+	regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN1, BIT(5));
+
+	/* deassert reset on codec / interface clock / working clock */
+	regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
+	regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS1, BIT(5));
+
+	/* not interested in i2s irqs */
+	val = hi6210_read_reg(i2s, HII2S_CODEC_IRQ_MASK);
+	val |= 0x3f;
+	hi6210_write_reg(i2s, HII2S_CODEC_IRQ_MASK, val);
+
+
+	/* reset the stereo downlink fifo */
+	val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
+	val |= (BIT(5) | BIT(4));
+	hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
+
+	val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
+	val &= ~(BIT(5) | BIT(4));
+	hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
+
+
+	val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
+	val &= ~(HII2S_SW_RST_N__ST_DL_WORDLEN_MASK <<
+			HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
+	val |= (HII2S_BITS_16 << HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
+	hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
+
+	val = hi6210_read_reg(i2s, HII2S_MISC_CFG);
+	/* mux 11/12 = APB not i2s */
+	val &= ~HII2S_MISC_CFG__ST_DL_TEST_SEL;
+	/* BT R ch  0 = mixer op of DACR ch */
+	val &= ~HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
+	val &= ~HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
+
+	val |= HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
+	/* BT L ch = 1 = mux 7 = "mixer output of DACL */
+	val |= HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
+	hi6210_write_reg(i2s, HII2S_MISC_CFG, val);
+
+	val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
+	val |= HII2S_SW_RST_N__SW_RST_N;
+	hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
+
+	return 0;
+}
+void hi6210_i2s_shutdown(struct snd_pcm_substream *substream,
+		       struct snd_soc_dai *cpu_dai)
+{
+	struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
+	int n;
+
+	for (n = 0; n < i2s->clocks; n++)
+		clk_disable_unprepare(i2s->clk[n]);
+
+	regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
+}
+
+static void hi6210_i2s_txctrl(struct snd_soc_dai *cpu_dai, int on)
+{
+	struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
+	u32 val;
+
+	spin_lock(&i2s->lock);
+	if (on) {
+		/* enable S2 TX */
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val |= HII2S_I2S_CFG__S2_IF_TX_EN;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+	} else {
+		/* disable S2 TX */
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val &= ~HII2S_I2S_CFG__S2_IF_TX_EN;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+	}
+	spin_unlock(&i2s->lock);
+}
+
+static void hi6210_i2s_rxctrl(struct snd_soc_dai *cpu_dai, int on)
+{
+	struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
+	u32 val;
+
+	spin_lock(&i2s->lock);
+	if (on) {
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val |= HII2S_I2S_CFG__S2_IF_RX_EN;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+	} else {
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val &= ~HII2S_I2S_CFG__S2_IF_RX_EN;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+	}
+	spin_unlock(&i2s->lock);
+}
+
+static int hi6210_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+	struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
+
+	/*
+	 * We don't actually set the hardware until the hw_params
+	 * call, but we need to validate the user input here.
+	 */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+	case SND_SOC_DAIFMT_LEFT_J:
+	case SND_SOC_DAIFMT_RIGHT_J:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	i2s->format = fmt;
+	i2s->master = (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) ==
+		      SND_SOC_DAIFMT_CBS_CFS;
+
+	return 0;
+}
+
+static int hi6210_i2s_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *cpu_dai)
+{
+	struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
+	u32 bits = 0, rate = 0, signed_data = 0, fmt = 0;
+	u32 val;
+	struct snd_dmaengine_dai_dma_data *dma_data;
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_U16_LE:
+		signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
+		/* fallthru */
+	case SNDRV_PCM_FORMAT_S16_LE:
+		bits = HII2S_BITS_16;
+		break;
+	case SNDRV_PCM_FORMAT_U24_LE:
+		signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
+		/* fallthru */
+	case SNDRV_PCM_FORMAT_S24_LE:
+		bits = HII2S_BITS_24;
+		break;
+	default:
+		dev_err(cpu_dai->dev, "Bad format\n");
+		return -EINVAL;
+	}
+
+
+	switch (params_rate(params)) {
+	case 8000:
+		rate = HII2S_FS_RATE_8KHZ;
+		break;
+	case 16000:
+		rate = HII2S_FS_RATE_16KHZ;
+		break;
+	case 32000:
+		rate = HII2S_FS_RATE_32KHZ;
+		break;
+	case 48000:
+		rate = HII2S_FS_RATE_48KHZ;
+		break;
+	case 96000:
+		rate = HII2S_FS_RATE_96KHZ;
+		break;
+	case 192000:
+		rate = HII2S_FS_RATE_192KHZ;
+		break;
+	default:
+		dev_err(cpu_dai->dev, "Bad rate: %d\n", params_rate(params));
+		return -EINVAL;
+	}
+
+	if (!(params_channels(params))) {
+		dev_err(cpu_dai->dev, "Bad channels\n");
+		return -EINVAL;
+	}
+
+	dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
+
+	switch (bits) {
+	case HII2S_BITS_24:
+		i2s->bits = 32;
+		dma_data->addr_width = 3;
+		break;
+	default:
+		i2s->bits = 16;
+		dma_data->addr_width = 2;
+	}
+	i2s->rate = params_rate(params);
+	i2s->channels = params_channels(params);
+	i2s->channel_length = i2s->channels * i2s->bits;
+
+	val = hi6210_read_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG);
+	val &= ~((HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK <<
+			HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
+		(HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK <<
+			HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
+		(HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK <<
+			HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
+		(HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK <<
+			HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
+	val |= ((16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
+		(30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
+		(16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
+		(30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
+	hi6210_write_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG, val);
+
+
+	val = hi6210_read_reg(i2s, HII2S_IF_CLK_EN_CFG);
+	val |= (BIT(19) | BIT(18) | BIT(17) |
+		HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN |
+		HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN |
+		HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN |
+		HII2S_IF_CLK_EN_CFG__ST_DL_R_EN |
+		HII2S_IF_CLK_EN_CFG__ST_DL_L_EN);
+	hi6210_write_reg(i2s, HII2S_IF_CLK_EN_CFG, val);
+
+
+	val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG);
+	val &= ~(HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN |
+		 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN |
+		 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN |
+		 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN |
+		 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN |
+		 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN);
+	val |= (HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN |
+		HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN);
+	hi6210_write_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG, val);
+
+
+	val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG);
+	val &= ~(HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE |
+		 HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE);
+	hi6210_write_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG, val);
+
+	val = hi6210_read_reg(i2s, HII2S_MUX_TOP_MODULE_CFG);
+	val &= ~(HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE |
+		 HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE |
+		 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE |
+		 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE);
+	hi6210_write_reg(i2s, HII2S_MUX_TOP_MODULE_CFG, val);
+
+
+	switch (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		i2s->master = false;
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val |= HII2S_I2S_CFG__S2_MST_SLV;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		i2s->master = true;
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val &= ~HII2S_I2S_CFG__S2_MST_SLV;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+		break;
+	default:
+		WARN_ONCE(1, "Invalid i2s->fmt MASTER_MASK. This shouldn't happen\n");
+	}
+
+	switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		fmt = HII2S_FORMAT_I2S;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fmt = HII2S_FORMAT_LEFT_JUST;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		fmt = HII2S_FORMAT_RIGHT_JUST;
+		break;
+	default:
+		WARN_ONCE(1, "Invalid i2s->fmt FORMAT_MASK. This shouldn't happen\n");
+	}
+
+	val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+	val &= ~(HII2S_I2S_CFG__S2_FUNC_MODE_MASK <<
+			HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT);
+	val |= fmt << HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT;
+	hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+
+
+	val = hi6210_read_reg(i2s, HII2S_CLK_SEL);
+	val &= ~(HII2S_CLK_SEL__I2S_BT_FM_SEL | /* BT gets the I2S */
+			HII2S_CLK_SEL__EXT_12_288MHZ_SEL);
+	hi6210_write_reg(i2s, HII2S_CLK_SEL, val);
+
+	dma_data->maxburst = 2;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		dma_data->addr = i2s->base_phys + HII2S_ST_DL_CHANNEL;
+	else
+		dma_data->addr = i2s->base_phys + HII2S_STEREO_UPLINK_CHANNEL;
+
+	switch (i2s->channels) {
+	case 1:
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val |= HII2S_I2S_CFG__S2_FRAME_MODE;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+		break;
+	default:
+		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+		val &= ~HII2S_I2S_CFG__S2_FRAME_MODE;
+		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+	}
+
+	/* clear loopback, set signed type and word length */
+	val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
+	val &= ~HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
+	val &= ~(HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK <<
+			HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
+	val &= ~(HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK <<
+			HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT);
+	val |= signed_data;
+	val |= (bits << HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
+	hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
+
+
+	if (!i2s->master)
+		return 0;
+
+	/* set DAC and related units to correct rate */
+	val = hi6210_read_reg(i2s, HII2S_FS_CFG);
+	val &= ~(HII2S_FS_CFG__FS_S2_MASK << HII2S_FS_CFG__FS_S2_SHIFT);
+	val &= ~(HII2S_FS_CFG__FS_DACLR_MASK << HII2S_FS_CFG__FS_DACLR_SHIFT);
+	val &= ~(HII2S_FS_CFG__FS_ST_DL_R_MASK <<
+					HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
+	val &= ~(HII2S_FS_CFG__FS_ST_DL_L_MASK <<
+					HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
+	val |= (rate << HII2S_FS_CFG__FS_S2_SHIFT);
+	val |= (rate << HII2S_FS_CFG__FS_DACLR_SHIFT);
+	val |= (rate << HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
+	val |= (rate << HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
+	hi6210_write_reg(i2s, HII2S_FS_CFG, val);
+
+	return 0;
+}
+
+static int hi6210_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *cpu_dai)
+{
+	pr_debug("%s\n", __func__);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			hi6210_i2s_rxctrl(cpu_dai, 1);
+		else
+			hi6210_i2s_txctrl(cpu_dai, 1);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			hi6210_i2s_rxctrl(cpu_dai, 0);
+		else
+			hi6210_i2s_txctrl(cpu_dai, 0);
+		break;
+	default:
+		dev_err(cpu_dai->dev, "uknown cmd\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+	struct hi6210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+
+	snd_soc_dai_init_dma_data(dai,
+				  &i2s->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
+				  &i2s->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
+
+	return 0;
+}
+
+
+static struct snd_soc_dai_ops hi6210_i2s_dai_ops = {
+	.trigger	= hi6210_i2s_trigger,
+	.hw_params	= hi6210_i2s_hw_params,
+	.set_fmt	= hi6210_i2s_set_fmt,
+	.startup	= hi6210_i2s_startup,
+	.shutdown	= hi6210_i2s_shutdown,
+};
+
+struct snd_soc_dai_driver hi6210_i2s_dai_init = {
+	.probe		= hi6210_i2s_dai_probe,
+	.playback = {
+		.channels_min = 2,
+		.channels_max = 2,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE |
+			   SNDRV_PCM_FMTBIT_U16_LE,
+		.rates = SNDRV_PCM_RATE_48000,
+	},
+	.capture = {
+		.channels_min = 2,
+		.channels_max = 2,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE |
+			   SNDRV_PCM_FMTBIT_U16_LE,
+		.rates = SNDRV_PCM_RATE_48000,
+	},
+	.ops = &hi6210_i2s_dai_ops,
+};
+
+static const struct snd_soc_component_driver hi6210_i2s_i2s_comp = {
+	.name = "hi6210_i2s-i2s",
+};
+
+static int hi6210_i2s_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct hi6210_i2s *i2s;
+	struct resource *res;
+	int ret;
+
+	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
+	if (!i2s)
+		return -ENOMEM;
+
+	i2s->dev = dev;
+	spin_lock_init(&i2s->lock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	i2s->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(i2s->base))
+		return PTR_ERR(i2s->base);
+
+	i2s->base_phys = (phys_addr_t)res->start;
+	i2s->dai = hi6210_i2s_dai_init;
+
+	dev_set_drvdata(&pdev->dev, i2s);
+
+	i2s->sysctrl = syscon_regmap_lookup_by_phandle(node,
+						"hisilicon,sysctrl-syscon");
+	if (IS_ERR(i2s->sysctrl))
+		return PTR_ERR(i2s->sysctrl);
+
+	i2s->clk[CLK_DACODEC] = devm_clk_get(&pdev->dev, "dacodec");
+	if (IS_ERR_OR_NULL(i2s->clk[CLK_DACODEC]))
+		return PTR_ERR(i2s->clk[CLK_DACODEC]);
+	i2s->clocks++;
+
+	i2s->clk[CLK_I2S_BASE] = devm_clk_get(&pdev->dev, "i2s-base");
+	if (IS_ERR_OR_NULL(i2s->clk[CLK_I2S_BASE]))
+		return PTR_ERR(i2s->clk[CLK_I2S_BASE]);
+	i2s->clocks++;
+
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_register_component(&pdev->dev, &hi6210_i2s_i2s_comp,
+					 &i2s->dai, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register dai\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int hi6210_i2s_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_component(&pdev->dev);
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	return 0;
+}
+
+static const struct of_device_id hi6210_i2s_dt_ids[] = {
+	{ .compatible = "hisilicon,hi6210-i2s" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, hi6210_i2s_dt_ids);
+
+static struct platform_driver hi6210_i2s_driver = {
+	.probe = hi6210_i2s_probe,
+	.remove = hi6210_i2s_remove,
+	.driver = {
+		.name = "hi6210_i2s",
+		.of_match_table = hi6210_i2s_dt_ids,
+	},
+};
+
+module_platform_driver(hi6210_i2s_driver);
+
+MODULE_DESCRIPTION("Hisilicon HI6210 I2S driver");
+MODULE_AUTHOR("Andy Green <andy.green@linaro.org>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/hisilicon/hi6210-i2s.h b/sound/soc/hisilicon/hi6210-i2s.h
new file mode 100644
index 0000000..85cecc4
--- /dev/null
+++ b/sound/soc/hisilicon/hi6210-i2s.h
@@ -0,0 +1,276 @@
+/*
+ * linux/sound/soc/hisilicon/hi6210-i2s.h
+ *
+ * Copyright (C) 2015 Linaro, Ltd
+ * Author: Andy Green <andy.green@linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Note at least on 6220, S2 == BT, S1 == Digital FM Radio IF
+ */
+
+#ifndef _HI6210_I2S_H
+#define _HI6210_I2S_H
+
+#define HII2S_SW_RST_N				0
+
+#define HII2S_SW_RST_N__STEREO_UPLINK_WORDLEN_SHIFT			28
+#define HII2S_SW_RST_N__STEREO_UPLINK_WORDLEN_MASK			3
+#define HII2S_SW_RST_N__THIRDMD_UPLINK_WORDLEN_SHIFT			26
+#define HII2S_SW_RST_N__THIRDMD_UPLINK_WORDLEN_MASK			3
+#define HII2S_SW_RST_N__VOICE_UPLINK_WORDLEN_SHIFT			24
+#define HII2S_SW_RST_N__VOICE_UPLINK_WORDLEN_MASK			3
+#define HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT				20
+#define HII2S_SW_RST_N__ST_DL_WORDLEN_MASK				3
+#define HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_SHIFT			18
+#define HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_MASK			3
+#define HII2S_SW_RST_N__VOICE_DLINK_WORDLEN_SHIFT			16
+#define HII2S_SW_RST_N__VOICE_DLINK_WORDLEN_MASK			3
+
+#define HII2S_SW_RST_N__SW_RST_N					BIT(0)
+
+enum hi6210_bits {
+	HII2S_BITS_16,
+	HII2S_BITS_18,
+	HII2S_BITS_20,
+	HII2S_BITS_24,
+};
+
+
+#define HII2S_IF_CLK_EN_CFG			4
+
+#define HII2S_IF_CLK_EN_CFG__THIRDMD_UPLINK_EN				BIT(25)
+#define HII2S_IF_CLK_EN_CFG__THIRDMD_DLINK_EN				BIT(24)
+#define HII2S_IF_CLK_EN_CFG__S3_IF_CLK_EN				BIT(20)
+#define HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN				BIT(16)
+#define HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN				BIT(15)
+#define HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN				BIT(14)
+#define HII2S_IF_CLK_EN_CFG__S2_IR_PGA_EN				BIT(13)
+#define HII2S_IF_CLK_EN_CFG__S2_IL_PGA_EN				BIT(12)
+#define HII2S_IF_CLK_EN_CFG__S1_IR_PGA_EN				BIT(10)
+#define HII2S_IF_CLK_EN_CFG__S1_IL_PGA_EN				BIT(9)
+#define HII2S_IF_CLK_EN_CFG__S1_IF_CLK_EN				BIT(8)
+#define HII2S_IF_CLK_EN_CFG__VOICE_DLINK_SRC_EN				BIT(7)
+#define HII2S_IF_CLK_EN_CFG__VOICE_DLINK_EN				BIT(6)
+#define HII2S_IF_CLK_EN_CFG__ST_DL_R_EN					BIT(5)
+#define HII2S_IF_CLK_EN_CFG__ST_DL_L_EN					BIT(4)
+#define HII2S_IF_CLK_EN_CFG__VOICE_UPLINK_R_EN				BIT(3)
+#define HII2S_IF_CLK_EN_CFG__VOICE_UPLINK_L_EN				BIT(2)
+#define HII2S_IF_CLK_EN_CFG__STEREO_UPLINK_R_EN				BIT(1)
+#define HII2S_IF_CLK_EN_CFG__STEREO_UPLINK_L_EN				BIT(0)
+
+#define HII2S_DIG_FILTER_CLK_EN_CFG		8
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN			BIT(30)
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN			BIT(28)
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN			BIT(25)
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN			BIT(24)
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN			BIT(22)
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN			BIT(20)
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN			BIT(17)
+#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN			BIT(16)
+
+#define HII2S_FS_CFG				0xc
+
+#define HII2S_FS_CFG__FS_S2_SHIFT					28
+#define HII2S_FS_CFG__FS_S2_MASK					7
+#define HII2S_FS_CFG__FS_S1_SHIFT					24
+#define HII2S_FS_CFG__FS_S1_MASK					7
+#define HII2S_FS_CFG__FS_ADCLR_SHIFT					20
+#define HII2S_FS_CFG__FS_ADCLR_MASK					7
+#define HII2S_FS_CFG__FS_DACLR_SHIFT					16
+#define HII2S_FS_CFG__FS_DACLR_MASK					7
+#define HII2S_FS_CFG__FS_ST_DL_R_SHIFT					8
+#define HII2S_FS_CFG__FS_ST_DL_R_MASK					7
+#define HII2S_FS_CFG__FS_ST_DL_L_SHIFT					4
+#define HII2S_FS_CFG__FS_ST_DL_L_MASK					7
+#define HII2S_FS_CFG__FS_VOICE_DLINK_SHIFT				0
+#define HII2S_FS_CFG__FS_VOICE_DLINK_MASK				7
+
+enum hi6210_i2s_rates {
+	HII2S_FS_RATE_8KHZ = 0,
+	HII2S_FS_RATE_16KHZ = 1,
+	HII2S_FS_RATE_32KHZ = 2,
+	HII2S_FS_RATE_48KHZ = 4,
+	HII2S_FS_RATE_96KHZ = 5,
+	HII2S_FS_RATE_192KHZ = 6,
+};
+
+#define HII2S_I2S_CFG				0x10
+
+#define HII2S_I2S_CFG__S2_IF_TX_EN					BIT(31)
+#define HII2S_I2S_CFG__S2_IF_RX_EN					BIT(30)
+#define HII2S_I2S_CFG__S2_FRAME_MODE					BIT(29)
+#define HII2S_I2S_CFG__S2_MST_SLV					BIT(28)
+#define HII2S_I2S_CFG__S2_LRCK_MODE					BIT(27)
+#define HII2S_I2S_CFG__S2_CHNNL_MODE					BIT(26)
+#define HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT			24
+#define HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK			3
+#define HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT				22
+#define HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK				3
+#define HII2S_I2S_CFG__S2_TX_CLK_SEL					BIT(21)
+#define HII2S_I2S_CFG__S2_RX_CLK_SEL					BIT(20)
+#define HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT				BIT(19)
+#define HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT				16
+#define HII2S_I2S_CFG__S2_FUNC_MODE_MASK				7
+#define HII2S_I2S_CFG__S1_IF_TX_EN					BIT(15)
+#define HII2S_I2S_CFG__S1_IF_RX_EN					BIT(14)
+#define HII2S_I2S_CFG__S1_FRAME_MODE					BIT(13)
+#define HII2S_I2S_CFG__S1_MST_SLV					BIT(12)
+#define HII2S_I2S_CFG__S1_LRCK_MODE					BIT(11)
+#define HII2S_I2S_CFG__S1_CHNNL_MODE					BIT(10)
+#define HII2S_I2S_CFG__S1_CODEC_IO_WORDLENGTH_SHIFT			8
+#define HII2S_I2S_CFG__S1_CODEC_IO_WORDLENGTH_MASK			3
+#define HII2S_I2S_CFG__S1_DIRECT_LOOP_SHIFT				6
+#define HII2S_I2S_CFG__S1_DIRECT_LOOP_MASK				3
+#define HII2S_I2S_CFG__S1_TX_CLK_SEL					BIT(5)
+#define HII2S_I2S_CFG__S1_RX_CLK_SEL					BIT(4)
+#define HII2S_I2S_CFG__S1_CODEC_DATA_FORMAT				BIT(3)
+#define HII2S_I2S_CFG__S1_FUNC_MODE_SHIFT				0
+#define HII2S_I2S_CFG__S1_FUNC_MODE_MASK				7
+
+enum hi6210_i2s_formats {
+	HII2S_FORMAT_I2S,
+	HII2S_FORMAT_PCM_STD,
+	HII2S_FORMAT_PCM_USER,
+	HII2S_FORMAT_LEFT_JUST,
+	HII2S_FORMAT_RIGHT_JUST,
+};
+
+#define HII2S_DIG_FILTER_MODULE_CFG		0x14
+
+#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_GAIN_SHIFT		28
+#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_GAIN_MASK		3
+#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN4_MUTE		BIT(27)
+#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN3_MUTE		BIT(26)
+#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE		BIT(25)
+#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN1_MUTE		BIT(24)
+#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_GAIN_SHIFT		20
+#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_GAIN_MASK		3
+#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN4_MUTE		BIT(19)
+#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN3_MUTE		BIT(18)
+#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE		BIT(17)
+#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN1_MUTE		BIT(16)
+#define HII2S_DIG_FILTER_MODULE_CFG__SW_DACR_SDM_DITHER			BIT(9)
+#define HII2S_DIG_FILTER_MODULE_CFG__SW_DACL_SDM_DITHER			BIT(8)
+#define HII2S_DIG_FILTER_MODULE_CFG__LM_CODEC_DAC2ADC_SHIFT		4
+#define HII2S_DIG_FILTER_MODULE_CFG__LM_CODEC_DAC2ADC_MASK		7
+#define HII2S_DIG_FILTER_MODULE_CFG__RM_CODEC_DAC2ADC_SHIFT		0
+#define HII2S_DIG_FILTER_MODULE_CFG__RM_CODEC_DAC2ADC_MASK		7
+
+enum hi6210_gains {
+	HII2S_GAIN_100PC,
+	HII2S_GAIN_50PC,
+	HII2S_GAIN_25PC,
+};
+
+#define HII2S_MUX_TOP_MODULE_CFG		0x18
+
+#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_GAIN_SHIFT		14
+#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_GAIN_MASK		3
+#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE		BIT(13)
+#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE		BIT(12)
+#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_GAIN_SHIFT		10
+#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_GAIN_MASK			3
+#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE			BIT(9)
+#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE			BIT(8)
+#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_RDY				BIT(6)
+#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_MODE_SHIFT			4
+#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_MODE_MASK			3
+#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_RDY			BIT(3)
+#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_MODE_SHIFT		0
+#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_MODE_MASK		7
+
+enum hi6210_s2_src_mode {
+	HII2S_S2_SRC_MODE_3,
+	HII2S_S2_SRC_MODE_12,
+	HII2S_S2_SRC_MODE_6,
+	HII2S_S2_SRC_MODE_2,
+};
+
+enum hi6210_voice_dlink_src_mode {
+	HII2S_VOICE_DL_SRC_MODE_12 = 1,
+	HII2S_VOICE_DL_SRC_MODE_6,
+	HII2S_VOICE_DL_SRC_MODE_2,
+	HII2S_VOICE_DL_SRC_MODE_3,
+};
+
+#define HII2S_ADC_PGA_CFG			0x1c
+#define HII2S_S1_INPUT_PGA_CFG			0x20
+#define HII2S_S2_INPUT_PGA_CFG			0x24
+#define HII2S_ST_DL_PGA_CFG			0x28
+#define HII2S_VOICE_SIDETONE_DLINK_PGA_CFG	0x2c
+#define HII2S_APB_AFIFO_CFG_1			0x30
+#define HII2S_APB_AFIFO_CFG_2			0x34
+#define HII2S_ST_DL_FIFO_TH_CFG			0x38
+
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT			24
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK			0x1f
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT			16
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK			0x1f
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT			8
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK			0x1f
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT			0
+#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK			0x1f
+
+#define HII2S_STEREO_UPLINK_FIFO_TH_CFG		0x3c
+#define HII2S_VOICE_UPLINK_FIFO_TH_CFG		0x40
+#define HII2S_CODEC_IRQ_MASK			0x44
+#define HII2S_CODEC_IRQ				0x48
+#define HII2S_DACL_AGC_CFG_1			0x4c
+#define HII2S_DACL_AGC_CFG_2			0x50
+#define HII2S_DACR_AGC_CFG_1			0x54
+#define HII2S_DACR_AGC_CFG_2			0x58
+#define HII2S_DMIC_SIF_CFG			0x5c
+#define HII2S_MISC_CFG				0x60
+
+#define HII2S_MISC_CFG__THIRDMD_DLINK_TEST_SEL				BIT(17)
+#define HII2S_MISC_CFG__THIRDMD_DLINK_DIN_SEL				BIT(16)
+#define HII2S_MISC_CFG__S3_DOUT_RIGHT_SEL				BIT(14)
+#define HII2S_MISC_CFG__S3_DOUT_LEFT_SEL				BIT(13)
+#define HII2S_MISC_CFG__S3_DIN_TEST_SEL					BIT(12)
+#define HII2S_MISC_CFG__VOICE_DLINK_SRC_UP_DOUT_VLD_SEL			BIT(8)
+#define HII2S_MISC_CFG__VOICE_DLINK_TEST_SEL				BIT(7)
+#define HII2S_MISC_CFG__VOICE_DLINK_DIN_SEL				BIT(6)
+#define HII2S_MISC_CFG__ST_DL_TEST_SEL					BIT(4)
+#define HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL				BIT(3)
+#define HII2S_MISC_CFG__S2_DOUT_TEST_SEL				BIT(2)
+#define HII2S_MISC_CFG__S1_DOUT_TEST_SEL				BIT(1)
+#define HII2S_MISC_CFG__S2_DOUT_LEFT_SEL				BIT(0)
+
+#define HII2S_S2_SRC_CFG			0x64
+#define HII2S_MEM_CFG				0x68
+#define HII2S_THIRDMD_PCM_PGA_CFG		0x6c
+#define HII2S_THIRD_MODEM_FIFO_TH		0x70
+#define HII2S_S3_ANTI_FREQ_JITTER_TX_INC_CNT	0x74
+#define HII2S_S3_ANTI_FREQ_JITTER_TX_DEC_CNT	0x78
+#define HII2S_S3_ANTI_FREQ_JITTER_RX_INC_CNT	0x7c
+#define HII2S_S3_ANTI_FREQ_JITTER_RX_DEC_CNT	0x80
+#define HII2S_ANTI_FREQ_JITTER_EN		0x84
+#define HII2S_CLK_SEL				0x88
+
+/* 0 = BT owns the i2s */
+#define HII2S_CLK_SEL__I2S_BT_FM_SEL					BIT(0)
+/* 0 = internal source, 1 = ext */
+#define HII2S_CLK_SEL__EXT_12_288MHZ_SEL				BIT(1)
+
+
+#define HII2S_THIRDMD_DLINK_CHANNEL		0xe8
+#define HII2S_THIRDMD_ULINK_CHANNEL		0xec
+#define HII2S_VOICE_DLINK_CHANNEL		0xf0
+
+/* shovel data in here for playback */
+#define HII2S_ST_DL_CHANNEL			0xf4
+#define HII2S_STEREO_UPLINK_CHANNEL		0xf8
+#define HII2S_VOICE_UPLINK_CHANNEL		0xfc
+
+#endif/* _HI6210_I2S_H */
-- 
2.7.4

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

* [PATCH 3/3 v4] arm64: dts: hi6220: Add k3-dma and i2s/hdmi audio support
  2017-03-31 22:05 [PATCH 0/3 v4] HiKey i2s bindings, driver and dts changes John Stultz
  2017-03-31 22:05 ` [PATCH 1/3 v4] ASoC: add hi6210-i2s DT bindings John Stultz
  2017-03-31 22:06 ` [PATCH 2/3 v4] ASoC: hisilicon: Add hi6210 i2s audio driver John Stultz
@ 2017-03-31 22:06 ` John Stultz
  2 siblings, 0 replies; 8+ messages in thread
From: John Stultz @ 2017-03-31 22:06 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Zhangfei Gao, Jingoo Han, Krzysztof Kozlowski,
	Maxime Ripard, Vinod Koul, Dan Williams, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Wei Xu, Rob Herring,
	Andy Green

Add entry for k3-dma driver and i2s/hdmi audio devices.

This enables HDMI audio output.

Cc: Zhangfei Gao <zhangfei.gao@linaro.org>
Cc: Jingoo Han <jg1.han@samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Wei Xu <xuwei5@hisilicon.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Andy Green <andy@warmcat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
v2:
* Split core i2s entry into dtsi and hdmi specific bits into
  hikey dts
v4:
* Rework simple-card to use many-dai-links method, as
  there may be other links in the future
---
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 16 ++++++++++++++++
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi      | 26 ++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index dba3c13..81a3ce1 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -406,6 +406,21 @@
 			};
 		};
 	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "hikey-hdmi";
+
+		simple-audio-card,dai-link@0 {          /* I2S - HDMI */
+			format = "i2s";
+			cpu {
+				sound-dai = <&i2s0 0>;
+			};
+			codec {
+				sound-dai = <&adv7533>;
+			};
+		};
+	};
 };
 
 &uart2 {
@@ -446,6 +461,7 @@
 		interrupts = <1 2>;
 		pd-gpio = <&gpio0 4 0>;
 		adi,dsi-lanes = <4>;
+		#sound-dai-cells = <0>;
 
 		port {
 			adv7533_in: endpoint {
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 470461d..9033f5a 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -332,6 +332,19 @@
 			status = "disabled";
 		};
 
+		dma0: dma@f7370000 {
+			compatible = "hisilicon,k3-dma-1.0";
+			reg = <0x0 0xf7370000 0x0 0x1000>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+			dma-requests = <32>;
+			interrupts = <0 84 4>;
+			clocks = <&sys_ctrl HI6220_EDMAC_ACLK>;
+			dma-no-cci;
+			dma-type = "hi6220_dma";
+			status = "ok";
+		};
+
 		dual_timer0: timer@f8008000 {
 			compatible = "arm,sp804", "arm,primecell";
 			reg = <0x0 0xf8008000 0x0 0x1000>;
@@ -831,6 +844,19 @@
 			#thermal-sensor-cells = <1>;
 		};
 
+		i2s0: i2s@f7118000{
+			compatible = "hisilicon,hi6210-i2s";
+			reg = <0x0 0xf7118000 0x0 0x8000>; /* i2s unit */
+			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; /* 155 "DigACodec_intr"-32 */
+			clocks = <&sys_ctrl HI6220_DACODEC_PCLK>,
+				 <&sys_ctrl HI6220_BBPPLL0_DIV>;
+			clock-names = "dacodec", "i2s-base";
+			dmas = <&dma0 15 &dma0 14>;
+			dma-names = "rx", "tx";
+			hisilicon,sysctrl-syscon = <&sys_ctrl>;
+			#sound-dai-cells = <1>;
+		};
+
 		thermal-zones {
 
 			cls0: cls0 {
-- 
2.7.4

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

* Re: [PATCH 1/3 v4] ASoC: add hi6210-i2s  DT bindings
  2017-03-31 22:05 ` [PATCH 1/3 v4] ASoC: add hi6210-i2s DT bindings John Stultz
@ 2017-04-10 18:13   ` Mark Brown
  2017-04-10 18:37     ` John Stultz
  0 siblings, 1 reply; 8+ messages in thread
From: Mark Brown @ 2017-04-10 18:13 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Zhangfei Gao, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Wei Xu, Rob Herring, Andy Green, Dave Long, Guodong Xu

[-- Attachment #1: Type: text/plain, Size: 214 bytes --]

On Fri, Mar 31, 2017 at 03:05:59PM -0700, John Stultz wrote:

> +- #sound-dai-cells: Should be set to 1 (for multi-dai)

Please submit a followup patch documenting what these mean, at least for
what's in the code.

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

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

* Re: [PATCH 1/3 v4] ASoC: add hi6210-i2s DT bindings
  2017-04-10 18:13   ` Mark Brown
@ 2017-04-10 18:37     ` John Stultz
  2017-04-10 18:41       ` Mark Brown
  0 siblings, 1 reply; 8+ messages in thread
From: John Stultz @ 2017-04-10 18:37 UTC (permalink / raw)
  To: Mark Brown
  Cc: lkml, Zhangfei Gao, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Wei Xu, Rob Herring, Andy Green, Dave Long, Guodong Xu

On Mon, Apr 10, 2017 at 11:13 AM, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Mar 31, 2017 at 03:05:59PM -0700, John Stultz wrote:
>
>> +- #sound-dai-cells: Should be set to 1 (for multi-dai)
>
> Please submit a followup patch documenting what these mean, at least for
> what's in the code.

So just to make sure I understand, you want documentation on what the
sound-dia-cells index maps to? (ie 0 to S2, as that's the only one
supported right now?) Or something else?

thanks
-john

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

* Re: [PATCH 2/3 v4] ASoC: hisilicon: Add hi6210 i2s audio driver
  2017-03-31 22:06 ` [PATCH 2/3 v4] ASoC: hisilicon: Add hi6210 i2s audio driver John Stultz
@ 2017-04-10 18:39   ` Mark Brown
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Brown @ 2017-04-10 18:39 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Andy Green, Zhangfei Gao, Liam Girdwood, Jaroslav Kysela,
	Takashi Iwai, Wei Xu, Rob Herring, Andy Green, Dave Long,
	Guodong Xu

[-- Attachment #1: Type: text/plain, Size: 1142 bytes --]

On Fri, Mar 31, 2017 at 03:06:00PM -0700, John Stultz wrote:

Looks mostly good, a few more minor issues, please send incremental
fixes for these:

> +
> +	switch (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) {

> +	default:
> +		WARN_ONCE(1, "Invalid i2s->fmt MASTER_MASK. This shouldn't happen\n");
> +	}

It should still return an error just in case.

> +	switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {

> +	default:
> +		WARN_ONCE(1, "Invalid i2s->fmt FORMAT_MASK. This shouldn't happen\n");
> +	}

Similarly.

> +	default:
> +		val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
> +		val &= ~HII2S_I2S_CFG__S2_FRAME_MODE;
> +		hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
> +	}

Missing break.

> +	ret = snd_soc_register_component(&pdev->dev, &hi6210_i2s_i2s_comp,
> +					 &i2s->dai, 1);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to register dai\n");
> +		return ret;
> +	}

devm_snd_soc_register_component()

> +static int hi6210_i2s_remove(struct platform_device *pdev)
> +{
> +	snd_soc_unregister_component(&pdev->dev);
> +	dev_set_drvdata(&pdev->dev, NULL);

The core will set the driver data to NULL, though it shouldn't be
needed.

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

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

* Re: [PATCH 1/3 v4] ASoC: add hi6210-i2s DT bindings
  2017-04-10 18:37     ` John Stultz
@ 2017-04-10 18:41       ` Mark Brown
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Brown @ 2017-04-10 18:41 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Zhangfei Gao, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Wei Xu, Rob Herring, Andy Green, Dave Long, Guodong Xu

[-- Attachment #1: Type: text/plain, Size: 628 bytes --]

On Mon, Apr 10, 2017 at 11:37:00AM -0700, John Stultz wrote:
> On Mon, Apr 10, 2017 at 11:13 AM, Mark Brown <broonie@kernel.org> wrote:
> > On Fri, Mar 31, 2017 at 03:05:59PM -0700, John Stultz wrote:

> >> +- #sound-dai-cells: Should be set to 1 (for multi-dai)

> > Please submit a followup patch documenting what these mean, at least for
> > what's in the code.

> So just to make sure I understand, you want documentation on what the
> sound-dia-cells index maps to? (ie 0 to S2, as that's the only one

*dai*

> supported right now?) Or something else?

Yes, that.   People need to be able to tell what the binding means.


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

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

end of thread, other threads:[~2017-04-10 18:41 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-31 22:05 [PATCH 0/3 v4] HiKey i2s bindings, driver and dts changes John Stultz
2017-03-31 22:05 ` [PATCH 1/3 v4] ASoC: add hi6210-i2s DT bindings John Stultz
2017-04-10 18:13   ` Mark Brown
2017-04-10 18:37     ` John Stultz
2017-04-10 18:41       ` Mark Brown
2017-03-31 22:06 ` [PATCH 2/3 v4] ASoC: hisilicon: Add hi6210 i2s audio driver John Stultz
2017-04-10 18:39   ` Mark Brown
2017-03-31 22:06 ` [PATCH 3/3 v4] arm64: dts: hi6220: Add k3-dma and i2s/hdmi audio support John Stultz

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).