2005-05-12 12:25:58 +04:00
/*
* linux / sound / arm / devdma . c
*
* Copyright ( C ) 2003 - 2004 Russell King , All rights reserved .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* ARM DMA shim for ALSA .
*/
# include <linux/device.h>
# include <linux/dma-mapping.h>
# include <sound/driver.h>
# include <sound/core.h>
# include <sound/pcm.h>
# include "devdma.h"
2005-11-17 17:10:16 +03:00
void devdma_hw_free ( struct device * dev , struct snd_pcm_substream * substream )
2005-05-12 12:25:58 +04:00
{
2005-11-17 17:10:16 +03:00
struct snd_pcm_runtime * runtime = substream - > runtime ;
2005-05-12 12:25:58 +04:00
struct snd_dma_buffer * buf = runtime - > dma_buffer_p ;
if ( runtime - > dma_area = = NULL )
return ;
if ( buf ! = & substream - > dma_buffer ) {
dma_free_coherent ( buf - > dev . dev , buf - > bytes , buf - > area , buf - > addr ) ;
kfree ( runtime - > dma_buffer_p ) ;
}
snd_pcm_set_runtime_buffer ( substream , NULL ) ;
}
2005-11-17 17:10:16 +03:00
int devdma_hw_alloc ( struct device * dev , struct snd_pcm_substream * substream , size_t size )
2005-05-12 12:25:58 +04:00
{
2005-11-17 17:10:16 +03:00
struct snd_pcm_runtime * runtime = substream - > runtime ;
2005-05-12 12:25:58 +04:00
struct snd_dma_buffer * buf = runtime - > dma_buffer_p ;
int ret = 0 ;
if ( buf ) {
if ( buf - > bytes > = size )
goto out ;
devdma_hw_free ( dev , substream ) ;
}
if ( substream - > dma_buffer . area ! = NULL & & substream - > dma_buffer . bytes > = size ) {
buf = & substream - > dma_buffer ;
} else {
buf = kmalloc ( sizeof ( struct snd_dma_buffer ) , GFP_KERNEL ) ;
if ( ! buf )
goto nomem ;
buf - > dev . type = SNDRV_DMA_TYPE_DEV ;
buf - > dev . dev = dev ;
buf - > area = dma_alloc_coherent ( dev , size , & buf - > addr , GFP_KERNEL ) ;
buf - > bytes = size ;
buf - > private_data = NULL ;
if ( ! buf - > area )
goto free ;
}
snd_pcm_set_runtime_buffer ( substream , buf ) ;
ret = 1 ;
out :
runtime - > dma_bytes = size ;
return ret ;
free :
kfree ( buf ) ;
nomem :
return - ENOMEM ;
}
2005-11-17 17:10:16 +03:00
int devdma_mmap ( struct device * dev , struct snd_pcm_substream * substream , struct vm_area_struct * vma )
2005-05-12 12:25:58 +04:00
{
2005-11-17 17:10:16 +03:00
struct snd_pcm_runtime * runtime = substream - > runtime ;
2005-05-12 12:25:58 +04:00
return dma_mmap_coherent ( dev , vma , runtime - > dma_area , runtime - > dma_addr , runtime - > dma_bytes ) ;
}