2 * linux/sound/arm/devdma.c
4 * Copyright (C) 2003-2004 Russell King, All rights reserved.
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.
10 * ARM DMA shim for ALSA.
12 #include <linux/device.h>
13 #include <linux/dma-mapping.h>
15 #include <sound/core.h>
16 #include <sound/pcm.h>
20 void devdma_hw_free(struct device
*dev
, struct snd_pcm_substream
*substream
)
22 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
23 struct snd_dma_buffer
*buf
= runtime
->dma_buffer_p
;
25 if (runtime
->dma_area
== NULL
)
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
);
33 snd_pcm_set_runtime_buffer(substream
, NULL
);
36 int devdma_hw_alloc(struct device
*dev
, struct snd_pcm_substream
*substream
, size_t size
)
38 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
39 struct snd_dma_buffer
*buf
= runtime
->dma_buffer_p
;
43 if (buf
->bytes
>= size
)
45 devdma_hw_free(dev
, substream
);
48 if (substream
->dma_buffer
.area
!= NULL
&& substream
->dma_buffer
.bytes
>= size
) {
49 buf
= &substream
->dma_buffer
;
51 buf
= kmalloc(sizeof(struct snd_dma_buffer
), GFP_KERNEL
);
55 buf
->dev
.type
= SNDRV_DMA_TYPE_DEV
;
57 buf
->area
= dma_alloc_coherent(dev
, size
, &buf
->addr
, GFP_KERNEL
);
59 buf
->private_data
= NULL
;
64 snd_pcm_set_runtime_buffer(substream
, buf
);
67 runtime
->dma_bytes
= size
;
76 int devdma_mmap(struct device
*dev
, struct snd_pcm_substream
*substream
, struct vm_area_struct
*vma
)
78 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
79 return dma_mmap_coherent(dev
, vma
, runtime
->dma_area
, runtime
->dma_addr
, runtime
->dma_bytes
);