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!
Solved! Go to Solution.
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
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!
-----------------------------------------------------------------------------------------------------------------------
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 */ |
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
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.
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
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");
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
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
thanks,the audio is ok now.