Hi Takashi, Thanks for your explanation. My request was not clear, since my understanding of ALSA is lacking and I need to understand more...
The driver I currently have is here: http://www.pecore.ch/test/ep93xx-i2s.c.txt
It's really messy, it performs all the format conversions in the driver (they could be done in the alsa-lib) and it lacks some functionalities, so I would like to make it shorter, better and more readable.
The driver does not currently define SNDRV_PCM_INFO_MMAP and the memory is copied in the copy callback. I would like to delete the copy callback (which is not really used), since the samples could be written directly to the dma buffer by alsa-lib.
How does alsa-lib know how to store the samples in the dma-buffer? How does alsa-lib know that the samples are interleaved, occupy 32 bits each one (even if the format is 24 bits) and that the left channel samples are at index #0 and the left ones at index #1? Or that between two consecutive samples in mono there should be a 4 bytes gap?
I suppose this is set in the formats filed of the snd_pcm_hardware_t struct, but I did not find a clear explanation of that...
Thanks again Andrea
--- Takashi Iwai tiwai@suse.de wrote:
At Tue, 17 Apr 2007 01:03:24 -0700 (PDT), Ciaccia wrote:
Hi all, I am trying to fix (improve?) a driver for an
embedded
ARM device I bought months ago, and for some
reasons
some ALSA applications work fine while other ones don't...
Looking at the driver I got, I noticed that the
info
field in the snd_pcm_hardware_t struct just
defines:
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE
while the info in the tutorial "writing an alsa driver" defines:
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID
Furthermore, the driver defines a copy callback (actually 2, one for playback and one for
capture),
where it copies the data from the use space to the
dma
buffer. Since the dma buffer was preallocated with snd_pcm_lib_preallocate_pages_for_all and is accessible from the "outside", I wonder why the original author did this...
I have some questions for you gurus:
- what is the difference between
SNDRV_PCM_INFO_MMAP
and SNDRV_PCM_INFO_MMAP_VALID? What is SNDRV_PCM_INFO_BLOCK_TRANSFER?
MMAP flag is a very important flag. This indicates that the driver can work on mmap mode. If not given, no mmap is allowed.
Meanwhile, MMAP_VALID and BLOCK_TRANSFER flags are only for kernel-OSS emulation. For ALSA native apps, they have no meaning. MMAP_VALID is necessary for allowing OSS mmap mode. BLOCK_TRANSFER is specified, it resets REALTIME capability in OSS ioctl.
- The code calls
snd_pcm_lib_preallocate_pages_for_all
function as following:
/* allocate the pcm(DMA) memory */ ret = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,0, 4*128*1024, 4*128*1024);
is the DMA_TYPE right for an ARM device? Is NULL a correct value for data in this case?
No, it should pass the device pointer there. Also make sure that snd_pcm_lib_malloc() is actually used in hw_params callback. Otherwise, pre-allocation makes no sense.
- In case I get rid of the copy callback, how do I
specify the format of the stream? How does Where
can I
find an example for that?
The available formats are specified snd_pcm_hardware formats. Then in prepare callback, you can get the specified format by the application via runtime->format field.
I don't understand the rest question in the above. But, note that the copy callback isn't used at all in mmap mode. The copy/silenece callbacks are for read/write mode. When the app mmaps the buffer, it means that the buffer is directly accessible without read/write calls. So, it skips copy and silence callbacks. If any copy operation is needed, the driver itself has to do in some way, e.g. in background task or in ack callback.
HTH,
Takashi
__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com