ALSA DMA or ISA not working on IMX6Q

cancel
Showing results for 
Search instead for 
Did you mean: 

ALSA DMA or ISA not working on IMX6Q

5,315 Views
johnturnur
Contributor III

hi,

We are having a hardware with IMX6Q and TAS5706 audio amplifier chip.

Its configuration is different than standard SABRE SD board.

I have written a driver which works with ALSA.

I am able to communicat IC with I2C commands.

But i am not able to tranfer data .

getting follwoing error

"playback write error (DMA or IRQ trouble?)"

"aplay: pcm_write"

"write error: I/O error"

At this time state is in SNDRV_PCM_STATE_RUNNING.

Thanks,

Labels (6)
30 Replies

213 Views
wangshengjiu
NXP Employee
NXP Employee

Hi John

     Here is two advice for you, you can try it.

     1. please probe the clock in TXC and TXFS, make sure there is clock on these lines.

     2. As the SSI is master mode. So you need to update the machine driver like this

        imx_audmux_config(plat->src_port,plat->ext_port)  --> imx_audmux_config(plat->ext_port,plat->src_port).

0 Kudos

213 Views
johnturnur
Contributor III

Thansk for reply, Follwoing is my code.

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

static int imx_audmux_config(int slave, int master)
{
unsigned int ptcr, pdcr;
slave = slave - 1;
master = master - 1;

ptcr = MXC_AUDMUX_V2_PTCR_SYN |
  MXC_AUDMUX_V2_PTCR_TFSDIR |
  MXC_AUDMUX_V2_PTCR_TFSEL(master) |
  MXC_AUDMUX_V2_PTCR_TCLKDIR |
  MXC_AUDMUX_V2_PTCR_TCSEL(master);
pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(master);
mxc_audmux_v2_configure_port(slave, ptcr, pdcr);

ptcr = MXC_AUDMUX_V2_PTCR_SYN;
pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(slave);
mxc_audmux_v2_configure_port(master, ptcr, pdcr);

return 0;
}

according to you code change is right?

0 Kudos

213 Views
wangshengjiu
NXP Employee
NXP Employee

Hi John

  Change imx_audmux_config(plat->src_port,plat->ext_port) to imx_audmux_config(plat->ext_port,plat_src_port).

0 Kudos

213 Views
wangshengjiu
NXP Employee
NXP Employee

Add also please change "SND_SOC_DAIFMT_CBM_CFM" to "SND_SOC_DAIFMT_CBS_CFS".

213 Views
johnturnur
Contributor III

Thanks for this information. I will make a change and update the result.

0 Kudos

213 Views
vsv
Contributor III

Hi all,

We are building a custom board with iMX6Q and using Maxim Max98089 audio codec on it. We are getting the same error on trying to play back a wav file. We indeed made the suggestions given here in terms of changing the parameters of imx_aud_config() as well as changing SND_SOC_DAIFMT_CBS_CFS. But we still end up getting the same error at the end of running alsa_aplay command.

Is there any other setting that we should try to get this working? Any help will be much appreciated.

Thanks

0 Kudos

213 Views
wangshengjiu
NXP Employee
NXP Employee

Hi Vasan

     I check the datasheet of Max98089. it seems that it support master mode, why you want to use slave mode? otherwise, please check the BCLK and LRCLk, if there is clock on the line.

0 Kudos

213 Views
vsv
Contributor III

Hi Shengjiu,

We did check the MCLK and we could find the clock coming in. However LRCLK was not present. In order to determine if there is anything from the processor to codec issues, we tried our image on our hardware board with out the codec connected, and observed that now we get the same error as mentioned above (DMA or IRQ trouble?)

If you have any ideas on where to look out for to resolve this, please let us know. Really appreciate your help.

Thanks

Vasan

0 Kudos

212 Views
vismayshah
Contributor II

Hi Vasan,

I also faced simillar issue, i was able to get BCLK but was not able to get LRCLK, i could figure out the reason for that. I was playing Mono file which will have only single channel so in that case LRCLK may not be required as it doesn't need signal to indicate whether current word being transmitted is left channel word or right channel word but if you play a stereo file you will get LRCLK if everything else is correct, however if you want to play Mono file you may change in codec file inside kernel

sound/soc/codecs/<You Codec file> :

You will find this structure:

snd_soc_dai_driver

within that structure :

.playback = {

.stream_name = "Playback",

//.channels_min  = 1,

.channels_min  = 2, ---->Change to min channels 2 from 1

.channels_max = 2,

check if you have channels_min = 1. In case min channels = 1 then for mono streams ssi doesn't send LRCLK, So if you change .channels_min = 2 then imx ssi will consider it as 2 channels and send LRCLK in order to indentify channel number.

I hope it helps,

Regards,

Vismay

212 Views
vsv
Contributor III

Hi Vismay,

Thanks for your detailed inputs. Appreciate it very much.

We are using a stereo wav file and not a mono file. Our channels_min is also configured as 1 and channels_max is configured as 2. We are trying to operate the MAXIM audio codec as a slave on this since we have the iMX6 processor as the master for other reasons in our hardware. We also find that using the oscilloscope, the LRCLK is coming to be around 250Khz on this codec. We are suspecting of whether this is too high because of which the audio is just playing as a single pulse instead of as a normal wave file.

Have you faced any similar issues?

Thanks in advance for your inputs


Vasan

0 Kudos

212 Views
vismayshah
Contributor II

Hi Vasan,

That's true, if LRCLK is coming 250KHz its too high which makes audio play as fast forwarded.

Actually LRCLK should be same as the Sampling Rate of the Audio file used.That means if you are playing a Stereo 48KHz file then LRCLK should be same as 48KHz irrespective of databits within each word. So if you want to play 48KHz file then :

LRCLK = 48KHz

Bit Clock = ( 48000 (sampling rate) * 2 ( channels/words per frame )  * 32 ( bits/word ) = 3.072MHz

So if you set your Bit Clock to be 3.072MHz your LRCLK will automatically come down to 48KHz and will play audio file at correct speed.

To set your Bit Clock around 3.072MHz you need to set SSI Clock divisor to divide your SSI System clock to get your Bit Clock.

You can refer SSI Clocking---> DIV2, PSR and PM Bit Description in SSI Chapter of imx6 Reference Manual to set correct division.

Also right now as you are saying you are getting 250KHz LRCLK that means you would be getting

Bit Clock = ( 250,000) * 2 * 32 = 16MHz that means your SSI system clock might be twice of this = 32 MHz as per below equation from imx6 Reference Manual's SSI Chapter ---> SSI Clocking --->  DIV2, PSR and PM Bit Description

f INT _ BIT_CLK = f SSI's sys clock / [(DIV2 + 1) x (7 x PSR + 1) x (PM + 1) x2]

so if your f SSI's sys clock = 32MHz to get f INT _ BIT_CLK = 3.072MHz you need to set,

PM = 4 DIV2 = 0 PSR = 0, which makes overall divison by:  [ ( 4 (PM) + 1)  x ( 1 ) x ( 1 ) x 2 ]= 10 ,

so Bit Clock = 32MHz ( SSI sys clock ) / 10 = 3.2MHz

Try to get Bit Clock = 2 * 32 * Frame Rate ( Sampling Rate )

2 -- is for Stereo means 2 channels/words per frame

32 -- No. of bits per word it will always be 32 irrespective of actual data width you actually utilize out of 32 bits

Frame Rate = Sampling Rate = LRCLK

Hope it helps,

Regards,

Vismay

212 Views
vsv
Contributor III

Hi Vismay,

Thanks for your detailed analysis and inputs. From the details provided, it

is clear that you have taken lot of pains to explain. Appreciate your time

and inputs on this and I will try these and get back with the findings

definitely.

Since we are operating the maxim codec as a slave and the data sheet for

the codec was stating that LRCLK was an input when operating as a slave. So

we had not calculated and set it explicitly and expected it to set it by

itself.

Thanks

Vasan

0 Kudos

212 Views
johnturnur
Contributor III

Hi,

Are able to get it work?


0 Kudos

212 Views
vsv
Contributor III

Yes. Thanks to the detailed analysis provided by VismayShah, we were able to get the stereo working on our codec.

The main problem was the calculation of the divisor for generating the BITCLK since our codec was operating as a slave device. We had to play around with the three parameters to come up to the correct divisor calculation for a stereo wave file. After this, the stereo wave file is successfully playing.

Some of the other changes that we had to make was:

- Swapped the parameters of imx_audmux_config in the probe function to be the following:

     imx_audmux_config (plat->ext_port, plat->src_port)

since we were operating in slave mode

- (MAXIM CODEC specific) We had to set a register setting to derive the PCLK from MCLK

After making all these changes, the stereo file is successfully getting played.

We are trying currently to make a mono file successfully getting played.

Special thanks to Vismay Shah for his detailed inputs. Much appreciated.

0 Kudos

212 Views
VishnuSankar
Contributor I

Hi Vasan,

I am also facing the same issue. I am configuring my i.MX6 Solo lite processor as master and max98089 as slave. I am getting data and clock on I2S lines with BCLK as 3 MHz and LRCK as 48kHz  when I played a stereo file. But no sound is coming out from the Max98089. Can u just tell me what are the changes u have done in max98089 driver source code.

Thanx and regards

vishnu sankar

0 Kudos

212 Views
vsv
Contributor III

Hi Vishnu,

A few points:

a) Have you changed the parameters to imx_audmux_config in the max98089_probe function to make plat->ext_port and plat->src_port interchanged?

b) In your board-mx6q_sabrelite.c, what are the values that you have given for ext_port and src_port as part of your audio initialization?

c) In imx/imx-max98089.c file, max98089_params() function, have you set the divisors for PSR and Clock appropriately?

Vasan

0 Kudos

212 Views
vismayshah
Contributor II

You are welcome Vasan.

0 Kudos

213 Views
vsv
Contributor III

Hi Shengjiu,


The previous problem of DMA or IRQ trouble turned out to be because of i2c problem in our board. After this was fixed on the hardware, now, when we play the wav file on the board, we do not get any sound and neither any error.

We would like to get a clarification on the below code(arch/arm/plat-mxc/include/mach/audmux.h):

/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */

#define MXC_AUDMUX_V2_PTCR_TFSDIR       (1 << 31)

#define MXC_AUDMUX_V2_PTCR_TFSEL(x)     (((x) & 0xf) << 27)

#define MXC_AUDMUX_V2_PTCR_TCLKDIR      (1 << 26)

#define MXC_AUDMUX_V2_PTCR_TCSEL(x)     (((x) & 0xf) << 22)

#define MXC_AUDMUX_V2_PTCR_RFSDIR       (1 << 21)

#define MXC_AUDMUX_V2_PTCR_RFSEL(x)     (((x) & 0xf) << 17)

#define MXC_AUDMUX_V2_PTCR_RCLKDIR      (1 << 16)

#define MXC_AUDMUX_V2_PTCR_RCSEL(x)     (((x) & 0xf) << 12)

#define MXC_AUDMUX_V2_PTCR_SYN          (1 << 11)

#define MXC_AUDMUX_V2_PDCR_RXDSEL(x)    (((x) & 0x7) << 13)

#define MXC_AUDMUX_V2_PDCR_TXRXEN       (1 << 12)

#define MXC_AUDMUX_V2_PDCR_MODE(x)      (((x) & 0x3) << 8)

#define MXC_AUDMUX_V2_PDCR_INMMASK(x)   ((x) & 0xff)

----

The above set of definitions do not indicate that these are to be used for IMX6 processor but only talk till iMX51 only.

Will the same work for iMX6.


We are using SSI num as 1, Src Port as 2 and External port as 3 currently in board-init file. We are connected to AUD3 in our hardware board and we use the Second DAI interface of our codec (because of which we have kept the src port as 2).


Also, we call the audmux_configure function as follows:

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

Our imx_audmux_config is defined as follows:


static int imx_audmux_config(int slave, int master)

{

        unsigned int ptcr, pdcr;

        slave = slave - 1;

        master = master - 1;

                ptcr = MXC_AUDMUX_V2_PTCR_SYN |

                MXC_AUDMUX_V2_PTCR_TFSDIR |

                MXC_AUDMUX_V2_PTCR_TFSEL(master) |

                MXC_AUDMUX_V2_PTCR_TCLKDIR |

                MXC_AUDMUX_V2_PTCR_TCSEL(master);

        pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(master);

        mxc_audmux_v2_configure_port(slave, ptcr, pdcr);

        ptcr = MXC_AUDMUX_V2_PTCR_SYN;

        pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(slave);

        mxc_audmux_v2_configure_port(master, ptcr, pdcr);

        return 0;

}

Please let us know if you see any issue in the above configuration because of which we are not able to use it successfully.

Thanks in advance,

0 Kudos

212 Views
wangshengjiu
NXP Employee
NXP Employee

Hi Vasan

     I think the configuration of AUDMUX is correct. it is hard to say which cause your issue. I have some advice from you.

     1. In your case, the codec is in master mode, SSI is in slave mode. please check the configuration in machin driver is correct. that is dai_format = SND_SOC_DAIFMT_CBM_CFM.

    2. Please check there is data signal in the data pin.

    3. Is the codec configuration correct? Is the audio route opened? do you miss to set any register of codec?

  

best regards

wang shengjiu

0 Kudos

212 Views
vsv
Contributor III

Hi Shengjiu,

After swapping the src_port and ext_port in the audmux_configure function, we find that the clock is successfully coming in when we observe with a oscilloscope. The AUD3_TXD, AUD3_TXFS and AUD3_TXC are pulsing correctly when a wave file is being played. However, we still do not get to hear the sound except for a small pulse now. But we are not able to hear the full wave file played for 5-6 seconds.


We are trying to set the TDM slots with the following parameters (in our codec hw_params function) :

snd_soc_dai_set_tdm_slot (cpu_dai, 0xfffffffc, 0xfffffffc, 2, 32)

Is this something to be corrected or any other area to be looked at for this problem to be resolved?

Thanks in advance for your inputs,

Vasan

0 Kudos