diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-03 20:10:23 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-03 20:10:23 +0400 |
commit | 9992ba72327fa0d8bdc9fb624e80f5cce338a711 (patch) | |
tree | e0bf31ae53cb19c44674df7e0d0343a26037ad34 /sound/soc/tegra/tegra_pcm.c | |
parent | 00fdffb5131125dce0702bf61e24a806ec3aed80 (diff) | |
parent | 4ca231b2e6ed171107c5b21f9e92d1965fd6fd9e (diff) | |
download | linux-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/tegra/tegra_pcm.c')
-rw-r--r-- | sound/soc/tegra/tegra_pcm.c | 187 |
1 files changed, 9 insertions, 178 deletions
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 5e2c55c5b255..f056f632557c 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -29,9 +29,7 @@ * */ -#include <linux/dma-mapping.h> #include <linux/module.h> -#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -55,191 +53,24 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = { .fifo_size = 4, }; -static int tegra_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct device *dev = rtd->platform->dev; - int ret; - - /* Set HW params now that initialization is complete */ - snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); - - ret = snd_dmaengine_pcm_open(substream, NULL, NULL); - if (ret) { - dev_err(dev, "dmaengine pcm open failed with err %d\n", ret); - return ret; - } - - return 0; -} - -static int tegra_pcm_close(struct snd_pcm_substream *substream) -{ - snd_dmaengine_pcm_close(substream); - return 0; -} - -static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct device *dev = rtd->platform->dev; - struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); - struct tegra_pcm_dma_params *dmap; - struct dma_slave_config slave_config; - int ret; - - dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - ret = snd_hwparams_to_dma_slave_config(substream, params, - &slave_config); - if (ret) { - dev_err(dev, "hw params config failed with err %d\n", ret); - return ret; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - slave_config.dst_addr = dmap->addr; - slave_config.dst_maxburst = 4; - } else { - slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - slave_config.src_addr = dmap->addr; - slave_config.src_maxburst = 4; - } - slave_config.slave_id = dmap->req_sel; - - ret = dmaengine_slave_config(chan, &slave_config); - if (ret < 0) { - dev_err(dev, "dma slave config failed with err %d\n", ret); - return ret; - } - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - return 0; -} - -static int tegra_pcm_hw_free(struct snd_pcm_substream *substream) -{ - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - -static int tegra_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops tegra_pcm_ops = { - .open = tegra_pcm_open, - .close = tegra_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = tegra_pcm_hw_params, - .hw_free = tegra_pcm_hw_free, - .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer, - .mmap = tegra_pcm_mmap, -}; - -static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = tegra_pcm_hardware.buffer_bytes_max; - - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->bytes = size; - - return 0; -} - -static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - - substream = pcm->streams[stream].substream; - if (!substream) - return; - - buf = &substream->dma_buffer; - if (!buf->area) - return; - - dma_free_writecombine(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; -} - -static u64 tegra_dma_mask = DMA_BIT_MASK(32); - -static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret = 0; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &tegra_dma_mask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = tegra_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto err; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = tegra_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto err_free_play; - } - - return 0; - -err_free_play: - tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); -err: - return ret; -} - -static void tegra_pcm_free(struct snd_pcm *pcm) -{ - tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); - tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); -} - -static struct snd_soc_platform_driver tegra_pcm_platform = { - .ops = &tegra_pcm_ops, - .pcm_new = tegra_pcm_new, - .pcm_free = tegra_pcm_free, +static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = { + .pcm_hardware = &tegra_pcm_hardware, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, + .compat_filter_fn = NULL, + .prealloc_buffer_size = PAGE_SIZE * 8, }; int tegra_pcm_platform_register(struct device *dev) { - return snd_soc_register_platform(dev, &tegra_pcm_platform); + return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, + SND_DMAENGINE_PCM_FLAG_NO_DT | + SND_DMAENGINE_PCM_FLAG_COMPAT); } EXPORT_SYMBOL_GPL(tegra_pcm_platform_register); void tegra_pcm_platform_unregister(struct device *dev) { - snd_soc_unregister_platform(dev); + return snd_dmaengine_pcm_unregister(dev); } EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister); |