Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  *  linux/sound/arm/devdma.c
  3  *
  4  *  Copyright (C) 2003-2004 Russell King, All rights reserved.
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License version 2 as
  8  * published by the Free Software Foundation.
  9  *
 10  *  ARM DMA shim for ALSA.
 11  */
 12 #include <linux/device.h>
 13 #include <linux/dma-mapping.h>
 14 
 15 #include <sound/core.h>
 16 #include <sound/pcm.h>
 17 
 18 #include "devdma.h"
 19 
 20 void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream)
 21 {
 22         struct snd_pcm_runtime *runtime = substream->runtime;
 23         struct snd_dma_buffer *buf = runtime->dma_buffer_p;
 24 
 25         if (runtime->dma_area == NULL)
 26                 return;
 27 
 28         if (buf != &substream->dma_buffer) {
 29                 dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr);
 30                 kfree(runtime->dma_buffer_p);
 31         }
 32 
 33         snd_pcm_set_runtime_buffer(substream, NULL);
 34 }
 35 
 36 int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size)
 37 {
 38         struct snd_pcm_runtime *runtime = substream->runtime;
 39         struct snd_dma_buffer *buf = runtime->dma_buffer_p;
 40         int ret = 0;
 41 
 42         if (buf) {
 43                 if (buf->bytes >= size)
 44                         goto out;
 45                 devdma_hw_free(dev, substream);
 46         }
 47 
 48         if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
 49                 buf = &substream->dma_buffer;
 50         } else {
 51                 buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
 52                 if (!buf)
 53                         goto nomem;
 54 
 55                 buf->dev.type = SNDRV_DMA_TYPE_DEV;
 56                 buf->dev.dev = dev;
 57                 buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL);
 58                 buf->bytes = size;
 59                 buf->private_data = NULL;
 60 
 61                 if (!buf->area)
 62                         goto free;
 63         }
 64         snd_pcm_set_runtime_buffer(substream, buf);
 65         ret = 1;
 66  out:
 67         runtime->dma_bytes = size;
 68         return ret;
 69 
 70  free:
 71         kfree(buf);
 72  nomem:
 73         return -ENOMEM;
 74 }
 75 
 76 int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma)
 77 {
 78         struct snd_pcm_runtime *runtime = substream->runtime;
 79         return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
 80 }
 81 
  This page was automatically generated by the LXR engine.