1/* 2 * Routines for Gravis UltraSound soundcards - Synthesizer 3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 4 * 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 as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22#include <linux/time.h> 23#include <sound/core.h> 24#include <sound/gus.h> 25 26/* 27 * 28 */ 29 30int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave, 31 char __user *data, long len, int atomic) 32{ 33 struct snd_gus_card *gus = private_data; 34 struct snd_gf1_mem_block *block; 35 int err; 36 37 if (wave->format & IWFFFF_WAVE_ROM) 38 return 0; /* it's probably ok - verify the address? */ 39 if (wave->format & IWFFFF_WAVE_STEREO) 40 return -EINVAL; /* not supported */ 41 block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc, 42 SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF, 43 NULL, wave->size, 44 wave->format & IWFFFF_WAVE_16BIT, 1, 45 wave->share_id); 46 if (block == NULL) 47 return -ENOMEM; 48 err = snd_gus_dram_write(gus, data, 49 block->ptr, wave->size); 50 if (err < 0) { 51 snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0); 52 snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block); 53 snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1); 54 return err; 55 } 56 wave->address.memory = block->ptr; 57 return 0; 58} 59 60int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave, 61 char __user *data, long len, int atomic) 62{ 63 struct snd_gus_card *gus = private_data; 64 65 return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 66 wave->format & IWFFFF_WAVE_ROM ? 1 : 0); 67} 68 69int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave, 70 int atomic) 71{ 72 struct snd_gus_card *gus = private_data; 73 74 if (wave->format & IWFFFF_WAVE_ROM) 75 return 0; /* it's probably ok - verify the address? */ 76 return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory); 77} 78 79/* 80 * 81 */ 82 83int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave, 84 char __user *data, long len, int atomic) 85{ 86 struct snd_gus_card *gus = private_data; 87 struct snd_gf1_mem_block *block; 88 int err; 89 90 if (wave->format & GF1_WAVE_STEREO) 91 return -EINVAL; /* not supported */ 92 block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc, 93 SNDRV_GF1_MEM_OWNER_WAVE_GF1, 94 NULL, wave->size, 95 wave->format & GF1_WAVE_16BIT, 1, 96 wave->share_id); 97 if (block == NULL) 98 return -ENOMEM; 99 err = snd_gus_dram_write(gus, data, 100 block->ptr, wave->size); 101 if (err < 0) { 102 snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0); 103 snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block); 104 snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1); 105 return err; 106 } 107 wave->address.memory = block->ptr; 108 return 0; 109} 110 111int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave, 112 char __user *data, long len, int atomic) 113{ 114 struct snd_gus_card *gus = private_data; 115 116 return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 0); 117} 118 119int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave, 120 int atomic) 121{ 122 struct snd_gus_card *gus = private_data; 123 124 return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory); 125} 126 127/* 128 * 129 */ 130 131int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr, 132 char __user *data, long len, int atomic) 133{ 134 struct snd_gus_card *gus = private_data; 135 struct snd_gf1_mem_block *block; 136 int err; 137 138 if (instr->format & SIMPLE_WAVE_STEREO) 139 return -EINVAL; /* not supported */ 140 block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc, 141 SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE, 142 NULL, instr->size, 143 instr->format & SIMPLE_WAVE_16BIT, 1, 144 instr->share_id); 145 if (block == NULL) 146 return -ENOMEM; 147 err = snd_gus_dram_write(gus, data, block->ptr, instr->size); 148 if (err < 0) { 149 snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0); 150 snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block); 151 snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1); 152 return err; 153 } 154 instr->address.memory = block->ptr; 155 return 0; 156} 157 158int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr, 159 char __user *data, long len, int atomic) 160{ 161 struct snd_gus_card *gus = private_data; 162 163 return snd_gus_dram_read(gus, data, instr->address.memory, instr->size, 0); 164} 165 166int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr, 167 int atomic) 168{ 169 struct snd_gus_card *gus = private_data; 170 171 return snd_gf1_mem_free(&gus->gf1.mem_alloc, instr->address.memory); 172} 173