Daniel Ribeiro wrote:
I am not really sure of how the pcap <-> pxa-ssp communication is made, maybe it is 16 bit stereo audio sent with 32bit i2s emulation (8.4.11 of pxa manual) with PXA as slave, maybe it is not... All i know is that it does not work unless we use 32 bit ssp frames for 16 bit audio data.
I did some more research on this and now i am convinced that it is I2S MSB with PXA slave. The following (untested, its time to sleep ;) ) patches fixes I2S emulation on pxa2xx-ssp.c and removes the override hack on ezx.c. I think that nobody was using I2S emulation from pxa2xx-ssp.c because the hw_params call from soc-core was changing the frame size.

PS: Sorry for the obsolete pxa2xx-ssp version, it shouldnt be hard to port the changes for the current version. :)


--
Daniel Ribeiro
Fix I2S emulation on pxa2xx-ssp.

Signed-off-by: Daniel Ribeiro <[EMAIL PROTECTED]>
Index: linux-2.6.24.1/sound/soc/pxa/pxa2xx-ssp.c
===================================================================
--- linux-2.6.24.1.orig/sound/soc/pxa/pxa2xx-ssp.c
+++ linux-2.6.24.1/sound/soc/pxa/pxa2xx-ssp.c
@@ -383,39 +383,6 @@
 	SSCR1_P(port) = 0;
 	SSPSP_P(port) = 0;
 
-	/* NOTE: I2S emulation is still very much work in progress here */
-
-	/* FIXME: this is what wince uses for msb */
-	if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_MSB) {
-		SSCR0_P(port) = SSCR0_EDSS | SSCR0_TISSP | SSCR0_DataSize(16);
-
-//		SSCR1_P(port) = SSCR1_RxTresh(8) | SSCR1_TxTresh(8); /* doesn't seem to be needed */
-		return 0;
-	}
-
-	/* check for I2S emulation mode - handle it separately  */
-	if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) ||
-		((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_MSB)) {
-		/* 8.4.11 */
-
-		/* Only SSCR0[NCS] or SSCR0[ECS] bit fields settings are optional */
-		SSCR0_P(port) = SSCR0_EDSS | SSCR0_PSP | SSCR0_DataSize(16);
-
-		/* SSCR1 = 0x203C3C03 */
-		/* SSCR1[SCLKDIR] and SSCR1[SFRMDIR] must be cleared (master only ???),
-		 * all other bit fields settings are optional. */
-		//SSCR1_P(port) &= ~(SSCR1_SCLKDIR | SSCR1_SFRMDIR);
-
-		/* set FIFO thresholds */
-		SSCR1_P(port) = SSCR1_RxTresh(14) | SSCR1_TxTresh(1);
-
-		/* normal: */
-		/* all bit fields must be cleared except: FSRT = 1 and
-		 * SFRMWDTH = 16, DMYSTART=0,1) */
-		SSPSP_P(port) = SSPSP_FSRT | SSPSP_SFRMWDTH(16) | SSPSP_DMYSTRT(0);
-		return 0;
-	}
-
 	SSCR0_P(port) |= SSCR0_PSP;
 	SSCR1_P(port) = SSCR1_RxTresh(14) | SSCR1_TxTresh(1) |
 		SSCR1_TRAIL | SSCR1_RWOT;
@@ -446,15 +413,17 @@
 		return -EINVAL;
 	}
 
+	SSPSP_P(port) |= SSPSP_SCMODE(2);
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_DSP_A:
 		SSPSP_P(port) |= SSPSP_DMYSTRT(1);
 	case SND_SOC_DAIFMT_DSP_B:
-		SSPSP_P(port) |= SSPSP_SCMODE(2);
 		break;
 	case SND_SOC_DAIFMT_I2S:
+		SSPSP_P(port) |= SSPSP_FSRT;
 	case SND_SOC_DAIFMT_MSB:
-		/* handled above */
+		SSCR0_P(port) |= SSCR0_EDSS | SCCR0_DataSize(16);
+		SSPSP_P(port) |= SSPSP_SFRMWDTH(16);
 		break;
 	default:
 		return -EINVAL;
@@ -484,7 +453,13 @@
 
 	/* we can only change the settings if the port is not in use */
 	if (SSCR0_P(port) & SSCR0_SSE)
-		return 0;
+		goto ret;
+	
+	/* check if we are running on I2S mode */
+	/* FIXME: Is there a better way to check this? */
+	if ((SSCR0_P(port)&(SSCR0_EDSS|SSCR0_DataSize(16)|SSCR0_PSP)) ==
+				(SSCR0_EDSS|SSCR0_DataSize(16)|SSCR0_PSP))
+		goto ret;
 
 	/* clear selected SSP bits */
 	SSCR0_P(port) &= ~(SSCR0_DSS | SSCR0_EDSS);
@@ -504,6 +479,7 @@
 		break;
 	}
 
+ret:
 #if PXA_SSP_DEBUG
 	printk("SSCR0 %x SSCR1 %x SSTO %x SSPSP %x SSSR %x SSACD %x\n",
 		SSCR0_P(port), SSCR1_P(port),
Use the I2S emulation from pxa2xx-ssp, remove override hack.

Signed-off-by: Daniel Ribeiro <[EMAIL PROTECTED]>

Index: linux-2.6.24.1/sound/soc/pxa/ezx.c
===================================================================
--- linux-2.6.24.1.orig/sound/soc/pxa/ezx.c
+++ linux-2.6.24.1/sound/soc/pxa/ezx.c
@@ -111,8 +111,13 @@
 		return ret;
 
 	/* set cpu DAI configuration */
-	ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B |
+	if (codec_dai->id == PCAP2_STEREO_DAI)
+		ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_MSB |
 			SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
+	else
+		ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B |
+			SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
+
 	if (ret < 0)
 		return ret;
 
@@ -138,24 +143,9 @@
 	return 0;
 }
 
-static int ezx_machine_prepare(struct snd_pcm_substream *substream)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
-
-	if (codec_dai->id == PCAP2_STEREO_DAI) {
-		/* override pxa2xx-ssp sample size for stereo/network mode */
-		SSCR0_P(cpu_dai->id+1) &= ~(SSCR0_DSS | SSCR0_EDSS);
-		SSCR0_P(cpu_dai->id+1) |= (SSCR0_EDSS | SSCR0_DataSize(16));
-	}
-	return 0;
-}
-
 /* machine Alsa PCM operations */
 static struct snd_soc_ops ezx_ops = {
 	.startup = ezx_machine_startup,
-	.prepare = ezx_machine_prepare,
 	.hw_free = ezx_machine_hw_free,
 	.hw_params = ezx_machine_hw_params,
 };

Reply via email to