2005-04-17 02:20:36 +04:00
/*
* Routines for Gravis UltraSound soundcards - Synthesizer
2007-10-15 11:50:19 +04:00
* Copyright ( c ) by Jaroslav Kysela < perex @ perex . cz >
2005-04-17 02:20:36 +04:00
*
*
* 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 .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
# include <linux/time.h>
# include <sound/core.h>
# include <sound/gus.h>
/*
*
*/
2005-11-17 16:36:44 +03:00
int snd_gus_iwffff_put_sample ( void * private_data , struct iwffff_wave * wave ,
2005-04-17 02:20:36 +04:00
char __user * data , long len , int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
struct snd_gf1_mem_block * block ;
2005-04-17 02:20:36 +04:00
int err ;
if ( wave - > format & IWFFFF_WAVE_ROM )
return 0 ; /* it's probably ok - verify the address? */
if ( wave - > format & IWFFFF_WAVE_STEREO )
return - EINVAL ; /* not supported */
block = snd_gf1_mem_alloc ( & gus - > gf1 . mem_alloc ,
SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF ,
NULL , wave - > size ,
wave - > format & IWFFFF_WAVE_16BIT , 1 ,
wave - > share_id ) ;
if ( block = = NULL )
return - ENOMEM ;
err = snd_gus_dram_write ( gus , data ,
block - > ptr , wave - > size ) ;
if ( err < 0 ) {
snd_gf1_mem_lock ( & gus - > gf1 . mem_alloc , 0 ) ;
snd_gf1_mem_xfree ( & gus - > gf1 . mem_alloc , block ) ;
snd_gf1_mem_lock ( & gus - > gf1 . mem_alloc , 1 ) ;
return err ;
}
wave - > address . memory = block - > ptr ;
return 0 ;
}
2005-11-17 16:36:44 +03:00
int snd_gus_iwffff_get_sample ( void * private_data , struct iwffff_wave * wave ,
2005-04-17 02:20:36 +04:00
char __user * data , long len , int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
2005-04-17 02:20:36 +04:00
return snd_gus_dram_read ( gus , data , wave - > address . memory , wave - > size ,
wave - > format & IWFFFF_WAVE_ROM ? 1 : 0 ) ;
}
2005-11-17 16:36:44 +03:00
int snd_gus_iwffff_remove_sample ( void * private_data , struct iwffff_wave * wave ,
2005-04-17 02:20:36 +04:00
int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
2005-04-17 02:20:36 +04:00
if ( wave - > format & IWFFFF_WAVE_ROM )
return 0 ; /* it's probably ok - verify the address? */
return snd_gf1_mem_free ( & gus - > gf1 . mem_alloc , wave - > address . memory ) ;
}
/*
*
*/
2005-11-17 16:36:44 +03:00
int snd_gus_gf1_put_sample ( void * private_data , struct gf1_wave * wave ,
2005-04-17 02:20:36 +04:00
char __user * data , long len , int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
struct snd_gf1_mem_block * block ;
2005-04-17 02:20:36 +04:00
int err ;
if ( wave - > format & GF1_WAVE_STEREO )
return - EINVAL ; /* not supported */
block = snd_gf1_mem_alloc ( & gus - > gf1 . mem_alloc ,
SNDRV_GF1_MEM_OWNER_WAVE_GF1 ,
NULL , wave - > size ,
wave - > format & GF1_WAVE_16BIT , 1 ,
wave - > share_id ) ;
if ( block = = NULL )
return - ENOMEM ;
err = snd_gus_dram_write ( gus , data ,
block - > ptr , wave - > size ) ;
if ( err < 0 ) {
snd_gf1_mem_lock ( & gus - > gf1 . mem_alloc , 0 ) ;
snd_gf1_mem_xfree ( & gus - > gf1 . mem_alloc , block ) ;
snd_gf1_mem_lock ( & gus - > gf1 . mem_alloc , 1 ) ;
return err ;
}
wave - > address . memory = block - > ptr ;
return 0 ;
}
2005-11-17 16:36:44 +03:00
int snd_gus_gf1_get_sample ( void * private_data , struct gf1_wave * wave ,
2005-04-17 02:20:36 +04:00
char __user * data , long len , int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
2005-04-17 02:20:36 +04:00
return snd_gus_dram_read ( gus , data , wave - > address . memory , wave - > size , 0 ) ;
}
2005-11-17 16:36:44 +03:00
int snd_gus_gf1_remove_sample ( void * private_data , struct gf1_wave * wave ,
2005-04-17 02:20:36 +04:00
int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
2005-04-17 02:20:36 +04:00
return snd_gf1_mem_free ( & gus - > gf1 . mem_alloc , wave - > address . memory ) ;
}
/*
*
*/
2005-11-17 16:36:44 +03:00
int snd_gus_simple_put_sample ( void * private_data , struct simple_instrument * instr ,
2005-04-17 02:20:36 +04:00
char __user * data , long len , int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
struct snd_gf1_mem_block * block ;
2005-04-17 02:20:36 +04:00
int err ;
if ( instr - > format & SIMPLE_WAVE_STEREO )
return - EINVAL ; /* not supported */
block = snd_gf1_mem_alloc ( & gus - > gf1 . mem_alloc ,
SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE ,
NULL , instr - > size ,
instr - > format & SIMPLE_WAVE_16BIT , 1 ,
instr - > share_id ) ;
if ( block = = NULL )
return - ENOMEM ;
err = snd_gus_dram_write ( gus , data , block - > ptr , instr - > size ) ;
if ( err < 0 ) {
snd_gf1_mem_lock ( & gus - > gf1 . mem_alloc , 0 ) ;
snd_gf1_mem_xfree ( & gus - > gf1 . mem_alloc , block ) ;
snd_gf1_mem_lock ( & gus - > gf1 . mem_alloc , 1 ) ;
return err ;
}
instr - > address . memory = block - > ptr ;
return 0 ;
}
2005-11-17 16:36:44 +03:00
int snd_gus_simple_get_sample ( void * private_data , struct simple_instrument * instr ,
2005-04-17 02:20:36 +04:00
char __user * data , long len , int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
2005-04-17 02:20:36 +04:00
return snd_gus_dram_read ( gus , data , instr - > address . memory , instr - > size , 0 ) ;
}
2005-11-17 16:36:44 +03:00
int snd_gus_simple_remove_sample ( void * private_data , struct simple_instrument * instr ,
2005-04-17 02:20:36 +04:00
int atomic )
{
2005-11-17 16:36:44 +03:00
struct snd_gus_card * gus = private_data ;
2005-04-17 02:20:36 +04:00
return snd_gf1_mem_free ( & gus - > gf1 . mem_alloc , instr - > address . memory ) ;
}