linux/sound/arm/devdma.c
<<
>>
Prefs
   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
  20void 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
  36int 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
  76int 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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.