alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
@ 2014-03-15 12:44 Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 01/16] ASoC: fsl-ssi: Remove fsl_ssi_setup Markus Pargmann
                   ` (17 more replies)
  0 siblings, 18 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Hi,

This new version of the cleanup is mainly a reordering of the patches. It moves
the regmap patch to the end of the series so none of the other patches depend
on it. This also fixes a bug I introduced in "Remove fsl_ssi_setup" which also
removed the switching between network and normal mode depending on the number
of channels. I reversed this code removal. Another new patch was added "Fix
i2s_mode variable setup" which fixes the i2s_mode assignment in set_dai_fmt().

Best regards,

Markus


Changes in v2:
 - Move "Use regmap" patch to the end of the series
 - Add normal/network mode switching code to again (previously removed in
   "Remove fsl_ssi_setup"
 - Add patch "Fix i2s_mode variable setup"


Markus Pargmann (16):
  ASoC: fsl-ssi: Remove fsl_ssi_setup
  ASoC: fsl-ssi: Fix i2s_mode variable setup
  ASoC: fsl-ssi: Move debugging to seperate file
  ASoC: fsl-ssi: Use dev_name for DAI driver struct
  ASoC: fsl-ssi: Move imx-specific probe to seperate function
  ASoC: fsl-ssi: Remove useless DMA code
  ASoC: fsl-ssi: baud clock error handling
  ASoC: fsl-ssi: Cleanup probe function
  ASoC: fsl-ssi: Remove unnecessary variables from ssi_private
  ASoC: fsl-ssi: reorder and document fsl_ssi_private
  ASoC: fsl-ssi: Fix register values when disabling
  ASoC: fsl-ssi: Only enable baudclk when used
  ASoC: fsl-ssi: Set default dai-fmts
  ASoC: fsl-ssi: Transmit enable synchronization
  ASoC: fsl-ssi: Update binding documentation
  ASoC: fsl-ssi: Use regmap

 .../devicetree/bindings/sound/fsl,ssi.txt          |   21 +-
 sound/soc/fsl/Kconfig                              |    1 +
 sound/soc/fsl/Makefile                             |    2 +
 sound/soc/fsl/fsl_ssi.c                            | 1173 +++++++++-----------
 sound/soc/fsl/fsl_ssi.h                            |  112 +-
 sound/soc/fsl/fsl_ssi_dbg.c                        |  163 +++
 6 files changed, 759 insertions(+), 713 deletions(-)
 create mode 100644 sound/soc/fsl/fsl_ssi_dbg.c

-- 
1.9.0

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

* [PATCH v2 01/16] ASoC: fsl-ssi: Remove fsl_ssi_setup
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 02/16] ASoC: fsl-ssi: Fix i2s_mode variable setup Markus Pargmann
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

fsl_ssi_set_dai_fmt() manages most of the register setup routines now.
fsl_ssi_setup() makes the same as fsl_ssi_set_dai_fmt() but it relies on
DT properties.

In most cases the settings of fsl_ssi_setup() are already overwritten by
fsl_ssi_set_dai_fmt() when it is called by the soc-core when a sound
card is added. As these settings depend on the combination of codec and
cpu DAI, this should really be done by sound cards.

This patch removes fsl_ssi_setup() and adds the missing register setups
to fsl_ssi_set_dai_fmt(). It also removes all calls to fsl_ssi_setup().

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 143 +++++++++++++-----------------------------------
 1 file changed, 39 insertions(+), 104 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 5428a1f..144934e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -642,96 +642,6 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
 	write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
 }
 
-static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
-{
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-	u8 wm;
-	int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
-
-	fsl_ssi_setup_reg_vals(ssi_private);
-
-	if (ssi_private->imx_ac97)
-		ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
-	else
-		ssi_private->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 |
-		ssi_private->i2s_mode |
-		(synchronous ? CCSR_SSI_SCR_SYN : 0));
-
-	write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI |
-			CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr);
-
-	write_ssi(CCSR_SSI_SRCR_RXBIT0 | 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 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)
-		fsl_ssi_setup_ac97(ssi_private);
-
-	/*
-	 * Set a default slot number so that there is no need for those common
-	 * cases like I2S mode to call the extra set_tdm_slot() any more.
-	 */
-	if (!ssi_private->imx_ac97) {
-		write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
-				CCSR_SSI_SxCCR_DC(2));
-		write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
-				CCSR_SSI_SxCCR_DC(2));
-	}
-
-	if (ssi_private->use_dual_fifo) {
-		write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1);
-		write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1);
-		write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN);
-	}
-
-	return 0;
-}
-
-
 /**
  * fsl_ssi_startup: create a new substream
  *
@@ -748,12 +658,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 		snd_soc_dai_get_drvdata(rtd->cpu_dai);
 	unsigned long flags;
 
-	/* First, we only do fsl_ssi_setup() when SSI is going to be active.
-	 * Second, fsl_ssi_setup was already called by ac97_init earlier if
-	 * the driver is in ac97 mode.
-	 */
 	if (!dai->active && !ssi_private->imx_ac97) {
-		fsl_ssi_setup(ssi_private);
 		spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
 		ssi_private->baudclk_locked = false;
 		spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
@@ -835,6 +740,9 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 	u32 strcr = 0, stcr, srcr, scr, mask;
+	u8 wm;
+
+	fsl_ssi_setup_reg_vals(ssi_private);
 
 	scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
 	scr |= CCSR_SSI_SCR_NET;
@@ -857,7 +765,6 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 		default:
 			return -EINVAL;
 		}
-		scr |= ssi_private->i2s_mode;
 
 		/* Data on rising edge of bclk, frame low, 1clk before data */
 		strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP |
@@ -877,9 +784,13 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 		strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP |
 			CCSR_SSI_STCR_TXBIT0;
 		break;
+	case SND_SOC_DAIFMT_AC97:
+		ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL;
+		break;
 	default:
 		return -EINVAL;
 	}
+	scr |= ssi_private->i2s_mode;
 
 	/* DAI clock inversion */
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -929,6 +840,38 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 	write_ssi(srcr, &ssi->srcr);
 	write_ssi(scr, &ssi->scr);
 
+	/*
+	 * 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);
+
+	if (ssi_private->use_dual_fifo) {
+		write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1,
+				CCSR_SSI_SRCR_RFEN1);
+		write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1,
+				CCSR_SSI_STCR_TFEN1);
+		write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN,
+				CCSR_SSI_SCR_TCH_EN);
+	}
+
+	if (fmt & SND_SOC_DAIFMT_AC97)
+		fsl_ssi_setup_ac97(ssi_private);
+
 	return 0;
 }
 
@@ -1184,11 +1127,6 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
 
 static struct fsl_ssi_private *fsl_ac97_data;
 
-static void fsl_ssi_ac97_init(void)
-{
-	fsl_ssi_setup(fsl_ac97_data);
-}
-
 static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 		unsigned short val)
 {
@@ -1547,9 +1485,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 done:
-	if (ssi_private->imx_ac97)
-		fsl_ssi_ac97_init();
-
 	return 0;
 
 error_dai:
-- 
1.9.0

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

* [PATCH v2 02/16] ASoC: fsl-ssi: Fix i2s_mode variable setup
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 01/16] ASoC: fsl-ssi: Remove fsl_ssi_setup Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 03/16] ASoC: fsl-ssi: Move debugging to seperate file Markus Pargmann
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

In fsl_ssi_hw_params() we update the I2S and NET bits using the i2s_mode
variable. The fsl_ssi_set_dai_fmt() function only writes the i2s-mode to
the i2s_mode variable and not the NET bit. This fixes it by adding that
bit to i2s_mode.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 144934e..fdb123d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -745,7 +745,6 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 	fsl_ssi_setup_reg_vals(ssi_private);
 
 	scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
-	scr |= CCSR_SSI_SCR_NET;
 
 	mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR |
 		CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL |
@@ -753,14 +752,15 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 	stcr = read_ssi(&ssi->stcr) & ~mask;
 	srcr = read_ssi(&ssi->srcr) & ~mask;
 
+	ssi_private->i2s_mode = CCSR_SSI_SCR_NET;
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
 		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 		case SND_SOC_DAIFMT_CBS_CFS:
-			ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER;
+			ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER;
 			break;
 		case SND_SOC_DAIFMT_CBM_CFM:
-			ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
+			ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE;
 			break;
 		default:
 			return -EINVAL;
@@ -785,7 +785,7 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 			CCSR_SSI_STCR_TXBIT0;
 		break;
 	case SND_SOC_DAIFMT_AC97:
-		ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL;
+		ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_NORMAL;
 		break;
 	default:
 		return -EINVAL;
-- 
1.9.0

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

* [PATCH v2 03/16] ASoC: fsl-ssi: Move debugging to seperate file
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 01/16] ASoC: fsl-ssi: Remove fsl_ssi_setup Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 02/16] ASoC: fsl-ssi: Fix i2s_mode variable setup Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 04/16] ASoC: fsl-ssi: Use dev_name for DAI driver struct Markus Pargmann
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Move all code that is only used for debugging to a seperate file. This
makes it easier to see what functions are used for debugging only.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/Makefile      |   2 +
 sound/soc/fsl/fsl_ssi.c     | 241 ++------------------------------------------
 sound/soc/fsl/fsl_ssi.h     |  61 ++++++++++-
 sound/soc/fsl/fsl_ssi_dbg.c | 163 ++++++++++++++++++++++++++++++
 4 files changed, 232 insertions(+), 235 deletions(-)
 create mode 100644 sound/soc/fsl/fsl_ssi_dbg.c

diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b12ad4b..02a2e2e 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -13,12 +13,14 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 # Freescale SSI/DMA/SAI/SPDIF Support
 snd-soc-fsl-sai-objs := fsl_sai.o
 snd-soc-fsl-ssi-objs := fsl_ssi.o
+snd-soc-fsl-ssi-dbg-objs := fsl_ssi_dbg.o
 snd-soc-fsl-spdif-objs := fsl_spdif.o
 snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_dma.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
 obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
+obj-$(CONFIG_DEBUG_FS) += snd-soc-fsl-ssi-dbg.o
 obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
 obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
 obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index fdb123d..6b198f3 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -35,7 +35,6 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
-#include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
@@ -113,8 +112,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
 #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \
 		CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \
 		CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN)
-#define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS)
-
 
 enum fsl_ssi_type {
 	FSL_SSI_MCP8610,
@@ -177,31 +174,7 @@ struct fsl_ssi_private {
 	/* Register values for rx/tx configuration */
 	struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
 
-	struct {
-		unsigned int rfrc;
-		unsigned int tfrc;
-		unsigned int cmdau;
-		unsigned int cmddu;
-		unsigned int rxt;
-		unsigned int rdr1;
-		unsigned int rdr0;
-		unsigned int tde1;
-		unsigned int tde0;
-		unsigned int roe1;
-		unsigned int roe0;
-		unsigned int tue1;
-		unsigned int tue0;
-		unsigned int tfs;
-		unsigned int rfs;
-		unsigned int tls;
-		unsigned int rls;
-		unsigned int rff1;
-		unsigned int rff0;
-		unsigned int tfe1;
-		unsigned int tfe0;
-	} stats;
-	struct dentry *dbg_dir;
-	struct dentry *dbg_stats;
+	struct fsl_ssi_dbg dbg_stats;
 
 	char name[1];
 };
@@ -231,7 +204,6 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 {
 	struct fsl_ssi_private *ssi_private = dev_id;
 	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-	irqreturn_t ret = IRQ_NONE;
 	__be32 sisr;
 	__be32 sisr2;
 	__be32 sisr_write_mask = 0;
@@ -258,217 +230,18 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 	   were interrupted for.  We mask it with the Interrupt Enable register
 	   so that we only check for events that we're interested in.
 	 */
-	sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK;
-
-	if (sisr & CCSR_SSI_SISR_RFRC) {
-		ssi_private->stats.rfrc++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TFRC) {
-		ssi_private->stats.tfrc++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_CMDAU) {
-		ssi_private->stats.cmdau++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_CMDDU) {
-		ssi_private->stats.cmddu++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_RXT) {
-		ssi_private->stats.rxt++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_RDR1) {
-		ssi_private->stats.rdr1++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_RDR0) {
-		ssi_private->stats.rdr0++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TDE1) {
-		ssi_private->stats.tde1++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TDE0) {
-		ssi_private->stats.tde0++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_ROE1) {
-		ssi_private->stats.roe1++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_ROE0) {
-		ssi_private->stats.roe0++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TUE1) {
-		ssi_private->stats.tue1++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TUE0) {
-		ssi_private->stats.tue0++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TFS) {
-		ssi_private->stats.tfs++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_RFS) {
-		ssi_private->stats.rfs++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TLS) {
-		ssi_private->stats.tls++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_RLS) {
-		ssi_private->stats.rls++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_RFF1) {
-		ssi_private->stats.rff1++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_RFF0) {
-		ssi_private->stats.rff0++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TFE1) {
-		ssi_private->stats.tfe1++;
-		ret = IRQ_HANDLED;
-	}
-
-	if (sisr & CCSR_SSI_SISR_TFE0) {
-		ssi_private->stats.tfe0++;
-		ret = IRQ_HANDLED;
-	}
+	sisr = read_ssi(&ssi->sisr);
 
 	sisr2 = sisr & sisr_write_mask;
 	/* Clear the bits that we set */
 	if (sisr2)
 		write_ssi(sisr2, &ssi->sisr);
 
-	return ret;
-}
-
-#if IS_ENABLED(CONFIG_DEBUG_FS)
-/* 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.
- */
-#define SIER_SHOW(flag, name) \
-	do { \
-		if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \
-			seq_printf(s, #name "=%u\n", ssi_private->stats.name); \
-	} while (0)
-
-
-/**
- * fsl_sysfs_ssi_show: display SSI statistics
- *
- * Display the statistics for the current SSI device.  To avoid confusion,
- * we only show those counts that are enabled.
- */
-static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
-{
-	struct fsl_ssi_private *ssi_private = s->private;
-
-	SIER_SHOW(RFRC_EN, rfrc);
-	SIER_SHOW(TFRC_EN, tfrc);
-	SIER_SHOW(CMDAU_EN, cmdau);
-	SIER_SHOW(CMDDU_EN, cmddu);
-	SIER_SHOW(RXT_EN, rxt);
-	SIER_SHOW(RDR1_EN, rdr1);
-	SIER_SHOW(RDR0_EN, rdr0);
-	SIER_SHOW(TDE1_EN, tde1);
-	SIER_SHOW(TDE0_EN, tde0);
-	SIER_SHOW(ROE1_EN, roe1);
-	SIER_SHOW(ROE0_EN, roe0);
-	SIER_SHOW(TUE1_EN, tue1);
-	SIER_SHOW(TUE0_EN, tue0);
-	SIER_SHOW(TFS_EN, tfs);
-	SIER_SHOW(RFS_EN, rfs);
-	SIER_SHOW(TLS_EN, tls);
-	SIER_SHOW(RLS_EN, rls);
-	SIER_SHOW(RFF1_EN, rff1);
-	SIER_SHOW(RFF0_EN, rff0);
-	SIER_SHOW(TFE1_EN, tfe1);
-	SIER_SHOW(TFE0_EN, tfe0);
-
-	return 0;
-}
-
-static int fsl_ssi_stats_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, fsl_ssi_stats_show, inode->i_private);
-}
-
-static const struct file_operations fsl_ssi_stats_ops = {
-	.open = fsl_ssi_stats_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
-		struct device *dev)
-{
-	ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
-	if (!ssi_private->dbg_dir)
-		return -ENOMEM;
-
-	ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO,
-			ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops);
-	if (!ssi_private->dbg_stats) {
-		debugfs_remove(ssi_private->dbg_dir);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
-{
-	debugfs_remove(ssi_private->dbg_stats);
-	debugfs_remove(ssi_private->dbg_dir);
-}
-
-#else
-
-static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
-		struct device *dev)
-{
-	return 0;
-}
+	fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr);
 
-static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
-{
+	return IRQ_HANDLED;
 }
 
-#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
-
 /*
  * Enable/Disable all rx/tx config flags at once.
  */
@@ -1422,7 +1195,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		goto error_dev;
 	}
 
-	ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev);
+	ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev);
 	if (ret)
 		goto error_dbgfs;
 
@@ -1492,7 +1265,7 @@ error_dai:
 		imx_pcm_fiq_exit(pdev);
 
 error_pcm:
-	fsl_ssi_debugfs_remove(ssi_private);
+	fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);
 
 error_dbgfs:
 	snd_soc_unregister_component(&pdev->dev);
@@ -1518,7 +1291,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
 {
 	struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
 
-	fsl_ssi_debugfs_remove(ssi_private);
+	fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);
 
 	if (!ssi_private->new_binding)
 		platform_device_unregister(ssi_private->pdev);
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index e6b6324..2e95dd7 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -206,5 +206,64 @@ struct ccsr_ssi {
 #define CCSR_SSI_SACNT_FV		0x00000002
 #define CCSR_SSI_SACNT_AC97EN		0x00000001
 
-#endif
 
+struct device;
+
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+
+struct fsl_ssi_dbg {
+	struct dentry *dbg_dir;
+	struct dentry *dbg_stats;
+
+	struct {
+		unsigned int rfrc;
+		unsigned int tfrc;
+		unsigned int cmdau;
+		unsigned int cmddu;
+		unsigned int rxt;
+		unsigned int rdr1;
+		unsigned int rdr0;
+		unsigned int tde1;
+		unsigned int tde0;
+		unsigned int roe1;
+		unsigned int roe0;
+		unsigned int tue1;
+		unsigned int tue0;
+		unsigned int tfs;
+		unsigned int rfs;
+		unsigned int tls;
+		unsigned int rls;
+		unsigned int rff1;
+		unsigned int rff0;
+		unsigned int tfe1;
+		unsigned int tfe0;
+	} stats;
+};
+
+void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *ssi_dbg, u32 sisr);
+
+int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev);
+
+void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg);
+
+#else
+
+struct fsl_ssi_dbg {
+};
+
+static inline void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *stats, u32 sisr)
+{
+}
+
+static inline int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg,
+		struct device *dev)
+{
+	return 0;
+}
+
+static inline void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)
+{
+}
+#endif  /* ! IS_ENABLED(CONFIG_DEBUG_FS) */
+
+#endif
diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c
new file mode 100644
index 0000000..5469ffb
--- /dev/null
+++ b/sound/soc/fsl/fsl_ssi_dbg.c
@@ -0,0 +1,163 @@
+/*
+ * Freescale SSI ALSA SoC Digital Audio Interface (DAI) debugging functions
+ *
+ * Copyright 2014 Markus Pargmann <mpa@pengutronix.de>, Pengutronix
+ *
+ * Splitted from fsl_ssi.c
+ *
+ * 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/debugfs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#include "fsl_ssi.h"
+
+void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr)
+{
+	if (sisr & CCSR_SSI_SISR_RFRC)
+		dbg->stats.rfrc++;
+
+	if (sisr & CCSR_SSI_SISR_TFRC)
+		dbg->stats.tfrc++;
+
+	if (sisr & CCSR_SSI_SISR_CMDAU)
+		dbg->stats.cmdau++;
+
+	if (sisr & CCSR_SSI_SISR_CMDDU)
+		dbg->stats.cmddu++;
+
+	if (sisr & CCSR_SSI_SISR_RXT)
+		dbg->stats.rxt++;
+
+	if (sisr & CCSR_SSI_SISR_RDR1)
+		dbg->stats.rdr1++;
+
+	if (sisr & CCSR_SSI_SISR_RDR0)
+		dbg->stats.rdr0++;
+
+	if (sisr & CCSR_SSI_SISR_TDE1)
+		dbg->stats.tde1++;
+
+	if (sisr & CCSR_SSI_SISR_TDE0)
+		dbg->stats.tde0++;
+
+	if (sisr & CCSR_SSI_SISR_ROE1)
+		dbg->stats.roe1++;
+
+	if (sisr & CCSR_SSI_SISR_ROE0)
+		dbg->stats.roe0++;
+
+	if (sisr & CCSR_SSI_SISR_TUE1)
+		dbg->stats.tue1++;
+
+	if (sisr & CCSR_SSI_SISR_TUE0)
+		dbg->stats.tue0++;
+
+	if (sisr & CCSR_SSI_SISR_TFS)
+		dbg->stats.tfs++;
+
+	if (sisr & CCSR_SSI_SISR_RFS)
+		dbg->stats.rfs++;
+
+	if (sisr & CCSR_SSI_SISR_TLS)
+		dbg->stats.tls++;
+
+	if (sisr & CCSR_SSI_SISR_RLS)
+		dbg->stats.rls++;
+
+	if (sisr & CCSR_SSI_SISR_RFF1)
+		dbg->stats.rff1++;
+
+	if (sisr & CCSR_SSI_SISR_RFF0)
+		dbg->stats.rff0++;
+
+	if (sisr & CCSR_SSI_SISR_TFE1)
+		dbg->stats.tfe1++;
+
+	if (sisr & CCSR_SSI_SISR_TFE0)
+		dbg->stats.tfe0++;
+}
+
+/* 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.
+ */
+#define SIER_SHOW(flag, name) \
+	do { \
+		if (CCSR_SSI_SIER_##flag) \
+			seq_printf(s, #name "=%u\n", ssi_dbg->stats.name); \
+	} while (0)
+
+
+/**
+ * fsl_sysfs_ssi_show: display SSI statistics
+ *
+ * Display the statistics for the current SSI device.  To avoid confusion,
+ * we only show those counts that are enabled.
+ */
+static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
+{
+	struct fsl_ssi_dbg *ssi_dbg = s->private;
+
+	SIER_SHOW(RFRC_EN, rfrc);
+	SIER_SHOW(TFRC_EN, tfrc);
+	SIER_SHOW(CMDAU_EN, cmdau);
+	SIER_SHOW(CMDDU_EN, cmddu);
+	SIER_SHOW(RXT_EN, rxt);
+	SIER_SHOW(RDR1_EN, rdr1);
+	SIER_SHOW(RDR0_EN, rdr0);
+	SIER_SHOW(TDE1_EN, tde1);
+	SIER_SHOW(TDE0_EN, tde0);
+	SIER_SHOW(ROE1_EN, roe1);
+	SIER_SHOW(ROE0_EN, roe0);
+	SIER_SHOW(TUE1_EN, tue1);
+	SIER_SHOW(TUE0_EN, tue0);
+	SIER_SHOW(TFS_EN, tfs);
+	SIER_SHOW(RFS_EN, rfs);
+	SIER_SHOW(TLS_EN, tls);
+	SIER_SHOW(RLS_EN, rls);
+	SIER_SHOW(RFF1_EN, rff1);
+	SIER_SHOW(RFF0_EN, rff0);
+	SIER_SHOW(TFE1_EN, tfe1);
+	SIER_SHOW(TFE0_EN, tfe0);
+
+	return 0;
+}
+
+static int fsl_ssi_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, fsl_ssi_stats_show, inode->i_private);
+}
+
+static const struct file_operations fsl_ssi_stats_ops = {
+	.open = fsl_ssi_stats_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev)
+{
+	ssi_dbg->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
+	if (!ssi_dbg->dbg_dir)
+		return -ENOMEM;
+
+	ssi_dbg->dbg_stats = debugfs_create_file("stats", S_IRUGO,
+			ssi_dbg->dbg_dir, ssi_dbg, &fsl_ssi_stats_ops);
+	if (!ssi_dbg->dbg_stats) {
+		debugfs_remove(ssi_dbg->dbg_dir);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)
+{
+	debugfs_remove(ssi_dbg->dbg_stats);
+	debugfs_remove(ssi_dbg->dbg_dir);
+}
-- 
1.9.0

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

* [PATCH v2 04/16] ASoC: fsl-ssi: Use dev_name for DAI driver struct
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (2 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 03/16] ASoC: fsl-ssi: Move debugging to seperate file Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 05/16] ASoC: fsl-ssi: Move imx-specific probe to seperate function Markus Pargmann
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Instead of creating a name using string manipulation functions, we can
simply use the device name for the DAI driver struct.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 6b198f3..f31bd15 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -997,17 +997,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	if (!strcmp(sprop, "ac97-slave"))
 		ac97 = true;
 
-	/* The DAI name is the last part of the full name of the node. */
-	p = strrchr(np->full_name, '/') + 1;
-	ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private) + strlen(p),
-			      GFP_KERNEL);
+	ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private),
+			GFP_KERNEL);
 	if (!ssi_private) {
 		dev_err(&pdev->dev, "could not allocate DAI object\n");
 		return -ENOMEM;
 	}
 
-	strcpy(ssi_private->name, p);
-
 	ssi_private->use_dma = !of_property_read_bool(np,
 			"fsl,fiq-stream-filter");
 	ssi_private->hw_type = hw_type;
@@ -1025,7 +1021,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		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->cpu_dai_drv.name = dev_name(&pdev->dev);
 
 	/* Get the addresses and IRQ */
 	ret = of_address_to_resource(np, 0, &res);
@@ -1173,7 +1169,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	 * different writeable interrupt status registers.
 	 */
 	if (ssi_private->use_dma) {
-		/* The 'name' should not have any slashes in it. */
 		ret = devm_request_irq(&pdev->dev, ssi_private->irq,
 					fsl_ssi_isr, 0, ssi_private->name,
 					ssi_private);
-- 
1.9.0

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

* [PATCH v2 05/16] ASoC: fsl-ssi: Move imx-specific probe to seperate function
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (3 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 04/16] ASoC: fsl-ssi: Use dev_name for DAI driver struct Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 06/16] ASoC: fsl-ssi: Remove useless DMA code Markus Pargmann
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Move imx specific probe code to a seperate function. It reduces the
size of the probe() function and makes the code and error handling
easier to understand.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 185 +++++++++++++++++++++++++++---------------------
 1 file changed, 103 insertions(+), 82 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index f31bd15..b28f874 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -962,6 +962,100 @@ static void make_lowercase(char *s)
 	}
 }
 
+static int fsl_ssi_imx_probe(struct platform_device *pdev,
+		struct fsl_ssi_private *ssi_private)
+{
+	struct device_node *np = pdev->dev.of_node;
+	u32 dma_events[2], dmas[4];
+	bool shared;
+	int ret;
+
+	ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(ssi_private->clk)) {
+		ret = PTR_ERR(ssi_private->clk);
+		dev_err(&pdev->dev, "could not get clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(ssi_private->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
+		return ret;
+	}
+
+	/* For those SLAVE implementations, we ingore non-baudclk cases
+	 * and, instead, abandon MASTER mode that needs baud clock.
+	 */
+	ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
+	if (IS_ERR(ssi_private->baudclk))
+		dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
+			 PTR_ERR(ssi_private->baudclk));
+	else
+		clk_prepare_enable(ssi_private->baudclk);
+
+	/*
+	 * We have burstsize be "fifo_depth - 2" to match the SSI
+	 * watermark setting in fsl_ssi_startup().
+	 */
+	ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2;
+	ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2;
+	ssi_private->dma_params_tx.addr = ssi_private->ssi_phys +
+			offsetof(struct ccsr_ssi, stx0);
+	ssi_private->dma_params_rx.addr = ssi_private->ssi_phys +
+			offsetof(struct ccsr_ssi, srx0);
+	ssi_private->dma_params_tx.filter_data = &ssi_private->filter_data_tx;
+	ssi_private->dma_params_rx.filter_data = &ssi_private->filter_data_rx;
+
+	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 but fsl-ssi is configured to use DMA\n");
+			goto error_dma_events;
+		}
+	}
+	/* Should this be merge with the above? */
+	if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
+			&& dmas[2] == IMX_DMATYPE_SSI_DUAL) {
+		ssi_private->use_dual_fifo = true;
+		/* When using dual fifo mode, we need to keep watermark
+		 * as even numbers due to dma script limitation.
+		 */
+		ssi_private->dma_params_tx.maxburst &= ~0x1;
+		ssi_private->dma_params_rx.maxburst &= ~0x1;
+	}
+
+	shared = of_device_is_compatible(of_get_parent(np), "fsl,spba-bus");
+
+	imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
+		dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
+	imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
+		dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
+
+	return 0;
+
+error_dma_events:
+	if (!IS_ERR(ssi_private->baudclk))
+		clk_disable_unprepare(ssi_private->baudclk);
+	clk_disable_unprepare(ssi_private->clk);
+
+	return ret;
+}
+
+static void fsl_ssi_imx_clean(struct platform_device *pdev,
+		struct fsl_ssi_private *ssi_private)
+{
+	if (!IS_ERR(ssi_private->baudclk))
+		clk_disable_unprepare(ssi_private->baudclk);
+	clk_disable_unprepare(ssi_private->clk);
+}
+
 static int fsl_ssi_probe(struct platform_device *pdev)
 {
 	struct fsl_ssi_private *ssi_private;
@@ -974,7 +1068,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	const uint32_t *iprop;
 	struct resource res;
 	char name[64];
-	bool shared;
 	bool ac97 = false;
 
 	/* SSIs that are not connected on the board should have a
@@ -1088,80 +1181,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
 			hw_type == FSL_SSI_MX35) {
-		u32 dma_events[2], dmas[4];
 		ssi_private->ssi_on_imx = true;
 
-		ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
-		if (IS_ERR(ssi_private->clk)) {
-			ret = PTR_ERR(ssi_private->clk);
-			dev_err(&pdev->dev, "could not get clock: %d\n", ret);
+		ret = fsl_ssi_imx_probe(pdev, ssi_private);
+		if (ret)
 			goto error_irqmap;
-		}
-		ret = clk_prepare_enable(ssi_private->clk);
-		if (ret) {
-			dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n",
-				ret);
-			goto error_irqmap;
-		}
-
-		/* For those SLAVE implementations, we ingore non-baudclk cases
-		 * and, instead, abandon MASTER mode that needs baud clock.
-		 */
-		ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
-		if (IS_ERR(ssi_private->baudclk))
-			dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
-				 PTR_ERR(ssi_private->baudclk));
-		else
-			clk_prepare_enable(ssi_private->baudclk);
-
-		/*
-		 * We have burstsize be "fifo_depth - 2" to match the SSI
-		 * watermark setting in fsl_ssi_startup().
-		 */
-		ssi_private->dma_params_tx.maxburst =
-			ssi_private->fifo_depth - 2;
-		ssi_private->dma_params_rx.maxburst =
-			ssi_private->fifo_depth - 2;
-		ssi_private->dma_params_tx.addr =
-			ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
-		ssi_private->dma_params_rx.addr =
-			ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
-		ssi_private->dma_params_tx.filter_data =
-			&ssi_private->filter_data_tx;
-		ssi_private->dma_params_rx.filter_data =
-			&ssi_private->filter_data_rx;
-		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 but fsl-ssi is configured to use DMA\n");
-				goto error_clk;
-			}
-		}
-		/* Should this be merge with the above? */
-		if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
-				&& dmas[2] == IMX_DMATYPE_SSI_DUAL) {
-			ssi_private->use_dual_fifo = true;
-			/* When using dual fifo mode, we need to keep watermark
-			 * as even numbers due to dma script limitation.
-			 */
-			ssi_private->dma_params_tx.maxburst &= ~0x1;
-			ssi_private->dma_params_rx.maxburst &= ~0x1;
-		}
-
-		shared = of_device_is_compatible(of_get_parent(np),
-			    "fsl,spba-bus");
-
-		imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
-			dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
-		imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
-			dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
 	}
 
 	/*
@@ -1176,7 +1200,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		if (ret < 0) {
 			dev_err(&pdev->dev, "could not claim irq %u\n",
 					ssi_private->irq);
-			goto error_clk;
+			goto error_irq;
 		}
 	}
 
@@ -1268,11 +1292,9 @@ error_dbgfs:
 error_dev:
 	device_remove_file(&pdev->dev, dev_attr);
 
-error_clk:
+error_irq:
 	if (ssi_private->ssi_on_imx) {
-		if (!IS_ERR(ssi_private->baudclk))
-			clk_disable_unprepare(ssi_private->baudclk);
-		clk_disable_unprepare(ssi_private->clk);
+		fsl_ssi_imx_clean(pdev, ssi_private);
 	}
 
 error_irqmap:
@@ -1291,11 +1313,10 @@ static int fsl_ssi_remove(struct platform_device *pdev)
 	if (!ssi_private->new_binding)
 		platform_device_unregister(ssi_private->pdev);
 	snd_soc_unregister_component(&pdev->dev);
-	if (ssi_private->ssi_on_imx) {
-		if (!IS_ERR(ssi_private->baudclk))
-			clk_disable_unprepare(ssi_private->baudclk);
-		clk_disable_unprepare(ssi_private->clk);
-	}
+
+	if (ssi_private->ssi_on_imx)
+		fsl_ssi_imx_clean(pdev, ssi_private);
+
 	if (ssi_private->irq_stats)
 		irq_dispose_mapping(ssi_private->irq);
 
-- 
1.9.0

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

* [PATCH v2 06/16] ASoC: fsl-ssi: Remove useless DMA code
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (4 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 05/16] ASoC: fsl-ssi: Move imx-specific probe to seperate function Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 07/16] ASoC: fsl-ssi: baud clock error handling Markus Pargmann
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Simplify dma DT property handling. fsl,ssi-dma-events is not used
anymore. It passes invalid data to imx_pcm_dma_params_init_data() which
copies some data into an imx dma struct. This struct is never used in
imx-dma or imx-sdma because of generic OF DMA handling. The
"fsl,ssi-dma-events" is not used anywhere in dts files.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 40 +++-------------------------------------
 1 file changed, 3 insertions(+), 37 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index b28f874..fcc73d3 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -168,8 +168,6 @@ struct fsl_ssi_private {
 	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;
 	/* Register values for rx/tx configuration */
 	struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
@@ -966,8 +964,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 		struct fsl_ssi_private *ssi_private)
 {
 	struct device_node *np = pdev->dev.of_node;
-	u32 dma_events[2], dmas[4];
-	bool shared;
+	u32 dmas[4];
 	int ret;
 
 	ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
@@ -1003,26 +1000,9 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 			offsetof(struct ccsr_ssi, stx0);
 	ssi_private->dma_params_rx.addr = ssi_private->ssi_phys +
 			offsetof(struct ccsr_ssi, srx0);
-	ssi_private->dma_params_tx.filter_data = &ssi_private->filter_data_tx;
-	ssi_private->dma_params_rx.filter_data = &ssi_private->filter_data_rx;
 
-	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 but fsl-ssi is configured to use DMA\n");
-			goto error_dma_events;
-		}
-	}
-	/* Should this be merge with the above? */
-	if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
-			&& dmas[2] == IMX_DMATYPE_SSI_DUAL) {
+	ret = !of_property_read_u32_array(np, "dmas", dmas, 4);
+	if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
 		ssi_private->use_dual_fifo = true;
 		/* When using dual fifo mode, we need to keep watermark
 		 * as even numbers due to dma script limitation.
@@ -1031,21 +1011,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 		ssi_private->dma_params_rx.maxburst &= ~0x1;
 	}
 
-	shared = of_device_is_compatible(of_get_parent(np), "fsl,spba-bus");
-
-	imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
-		dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
-	imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
-		dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
-
 	return 0;
-
-error_dma_events:
-	if (!IS_ERR(ssi_private->baudclk))
-		clk_disable_unprepare(ssi_private->baudclk);
-	clk_disable_unprepare(ssi_private->clk);
-
-	return ret;
 }
 
 static void fsl_ssi_imx_clean(struct platform_device *pdev,
-- 
1.9.0

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

* [PATCH v2 07/16] ASoC: fsl-ssi: baud clock error handling
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (5 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 06/16] ASoC: fsl-ssi: Remove useless DMA code Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 08/16] ASoC: fsl-ssi: Cleanup probe function Markus Pargmann
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

This patch adds error handling for baud clock. It checks for PROBE_DEFER
error codes and handles clk_prepare_enable() errors.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index fcc73d3..663ac8b 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -984,11 +984,19 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 	 * and, instead, abandon MASTER mode that needs baud clock.
 	 */
 	ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
-	if (IS_ERR(ssi_private->baudclk))
+	if (IS_ERR(ssi_private->baudclk)) {
+		ret = PTR_ERR(ssi_private->baudclk);
+		if (ret == -EPROBE_DEFER)
+			goto error_baud_clk;
 		dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
-			 PTR_ERR(ssi_private->baudclk));
-	else
-		clk_prepare_enable(ssi_private->baudclk);
+				PTR_ERR(ssi_private->baudclk));
+	} else {
+		ret = clk_prepare_enable(ssi_private->baudclk);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to enable baud clock\n");
+			goto error_baud_clk;
+		}
+	}
 
 	/*
 	 * We have burstsize be "fifo_depth - 2" to match the SSI
@@ -1012,6 +1020,11 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 	}
 
 	return 0;
+
+error_baud_clk:
+	clk_disable_unprepare(ssi_private->clk);
+
+	return ret;
 }
 
 static void fsl_ssi_imx_clean(struct platform_device *pdev,
-- 
1.9.0

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

* [PATCH v2 08/16] ASoC: fsl-ssi: Cleanup probe function
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (6 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 07/16] ASoC: fsl-ssi: baud clock error handling Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 09/16] ASoC: fsl-ssi: Remove unnecessary variables from ssi_private Markus Pargmann
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Reorder the probe function to be able to move the second imx-specific
block to the seperate imx probe function. The patch also removes some
comments/variables/code that are not used anymore or could be simply
replaced by other variables.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 109 ++++++++++++++++++++++--------------------------
 1 file changed, 49 insertions(+), 60 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 663ac8b..b0c04ef 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -159,7 +159,6 @@ struct fsl_ssi_private {
 	bool imx_ac97;
 	bool use_dma;
 	bool baudclk_locked;
-	bool irq_stats;
 	bool offline_config;
 	bool use_dual_fifo;
 	u8 i2s_mode;
@@ -961,7 +960,7 @@ static void make_lowercase(char *s)
 }
 
 static int fsl_ssi_imx_probe(struct platform_device *pdev,
-		struct fsl_ssi_private *ssi_private)
+		struct fsl_ssi_private *ssi_private, void __iomem *iomem)
 {
 	struct device_node *np = pdev->dev.of_node;
 	u32 dmas[4];
@@ -1019,8 +1018,37 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 		ssi_private->dma_params_rx.maxburst &= ~0x1;
 	}
 
+	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 = iomem;
+		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_pcm;
+	} else {
+		ret = imx_pcm_dma_init(pdev);
+		if (ret)
+			goto error_pcm;
+	}
+
 	return 0;
 
+error_pcm:
+	if (!IS_ERR(ssi_private->baudclk))
+		clk_disable_unprepare(ssi_private->baudclk);
+
 error_baud_clk:
 	clk_disable_unprepare(ssi_private->clk);
 
@@ -1030,6 +1058,8 @@ error_baud_clk:
 static void fsl_ssi_imx_clean(struct platform_device *pdev,
 		struct fsl_ssi_private *ssi_private)
 {
+	if (!ssi_private->use_dma)
+		imx_pcm_fiq_exit(pdev);
 	if (!IS_ERR(ssi_private->baudclk))
 		clk_disable_unprepare(ssi_private->baudclk);
 	clk_disable_unprepare(ssi_private->clk);
@@ -1039,7 +1069,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 {
 	struct fsl_ssi_private *ssi_private;
 	int ret = 0;
-	struct device_attribute *dev_attr = NULL;
 	struct device_node *np = pdev->dev.of_node;
 	const struct of_device_id *of_id;
 	enum fsl_ssi_type hw_type;
@@ -1132,6 +1161,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	ssi_private->baudclk_locked = false;
 	spin_lock_init(&ssi_private->baudclk_lock);
 
+	dev_set_drvdata(&pdev->dev, ssi_private);
+
 	/*
 	 * imx51 and later SoCs have a slightly different IP that allows the
 	 * SSI configuration while the SSI unit is running.
@@ -1162,20 +1193,22 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 			hw_type == FSL_SSI_MX35) {
 		ssi_private->ssi_on_imx = true;
 
-		ret = fsl_ssi_imx_probe(pdev, ssi_private);
+		ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi);
 		if (ret)
 			goto error_irqmap;
 	}
 
-	/*
-	 * Enable interrupts only for MCP8610 and MX51. The other MXs have
-	 * different writeable interrupt status registers.
-	 */
+	ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component,
+					 &ssi_private->cpu_dai_drv, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
+		goto error_asoc_register;
+	}
+
 	if (ssi_private->use_dma) {
 		ret = devm_request_irq(&pdev->dev, ssi_private->irq,
 					fsl_ssi_isr, 0, ssi_private->name,
 					ssi_private);
-		ssi_private->irq_stats = true;
 		if (ret < 0) {
 			dev_err(&pdev->dev, "could not claim irq %u\n",
 					ssi_private->irq);
@@ -1183,46 +1216,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* Register with ASoC */
-	dev_set_drvdata(&pdev->dev, ssi_private);
-
-	ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component,
-					 &ssi_private->cpu_dai_drv, 1);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
-		goto error_dev;
-	}
-
 	ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev);
 	if (ret)
-		goto error_dbgfs;
-
-	if (ssi_private->ssi_on_imx) {
-		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_pcm;
-		} else {
-			ret = imx_pcm_dma_init(pdev);
-			if (ret)
-				goto error_pcm;
-		}
-	}
+		goto error_asoc_register;
 
 	/*
 	 * If codec-handle property is missing from SSI node, we assume
@@ -1252,32 +1248,25 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	if (IS_ERR(ssi_private->pdev)) {
 		ret = PTR_ERR(ssi_private->pdev);
 		dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
-		goto error_dai;
+		goto error_sound_card;
 	}
 
 done:
 	return 0;
 
-error_dai:
-	if (ssi_private->ssi_on_imx && !ssi_private->use_dma)
-		imx_pcm_fiq_exit(pdev);
-
-error_pcm:
+error_sound_card:
 	fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);
 
-error_dbgfs:
+error_irq:
 	snd_soc_unregister_component(&pdev->dev);
 
-error_dev:
-	device_remove_file(&pdev->dev, dev_attr);
-
-error_irq:
+error_asoc_register:
 	if (ssi_private->ssi_on_imx) {
 		fsl_ssi_imx_clean(pdev, ssi_private);
 	}
 
 error_irqmap:
-	if (ssi_private->irq_stats)
+	if (ssi_private->use_dma)
 		irq_dispose_mapping(ssi_private->irq);
 
 	return ret;
@@ -1296,7 +1285,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
 	if (ssi_private->ssi_on_imx)
 		fsl_ssi_imx_clean(pdev, ssi_private);
 
-	if (ssi_private->irq_stats)
+	if (ssi_private->use_dma)
 		irq_dispose_mapping(ssi_private->irq);
 
 	return 0;
-- 
1.9.0

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

* [PATCH v2 09/16] ASoC: fsl-ssi: Remove unnecessary variables from ssi_private
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (7 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 08/16] ASoC: fsl-ssi: Cleanup probe function Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 10/16] ASoC: fsl-ssi: reorder and document fsl_ssi_private Markus Pargmann
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

There are some variables defined in struct fsl_ssi_private that describe
states that are also described by other variables.

This patch adds some helper functions that return exactly the same
information based on available variables. This helps to clean up struct
fsl_ssi_private and remove them from the probe function.

It also removes some not really used variables (new_binding, name).

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 117 ++++++++++++++++++++++++++----------------------
 1 file changed, 64 insertions(+), 53 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index b0c04ef..126f277 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -143,7 +143,6 @@ struct fsl_ssi_rxtx_reg_val {
  * @cpu_dai: the CPU DAI for this device
  * @dev_attr: the sysfs device attribute structure
  * @stats: SSI statistics
- * @name: name for this device
  */
 struct fsl_ssi_private {
 	struct ccsr_ssi __iomem *ssi;
@@ -152,14 +151,11 @@ struct fsl_ssi_private {
 	unsigned int fifo_depth;
 	struct snd_soc_dai_driver cpu_dai_drv;
 	struct platform_device *pdev;
+	unsigned int dai_fmt;
 
 	enum fsl_ssi_type hw_type;
-	bool new_binding;
-	bool ssi_on_imx;
-	bool imx_ac97;
 	bool use_dma;
 	bool baudclk_locked;
-	bool offline_config;
 	bool use_dual_fifo;
 	u8 i2s_mode;
 	spinlock_t baudclk_lock;
@@ -172,8 +168,6 @@ struct fsl_ssi_private {
 	struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
 
 	struct fsl_ssi_dbg dbg_stats;
-
-	char name[1];
 };
 
 static const struct of_device_id fsl_ssi_ids[] = {
@@ -185,6 +179,54 @@ static const struct of_device_id fsl_ssi_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
 
+static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
+{
+	return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
+}
+
+static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private)
+{
+	switch (ssi_private->hw_type) {
+	case FSL_SSI_MX21:
+	case FSL_SSI_MX35:
+	case FSL_SSI_MX51:
+		return true;
+	case FSL_SSI_MCP8610:
+		return false;
+	}
+
+	return false;
+}
+
+/*
+ * imx51 and later SoCs have a slightly different IP that allows the
+ * SSI configuration while the SSI unit is running.
+ *
+ * More important, it is necessary on those SoCs to configure the
+ * sperate TX/RX DMA bits just before starting the stream
+ * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi
+ * sends any DMA requests to the SDMA unit, otherwise it is not defined
+ * how the SDMA unit handles the DMA request.
+ *
+ * SDMA units are present on devices starting at imx35 but the imx35
+ * reference manual states that the DMA bits should not be changed
+ * while the SSI unit is running (SSIEN). So we support the necessary
+ * online configuration of fsl-ssi starting at imx51.
+ */
+static bool fsl_ssi_offline_config(struct fsl_ssi_private *ssi_private)
+{
+	switch (ssi_private->hw_type) {
+	case FSL_SSI_MCP8610:
+	case FSL_SSI_MX21:
+	case FSL_SSI_MX35:
+		return true;
+	case FSL_SSI_MX51:
+		return false;
+	}
+
+	return true;
+}
+
 /**
  * fsl_ssi_isr: SSI interrupt handler
  *
@@ -290,7 +332,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 	 * reconfiguration, so we have to enable all necessary flags at once
 	 * even if we do not use them later (capture and playback configuration)
 	 */
-	if (ssi_private->offline_config) {
+	if (fsl_ssi_offline_config(ssi_private)) {
 		if ((enable && !nr_active_streams) ||
 				(!enable && nr_active_streams == 1))
 			fsl_ssi_rxtx_config(ssi_private, enable);
@@ -363,7 +405,7 @@ static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private)
 	reg->tx.stcr = CCSR_SSI_STCR_TFEN0;
 	reg->tx.scr = 0;
 
-	if (!ssi_private->imx_ac97) {
+	if (!fsl_ssi_is_ac97(ssi_private)) {
 		reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE;
 		reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN;
 		reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE;
@@ -428,7 +470,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 		snd_soc_dai_get_drvdata(rtd->cpu_dai);
 	unsigned long flags;
 
-	if (!dai->active && !ssi_private->imx_ac97) {
+	if (!dai->active && !fsl_ssi_is_ac97(ssi_private)) {
 		spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
 		ssi_private->baudclk_locked = false;
 		spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
@@ -494,7 +536,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 	else
 		write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
 
-	if (!ssi_private->imx_ac97)
+	if (!fsl_ssi_is_ac97(ssi_private))
 		write_ssi_mask(&ssi->scr,
 				CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
 				channels == 1 ? 0 : ssi_private->i2s_mode);
@@ -512,6 +554,8 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 	u32 strcr = 0, stcr, srcr, scr, mask;
 	u8 wm;
 
+	ssi_private->dai_fmt = fmt;
+
 	fsl_ssi_setup_reg_vals(ssi_private);
 
 	scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
@@ -810,7 +854,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 		else
 			fsl_ssi_rx_config(ssi_private, false);
 
-		if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
+		if (!fsl_ssi_is_ac97(ssi_private) && (read_ssi(&ssi->scr) &
 					(CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
 			spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
 			ssi_private->baudclk_locked = false;
@@ -822,7 +866,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 		return -EINVAL;
 	}
 
-	if (ssi_private->imx_ac97) {
+	if (fsl_ssi_is_ac97(ssi_private)) {
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
 		else
@@ -836,7 +880,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 && ssi_private->use_dma) {
+	if (fsl_ssi_on_imx(ssi_private) && ssi_private->use_dma) {
 		dai->playback_dma_data = &ssi_private->dma_params_tx;
 		dai->capture_dma_data = &ssi_private->dma_params_rx;
 	}
@@ -1114,7 +1158,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 				sizeof(fsl_ssi_ac97_dai));
 
 		fsl_ac97_data = ssi_private;
-		ssi_private->imx_ac97 = true;
 
 		snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev);
 	} else {
@@ -1163,36 +1206,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	dev_set_drvdata(&pdev->dev, ssi_private);
 
-	/*
-	 * imx51 and later SoCs have a slightly different IP that allows the
-	 * SSI configuration while the SSI unit is running.
-	 *
-	 * More important, it is necessary on those SoCs to configure the
-	 * sperate TX/RX DMA bits just before starting the stream
-	 * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi
-	 * sends any DMA requests to the SDMA unit, otherwise it is not defined
-	 * how the SDMA unit handles the DMA request.
-	 *
-	 * SDMA units are present on devices starting at imx35 but the imx35
-	 * reference manual states that the DMA bits should not be changed
-	 * while the SSI unit is running (SSIEN). So we support the necessary
-	 * online configuration of fsl-ssi starting at imx51.
-	 */
-	switch (hw_type) {
-	case FSL_SSI_MCP8610:
-	case FSL_SSI_MX21:
-	case FSL_SSI_MX35:
-		ssi_private->offline_config = true;
-		break;
-	case FSL_SSI_MX51:
-		ssi_private->offline_config = false;
-		break;
-	}
-
-	if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
-			hw_type == FSL_SSI_MX35) {
-		ssi_private->ssi_on_imx = true;
-
+	if (fsl_ssi_on_imx(ssi_private)) {
 		ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi);
 		if (ret)
 			goto error_irqmap;
@@ -1207,7 +1221,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	if (ssi_private->use_dma) {
 		ret = devm_request_irq(&pdev->dev, ssi_private->irq,
-					fsl_ssi_isr, 0, ssi_private->name,
+					fsl_ssi_isr, 0, dev_name(&pdev->dev),
 					ssi_private);
 		if (ret < 0) {
 			dev_err(&pdev->dev, "could not claim irq %u\n",
@@ -1225,10 +1239,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	 * that the machine driver uses new binding which does not require
 	 * SSI driver to trigger machine driver's probe.
 	 */
-	if (!of_get_property(np, "codec-handle", NULL)) {
-		ssi_private->new_binding = true;
+	if (!of_get_property(np, "codec-handle", NULL))
 		goto done;
-	}
 
 	/* Trigger the machine driver's probe function.  The platform driver
 	 * name of the machine driver is taken from /compatible property of the
@@ -1261,9 +1273,8 @@ error_irq:
 	snd_soc_unregister_component(&pdev->dev);
 
 error_asoc_register:
-	if (ssi_private->ssi_on_imx) {
+	if (fsl_ssi_on_imx(ssi_private))
 		fsl_ssi_imx_clean(pdev, ssi_private);
-	}
 
 error_irqmap:
 	if (ssi_private->use_dma)
@@ -1278,11 +1289,11 @@ static int fsl_ssi_remove(struct platform_device *pdev)
 
 	fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);
 
-	if (!ssi_private->new_binding)
+	if (ssi_private->pdev)
 		platform_device_unregister(ssi_private->pdev);
 	snd_soc_unregister_component(&pdev->dev);
 
-	if (ssi_private->ssi_on_imx)
+	if (fsl_ssi_on_imx(ssi_private))
 		fsl_ssi_imx_clean(pdev, ssi_private);
 
 	if (ssi_private->use_dma)
-- 
1.9.0

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

* [PATCH v2 10/16] ASoC: fsl-ssi: reorder and document fsl_ssi_private
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (8 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 09/16] ASoC: fsl-ssi: Remove unnecessary variables from ssi_private Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 11/16] ASoC: fsl-ssi: Fix register values when disabling Markus Pargmann
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Reorder all variables in struct fsl_ssi_private to have groups that make
sense together. The patch also updates the struct documentation.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 61 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 17 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 126f277..c8002d3 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -135,37 +135,64 @@ struct fsl_ssi_rxtx_reg_val {
 /**
  * fsl_ssi_private: per-SSI private data
  *
- * @ssi: pointer to the SSI's registers
- * @ssi_phys: physical address of the SSI registers
+ * @regs: Registers regmap pointer
  * @irq: IRQ of this SSI
- * @playback: the number of playback streams opened
- * @capture: the number of capture streams opened
- * @cpu_dai: the CPU DAI for this device
- * @dev_attr: the sysfs device attribute structure
- * @stats: SSI statistics
+ * @cpu_dai_drv: CPU DAI driver for this device
+ *
+ * @hw_type: Hardware type this device is used in
+ * @dai_fmt: DAI configuration this device is currently used with
+ * @i2s_mode: i2s and network mode configuration of the device. Is used to
+ * switch between normal and i2s/network mode
+ * mode depending on the number of channels
+ * @use_dma: DMA is used or FIQ with stream filter
+ * @use_dual_fifo: DMA with support for both FIFOs used
+ * @fifo_deph: Depth of the SSI FIFOs
+ * @rxtx_reg_val: Specific register settings for receive/transmit configuration
+ *
+ * @clk: SSI clock
+ * @baudclk: SSI baud clock for master mode
+ * @baudclk_locked: SSI baudclk is locked because it is in use
+ * @baudclk_lock: spinlock for baudclk_locked variable
+ *
+ * @dma_params_tx: DMA transmit parameters
+ * @dma_params_rx: DMA receive parameters
+ * @ssi_phys: physical address of the SSI registers
+ *
+ * @fiq_params: FIQ stream filtering parameters
+ *
+ * @pdev: Pointer to pdev used for deprecated fsl-ssi sound card
+ *
+ * @dbg_stats: Debugging statistics
  */
 struct fsl_ssi_private {
 	struct ccsr_ssi __iomem *ssi;
-	dma_addr_t ssi_phys;
 	unsigned int irq;
-	unsigned int fifo_depth;
 	struct snd_soc_dai_driver cpu_dai_drv;
-	struct platform_device *pdev;
-	unsigned int dai_fmt;
 
 	enum fsl_ssi_type hw_type;
+	unsigned int dai_fmt;
+	u8 i2s_mode;
 	bool use_dma;
-	bool baudclk_locked;
 	bool use_dual_fifo;
-	u8 i2s_mode;
-	spinlock_t baudclk_lock;
-	struct clk *baudclk;
+	unsigned int fifo_depth;
+	struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
+
 	struct clk *clk;
+	struct clk *baudclk;
+	bool baudclk_locked;
+	spinlock_t baudclk_lock;
+
+	/* DMA params */
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
 	struct snd_dmaengine_dai_dma_data dma_params_rx;
+	dma_addr_t ssi_phys;
+
+	/* params for non-dma FIQ stream filtered mode */
 	struct imx_pcm_fiq_params fiq_params;
-	/* Register values for rx/tx configuration */
-	struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
+
+	/* Used when using fsl-ssi as sound-card. This is only used by ppc and
+	 * should be replaced with simple-sound-card. */
+	struct platform_device *pdev;
 
 	struct fsl_ssi_dbg dbg_stats;
 };
-- 
1.9.0

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

* [PATCH v2 11/16] ASoC: fsl-ssi: Fix register values when disabling
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (9 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 10/16] ASoC: fsl-ssi: reorder and document fsl_ssi_private Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-04-03 22:11   ` Mark Brown
  2014-03-15 12:44 ` [PATCH v2 12/16] ASoC: fsl-ssi: Only enable baudclk when used Markus Pargmann
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

The bits we have to clear when disabling are different when the other
stream is still active.

This patch fixes the calculation of new register values after disabling
one stream. It also adds a more detailed description of the new register
value calculation.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index c8002d3..0d10b7e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -329,6 +329,26 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
 }
 
 /*
+ * Calculate the bits that have to be disabled for the current stream that is
+ * getting disabled. This keeps the bits enabled that are necessary for the
+ * second stream to work if 'stream_active' is true.
+ *
+ * Detailed calculation:
+ * These are the values that need to be active after disabling. For non-active
+ * second stream, this is 0:
+ *	vals_stream * !!stream_active
+ *
+ * The following computes the overall differences between the setup for the
+ * to-disable stream and the active stream, a simple XOR:
+ *	vals_disable ^ (vals_stream * !!(stream_active))
+ *
+ * The full expression adds a mask on all values we care about
+ */
+#define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \
+	((vals_disable) & \
+	 ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active))))
+
+/*
  * Enable/Disable a ssi configuration. You have to pass either
  * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
  */
@@ -340,6 +360,12 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 	u32 scr_val = read_ssi(&ssi->scr);
 	int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) +
 				!!(scr_val & CCSR_SSI_SCR_RE);
+	int keep_active;
+
+	if (nr_active_streams - 1 > 0)
+		keep_active = 1;
+	else
+		keep_active = 0;
 
 	/* Find the other direction values rx or tx which we do not want to
 	 * modify */
@@ -350,7 +376,8 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 
 	/* If vals should be disabled, start with disabling the unit */
 	if (!enable) {
-		u32 scr = vals->scr & (vals->scr ^ avals->scr);
+		u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr,
+				keep_active);
 		write_ssi_mask(&ssi->scr, scr, 0);
 	}
 
@@ -361,7 +388,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 	 */
 	if (fsl_ssi_offline_config(ssi_private)) {
 		if ((enable && !nr_active_streams) ||
-				(!enable && nr_active_streams == 1))
+				(!enable && !keep_active))
 			fsl_ssi_rxtx_config(ssi_private, enable);
 
 		goto config_done;
@@ -390,9 +417,12 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 		 */
 
 		/* These assignments are simply vals without bits set in avals*/
-		sier = vals->sier & (vals->sier ^ avals->sier);
-		srcr = vals->srcr & (vals->srcr ^ avals->srcr);
-		stcr = vals->stcr & (vals->stcr ^ avals->stcr);
+		sier = fsl_ssi_disable_val(vals->sier, avals->sier,
+				keep_active);
+		srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr,
+				keep_active);
+		stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr,
+				keep_active);
 
 		write_ssi_mask(&ssi->srcr, srcr, 0);
 		write_ssi_mask(&ssi->stcr, stcr, 0);
-- 
1.9.0

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

* [PATCH v2 12/16] ASoC: fsl-ssi: Only enable baudclk when used
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (10 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 11/16] ASoC: fsl-ssi: Fix register values when disabling Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 13/16] ASoC: fsl-ssi: Set default dai-fmts Markus Pargmann
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

Enable baudclk only when it is used. The baudclk should not be enabled
all the time when the SSI driver is active. Instead this patch
enables/disables the clock in the trigger function. It also limits the
use of this clock to cases where the SSI unit is the I2S master.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 77 +++++++++++++++++++++++++++++++------------------
 1 file changed, 49 insertions(+), 28 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 0d10b7e..ab17055 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -211,6 +211,12 @@ static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
 	return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
 }
 
+static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private)
+{
+	return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
+		SND_SOC_DAIFMT_CBS_CFS;
+}
+
 static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private)
 {
 	switch (ssi_private->hw_type) {
@@ -525,13 +531,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct fsl_ssi_private *ssi_private =
 		snd_soc_dai_get_drvdata(rtd->cpu_dai);
-	unsigned long flags;
-
-	if (!dai->active && !fsl_ssi_is_ac97(ssi_private)) {
-		spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
-		ssi_private->baudclk_locked = false;
-		spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
-	}
 
 	/* When using dual fifo mode, it is safer to ensure an even period
 	 * size. If appearing to an odd number while DMA always starts its
@@ -613,6 +612,9 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 
 	ssi_private->dai_fmt = fmt;
 
+	if (fsl_ssi_is_i2s_master(ssi_private) && IS_ERR(ssi_private->baudclk))
+		return -EINVAL;
+
 	fsl_ssi_setup_reg_vals(ssi_private);
 
 	scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
@@ -766,8 +768,10 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 	u64 sub, savesub = 100000;
 
 	/* Don't apply it to any non-baudclk circumstance */
-	if (IS_ERR(ssi_private->baudclk))
+	if (IS_ERR(ssi_private->baudclk)) {
+		dev_err(cpu_dai->dev, "Failed to set clock, no baudclk present\n");
 		return -EINVAL;
+	}
 
 	/* It should be already enough to divide clock by setting pm alone */
 	psr = 0;
@@ -833,7 +837,10 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 			dev_err(cpu_dai->dev, "failed to set baudclk rate\n");
 			return -EINVAL;
 		}
-		ssi_private->baudclk_locked = true;
+	} else {
+		spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
+		dev_err(cpu_dai->dev, "Failed to set baudclk rate because it is in use\n");
+		return -EBUSY;
 	}
 	spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
 
@@ -894,10 +901,34 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
 	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 	unsigned long flags;
+	u32 val;
+	int nr_active;
+
+	val = read_ssi(&ssi->scr);
+	nr_active = !!(val & CCSR_SSI_SCR_TE) + !!(val & CCSR_SSI_SCR_RE);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (fsl_ssi_is_i2s_master(ssi_private) && nr_active == 0) {
+			int ret;
+
+			spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
+			ret = clk_prepare_enable(ssi_private->baudclk);
+			if (ret) {
+				spin_unlock_irqrestore(
+						&ssi_private->baudclk_lock,
+						flags);
+				dev_err(rtd->cpu_dai->dev,
+						"Failed to enable baud clock (%d)\n",
+						ret);
+				return ret;
+			}
+			ssi_private->baudclk_locked = true;
+			spin_unlock_irqrestore(&ssi_private->baudclk_lock,
+					flags);
+		}
+
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			fsl_ssi_tx_config(ssi_private, true);
 		else
@@ -911,11 +942,14 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 		else
 			fsl_ssi_rx_config(ssi_private, false);
 
-		if (!fsl_ssi_is_ac97(ssi_private) && (read_ssi(&ssi->scr) &
-					(CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
+		if (fsl_ssi_is_i2s_master(ssi_private) && nr_active == 1) {
 			spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
-			ssi_private->baudclk_locked = false;
-			spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
+			if (ssi_private->baudclk_locked) {
+				clk_disable_unprepare(ssi_private->baudclk);
+				ssi_private->baudclk_locked = false;
+			}
+			spin_unlock_irqrestore(&ssi_private->baudclk_lock,
+					flags);
 		}
 		break;
 
@@ -1090,12 +1124,6 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 			goto error_baud_clk;
 		dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
 				PTR_ERR(ssi_private->baudclk));
-	} else {
-		ret = clk_prepare_enable(ssi_private->baudclk);
-		if (ret) {
-			dev_err(&pdev->dev, "Failed to enable baud clock\n");
-			goto error_baud_clk;
-		}
 	}
 
 	/*
@@ -1137,19 +1165,15 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 
 		ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
 		if (ret)
-			goto error_pcm;
+			goto error_baud_clk;
 	} else {
 		ret = imx_pcm_dma_init(pdev);
 		if (ret)
-			goto error_pcm;
+			goto error_baud_clk;
 	}
 
 	return 0;
 
-error_pcm:
-	if (!IS_ERR(ssi_private->baudclk))
-		clk_disable_unprepare(ssi_private->baudclk);
-
 error_baud_clk:
 	clk_disable_unprepare(ssi_private->clk);
 
@@ -1161,8 +1185,6 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev,
 {
 	if (!ssi_private->use_dma)
 		imx_pcm_fiq_exit(pdev);
-	if (!IS_ERR(ssi_private->baudclk))
-		clk_disable_unprepare(ssi_private->baudclk);
 	clk_disable_unprepare(ssi_private->clk);
 }
 
@@ -1258,7 +1280,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
                 /* Older 8610 DTs didn't have the fifo-depth property */
 		ssi_private->fifo_depth = 8;
 
-	ssi_private->baudclk_locked = false;
 	spin_lock_init(&ssi_private->baudclk_lock);
 
 	dev_set_drvdata(&pdev->dev, ssi_private);
-- 
1.9.0

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

* [PATCH v2 13/16] ASoC: fsl-ssi: Set default dai-fmts
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (11 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 12/16] ASoC: fsl-ssi: Only enable baudclk when used Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 14/16] ASoC: fsl-ssi: Transmit enable synchronization Markus Pargmann
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

The old fsl_ssi_setup function was replaced by a set_dai_fmt function.
As the fsl-ssi driver has a 'fsl,mode' DT binding we should keep the
backward compatibility for the moment.

This patch sets default dai-fmt for backwards compatibility and
initializes the DAI using _fsl_ssi_set_dai_fmt().

The fsl,mode property parsing is moved, so it can directly set the
correct dai-fmt in ssi_private.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 43 ++++++++++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index ab17055..bb6d607 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -600,12 +600,9 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-/**
- * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format.
- */
-static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private,
+		unsigned int fmt)
 {
-	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 	u32 strcr = 0, stcr, srcr, scr, mask;
 	u8 wm;
@@ -746,6 +743,17 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 		fsl_ssi_setup_ac97(ssi_private);
 
 	return 0;
+
+}
+
+/**
+ * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format.
+ */
+static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
+
+	return _fsl_ssi_set_dai_fmt(ssi_private, fmt);
 }
 
 /**
@@ -1199,7 +1207,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	const uint32_t *iprop;
 	struct resource res;
 	char name[64];
-	bool ac97 = false;
 
 	/* SSIs that are not connected on the board should have a
 	 *      status = "disabled"
@@ -1213,14 +1220,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		return -EINVAL;
 	hw_type = (enum fsl_ssi_type) of_id->data;
 
-	sprop = of_get_property(np, "fsl,mode", NULL);
-	if (!sprop) {
-		dev_err(&pdev->dev, "fsl,mode property is necessary\n");
-		return -EINVAL;
-	}
-	if (!strcmp(sprop, "ac97-slave"))
-		ac97 = true;
-
 	ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private),
 			GFP_KERNEL);
 	if (!ssi_private) {
@@ -1228,11 +1227,22 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	sprop = of_get_property(np, "fsl,mode", NULL);
+	if (!sprop) {
+		dev_err(&pdev->dev, "fsl,mode property is necessary\n");
+		return -EINVAL;
+	}
+	if (!strcmp(sprop, "ac97-slave"))
+		ssi_private->dai_fmt = SND_SOC_DAIFMT_AC97;
+	else if (!strcmp(sprop, "i2s-slave"))
+		ssi_private->dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_CBM_CFM;
+
 	ssi_private->use_dma = !of_property_read_bool(np,
 			"fsl,fiq-stream-filter");
 	ssi_private->hw_type = hw_type;
 
-	if (ac97) {
+	if (fsl_ssi_is_ac97(ssi_private)) {
 		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
 				sizeof(fsl_ssi_ac97_dai));
 
@@ -1342,6 +1352,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 done:
+	if (ssi_private->dai_fmt)
+		_fsl_ssi_set_dai_fmt(ssi_private, ssi_private->dai_fmt);
+
 	return 0;
 
 error_sound_card:
-- 
1.9.0

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

* [PATCH v2 14/16] ASoC: fsl-ssi: Transmit enable synchronization
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (12 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 13/16] ASoC: fsl-ssi: Set default dai-fmts Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 15/16] ASoC: fsl-ssi: Update binding documentation Markus Pargmann
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

When the fsl-ssi unit is used in i2s slave mode, it is possible that the
SSI unit starts transmitting data on the wrong channel. This happens
because the SSI does not synchronize with the left-right-clock by
default.

This patch enables transmit enable synchronization.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 1 +
 sound/soc/fsl/fsl_ssi.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index bb6d607..6095a15 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -615,6 +615,7 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private,
 	fsl_ssi_setup_reg_vals(ssi_private);
 
 	scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
+	scr |= CCSR_SSI_SCR_SYNC_TX_FS;
 
 	mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR |
 		CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL |
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index 2e95dd7..71c3e7e 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -39,6 +39,7 @@ struct ccsr_ssi {
 	__be32 saccdis; /* 0x.0058 - SSI AC97 Channel Disable Register */
 };
 
+#define CCSR_SSI_SCR_SYNC_TX_FS		0x00001000
 #define CCSR_SSI_SCR_RFR_CLK_DIS	0x00000800
 #define CCSR_SSI_SCR_TFR_CLK_DIS	0x00000400
 #define CCSR_SSI_SCR_TCH_EN		0x00000100
-- 
1.9.0

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

* [PATCH v2 15/16] ASoC: fsl-ssi: Update binding documentation
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (13 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 14/16] ASoC: fsl-ssi: Transmit enable synchronization Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 12:44 ` [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap Markus Pargmann
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

A lot of bindings where changed without an update of the binding
documentation. This patch adds those changes to the documentation.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 Documentation/devicetree/bindings/sound/fsl,ssi.txt | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index b93e9a9..3aa4a8f 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -20,15 +20,6 @@ Required properties:
                     have.
 - interrupt-parent: The phandle for the interrupt controller that
                     services interrupts for this device.
-- fsl,mode:         The operating mode for the SSI interface.
-                    "i2s-slave" - I2S mode, SSI is clock slave
-                    "i2s-master" - I2S mode, SSI is clock master
-                    "lj-slave" - left-justified mode, SSI is clock slave
-                    "lj-master" - l.j. mode, SSI is clock master
-                    "rj-slave" - right-justified mode, SSI is clock slave
-                    "rj-master" - r.j., SSI is clock master
-                    "ac97-slave" - AC97 mode, SSI is clock slave
-                    "ac97-master" - AC97 mode, SSI is clock master
 - fsl,playback-dma: Phandle to a node for the DMA channel to use for
                     playback of audio.  This is typically dictated by SOC
                     design.  See the notes below.
@@ -47,6 +38,9 @@ Required properties:
                     be connected together, and SRFS and STFS be connected
                     together.  This would still allow different sample sizes,
                     but not different sample rates.
+ - clocks:          "ipg" - Required clock for the SSI unit
+                    "baud" - Required clock for SSI master mode. Otherwise this
+		      clock is not used
 
 Required are also ac97 link bindings if ac97 is used. See
 Documentation/devicetree/bindings/sound/soc-ac97link.txt for the necessary
@@ -64,6 +58,15 @@ Optional properties:
 		    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,mode:         The operating mode for the SSI interface.
+                    "i2s-slave" - I2S mode, SSI is clock slave
+                    "i2s-master" - I2S mode, SSI is clock master
+                    "lj-slave" - left-justified mode, SSI is clock slave
+                    "lj-master" - l.j. mode, SSI is clock master
+                    "rj-slave" - right-justified mode, SSI is clock slave
+                    "rj-master" - r.j., SSI is clock master
+                    "ac97-slave" - AC97 mode, SSI is clock slave
+                    "ac97-master" - AC97 mode, SSI is clock master
 
 Child 'codec' node required properties:
 - compatible:       Compatible list, contains the name of the codec
-- 
1.9.0

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

* [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (14 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 15/16] ASoC: fsl-ssi: Update binding documentation Markus Pargmann
@ 2014-03-15 12:44 ` Markus Pargmann
  2014-03-15 14:43   ` Alexander Shiyan
  2014-03-18 12:44 ` [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Mark Brown
  2014-04-03 22:14 ` Mark Brown
  17 siblings, 1 reply; 34+ messages in thread
From: Markus Pargmann @ 2014-03-15 12:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	Markus Pargmann, linux-arm-kernel

This patch replaces the ssi specific functions write_ssi, read_ssi and
write_ssi_mask by standard regmap function calls.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/Kconfig   |   1 +
 sound/soc/fsl/fsl_ssi.c | 232 ++++++++++++++++++++++++++----------------------
 sound/soc/fsl/fsl_ssi.h |  50 +++++------
 3 files changed, 153 insertions(+), 130 deletions(-)

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 07f8f14..fbaea8a 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -3,6 +3,7 @@ config SND_SOC_FSL_SAI
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 
 config SND_SOC_FSL_SSI
+	select REGMAP_MMIO
 	tristate
 
 config SND_SOC_FSL_SPDIF
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 6095a15..7873815 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -53,25 +53,6 @@
 #include "fsl_ssi.h"
 #include "imx-pcm.h"
 
-#ifdef PPC
-#define read_ssi(addr)			 in_be32(addr)
-#define write_ssi(val, addr)		 out_be32(addr, val)
-#define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set)
-#else
-#define read_ssi(addr)			 readl(addr)
-#define write_ssi(val, addr)		 writel(val, addr)
-/*
- * FIXME: Proper locking should be added at write_ssi_mask caller level
- * to ensure this register read/modify/write sequence is race free.
- */
-static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
-{
-	u32 val = readl(addr);
-	val = (val & ~clear) | set;
-	writel(val, addr);
-}
-#endif
-
 /**
  * FSLSSI_I2S_RATES: sample rates supported by the I2S
  *
@@ -131,6 +112,15 @@ struct fsl_ssi_rxtx_reg_val {
 	struct fsl_ssi_reg_val rx;
 	struct fsl_ssi_reg_val tx;
 };
+static const struct regmap_config fsl_ssi_regconfig = {
+	.max_register = CCSR_SSI_SACCDIS,
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+#ifdef PPC
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+#endif
+};
 
 /**
  * fsl_ssi_private: per-SSI private data
@@ -165,7 +155,7 @@ struct fsl_ssi_rxtx_reg_val {
  * @dbg_stats: Debugging statistics
  */
 struct fsl_ssi_private {
-	struct ccsr_ssi __iomem *ssi;
+	struct regmap *regs;
 	unsigned int irq;
 	struct snd_soc_dai_driver cpu_dai_drv;
 
@@ -275,7 +265,7 @@ static bool fsl_ssi_offline_config(struct fsl_ssi_private *ssi_private)
 static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 {
 	struct fsl_ssi_private *ssi_private = dev_id;
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 	__be32 sisr;
 	__be32 sisr2;
 	__be32 sisr_write_mask = 0;
@@ -302,12 +292,12 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 	   were interrupted for.  We mask it with the Interrupt Enable register
 	   so that we only check for events that we're interested in.
 	 */
-	sisr = read_ssi(&ssi->sisr);
+	regmap_read(regs, CCSR_SSI_SISR, &sisr);
 
 	sisr2 = sisr & sisr_write_mask;
 	/* Clear the bits that we set */
 	if (sisr2)
-		write_ssi(sisr2, &ssi->sisr);
+		regmap_write(regs, CCSR_SSI_SISR, sisr2);
 
 	fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr);
 
@@ -320,17 +310,26 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
 		bool enable)
 {
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 	struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val;
 
 	if (enable) {
-		write_ssi_mask(&ssi->sier, 0, vals->rx.sier | vals->tx.sier);
-		write_ssi_mask(&ssi->srcr, 0, vals->rx.srcr | vals->tx.srcr);
-		write_ssi_mask(&ssi->stcr, 0, vals->rx.stcr | vals->tx.stcr);
+		regmap_update_bits(regs, CCSR_SSI_SIER,
+				vals->rx.sier | vals->tx.sier,
+				vals->rx.sier | vals->tx.sier);
+		regmap_update_bits(regs, CCSR_SSI_SRCR,
+				vals->rx.srcr | vals->tx.srcr,
+				vals->rx.srcr | vals->tx.srcr);
+		regmap_update_bits(regs, CCSR_SSI_STCR,
+				vals->rx.stcr | vals->tx.stcr,
+				vals->rx.stcr | vals->tx.stcr);
 	} else {
-		write_ssi_mask(&ssi->srcr, vals->rx.srcr | vals->tx.srcr, 0);
-		write_ssi_mask(&ssi->stcr, vals->rx.stcr | vals->tx.stcr, 0);
-		write_ssi_mask(&ssi->sier, vals->rx.sier | vals->tx.sier, 0);
+		regmap_update_bits(regs, CCSR_SSI_SRCR,
+				vals->rx.srcr | vals->tx.srcr, 0);
+		regmap_update_bits(regs, CCSR_SSI_STCR,
+				vals->rx.stcr | vals->tx.stcr, 0);
+		regmap_update_bits(regs, CCSR_SSI_SIER,
+				vals->rx.sier | vals->tx.sier, 0);
 	}
 }
 
@@ -361,13 +360,16 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
 static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 		struct fsl_ssi_reg_val *vals)
 {
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 	struct fsl_ssi_reg_val *avals;
-	u32 scr_val = read_ssi(&ssi->scr);
-	int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) +
-				!!(scr_val & CCSR_SSI_SCR_RE);
+	u32 scr_val;
+	int nr_active_streams;
 	int keep_active;
 
+	regmap_read(regs, CCSR_SSI_SCR, &scr_val);
+	nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) +
+			!!(scr_val & CCSR_SSI_SCR_RE);
+
 	if (nr_active_streams - 1 > 0)
 		keep_active = 1;
 	else
@@ -384,7 +386,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 	if (!enable) {
 		u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr,
 				keep_active);
-		write_ssi_mask(&ssi->scr, scr, 0);
+		regmap_update_bits(regs, CCSR_SSI_SCR, scr, 0);
 	}
 
 	/*
@@ -405,9 +407,9 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 	 * (online configuration)
 	 */
 	if (enable) {
-		write_ssi_mask(&ssi->sier, 0, vals->sier);
-		write_ssi_mask(&ssi->srcr, 0, vals->srcr);
-		write_ssi_mask(&ssi->stcr, 0, vals->stcr);
+		regmap_update_bits(regs, CCSR_SSI_SIER, vals->sier, vals->sier);
+		regmap_update_bits(regs, CCSR_SSI_SRCR, vals->srcr, vals->srcr);
+		regmap_update_bits(regs, CCSR_SSI_STCR, vals->stcr, vals->stcr);
 	} else {
 		u32 sier;
 		u32 srcr;
@@ -430,15 +432,15 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
 		stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr,
 				keep_active);
 
-		write_ssi_mask(&ssi->srcr, srcr, 0);
-		write_ssi_mask(&ssi->stcr, stcr, 0);
-		write_ssi_mask(&ssi->sier, sier, 0);
+		regmap_update_bits(regs, CCSR_SSI_SRCR, srcr, 0);
+		regmap_update_bits(regs, CCSR_SSI_STCR, stcr, 0);
+		regmap_update_bits(regs, CCSR_SSI_SIER, sier, 0);
 	}
 
 config_done:
 	/* Enabling of subunits is done after configuration */
 	if (enable)
-		write_ssi_mask(&ssi->scr, 0, vals->scr);
+		regmap_update_bits(regs, CCSR_SSI_SCR, vals->scr, vals->scr);
 }
 
 
@@ -489,32 +491,33 @@ static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private)
 
 static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
 {
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 
 	/*
 	 * 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);
+	regmap_write(regs, CCSR_SSI_STCCR,
+			CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13));
+	regmap_write(regs, CCSR_SSI_SRCCR,
+			CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13));
 
 	/*
 	 * 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);
+	regmap_write(regs, CCSR_SSI_SACNT,
+			CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV);
+	regmap_write(regs, CCSR_SSI_SACCDIS, 0xff);
+	regmap_write(regs, CCSR_SSI_SACCEN, 0x300);
 
 	/*
 	 * Enable SSI, Transmit and Receive. AC97 has to communicate with the
 	 * codec before a stream is started.
 	 */
-	write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN |
-			CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
+	regmap_update_bits(regs, CCSR_SSI_SCR,
+			CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE,
+			CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
 
-	write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
+	regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_WAIT(3));
 }
 
 /**
@@ -561,12 +564,16 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
 {
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 	unsigned int channels = params_channels(hw_params);
 	unsigned int sample_size =
 		snd_pcm_format_width(params_format(hw_params));
 	u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
-	int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
+	u32 scr_val;
+	int enabled;
+
+	regmap_read(regs, CCSR_SSI_SCR, &scr_val);
+	enabled = scr_val & CCSR_SSI_SCR_SSIEN;
 
 	/*
 	 * If we're in synchronous mode, and the SSI is already enabled,
@@ -588,12 +595,14 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 	/* In synchronous mode, the SSI uses STCCR for capture */
 	if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
 	    ssi_private->cpu_dai_drv.symmetric_rates)
-		write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
+		regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_WL_MASK,
+				wl);
 	else
-		write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
+		regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK,
+				wl);
 
 	if (!fsl_ssi_is_ac97(ssi_private))
-		write_ssi_mask(&ssi->scr,
+		regmap_update_bits(regs, CCSR_SSI_SCR,
 				CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
 				channels == 1 ? 0 : ssi_private->i2s_mode);
 
@@ -603,7 +612,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private,
 		unsigned int fmt)
 {
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 	u32 strcr = 0, stcr, srcr, scr, mask;
 	u8 wm;
 
@@ -614,14 +623,17 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private,
 
 	fsl_ssi_setup_reg_vals(ssi_private);
 
-	scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
+	regmap_read(regs, CCSR_SSI_SCR, &scr);
+	scr &= ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
 	scr |= CCSR_SSI_SCR_SYNC_TX_FS;
 
 	mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR |
 		CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL |
 		CCSR_SSI_STCR_TEFS;
-	stcr = read_ssi(&ssi->stcr) & ~mask;
-	srcr = read_ssi(&ssi->srcr) & ~mask;
+	regmap_read(regs, CCSR_SSI_STCR, &stcr);
+	regmap_read(regs, CCSR_SSI_SRCR, &srcr);
+	stcr &= ~mask;
+	srcr &= ~mask;
 
 	ssi_private->i2s_mode = CCSR_SSI_SCR_NET;
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -707,9 +719,9 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private,
 		scr |= CCSR_SSI_SCR_SYN;
 	}
 
-	write_ssi(stcr, &ssi->stcr);
-	write_ssi(srcr, &ssi->srcr);
-	write_ssi(scr, &ssi->scr);
+	regmap_write(regs, CCSR_SSI_STCR, stcr);
+	regmap_write(regs, CCSR_SSI_SRCR, srcr);
+	regmap_write(regs, CCSR_SSI_SCR, scr);
 
 	/*
 	 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't
@@ -727,16 +739,16 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private,
 	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);
+	regmap_write(regs, CCSR_SSI_SFCSR,
+			CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) |
+			CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm));
 
 	if (ssi_private->use_dual_fifo) {
-		write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1,
+		regmap_update_bits(regs, CCSR_SSI_SRCR, CCSR_SSI_SRCR_RFEN1,
 				CCSR_SSI_SRCR_RFEN1);
-		write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1,
+		regmap_update_bits(regs, CCSR_SSI_STCR, CCSR_SSI_STCR_TFEN1,
 				CCSR_SSI_STCR_TFEN1);
-		write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN,
+		regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_TCH_EN,
 				CCSR_SSI_SCR_TCH_EN);
 	}
 
@@ -770,7 +782,7 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 	int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret;
 	u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
 	unsigned long flags, clkrate, baudrate, tmprate;
@@ -834,9 +846,9 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 	mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | CCSR_SSI_SxCCR_PSR;
 
 	if (dir == SND_SOC_CLOCK_OUT || synchronous)
-		write_ssi_mask(&ssi->stccr, mask, stccr);
+		regmap_update_bits(regs, CCSR_SSI_STCCR, mask, stccr);
 	else
-		write_ssi_mask(&ssi->srccr, mask, stccr);
+		regmap_update_bits(regs, CCSR_SSI_SRCCR, mask, stccr);
 
 	spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
 	if (!ssi_private->baudclk_locked) {
@@ -865,31 +877,34 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
 				u32 rx_mask, int slots, int slot_width)
 {
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
-	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct regmap *regs = ssi_private->regs;
 	u32 val;
 
 	/* The slot number should be >= 2 if using Network mode or I2S mode */
-	val = read_ssi(&ssi->scr) & (CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET);
+	regmap_read(regs, CCSR_SSI_SCR, &val);
+	val &= CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET;
 	if (val && slots < 2) {
 		dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n");
 		return -EINVAL;
 	}
 
-	write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
+	regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_DC_MASK,
 			CCSR_SSI_SxCCR_DC(slots));
-	write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
+	regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_DC_MASK,
 			CCSR_SSI_SxCCR_DC(slots));
 
 	/* The register SxMSKs needs SSI to provide essential clock due to
 	 * hardware design. So we here temporarily enable SSI to set them.
 	 */
-	val = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
-	write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN);
+	regmap_read(regs, CCSR_SSI_SCR, &val);
+	val &= CCSR_SSI_SCR_SSIEN;
+	regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN,
+			CCSR_SSI_SCR_SSIEN);
 
-	write_ssi(tx_mask, &ssi->stmsk);
-	write_ssi(rx_mask, &ssi->srmsk);
+	regmap_write(regs, CCSR_SSI_STMSK, tx_mask);
+	regmap_write(regs, CCSR_SSI_SRMSK, rx_mask);
 
-	write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, val);
+	regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, val);
 
 	return 0;
 }
@@ -908,12 +923,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 {
 	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;
+	struct regmap *regs = ssi_private->regs;
 	unsigned long flags;
 	u32 val;
 	int nr_active;
 
-	val = read_ssi(&ssi->scr);
+	regmap_read(regs, CCSR_SSI_SCR, &val);
 	nr_active = !!(val & CCSR_SSI_SCR_TE) + !!(val & CCSR_SSI_SCR_RE);
 
 	switch (cmd) {
@@ -968,9 +983,9 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 
 	if (fsl_ssi_is_ac97(ssi_private)) {
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
+			regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_TX_CLR);
 		else
-			write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
+			regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_RX_CLR);
 	}
 
 	return 0;
@@ -1044,7 +1059,7 @@ static struct fsl_ssi_private *fsl_ac97_data;
 static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 		unsigned short val)
 {
-	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+	struct regmap *regs = fsl_ac97_data->regs;
 	unsigned int lreg;
 	unsigned int lval;
 
@@ -1053,12 +1068,12 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 
 
 	lreg = reg <<  12;
-	write_ssi(lreg, &ssi->sacadd);
+	regmap_write(regs, CCSR_SSI_SACADD, lreg);
 
 	lval = val << 4;
-	write_ssi(lval , &ssi->sacdat);
+	regmap_write(regs, CCSR_SSI_SACDAT, lval);
 
-	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+	regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK,
 			CCSR_SSI_SACNT_WR);
 	udelay(100);
 }
@@ -1066,19 +1081,21 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
 		unsigned short reg)
 {
-	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+	struct regmap *regs = fsl_ac97_data->regs;
 
 	unsigned short val = -1;
+	u32 reg_val;
 	unsigned int lreg;
 
 	lreg = (reg & 0x7f) <<  12;
-	write_ssi(lreg, &ssi->sacadd);
-	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+	regmap_write(regs, CCSR_SSI_SACADD, lreg);
+	regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK,
 			CCSR_SSI_SACNT_RD);
 
 	udelay(100);
 
-	val = (read_ssi(&ssi->sacdat) >> 4) & 0xffff;
+	regmap_read(regs, CCSR_SSI_SACDAT, &reg_val);
+	val = (reg_val >> 4) & 0xffff;
 
 	return val;
 }
@@ -1141,10 +1158,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
 	 */
 	ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2;
 	ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2;
-	ssi_private->dma_params_tx.addr = ssi_private->ssi_phys +
-			offsetof(struct ccsr_ssi, stx0);
-	ssi_private->dma_params_rx.addr = ssi_private->ssi_phys +
-			offsetof(struct ccsr_ssi, srx0);
+	ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0;
+	ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0;
 
 	ret = !of_property_read_u32_array(np, "dmas", dmas, 4);
 	if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
@@ -1207,6 +1222,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	const char *p, *sprop;
 	const uint32_t *iprop;
 	struct resource res;
+	void __iomem *iomem;
 	char name[64];
 
 	/* SSIs that are not connected on the board should have a
@@ -1263,12 +1279,20 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "could not determine device resources\n");
 		return ret;
 	}
-	ssi_private->ssi = of_iomap(np, 0);
-	if (!ssi_private->ssi) {
+	ssi_private->ssi_phys = res.start;
+
+	iomem = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
+	if (!iomem) {
 		dev_err(&pdev->dev, "could not map device resources\n");
 		return -ENOMEM;
 	}
-	ssi_private->ssi_phys = res.start;
+
+	ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,
+			&fsl_ssi_regconfig);
+	if (IS_ERR(ssi_private->regs)) {
+		dev_err(&pdev->dev, "Failed to init register map\n");
+		return PTR_ERR(ssi_private->regs);
+	}
 
 	ssi_private->irq = irq_of_parse_and_map(np, 0);
 	if (!ssi_private->irq) {
@@ -1296,7 +1320,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	dev_set_drvdata(&pdev->dev, ssi_private);
 
 	if (fsl_ssi_on_imx(ssi_private)) {
-		ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi);
+		ret = fsl_ssi_imx_probe(pdev, ssi_private, iomem);
 		if (ret)
 			goto error_irqmap;
 	}
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index 71c3e7e..5065105 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -12,32 +12,30 @@
 #ifndef _MPC8610_I2S_H
 #define _MPC8610_I2S_H
 
-/* SSI Register Map */
-struct ccsr_ssi {
-	__be32 stx0;	/* 0x.0000 - SSI Transmit Data Register 0 */
-	__be32 stx1;	/* 0x.0004 - SSI Transmit Data Register 1 */
-	__be32 srx0;	/* 0x.0008 - SSI Receive Data Register 0 */
-	__be32 srx1;	/* 0x.000C - SSI Receive Data Register 1 */
-	__be32 scr;	/* 0x.0010 - SSI Control Register */
-	__be32 sisr;	/* 0x.0014 - SSI Interrupt Status Register Mixed */
-	__be32 sier;	/* 0x.0018 - SSI Interrupt Enable Register */
-	__be32 stcr;	/* 0x.001C - SSI Transmit Configuration Register */
-	__be32 srcr;	/* 0x.0020 - SSI Receive Configuration Register */
-	__be32 stccr;	/* 0x.0024 - SSI Transmit Clock Control Register */
-	__be32 srccr;	/* 0x.0028 - SSI Receive Clock Control Register */
-	__be32 sfcsr;	/* 0x.002C - SSI FIFO Control/Status Register */
-	__be32 str;	/* 0x.0030 - SSI Test Register */
-	__be32 sor;	/* 0x.0034 - SSI Option Register */
-	__be32 sacnt;	/* 0x.0038 - SSI AC97 Control Register */
-	__be32 sacadd;	/* 0x.003C - SSI AC97 Command Address Register */
-	__be32 sacdat;	/* 0x.0040 - SSI AC97 Command Data Register */
-	__be32 satag;	/* 0x.0044 - SSI AC97 Tag Register */
-	__be32 stmsk;	/* 0x.0048 - SSI Transmit Time Slot Mask Register */
-	__be32 srmsk;	/* 0x.004C - SSI Receive Time Slot Mask Register */
-	__be32 saccst;	/* 0x.0050 - SSI AC97 Channel Status Register */
-	__be32 saccen;	/* 0x.0054 - SSI AC97 Channel Enable Register */
-	__be32 saccdis; /* 0x.0058 - SSI AC97 Channel Disable Register */
-};
+/* SSI registers */
+#define CCSR_SSI_STX0			0x00
+#define CCSR_SSI_STX1			0x04
+#define CCSR_SSI_SRX0			0x08
+#define CCSR_SSI_SRX1			0x0c
+#define CCSR_SSI_SCR			0x10
+#define CCSR_SSI_SISR			0x14
+#define CCSR_SSI_SIER			0x18
+#define CCSR_SSI_STCR			0x1c
+#define CCSR_SSI_SRCR			0x20
+#define CCSR_SSI_STCCR			0x24
+#define CCSR_SSI_SRCCR			0x28
+#define CCSR_SSI_SFCSR			0x2c
+#define CCSR_SSI_STR			0x30
+#define CCSR_SSI_SOR			0x34
+#define CCSR_SSI_SACNT			0x38
+#define CCSR_SSI_SACADD			0x3c
+#define CCSR_SSI_SACDAT			0x40
+#define CCSR_SSI_SATAG			0x44
+#define CCSR_SSI_STMSK			0x48
+#define CCSR_SSI_SRMSK			0x4c
+#define CCSR_SSI_SACCST			0x50
+#define CCSR_SSI_SACCEN			0x54
+#define CCSR_SSI_SACCDIS		0x58
 
 #define CCSR_SSI_SCR_SYNC_TX_FS		0x00001000
 #define CCSR_SSI_SCR_RFR_CLK_DIS	0x00000800
-- 
1.9.0

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

* Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-15 12:44 ` [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap Markus Pargmann
@ 2014-03-15 14:43   ` Alexander Shiyan
  2014-03-18  8:10     ` Markus Pargmann
  0 siblings, 1 reply; 34+ messages in thread
From: Alexander Shiyan @ 2014-03-15 14:43 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, Mark Brown, kernel,
	Nicolin Chen, linux-arm-kernel

Суббота, 15 марта 2014, 13:44 +01:00 от Markus Pargmann <mpa@pengutronix.de>:
> This patch replaces the ssi specific functions write_ssi, read_ssi and
> write_ssi_mask by standard regmap function calls.
...
> diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
...
> +static const struct regmap_config fsl_ssi_regconfig = {
> +	.max_register = CCSR_SSI_SACCDIS,
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +#ifdef PPC
> +	.val_format_endian = REGMAP_ENDIAN_BIG,
> +#endif
> +};

Why we cannot use REGMAP_ENDIAN_NATIVE here for all cases?
Theoretically, we can use for i.MX SOCs with different endianness,
so this will help us.

---
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

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

* Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-15 14:43   ` Alexander Shiyan
@ 2014-03-18  8:10     ` Markus Pargmann
  2014-03-20  6:07       ` Li.Xiubo
  0 siblings, 1 reply; 34+ messages in thread
From: Markus Pargmann @ 2014-03-18  8:10 UTC (permalink / raw)
  To: Alexander Shiyan
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, Mark Brown, kernel,
	Nicolin Chen, linux-arm-kernel


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

On Sat, Mar 15, 2014 at 06:43:36PM +0400, Alexander Shiyan wrote:
> Суббота, 15 марта 2014, 13:44 +01:00 от Markus Pargmann <mpa@pengutronix.de>:
> > This patch replaces the ssi specific functions write_ssi, read_ssi and
> > write_ssi_mask by standard regmap function calls.
> ...
> > diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
> ...
> > +static const struct regmap_config fsl_ssi_regconfig = {
> > +	.max_register = CCSR_SSI_SACCDIS,
> > +	.reg_bits = 32,
> > +	.val_bits = 32,
> > +	.reg_stride = 4,
> > +#ifdef PPC
> > +	.val_format_endian = REGMAP_ENDIAN_BIG,
> > +#endif
> > +};
> 
> Why we cannot use REGMAP_ENDIAN_NATIVE here for all cases?
> Theoretically, we can use for i.MX SOCs with different endianness,
> so this will help us.

I can change and test it on i.MX, but I am not sure if it helps with the
PPC situation as I don't have the hardware.

Regards,

Markus

> 
> ---

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (15 preceding siblings ...)
  2014-03-15 12:44 ` [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap Markus Pargmann
@ 2014-03-18 12:44 ` Mark Brown
  2014-04-03 22:14 ` Mark Brown
  17 siblings, 0 replies; 34+ messages in thread
From: Mark Brown @ 2014-03-18 12:44 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	linux-arm-kernel


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

On Sat, Mar 15, 2014 at 01:44:08PM +0100, Markus Pargmann wrote:

> This new version of the cleanup is mainly a reordering of the patches. It moves
> the regmap patch to the end of the series so none of the other patches depend
> on it. This also fixes a bug I introduced in "Remove fsl_ssi_setup" which also
> removed the switching between network and normal mode depending on the number
> of channels. I reversed this code removal. Another new patch was added "Fix
> i2s_mode variable setup" which fixes the i2s_mode assignment in set_dai_fmt().

I'd really like to see some review/testin from other users on this
series.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-18  8:10     ` Markus Pargmann
@ 2014-03-20  6:07       ` Li.Xiubo
  2014-03-20 15:10         ` Timur Tabi
  0 siblings, 1 reply; 34+ messages in thread
From: Li.Xiubo @ 2014-03-20  6:07 UTC (permalink / raw)
  To: Markus Pargmann, Alexander Shiyan
  Cc: Fabio.Estevam, alsa-devel, Timur Tabi, Mark Brown, kernel,
	guangyu.chen, linux-arm-kernel


> Subject: Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
> 
> On Sat, Mar 15, 2014 at 06:43:36PM +0400, Alexander Shiyan wrote:
> > Суббота, 15 марта 2014, 13:44 +01:00 от Markus Pargmann <mpa@pengutronix.de>:
> > > This patch replaces the ssi specific functions write_ssi, read_ssi and
> > > write_ssi_mask by standard regmap function calls.
> > ...
> > > diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
> > ...
> > > +static const struct regmap_config fsl_ssi_regconfig = {
> > > +	.max_register = CCSR_SSI_SACCDIS,
> > > +	.reg_bits = 32,
> > > +	.val_bits = 32,
> > > +	.reg_stride = 4,
> > > +#ifdef PPC
> > > +	.val_format_endian = REGMAP_ENDIAN_BIG,
> > > +#endif
> > > +};
> >
> > Why we cannot use REGMAP_ENDIAN_NATIVE here for all cases?
> > Theoretically, we can use for i.MX SOCs with different endianness,
> > so this will help us.
> 
> I can change and test it on i.MX, but I am not sure if it helps with the
> PPC situation as I don't have the hardware.
> 

For the scenario of PowerPC(for CPU and devices mostly are in BE mode):
CPU		SSI
BE		BE	we can just use the REGMAP_ENDIAN_NATIVE here.

For the scenario of ARM(for CPU and devices mostly are in LE mode):
CPU		SSI
LE		LE	we can also just use the REGMAP_ENDIAN_NATIVE here.

While for the scenario like our LS1(ARM) platform.
CPU		SSI
LE		BE	then should we set the .val_format_endian to
			REGMAP_ENDIAN_BIG


And so not only for PowerPC, but also maybe for ARM platforms.
So here how about just adding one Boolean property like 'big-endian' in DT node
to learn the endianness of the devices dynamically ?  

Thanks,
:)

Best Regards,
Xiubo


_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

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

* Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-20  6:07       ` Li.Xiubo
@ 2014-03-20 15:10         ` Timur Tabi
  2014-03-21  1:52           ` Li.Xiubo
  2014-03-21  8:45           ` Markus Pargmann
  0 siblings, 2 replies; 34+ messages in thread
From: Timur Tabi @ 2014-03-20 15:10 UTC (permalink / raw)
  To: Li.Xiubo
  Cc: Fabio.Estevam, alsa-devel, Alexander Shiyan, Mark Brown, kernel,
	guangyu.chen, Markus Pargmann, linux-arm-kernel

On 03/20/2014 01:07 AM, Li.Xiubo@freescale.com wrote:
> While for the scenario like our LS1(ARM) platform.
> CPU		SSI
> LE		BE	then should we set the .val_format_endian to
> 			REGMAP_ENDIAN_BIG
>
>
> And so not only for PowerPC, but also maybe for ARM platforms.
> So here how about just adding one Boolean property like 'big-endian' in DT node
> to learn the endianness of the devices dynamically ?

That's not a bad idea.  The property should be something like, 
"fsl,ssi-endian" and is should be set to "big", "little", or "native". 
In the absence of the property, it should default to native endian.

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

* Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-20 15:10         ` Timur Tabi
@ 2014-03-21  1:52           ` Li.Xiubo
  2014-03-21  8:45           ` Markus Pargmann
  1 sibling, 0 replies; 34+ messages in thread
From: Li.Xiubo @ 2014-03-21  1:52 UTC (permalink / raw)
  To: Timur Tabi
  Cc: Fabio.Estevam, alsa-devel, Alexander Shiyan, Mark Brown, kernel,
	guangyu.chen, Markus Pargmann, linux-arm-kernel

> Subject: Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
> 
> On 03/20/2014 01:07 AM, Li.Xiubo@freescale.com wrote:
> > While for the scenario like our LS1(ARM) platform.
> > CPU		SSI
> > LE		BE	then should we set the .val_format_endian to
> > 			REGMAP_ENDIAN_BIG
> >
> >
> > And so not only for PowerPC, but also maybe for ARM platforms.
> > So here how about just adding one Boolean property like 'big-endian' in DT
> node
> > to learn the endianness of the devices dynamically ?
> 
> That's not a bad idea.  The property should be something like,
> "fsl,ssi-endian" and is should be set to "big", "little", or "native".
> In the absence of the property, it should default to native endian.
> 

Well, yes, sounds good.
That will lead the individual driver a little more complex. I do think that
The regmap core should use the REGMAP_ENDIAN_SWAP instead of 
REGMAP_ENDIAN_BIG/LITTLE ones if possible.


:)
Thanks,
--

Best Regards,
Xiubo

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

* Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-20 15:10         ` Timur Tabi
  2014-03-21  1:52           ` Li.Xiubo
@ 2014-03-21  8:45           ` Markus Pargmann
  2014-03-21  9:19             ` Li.Xiubo
  1 sibling, 1 reply; 34+ messages in thread
From: Markus Pargmann @ 2014-03-21  8:45 UTC (permalink / raw)
  To: Timur Tabi
  Cc: Fabio.Estevam, alsa-devel, Alexander Shiyan, Mark Brown,
	Li.Xiubo, kernel, guangyu.chen, linux-arm-kernel


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

Hi,

On Thu, Mar 20, 2014 at 10:10:09AM -0500, Timur Tabi wrote:
> On 03/20/2014 01:07 AM, Li.Xiubo@freescale.com wrote:
> >While for the scenario like our LS1(ARM) platform.
> >CPU		SSI
> >LE		BE	then should we set the .val_format_endian to
> >			REGMAP_ENDIAN_BIG
> >
> >
> >And so not only for PowerPC, but also maybe for ARM platforms.
> >So here how about just adding one Boolean property like 'big-endian' in DT node
> >to learn the endianness of the devices dynamically ?
> 
> That's not a bad idea.  The property should be something like,
> "fsl,ssi-endian" and is should be set to "big", "little", or
> "native". In the absence of the property, it should default to
> native endian.

Perhaps it is better to create some generic binding for that? There may
be other drivers/components that have the same strange combinations and
need a similar binding to use for regmap.

We could use something like an "endian" property with "big", "little"
and "native" which is then parsed by some function of the regmap
framework. It could directly fill those information into the
struct regmap_config.

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
  2014-03-21  8:45           ` Markus Pargmann
@ 2014-03-21  9:19             ` Li.Xiubo
  0 siblings, 0 replies; 34+ messages in thread
From: Li.Xiubo @ 2014-03-21  9:19 UTC (permalink / raw)
  To: Markus Pargmann, Timur Tabi
  Cc: Fabio.Estevam, alsa-devel, Alexander Shiyan, Mark Brown, kernel,
	guangyu.chen, linux-arm-kernel


> Subject: Re: [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap
> 
> Hi,
> 
> On Thu, Mar 20, 2014 at 10:10:09AM -0500, Timur Tabi wrote:
> > On 03/20/2014 01:07 AM, Li.Xiubo@freescale.com wrote:
> > >While for the scenario like our LS1(ARM) platform.
> > >CPU		SSI
> > >LE		BE	then should we set the .val_format_endian to
> > >			REGMAP_ENDIAN_BIG
> > >
> > >
> > >And so not only for PowerPC, but also maybe for ARM platforms.
> > >So here how about just adding one Boolean property like 'big-endian' in DT
> node
> > >to learn the endianness of the devices dynamically ?
> >
> > That's not a bad idea.  The property should be something like,
> > "fsl,ssi-endian" and is should be set to "big", "little", or
> > "native". In the absence of the property, it should default to
> > native endian.
> 
> Perhaps it is better to create some generic binding for that? There may
> be other drivers/components that have the same strange combinations and
> need a similar binding to use for regmap.
> 
> We could use something like an "endian" property with "big", "little"
> and "native" which is then parsed by some function of the regmap
> framework. It could directly fill those information into the
> struct regmap_config.
> 
> Thanks,
> 
> Markus
> 

Yes, actually the fsl-sai, fsl-esai and fsl-spdif have already supported
this. In our Platforms of Vybird, LS1 and LS2 will support different endianess
of these devices and also many other IP blocks.

But I used the Boolean property like "big-endian" and this is enough, because
for now the regmap core does not support the following scenario:

CPU		IP
------------------
BE		LE

:)

Thanks,
--

Best Regards,
Xiubo

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

* Re: [PATCH v2 11/16] ASoC: fsl-ssi: Fix register values when disabling
  2014-03-15 12:44 ` [PATCH v2 11/16] ASoC: fsl-ssi: Fix register values when disabling Markus Pargmann
@ 2014-04-03 22:11   ` Mark Brown
  2014-04-04  6:52     ` Markus Pargmann
  0 siblings, 1 reply; 34+ messages in thread
From: Mark Brown @ 2014-04-03 22:11 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	linux-arm-kernel


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

On Sat, Mar 15, 2014 at 01:44:19PM +0100, Markus Pargmann wrote:
> The bits we have to clear when disabling are different when the other
> stream is still active.

If this is a bug fix I'd have expected to see it at the start of the
series so we could merge it prior to the rest of the series (which is
new development) - what practical issues does this bug cause?

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
                   ` (16 preceding siblings ...)
  2014-03-18 12:44 ` [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Mark Brown
@ 2014-04-03 22:14 ` Mark Brown
  2014-04-04  6:49   ` Markus Pargmann
  17 siblings, 1 reply; 34+ messages in thread
From: Mark Brown @ 2014-04-03 22:14 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	linux-arm-kernel


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

On Sat, Mar 15, 2014 at 01:44:08PM +0100, Markus Pargmann wrote:
> Hi,
> 
> This new version of the cleanup is mainly a reordering of the patches. It moves
> the regmap patch to the end of the series so none of the other patches depend
> on it. This also fixes a bug I introduced in "Remove fsl_ssi_setup" which also
> removed the switching between network and normal mode depending on the number
> of channels. I reversed this code removal. Another new patch was added "Fix
> i2s_mode variable setup" which fixes the i2s_mode assignment in set_dai_fmt().

It's been nearly three weeks with no response to this except for the
last patch - I've got ahead and applied since it all looks sane (modulo
the bugfix question), we can see if problems occur in -next after the
merge window.  Thanks!

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-04-03 22:14 ` Mark Brown
@ 2014-04-04  6:49   ` Markus Pargmann
  2014-04-04  7:58     ` [alsa-devel] " Michael Trimarchi
  2014-04-04 10:03     ` Mark Brown
  0 siblings, 2 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-04-04  6:49 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	linux-arm-kernel


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

Hi,

On Thu, Apr 03, 2014 at 11:14:06PM +0100, Mark Brown wrote:
> On Sat, Mar 15, 2014 at 01:44:08PM +0100, Markus Pargmann wrote:
> > Hi,
> > 
> > This new version of the cleanup is mainly a reordering of the patches. It moves
> > the regmap patch to the end of the series so none of the other patches depend
> > on it. This also fixes a bug I introduced in "Remove fsl_ssi_setup" which also
> > removed the switching between network and normal mode depending on the number
> > of channels. I reversed this code removal. Another new patch was added "Fix
> > i2s_mode variable setup" which fixes the i2s_mode assignment in set_dai_fmt().
> 
> It's been nearly three weeks with no response to this except for the
> last patch - I've got ahead and applied since it all looks sane (modulo
> the bugfix question), we can see if problems occur in -next after the
> merge window.  Thanks!

Thanks for applying this series, but could you please drop it for the
moment? We found some issues with the baud clock setup for i2s master
mode and have some fixed patches for the series. So it would be nice to
get this in without fixups if that's still possible? I could send a v3
next week.

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 11/16] ASoC: fsl-ssi: Fix register values when disabling
  2014-04-03 22:11   ` Mark Brown
@ 2014-04-04  6:52     ` Markus Pargmann
  0 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-04-04  6:52 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	linux-arm-kernel


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

Hi,

On Thu, Apr 03, 2014 at 11:11:43PM +0100, Mark Brown wrote:
> On Sat, Mar 15, 2014 at 01:44:19PM +0100, Markus Pargmann wrote:
> > The bits we have to clear when disabling are different when the other
> > stream is still active.
> 
> If this is a bug fix I'd have expected to see it at the start of the
> series so we could merge it prior to the rest of the series (which is
> new development) - what practical issues does this bug cause?

I can put it to the beginning of the series. The only 'bug' I could
observe was a enabled SSI unit although all streams were stopped. But I
could not observe any malfunctions through that.

Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [alsa-devel] [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-04-04  6:49   ` Markus Pargmann
@ 2014-04-04  7:58     ` Michael Trimarchi
  2014-04-04 10:59       ` Markus Pargmann
  2014-04-04 10:03     ` Mark Brown
  1 sibling, 1 reply; 34+ messages in thread
From: Michael Trimarchi @ 2014-04-04  7:58 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, Mark Brown, kernel,
	Nicolin Chen, linux-arm-kernel

Hi Markus

On Fri, Apr 4, 2014 at 8:49 AM, Markus Pargmann <mpa@pengutronix.de> wrote:
> Hi,
>
> On Thu, Apr 03, 2014 at 11:14:06PM +0100, Mark Brown wrote:
>> On Sat, Mar 15, 2014 at 01:44:08PM +0100, Markus Pargmann wrote:
>> > Hi,
>> >
>> > This new version of the cleanup is mainly a reordering of the patches. It moves
>> > the regmap patch to the end of the series so none of the other patches depend
>> > on it. This also fixes a bug I introduced in "Remove fsl_ssi_setup" which also
>> > removed the switching between network and normal mode depending on the number
>> > of channels. I reversed this code removal. Another new patch was added "Fix
>> > i2s_mode variable setup" which fixes the i2s_mode assignment in set_dai_fmt().
>>
>> It's been nearly three weeks with no response to this except for the
>> last patch - I've got ahead and applied since it all looks sane (modulo
>> the bugfix question), we can see if problems occur in -next after the
>> merge window.  Thanks!
>
> Thanks for applying this series, but could you please drop it for the
> moment? We found some issues with the baud clock setup for i2s master
> mode and have some fixed patches for the series. So it would be nice to
> get this in without fixups if that's still possible? I could send a v3
> next week.

We have tested a bit them on Wandboard and rebase our patches.
I was busy in the last 2 weeks but they are fine so far.

Michael

>
> Thanks,
>
> Markus
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

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

* Re: [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-04-04  6:49   ` Markus Pargmann
  2014-04-04  7:58     ` [alsa-devel] " Michael Trimarchi
@ 2014-04-04 10:03     ` Mark Brown
  2014-04-04 10:51       ` Markus Pargmann
  1 sibling, 1 reply; 34+ messages in thread
From: Mark Brown @ 2014-04-04 10:03 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	linux-arm-kernel


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

On Fri, Apr 04, 2014 at 08:49:32AM +0200, Markus Pargmann wrote:

> Thanks for applying this series, but could you please drop it for the
> moment? We found some issues with the baud clock setup for i2s master
> mode and have some fixed patches for the series. So it would be nice to
> get this in without fixups if that's still possible? I could send a v3
> next week.

I've dropped everything after "fsl-ssi: Move debugging to a separate
file" since that didn't compile anyway (though I'll add the binding
document update as a fix).  In future please don't wait until after your
patches have been applied before saying things like this, it's not good
to rebase branches normally.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-04-04 10:03     ` Mark Brown
@ 2014-04-04 10:51       ` Markus Pargmann
  0 siblings, 0 replies; 34+ messages in thread
From: Markus Pargmann @ 2014-04-04 10:51 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, kernel, Nicolin Chen,
	linux-arm-kernel


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

On Fri, Apr 04, 2014 at 11:03:51AM +0100, Mark Brown wrote:
> On Fri, Apr 04, 2014 at 08:49:32AM +0200, Markus Pargmann wrote:
> 
> > Thanks for applying this series, but could you please drop it for the
> > moment? We found some issues with the baud clock setup for i2s master
> > mode and have some fixed patches for the series. So it would be nice to
> > get this in without fixups if that's still possible? I could send a v3
> > next week.
> 
> I've dropped everything after "fsl-ssi: Move debugging to a separate
> file" since that didn't compile anyway (though I'll add the binding
> document update as a fix).  In future please don't wait until after your
> patches have been applied before saying things like this, it's not good
> to rebase branches normally.

Thank you. Sorry for the extra work and rebase. I will send the new
version next week.

Regards,

Markus



-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-04-04  7:58     ` [alsa-devel] " Michael Trimarchi
@ 2014-04-04 10:59       ` Markus Pargmann
  2014-04-04 12:59         ` Michael Trimarchi
  0 siblings, 1 reply; 34+ messages in thread
From: Markus Pargmann @ 2014-04-04 10:59 UTC (permalink / raw)
  To: Michael Trimarchi
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, Mark Brown, kernel,
	Nicolin Chen, linux-arm-kernel


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

Hi Michael,

On Fri, Apr 04, 2014 at 09:58:03AM +0200, Michael Trimarchi wrote:
> Hi Markus
> 
> On Fri, Apr 4, 2014 at 8:49 AM, Markus Pargmann <mpa@pengutronix.de> wrote:
> > Hi,
> >
> > On Thu, Apr 03, 2014 at 11:14:06PM +0100, Mark Brown wrote:
> >> On Sat, Mar 15, 2014 at 01:44:08PM +0100, Markus Pargmann wrote:
> >> > Hi,
> >> >
> >> > This new version of the cleanup is mainly a reordering of the patches. It moves
> >> > the regmap patch to the end of the series so none of the other patches depend
> >> > on it. This also fixes a bug I introduced in "Remove fsl_ssi_setup" which also
> >> > removed the switching between network and normal mode depending on the number
> >> > of channels. I reversed this code removal. Another new patch was added "Fix
> >> > i2s_mode variable setup" which fixes the i2s_mode assignment in set_dai_fmt().
> >>
> >> It's been nearly three weeks with no response to this except for the
> >> last patch - I've got ahead and applied since it all looks sane (modulo
> >> the bugfix question), we can see if problems occur in -next after the
> >> merge window.  Thanks!
> >
> > Thanks for applying this series, but could you please drop it for the
> > moment? We found some issues with the baud clock setup for i2s master
> > mode and have some fixed patches for the series. So it would be nice to
> > get this in without fixups if that's still possible? I could send a v3
> > next week.
> 
> We have tested a bit them on Wandboard and rebase our patches.
> I was busy in the last 2 weeks but they are fine so far.

Thank you for testing. Can I add a Tested-by tag to the commits that
didn't change for the next version of this series?

Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup
  2014-04-04 10:59       ` Markus Pargmann
@ 2014-04-04 12:59         ` Michael Trimarchi
  0 siblings, 0 replies; 34+ messages in thread
From: Michael Trimarchi @ 2014-04-04 12:59 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Timur Tabi, Mark Brown, kernel,
	Nicolin Chen, linux-arm-kernel

Hi Markus

On Fri, Apr 4, 2014 at 12:59 PM, Markus Pargmann <mpa@pengutronix.de> wrote:
> Hi Michael,
>
> On Fri, Apr 04, 2014 at 09:58:03AM +0200, Michael Trimarchi wrote:
>> Hi Markus
>>
>> On Fri, Apr 4, 2014 at 8:49 AM, Markus Pargmann <mpa@pengutronix.de> wrote:
>> > Hi,
>> >
>> > On Thu, Apr 03, 2014 at 11:14:06PM +0100, Mark Brown wrote:
>> >> On Sat, Mar 15, 2014 at 01:44:08PM +0100, Markus Pargmann wrote:
>> >> > Hi,
>> >> >
>> >> > This new version of the cleanup is mainly a reordering of the patches. It moves
>> >> > the regmap patch to the end of the series so none of the other patches depend
>> >> > on it. This also fixes a bug I introduced in "Remove fsl_ssi_setup" which also
>> >> > removed the switching between network and normal mode depending on the number
>> >> > of channels. I reversed this code removal. Another new patch was added "Fix
>> >> > i2s_mode variable setup" which fixes the i2s_mode assignment in set_dai_fmt().
>> >>
>> >> It's been nearly three weeks with no response to this except for the
>> >> last patch - I've got ahead and applied since it all looks sane (modulo
>> >> the bugfix question), we can see if problems occur in -next after the
>> >> merge window.  Thanks!
>> >
>> > Thanks for applying this series, but could you please drop it for the
>> > moment? We found some issues with the baud clock setup for i2s master
>> > mode and have some fixed patches for the series. So it would be nice to
>> > get this in without fixups if that's still possible? I could send a v3
>> > next week.
>>
>> We have tested a bit them on Wandboard and rebase our patches.
>> I was busy in the last 2 weeks but they are fine so far.
>
> Thank you for testing. Can I add a Tested-by tag to the commits that
> didn't change for the next version of this series?
>

Yes you can add it.

Michael

> Regards,
>
> Markus
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

end of thread, other threads:[~2014-04-04 12:59 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-15 12:44 [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 01/16] ASoC: fsl-ssi: Remove fsl_ssi_setup Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 02/16] ASoC: fsl-ssi: Fix i2s_mode variable setup Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 03/16] ASoC: fsl-ssi: Move debugging to seperate file Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 04/16] ASoC: fsl-ssi: Use dev_name for DAI driver struct Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 05/16] ASoC: fsl-ssi: Move imx-specific probe to seperate function Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 06/16] ASoC: fsl-ssi: Remove useless DMA code Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 07/16] ASoC: fsl-ssi: baud clock error handling Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 08/16] ASoC: fsl-ssi: Cleanup probe function Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 09/16] ASoC: fsl-ssi: Remove unnecessary variables from ssi_private Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 10/16] ASoC: fsl-ssi: reorder and document fsl_ssi_private Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 11/16] ASoC: fsl-ssi: Fix register values when disabling Markus Pargmann
2014-04-03 22:11   ` Mark Brown
2014-04-04  6:52     ` Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 12/16] ASoC: fsl-ssi: Only enable baudclk when used Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 13/16] ASoC: fsl-ssi: Set default dai-fmts Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 14/16] ASoC: fsl-ssi: Transmit enable synchronization Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 15/16] ASoC: fsl-ssi: Update binding documentation Markus Pargmann
2014-03-15 12:44 ` [PATCH v2 16/16] ASoC: fsl-ssi: Use regmap Markus Pargmann
2014-03-15 14:43   ` Alexander Shiyan
2014-03-18  8:10     ` Markus Pargmann
2014-03-20  6:07       ` Li.Xiubo
2014-03-20 15:10         ` Timur Tabi
2014-03-21  1:52           ` Li.Xiubo
2014-03-21  8:45           ` Markus Pargmann
2014-03-21  9:19             ` Li.Xiubo
2014-03-18 12:44 ` [PATCH v2 00/16] ASoC: fsl-ssi: Driver cleanup Mark Brown
2014-04-03 22:14 ` Mark Brown
2014-04-04  6:49   ` Markus Pargmann
2014-04-04  7:58     ` [alsa-devel] " Michael Trimarchi
2014-04-04 10:59       ` Markus Pargmann
2014-04-04 12:59         ` Michael Trimarchi
2014-04-04 10:03     ` Mark Brown
2014-04-04 10:51       ` 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).