Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9eb8ae72 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/dma' into asoc-next

parents 5561f17f 6f1fd93e
Loading
Loading
Loading
Loading
+69 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#define __SOUND_DMAENGINE_PCM_H__

#include <sound/pcm.h>
#include <sound/soc.h>
#include <linux/dmaengine.h>

/**
@@ -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);

/**
@@ -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
+4 −0
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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"
+4 −0
Original line number Diff line number Diff line
@@ -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/
+3 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
}

@@ -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