Beaglebone - McASP - PCM

I am working with beaglebone/am335x and would like to use McASP (Creating human signal generator :)). I think I almost did it but it’s not working properly yet.

With a help form Ti-wiki. I do:

  • create driver for PCM1690
  • build driver to kernel
  • configure ALSA machine layer
  • add everything to Device Tree
  • then enable it in kernel

As a platform I use sitarta-TI Linux Image and SDK from TI (great tools thx :P).

What is coming out from my processor (measure by oscilloscope):
-AHCLKX (~24MHz ~ 512xfs)
-FSX (50kHz)
-ACLKX(1.6MHz ~ 32xfs)
-AXR0 (Some data)

And my PCM1690 have register 69 (0x45) which is changing if PCM see any inputs. It’s works but I still see no output from my DAC.

From start I have 3 questions:

  1. When I play 48kHz wav files (example /usr/share/sound/alsa/Front_left.wav or speaker-test -c 2. My ‘fs’ is 48kHz right? So why my FSX is 50kHz? Shouldn’t be 48kHz?
  2. How to set properly AHCLKX? In wiki there was no need to even turn it on. My DAC needs it and I lunch it by adding this 2 lines in davinci-mcasp.c file to section:
    /* codec is clock and frame slave */”
    //my code
    mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX);
    mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);

But It’s let me only to output 24MHz, but I want to change it depends on my fs rate (I should have exactly 512xfs, now its only close to this) I guess It should be in davinci-evm.c where I set ACLKX. Here is my code where I do this:

unsigned int bclk_freq = evm_get_bclk(params);
unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
int ret;
ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);

So I set divider from my sysclk (default 24MHz in sitara-TI procesors). So how to change also AHCLKX (Is there a mirror divider as I do with ACLKX?)
3.Why my PCM not working? xD Or more precise where you advise me to look for mistakes or answers? Maybe I should try with polarity of my signals? Or with PCM169 configuration?

If you need any more outputs, informations or even screen from oscilloscope, do not hesitate to ask me. I will replay as fast as I can and with all my knowledge I have/will get.

Hi pl.krzy

I’m wondering if you have go further in this issue. Right now I’m using mcasp (master) AM3354 board and an audio codec (slave). MLCK (ahclkx) and BCLK (aclkx) shows a 24MHz clock (when it needs MCLK = 48KHz x 256 and BLCK = 48KHz x 62 (32bits x 2ch).
As base I’m using this file and my init looks like:


static int evm_hw_params(struct snd_pcm_substream *substream,

struct snd_pcm_hw_params *params)


struct snd_soc_pcm_runtime *rtd = substream->private_data;

struct snd_soc_dai *codec_dai = rtd->codec_dai;

struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

int ret = 0;

unsigned sysclk;

printk(KERN_ALERT “DEBUG(%s):\n”, FUNCTION);

sysclk = 24576000;

printk(KERN_ALERT “DEBUG(%s): cpu snd_soc_dai_set_fmt\n”, FUNCTION);

/* set cpu DAI configuration */

ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);

if (ret < 0)

return ret;

printk(KERN_ALERT “DEBUG(%s): codec snd_soc_dai_set_fmt\n”, FUNCTION);

/* set codec DAI configuration */

ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);

if (ret < 0)

return ret;

sysclk = 256*48000;

// cpu

// printk(KERN_ALERT “DEBUG(%s): cpu snd_soc_dai_set_sysclk=%d\n”, FUNCTION , sysclk);

// ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);

// if (ret < 0)

// return ret;

// codec

printk(KERN_ALERT “DEBUG(%s): codec snd_soc_dai_set_sysclk=%d\n”, FUNCTION , sysclk);

ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN);

if (ret < 0)

return ret;

return 0;


Please can you share your toughs with me?