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,
};