2007-02-14 13:20:03 +01:00
/*
2010-11-22 15:35:57 +09:00
* dma . c - - ALSA Soc Audio Layer
2007-02-14 13:20:03 +01:00
*
* ( c ) 2006 Wolfson Microelectronics PLC .
* Graeme Gregory graeme . gregory @ wolfsonmicro . com or linux @ wolfsonmicro . com
*
2009-02-28 17:09:57 +00:00
* Copyright 2004 - 2005 Simtec Electronics
2007-02-14 13:20:03 +01:00
* http : //armlinux.simtec.co.uk/
* Ben Dooks < ben @ simtec . co . uk >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*/
# include <linux/module.h>
# include <linux/init.h>
2008-04-30 17:19:32 +02:00
# include <linux/io.h>
2007-02-14 13:20:03 +01:00
# include <linux/platform_device.h>
# include <linux/slab.h>
# include <linux/dma-mapping.h>
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/pcm_params.h>
# include <sound/soc.h>
# include <asm/dma.h>
2008-08-05 16:14:15 +01:00
# include <mach/hardware.h>
# include <mach/dma.h>
2007-02-14 13:20:03 +01:00
2010-11-22 15:35:57 +09:00
# include "dma.h"
2007-02-14 13:20:03 +01:00
2011-01-07 13:51:26 +09:00
# define ST_RUNNING (1<<0)
# define ST_OPENED (1<<1)
2010-11-22 15:36:50 +09:00
static const struct snd_pcm_hardware dma_hardware = {
2007-02-14 13:20:03 +01:00
. info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
2008-01-10 14:44:24 +01:00
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME ,
2007-02-14 13:20:03 +01:00
. formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_U16_LE |
SNDRV_PCM_FMTBIT_U8 |
SNDRV_PCM_FMTBIT_S8 ,
. channels_min = 2 ,
. channels_max = 2 ,
. buffer_bytes_max = 128 * 1024 ,
. period_bytes_min = PAGE_SIZE ,
. period_bytes_max = PAGE_SIZE * 2 ,
. periods_min = 2 ,
. periods_max = 128 ,
. fifo_size = 32 ,
} ;
2010-11-22 15:36:50 +09:00
struct runtime_data {
2007-02-14 13:20:03 +01:00
spinlock_t lock ;
int state ;
unsigned int dma_loaded ;
unsigned int dma_limit ;
unsigned int dma_period ;
dma_addr_t dma_start ;
dma_addr_t dma_pos ;
dma_addr_t dma_end ;
2009-11-17 16:53:23 +09:00
struct s3c_dma_params * params ;
2007-02-14 13:20:03 +01:00
} ;
2010-11-22 15:36:50 +09:00
/* dma_enqueue
2007-02-14 13:20:03 +01:00
*
* place a dma buffer onto the queue for the dma system
* to handle .
*/
2010-11-22 15:36:50 +09:00
static void dma_enqueue ( struct snd_pcm_substream * substream )
2007-02-14 13:20:03 +01:00
{
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd = substream - > runtime - > private_data ;
2007-02-14 13:20:03 +01:00
dma_addr_t pos = prtd - > dma_pos ;
2009-09-22 16:48:56 +01:00
unsigned int limit ;
2007-02-14 13:20:03 +01:00
int ret ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
2009-11-17 16:53:31 +09:00
if ( s3c_dma_has_circular ( ) )
2009-09-22 16:48:56 +01:00
limit = ( prtd - > dma_end - prtd - > dma_start ) / prtd - > dma_period ;
2009-11-17 16:53:31 +09:00
else
2009-09-22 16:48:56 +01:00
limit = prtd - > dma_limit ;
2009-11-17 16:53:31 +09:00
pr_debug ( " %s: loaded %d, limit %d \n " ,
__func__ , prtd - > dma_loaded , limit ) ;
2009-09-22 16:48:56 +01:00
while ( prtd - > dma_loaded < limit ) {
2007-02-14 13:20:03 +01:00
unsigned long len = prtd - > dma_period ;
2009-03-06 18:04:34 +00:00
pr_debug ( " dma_loaded: %d \n " , prtd - > dma_loaded ) ;
2007-02-14 13:20:03 +01:00
if ( ( pos + len ) > prtd - > dma_end ) {
len = prtd - > dma_end - pos ;
2010-09-11 22:10:59 -07:00
pr_debug ( " %s: corrected dma len %ld \n " , __func__ , len ) ;
2007-02-14 13:20:03 +01:00
}
2008-04-30 17:19:32 +02:00
ret = s3c2410_dma_enqueue ( prtd - > params - > channel ,
2007-04-17 12:35:18 +02:00
substream , pos , len ) ;
2007-02-14 13:20:03 +01:00
if ( ret = = 0 ) {
prtd - > dma_loaded + + ;
pos + = prtd - > dma_period ;
if ( pos > = prtd - > dma_end )
pos = prtd - > dma_start ;
} else
break ;
}
prtd - > dma_pos = pos ;
}
2010-11-22 15:36:50 +09:00
static void audio_buffdone ( struct s3c2410_dma_chan * channel ,
2007-04-17 12:35:18 +02:00
void * dev_id , int size ,
enum s3c2410_dma_buffresult result )
2007-02-14 13:20:03 +01:00
{
struct snd_pcm_substream * substream = dev_id ;
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd ;
2007-02-14 13:20:03 +01:00
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
if ( result = = S3C2410_RES_ABORT | | result = = S3C2410_RES_ERR )
return ;
2007-04-17 12:35:18 +02:00
prtd = substream - > runtime - > private_data ;
2008-04-30 17:19:32 +02:00
2007-02-14 13:20:03 +01:00
if ( substream )
snd_pcm_period_elapsed ( substream ) ;
spin_lock ( & prtd - > lock ) ;
2009-09-22 16:48:56 +01:00
if ( prtd - > state & ST_RUNNING & & ! s3c_dma_has_circular ( ) ) {
2007-02-14 13:20:03 +01:00
prtd - > dma_loaded - - ;
2010-11-22 15:36:50 +09:00
dma_enqueue ( substream ) ;
2007-02-14 13:20:03 +01:00
}
spin_unlock ( & prtd - > lock ) ;
}
2010-11-22 15:36:50 +09:00
static int dma_hw_params ( struct snd_pcm_substream * substream ,
2007-02-14 13:20:03 +01:00
struct snd_pcm_hw_params * params )
{
struct snd_pcm_runtime * runtime = substream - > runtime ;
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd = runtime - > private_data ;
2007-02-14 13:20:03 +01:00
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
unsigned long totbytes = params_buffer_bytes ( params ) ;
2010-03-22 10:11:15 +01:00
struct s3c_dma_params * dma =
2010-03-17 20:15:21 +00:00
snd_soc_dai_get_dma_data ( rtd - > cpu_dai , substream ) ;
2008-04-30 17:19:32 +02:00
int ret = 0 ;
2007-02-14 13:20:03 +01:00
2010-03-22 10:11:15 +01:00
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
/* return if this is a bufferless transfer e.g.
* codec < - - > BT codec or GSM modem - - lg FIXME */
if ( ! dma )
return 0 ;
2007-07-24 12:49:39 +02:00
/* this may get called several times by oss emulation
* with different params - HW */
if ( prtd - > params = = NULL ) {
/* prepare DMA */
prtd - > params = dma ;
2007-02-14 13:20:03 +01:00
2009-03-06 18:04:34 +00:00
pr_debug ( " params %p, client %p, channel %d \n " , prtd - > params ,
2007-07-24 12:49:39 +02:00
prtd - > params - > client , prtd - > params - > channel ) ;
2007-02-14 13:20:03 +01:00
2007-07-24 12:49:39 +02:00
ret = s3c2410_dma_request ( prtd - > params - > channel ,
prtd - > params - > client , NULL ) ;
2007-02-14 13:20:03 +01:00
2008-05-05 14:56:07 +02:00
if ( ret < 0 ) {
2009-03-06 18:13:43 +00:00
printk ( KERN_ERR " failed to get dma channel \n " ) ;
2007-07-24 12:49:39 +02:00
return ret ;
}
2009-09-22 16:48:56 +01:00
/* use the circular buffering if we have it available. */
if ( s3c_dma_has_circular ( ) )
s3c2410_dma_setflags ( prtd - > params - > channel ,
S3C2410_DMAF_CIRCULAR ) ;
2007-02-14 13:20:03 +01:00
}
s3c2410_dma_set_buffdone_fn ( prtd - > params - > channel ,
2010-11-22 15:36:50 +09:00
audio_buffdone ) ;
2007-02-14 13:20:03 +01:00
snd_pcm_set_runtime_buffer ( substream , & substream - > dma_buffer ) ;
runtime - > dma_bytes = totbytes ;
spin_lock_irq ( & prtd - > lock ) ;
prtd - > dma_loaded = 0 ;
prtd - > dma_limit = runtime - > hw . periods_min ;
prtd - > dma_period = params_period_bytes ( params ) ;
prtd - > dma_start = runtime - > dma_addr ;
prtd - > dma_pos = prtd - > dma_start ;
prtd - > dma_end = prtd - > dma_start + totbytes ;
spin_unlock_irq ( & prtd - > lock ) ;
return 0 ;
}
2010-11-22 15:36:50 +09:00
static int dma_hw_free ( struct snd_pcm_substream * substream )
2007-02-14 13:20:03 +01:00
{
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd = substream - > runtime - > private_data ;
2007-02-14 13:20:03 +01:00
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
/* TODO - do we need to ensure DMA flushed */
snd_pcm_set_runtime_buffer ( substream , NULL ) ;
2007-04-17 12:35:18 +02:00
if ( prtd - > params ) {
2007-02-14 13:20:03 +01:00
s3c2410_dma_free ( prtd - > params - > channel , prtd - > params - > client ) ;
prtd - > params = NULL ;
}
return 0 ;
}
2010-11-22 15:36:50 +09:00
static int dma_prepare ( struct snd_pcm_substream * substream )
2007-02-14 13:20:03 +01:00
{
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd = substream - > runtime - > private_data ;
2007-02-14 13:20:03 +01:00
int ret = 0 ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
/* return if this is a bufferless transfer e.g.
* codec < - - > BT codec or GSM modem - - lg FIXME */
if ( ! prtd - > params )
2008-04-30 17:19:32 +02:00
return 0 ;
2007-02-14 13:20:03 +01:00
2008-01-10 14:44:24 +01:00
/* channel needs configuring for mem=>device, increment memory addr,
* sync to pclk , half - word transfers to the IIS - FIFO . */
if ( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK ) {
s3c2410_dma_devconfig ( prtd - > params - > channel ,
2009-03-19 15:02:34 +00:00
S3C2410_DMASRC_MEM ,
prtd - > params - > dma_addr ) ;
2008-01-10 14:44:24 +01:00
} else {
s3c2410_dma_devconfig ( prtd - > params - > channel ,
2009-03-19 15:02:34 +00:00
S3C2410_DMASRC_HW ,
prtd - > params - > dma_addr ) ;
2008-01-10 14:44:24 +01:00
}
2009-03-19 15:02:34 +00:00
s3c2410_dma_config ( prtd - > params - > channel ,
prtd - > params - > dma_size ) ;
2007-02-14 13:20:03 +01:00
/* flush the DMA channel */
s3c2410_dma_ctrl ( prtd - > params - > channel , S3C2410_DMAOP_FLUSH ) ;
prtd - > dma_loaded = 0 ;
prtd - > dma_pos = prtd - > dma_start ;
/* enqueue dma buffers */
2010-11-22 15:36:50 +09:00
dma_enqueue ( substream ) ;
2007-02-14 13:20:03 +01:00
return ret ;
}
2010-11-22 15:36:50 +09:00
static int dma_trigger ( struct snd_pcm_substream * substream , int cmd )
2007-02-14 13:20:03 +01:00
{
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd = substream - > runtime - > private_data ;
2007-02-14 13:20:03 +01:00
int ret = 0 ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
spin_lock ( & prtd - > lock ) ;
switch ( cmd ) {
case SNDRV_PCM_TRIGGER_START :
case SNDRV_PCM_TRIGGER_RESUME :
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
prtd - > state | = ST_RUNNING ;
s3c2410_dma_ctrl ( prtd - > params - > channel , S3C2410_DMAOP_START ) ;
break ;
case SNDRV_PCM_TRIGGER_STOP :
case SNDRV_PCM_TRIGGER_SUSPEND :
case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
prtd - > state & = ~ ST_RUNNING ;
s3c2410_dma_ctrl ( prtd - > params - > channel , S3C2410_DMAOP_STOP ) ;
break ;
default :
ret = - EINVAL ;
break ;
}
spin_unlock ( & prtd - > lock ) ;
return ret ;
}
2008-04-30 17:19:32 +02:00
static snd_pcm_uframes_t
2010-11-22 15:36:50 +09:00
dma_pointer ( struct snd_pcm_substream * substream )
2007-02-14 13:20:03 +01:00
{
struct snd_pcm_runtime * runtime = substream - > runtime ;
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd = runtime - > private_data ;
2007-02-14 13:20:03 +01:00
unsigned long res ;
dma_addr_t src , dst ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
spin_lock ( & prtd - > lock ) ;
s3c2410_dma_getposition ( prtd - > params - > channel , & src , & dst ) ;
if ( substream - > stream = = SNDRV_PCM_STREAM_CAPTURE )
res = dst - prtd - > dma_start ;
else
res = src - prtd - > dma_start ;
spin_unlock ( & prtd - > lock ) ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Pointer %x %x \n " , src , dst ) ;
2007-02-14 13:20:03 +01:00
/* we seem to be getting the odd error from the pcm library due
* to out - of - bounds pointers . this is maybe due to the dma engine
* not having loaded the new values for the channel before being
* callled . . . ( todo - fix )
*/
if ( res > = snd_pcm_lib_buffer_bytes ( substream ) ) {
if ( res = = snd_pcm_lib_buffer_bytes ( substream ) )
res = 0 ;
}
return bytes_to_frames ( substream - > runtime , res ) ;
}
2010-11-22 15:36:50 +09:00
static int dma_open ( struct snd_pcm_substream * substream )
2007-02-14 13:20:03 +01:00
{
struct snd_pcm_runtime * runtime = substream - > runtime ;
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd ;
2007-02-14 13:20:03 +01:00
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
2009-08-20 23:02:23 +08:00
snd_pcm_hw_constraint_integer ( runtime , SNDRV_PCM_HW_PARAM_PERIODS ) ;
2010-11-22 15:36:50 +09:00
snd_soc_set_runtime_hwparams ( substream , & dma_hardware ) ;
2007-02-14 13:20:03 +01:00
2010-11-22 15:36:50 +09:00
prtd = kzalloc ( sizeof ( struct runtime_data ) , GFP_KERNEL ) ;
2007-02-14 13:20:03 +01:00
if ( prtd = = NULL )
return - ENOMEM ;
2007-05-22 16:17:05 +02:00
spin_lock_init ( & prtd - > lock ) ;
2007-02-14 13:20:03 +01:00
runtime - > private_data = prtd ;
return 0 ;
}
2010-11-22 15:36:50 +09:00
static int dma_close ( struct snd_pcm_substream * substream )
2007-02-14 13:20:03 +01:00
{
struct snd_pcm_runtime * runtime = substream - > runtime ;
2010-11-22 15:36:50 +09:00
struct runtime_data * prtd = runtime - > private_data ;
2007-02-14 13:20:03 +01:00
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
2008-04-30 17:19:32 +02:00
if ( ! prtd )
2010-11-22 15:36:50 +09:00
pr_debug ( " dma_close called with prtd == NULL \n " ) ;
2007-02-14 13:20:03 +01:00
2008-04-30 17:19:32 +02:00
kfree ( prtd ) ;
2007-02-14 13:20:03 +01:00
return 0 ;
}
2010-11-22 15:36:50 +09:00
static int dma_mmap ( struct snd_pcm_substream * substream ,
2007-02-14 13:20:03 +01:00
struct vm_area_struct * vma )
{
struct snd_pcm_runtime * runtime = substream - > runtime ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
return dma_mmap_writecombine ( substream - > pcm - > card - > dev , vma ,
2008-04-30 17:19:32 +02:00
runtime - > dma_area ,
runtime - > dma_addr ,
runtime - > dma_bytes ) ;
2007-02-14 13:20:03 +01:00
}
2010-11-22 15:36:50 +09:00
static struct snd_pcm_ops dma_ops = {
. open = dma_open ,
. close = dma_close ,
2007-02-14 13:20:03 +01:00
. ioctl = snd_pcm_lib_ioctl ,
2010-11-22 15:36:50 +09:00
. hw_params = dma_hw_params ,
. hw_free = dma_hw_free ,
. prepare = dma_prepare ,
. trigger = dma_trigger ,
. pointer = dma_pointer ,
. mmap = dma_mmap ,
2007-02-14 13:20:03 +01:00
} ;
2010-11-22 15:36:50 +09:00
static int preallocate_dma_buffer ( struct snd_pcm * pcm , int stream )
2007-02-14 13:20:03 +01:00
{
struct snd_pcm_substream * substream = pcm - > streams [ stream ] . substream ;
struct snd_dma_buffer * buf = & substream - > dma_buffer ;
2010-11-22 15:36:50 +09:00
size_t size = dma_hardware . buffer_bytes_max ;
2007-02-14 13:20:03 +01:00
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
buf - > dev . type = SNDRV_DMA_TYPE_DEV ;
buf - > dev . dev = pcm - > card - > dev ;
buf - > private_data = NULL ;
buf - > area = dma_alloc_writecombine ( pcm - > card - > dev , size ,
& buf - > addr , GFP_KERNEL ) ;
if ( ! buf - > area )
return - ENOMEM ;
buf - > bytes = size ;
return 0 ;
}
2010-11-22 15:36:50 +09:00
static void dma_free_dma_buffers ( struct snd_pcm * pcm )
2007-02-14 13:20:03 +01:00
{
struct snd_pcm_substream * substream ;
struct snd_dma_buffer * buf ;
int stream ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
for ( stream = 0 ; stream < 2 ; stream + + ) {
substream = pcm - > streams [ stream ] . substream ;
if ( ! substream )
continue ;
buf = & substream - > dma_buffer ;
if ( ! buf - > area )
continue ;
dma_free_writecombine ( pcm - > card - > dev , buf - > bytes ,
buf - > area , buf - > addr ) ;
buf - > area = NULL ;
}
}
2010-11-22 15:36:50 +09:00
static u64 dma_mask = DMA_BIT_MASK ( 32 ) ;
2007-02-14 13:20:03 +01:00
2010-11-22 15:36:50 +09:00
static int dma_new ( struct snd_card * card ,
2008-07-07 16:08:24 +01:00
struct snd_soc_dai * dai , struct snd_pcm * pcm )
2007-02-14 13:20:03 +01:00
{
int ret = 0 ;
2009-03-06 18:04:34 +00:00
pr_debug ( " Entered %s \n " , __func__ ) ;
2007-02-14 13:20:03 +01:00
if ( ! card - > dev - > dma_mask )
2010-11-22 15:36:50 +09:00
card - > dev - > dma_mask = & dma_mask ;
2007-02-14 13:20:03 +01:00
if ( ! card - > dev - > coherent_dma_mask )
card - > dev - > coherent_dma_mask = 0xffffffff ;
2010-03-17 20:15:21 +00:00
if ( dai - > driver - > playback . channels_min ) {
2010-11-22 15:36:50 +09:00
ret = preallocate_dma_buffer ( pcm ,
2007-02-14 13:20:03 +01:00
SNDRV_PCM_STREAM_PLAYBACK ) ;
if ( ret )
goto out ;
}
2010-03-17 20:15:21 +00:00
if ( dai - > driver - > capture . channels_min ) {
2010-11-22 15:36:50 +09:00
ret = preallocate_dma_buffer ( pcm ,
2007-02-14 13:20:03 +01:00
SNDRV_PCM_STREAM_CAPTURE ) ;
if ( ret )
goto out ;
}
2010-11-22 15:35:57 +09:00
out :
2007-02-14 13:20:03 +01:00
return ret ;
}
2010-11-22 15:36:50 +09:00
static struct snd_soc_platform_driver samsung_asoc_platform = {
. ops = & dma_ops ,
. pcm_new = dma_new ,
. pcm_free = dma_free_dma_buffers ,
2007-02-14 13:20:03 +01:00
} ;
2010-11-22 15:36:50 +09:00
static int __devinit samsung_asoc_platform_probe ( struct platform_device * pdev )
2008-12-03 19:58:17 +00:00
{
2010-11-22 15:36:50 +09:00
return snd_soc_register_platform ( & pdev - > dev , & samsung_asoc_platform ) ;
2008-12-03 19:58:17 +00:00
}
2010-11-22 15:36:50 +09:00
static int __devexit samsung_asoc_platform_remove ( struct platform_device * pdev )
2008-12-03 19:58:17 +00:00
{
2010-03-17 20:15:21 +00:00
snd_soc_unregister_platform ( & pdev - > dev ) ;
return 0 ;
}
2010-11-22 15:36:50 +09:00
static struct platform_driver asoc_dma_driver = {
2010-03-17 20:15:21 +00:00
. driver = {
2010-11-22 15:35:50 +09:00
. name = " samsung-audio " ,
2010-03-17 20:15:21 +00:00
. owner = THIS_MODULE ,
} ,
2010-11-22 15:36:50 +09:00
. probe = samsung_asoc_platform_probe ,
. remove = __devexit_p ( samsung_asoc_platform_remove ) ,
2010-03-17 20:15:21 +00:00
} ;
2010-11-22 15:36:50 +09:00
static int __init samsung_asoc_init ( void )
2010-03-17 20:15:21 +00:00
{
2010-11-22 15:36:50 +09:00
return platform_driver_register ( & asoc_dma_driver ) ;
2010-03-17 20:15:21 +00:00
}
2010-11-22 15:36:50 +09:00
module_init ( samsung_asoc_init ) ;
2010-03-17 20:15:21 +00:00
2010-11-22 15:36:50 +09:00
static void __exit samsung_asoc_exit ( void )
2010-03-17 20:15:21 +00:00
{
2010-11-22 15:36:50 +09:00
platform_driver_unregister ( & asoc_dma_driver ) ;
2008-12-03 19:58:17 +00:00
}
2010-11-22 15:36:50 +09:00
module_exit ( samsung_asoc_exit ) ;
2008-12-03 19:58:17 +00:00
2007-02-14 13:20:03 +01:00
MODULE_AUTHOR ( " Ben Dooks, <ben@simtec.co.uk> " ) ;
2010-11-22 15:36:50 +09:00
MODULE_DESCRIPTION ( " Samsung ASoC DMA Driver " ) ;
2007-02-14 13:20:03 +01:00
MODULE_LICENSE ( " GPL " ) ;
2010-11-22 15:35:50 +09:00
MODULE_ALIAS ( " platform:samsung-audio " ) ;