Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/isa/gus/gus_instr.c
10817 views
1
/*
2
* Routines for Gravis UltraSound soundcards - Synthesizer
3
* Copyright (c) by Jaroslav Kysela <[email protected]>
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
30
int 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
60
int 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
69
int 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
83
int 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
111
int 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
119
int 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
131
int 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
158
int 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
166
int 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
174