Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.6 105 lines 2.7 kB view raw
1/* 2 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de> 3 * 4 * This code is based on code copyrighted by Freescale, 5 * Liam Girdwood, Javier Martin and probably others. 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 */ 12 13#include <linux/dma-mapping.h> 14#include <linux/module.h> 15#include <sound/pcm.h> 16#include <sound/soc.h> 17#include "imx-pcm.h" 18 19int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, 20 struct vm_area_struct *vma) 21{ 22 struct snd_pcm_runtime *runtime = substream->runtime; 23 int ret; 24 25 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, 26 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); 27 28 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, 29 runtime->dma_area, 30 runtime->dma_addr, 31 runtime->dma_bytes); 32 return ret; 33} 34EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap); 35 36static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 37{ 38 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 39 struct snd_dma_buffer *buf = &substream->dma_buffer; 40 size_t size = IMX_SSI_DMABUF_SIZE; 41 42 buf->dev.type = SNDRV_DMA_TYPE_DEV; 43 buf->dev.dev = pcm->card->dev; 44 buf->private_data = NULL; 45 buf->area = dma_alloc_writecombine(pcm->card->dev, size, 46 &buf->addr, GFP_KERNEL); 47 if (!buf->area) 48 return -ENOMEM; 49 buf->bytes = size; 50 51 return 0; 52} 53 54static u64 imx_pcm_dmamask = DMA_BIT_MASK(32); 55 56int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) 57{ 58 struct snd_card *card = rtd->card->snd_card; 59 struct snd_pcm *pcm = rtd->pcm; 60 int ret = 0; 61 62 if (!card->dev->dma_mask) 63 card->dev->dma_mask = &imx_pcm_dmamask; 64 if (!card->dev->coherent_dma_mask) 65 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 66 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 67 ret = imx_pcm_preallocate_dma_buffer(pcm, 68 SNDRV_PCM_STREAM_PLAYBACK); 69 if (ret) 70 goto out; 71 } 72 73 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { 74 ret = imx_pcm_preallocate_dma_buffer(pcm, 75 SNDRV_PCM_STREAM_CAPTURE); 76 if (ret) 77 goto out; 78 } 79 80out: 81 return ret; 82} 83EXPORT_SYMBOL_GPL(imx_pcm_new); 84 85void imx_pcm_free(struct snd_pcm *pcm) 86{ 87 struct snd_pcm_substream *substream; 88 struct snd_dma_buffer *buf; 89 int stream; 90 91 for (stream = 0; stream < 2; stream++) { 92 substream = pcm->streams[stream].substream; 93 if (!substream) 94 continue; 95 96 buf = &substream->dma_buffer; 97 if (!buf->area) 98 continue; 99 100 dma_free_writecombine(pcm->card->dev, buf->bytes, 101 buf->area, buf->addr); 102 buf->area = NULL; 103 } 104} 105EXPORT_SYMBOL_GPL(imx_pcm_free);