Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1405208 > unrolled thread

[PATCH 0/4 v7] Add I2S audio support for ARC AXS10x boards

Started byJose Abreu <Jose.Abreu@synopsys.com>
First post2016-05-23 12:10 +0200
Last post2016-05-23 23:40 +0200
Articles 13 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/4 v7] Add I2S audio support for ARC AXS10x boards Jose Abreu <Jose.Abreu@synopsys.com> - 2016-05-23 12:10 +0200
    [PATCH 2/4 v7] ASoC: dwc: Do not use devm_clk_get() if using platform data Jose Abreu <Jose.Abreu@synopsys.com> - 2016-05-23 12:10 +0200
      Re: [PATCH 2/4 v7] ASoC: dwc: Do not use devm_clk_get() if using  platform data Mark Brown <broonie@kernel.org> - 2016-05-23 19:00 +0200
    [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Jose Abreu <Jose.Abreu@synopsys.com> - 2016-05-23 12:10 +0200
      Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Mark Brown <broonie@kernel.org> - 2016-05-24 18:50 +0200
        Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Jose Abreu <Jose.Abreu@synopsys.com> - 2016-05-24 19:10 +0200
          Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Mark Brown <broonie@kernel.org> - 2016-05-24 20:00 +0200
            Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Jose Abreu <Jose.Abreu@synopsys.com> - 2016-05-25 12:20 +0200
              Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Mark Brown <broonie@kernel.org> - 2016-05-25 12:20 +0200
                Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Jose Abreu <Jose.Abreu@synopsys.com> - 2016-05-25 12:50 +0200
                  Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension Mark Brown <broonie@kernel.org> - 2016-05-25 15:50 +0200
    [PATCH 4/4 v7] ASoC: dwc: Add irq parameter to DOCUMENTATION Jose Abreu <Jose.Abreu@synopsys.com> - 2016-05-23 12:10 +0200
      Re: [PATCH 4/4 v7] ASoC: dwc: Add irq parameter to DOCUMENTATION Rob Herring <robh@kernel.org> - 2016-05-23 23:40 +0200

#1405208 — [PATCH 0/4 v7] Add I2S audio support for ARC AXS10x boards

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2016-05-23 12:10 +0200
Subject[PATCH 0/4 v7] Add I2S audio support for ARC AXS10x boards
Message-ID<rBUY9-4uz-3@gated-at.bofh.it>
ARC AXS10x platforms consist of a mainboard with several peripherals.
One of those peripherals is an HDMI output port controlled by the ADV7511
transmitter.

This patch set adds I2S audio for the AXS10x platform.

NOTE:
Although the mainline I2S driver uses ALSA DMA engine, this controller
can be built without DMA support so it was necessary to add this
custom platform driver so that HDMI audio works in AXS boards.

Changes v6 -> v7:
* Discard the use of memcpy
* Report IRQ_HANDLED only when there is an IRQ
* Use interrupts to check if PIO mode is in use
* Unmask interrupts only when in PIO mode
* Remove empty functions

Changes v5 -> v6:
* Use SNDRV_DMA_TYPE_CONTINUOUS

Changes v4 -> v5:
* Resolve undefined references when compiling as module
* Dropped adv7511 audio patches
* Use DMA properties in I2S to check which mode to use: PIO or DMA (as suggested by Lars-Peter Clausen)

Changes v3 -> v4:
* Reintroduced custom PCM driver (see note below)
* Use DT boolean to switch between ALSA DMA engine PCM or custom PCM
* Use fifo depth to program I2S FCR
* Update I2S documentation

Changes v2 -> v3:
* Removed pll_config functions (as suggested by Alexey Brodkin)
* Removed HDMI start at adv7511_core (as suggested by Archit Taneja)
* Use NOP functions for adv7511_audio (as suggested by Archit Taneja)
* Added adv7511_audio_exit() function (as suggested by Archit Taneja)
* Moved adv7511 to its own folder (as suggested by Archit Taneja)
* Separated file rename of adv7511_core (as suggested by Emil Velikov)
* Compile adv7511 as module if ALSA SoC is compiled as module
* Load adv7511 audio only if declared in device tree (as suggested by Laurent Pinchart)
* Dropped custom platform driver, using now ALSA DMA engine
* Dropped IRQ handler for I2S

Changes v1 -> v2:
* DT bindings moved to separate patch (as suggested by Alexey Brodkin)
* Removed defconfigs entries (as suggested by Alexey Brodkin)


Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: alsa-devel@alsa-project.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

Jose Abreu (4):
  ASoC: dwc: Add helper functions to disable/enable irqs
  ASoC: dwc: Do not use devm_clk_get() if using platform data
  ASoC: dwc: Add PIO PCM extension
  ASoC: dwc: Add irq parameter to DOCUMENTATION

 .../devicetree/bindings/sound/designware-i2s.txt   |   4 +
 sound/soc/dwc/Kconfig                              |   9 +
 sound/soc/dwc/Makefile                             |   5 +-
 sound/soc/dwc/designware_i2s.c                     | 229 ++++++++++-----------
 sound/soc/dwc/designware_pcm.c                     | 220 ++++++++++++++++++++
 sound/soc/dwc/local.h                              | 122 +++++++++++
 6 files changed, 467 insertions(+), 122 deletions(-)
 create mode 100644 sound/soc/dwc/designware_pcm.c
 create mode 100644 sound/soc/dwc/local.h

-- 
1.9.1

[toc] | [next] | [standalone]


#1405209 — [PATCH 2/4 v7] ASoC: dwc: Do not use devm_clk_get() if using platform data

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2016-05-23 12:10 +0200
Subject[PATCH 2/4 v7] ASoC: dwc: Do not use devm_clk_get() if using platform data
Message-ID<rBUY9-4uz-15@gated-at.bofh.it>
In reply to#1405208
When using platform data the devm_clk_get() function is
called causing a probe failure if the clock is not
declared. As we can pass the clock handler by platform
data call only devm_clk_get() when platform data is not
used.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: alsa-devel@alsa-project.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---

This patch was only introduced in v7.

 sound/soc/dwc/designware_i2s.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 4c4f0dc..a97be8e 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -690,15 +690,16 @@ static int dw_i2s_probe(struct platform_device *pdev)
 				dev_err(&pdev->dev, "no clock configure method\n");
 				return -ENODEV;
 			}
-		}
-		dev->clk = devm_clk_get(&pdev->dev, clk_id);
+		} else {
+			dev->clk = devm_clk_get(&pdev->dev, clk_id);
 
-		if (IS_ERR(dev->clk))
-			return PTR_ERR(dev->clk);
+			if (IS_ERR(dev->clk))
+				return PTR_ERR(dev->clk);
 
-		ret = clk_prepare_enable(dev->clk);
-		if (ret < 0)
-			return ret;
+			ret = clk_prepare_enable(dev->clk);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
 	dev_set_drvdata(&pdev->dev, dev);
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1405515 — Re: [PATCH 2/4 v7] ASoC: dwc: Do not use devm_clk_get() if using platform data

FromMark Brown <broonie@kernel.org>
Date2016-05-23 19:00 +0200
SubjectRe: [PATCH 2/4 v7] ASoC: dwc: Do not use devm_clk_get() if using platform data
Message-ID<rC1mW-8ml-13@gated-at.bofh.it>
In reply to#1405209

[Multipart message — attachments visible in raw view] — view raw

On Mon, May 23, 2016 at 11:02:23AM +0100, Jose Abreu wrote:

> When using platform data the devm_clk_get() function is
> called causing a probe failure if the clock is not
> declared. As we can pass the clock handler by platform
> data call only devm_clk_get() when platform data is not
> used.

No, this is broken - if the device needs a clock the device needs a
clock and clock names should be static rather than passed in via
platform data (indeed NULL is a perfectly valid clock name).  The system
integation should map in a clock as needed, if it's just a fixed crystal
or something then just register a fixed clock and connect it up.

[toc] | [prev] | [next] | [standalone]


#1405210 — [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2016-05-23 12:10 +0200
Subject[PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rBUY9-4uz-13@gated-at.bofh.it>
In reply to#1405208
A PCM extension was added to I2S driver so that audio
samples are transferred using PIO mode.

The PCM supports two channels @ 16 or 32 bits with rates
32k, 44.1k and 48k.

Although the mainline I2S driver uses ALSA DMA engine the
I2S controller can be built without DMA support, therefore
this is the reason why this extension was added.

The selection between the use of DMA engine or PIO mode
is detected by declaring or not the interrupt parameters
in the DT and using Kconfig.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: alsa-devel@alsa-project.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---

Changes v6 -> v7:
* Discard the use of memcpy
* Report IRQ_HANDLED only when there is an IRQ
* Use interrupts to check if PIO mode is in use
* Unmask interrupts only when in PIO mode
* Remove empty functions

Changes v5 -> v6:
* Use SNDRV_DMA_TYPE_CONTINUOUS

Changes v4 -> v5:
* Resolve undefined references when compiling as module
* Use DMA properties in I2S to check which mode to use: PIO or DMA (as suggested by Lars-Peter Clausen)

Changes v3 -> v4:
* Reintroduced custom PCM driver
* Use DT boolean to switch between ALSA DMA engine PCM or custom PCM

Changes v2 -> v3:
* Removed pll_config functions (as suggested by Alexey Brodkin)
* Dropped custom platform driver, using now ALSA DMA engine
* Dropped IRQ handler for I2S

No changes v1 -> v2.

 sound/soc/dwc/Kconfig          |   9 ++
 sound/soc/dwc/Makefile         |   5 +-
 sound/soc/dwc/designware_i2s.c | 148 ++++++++++++---------------
 sound/soc/dwc/designware_pcm.c | 220 +++++++++++++++++++++++++++++++++++++++++
 sound/soc/dwc/local.h          | 122 +++++++++++++++++++++++
 5 files changed, 415 insertions(+), 89 deletions(-)
 create mode 100644 sound/soc/dwc/designware_pcm.c
 create mode 100644 sound/soc/dwc/local.h

diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
index d50e085..c6fd95f 100644
--- a/sound/soc/dwc/Kconfig
+++ b/sound/soc/dwc/Kconfig
@@ -7,4 +7,13 @@ config SND_DESIGNWARE_I2S
 	 Synopsys desigwnware I2S device. The device supports upto
 	 maximum of 8 channels each for play and record.
 
+config SND_DESIGNWARE_PCM
+	bool "PCM PIO extension for I2S driver"
+	depends on SND_DESIGNWARE_I2S
+	help
+	 Say Y or N if you want to add a custom ALSA extension that registers
+	 a PCM and uses PIO to transfer data.
+
+	 This functionality is specially suited for I2S devices that don't have
+	 DMA support.
 
diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile
index 319371f..11ea966 100644
--- a/sound/soc/dwc/Makefile
+++ b/sound/soc/dwc/Makefile
@@ -1,3 +1,4 @@
 # SYNOPSYS Platform Support
-obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o
-
+obj-$(CONFIG_SND_DESIGNWARE_I2S) += dwc_i2s.o
+dwc_i2s-y := designware_i2s.o
+dwc_i2s-$(CONFIG_SND_DESIGNWARE_PCM) += designware_pcm.o
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index a97be8e..d4c3811 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -24,90 +24,7 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/dmaengine_pcm.h>
-
-/* common register for all channel */
-#define IER		0x000
-#define IRER		0x004
-#define ITER		0x008
-#define CER		0x00C
-#define CCR		0x010
-#define RXFFR		0x014
-#define TXFFR		0x018
-
-/* I2STxRxRegisters for all channels */
-#define LRBR_LTHR(x)	(0x40 * x + 0x020)
-#define RRBR_RTHR(x)	(0x40 * x + 0x024)
-#define RER(x)		(0x40 * x + 0x028)
-#define TER(x)		(0x40 * x + 0x02C)
-#define RCR(x)		(0x40 * x + 0x030)
-#define TCR(x)		(0x40 * x + 0x034)
-#define ISR(x)		(0x40 * x + 0x038)
-#define IMR(x)		(0x40 * x + 0x03C)
-#define ROR(x)		(0x40 * x + 0x040)
-#define TOR(x)		(0x40 * x + 0x044)
-#define RFCR(x)		(0x40 * x + 0x048)
-#define TFCR(x)		(0x40 * x + 0x04C)
-#define RFF(x)		(0x40 * x + 0x050)
-#define TFF(x)		(0x40 * x + 0x054)
-
-/* I2SCOMPRegisters */
-#define I2S_COMP_PARAM_2	0x01F0
-#define I2S_COMP_PARAM_1	0x01F4
-#define I2S_COMP_VERSION	0x01F8
-#define I2S_COMP_TYPE		0x01FC
-
-/*
- * Component parameter register fields - define the I2S block's
- * configuration.
- */
-#define	COMP1_TX_WORDSIZE_3(r)	(((r) & GENMASK(27, 25)) >> 25)
-#define	COMP1_TX_WORDSIZE_2(r)	(((r) & GENMASK(24, 22)) >> 22)
-#define	COMP1_TX_WORDSIZE_1(r)	(((r) & GENMASK(21, 19)) >> 19)
-#define	COMP1_TX_WORDSIZE_0(r)	(((r) & GENMASK(18, 16)) >> 16)
-#define	COMP1_TX_CHANNELS(r)	(((r) & GENMASK(10, 9)) >> 9)
-#define	COMP1_RX_CHANNELS(r)	(((r) & GENMASK(8, 7)) >> 7)
-#define	COMP1_RX_ENABLED(r)	(((r) & BIT(6)) >> 6)
-#define	COMP1_TX_ENABLED(r)	(((r) & BIT(5)) >> 5)
-#define	COMP1_MODE_EN(r)	(((r) & BIT(4)) >> 4)
-#define	COMP1_FIFO_DEPTH_GLOBAL(r)	(((r) & GENMASK(3, 2)) >> 2)
-#define	COMP1_APB_DATA_WIDTH(r)	(((r) & GENMASK(1, 0)) >> 0)
-
-#define	COMP2_RX_WORDSIZE_3(r)	(((r) & GENMASK(12, 10)) >> 10)
-#define	COMP2_RX_WORDSIZE_2(r)	(((r) & GENMASK(9, 7)) >> 7)
-#define	COMP2_RX_WORDSIZE_1(r)	(((r) & GENMASK(5, 3)) >> 3)
-#define	COMP2_RX_WORDSIZE_0(r)	(((r) & GENMASK(2, 0)) >> 0)
-
-/* Number of entries in WORDSIZE and DATA_WIDTH parameter registers */
-#define	COMP_MAX_WORDSIZE	(1 << 3)
-#define	COMP_MAX_DATA_WIDTH	(1 << 2)
-
-#define MAX_CHANNEL_NUM		8
-#define MIN_CHANNEL_NUM		2
-
-union dw_i2s_snd_dma_data {
-	struct i2s_dma_data pd;
-	struct snd_dmaengine_dai_dma_data dt;
-};
-
-struct dw_i2s_dev {
-	void __iomem *i2s_base;
-	struct clk *clk;
-	int active;
-	unsigned int capability;
-	unsigned int quirks;
-	unsigned int i2s_reg_comp1;
-	unsigned int i2s_reg_comp2;
-	struct device *dev;
-	u32 ccr;
-	u32 xfer_resolution;
-	u32 fifo_th;
-
-	/* data related to DMA transfers b/w i2s and DMAC */
-	union dw_i2s_snd_dma_data play_dma_data;
-	union dw_i2s_snd_dma_data capture_dma_data;
-	struct i2s_clk_config_data config;
-	int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
-};
+#include "local.h"
 
 static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
 {
@@ -181,13 +98,49 @@ static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
 	}
 }
 
+static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
+{
+	struct dw_i2s_dev *dev = dev_id;
+	bool irq_valid = false;
+	u32 isr[4];
+	int i;
+
+	for (i = 0; i < 4; i++)
+		isr[i] = i2s_read_reg(dev->i2s_base, ISR(i));
+
+	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_PLAYBACK);
+	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_CAPTURE);
+
+	for (i = 0; i < 4; i++) {
+		if (isr[i] & 0x33)
+			irq_valid = true;
+
+		/*
+		 * Check if TX fifo is empty. If empty fill FIFO with samples
+		 * NOTE: Only two channels supported
+		 */
+		if ((isr[i] & 0x10) && (i == 0))
+			dw_pcm_push_tx(dev);
+
+		/* Error Handling */
+		if (isr[i] & 0x20)
+			dev_err(dev->dev, "TX overrun (ch_id=%d)\n", i);
+		if (isr[i] & 0x02)
+			dev_err(dev->dev, "RX overrun (ch_id=%d)\n", i);
+	}
+
+	return irq_valid ? IRQ_HANDLED : IRQ_NONE;
+}
+
 static void i2s_start(struct dw_i2s_dev *dev,
 		      struct snd_pcm_substream *substream)
 {
 	struct i2s_clk_config_data *config = &dev->config;
 
 	i2s_write_reg(dev->i2s_base, IER, 1);
-	i2s_enable_irqs(dev, substream->stream, config->chan_nr);
+
+	if (dev->use_pio)
+		i2s_enable_irqs(dev, substream->stream, config->chan_nr);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		i2s_write_reg(dev->i2s_base, ITER, 1);
@@ -640,7 +593,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
 	const struct i2s_platform_data *pdata = pdev->dev.platform_data;
 	struct dw_i2s_dev *dev;
 	struct resource *res;
-	int ret;
+	int ret, irq;
 	struct snd_soc_dai_driver *dw_i2s_dai;
 	const char *clk_id;
 
@@ -665,6 +618,19 @@ static int dw_i2s_probe(struct platform_device *pdev)
 
 	dev->dev = &pdev->dev;
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq >= 0) {
+		dev_dbg(&pdev->dev, "using PIO mode\n");
+		dev->use_pio = true;
+
+		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
+				pdev->name, dev);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "failed to request irq\n");
+			return ret;
+		}
+	}
+
 	dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
 	dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
 	if (pdata) {
@@ -710,14 +676,22 @@ static int dw_i2s_probe(struct platform_device *pdev)
 		goto err_clk_disable;
 	}
 
-	if (!pdata) {
+	if (!pdata && !dev->use_pio) {
 		ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
 		if (ret) {
 			dev_err(&pdev->dev,
 				"Could not register PCM: %d\n", ret);
 			goto err_clk_disable;
 		}
+	} else if (dev->use_pio) {
+		ret = dw_pcm_register(pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Could not register PIO PCM: %d\n", ret);
+			goto err_clk_disable;
+		}
 	}
+
 	pm_runtime_enable(&pdev->dev);
 	return 0;
 
diff --git a/sound/soc/dwc/designware_pcm.c b/sound/soc/dwc/designware_pcm.c
new file mode 100644
index 0000000..d995b50
--- /dev/null
+++ b/sound/soc/dwc/designware_pcm.c
@@ -0,0 +1,220 @@
+/*
+ * ALSA SoC Synopsys PIO PCM for I2S driver
+ *
+ * sound/soc/dwc/designware_pcm.c
+ *
+ * Copyright (C) 2016 Synopsys
+ * Jose Abreu <joabreu@synopsys.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/rcupdate.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include "local.h"
+
+#define BUFFER_BYTES_MAX	(3 * 2 * 8 * PERIOD_BYTES_MIN)
+#define PERIOD_BYTES_MIN	4096
+#define PERIODS_MIN		2
+
+#define dw_pcm_tx_fn(sample_bits) \
+static unsigned int dw_pcm_tx_##sample_bits(struct dw_i2s_dev *dev, \
+		struct snd_pcm_runtime *runtime, unsigned int tx_ptr, \
+		bool *period_elapsed) \
+{ \
+	const u##sample_bits (*p)[2] = (void *)runtime->dma_area; \
+	unsigned int period_pos = tx_ptr % runtime->period_size; \
+	int i; \
+\
+	for (i = 0; i < dev->fifo_th; i++) { \
+		iowrite32(p[tx_ptr][0], dev->i2s_base + LRBR_LTHR(0)); \
+		iowrite32(p[tx_ptr][1], dev->i2s_base + RRBR_RTHR(0)); \
+		period_pos++; \
+		if (++tx_ptr >= runtime->buffer_size) \
+			tx_ptr = 0; \
+	} \
+	*period_elapsed = period_pos >= runtime->period_size; \
+	return tx_ptr; \
+}
+
+dw_pcm_tx_fn(16);
+dw_pcm_tx_fn(32);
+
+#undef dw_pcm_tx_fn
+
+static const struct snd_pcm_hardware dw_pcm_hardware = {
+	.info = SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER,
+	.rates = SNDRV_PCM_RATE_32000 |
+		SNDRV_PCM_RATE_44100 |
+		SNDRV_PCM_RATE_48000,
+	.rate_min = 32000,
+	.rate_max = 48000,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE |
+		SNDRV_PCM_FMTBIT_S32_LE,
+	.channels_min = 2,
+	.channels_max = 2,
+	.buffer_bytes_max = BUFFER_BYTES_MAX,
+	.period_bytes_min = PERIOD_BYTES_MIN,
+	.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
+	.periods_min = PERIODS_MIN,
+	.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
+	.fifo_size = 16,
+};
+
+void dw_pcm_push_tx(struct dw_i2s_dev *dev)
+{
+	struct snd_pcm_substream *tx_substream;
+	bool tx_active, period_elapsed;
+
+	rcu_read_lock();
+	tx_substream = rcu_dereference(dev->tx_substream);
+	tx_active = tx_substream && snd_pcm_running(tx_substream);
+	if (tx_active) {
+		unsigned int tx_ptr = ACCESS_ONCE(dev->tx_ptr);
+		unsigned int new_tx_ptr = dev->tx_fn(dev, tx_substream->runtime,
+				tx_ptr, &period_elapsed);
+		cmpxchg(&dev->tx_ptr, tx_ptr, new_tx_ptr);
+
+		if (period_elapsed)
+			snd_pcm_period_elapsed(tx_substream);
+	}
+	rcu_read_unlock();
+}
+
+static int dw_pcm_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
+
+	snd_soc_set_runtime_hwparams(substream, &dw_pcm_hardware);
+	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	runtime->private_data = dev;
+
+	return 0;
+}
+
+static int dw_pcm_close(struct snd_pcm_substream *substream)
+{
+	synchronize_rcu();
+	return 0;
+}
+
+static int dw_pcm_hw_params(struct snd_pcm_substream *substream,
+		struct snd_pcm_hw_params *hw_params)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dw_i2s_dev *dev = runtime->private_data;
+	int ret;
+
+	switch (params_channels(hw_params)) {
+	case 2:
+		break;
+	default:
+		dev_err(dev->dev, "invalid channels number\n");
+		return -EINVAL;
+	}
+
+	switch (params_format(hw_params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		dev->tx_fn = dw_pcm_tx_16;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		dev->tx_fn = dw_pcm_tx_32;
+		break;
+	default:
+		dev_err(dev->dev, "invalid format\n");
+		return -EINVAL;
+	}
+
+	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
+		dev_err(dev->dev, "only playback is available\n");
+		return -EINVAL;
+	}
+
+	ret = snd_pcm_lib_malloc_pages(substream,
+			params_buffer_bytes(hw_params));
+	return (ret < 0) ? ret : 0;
+}
+
+static int dw_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static int dw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dw_i2s_dev *dev = runtime->private_data;
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		ACCESS_ONCE(dev->tx_ptr) = 0;
+		rcu_assign_pointer(dev->tx_substream, substream);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		rcu_assign_pointer(dev->tx_substream, NULL);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t dw_pcm_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dw_i2s_dev *dev = runtime->private_data;
+	snd_pcm_uframes_t pos = ACCESS_ONCE(dev->tx_ptr);
+
+	return pos < runtime->buffer_size ? pos : 0;
+}
+
+static int dw_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+	size_t size = dw_pcm_hardware.buffer_bytes_max;
+
+	return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
+			SNDRV_DMA_TYPE_CONTINUOUS,
+			snd_dma_continuous_data(GFP_KERNEL), size, size);
+}
+
+static void dw_pcm_free(struct snd_pcm *pcm)
+{
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static const struct snd_pcm_ops dw_pcm_ops = {
+	.open = dw_pcm_open,
+	.close = dw_pcm_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = dw_pcm_hw_params,
+	.hw_free = dw_pcm_hw_free,
+	.trigger = dw_pcm_trigger,
+	.pointer = dw_pcm_pointer,
+};
+
+static const struct snd_soc_platform_driver dw_pcm_platform = {
+	.pcm_new = dw_pcm_new,
+	.pcm_free = dw_pcm_free,
+	.ops = &dw_pcm_ops,
+};
+
+int dw_pcm_register(struct platform_device *pdev)
+{
+	return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform);
+}
diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h
new file mode 100644
index 0000000..6a8edc7
--- /dev/null
+++ b/sound/soc/dwc/local.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (ST) 2012 Rajeev Kumar (rajeevkumar.linux@gmail.com)
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __DESIGNWARE_LOCAL_H
+#define __DESIGNWARE_LOCAL_H
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/pcm.h>
+#include <sound/designware_i2s.h>
+
+/* common register for all channel */
+#define IER		0x000
+#define IRER		0x004
+#define ITER		0x008
+#define CER		0x00C
+#define CCR		0x010
+#define RXFFR		0x014
+#define TXFFR		0x018
+
+/* I2STxRxRegisters for all channels */
+#define LRBR_LTHR(x)	(0x40 * x + 0x020)
+#define RRBR_RTHR(x)	(0x40 * x + 0x024)
+#define RER(x)		(0x40 * x + 0x028)
+#define TER(x)		(0x40 * x + 0x02C)
+#define RCR(x)		(0x40 * x + 0x030)
+#define TCR(x)		(0x40 * x + 0x034)
+#define ISR(x)		(0x40 * x + 0x038)
+#define IMR(x)		(0x40 * x + 0x03C)
+#define ROR(x)		(0x40 * x + 0x040)
+#define TOR(x)		(0x40 * x + 0x044)
+#define RFCR(x)		(0x40 * x + 0x048)
+#define TFCR(x)		(0x40 * x + 0x04C)
+#define RFF(x)		(0x40 * x + 0x050)
+#define TFF(x)		(0x40 * x + 0x054)
+
+/* I2SCOMPRegisters */
+#define I2S_COMP_PARAM_2	0x01F0
+#define I2S_COMP_PARAM_1	0x01F4
+#define I2S_COMP_VERSION	0x01F8
+#define I2S_COMP_TYPE		0x01FC
+
+/*
+ * Component parameter register fields - define the I2S block's
+ * configuration.
+ */
+#define	COMP1_TX_WORDSIZE_3(r)	(((r) & GENMASK(27, 25)) >> 25)
+#define	COMP1_TX_WORDSIZE_2(r)	(((r) & GENMASK(24, 22)) >> 22)
+#define	COMP1_TX_WORDSIZE_1(r)	(((r) & GENMASK(21, 19)) >> 19)
+#define	COMP1_TX_WORDSIZE_0(r)	(((r) & GENMASK(18, 16)) >> 16)
+#define	COMP1_TX_CHANNELS(r)	(((r) & GENMASK(10, 9)) >> 9)
+#define	COMP1_RX_CHANNELS(r)	(((r) & GENMASK(8, 7)) >> 7)
+#define	COMP1_RX_ENABLED(r)	(((r) & BIT(6)) >> 6)
+#define	COMP1_TX_ENABLED(r)	(((r) & BIT(5)) >> 5)
+#define	COMP1_MODE_EN(r)	(((r) & BIT(4)) >> 4)
+#define	COMP1_FIFO_DEPTH_GLOBAL(r)	(((r) & GENMASK(3, 2)) >> 2)
+#define	COMP1_APB_DATA_WIDTH(r)	(((r) & GENMASK(1, 0)) >> 0)
+
+#define	COMP2_RX_WORDSIZE_3(r)	(((r) & GENMASK(12, 10)) >> 10)
+#define	COMP2_RX_WORDSIZE_2(r)	(((r) & GENMASK(9, 7)) >> 7)
+#define	COMP2_RX_WORDSIZE_1(r)	(((r) & GENMASK(5, 3)) >> 3)
+#define	COMP2_RX_WORDSIZE_0(r)	(((r) & GENMASK(2, 0)) >> 0)
+
+/* Number of entries in WORDSIZE and DATA_WIDTH parameter registers */
+#define	COMP_MAX_WORDSIZE	(1 << 3)
+#define	COMP_MAX_DATA_WIDTH	(1 << 2)
+
+#define MAX_CHANNEL_NUM		8
+#define MIN_CHANNEL_NUM		2
+
+union dw_i2s_snd_dma_data {
+	struct i2s_dma_data pd;
+	struct snd_dmaengine_dai_dma_data dt;
+};
+
+struct dw_i2s_dev {
+	void __iomem *i2s_base;
+	struct clk *clk;
+	int active;
+	unsigned int capability;
+	unsigned int quirks;
+	unsigned int i2s_reg_comp1;
+	unsigned int i2s_reg_comp2;
+	struct device *dev;
+	u32 ccr;
+	u32 xfer_resolution;
+	u32 fifo_th;
+
+	/* data related to DMA transfers b/w i2s and DMAC */
+	union dw_i2s_snd_dma_data play_dma_data;
+	union dw_i2s_snd_dma_data capture_dma_data;
+	struct i2s_clk_config_data config;
+	int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
+
+	/* data related to PIO transfers (TX) */
+	bool use_pio;
+	struct snd_pcm_substream __rcu *tx_substream;
+	unsigned int (*tx_fn)(struct dw_i2s_dev *dev,
+			struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
+			bool *period_elapsed);
+	unsigned int tx_ptr;
+};
+
+#if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM)
+void dw_pcm_push_tx(struct dw_i2s_dev *dev);
+int dw_pcm_register(struct platform_device *pdev);
+#else
+void dw_pcm_push_tx(struct dw_i2s_dev *dev) { }
+int dw_pcm_register(struct platform_device *pdev)
+{
+	return -EINVAL;
+}
+#endif
+
+#endif
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1406280 — Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromMark Brown <broonie@kernel.org>
Date2016-05-24 18:50 +0200
SubjectRe: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rCnGN-5K5-3@gated-at.bofh.it>
In reply to#1405210

[Multipart message — attachments visible in raw view] — view raw

On Mon, May 23, 2016 at 11:02:24AM +0100, Jose Abreu wrote:

> +config SND_DESIGNWARE_PCM
> +	bool "PCM PIO extension for I2S driver"

Why can't this be built as a module?

> +
> +	return irq_valid ? IRQ_HANDLED : IRQ_NONE;

Please write a normal if statement, the ternery operator doesn't help
legibility.

>  static void i2s_start(struct dw_i2s_dev *dev,
>  		      struct snd_pcm_substream *substream)
>  {
>  	struct i2s_clk_config_data *config = &dev->config;
>  
>  	i2s_write_reg(dev->i2s_base, IER, 1);
> -	i2s_enable_irqs(dev, substream->stream, config->chan_nr);
> +
> +	if (dev->use_pio)
> +		i2s_enable_irqs(dev, substream->stream, config->chan_nr);
>  
>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>  		i2s_write_reg(dev->i2s_base, ITER, 1);

That seems wrong, or at least something that should be separate?
Previously we needed interrupts for DMA operation but now we enable
interrupts only if we don't use DMA.  It feels like we want to make the
change for DMA separately if only to make it clear for bisection, are we
100% sure that masking the interrupt won't also mask the DMA request
signals?

> +	irq = platform_get_irq(pdev, 0);
> +	if (irq >= 0) {
> +		dev_dbg(&pdev->dev, "using PIO mode\n");
> +		dev->use_pio = true;
> +
> +		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
> +				pdev->name, dev);
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "failed to request irq\n");
> +			return ret;
> +		}
> +	}

This also seems wrong.  We're forcing PIO if an interrupt is provided
rather than based on DMA being configured which means that if the
interrupt is wired up and happens to be described in DT we'll get worse
performance.  People should be able to just describe the system without
worrying about this, and we might find some other use for the interrupts
in future.  Indeed right now it would probably be reasonable to use the
error interrupts all the time if they're available.

[toc] | [prev] | [next] | [standalone]


#1406293 — Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2016-05-24 19:10 +0200
SubjectRe: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rCo0a-65z-23@gated-at.bofh.it>
In reply to#1406280
Hi Mark,

Thanks for your comments.

On 24-05-2016 17:41, Mark Brown wrote:
> On Mon, May 23, 2016 at 11:02:24AM +0100, Jose Abreu wrote:
>
>> +config SND_DESIGNWARE_PCM
>> +	bool "PCM PIO extension for I2S driver"
> Why can't this be built as a module?

I can change but my intention was to make this PCM a kind of extension to the
driver instead of adding a new module to the system.

>
>> +
>> +	return irq_valid ? IRQ_HANDLED : IRQ_NONE;
> Please write a normal if statement, the ternery operator doesn't help
> legibility.

Ok.

>
>>  static void i2s_start(struct dw_i2s_dev *dev,
>>  		      struct snd_pcm_substream *substream)
>>  {
>>  	struct i2s_clk_config_data *config = &dev->config;
>>  
>>  	i2s_write_reg(dev->i2s_base, IER, 1);
>> -	i2s_enable_irqs(dev, substream->stream, config->chan_nr);
>> +
>> +	if (dev->use_pio)
>> +		i2s_enable_irqs(dev, substream->stream, config->chan_nr);
>>  
>>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>>  		i2s_write_reg(dev->i2s_base, ITER, 1);
> That seems wrong, or at least something that should be separate?
> Previously we needed interrupts for DMA operation but now we enable
> interrupts only if we don't use DMA.  It feels like we want to make the
> change for DMA separately if only to make it clear for bisection, are we
> 100% sure that masking the interrupt won't also mask the DMA request
> signals?

Indeed I thought about this and the interrupts must also be enabled when in DMA
mode. Although there is no interrupt handler in the original driver (without
this patches) in some setups the interrupt line may be connected to the DMA
controller. I will drop this change and always enable interrupts. Please note
that I don't have a setup with DMA support so I can only test using the PIO mode.

>> +	irq = platform_get_irq(pdev, 0);
>> +	if (irq >= 0) {
>> +		dev_dbg(&pdev->dev, "using PIO mode\n");
>> +		dev->use_pio = true;
>> +
>> +		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
>> +				pdev->name, dev);
>> +		if (ret < 0) {
>> +			dev_err(&pdev->dev, "failed to request irq\n");
>> +			return ret;
>> +		}
>> +	}
> This also seems wrong.  We're forcing PIO if an interrupt is provided
> rather than based on DMA being configured which means that if the
> interrupt is wired up and happens to be described in DT we'll get worse
> performance.  People should be able to just describe the system without
> worrying about this, and we might find some other use for the interrupts
> in future.  Indeed right now it would probably be reasonable to use the
> error interrupts all the time if they're available.

How should I then determine which mode to use?
    - Check if DMA parameters are declared in DT, or
    - Check if snd_dmaengine_pcm_register() fails, or
    - Assume PIO mode will be used when compiling with PIO PCM, or
    - Something else ?

Best regards,
Jose Miguel Abreu

[toc] | [prev] | [next] | [standalone]


#1406322 — Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromMark Brown <broonie@kernel.org>
Date2016-05-24 20:00 +0200
SubjectRe: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rCoMy-6n2-31@gated-at.bofh.it>
In reply to#1406293

[Multipart message — attachments visible in raw view] — view raw

On Tue, May 24, 2016 at 06:07:14PM +0100, Jose Abreu wrote:
> On 24-05-2016 17:41, Mark Brown wrote:

Please fix your mail client to word wrap within paragraphs at something
substantially less than 80 columns.  Doing this makes your messages much
easier to read and reply to.

> >>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> >>  		i2s_write_reg(dev->i2s_base, ITER, 1);

> > That seems wrong, or at least something that should be separate?
> > Previously we needed interrupts for DMA operation but now we enable
> > interrupts only if we don't use DMA.  It feels like we want to make the
> > change for DMA separately if only to make it clear for bisection, are we
> > 100% sure that masking the interrupt won't also mask the DMA request
> > signals?

> Indeed I thought about this and the interrupts must also be enabled when in DMA
> mode. Although there is no interrupt handler in the original driver (without
> this patches) in some setups the interrupt line may be connected to the DMA
> controller. I will drop this change and always enable interrupts. Please note
> that I don't have a setup with DMA support so I can only test using the PIO mode.

Presumably you can talk to your hardware colleagues and get them to make
you a FPGA with a DMA IP available?

> > This also seems wrong.  We're forcing PIO if an interrupt is provided
> > rather than based on DMA being configured which means that if the
> > interrupt is wired up and happens to be described in DT we'll get worse

> How should I then determine which mode to use?
>     - Check if DMA parameters are declared in DT, or
>     - Check if snd_dmaengine_pcm_register() fails, or
>     - Assume PIO mode will be used when compiling with PIO PCM, or
>     - Something else ?

You could either unconditionally register the PIO driver and only
actually start using it if the driver is instantiated or you could check
to see if the registration function works (handling deferred probe - if
the DMA driver just didn't load yet you should wait for it).

[toc] | [prev] | [next] | [standalone]


#1406810 — Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2016-05-25 12:20 +0200
SubjectRe: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rCE4V-8dd-15@gated-at.bofh.it>
In reply to#1406322
Hi Mark,


On 24-05-2016 18:51, Mark Brown wrote:
> On Tue, May 24, 2016 at 06:07:14PM +0100, Jose Abreu wrote:
>> On 24-05-2016 17:41, Mark Brown wrote:
> Please fix your mail client to word wrap within paragraphs at something
> substantially less than 80 columns.  Doing this makes your messages much
> easier to read and reply to.
>
>>>>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>>>>  		i2s_write_reg(dev->i2s_base, ITER, 1);
>>> That seems wrong, or at least something that should be separate?
>>> Previously we needed interrupts for DMA operation but now we enable
>>> interrupts only if we don't use DMA.  It feels like we want to make the
>>> change for DMA separately if only to make it clear for bisection, are we
>>> 100% sure that masking the interrupt won't also mask the DMA request
>>> signals?
>> Indeed I thought about this and the interrupts must also be enabled when in DMA
>> mode. Although there is no interrupt handler in the original driver (without
>> this patches) in some setups the interrupt line may be connected to the DMA
>> controller. I will drop this change and always enable interrupts. Please note
>> that I don't have a setup with DMA support so I can only test using the PIO mode.
> Presumably you can talk to your hardware colleagues and get them to make
> you a FPGA with a DMA IP available?

Its already in the todo list.

>
>>> This also seems wrong.  We're forcing PIO if an interrupt is provided
>>> rather than based on DMA being configured which means that if the
>>> interrupt is wired up and happens to be described in DT we'll get worse
>> How should I then determine which mode to use?
>>     - Check if DMA parameters are declared in DT, or
>>     - Check if snd_dmaengine_pcm_register() fails, or
>>     - Assume PIO mode will be used when compiling with PIO PCM, or
>>     - Something else ?
> You could either unconditionally register the PIO driver and only
> actually start using it if the driver is instantiated or you could check
> to see if the registration function works (handling deferred probe - if
> the DMA driver just didn't load yet you should wait for it).

I think I will take the second option. Something like this:
"
    ret = snd_dmaengine_pcm_register(...)
    if (ret == -EPROBE_DEFER)
        return ret;
    else
        pio_register(...);
"?


Best regards,
Jose Miguel Abreu

[toc] | [prev] | [next] | [standalone]


#1406812 — Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromMark Brown <broonie@kernel.org>
Date2016-05-25 12:20 +0200
SubjectRe: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rCE4W-8dd-19@gated-at.bofh.it>
In reply to#1406810

[Multipart message — attachments visible in raw view] — view raw

On Wed, May 25, 2016 at 11:11:47AM +0100, Jose Abreu wrote:

> I think I will take the second option. Something like this:
> "
>     ret = snd_dmaengine_pcm_register(...)
>     if (ret == -EPROBE_DEFER)
>         return ret;
>     else
>         pio_register(...);
> "?

Sure.  You should print a diagnostic if you fail to get the DMA, for any
real system it's going to be a bug.

[toc] | [prev] | [next] | [standalone]


#1406834 — Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2016-05-25 12:50 +0200
SubjectRe: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rCExY-8n2-19@gated-at.bofh.it>
In reply to#1406812
Hi Mark,


On 25-05-2016 11:18, Mark Brown wrote:
> On Wed, May 25, 2016 at 11:11:47AM +0100, Jose Abreu wrote:
>
>> I think I will take the second option. Something like this:
>> "
>>     ret = snd_dmaengine_pcm_register(...)
>>     if (ret == -EPROBE_DEFER)
>>         return ret;
>>     else
>>         pio_register(...);
>> "?
> Sure.  You should print a diagnostic if you fail to get the DMA, for any
> real system it's going to be a bug.

Ok, will do that. I noticed the last I2S patch that you merged
("ASoC: dwc: Add helper functions to disable/enable irqs") is not
in for-next yet. Should I base my work on 'topic/dwc' branch?

Best regards,
Jose Miguel Abreu

[toc] | [prev] | [next] | [standalone]


#1406919 — Re: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension

FromMark Brown <broonie@kernel.org>
Date2016-05-25 15:50 +0200
SubjectRe: [PATCH 3/4 v7] ASoC: dwc: Add PIO PCM extension
Message-ID<rCHma-1A6-37@gated-at.bofh.it>
In reply to#1406834

[Multipart message — attachments visible in raw view] — view raw

On Wed, May 25, 2016 at 11:49:12AM +0100, Jose Abreu wrote:

> Ok, will do that. I noticed the last I2S patch that you merged
> ("ASoC: dwc: Add helper functions to disable/enable irqs") is not
> in for-next yet. Should I base my work on 'topic/dwc' branch?

We are in the merge window.  No new non-bugfix patches will be merged
until the merge window ends, most likely sometime this weekend.

[toc] | [prev] | [next] | [standalone]


#1405211 — [PATCH 4/4 v7] ASoC: dwc: Add irq parameter to DOCUMENTATION

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2016-05-23 12:10 +0200
Subject[PATCH 4/4 v7] ASoC: dwc: Add irq parameter to DOCUMENTATION
Message-ID<rBUYa-4uz-19@gated-at.bofh.it>
In reply to#1405208
A parameter description for the interruptions of the
I2S controller was added. This interrupt parameter
should only be set when I2S does not have DMA support.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: alsa-devel@alsa-project.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---

Changes v6 -> v7:
* interrupts is now optional property

No changes v5 -> v6.

Changes v4 -> v5:
* interrupts is now required property
* Drop 'snps-use-dmaengine' property

This patch was only introduced in v4.

 Documentation/devicetree/bindings/sound/designware-i2s.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/designware-i2s.txt b/Documentation/devicetree/bindings/sound/designware-i2s.txt
index 7bb5424..6a536d5 100644
--- a/Documentation/devicetree/bindings/sound/designware-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/designware-i2s.txt
@@ -12,6 +12,10 @@ Required properties:
    one for receive.
  - dma-names : "tx" for the transmit channel, "rx" for the receive channel.
 
+Optional properties:
+ - interrupts: The interrupt line number for the I2S controller. Add this
+   parameter if the I2S controller that you are using does not support DMA.
+
 For more details on the 'dma', 'dma-names', 'clock' and 'clock-names'
 properties please check:
 	* resource-names.txt
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1405667 — Re: [PATCH 4/4 v7] ASoC: dwc: Add irq parameter to DOCUMENTATION

FromRob Herring <robh@kernel.org>
Date2016-05-23 23:40 +0200
SubjectRe: [PATCH 4/4 v7] ASoC: dwc: Add irq parameter to DOCUMENTATION
Message-ID<rC5JU-2KA-31@gated-at.bofh.it>
In reply to#1405211
On Mon, May 23, 2016 at 11:02:25AM +0100, Jose Abreu wrote:
> A parameter description for the interruptions of the
> I2S controller was added. This interrupt parameter
> should only be set when I2S does not have DMA support.
> 
> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> Cc: Carlos Palminha <palminha@synopsys.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Liam Girdwood <lgirdwood@gmail.com>
> Cc: Jaroslav Kysela <perex@perex.cz>
> Cc: Takashi Iwai <tiwai@suse.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> Cc: linux-snps-arc@lists.infradead.org
> Cc: alsa-devel@alsa-project.org
> Cc: devicetree@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> 
> Changes v6 -> v7:
> * interrupts is now optional property
> 
> No changes v5 -> v6.
> 
> Changes v4 -> v5:
> * interrupts is now required property
> * Drop 'snps-use-dmaengine' property
> 
> This patch was only introduced in v4.
> 
>  Documentation/devicetree/bindings/sound/designware-i2s.txt | 4 ++++
>  1 file changed, 4 insertions(+)

Acked-by: Rob Herring <robh@kernel.org>

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web