[alsa-devel] WM8731 using I2S on omap3 McBSP2 issues

Hi,
I'm working on getting a WM8731 (in SLAVE) working using I2S on omap3 McBSP2 (in MASTER).
Here is the hardware:
http://www.efn.org/~rick/pub/wm8731.jpg
Here are the PADCONF's and the pins they hook to on the WM8731:
/*Audio Interface for csb740 */\ MUX_VAL(CP(McBSP2_FSX), (OFF_OUT_PD | IDIS | PTU | EN | M0)) /* McBSP2_FSX -> I2S_FRM -> LRCLK -> DACLRC and ADCLRC*/\ MUX_VAL(CP(McBSP2_CLKX), (OFF_OUT_PD | IDIS | PTU | EN | M0)) /* McBSP2_CLKX -> I2S_CLK -> I2S_BCLK -> BCLK */\ MUX_VAL(CP(McBSP2_DR), (OFF_IN_PD | IEN | PTD | DIS | M0)) /* McBSP2_DR <- I2S_RXD <- ACDDAT */\ MUX_VAL(CP(McBSP2_DX), (OFF_OUT_PD | IDIS | PTU | EN | M0)) /* McBSP2_DX -> I2S_TXD -> DACDAT */\ MUX_VAL(CP(McBSP_CLKS), (OFF_IN_PD | IEN | PTD | DIS | M0)) /* McBSP_CLKS <- I2S_MCLK <- CLKOUT */\
My kernel is "2.6.29-rc3-omap1", here's what I see at bootup:
1 WM8731 Audio Codec 0.13<6>asoc: WM8731 <-> omap-mcbsp-dai-0 mapping ok 2 ALSA device list: 3 #0: omap3csb740 (WM8731) ... 4 beagle:~# aplay test48000.wav 5 Playing WAVE 'test48000.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo 6 aplay: pcm_write:1269: write error: Input/output error
I get no audio output, other than a "click" when the 8731 is initialized upon boot. When I look at the signals the McBSP2_DX line just goes low for the duration of the "aplay", it does not toggle. The other lines look fine. The file is at http://www.efn.org/~rick/pub/omap3csb740.c but roughly, here's what I'm doing:
static struct snd_soc_dai_link omap3csb740_dai = { ... .cpu_dai = &omap_mcbsp_dai[0], /* use 1st one */
static int __init omap3csb740_soc_init(void) ... *(unsigned int *)omap_mcbsp_dai[0].private_data = 1; /* McBSP2 */ *(unsigned int *)omap3csb740_dai.cpu_dai->private_data = 1; /* McBSP2 debug only? */
static int omap3csb740_hw_params(struct snd_pcm_substream *substream, ... ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000, SND_SOC_CLOCK_IN); ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0, SND_SOC_CLOCK_IN); ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 256);
Any help is greatly appreciated.
Rick Bronson

On Thu, Sep 24, 2009 at 10:06:07AM -0700, Rick Bronson wrote:
MUX_VAL(CP(McBSP_CLKS), (OFF_IN_PD | IEN | PTD | DIS | M0)) /* McBSP_CLKS <- I2S_MCLK <- CLKOUT */\
...
5 Playing WAVE 'test48000.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo 6 aplay: pcm_write:1269: write error: Input/output error
This suggests that the DMA isn't happening which usually means that the CPU isn't seeing all the clocks it's supposed to. I'm not familiar enough with the OMAP internals to know if you've set the CPU up properly.
I get no audio output, other than a "click" when the 8731 is initialized upon boot. When I look at the signals the McBSP2_DX line just goes low for the duration of the "aplay", it does not toggle. The other lines look fine. The file is at
If you try a record then does the ADCDAT line show a signal?

Mark,
This suggests that the DMA isn't happening which usually means that the CPU isn't seeing all the clocks it's supposed to. I'm not familiar enough with the OMAP internals to know if you've set the CPU up properly.
I've poured over the relavent code for this and am pretty sure I don't need to touch it. The same code works on the beagleboard, at least the DMA part. But you never know...
I get no audio output, other than a "click" when the 8731 is initialized upon boot. When I look at the signals the McBSP2_DX line just goes low for the duration of the "aplay", it does not toggle. The other lines look fine. The file is at
If you try a record then does the ADCDAT line show a signal?
I tried this and the ADCDAT does show a signal. See http://www.efn.org/~rick/pub/win10586.jpg The bottom five traces are as follows:
McBSP2_CLKX -> I2S_CLK -> I2S_BCLK -> BCLK */\ McBSP2_FSX -> I2S_FRM -> LRCLK -> DACLRC and ADCLRC*/\ McBSP2_DR <- I2S_RXD <- ACDDAT */\ McBSP_CLKS <- I2S_MCLK <- CLKOUT */\ McBSP2_DX -> I2S_TXD -> DACDAT */\
BTW, when I do a aplay, the trace looks the same except ACDDAT is low.
I still get a write error though:
beagle:~# arecord -t wav -f cd -d 1500 dar.wav Recording WAVE 'dar.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo arecord: pcm_read:1348: read error: Input/output error
Rick

On Thu, Sep 24, 2009 at 11:00:52AM -0700, Rick Bronson wrote:
Mark,
This suggests that the DMA isn't happening which usually means that the CPU isn't seeing all the clocks it's supposed to. I'm not familiar enough with the OMAP internals to know if you've set the CPU up properly.
I've poured over the relavent code for this and am pretty sure I don't need to touch it. The same code works on the beagleboard, at least the DMA part. But you never know...
You shouldn't need to touch the DMA code itself, it's normally an issue with the clocks and/or the pinmux code not managing to get the signals required to clock the data transfer.
BTW, when I do a aplay, the trace looks the same except ACDDAT is low.
Yes, that's what I'd expect - this was just an attempt to confirm that the CODEC is happy.

You shouldn't need to touch the DMA code itself, it's normally an issue with the clocks and/or the pinmux code not managing to get the signals required to clock the data transfer.
I noticed the dma code has been changed from what I have.
Also noticed that the beagleboard is getting DMA interrupts when I "aplay":
cat /proc/interrupts | grep DMA
12: 4646 INTC DMA
but I'm not. As I mentioned, I'm at "2.6.29-rc3-omap1", anyone think there is a problem with pcm DMA's in that version?
Thanks
Rick

On Thu, Sep 24, 2009 at 03:37:28PM -0700, Rick Bronson wrote:
Also noticed that the beagleboard is getting DMA interrupts when I "aplay":
cat /proc/interrupts | grep DMA
12: 4646 INTC DMA
That's just the same symptom - the I/O error that aplay reports is a lack of interrupts reporting that audio is moving through the system.
but I'm not. As I mentioned, I'm at "2.6.29-rc3-omap1", anyone think there is a problem with pcm DMA's in that version?

Hello,
On Thursday 24 September 2009 20:06:07 ext Rick Bronson wrote:
Hi,
I'm working on getting a WM8731 (in SLAVE) working using I2S on omap3 McBSP2 (in MASTER).
static int omap3csb740_hw_params(struct snd_pcm_substream *substream, ... ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000, SND_SOC_CLOCK_IN); ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0, SND_SOC_CLOCK_IN);
I think the problem is here. The MCBSP_CLKS pin is connected to CLK256FS pin of TWL4030 (or TPA). Since you are not using the TWL codec, there will be no clock on the MCBSP_CLKS pin, thus no functional clock for McBSP, thus no bits are shifted in or out. You can try to use the internal functional clock:
ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, 0, SND_SOC_CLOCK_IN);
Than set the correct divider, which depends on the frequency you would like to play. The source for the CLKS_FCLK is (in case of McBSP2) PER_96M_FCLK, so 96MHz. Now you have to divide this to get the correct value, as I recall quite a long time ago there were some discussion about this here, and I have sent some 'formula' to calculate it, but I can not find it now :(
ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 256);
Any help is greatly appreciated.
Rick Bronson

On Friday 25 September 2009 09:03:06 Ujfalusi Peter (Nokia-D/Tampere) wrote:
Hello,
On Thursday 24 September 2009 20:06:07 ext Rick Bronson wrote:
Hi,
I'm working on getting a WM8731 (in SLAVE) working using I2S on omap3 McBSP2 (in MASTER).
static int omap3csb740_hw_params(struct snd_pcm_substream *substream, ... ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000, SND_SOC_CLOCK_IN); ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0, SND_SOC_CLOCK_IN);
I think the problem is here. The MCBSP_CLKS pin is connected to CLK256FS pin of TWL4030 (or TPA).
This applies for the Beagle board, which I thought that you are using that from this line:
4 beagle:~# aplay test48000.wav
Can you check that the clock is running between CLKOUT (WM8731) -> McBSP_CLKS (OMAP3) pins?
If the clock is missing, than the functional clock is not running.
Since you are not using the TWL codec, there will be no clock on the MCBSP_CLKS pin, thus no functional clock for McBSP, thus no bits are shifted in or out. You can try to use the internal functional clock:
ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, 0, SND_SOC_CLOCK_IN);
Than set the correct divider, which depends on the frequency you would like to play. The source for the CLKS_FCLK is (in case of McBSP2) PER_96M_FCLK, so 96MHz. Now you have to divide this to get the correct value, as I recall quite a long time ago there were some discussion about this here, and I have sent some 'formula' to calculate it, but I can not find it now :(
ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 256);
Any help is greatly appreciated.
Rick Bronson
participants (3)
-
Mark Brown
-
Peter Ujfalusi
-
Rick Bronson