IMX6 SSI in 16b instead of 24

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

IMX6 SSI in 16b instead of 24

Jump to solution
795 Views
yann_cardaillac
Contributor II

Hi,

I've been stuck on this issue for few days now.

I am using kernel 4.14.39, I want to use the SSI within alsa in S16_LE, however I seem to be stuck with S24_LE, I cannot find where does that comes from.

I have been able to force the SSI in 16b mode by calling within the driver :

regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_WL_MASK,
                    CCSR_SSI_SxCCR_WL(16));

I am using the driver fsl-ssi.c with the dummy-codec and alsa simple card. None of them should be giving limitation when it come to bitdepth. Does any one can help me on that one ?

How can I overcome that? Does  anyone fall on the same problem ? Is it fixed on more recent release?

Regards,

Labels (5)
0 Kudos
1 Solution
650 Views
yann_cardaillac
Contributor II

Hi Igorpadykow,

Thanks for your links, I found the issue, it was hard to catch, but basically the problem was about the sdma declaring wrong info about it's abilities, it has been fixed in upstream kernels, if someone encountered this issue, one should look into imx-sdma.c, static int sdma_probe(struct platform_device *pdev), and look for the place where src_addr_widths (and dst_addr_widths too) and change it for newer version :

find :

sdma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
sdma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);

and replace with :

sdma->dma_device.src_addr_widths = SDMA_DMA_BUSWIDTHS;
sdma->dma_device.dst_addr_widths = SDMA_DMA_BUSWIDTHS;

don't forget to add the define :

#define SDMA_DMA_BUSWIDTHS    (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
                 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
                 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))

What was happening is that when setting capabilities in Alsa, the DMA was not showing proper allowed formats. See soc-generic-dmaengine-pcm.c and dmaengine.c. One should give a close look to int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) and static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substream). This is very deep in asoc, but eventually we figured out the issue. Thanks again to those that helped me find the issue in alsa and asoc IRC (snawrocky, ckeepax and wabbits).

Thanks for the support,

Regards,

Yann

View solution in original post

0 Kudos
2 Replies
650 Views
igorpadykov
NXP Employee
NXP Employee

Hi yann

one can try with some of official nxp linux releases

linux-imx - i.MX Linux kernel 

and check Linux Manual with description of audio drivers

https://www.nxp.com/support/developer-resources/software-development-tools/i.mx-developer-resources/... 

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

0 Kudos
651 Views
yann_cardaillac
Contributor II

Hi Igorpadykow,

Thanks for your links, I found the issue, it was hard to catch, but basically the problem was about the sdma declaring wrong info about it's abilities, it has been fixed in upstream kernels, if someone encountered this issue, one should look into imx-sdma.c, static int sdma_probe(struct platform_device *pdev), and look for the place where src_addr_widths (and dst_addr_widths too) and change it for newer version :

find :

sdma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
sdma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);

and replace with :

sdma->dma_device.src_addr_widths = SDMA_DMA_BUSWIDTHS;
sdma->dma_device.dst_addr_widths = SDMA_DMA_BUSWIDTHS;

don't forget to add the define :

#define SDMA_DMA_BUSWIDTHS    (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
                 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
                 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))

What was happening is that when setting capabilities in Alsa, the DMA was not showing proper allowed formats. See soc-generic-dmaengine-pcm.c and dmaengine.c. One should give a close look to int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) and static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substream). This is very deep in asoc, but eventually we figured out the issue. Thanks again to those that helped me find the issue in alsa and asoc IRC (snawrocky, ckeepax and wabbits).

Thanks for the support,

Regards,

Yann

0 Kudos