On 04/15/2013 07:19 PM, Lars-Peter Clausen wrote:
This patch adds a generic dmaengine PCM driver. It builds on top of the dmaengine PCM library and adds the missing pieces like DMA channel management, buffer management and channel configuration. It will be able to replace the majority of the existing platform specific dmaengine based PCM drivers. Devicetree is used to map the DMA channels to the PCM device.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de
+static const char * const dmaengine_pcm_dma_channel_names[] = {
- [SNDRV_PCM_STREAM_PLAYBACK] = "tx",
- [SNDRV_PCM_STREAM_CAPTURE] = "rx",
+};
+/**
- snd_dmaengine_pcm_register - Register a dmaengine based PCM device
- @dev: The parent device for the PCM device
- @config: Platform specific PCM configuration
- @flags: Platform specific quirks
- */
+int snd_dmaengine_pcm_register(struct device *dev,
- const struct snd_dmaengine_pcm_config *config, unsigned int flags)
+{
- struct dmaengine_pcm *pcm;
- unsigned int i;
- if (!dev->of_node)
return -EINVAL;
- pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
- if (!pcm)
return -ENOMEM;
- pcm->config = config;
- for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
pcm->chan[i] = of_dma_request_slave_channel(dev->of_node,
dmaengine_pcm_dma_channel_names[i]);
Here we should have flexibility to provide custom DMA channel names. For OMAP4 AESS support (which I'm cleaning up right now for upstream) will need such a flexibility since we will have 8 DMA channels and none of them is dedicated tx or rx.
- }
- return snd_soc_add_platform(dev, &pcm->platform,
&dmaengine_pcm_platform);
+} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);
+/**
- snd_dmaengine_pcm_unregister - Removes a dmaengine based PCM device
- @dev: Parent device the PCM was register with
- Removes a dmaengine based PCM device previously registered with
- snd_dmaengine_pcm_register.
- */
+void snd_dmaengine_pcm_unregister(struct device *dev) +{
- struct snd_soc_platform *platform;
- struct dmaengine_pcm *pcm;
- unsigned int i;
- platform = snd_soc_lookup_platform(dev);
- if (!platform)
return;
- pcm = soc_platform_to_pcm(platform);
- for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
if (pcm->chan[i])
dma_release_channel(pcm->chan[i]);
- }
- snd_soc_remove_platform(platform);
- kfree(pcm);
+} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister);
+MODULE_LICENSE("GPL");