linux/sound/isa/gus/gus_instr.c
<<
>>
Prefs
   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