devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 00/11] ASoC: fsl-ssi: ac97-slave support
@ 2013-05-30 14:51 Markus Pargmann
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  2013-05-30 14:51 ` [PATCH v7 10/11] ASoC: fsl: Move fsl-ssi binding doc to sound/ Markus Pargmann
  0 siblings, 2 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

Hi,

This series adds DT support for phycore-ac97. Beside ac97 support, the series
adds imx-pcm-fiq and generic DMA bindings to fsl-ssi.

Regards,

Markus

Changes in v7:
 - Only one soc_ac97_ops struct for both ssi drivers (fsl-ssi and imx-ssi) to
   make it possible to compile a kernel with both drivers.
 - Other small bug/style fixes described in the changelogs of the patches.

Changes in v6:
 - Rebased onto 3.10-rc3 with Shawn's pcm cleanup patches
 - Setup of reset functions moved to phycore-ac97.c

Changes in v5:
 - Pass of_node via parent device to imx-pcm-dma.

Changes in v4:
 - phycore-ac97 uses the iomux functions based on audmux phandle now.
 - fsl-ssi imx-pcm-fiq got some new comments about problems with imx-ssi and
   incompatible codecs

Changes in v3:
 - Rebased onto pcm dma cleanup patches
 - A lot of cleanups for the fsl-ssi ac97 integration
 - Some small changes which are listed in the notes of the patches.

Markus Pargmann (11):
      ASoC: imx-pcm-dma: DT support
      ASoC: imx-pcm-fiq: Introduce pcm-fiq-params
      ASoC: fsl: Move soc_ac97_ops from imx-ssi to fsl_ssi
      ASoC: fsl-ssi: Add support for imx-pcm-fiq
      ASoC: fsl-ssi: Use generic DMA bindings if possible
      ASoC: fsl-ssi: imx ac97 support
      ARM: imx: Export ac97 reset functions
      ASoC: phycore-ac97: Add DT support
      ASoC: fsl: Kconfig: Use fsl-ssi for phycore-ac97
      ASoC: fsl: Move fsl-ssi binding doc to sound/
      ASoC: fsl: Update fsl-ssi binding doc

 .../{powerpc/fsl/ssi.txt => sound/fsl,ssi.txt}     |  10 +
 .../bindings/sound/phytec,phycore-ac97.txt         |  14 +
 arch/arm/mach-imx/mach-pca100.c                    |   7 +-
 arch/arm/mach-imx/mach-pcm043.c                    |   7 +-
 sound/soc/fsl/Kconfig                              |   4 +-
 sound/soc/fsl/fsl_ssi.c                            | 450 +++++++++++++++++----
 sound/soc/fsl/fsl_ssi.h                            |   7 +
 sound/soc/fsl/imx-pcm-dma.c                        |   1 -
 sound/soc/fsl/imx-pcm-fiq.c                        |  18 +-
 sound/soc/fsl/imx-pcm.h                            |  15 +-
 sound/soc/fsl/imx-ssi.c                            |  14 +-
 sound/soc/fsl/imx-ssi.h                            |   1 +
 sound/soc/fsl/phycore-ac97.c                       | 236 +++++++++--
 13 files changed, 656 insertions(+), 128 deletions(-)
 rename Documentation/devicetree/bindings/{powerpc/fsl/ssi.txt => sound/fsl,ssi.txt} (88%)
 create mode 100644 Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt

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

* [PATCH v7 01/11] ASoC: imx-pcm-dma: DT support
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 02/11] ASoC: imx-pcm-fiq: Introduce pcm-fiq-params Markus Pargmann
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

This patch removes the NO_DT flag. The pdev pointer may have a proper
of_node with the dmas property, so we can use it to request DMA
channels.

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---

Notes:
    Changes in v6:
     - After rebasing onto Shawn's imx-pcm cleanups, this patch just consists of
       removing the NO_DT flag.
    
    Changes in v5:
     - Use dev.parent pointer to get the of_node.

 sound/soc/fsl/imx-pcm-dma.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index fde4d2e..f323ce0 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -64,7 +64,6 @@ int imx_pcm_dma_init(struct platform_device *pdev)
 {
 	return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config,
 		SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
-		SND_DMAENGINE_PCM_FLAG_NO_DT |
 		SND_DMAENGINE_PCM_FLAG_COMPAT);
 }
 EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
-- 
1.8.2.1

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

* [PATCH v7 02/11] ASoC: imx-pcm-fiq: Introduce pcm-fiq-params
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  2013-05-30 14:51   ` [PATCH v7 01/11] ASoC: imx-pcm-dma: DT support Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 03/11] ASoC: fsl: Move soc_ac97_ops from imx-ssi to fsl_ssi Markus Pargmann
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

Cleaner parameter passing for imx-pcm-fiq. Create a seperated fiq-params
struct to pass all arguments.

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---

Notes:
    Changes in v7:
     - Fix init function signature for !CONFIG_SND_SOC_IMX_PCM_FIQ
    
    Changes in v6:
     - After rebasing onto Shawn's imx-pcm cleanups, the imx_pcm_fiq_params are now
       passed as function arguments instead of platform driver data.
    
    Changes in v3:
     - Using snd_dmaengine_dai_dma_data for dma_params after rebasing onto
       dmaengine cleanups.

 sound/soc/fsl/imx-pcm-fiq.c | 18 ++++++++++--------
 sound/soc/fsl/imx-pcm.h     | 15 +++++++++++++--
 sound/soc/fsl/imx-ssi.c     |  7 ++++++-
 sound/soc/fsl/imx-ssi.h     |  1 +
 4 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 310d902..3b2ba99 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 
 #include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -32,6 +33,7 @@
 #include <linux/platform_data/asoc-imx-ssi.h>
 
 #include "imx-ssi.h"
+#include "imx-pcm.h"
 
 struct imx_pcm_runtime_data {
 	unsigned int period;
@@ -366,9 +368,9 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = {
 	.pcm_free	= imx_pcm_fiq_free,
 };
 
-int imx_pcm_fiq_init(struct platform_device *pdev)
+int imx_pcm_fiq_init(struct platform_device *pdev,
+		struct imx_pcm_fiq_params *params)
 {
-	struct imx_ssi *ssi = platform_get_drvdata(pdev);
 	int ret;
 
 	ret = claim_fiq(&fh);
@@ -377,15 +379,15 @@ int imx_pcm_fiq_init(struct platform_device *pdev)
 		return ret;
 	}
 
-	mxc_set_irq_fiq(ssi->irq, 1);
-	ssi_irq = ssi->irq;
+	mxc_set_irq_fiq(params->irq, 1);
+	ssi_irq = params->irq;
 
-	imx_pcm_fiq = ssi->irq;
+	imx_pcm_fiq = params->irq;
 
-	imx_ssi_fiq_base = (unsigned long)ssi->base;
+	imx_ssi_fiq_base = (unsigned long)params->base;
 
-	ssi->dma_params_tx.maxburst = 4;
-	ssi->dma_params_rx.maxburst = 6;
+	params->dma_params_tx->maxburst = 4;
+	params->dma_params_rx->maxburst = 6;
 
 	ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
 	if (ret)
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index 67f656c..cd8a796 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -32,6 +32,15 @@ imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
 		dma_data->peripheral_type = IMX_DMATYPE_SSI;
 }
 
+struct imx_pcm_fiq_params {
+	int irq;
+	void __iomem *base;
+
+	/* Pointer to original ssi driver to setup tx rx sizes */
+	struct snd_dmaengine_dai_dma_data *dma_params_rx;
+	struct snd_dmaengine_dai_dma_data *dma_params_tx;
+};
+
 #ifdef CONFIG_SND_SOC_IMX_PCM_DMA
 int imx_pcm_dma_init(struct platform_device *pdev);
 void imx_pcm_dma_exit(struct platform_device *pdev);
@@ -47,10 +56,12 @@ static inline void imx_pcm_dma_exit(struct platform_device *pdev)
 #endif
 
 #ifdef CONFIG_SND_SOC_IMX_PCM_FIQ
-int imx_pcm_fiq_init(struct platform_device *pdev);
+int imx_pcm_fiq_init(struct platform_device *pdev,
+		struct imx_pcm_fiq_params *params);
 void imx_pcm_fiq_exit(struct platform_device *pdev);
 #else
-static inline int imx_pcm_fiq_init(struct platform_device *pdev)
+static inline int imx_pcm_fiq_init(struct platform_device *pdev,
+		struct imx_pcm_fiq_params *params);
 {
 	return -ENODEV;
 }
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index a8362be..16ae16d 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -590,7 +590,12 @@ static int imx_ssi_probe(struct platform_device *pdev)
 		goto failed_register;
 	}
 
-	ret = imx_pcm_fiq_init(pdev);
+	ssi->fiq_params.irq = ssi->irq;
+	ssi->fiq_params.base = ssi->base;
+	ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx;
+	ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx;
+
+	ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
 	if (ret)
 		goto failed_pcm_fiq;
 
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index d5003ce..fb1616b 100644
--- a/sound/soc/fsl/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
@@ -209,6 +209,7 @@ struct imx_ssi {
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
 	struct imx_dma_data filter_data_tx;
 	struct imx_dma_data filter_data_rx;
+	struct imx_pcm_fiq_params fiq_params;
 
 	int enabled;
 };
-- 
1.8.2.1

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

* [PATCH v7 03/11] ASoC: fsl: Move soc_ac97_ops from imx-ssi to fsl_ssi
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  2013-05-30 14:51   ` [PATCH v7 01/11] ASoC: imx-pcm-dma: DT support Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 02/11] ASoC: imx-pcm-fiq: Introduce pcm-fiq-params Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 04/11] ASoC: fsl-ssi: Add support for imx-pcm-fiq Markus Pargmann
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

fsl_ssi and imx-ssi can be both enabled at the same time. To be able to
add AC97 support to fsl_ssi, soc_ac97_ops have to be available to both
drivers.

fsl_ssi has DT support and should be the only driver at some point in
the future. This patch moves the definition of soc_ac97_ops to fsl_ssi.
imx-ssi copies its own ac97 ops struct into soc_ac97_ops when used in
AC97 mode.

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 sound/soc/fsl/Kconfig   | 1 +
 sound/soc/fsl/fsl_ssi.c | 8 ++++++++
 sound/soc/fsl/imx-ssi.c | 7 +++++--
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7860cc2..74ef96e 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -107,6 +107,7 @@ if SND_IMX_SOC
 
 config SND_SOC_IMX_SSI
 	tristate
+	select SND_SOC_FSL_SSI
 
 config SND_SOC_IMX_PCM_FIQ
 	bool
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2f2d837..db55499 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -587,6 +587,14 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
 	.name		= "fsl-ssi",
 };
 
+/*
+ * FIXME: As soon as all boards using imx-ssi AC97 mode are able to use
+ * fsl-ssi, soc_ac97_ops can be used exclusively in this driver without copying
+ * the struct. AC97 support can then be removed from imx-ssi.
+ */
+struct snd_ac97_bus_ops soc_ac97_ops;
+EXPORT_SYMBOL_GPL(soc_ac97_ops);
+
 /* Show the statistics of a flag only if its interrupt is enabled.  The
  * compiler will optimze this code to a no-op if the interrupt is not
  * enabled.
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 16ae16d..3760220 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -501,13 +501,14 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
 	imx_ssi_ac97_read(ac97, 0);
 }
 
-struct snd_ac97_bus_ops soc_ac97_ops = {
+static struct snd_ac97_bus_ops imx_ssi_soc_ac97_ops = {
 	.read		= imx_ssi_ac97_read,
 	.write		= imx_ssi_ac97_write,
 	.reset		= imx_ssi_ac97_reset,
 	.warm_reset	= imx_ssi_ac97_warm_reset
 };
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
+
+extern struct snd_ac97_bus_ops soc_ac97_ops;
 
 static int imx_ssi_probe(struct platform_device *pdev)
 {
@@ -547,6 +548,8 @@ static int imx_ssi_probe(struct platform_device *pdev)
 	}
 
 	if (ssi->flags & IMX_SSI_USE_AC97) {
+		memcpy(&soc_ac97_ops, &imx_ssi_soc_ac97_ops,
+				sizeof(soc_ac97_ops));
 		if (ac97_ssi) {
 			dev_err(&pdev->dev, "AC'97 SSI already registered\n");
 			ret = -EBUSY;
-- 
1.8.2.1

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

* [PATCH v7 04/11] ASoC: fsl-ssi: Add support for imx-pcm-fiq
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                     ` (2 preceding siblings ...)
  2013-05-30 14:51   ` [PATCH v7 03/11] ASoC: fsl: Move soc_ac97_ops from imx-ssi to fsl_ssi Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 05/11] ASoC: fsl-ssi: Use generic DMA bindings if possible Markus Pargmann
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

Add support for non-dma pcm for imx platforms with imx-pcm-fiq support.
Instead of imx-pcm-audio, in this case imx-pcm-fiq-audio device is added
and the SIER flags are set differently.

We need imx-pcm-fiq for some boards that use an incompatible codec.
imx-pcm-fiq handles those codecs differently and allows to operate with
them. DMA is not possible because some data sent by the codecs, e.g.
wm9712, is not in the datastream. Also some data is mixed up in the
fifos, so that we need to sort them out manually.

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---

Notes:
    Changes in v4:
     - Add a comment about the reason why we add a imx-pcm-fiq device.
     - Change commit message to include information about the usage of imx-pcm-fiq
    
    Changes in v3:
     - Rename bool "dma" to "use_dma"

 sound/soc/fsl/fsl_ssi.c | 77 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 65 insertions(+), 12 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index db55499..2fe4dbd 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -8,6 +8,26 @@
  * 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.
+ *
+ *
+ * Some notes why imx-pcm-fiq is used instead of DMA on some boards:
+ *
+ * The i.MX SSI core has some nasty limitations in AC97 mode. While most
+ * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
+ * one FIFO which combines all valid receive slots. We cannot even select
+ * which slots we want to receive. The WM9712 with which this driver
+ * was developed with always sends GPIO status data in slot 12 which
+ * we receive in our (PCM-) data stream. The only chance we have is to
+ * manually skip this data in the FIQ handler. With sampling rates different
+ * from 48000Hz not every frame has valid receive data, so the ratio
+ * between pcm data and GPIO status data changes. Our FIQ handler is not
+ * able to handle this, hence this driver only works with 48000Hz sampling
+ * rate.
+ * Reading and writing AC97 registers is another challenge. The core
+ * provides us status bits when the read register is updated with *another*
+ * value. When we read the same register two times (and the register still
+ * contains the same value) these status bits are not set. We work
+ * around this by not polling these bits but only wait a fixed delay.
  */
 
 #include <linux/init.h>
@@ -121,11 +141,13 @@ struct fsl_ssi_private {
 
 	bool new_binding;
 	bool ssi_on_imx;
+	bool use_dma;
 	struct clk *clk;
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
 	struct snd_dmaengine_dai_dma_data dma_params_rx;
 	struct imx_dma_data filter_data_tx;
 	struct imx_dma_data filter_data_rx;
+	struct imx_pcm_fiq_params fiq_params;
 
 	struct {
 		unsigned int rfrc;
@@ -355,7 +377,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 		 */
 
 		/* Enable the interrupts and DMA requests */
-		write_ssi(SIER_FLAGS, &ssi->sier);
+		if (ssi_private->use_dma)
+			write_ssi(SIER_FLAGS, &ssi->sier);
+		else
+			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
+					CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
 
 		/*
 		 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
@@ -549,7 +576,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
 {
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
 
-	if (ssi_private->ssi_on_imx) {
+	if (ssi_private->ssi_on_imx && ssi_private->use_dma) {
 		dai->playback_dma_data = &ssi_private->dma_params_tx;
 		dai->capture_dma_data = &ssi_private->dma_params_rx;
 	}
@@ -702,6 +729,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	       sizeof(fsl_ssi_dai_template));
 	ssi_private->cpu_dai_drv.name = ssi_private->name;
 
+	ssi_private->use_dma = !of_property_read_bool(np, "fsl,imx-fiq");
+
 	/* Get the addresses and IRQ */
 	ret = of_address_to_resource(np, 0, &res);
 	if (ret) {
@@ -723,12 +752,15 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		goto error_iomap;
 	}
 
-	/* The 'name' should not have any slashes in it. */
-	ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
-			  ssi_private);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
-		goto error_irqmap;
+	if (ssi_private->use_dma) {
+		/* The 'name' should not have any slashes in it. */
+		ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
+				ssi_private->name, ssi_private);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "could not claim irq %u\n",
+					ssi_private->irq);
+			goto error_irqmap;
+		}
 	}
 
 	/* Are the RX and the TX clocks locked? */
@@ -777,7 +809,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		 */
 		ret = of_property_read_u32_array(pdev->dev.of_node,
 					"fsl,ssi-dma-events", dma_events, 2);
-		if (ret) {
+		if (ret && !ssi_private->use_dma) {
 			dev_err(&pdev->dev, "could not get dma events\n");
 			goto error_clk;
 		}
@@ -816,9 +848,30 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 	if (ssi_private->ssi_on_imx) {
-		ret = imx_pcm_dma_init(pdev);
-		if (ret)
-			goto error_dev;
+		if (!ssi_private->use_dma) {
+
+			/*
+			 * Some boards use an incompatible codec. To get it
+			 * working, we are using imx-fiq-pcm-audio, that
+			 * can handle those codecs. DMA is not possible in this
+			 * situation.
+			 */
+
+			ssi_private->fiq_params.irq = ssi_private->irq;
+			ssi_private->fiq_params.base = ssi_private->ssi;
+			ssi_private->fiq_params.dma_params_rx =
+				&ssi_private->dma_params_rx;
+			ssi_private->fiq_params.dma_params_tx =
+				&ssi_private->dma_params_tx;
+
+			ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
+			if (ret)
+				goto error_dev;
+		} else {
+			ret = imx_pcm_dma_init(pdev);
+			if (ret)
+				goto error_dev;
+		}
 	}
 
 	/*
-- 
1.8.2.1

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

* [PATCH v7 05/11] ASoC: fsl-ssi: Use generic DMA bindings if possible
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                     ` (3 preceding siblings ...)
  2013-05-30 14:51   ` [PATCH v7 04/11] ASoC: fsl-ssi: Add support for imx-pcm-fiq Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 06/11] ASoC: fsl-ssi: imx ac97 support Markus Pargmann
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

There may be some platforms using fsl-ssi that do not have a DMA driver
with generic DMA bindings. So this patch adds support for the generic
DMA bindings, while still accepting the old "fsl,dma-events" property if
"dmas" is not found.

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---

Notes:
    Changes in v5:
     - Not passing of_node now, instead setting the parent device
    
    Changes in v4:
     - Change TODO comment to a FIXME, to remove the old dma-events property as soon
       as all dma drivers support the generic DMA bindings.

 sound/soc/fsl/fsl_ssi.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2fe4dbd..ed1fbbb 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -803,15 +803,19 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 			&ssi_private->filter_data_tx;
 		ssi_private->dma_params_rx.filter_data =
 			&ssi_private->filter_data_rx;
-		/*
-		 * TODO: This is a temporary solution and should be changed
-		 * to use generic DMA binding later when the helplers get in.
-		 */
-		ret = of_property_read_u32_array(pdev->dev.of_node,
+		if (!of_property_read_bool(pdev->dev.of_node, "dmas") &&
+				ssi_private->use_dma) {
+			/*
+			 * FIXME: This is a temporary solution until all
+			 * necessary dma drivers support the generic dma
+			 * bindings.
+			 */
+			ret = of_property_read_u32_array(pdev->dev.of_node,
 					"fsl,ssi-dma-events", dma_events, 2);
-		if (ret && !ssi_private->use_dma) {
-			dev_err(&pdev->dev, "could not get dma events\n");
-			goto error_clk;
+			if (ret && ssi_private->use_dma) {
+				dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n");
+				goto error_clk;
+			}
 		}
 
 		shared = of_device_is_compatible(of_get_parent(np),
-- 
1.8.2.1

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

* [PATCH v7 06/11] ASoC: fsl-ssi: imx ac97 support
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                     ` (4 preceding siblings ...)
  2013-05-30 14:51   ` [PATCH v7 05/11] ASoC: fsl-ssi: Use generic DMA bindings if possible Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 07/11] ARM: imx: Export ac97 reset functions Markus Pargmann
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

This patch copies some parts from imx-ssi to support AC97 on
imx27-pca100 and imx35-pcm043. This is a implementation of the
ac97-slave mode.

For ac97, the registers have to be setup earlier than for other ssi
modes because there is some communication with the external device
before actual streaming. So this patch introduces a fsl_ssi_setup
function to setup the registers at different times.

To seperate board specific ac97 reset functions, ac97 read/write
functions are exported. The reset functions are set by other drivers.

This patch was tested with imx27-pca100.

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---

Notes:
    Changes in v7:
     - ac97 ops are now assigned to soc_ac97_ops to allow enabled imx-ssi and
       fsl-ssi at the same time.
    
    Changes in v6:
     - ac97 reset functions are not provided by fsl-ssi code anymore. They were
       moved to board specific code like phycore-ac97. Therefore ac97 read/write
       functions are exported and a helper function to set the soc_ac97_ops reset
       functions was created.
    
    Changes in v3:
     - Cleanup ac97 code by adding a fsl_ssi_setup function for initial register
       setup. For ac97 the registers have to be setup earlier than in normal
       mode.

 sound/soc/fsl/fsl_ssi.c | 363 ++++++++++++++++++++++++++++++++++++++----------
 sound/soc/fsl/fsl_ssi.h |   7 +
 2 files changed, 298 insertions(+), 72 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index ed1fbbb..7c20bd7 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -141,6 +141,7 @@ struct fsl_ssi_private {
 
 	bool new_binding;
 	bool ssi_on_imx;
+	bool imx_ac97;
 	bool use_dma;
 	struct clk *clk;
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
@@ -320,6 +321,124 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 	return ret;
 }
 
+static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
+{
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	u8 i2s_mode;
+	u8 wm;
+	int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
+
+	if (ssi_private->imx_ac97)
+		i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
+	else
+		i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
+
+	/*
+	 * Section 16.5 of the MPC8610 reference manual says that the SSI needs
+	 * to be disabled before updating the registers we set here.
+	 */
+	write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
+
+	/*
+	 * Program the SSI into I2S Slave Non-Network Synchronous mode. Also
+	 * enable the transmit and receive FIFO.
+	 *
+	 * FIXME: Little-endian samples require a different shift dir
+	 */
+	write_ssi_mask(&ssi->scr,
+		CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
+		CCSR_SSI_SCR_TFR_CLK_DIS |
+		i2s_mode |
+		(synchronous ? CCSR_SSI_SCR_SYN : 0));
+
+	write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
+		 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
+		 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
+
+	write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
+		 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
+		 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
+	/*
+	 * The DC and PM bits are only used if the SSI is the clock master.
+	 */
+
+	/*
+	 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't
+	 * use FIFO 1. We program the transmit water to signal a DMA transfer
+	 * if there are only two (or fewer) elements left in the FIFO. Two
+	 * elements equals one frame (left channel, right channel). This value,
+	 * however, depends on the depth of the transmit buffer.
+	 *
+	 * We set the watermark on the same level as the DMA burstsize.  For
+	 * fiq it is probably better to use the biggest possible watermark
+	 * size.
+	 */
+	if (ssi_private->use_dma)
+		wm = ssi_private->fifo_depth - 2;
+	else
+		wm = ssi_private->fifo_depth;
+
+	write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) |
+		CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm),
+		&ssi->sfcsr);
+
+	/*
+	 * For non-ac97 setups, we keep the SSI disabled because if we enable
+	 * it, then the DMA controller will start. It's not supposed to start
+	 * until the SCR.TE (or SCR.RE) bit is set, but it does anyway. The DMA
+	 * controller will transfer one "BWC" of data (i.e. the amount of data
+	 * that the MR.BWC bits are set to). The reason this is bad is because
+	 * at this point, the PCM driver has not finished initializing the DMA
+	 * controller.
+	 */
+
+
+	/*
+	 * For ac97 interrupts are enabled with the startup of the substream
+	 * because it is also running without an active substream. Normally SSI
+	 * is only enabled when there is a substream.
+	 */
+	if (!ssi_private->imx_ac97) {
+		/* Enable the interrupts and DMA requests */
+		if (ssi_private->use_dma)
+			write_ssi(SIER_FLAGS, &ssi->sier);
+		else
+			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
+					CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
+	} else {
+		/*
+		 * Setup the clock control register
+		 */
+		write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+				&ssi->stccr);
+		write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+				&ssi->srccr);
+
+		/*
+		 * Enable AC97 mode and startup the SSI
+		 */
+		write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
+				&ssi->sacnt);
+		write_ssi(0xff, &ssi->saccdis);
+		write_ssi(0x300, &ssi->saccen);
+
+		/*
+		 * Enable SSI
+		 */
+		write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN);
+		write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
+
+		/*
+		 * Enable Transmit and Receive
+		 */
+		write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
+	}
+
+	return 0;
+}
+
+
 /**
  * fsl_ssi_startup: create a new substream
  *
@@ -341,75 +460,14 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 	 * and initialize the SSI registers.
 	 */
 	if (!ssi_private->first_stream) {
-		struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
 		ssi_private->first_stream = substream;
 
 		/*
-		 * Section 16.5 of the MPC8610 reference manual says that the
-		 * SSI needs to be disabled before updating the registers we set
-		 * here.
-		 */
-		write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
-
-		/*
-		 * Program the SSI into I2S Slave Non-Network Synchronous mode.
-		 * Also enable the transmit and receive FIFO.
-		 *
-		 * FIXME: Little-endian samples require a different shift dir
-		 */
-		write_ssi_mask(&ssi->scr,
-			CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
-			CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
-			| (synchronous ? CCSR_SSI_SCR_SYN : 0));
-
-		write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
-			 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
-			 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
-
-		write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
-			 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
-			 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
-
-		/*
-		 * The DC and PM bits are only used if the SSI is the clock
-		 * master.
-		 */
-
-		/* Enable the interrupts and DMA requests */
-		if (ssi_private->use_dma)
-			write_ssi(SIER_FLAGS, &ssi->sier);
-		else
-			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
-					CCSR_SSI_SIER_RIE |
-					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
-
-		/*
-		 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
-		 * don't use FIFO 1.  We program the transmit water to signal a
-		 * DMA transfer if there are only two (or fewer) elements left
-		 * in the FIFO.  Two elements equals one frame (left channel,
-		 * right channel).  This value, however, depends on the depth of
-		 * the transmit buffer.
-		 *
-		 * We program the receive FIFO to notify us if at least two
-		 * elements (one frame) have been written to the FIFO.  We could
-		 * make this value larger (and maybe we should), but this way
-		 * data will be written to memory as soon as it's available.
-		 */
-		write_ssi(CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
-			CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2),
-			&ssi->sfcsr);
-
-		/*
-		 * We keep the SSI disabled because if we enable it, then the
-		 * DMA controller will start.  It's not supposed to start until
-		 * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
-		 * DMA controller will transfer one "BWC" of data (i.e. the
-		 * amount of data that the MR.BWC bits are set to).  The reason
-		 * this is bad is because at this point, the PCM driver has not
-		 * finished initializing the DMA controller.
+		 * fsl_ssi_setup was already called by ac97_init earlier if
+		 * the driver is in ac97 mode.
 		 */
+		if (!ssi_private->imx_ac97)
+			fsl_ssi_setup(ssi_private);
 	} else {
 		if (synchronous) {
 			struct snd_pcm_runtime *first_runtime =
@@ -564,8 +622,9 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
 
 	/*
 	 * If this is the last active substream, disable the SSI.
+	 * If AC97 is active, we don't want to disable SSI.
 	 */
-	if (!ssi_private->first_stream) {
+	if (!ssi_private->first_stream && !ssi_private->imx_ac97) {
 		struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 
 		write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
@@ -614,6 +673,129 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
 	.name		= "fsl-ssi",
 };
 
+/**
+ * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
+ *
+ * This function is called by ALSA to start, stop, pause, and resume the
+ * transfer of data.
+ */
+static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
+			   struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
+					CCSR_SSI_SIER_TFE0_EN);
+		else
+			write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
+					CCSR_SSI_SIER_TFE0_EN, 0);
+		else
+			write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
+	else
+		write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
+	.startup	= fsl_ssi_startup,
+	.shutdown	= fsl_ssi_shutdown,
+	.trigger	= fsl_ssi_ac97_trigger,
+};
+
+static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
+	.ac97_control = 1,
+	.playback = {
+		.stream_name = "AC97 Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "AC97 Capture",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.ops = &fsl_ssi_ac97_dai_ops,
+};
+
+
+static struct fsl_ssi_private *fsl_ac97_data;
+
+static void fsl_ssi_ac97_init(void)
+{
+	fsl_ssi_setup(fsl_ac97_data);
+}
+
+void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+		unsigned short val)
+{
+	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+	unsigned int lreg;
+	unsigned int lval;
+
+	if (reg > 0x7f)
+		return;
+
+
+	lreg = reg <<  12;
+	write_ssi(lreg, &ssi->sacadd);
+
+	lval = val << 4;
+	write_ssi(lval , &ssi->sacdat);
+
+	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+			CCSR_SSI_SACNT_WR);
+	udelay(100);
+}
+EXPORT_SYMBOL(fsl_ssi_ac97_write);
+
+unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
+		unsigned short reg)
+{
+	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+
+	unsigned short val = -1;
+	unsigned int lreg;
+
+	lreg = (reg & 0x7f) <<  12 ;
+	write_ssi(lreg, &ssi->sacadd);
+	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+			CCSR_SSI_SACNT_RD);
+
+	udelay(100);
+
+	val = (read_ssi(&ssi->sacdat) >> 4) & 0xffff;
+
+	return val;
+}
+EXPORT_SYMBOL(fsl_ssi_ac97_read);
+
 /*
  * FIXME: As soon as all boards using imx-ssi AC97 mode are able to use
  * fsl-ssi, soc_ac97_ops can be used exclusively in this driver without copying
@@ -622,6 +804,23 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
 struct snd_ac97_bus_ops soc_ac97_ops;
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
+static struct snd_ac97_bus_ops fsl_ssi_soc_ac97_ops = {
+	.read		= fsl_ssi_ac97_read,
+	.write		= fsl_ssi_ac97_write,
+};
+
+/*
+ * ac97 reset and warm_reset functions are setup by board specific drivers.
+ * ssi does not have any knowledge about the used board.
+ */
+void fsl_ssi_ac97_set_reset(void (*ac97_reset)(struct snd_ac97 *ac97),
+		void (*ac97_warm_reset)(struct snd_ac97 *ac97))
+{
+	soc_ac97_ops.reset = ac97_reset;
+	soc_ac97_ops.warm_reset = ac97_warm_reset;
+}
+EXPORT_SYMBOL(fsl_ssi_ac97_set_reset);
+
 /* Show the statistics of a flag only if its interrupt is enabled.  The
  * compiler will optimze this code to a no-op if the interrupt is not
  * enabled.
@@ -698,6 +897,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	struct resource res;
 	char name[64];
 	bool shared;
+	bool ac97 = false;
 
 	/* SSIs that are not connected on the board should have a
 	 *      status = "disabled"
@@ -708,7 +908,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	/* We only support the SSI in "I2S Slave" mode */
 	sprop = of_get_property(np, "fsl,mode", NULL);
-	if (!sprop || strcmp(sprop, "i2s-slave")) {
+	if (!sprop) {
+		dev_err(&pdev->dev, "fsl,mode property is necessary\n");
+		return -EINVAL;
+	}
+	if (!strcmp(sprop, "ac97-slave")) {
+		ac97 = true;
+	} else if (strcmp(sprop, "i2s-slave")) {
 		dev_notice(&pdev->dev, "mode %s is unsupported\n", sprop);
 		return -ENODEV;
 	}
@@ -724,13 +930,23 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	strcpy(ssi_private->name, p);
 
-	/* Initialize this copy of the CPU DAI driver structure */
-	memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
-	       sizeof(fsl_ssi_dai_template));
-	ssi_private->cpu_dai_drv.name = ssi_private->name;
-
 	ssi_private->use_dma = !of_property_read_bool(np, "fsl,imx-fiq");
 
+	if (ac97) {
+		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
+				sizeof(fsl_ssi_ac97_dai));
+		memcpy(&soc_ac97_ops, &fsl_ssi_soc_ac97_ops,
+				sizeof(soc_ac97_ops));
+
+		fsl_ac97_data = ssi_private;
+		ssi_private->imx_ac97 = true;
+	} else {
+		/* Initialize this copy of the CPU DAI driver structure */
+		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
+		       sizeof(fsl_ssi_dai_template));
+	}
+	ssi_private->cpu_dai_drv.name = ssi_private->name;
+
 	/* Get the addresses and IRQ */
 	ret = of_address_to_resource(np, 0, &res);
 	if (ret) {
@@ -910,6 +1126,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 done:
+	if (ssi_private->imx_ac97)
+		fsl_ssi_ac97_init();
+
 	return 0;
 
 error_dai:
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index e6b9a69..87004ae 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -206,3 +206,10 @@ struct ccsr_ssi {
 
 #endif
 
+
+void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+		unsigned short val);
+unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
+		unsigned short reg);
+void fsl_ssi_ac97_set_reset(void (*ac97_reset)(struct snd_ac97 *ac97),
+		void (*ac97_warm_reset)(struct snd_ac97 *ac97));
-- 
1.8.2.1

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

* [PATCH v7 07/11] ARM: imx: Export ac97 reset functions
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                     ` (5 preceding siblings ...)
  2013-05-30 14:51   ` [PATCH v7 06/11] ASoC: fsl-ssi: imx ac97 support Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 08/11] ASoC: phycore-ac97: Add DT support Markus Pargmann
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 arch/arm/mach-imx/mach-pca100.c | 7 +++++--
 arch/arm/mach-imx/mach-pcm043.c | 7 +++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index b8b15bb..68badf8 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -22,6 +22,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 #include <linux/irq.h>
@@ -208,7 +209,7 @@ static const struct spi_imx_master pca100_spi0_data __initconst = {
 	.num_chipselect = ARRAY_SIZE(pca100_spi_cs),
 };
 
-static void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
+void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
 {
 	mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);
 	gpio_set_value(GPIO_PORTC + 20, 1);
@@ -217,8 +218,9 @@ static void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
 	mxc_gpio_mode(PC20_PF_SSI1_FS);
 	msleep(2);
 }
+EXPORT_SYMBOL(pca100_ac97_warm_reset);
 
-static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
+void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
 {
 	mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);  /* FS */
 	gpio_set_value(GPIO_PORTC + 20, 0);
@@ -232,6 +234,7 @@ static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
 	mxc_gpio_mode(PC22_PF_SSI1_TXD);
 	msleep(2);
 }
+EXPORT_SYMBOL(pca100_ac97_cold_reset);
 
 static const struct imx_ssi_platform_data pca100_ssi_pdata __initconst = {
 	.ac97_reset		= pca100_ac97_cold_reset,
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
index 8ed533f..4f318ca 100644
--- a/arch/arm/mach-imx/mach-pcm043.c
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -27,6 +27,7 @@
 #include <linux/i2c/at24.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
+#include <linux/export.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -217,7 +218,7 @@ static iomux_v3_cfg_t pcm043_pads[] = {
 #define SD1_GPIO_WP	IMX_GPIO_NR(2, 23)
 #define SD1_GPIO_CD	IMX_GPIO_NR(2, 24)
 
-static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
+void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
 {
 	iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
 	iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
@@ -239,8 +240,9 @@ static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
 	gpio_free(AC97_GPIO_TXFS);
 	mxc_iomux_v3_setup_pad(txfs);
 }
+EXPORT_SYMBOL(pcm043_ac97_warm_reset);
 
-static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
+void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
 {
 	iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
 	iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
@@ -286,6 +288,7 @@ err1:
 		printk("%s failed with %d\n", __func__, ret);
 	mdelay(1);
 }
+EXPORT_SYMBOL(pcm043_ac97_cold_reset);
 
 static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = {
 	.ac97_reset = pcm043_ac97_cold_reset,
-- 
1.8.2.1

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

* [PATCH v7 08/11] ASoC: phycore-ac97: Add DT support
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                     ` (6 preceding siblings ...)
  2013-05-30 14:51   ` [PATCH v7 07/11] ARM: imx: Export ac97 reset functions Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
       [not found]     ` <1369925513-19329-9-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  2013-05-30 14:51   ` [PATCH v7 09/11] ASoC: fsl: Kconfig: Use fsl-ssi for phycore-ac97 Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 11/11] ASoC: fsl: Update fsl-ssi binding doc Markus Pargmann
  9 siblings, 1 reply; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

Add devicetree support for phycore-ac97 driver.

platform_of_node and cpu_of_node are set according to the fsl,audmux
phandle.

This patch adds handling of ac97 reset functions according to fsl ac97
support. They are setup from here to avoid board specific code in the
generic fsl-ssi driver.

This patch changes the handling of pca100 boards from non-DT to DT only.
pcm043 is still handled without DT.

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---

Notes:
    Changes in v7:
     - Declare empty ac97 reset functions static.
     - Replace complicated machine compatible comparison with
       of_machine_is_compatible
     - Missing snd_soc_unregister_card in imx_phycore_ac97_remove
     - Rename driver
    
    Changes in v6:
     - phycore-ac97 now manages the ac97 reset functions of the boards using
       this combination of ssi-codec.
     - Removed preprocessor ifs for DT, non-DT distinction. pcm043 is now
       non-DT only and pca100 DT only.
    
    Changes in v4:
     - New property phytec,audmux to check which audmux setup should be
       executed. Checking for fsl,imx21-audmux and fsl,imx31-audmux.
    
    Changes in v3:
     - Add some more information in the commit message.
    
    Changes in v2:
     - Simplify the driver, by combining audmux port configurations. The
       audmux driver actually knows on which platform he is running and
       will return the appropriate error code if we use functions for
       another platform. So we don't need to have the knowledge about it
       in phycore-ac97 and can try both functions. This removes the need
       of different compatibilities and renames it to phycore-ac97.
     - Use a phandle for the cpu_dai link.
     - Add devicetree binding documentation.
     - Rename binding to phytec,phycore-ac97 and fsl,ssi to phytec,ssi
    
    Changes in v2:
     - Simplify the driver, by combining audmux port configurations. The
       audmux driver actually knows on which platform he is running and
       will return the appropriate error code if we use functions for
       another platform. So we don't need to have the knowledge about it
       in phycore-ac97 and can try both functions. This removes the need
       of different compatibilities and renames it to imx27-ac97.
     - Use a phandle for the cpu_dai link.
     - Add devicetree binding documentation.
     - Rename binding to phytec,phycore-ac97 and fsl,ssi to phytec,ssi
    
    Changes in v7:
     - Declare empty ac97 reset functions static.
     - Replace complicated machine compatible comparison with
       of_machine_is_compatible
     - Missing snd_soc_unregister_card in imx_phycore_ac97_remove
    
    Changes in v6:
     - phycore-ac97 now manages the ac97 reset functions of the boards using
       this combination of ssi-codec.
     - Removed preprocessor ifs for DT, non-DT distinction. pcm043 is now
       non-DT only and pca100 DT only.
    
    Changes in v4:
     - New property phytec,audmux to check which audmux setup should be
       executed. Checking for fsl,imx21-audmux and fsl,imx31-audmux.
    
    Changes in v3:
     - Add some more information in the commit message.
    
    Changes in v2:
     - Simplify the driver, by combining audmux port configurations. The
       audmux driver actually knows on which platform he is running and
       will return the appropriate error code if we use functions for
       another platform. So we don't need to have the knowledge about it
       in phycore-ac97 and can try both functions. This removes the need
       of different compatibilities and renames it to phycore-ac97.
     - Use a phandle for the cpu_dai link.
     - Add devicetree binding documentation.
     - Rename binding to phytec,phycore-ac97 and fsl,ssi to phytec,ssi
    
    Changes in v2:
     - Simplify the driver, by combining audmux port configurations. The
       audmux driver actually knows on which platform he is running and
       will return the appropriate error code if we use functions for
       another platform. So we don't need to have the knowledge about it
       in phycore-ac97 and can try both functions. This removes the need
       of different compatibilities and renames it to imx27-ac97.
     - Use a phandle for the cpu_dai link.
     - Add devicetree binding documentation.
     - Rename binding to phytec,phycore-ac97 and fsl,ssi to phytec,ssi

 .../bindings/sound/phytec,phycore-ac97.txt         |  14 ++
 sound/soc/fsl/phycore-ac97.c                       | 236 ++++++++++++++++++---
 2 files changed, 224 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt

diff --git a/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt b/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
new file mode 100644
index 0000000..41201ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
@@ -0,0 +1,14 @@
+Phytec phycore AC97
+
+Required properties:
+- compatible: "phytec,phycore-ac97"
+- phytec,ssi: A phandle to the ssi device that is connected to ac97.
+- phytec,audmux: A phandle to the audmux device.
+
+Example:
+
+sound {
+	compatible = "phytec,phycore-ac97";
+	phytec,ssi = <&ssi1>;
+	phytec,audmux = <&audmux>;
+};
diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index ae403c2..5eb756c9 100644
--- a/sound/soc/fsl/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
@@ -20,8 +20,14 @@
 #include <asm/mach-types.h>
 
 #include "imx-audmux.h"
+#include "fsl_ssi.h"
+
+#define DRV_NAME "phycore-audio-fabric"
 
 static struct snd_soc_card imx_phycore;
+static struct device_node *phycore_dai_cpu_node;
+static void (*phycore_ac97_reset) (struct snd_ac97 *ac97);
+static void (*phycore_ac97_warm_reset)(struct snd_ac97 *ac97);
 
 static struct snd_soc_ops imx_phycore_hifi_ops = {
 };
@@ -32,12 +38,12 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
 		.stream_name	= "HiFi",
 		.codec_dai_name		= "wm9712-hifi",
 		.codec_name	= "wm9712-codec",
-		.cpu_dai_name	= "imx-ssi.0",
-		.platform_name	= "imx-ssi.0",
 		.ops		= &imx_phycore_hifi_ops,
 	},
 };
 
+static const char phycore_ac97_plat_name[] = "imx-ssi.0";
+
 static struct snd_soc_card imx_phycore = {
 	.name		= "PhyCORE-ac97-audio",
 	.owner		= THIS_MODULE,
@@ -45,40 +51,52 @@ static struct snd_soc_card imx_phycore = {
 	.num_links	= ARRAY_SIZE(imx_phycore_dai_ac97),
 };
 
-static struct platform_device *imx_phycore_snd_ac97_device;
+static void phycore_ac97_imx21_audmux(void)
+{
+	imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+		IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+		IMX_AUDMUX_V1_PCR_TFCSEL(3) |
+		IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
+		IMX_AUDMUX_V1_PCR_RXDSEL(3));
+	imx_audmux_v1_configure_port(3,
+		IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+		IMX_AUDMUX_V1_PCR_TFCSEL(0) |
+		IMX_AUDMUX_V1_PCR_TFSDIR |
+		IMX_AUDMUX_V1_PCR_RXDSEL(0));
+}
+
+static void phycore_ac97_imx31_audmux(void)
+{
+	imx_audmux_v2_configure_port(3,
+		IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+		IMX_AUDMUX_V2_PTCR_TFSEL(0) |
+		IMX_AUDMUX_V2_PTCR_TFSDIR,
+		IMX_AUDMUX_V2_PDCR_RXDSEL(0));
+	imx_audmux_v2_configure_port(0,
+		IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+		IMX_AUDMUX_V2_PTCR_TCSEL(3) |
+		IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
+		IMX_AUDMUX_V2_PDCR_RXDSEL(3));
+}
+
 static struct platform_device *imx_phycore_snd_device;
 
+static struct platform_device *imx_phycore_snd_ac97_device;
+
 static int __init imx_phycore_init(void)
 {
 	int ret;
 
-	if (machine_is_pca100()) {
-		imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-			IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V1_PCR_TFCSEL(3) |
-			IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
-			IMX_AUDMUX_V1_PCR_RXDSEL(3));
-		imx_audmux_v1_configure_port(3,
-			IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V1_PCR_TFCSEL(0) |
-			IMX_AUDMUX_V1_PCR_TFSDIR |
-			IMX_AUDMUX_V1_PCR_RXDSEL(0));
-	} else if (machine_is_pcm043()) {
-		imx_audmux_v2_configure_port(3,
-			IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V2_PTCR_TFSEL(0) |
-			IMX_AUDMUX_V2_PTCR_TFSDIR,
-			IMX_AUDMUX_V2_PDCR_RXDSEL(0));
-		imx_audmux_v2_configure_port(0,
-			IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V2_PTCR_TCSEL(3) |
-			IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
-			IMX_AUDMUX_V2_PDCR_RXDSEL(3));
+	if (machine_is_pcm043()) {
+		phycore_ac97_imx31_audmux();
 	} else {
 		/* return happy. We might run on a totally different machine */
 		return 0;
 	}
 
+	imx_phycore_dai_ac97[0].cpu_dai_name = phycore_ac97_plat_name;
+	imx_phycore_dai_ac97[0].platform_name = phycore_ac97_plat_name;
+
 	imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
 	if (!imx_phycore_snd_ac97_device)
 		return -ENOMEM;
@@ -108,18 +126,184 @@ fail2:
 	platform_device_del(imx_phycore_snd_ac97_device);
 fail1:
 	platform_device_put(imx_phycore_snd_ac97_device);
+	imx_phycore_dai_ac97[0].cpu_dai_name = NULL;
+	imx_phycore_dai_ac97[0].platform_name = NULL;
 	return ret;
 }
 
 static void __exit imx_phycore_exit(void)
 {
+	if (!machine_is_pcm043())
+		return;
+
 	platform_device_unregister(imx_phycore_snd_device);
 	platform_device_unregister(imx_phycore_snd_ac97_device);
+
+	imx_phycore_dai_ac97[0].cpu_dai_name = NULL;
+	imx_phycore_dai_ac97[0].platform_name = NULL;
 }
 
 late_initcall(imx_phycore_init);
 module_exit(imx_phycore_exit);
 
+
+static const struct of_device_id imx_phycore_ac97_of_dev_id[] = {
+	{
+		.compatible = "phytec,phycore-ac97",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx_phycore_ac97_of_dev_id);
+
+
+/*
+ * Pointer to AC97 reset functions for specific boards
+ */
+#if IS_ENABLED(CONFIG_MACH_PCA100)
+extern void pca100_ac97_cold_reset(struct snd_ac97 *ac97);
+extern void pca100_ac97_warm_reset(struct snd_ac97 *ac97);
+#else
+static void pca100_ac97_cold_reset(struct snd_ac97 *ac97) { }
+static void pca100_ac97_warm_reset(struct snd_ac97 *ac97) { }
+#endif
+
+#if IS_ENABLED(CONFIG_MACH_PCM043)
+extern void pcm043_ac97_cold_reset(struct snd_ac97 *ac97);
+extern void pcm043_ac97_warm_reset(struct snd_ac97 *ac97);
+#else
+static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97) { }
+static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97) { }
+#endif
+
+static void phycore_soc_ac97_reset(struct snd_ac97 *ac97)
+{
+	if (phycore_ac97_reset)
+		phycore_ac97_reset(ac97);
+	/* First read sometimes fails, do a dummy read */
+	fsl_ssi_ac97_read(ac97, 0);
+}
+
+static void phycore_soc_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	if (phycore_ac97_warm_reset)
+		phycore_ac97_warm_reset(ac97);
+
+	/* First read sometimes fails, do a dummy read */
+	fsl_ssi_ac97_read(ac97, 0);
+}
+
+static int phycore_ac97_setup_devices(struct platform_device *pdev)
+{
+	int ret;
+
+	imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
+	if (!imx_phycore_snd_device)
+		return -ENOMEM;
+
+	ret = platform_device_add(imx_phycore_snd_device);
+	if (ret) {
+		dev_err(&pdev->dev, "ASoC: Platform device allocation failed\n");
+		goto fail1;
+	}
+
+	ret = snd_soc_register_card(&imx_phycore);
+	if (ret) {
+		dev_err(&pdev->dev, "ASoC: soc card registration failed\n");
+		goto fail2;
+	}
+	return 0;
+
+fail2:
+	platform_device_del(imx_phycore_snd_device);
+fail1:
+	platform_device_put(imx_phycore_snd_device);
+	return ret;
+}
+
+static int imx_phycore_ac97_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct device_node *ssi_np;
+	struct device_node *audmux_np;
+
+	imx_phycore.dev = &pdev->dev;
+
+	audmux_np = of_parse_phandle(pdev->dev.of_node, "phytec,audmux", 0);
+	if (!audmux_np) {
+		dev_err(&pdev->dev, "Failed to parse phytec,audmux phandle\n");
+		return -EINVAL;
+	}
+
+	if (of_device_is_compatible(audmux_np, "fsl,imx21-audmux")) {
+		phycore_ac97_imx21_audmux();
+	} else if (of_device_is_compatible(audmux_np, "fsl,imx31-audmux")) {
+		phycore_ac97_imx31_audmux();
+	} else {
+		dev_err(&pdev->dev, "Unknown audmux, failed to setup audmux\n");
+		of_node_put(audmux_np);
+		return -EINVAL;
+	}
+	of_node_put(audmux_np);
+
+	ssi_np = of_parse_phandle(pdev->dev.of_node, "phytec,ssi", 0);
+	if (!ssi_np) {
+		dev_err(&pdev->dev, "No valid ssi phandle found\n");
+		return -EINVAL;
+	}
+
+	imx_phycore_dai_ac97[0].cpu_of_node = ssi_np;
+	imx_phycore_dai_ac97[0].platform_of_node = ssi_np;
+	phycore_dai_cpu_node = ssi_np;
+
+	if (of_machine_is_compatible("phytec,imx27-pca100")) {
+		phycore_ac97_reset = pca100_ac97_cold_reset;
+		phycore_ac97_warm_reset = pca100_ac97_warm_reset;
+	} else if (of_machine_is_compatible("phytec,imx35-pcm043")) {
+		phycore_ac97_reset = pcm043_ac97_cold_reset;
+		phycore_ac97_warm_reset = pcm043_ac97_warm_reset;
+	} else {
+		dev_err(&pdev->dev, "Failed to set AC97 reset functions, unknown board.\n");
+		return -EINVAL;
+	}
+
+	fsl_ssi_ac97_set_reset(phycore_soc_ac97_reset,
+			phycore_soc_ac97_warm_reset);
+
+	ret = phycore_ac97_setup_devices(pdev);
+	if (ret)
+		of_node_put(phycore_dai_cpu_node);
+
+	return ret;
+}
+
+static int imx_phycore_ac97_remove(struct platform_device *pdev)
+{
+	of_node_put(phycore_dai_cpu_node);
+	phycore_dai_cpu_node = NULL;
+
+	snd_soc_unregister_card(&imx_phycore);
+
+	platform_device_unregister(imx_phycore_snd_device);
+
+	phycore_ac97_reset = NULL;
+	phycore_ac97_warm_reset = NULL;
+
+	return 0;
+}
+
+static struct platform_driver imx_phycore_ac97_driver = {
+	.probe		= imx_phycore_ac97_probe,
+	.remove		= imx_phycore_ac97_remove,
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = imx_phycore_ac97_of_dev_id,
+	},
+};
+
+module_platform_driver(imx_phycore_ac97_driver);
+
 MODULE_AUTHOR("Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>");
-MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
+MODULE_DESCRIPTION(DRV_NAME ": PhyCORE ALSA SoC AC97 audio driver");
 MODULE_LICENSE("GPL");
-- 
1.8.2.1

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

* [PATCH v7 09/11] ASoC: fsl: Kconfig: Use fsl-ssi for phycore-ac97
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                     ` (7 preceding siblings ...)
  2013-05-30 14:51   ` [PATCH v7 08/11] ASoC: phycore-ac97: Add DT support Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  2013-05-30 14:51   ` [PATCH v7 11/11] ASoC: fsl: Update fsl-ssi binding doc Markus Pargmann
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 sound/soc/fsl/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 74ef96e..71284c0 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -149,7 +149,8 @@ config SND_SOC_PHYCORE_AC97
 	select SND_SOC_WM9712
 	select SND_SOC_IMX_PCM_FIQ
 	select SND_SOC_IMX_AUDMUX
-	select SND_SOC_IMX_SSI
+	select SND_SOC_FSL_SSI if MACH_PCA100
+	select SND_SOC_IMX_SSI if MACH_PCM043
 	help
 	  Say Y if you want to add support for SoC audio on Phytec phyCORE
 	  and phyCARD boards in AC97 mode
-- 
1.8.2.1

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

* [PATCH v7 10/11] ASoC: fsl: Move fsl-ssi binding doc to sound/
  2013-05-30 14:51 [PATCH v7 00/11] ASoC: fsl-ssi: ac97-slave support Markus Pargmann
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2013-05-30 14:51 ` Markus Pargmann
  1 sibling, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen, devicetree-discuss,
	Mark Brown, Timur Tabi, Liam Girdwood, Grant Likely, Sascha Hauer,
	Markus Pargmann, Shawn Guo

fsl-ssi was located in powerpc/fsl/ssi.txt. This is no powerpc specific
device, so it should be moved to sound/ as it connects to differen audio
codecs.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 .../devicetree/bindings/{powerpc/fsl/ssi.txt => sound/fsl,ssi.txt}        | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/{powerpc/fsl/ssi.txt => sound/fsl,ssi.txt} (100%)

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
similarity index 100%
rename from Documentation/devicetree/bindings/powerpc/fsl/ssi.txt
rename to Documentation/devicetree/bindings/sound/fsl,ssi.txt
-- 
1.8.2.1

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

* [PATCH v7 11/11] ASoC: fsl: Update fsl-ssi binding doc
       [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
                     ` (8 preceding siblings ...)
  2013-05-30 14:51   ` [PATCH v7 09/11] ASoC: fsl: Kconfig: Use fsl-ssi for phycore-ac97 Markus Pargmann
@ 2013-05-30 14:51   ` Markus Pargmann
  9 siblings, 0 replies; 13+ messages in thread
From: Markus Pargmann @ 2013-05-30 14:51 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Timur Tabi, Liam Girdwood, Sascha Hauer

Update the fsl-ssi bindings. DMA is no required property anymore and
uses the generic DMA bindings. imx-fiq is a new alternative to DMA

Signed-off-by: Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---

Notes:
    Changes in v4:
     - Add a comment about hardware bugs for imx-pcm-fiq
    
    Changes in v3:
     - In previous versions, I removed fsl,playback-dma and capture-dma. But they
       are still in use by fsl_dma.c, so I added them again.

 Documentation/devicetree/bindings/sound/fsl,ssi.txt | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index 5ff76c9..0375ee0 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -43,10 +43,20 @@ Required properties:
                     together.  This would still allow different sample sizes,
                     but not different sample rates.
 
+Note that either dmas, dma-names or fsl,imx-fiq are required.
+
 Optional properties:
 - codec-handle:     Phandle to a 'codec' node that defines an audio
                     codec connected to this SSI.  This node is typically
                     a child of an I2C or other control node.
+- dmas:		    Generic dma devicetree binding as described in
+		    Documentation/devicetree/bindings/dma/dma.txt.
+- dma-names:	    Two dmas have to be defined, "tx" and "rx", if fsl,imx-fiq
+		    is not defined.
+- fsl,imx-fiq:	    Bool property. Use imx-pcm-fiq instead of imx-pcm-dma.
+  		    Only necessary for some boards with incompatible
+		    codec. imx-pcm-fiq will manually filter some data from
+		    the codec. It is a workaround for a hardware bug.
 
 Child 'codec' node required properties:
 - compatible:       Compatible list, contains the name of the codec
-- 
1.8.2.1

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

* Re: [PATCH v7 08/11] ASoC: phycore-ac97: Add DT support
       [not found]     ` <1369925513-19329-9-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2013-05-31  1:51       ` Shawn Guo
  0 siblings, 0 replies; 13+ messages in thread
From: Shawn Guo @ 2013-05-31  1:51 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	Lars-Peter Clausen, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Mark Brown, Liam Girdwood, Timur Tabi, Sascha Hauer,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Thu, May 30, 2013 at 04:51:50PM +0200, Markus Pargmann wrote:
> Add devicetree support for phycore-ac97 driver.
> 
> platform_of_node and cpu_of_node are set according to the fsl,audmux
> phandle.
> 
> This patch adds handling of ac97 reset functions according to fsl ac97
> support. They are setup from here to avoid board specific code in the
> generic fsl-ssi driver.
> 
> This patch changes the handling of pca100 boards from non-DT to DT only.
> pcm043 is still handled without DT.
> 
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>

Compiling phycore-ac97 as module,  I got the following errors.

  CC [M]  sound/soc/fsl/phycore-ac97.o
sound/soc/fsl/phycore-ac97.c:305:1: error: redefinition of ‘__inittest’
sound/soc/fsl/phycore-ac97.c:146:1: note: previous definition of ‘__inittest’ was here
sound/soc/fsl/phycore-ac97.c:305:1: error: redefinition of ‘init_module’
sound/soc/fsl/phycore-ac97.c:146:1: note: previous definition of ‘init_module’ was here
sound/soc/fsl/phycore-ac97.c:305:1: error: redefinition of ‘__exittest’
sound/soc/fsl/phycore-ac97.c:147:1: note: previous definition of ‘__exittest’ was here
sound/soc/fsl/phycore-ac97.c:305:1: error: redefinition of ‘cleanup_module’
sound/soc/fsl/phycore-ac97.c:147:1: note: previous definition of ‘cleanup_module’ was here
make[4]: *** [sound/soc/fsl/phycore-ac97.o] Error 1

Shawn

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

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

end of thread, other threads:[~2013-05-31  1:51 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-30 14:51 [PATCH v7 00/11] ASoC: fsl-ssi: ac97-slave support Markus Pargmann
     [not found] ` <1369925513-19329-1-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2013-05-30 14:51   ` [PATCH v7 01/11] ASoC: imx-pcm-dma: DT support Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 02/11] ASoC: imx-pcm-fiq: Introduce pcm-fiq-params Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 03/11] ASoC: fsl: Move soc_ac97_ops from imx-ssi to fsl_ssi Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 04/11] ASoC: fsl-ssi: Add support for imx-pcm-fiq Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 05/11] ASoC: fsl-ssi: Use generic DMA bindings if possible Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 06/11] ASoC: fsl-ssi: imx ac97 support Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 07/11] ARM: imx: Export ac97 reset functions Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 08/11] ASoC: phycore-ac97: Add DT support Markus Pargmann
     [not found]     ` <1369925513-19329-9-git-send-email-mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2013-05-31  1:51       ` Shawn Guo
2013-05-30 14:51   ` [PATCH v7 09/11] ASoC: fsl: Kconfig: Use fsl-ssi for phycore-ac97 Markus Pargmann
2013-05-30 14:51   ` [PATCH v7 11/11] ASoC: fsl: Update fsl-ssi binding doc Markus Pargmann
2013-05-30 14:51 ` [PATCH v7 10/11] ASoC: fsl: Move fsl-ssi binding doc to sound/ Markus Pargmann

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