Reading audio DMA memory via `readl`


I am writing a simple kernel module to read very small quantities of audio DMA data during an I2S recording on a Jetson AGX Xavier. My goal is to memory map useful I2S and DMA registers in my kernel module, and read actual audio data/bytes (via readl) during an I2S recording/capture operation. The base registers I have obtained are: I2S1 module’s base register: 0x2901000 (the I2S interface used during recording), the ADMAIF base register: 0x290f000 and the ADMA base register: 0x2930000.

Through my research in the Jetson sound driver code base, I understand that different channels are used during an I2S recording operation. I have tried reading some channel RX_FIFO_READ and TX_FIFO_WRITE registers during I2S capture, for example using: readl(admaif_base + CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i)), where `admaif_base = ioremap(adma_base_register + size). The data read does not seem to change during the recording operation so I assume this is not actual audio data.

I also tried similar tricks but with DMA memory. That is, memory mapping the ADMA registers using ioremap and using readl to read some specific offset but I haven’t succeeded in reading any actual audio bytes coming from the I2S mic during capture.

I am doing these for research purposes and will greatly appreciate any tips (e.g., sample code or links to code) on how to achieve my goal.


Hi petersonyuhala,
I understand your end goal, ADMAIF by default operates on DMA transfer mode, in this mode the data samples can’t be trapped/read using registers in any of the audio hw modules. The TEGRA_ADMAIF_RX_FIFO_READ you were trying to read applies for ADMAIF in PIO mode, the tegra drivers don’t support this mode as this for debug purpose and not for production use.

Does reading the data samples from memory/buffer after DMA transfer won’t help your case?.

Hi @mkumard , thanks for your reply.
Regarding your proposition, do you mean reading the data from DMA memory (i.e., somewhere in ADMA memory) after the I2S recording operation is completed? As concerns the final destination buffer, my simple kernel module cannot directly read the buffer used by the Tegra driver.

I also thought of allocating a local buffer in my kernel module and setting this as the target/destination address for the audio data during DMA transfers, by tweaking the value at ADMA_CH_LOWER_TRG_ADDR offset. Do you think this is feasible?

Lastly, regarding the PIO mode, I overlooked this. Could you point me to any documentation on how to use ADMAIF in PIO mode?


Hi @petersonyuhala,
Yes, I was referring to data from DMA memory which is allocated by kernel driver.

Actually, the final DMA buffer can be read by kernel driver if we have the pcm substream info. The source and target address programmed on ADMA channel register offset 0x34 and 0x3c are physical memory values, so we can’t directly access this. But we can read the buffer(virtual addr) using “runtime->dma_area” pointer for which info available at tegra_pcm.c (under function tegra_pcm_pointer ). If you able to use this pointer from right substream context then your kernel driver can read from the dma buffer.

PIO mode is just a debug mode. Though not recommended for usage (

Hi @mkumard, thank you very much for your help. I will rewrite my module taking all you have said into consideration.

Peterson Yuhala

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.