imx53 uda134x audio issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

imx53 uda134x audio issue

Jump to solution
2,276 Views
Jacky_Song
Contributor III

     hi,everyone:

          i have a problem with uda134x in imx53-loco.

          here is the kernel log:

[    1.837294] No device for DAI UDA134X

[    1.841094] No device for DAI imx-ssi-1-0

[    1.845128] No device for DAI imx-ssi-1-1

[    1.849188] No device for DAI imx-ssi-2-0

[    1.853223] No device for DAI imx-ssi-2-1

[    1.868003] UDA134X SoC Audio Codec

[    1.883014] DMA Sound Buffer Allocated: Playback UseIram=1 ext_ram=0 buf->addr=f8002000 buf->area=8e042000 size=24576

[    1.893726] DMA Sound Buffer Allocated: Capture  UseIram=1 ext_ram=1 buf->addr=7c298000 buf->area=fa28c000 size=24576

[    1.904353] asoc: UDA134X <-> imx-ssi-2-0 mapping ok

[    1.909516] usb 2-1: new high speed USB device using fsl-ehci and address 2

[    1.919852] ALSA device list:

[    1.922901]   #0: imx-3stack (UDA134X)

     then i got error when use madplay or aplay ,and both no sound.

[root@freescale: /mnt/mtdblock4]# ./madplay begin.wav

MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.

error: frame 0: lost synchronization

error: frame 1: lost synchronization

error: frame 2: forbidden bit allocation value

error: frame 3: lost synchronization

error: frame 4: forbidden bit allocation value

error: frame 5: forbidden bit allocation value

error: frame 6: forbidden bit allocation value

error: frame 7: CRC check failed

error: frame 8: forbidden bit allocation value

error: frame 9: forbidden bit allocation value

...

...

[root@freescale: /mnt/mtdblock4]# ./madplay laodifang.mp3

MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.

          Track: 1/1

output: write: Input/output error

     i got diffrent error when play .mp3 and .wav files.

[root@freescale: /mnt/mtdblock4]# ./aplay begin.wav

[aplay] AuHeader = 24

[aplay] VocHeader = 26

[1aplay] WAVE-header = 0

Playing WAVE 'begin.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

     aplay has no error but it finished as soon as i start it.

Is anyone can help me?

Best wishes!

Labels (2)
0 Kudos
Reply
1 Solution
1,937 Views
igorpadykov
NXP Employee
NXP Employee

Hi Jacky

if hardware is OK, then you can printf correct obds SSI/AUDMUX

registers and compare them with linux settings, just printf them.

~igor

View solution in original post

0 Kudos
Reply
9 Replies
1,937 Views
igorpadykov
NXP Employee
NXP Employee

Hi Jacky

one can check if this codec chip driver is correctly written using

MX53UG  Chapter 21 Porting Audio Codecs to a Custom Board

Also it may be recommended to check codec hardware connections

with OBDS audio test

On-Board Diagnostic Suit for the i.MX53 Quick Start Board  :

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
1,937 Views
Jacky_Song
Contributor III

hi igor,tks for your reply.

i have compared mx53_loco.c with the MX53UG, i think it should be no problem. finally i found the i2s lines have no signals when i play sound, and i can hear some noisy when i have a short circuit with i2s lines. so why the i2s do not work? i have config them in the loco.c file

MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC,
MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD,
MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS,
MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD,
MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK, /* Audio CLK*/
MX53_PAD_GPIO_18__GPIO7_13,  /* DAT  */
MX53_PAD_GPIO_17__GPIO7_12,  /* CLK  */
MX53_PAD_GPIO_16__GPIO7_11,  /* MODE */

0 Kudos
Reply
1,937 Views
igorpadykov
NXP Employee
NXP Employee

Hi Jacky

if you have not i2s signals, then one

can check SSI and uda134x clocks. Probably hardware

has errors, this can be found with obds.

~igor

0 Kudos
Reply
1,937 Views
Jacky_Song
Contributor III

hi igor

    

i have build the obds for mx53,but i dont kown how to use it. i cant see any use guide file to show it.

0 Kudos
Reply
1,937 Views
igorpadykov
NXP Employee
NXP Employee

Hi Jacky

one can look at User_Guide_for_imx28_obds_v1_0.pdf

from IMX_OBDS  : On-Board Diagnostic Suit for the i.MX28

~igor

0 Kudos
Reply
1,937 Views
Jacky_Song
Contributor III

hi igor

i have test with obds, and the result shows hardware is ok.

i worked on my own driver, i have L3 and SSi_clk signals,but still no i2s data signals. then i found when i play .mp3 file with madplay, it seems like stop at the decode part,and i can see messages 5686 frames decoded (0:02:16.4),+0.5 dB peak amplitude, 23 clip ped samples, what makes the decode take so long?

i enclose my driver,and i hope you can take a little time to read it. thanks very mach.

/*

* imx-3stack-uda134x.c  --  i.MX 3Stack Driver for UDA1341 Codec

*

* Copyright (C) 2011-2012 Edan Inc. All Rights Reserved.

*

*

*  Revision history

*    5-30-2011   Xiaaijun

*

*/

#include <linux/module.h>

#include <linux/moduleparam.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <linux/pm.h>

#include <linux/bitops.h>

#include <linux/platform_device.h>

#include <linux/err.h>

#include <linux/irq.h>

#include <linux/io.h>

#include <linux/fsl_devices.h>

#include <linux/slab.h>

#include <sound/core.h>

#include <sound/pcm.h>

#include <sound/pcm_params.h>

#include <sound/soc.h>

#include <sound/soc-dapm.h>

#include <sound/initval.h>

#include <sound/uda134x.h>

#include <mach/dma.h>

#include <mach/clock.h>

#include <mach/gpio.h>

#include "../codecs/uda134x.h"

#include "imx-ssi.h"

#include "imx-pcm.h"

#define UDA134X_SYSCLK 0

#define SYSCLK_RATE (512*8000)

struct imx_3stack_priv {

  int sysclk;

  int hw;

  struct platform_device *pdev;

};

static struct imx_3stack_priv card_priv;

static int imx_3stack_audio_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_link *machine = rtd->dai;

  struct snd_soc_dai *cpu_dai = machine->cpu_dai;

  struct snd_soc_dai *codec_dai = machine->codec_dai;

// struct imx_3stack_priv *priv = &card_priv;

  unsigned int rate = params_rate(params);

  struct imx_ssi *ssi_mode = (struct imx_ssi *)cpu_dai->private_data;

  int ret = 0;

  u32 dai_format;

  int bits;

  int channels = params_channels(params);

  switch (params_format(params)) {

  case SNDRV_PCM_FORMAT_S8:

  bits = 8;

  break;

  case SNDRV_PCM_FORMAT_S16_LE:

  bits = 16;

  break;

  case SNDRV_PCM_FORMAT_S24_LE:

  bits = 24;

  break;

  case SNDRV_PCM_FORMAT_S32_LE:

  bits = 32;

  break;

  default:

  return -EINVAL;

  }

#if 0

  /* only need to do this once as capture and playback are sync */

  if (priv->hw)

  return 0;

  priv->hw = 1;

#endif

  dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |

     SND_SOC_DAIFMT_CBS_CFS;

  ssi_mode->sync_mode = 1;

  if (channels == 1)

  ssi_mode->network_mode = 0;

  else

  ssi_mode->network_mode = 1;

  /* set cpu DAI configuration */

  ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);

  if (ret < 0)

  return ret;

  /* set i.MX active slot mask */

  snd_soc_dai_set_tdm_slot(cpu_dai,

  channels == 1 ? 0xfffffffe : 0xfffffffc,

  channels == 1 ? 0xfffffffe : 0xfffffffc,

  2, 32);

  /* set the SSI clock div  */

  snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_TX_DIV_2, 0);

  snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_TX_DIV_PSR, 0);

  snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_TX_DIV_PM, 23);

// snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_RX_DIV_2, 0);

// snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_RX_DIV_PSR, 0);

// snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_RX_DIV_PM, 11);

  /* set the SSI system clock as output  */

  snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_OUT);

  /* set codec DAI configuration */

  snd_soc_dai_set_fmt(codec_dai, dai_format);

  /* Set codec clock*/

  snd_soc_dai_set_sysclk(codec_dai, UDA134X_SYSCLK,512*rate, SND_SOC_CLOCK_OUT);

  return 0;

}

static int imx_3stack_startup(struct snd_pcm_substream *substream)

{

  return 0;

}

static void imx_3stack_shutdown(struct snd_pcm_substream *substream)

{

  struct imx_3stack_priv *priv = &card_priv;

  priv->hw = 0;

}

/*

* imx_3stack UDA134X audio DAI opserations.

*/

static struct snd_soc_ops imx_3stack_ops = {

  .startup = imx_3stack_startup,

  .shutdown = imx_3stack_shutdown,

  .hw_params = imx_3stack_audio_hw_params,

};

static void imx_3stack_init_dam(int ssi_port, int dai_port)

{

  unsigned int ssi_ptcr = 0;

  unsigned int dai_ptcr = 0;

  unsigned int ssi_pdcr = 0;

  unsigned int dai_pdcr = 0;

  /* UDA134X uses SSI1 via AUDMUX port dai_port for audio */

  /* reset port ssi_port & dai_port */

  __raw_writel(0, DAM_PTCR(ssi_port));

  __raw_writel(0, DAM_PTCR(dai_port));

  __raw_writel(0, DAM_PDCR(ssi_port));

  __raw_writel(0, DAM_PDCR(dai_port));

  /* set to synchronous */

  ssi_ptcr |= AUDMUX_PTCR_SYN;

  dai_ptcr |= AUDMUX_PTCR_SYN;

  /* set Rx sources ssi_port <--> dai_port */

  ssi_pdcr |= AUDMUX_PDCR_RXDSEL(dai_port);

  dai_pdcr |= AUDMUX_PDCR_RXDSEL(ssi_port);

  /* set Tx frame direction and source  ssi_port --> dai_port output */

  dai_ptcr |= AUDMUX_PTCR_TFSDIR;

  dai_ptcr |= AUDMUX_PTCR_TFSSEL(AUDMUX_FROM_TXFS, ssi_port);

  /* set Tx Clock direction and source ssi_port--> dai_port output */

  dai_ptcr |= AUDMUX_PTCR_TCLKDIR;

  dai_ptcr |= AUDMUX_PTCR_TCSEL(AUDMUX_FROM_TXFS, ssi_port);

  __raw_writel(ssi_ptcr, DAM_PTCR(ssi_port));

  __raw_writel(dai_ptcr, DAM_PTCR(dai_port));

  __raw_writel(ssi_pdcr, DAM_PDCR(ssi_port));

  __raw_writel(dai_pdcr, DAM_PDCR(dai_port));

}

static int imx_3stack_uda134x_init(struct snd_soc_codec *codec)

{

  return 0;

}

/* imx_3stack digital audio interface glue - connects codec <--> CPU */

static struct snd_soc_dai_link imx_3stack_dai = {

  .name = "UDA134X",

  .stream_name = "UDA134X",

  .codec_dai = &uda134x_dai,

// .cpu_dai = &imx_ssi_dai[2],

  .init = imx_3stack_uda134x_init,

  .ops = &imx_3stack_ops,

};

static int imx_3stack_card_remove(struct platform_device *pdev)

{

  struct imx_3stack_priv *priv = &card_priv;

  struct mxc_audio_platform_data *plat;

  if (priv->pdev) {

  plat = priv->pdev->dev.platform_data;

  if (plat->finit)

  plat->finit();

  }

  return 0;

}

static struct snd_soc_card snd_soc_card_imx_3stack = {

  .name = "imx-3stack",

  .platform = &imx_soc_platform,

  .dai_link = &imx_3stack_dai,

  .num_links = 1,

  .remove = imx_3stack_card_remove,

};

/*  L3 support */

#define L3_DAT   (6*32 + 13) /* GPIO_7_13 */

#define L3_CLK   (6*32 + 12) /* GPIO_7_12 */

#define L3_MODE (6*32 + 11) /* GPIO_7_11 */

static void l3_pin_configure(void)

{

  /*  Configure L3 pins */

  gpio_request(L3_DAT, "L3_DAT");

  gpio_direction_output(L3_DAT, 0);

  gpio_request(L3_CLK, "L3_CLK");

  gpio_direction_output(L3_CLK, 0);

  gpio_request(L3_MODE, "L3_MODE");

  gpio_direction_output(L3_MODE, 0);

}

static void l3_setdat(int v)

{

  gpio_set_value(L3_DAT, v>0);

}

static void l3_setclk(int v)

{

  gpio_set_value(L3_CLK, v>0);

}

static void l3_setmode(int v)

{

  gpio_set_value(L3_MODE, v>0);

}

static struct uda134x_platform_data imx_3stack_uda134x = {

  .l3 = {

  .setdat = l3_setdat,

  .setclk = l3_setclk,

  .setmode = l3_setmode,

  .data_hold = 1, 

  .data_setup = 1,

  .clock_high = 1,

  .mode_hold = 1,

  .mode = 1,

  .mode_setup = 1,

  },

  .model = UDA134X_UDA1341,

};

static struct snd_soc_device imx_3stack_snd_devdata = {

  .card = &snd_soc_card_imx_3stack,

  .codec_dev = &soc_codec_dev_uda134x,

  .codec_data = &imx_3stack_uda134x,

};

static int __devinit imx_3stack_uda134x_probe(struct platform_device *pdev)

{

  struct mxc_audio_platform_data *plat = pdev->dev.platform_data;

  struct imx_3stack_priv *priv = &card_priv;

  struct snd_soc_dai *uda134x_cpu_dai = 0;

  int ret = 0;

  priv->pdev = pdev;

  gpio_activate_audio_ports();

  l3_pin_configure();

  imx_3stack_init_dam(plat->src_port, plat->ext_port);

  if (plat->src_port == 2)

  uda134x_cpu_dai = imx_ssi_dai[2];

  else if (plat->src_port == 1)

  uda134x_cpu_dai = imx_ssi_dai[0];

  else if (plat->src_port == 7)

  uda134x_cpu_dai = imx_ssi_dai[4];

  imx_3stack_dai.cpu_dai = uda134x_cpu_dai;

  /* get mxc_audio_platform_data for pcm */

  imx_3stack_dai.cpu_dai->dev = &pdev->dev;

  ret = -EINVAL;

  if (plat->init && plat->init())

  goto err_plat_init;

  priv->sysclk = plat->sysclk;

// printk("cpu_dai = %d,sysclk = %d\n",plat->src_port,plat->sysclk);

  return 0;

err_plat_init:

  if (plat->finit)

  plat->finit();

  return ret;

}

static int imx_3stack_uda134x_remove(struct platform_device *pdev)

{

  struct mxc_audio_platform_data *plat = pdev->dev.platform_data;

  if (plat->finit)

  plat->finit();

  gpio_free(L3_DAT);

  gpio_free(L3_CLK);

  gpio_free(L3_MODE);

  return 0;

}

static struct platform_driver imx_3stack_uda134x_audio_driver = {

  .probe = imx_3stack_uda134x_probe,

  .remove = imx_3stack_uda134x_remove,

  .driver = {

    .name = "imx-3stack-uda134x",

    },

};

static struct platform_device *imx_3stack_snd_device;

static int __init imx_3stack_init(void)

{

  int ret;

  ret = platform_driver_register(&imx_3stack_uda134x_audio_driver);

  if (ret)

  return -ENOMEM;

  imx_3stack_snd_device = platform_device_alloc("soc-audio", -1);

  if (!imx_3stack_snd_device)

  return -ENOMEM;

  platform_set_drvdata(imx_3stack_snd_device, &imx_3stack_snd_devdata);

  imx_3stack_snd_devdata.dev = &imx_3stack_snd_device->dev;

  ret = platform_device_add(imx_3stack_snd_device);

  if (ret)

  platform_device_put(imx_3stack_snd_device);

  return ret;

}

static void __exit imx_3stack_exit(void)

{

  platform_driver_unregister(&imx_3stack_uda134x_audio_driver);

  platform_device_unregister(imx_3stack_snd_device);

}

module_init(imx_3stack_init);

module_exit(imx_3stack_exit);

MODULE_DESCRIPTION("UDA134X Driver for i.MX 3STACK");

MODULE_LICENSE("GPL");

0 Kudos
Reply
1,938 Views
igorpadykov
NXP Employee
NXP Employee

Hi Jacky

if hardware is OK, then you can printf correct obds SSI/AUDMUX

registers and compare them with linux settings, just printf them.

~igor

0 Kudos
Reply
1,937 Views
Jacky_Song
Contributor III

hi igor:

     i'm sorry for a period of time didn't respond. i can hear voice now. but it has big noise. i set the sysclk in board.c ,and i can measure the value as same as i set.

but i print ssi sysclk in imx_ssi.c file(in probe() or startup()),it always be 12M.and from the bclk and frame sync i can calculated the sysclk is 12M too. here is the init code in board.c

ssi_ext1 = clk_get(NULL, "ssi_ext1_clk");

if (IS_ERR(ssi_ext1))

   return -1;

rate = clk_round_rate(ssi_ext1, 12888000);

if (rate < 2000000 || rate > 24000000) {

   printk(KERN_ERR "Error: UDA134x mclk freq %d out of range!\n",rate);

   clk_put(ssi_ext1);

   return -1;

}

clk_set_rate(ssi_ext1, rate);

clk_enable(ssi_ext1);

uda134x_data.sysclk = rate;

i can't see any place in machine driver to use the rate i set. so what shall i do

0 Kudos
Reply
1,937 Views
Jacky_Song
Contributor III

thanks,the audio is ok now.

0 Kudos
Reply