Loading include/sound/dmaengine_pcm.h +69 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define __SOUND_DMAENGINE_PCM_H__ #include <sound/pcm.h> #include <sound/soc.h> #include <linux/dmaengine.h> /** Loading @@ -39,9 +40,15 @@ snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream); int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data); struct dma_chan *chan); int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream); int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data); int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream); struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn, void *filter_data); struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream); /** Loading @@ -68,4 +75,65 @@ void snd_dmaengine_pcm_set_config_from_dai_data( const struct snd_dmaengine_dai_dma_data *dma_data, struct dma_slave_config *config); /* * Try to request the DMA channel using compat_request_channel or * compat_filter_fn if it couldn't be requested through devicetree. */ #define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0) /* * Don't try to request the DMA channels through devicetree. This flag only * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well. */ #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1) /* * The platforms dmaengine driver does not support reporting the amount of * bytes that are still left to transfer. */ #define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(2) /* * The PCM is half duplex and the DMA channel is shared between capture and * playback. */ #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3) /** * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM * @prepare_slave_config: Callback used to fill in the DMA slave_config for a * PCM substream. Will be called from the PCM drivers hwparams callback. * @compat_request_channel: Callback to request a DMA channel for platforms * which do not use devicetree. * @compat_filter_fn: Will be used as the filter function when requesting a * channel for platforms which do not use devicetree. The filter parameter * will be the DAI's DMA data. * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM. * @prealloc_buffer_size: Size of the preallocated audio buffer. * * Note: If both compat_request_channel and compat_filter_fn are set * compat_request_channel will be used to request the channel and * compat_filter_fn will be ignored. Otherwise the channel will be requested * using dma_request_channel with compat_filter_fn as the filter function. */ struct snd_dmaengine_pcm_config { int (*prepare_slave_config)(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); struct dma_chan *(*compat_request_channel)( struct snd_soc_pcm_runtime *rtd, struct snd_pcm_substream *substream); dma_filter_fn compat_filter_fn; const struct snd_pcm_hardware *pcm_hardware; unsigned int prealloc_buffer_size; }; int snd_dmaengine_pcm_register(struct device *dev, const struct snd_dmaengine_pcm_config *config, unsigned int flags); void snd_dmaengine_pcm_unregister(struct device *dev); int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); #endif include/sound/soc.h +4 −0 Original line number Diff line number Diff line Loading @@ -375,6 +375,10 @@ int snd_soc_poweroff(struct device *dev); int snd_soc_register_platform(struct device *dev, const struct snd_soc_platform_driver *platform_drv); void snd_soc_unregister_platform(struct device *dev); int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, const struct snd_soc_platform_driver *platform_drv); void snd_soc_remove_platform(struct snd_soc_platform *platform); struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev); int snd_soc_register_codec(struct device *dev, const struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); Loading sound/soc/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,10 @@ config SND_SOC_AC97_BUS config SND_SOC_DMAENGINE_PCM bool config SND_SOC_GENERIC_DMAENGINE_PCM bool select SND_SOC_DMAENGINE_PCM # All the supported SoCs source "sound/soc/atmel/Kconfig" source "sound/soc/au1x/Kconfig" Loading sound/soc/Makefile +4 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,10 @@ ifneq ($(CONFIG_SND_SOC_DMAENGINE_PCM),) snd-soc-core-objs += soc-dmaengine-pcm.o endif ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) snd-soc-core-objs += soc-generic-dmaengine-pcm.o endif obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += generic/ Loading sound/soc/atmel/atmel-pcm-dma.c +3 −3 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, if (ssc->pdev) sdata = ssc->pdev->dev.platform_data; ret = snd_dmaengine_pcm_open(substream, filter, sdata); ret = snd_dmaengine_pcm_open_request_chan(substream, filter, sdata); if (ret) { pr_err("atmel-pcm: dmaengine pcm open failed\n"); return -EINVAL; Loading @@ -171,7 +171,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, return 0; err: snd_dmaengine_pcm_close(substream); snd_dmaengine_pcm_close_release_chan(substream); return ret; } Loading @@ -197,7 +197,7 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream) static struct snd_pcm_ops atmel_pcm_ops = { .open = atmel_pcm_open, .close = snd_dmaengine_pcm_close, .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = atmel_pcm_hw_params, .prepare = atmel_pcm_dma_prepare, Loading Loading
include/sound/dmaengine_pcm.h +69 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define __SOUND_DMAENGINE_PCM_H__ #include <sound/pcm.h> #include <sound/soc.h> #include <linux/dmaengine.h> /** Loading @@ -39,9 +40,15 @@ snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream); int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data); struct dma_chan *chan); int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream); int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data); int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream); struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn, void *filter_data); struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream); /** Loading @@ -68,4 +75,65 @@ void snd_dmaengine_pcm_set_config_from_dai_data( const struct snd_dmaengine_dai_dma_data *dma_data, struct dma_slave_config *config); /* * Try to request the DMA channel using compat_request_channel or * compat_filter_fn if it couldn't be requested through devicetree. */ #define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0) /* * Don't try to request the DMA channels through devicetree. This flag only * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well. */ #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1) /* * The platforms dmaengine driver does not support reporting the amount of * bytes that are still left to transfer. */ #define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(2) /* * The PCM is half duplex and the DMA channel is shared between capture and * playback. */ #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3) /** * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM * @prepare_slave_config: Callback used to fill in the DMA slave_config for a * PCM substream. Will be called from the PCM drivers hwparams callback. * @compat_request_channel: Callback to request a DMA channel for platforms * which do not use devicetree. * @compat_filter_fn: Will be used as the filter function when requesting a * channel for platforms which do not use devicetree. The filter parameter * will be the DAI's DMA data. * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM. * @prealloc_buffer_size: Size of the preallocated audio buffer. * * Note: If both compat_request_channel and compat_filter_fn are set * compat_request_channel will be used to request the channel and * compat_filter_fn will be ignored. Otherwise the channel will be requested * using dma_request_channel with compat_filter_fn as the filter function. */ struct snd_dmaengine_pcm_config { int (*prepare_slave_config)(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); struct dma_chan *(*compat_request_channel)( struct snd_soc_pcm_runtime *rtd, struct snd_pcm_substream *substream); dma_filter_fn compat_filter_fn; const struct snd_pcm_hardware *pcm_hardware; unsigned int prealloc_buffer_size; }; int snd_dmaengine_pcm_register(struct device *dev, const struct snd_dmaengine_pcm_config *config, unsigned int flags); void snd_dmaengine_pcm_unregister(struct device *dev); int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); #endif
include/sound/soc.h +4 −0 Original line number Diff line number Diff line Loading @@ -375,6 +375,10 @@ int snd_soc_poweroff(struct device *dev); int snd_soc_register_platform(struct device *dev, const struct snd_soc_platform_driver *platform_drv); void snd_soc_unregister_platform(struct device *dev); int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, const struct snd_soc_platform_driver *platform_drv); void snd_soc_remove_platform(struct snd_soc_platform *platform); struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev); int snd_soc_register_codec(struct device *dev, const struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); Loading
sound/soc/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,10 @@ config SND_SOC_AC97_BUS config SND_SOC_DMAENGINE_PCM bool config SND_SOC_GENERIC_DMAENGINE_PCM bool select SND_SOC_DMAENGINE_PCM # All the supported SoCs source "sound/soc/atmel/Kconfig" source "sound/soc/au1x/Kconfig" Loading
sound/soc/Makefile +4 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,10 @@ ifneq ($(CONFIG_SND_SOC_DMAENGINE_PCM),) snd-soc-core-objs += soc-dmaengine-pcm.o endif ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) snd-soc-core-objs += soc-generic-dmaengine-pcm.o endif obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += generic/ Loading
sound/soc/atmel/atmel-pcm-dma.c +3 −3 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, if (ssc->pdev) sdata = ssc->pdev->dev.platform_data; ret = snd_dmaengine_pcm_open(substream, filter, sdata); ret = snd_dmaengine_pcm_open_request_chan(substream, filter, sdata); if (ret) { pr_err("atmel-pcm: dmaengine pcm open failed\n"); return -EINVAL; Loading @@ -171,7 +171,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, return 0; err: snd_dmaengine_pcm_close(substream); snd_dmaengine_pcm_close_release_chan(substream); return ret; } Loading @@ -197,7 +197,7 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream) static struct snd_pcm_ops atmel_pcm_ops = { .open = atmel_pcm_open, .close = snd_dmaengine_pcm_close, .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = atmel_pcm_hw_params, .prepare = atmel_pcm_dma_prepare, Loading