summaryrefslogtreecommitdiff
path: root/sound/soc/soc-dmaengine-pcm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-03 20:10:23 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-03 20:10:23 +0400
commit9992ba72327fa0d8bdc9fb624e80f5cce338a711 (patch)
treee0bf31ae53cb19c44674df7e0d0343a26037ad34 /sound/soc/soc-dmaengine-pcm.c
parent00fdffb5131125dce0702bf61e24a806ec3aed80 (diff)
parent4ca231b2e6ed171107c5b21f9e92d1965fd6fd9e (diff)
downloadlinux-9992ba72327fa0d8bdc9fb624e80f5cce338a711.tar.xz
Merge tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "Mostly many small changes spread as seen in diffstat in sound/* directory by this update. A significant change in the subsystem level is the introduction of snd_soc_component, which will help more generic handling of SoC and off-SoC components. Also, snd_BUG_ON() macro is enabled unconditionally now due to its misuses, so people might hit kernel warnings (it's a good thing for us). - compress-offload: support for capture by Charles Keepax - HD-audio: codec delay support by Dylan Reid - HD-audio: improvements/fixes in generic parser: better headphone mic and headset mic support, jack_modes hint consolidation, proper beep attach/detachment, generalized power filter controls by David Henningsson, et al - HD-audio: Improved management of HDMI codec pins/converters - HD-audio: Better pin/DAC assignment for VIA codecs - HD-audio: Haswell HDMI workarounds - HD-audio: ALC268 codec support, a few new quirks for Chromebooks - USB: regression fixes: USB-MIDI autopm fix, the recent ISO latency fix by Clemens Ladisch - USB: support for DSD formats by Daniel Mack - USB: A few UAC2 device endian/cock fixes by Eldad Zack - USB: quirks for Emu 192kHz support, Novation Twitch DJ controller, Yamaha THRxx devices - HDSPM: updates for TCO controls by Adrian Knoth - ASoC: Add a snd_soc_component object type for generic handling of SoC and off-SoC components by Kuninori Morimoto, - dmaengine: a large set of cleanups and conversions by Lars-Peter Clausen - ASoC DAPM: performance optimizations from Ryo Tsutsui - ASoC DAPM: support for mixer control sharing by Stephen Warren - ASoC: multiplatform ARM cleanups from Arnd Bergmann - ASoC: new codec drivers for AK5385 and TAS5086 from Daniel Mack" * tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (315 commits) ALSA: usb-audio: caiaq: fix endianness bug in snd_usb_caiaq_maschine_dispatch ALSA: asihpi: add format support check in snd_card_asihpi_capture_formats ALSA: pcm_format_to_bits strong-typed conversion ALSA: compress: fix the states to check for allowing read ALSA: hda - Move Thinkpad X220 to use auto parser ALSA: USB: adjust for changed 3.8 USB API ALSA: usb - Avoid unnecessary sample rate changes on USB 2.0 clock sources sound: oss/dmabuf: use dma_map_single ALSA: ali5451: use mdelay instead of large udelay constants ALSA: hda - Add the support for ALC286 codec ALSA: usb-audio: USB quirk for Yamaha THR10C ALSA: usb-audio: USB quirk for Yamaha THR5A ALSA: usb-audio: USB quirk for Yamaha THR10 ALSA: usb-audio: Fix autopm error during probing ALSA: snd-usb: try harder to find USB_DT_CS_ENDPOINT ALSA: sound kconfig typo ALSA: emu10k1: Fix dock firmware loading ASoC: ux500: forward declare msp_i2s_platform_data ASoC: davinci-mcasp: Add Support BCLK-to-LRCLK ratio for TDM modes ASoC: davinci-pcm, davinci-mcasp: Clean up active_serializers ...
Diffstat (limited to 'sound/soc/soc-dmaengine-pcm.c')
-rw-r--r--sound/soc/soc-dmaengine-pcm.c150
1 files changed, 98 insertions, 52 deletions
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 111b7d921e89..aa924d9b7986 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -33,8 +33,6 @@ struct dmaengine_pcm_runtime_data {
dma_cookie_t cookie;
unsigned int pos;
-
- void *data;
};
static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
@@ -43,33 +41,6 @@ static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
return substream->runtime->private_data;
}
-/**
- * snd_dmaengine_pcm_set_data - Set dmaengine substream private data
- * @substream: PCM substream
- * @data: Data to set
- */
-void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-
- prtd->data = data;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data);
-
-/**
- * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data
- * @substream: PCM substream
- *
- * Returns the data previously set with snd_dmaengine_pcm_set_data
- */
-void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-
- return prtd->data;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data);
-
struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
@@ -118,10 +89,49 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
slave_config->src_addr_width = buswidth;
}
+ slave_config->device_fc = false;
+
return 0;
}
EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
+/**
+ * snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config
+ * using DAI DMA data.
+ * @substream: PCM substream
+ * @dma_data: DAI DMA data
+ * @slave_config: DMA slave configuration
+ *
+ * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and
+ * slave_id fields of the DMA slave config from the same fields of the DAI DMA
+ * data struct. The src and dst fields will be initialized depending on the
+ * direction of the substream. If the substream is a playback stream the dst
+ * fields will be initialized, if it is a capture stream the src fields will be
+ * initialized. The {dst,src}_addr_width field will only be initialized if the
+ * addr_width field of the DAI DMA data struct is not equal to
+ * DMA_SLAVE_BUSWIDTH_UNDEFINED.
+ */
+void snd_dmaengine_pcm_set_config_from_dai_data(
+ const struct snd_pcm_substream *substream,
+ const struct snd_dmaengine_dai_dma_data *dma_data,
+ struct dma_slave_config *slave_config)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ slave_config->dst_addr = dma_data->addr;
+ slave_config->dst_maxburst = dma_data->maxburst;
+ if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
+ slave_config->dst_addr_width = dma_data->addr_width;
+ } else {
+ slave_config->src_addr = dma_data->addr;
+ slave_config->src_maxburst = dma_data->maxburst;
+ if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
+ slave_config->src_addr_width = dma_data->addr_width;
+ }
+
+ slave_config->slave_id = dma_data->slave_id;
+}
+EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
+
static void dmaengine_pcm_dma_complete(void *arg)
{
struct snd_pcm_substream *substream = arg;
@@ -244,44 +254,48 @@ snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream)
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer);
-static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd,
- dma_filter_fn filter_fn, void *filter_data)
+/**
+ * snd_dmaengine_pcm_request_channel - Request channel for the dmaengine PCM
+ * @filter_fn: Filter function used to request the DMA channel
+ * @filter_data: Data passed to the DMA filter function
+ *
+ * Returns NULL or the requested DMA channel.
+ *
+ * This function request a DMA channel for usage with dmaengine PCM.
+ */
+struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
+ void *filter_data)
{
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_CYCLIC, mask);
- prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data);
- if (!prtd->dma_chan)
- return -ENXIO;
-
- return 0;
+ return dma_request_channel(mask, filter_fn, filter_data);
}
+EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_request_channel);
/**
* snd_dmaengine_pcm_open - Open a dmaengine based PCM substream
* @substream: PCM substream
- * @filter_fn: Filter function used to request the DMA channel
- * @filter_data: Data passed to the DMA filter function
+ * @chan: DMA channel to use for data transfers
*
* Returns 0 on success, a negative error code otherwise.
*
- * This function will request a DMA channel using the passed filter function and
- * data. The function should usually be called from the pcm open callback.
- *
- * Note that this function will use private_data field of the substream's
- * runtime. So it is not availabe to your pcm driver implementation. If you need
- * to keep additional data attached to a substream use
- * snd_dmaengine_pcm_{set,get}_data.
+ * The function should usually be called from the pcm open callback. Note that
+ * this function will use private_data field of the substream's runtime. So it
+ * is not availabe to your pcm driver implementation.
*/
int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
- dma_filter_fn filter_fn, void *filter_data)
+ struct dma_chan *chan)
{
struct dmaengine_pcm_runtime_data *prtd;
int ret;
+ if (!chan)
+ return -ENXIO;
+
ret = snd_pcm_hw_constraint_integer(substream->runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0)
@@ -291,11 +305,7 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
if (!prtd)
return -ENOMEM;
- ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data);
- if (ret < 0) {
- kfree(prtd);
- return ret;
- }
+ prtd->dma_chan = chan;
substream->runtime->private_data = prtd;
@@ -304,6 +314,27 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open);
/**
+ * snd_dmaengine_pcm_open_request_chan - Open a dmaengine based PCM substream and request channel
+ * @substream: PCM substream
+ * @filter_fn: Filter function used to request the DMA channel
+ * @filter_data: Data passed to the DMA filter function
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ *
+ * This function will request a DMA channel using the passed filter function and
+ * data. The function should usually be called from the pcm open callback. Note
+ * that this function will use private_data field of the substream's runtime. So
+ * it is not availabe to your pcm driver implementation.
+ */
+int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
+ dma_filter_fn filter_fn, void *filter_data)
+{
+ return snd_dmaengine_pcm_open(substream,
+ snd_dmaengine_pcm_request_channel(filter_fn, filter_data));
+}
+EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan);
+
+/**
* snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
* @substream: PCM substream
*/
@@ -311,11 +342,26 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
- dma_release_channel(prtd->dma_chan);
kfree(prtd);
return 0;
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
+/**
+ * snd_dmaengine_pcm_release_chan_close - Close a dmaengine based PCM substream and release channel
+ * @substream: PCM substream
+ *
+ * Releases the DMA channel associated with the PCM substream.
+ */
+int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream)
+{
+ struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+
+ dma_release_channel(prtd->dma_chan);
+
+ return snd_dmaengine_pcm_close(substream);
+}
+EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan);
+
MODULE_LICENSE("GPL");