Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* PXA SSP - work in progress
@ 2009-03-13 14:37 Mark Brown
  2009-03-13 14:37 ` [RFC] ASoC: switch PXA SSP driver from network mode to PSP Mark Brown
  2009-03-13 17:15 ` PXA SSP - work in progress Daniel Mack
  0 siblings, 2 replies; 5+ messages in thread
From: Mark Brown @ 2009-03-13 14:37 UTC (permalink / raw)
  To: Daniel Mack, pHilipp Zabel; +Cc: alsa-devel

I worked a bit on the PXA SSP code last night and was able to come up
with a configuration which uses non-network mode for I2S and works well
on the Zylonite.  I'll post the current series I have in a followup to
this, if you could take a look that'd be great - I haven't yet worked
through all the testing I'd like to do.

Unfortunately it's going to have broken Daniel's configuration since I
inverted the sense of LRCLK as the chip seemed not to generate an LRCLK
with a non-zero frame delay; I need to check to see if this is just
something I've overlooked.  Hopefully Daniel's system should just have
inverted the left and right channels.

Having worked through non-network mode my feeling is that we should be
able to come up with something that can figure out the extra clock
cycles needed for Daniel's configuration with less of a special case.
Non-network mode does seem like a better default than network mode
because it avoids needing to look at the TDM configuration unless you
want to use that.

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

* [RFC] ASoC: switch PXA SSP driver from network mode to PSP
  2009-03-13 14:37 PXA SSP - work in progress Mark Brown
@ 2009-03-13 14:37 ` Mark Brown
  2009-03-13 14:37   ` [RFC] ASoC: Fix non-networked I2S mode for PXA SSP Mark Brown
  2009-03-13 17:15 ` PXA SSP - work in progress Daniel Mack
  1 sibling, 1 reply; 5+ messages in thread
From: Mark Brown @ 2009-03-13 14:37 UTC (permalink / raw)
  To: Daniel Mack, pHilipp Zabel; +Cc: alsa-devel, Mark Brown

From: Daniel Mack <daniel@caiaq.de>

This switches the pxa ssp port usage from network mode to PSP mode.
Removed some comments and checks for configured TDM channels.
A special case is added to support configuration where BCLK = 64fs. We
need to do some black magic in this case which doesn't look nice but
there is unfortunately no other option than that.

Diagnosed-by: Tim Ruetz <tim@caiaq.de>
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/pxa/pxa-ssp.c |   44 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d3fa635..4dd0d7c 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -558,18 +558,17 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		sscr0 |= SSCR0_MOD | SSCR0_PSP;
+		sscr0 |= SSCR0_PSP;
 		sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
 
 		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 		case SND_SOC_DAIFMT_NB_NF:
-			sspsp |= SSPSP_FSRT;
 			break;
 		case SND_SOC_DAIFMT_NB_IF:
-			sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
+			sspsp |= SSPSP_SFRMP;
 			break;
 		case SND_SOC_DAIFMT_IB_IF:
-			sspsp |= SSPSP_SFRMP;
+			sspsp |= SSPSP_SFRMP | SSPSP_SCMODE(3);
 			break;
 		default:
 			return -EINVAL;
@@ -655,33 +654,56 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
 			sscr0 |= SSCR0_FPCKE;
 #endif
 		sscr0 |= SSCR0_DataSize(16);
-		/* use network mode (2 slots) for 16 bit stereo */
 		break;
 	case SNDRV_PCM_FORMAT_S24_LE:
 		sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
-		/* we must be in network mode (2 slots) for 24 bit stereo */
 		break;
 	case SNDRV_PCM_FORMAT_S32_LE:
 		sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
-		/* we must be in network mode (2 slots) for 32 bit stereo */
 		break;
 	}
 	ssp_write_reg(ssp, SSCR0, sscr0);
 
 	switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-		/* Cleared when the DAI format is set */
-		sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width);
+	       sspsp = ssp_read_reg(ssp, SSPSP);
+
+		if (((sscr0 & SSCR0_SCR) == SSCR0_SerClkDiv(4)) &&
+		     (width == 16)) {
+			/* This is a special case where the bitclk is 64fs
+			* and we're not dealing with 2*32 bits of audio
+			* samples.
+			*
+			* The SSP values used for that are all found out by
+			* trying and failing a lot; some of the registers
+			* needed for that mode are only available on PXA3xx.
+			*/
+
+#ifdef CONFIG_PXA3xx
+			if (!cpu_is_pxa3xx())
+				return -EINVAL;
+
+			sspsp |= SSPSP_SFRMWDTH(width * 2);
+			sspsp |= SSPSP_SFRMDLY(width * 4);
+			sspsp |= SSPSP_EDMYSTOP(3);
+			sspsp |= SSPSP_DMYSTOP(3);
+			sspsp |= SSPSP_DMYSTRT(1);
+#else
+			return -EINVAL;
+#endif
+		} else
+			sspsp |= SSPSP_SFRMWDTH(width);
+
 		ssp_write_reg(ssp, SSPSP, sspsp);
 		break;
 	default:
 		break;
 	}
 
-	/* We always use a network mode so we always require TDM slots
+	/* When we use a network mode, we always require TDM slots
 	 * - complain loudly and fail if they've not been set up yet.
 	 */
-	if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) {
+	if ((sscr0 & SSCR0_MOD) && !(ssp_read_reg(ssp, SSTSA) & 0xf)) {
 		dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
 		return -EINVAL;
 	}
-- 
1.5.6.3

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

* [RFC] ASoC: Fix non-networked I2S mode for PXA SSP
  2009-03-13 14:37 ` [RFC] ASoC: switch PXA SSP driver from network mode to PSP Mark Brown
@ 2009-03-13 14:37   ` Mark Brown
  2009-03-13 14:37     ` [RFC] ASoC: Fix Zylonite for non-networked SSP mode Mark Brown
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Brown @ 2009-03-13 14:37 UTC (permalink / raw)
  To: Daniel Mack, pHilipp Zabel; +Cc: alsa-devel, Mark Brown

Two issues are fixed here:

 - I2S transmits the left frame with the clock low but I don't seem to
   get LRCLK out without SFRMDLY being set so invert SFRMP and set a
   delay.
 - I2S has a clock cycle prior to the first data byte in each channel
   so we need to delay the data by one cycle.

Only tested on Zylonite in master mode.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/pxa/pxa-ssp.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 4dd0d7c..b0bf409 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -1,4 +1,3 @@
-#define DEBUG
 /*
  * pxa-ssp.c  --  ALSA Soc Audio Layer
  *
@@ -561,14 +560,15 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 		sscr0 |= SSCR0_PSP;
 		sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
 
+		/* See hw_params() */
 		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 		case SND_SOC_DAIFMT_NB_NF:
+			sspsp |= SSPSP_SFRMP;
 			break;
 		case SND_SOC_DAIFMT_NB_IF:
-			sspsp |= SSPSP_SFRMP;
 			break;
 		case SND_SOC_DAIFMT_IB_IF:
-			sspsp |= SSPSP_SFRMP | SSPSP_SCMODE(3);
+			sspsp |= SSPSP_SCMODE(3);
 			break;
 		default:
 			return -EINVAL;
@@ -691,8 +691,17 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
 #else
 			return -EINVAL;
 #endif
-		} else
-			sspsp |= SSPSP_SFRMWDTH(width);
+		} else {
+			/* The frame width is the width the LRCLK is
+			 * asserted for; the delay is expressed in
+			 * half cycle units.  We need the extra cycle
+			 * because the data starts clocking out one BCLK
+			 * after LRCLK changes polarity.
+			 */
+			sspsp |= SSPSP_SFRMWDTH(width + 1);
+			sspsp |= SSPSP_SFRMDLY((width + 1) * 2);
+			sspsp |= SSPSP_DMYSTRT(1);
+		}
 
 		ssp_write_reg(ssp, SSPSP, sspsp);
 		break;
-- 
1.5.6.3

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

* [RFC] ASoC: Fix Zylonite for non-networked SSP mode
  2009-03-13 14:37   ` [RFC] ASoC: Fix non-networked I2S mode for PXA SSP Mark Brown
@ 2009-03-13 14:37     ` Mark Brown
  0 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2009-03-13 14:37 UTC (permalink / raw)
  To: Daniel Mack, pHilipp Zabel; +Cc: alsa-devel, Mark Brown

This also simplifies the code a bit.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/pxa/zylonite.c |   55 +++++++++++++++++++++-------------------------
 1 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 9f6116e..9a386b4 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -96,42 +96,35 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
 	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
 	unsigned int pll_out = 0;
-	unsigned int acds = 0;
 	unsigned int wm9713_div = 0;
 	int ret = 0;
-
-	switch (params_rate(params)) {
+	int rate = params_rate(params);
+	int width = snd_pcm_format_physical_width(params_format(params));
+
+	/* Only support ratios that we can generate neatly from the AC97
+	 * based master clock - in particular, this excludes 44.1kHz.
+	 * In most applications the voice DAC will be used for telephony
+	 * data so multiples of 8kHz will be the common case.
+	 */
+	switch (rate) {
 	case 8000:
 		wm9713_div = 12;
-		pll_out = 2048000;
 		break;
 	case 16000:
 		wm9713_div = 6;
-		pll_out = 4096000;
 		break;
 	case 48000:
-	default:
 		wm9713_div = 2;
-		pll_out = 12288000;
-		acds = 1;
 		break;
+	default:
+		/* Don't support OSS emulation */
+		return -EINVAL;
 	}
 
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
-	if (ret < 0)
-		return ret;
-
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
-	if (ret < 0)
-		return ret;
+	/* Add 1 to the width for the leading clock cycle */
+	pll_out = rate * (width + 1) * 8;
 
-	/* Use network mode for stereo, one slot per channel. */
-	if (params_channels(params) > 1)
-		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 2);
-	else
-		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 1);
+	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
 	if (ret < 0)
 		return ret;
 
@@ -139,14 +132,6 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
 	if (ret < 0)
 		return ret;
 
-	ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds);
-	if (ret < 0)
-		return ret;
-
-	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
-	if (ret < 0)
-		return ret;
-
 	if (clk_pout)
 		ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
 					     WM9713_PCMDIV(wm9713_div));
@@ -156,6 +141,16 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
 	if (ret < 0)
 		return ret;
 
+	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0)
+		return ret;
+
 	return 0;
 }
 
-- 
1.5.6.3

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

* Re: PXA SSP - work in progress
  2009-03-13 14:37 PXA SSP - work in progress Mark Brown
  2009-03-13 14:37 ` [RFC] ASoC: switch PXA SSP driver from network mode to PSP Mark Brown
@ 2009-03-13 17:15 ` Daniel Mack
  1 sibling, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2009-03-13 17:15 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, pHilipp Zabel

Hi Mark,

On Fri, Mar 13, 2009 at 02:37:24PM +0000, Mark Brown wrote:
> I worked a bit on the PXA SSP code last night and was able to come up
> with a configuration which uses non-network mode for I2S and works well
> on the Zylonite.  I'll post the current series I have in a followup to
> this, if you could take a look that'd be great - I haven't yet worked
> through all the testing I'd like to do.
> 
> Unfortunately it's going to have broken Daniel's configuration since I
> inverted the sense of LRCLK as the chip seemed not to generate an LRCLK
> with a non-zero frame delay; I need to check to see if this is just
> something I've overlooked.  Hopefully Daniel's system should just have
> inverted the left and right channels.

I can confirm that my board still works with your latest patches, so I'm
fine with your changes :) And indeed - the channels were inverted, I
didn't check that before as it wasn't my greatest concern ...

Thanks,
Daniel

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

end of thread, other threads:[~2009-03-13 17:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-13 14:37 PXA SSP - work in progress Mark Brown
2009-03-13 14:37 ` [RFC] ASoC: switch PXA SSP driver from network mode to PSP Mark Brown
2009-03-13 14:37   ` [RFC] ASoC: Fix non-networked I2S mode for PXA SSP Mark Brown
2009-03-13 14:37     ` [RFC] ASoC: Fix Zylonite for non-networked SSP mode Mark Brown
2009-03-13 17:15 ` PXA SSP - work in progress Daniel Mack

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox