This source file includes following definitions.
- audio_open
- audio_release
- translate_bytes
- translate_bytes
- audio_write
- audio_read
- audio_ioctl
- audio_init
- audio_read
- audio_write
- audio_open
- audio_release
- audio_ioctl
- audio_lseek
- audio_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include "sound_config.h"
31
32 #ifdef CONFIGURE_SOUNDCARD
33 #ifndef EXCLUDE_AUDIO
34
35 #include "ulaw.h"
36
37 #define ON 1
38 #define OFF 0
39
40 static int wr_buff_no[MAX_DSP_DEV];
41
42 static int wr_buff_size[MAX_DSP_DEV], wr_buff_ptr[MAX_DSP_DEV];
43
44 static int audio_mode[MAX_DSP_DEV];
45 #define AM_NONE 0
46 #define AM_WRITE 1
47 #define AM_READ 2
48
49 static char *wr_dma_buf[MAX_DSP_DEV];
50
51 int
52 audio_open (int dev, struct fileinfo *file)
53 {
54 int ret;
55 int bits;
56 int dev_type = dev & 0x0f;
57 int mode = file->mode & O_ACCMODE;
58
59 dev = dev >> 4;
60
61 if (dev_type == SND_DEV_DSP16)
62 bits = 16;
63 else
64 bits = 8;
65
66 if ((ret = DMAbuf_open (dev, mode)) < 0)
67 return ret;
68
69 if (DMAbuf_ioctl (dev, SNDCTL_DSP_SAMPLESIZE, bits, 1) != bits)
70 {
71 audio_release (dev, file);
72 return RET_ERROR (ENXIO);
73 }
74
75 wr_buff_no[dev] = -1;
76 audio_mode[dev] = AM_NONE;
77
78 return ret;
79 }
80
81 void
82 audio_release (int dev, struct fileinfo *file)
83 {
84 int mode;
85
86 dev = dev >> 4;
87 mode = file->mode & O_ACCMODE;
88
89 if (wr_buff_no[dev] >= 0)
90 {
91 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
92
93 wr_buff_no[dev] = -1;
94 }
95
96 DMAbuf_release (dev, mode);
97 }
98
99 #ifdef NO_INLINE_ASM
100 static void
101 translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
102 {
103 unsigned long i;
104
105 for (i = 0; i < n; ++i)
106 buff[i] = table[buff[i]];
107 }
108
109 #else
110 extern inline void
111 translate_bytes (const void *table, void *buff, unsigned long n)
112 {
113 __asm__ ("cld\n"
114 "1:\tlodsb\n\t"
115 "xlatb\n\t"
116 "stosb\n\t"
117 "loop 1b\n\t":
118 :"b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
119 :"bx", "cx", "di", "si", "ax");
120 }
121
122 #endif
123
124 int
125 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
126 {
127 int c, p, l;
128 int err;
129 int dev_type = dev & 0x0f;
130
131 dev = dev >> 4;
132
133 p = 0;
134 c = count;
135
136 if (audio_mode[dev] == AM_READ)
137 {
138 wr_buff_no[dev] = -1;
139 }
140
141 audio_mode[dev] = AM_WRITE;
142
143 if (!count)
144 {
145 if (wr_buff_no[dev] >= 0)
146 {
147 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
148
149 wr_buff_no[dev] = -1;
150 }
151 return 0;
152 }
153
154 while (c)
155 {
156 if (wr_buff_no[dev] < 0)
157 {
158 if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev], &wr_buff_size[dev])) < 0)
159 return wr_buff_no[dev];
160 wr_buff_ptr[dev] = 0;
161 }
162
163 l = c;
164 if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
165 l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
166
167 if (!dsp_devs[dev]->copy_from_user)
168 {
169 COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
170 }
171 else
172 dsp_devs[dev]->copy_from_user (dev,
173 wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
174
175
176
177
178 if (dev_type == SND_DEV_AUDIO)
179 {
180 #ifdef linux
181
182 __asm__ ("sti");
183 #endif
184 translate_bytes (ulaw_dsp, &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
185 }
186
187 c -= l;
188 p += l;
189 wr_buff_ptr[dev] += l;
190
191 if (wr_buff_ptr[dev] >= wr_buff_size[dev])
192 {
193 if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
194 return err;
195
196 wr_buff_no[dev] = -1;
197 }
198
199 }
200
201 return count;
202 }
203
204 int
205 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
206 {
207 int c, p, l;
208 char *dmabuf;
209 int buff_no;
210 int dev_type = dev & 0x0f;
211
212 dev = dev >> 4;
213 p = 0;
214 c = count;
215
216 if (audio_mode[dev] == AM_WRITE)
217 {
218 if (wr_buff_no[dev] >= 0)
219 {
220 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
221
222 wr_buff_no[dev] = -1;
223 }
224 }
225
226 audio_mode[dev] = AM_READ;
227
228 while (c)
229 {
230 if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l)) < 0)
231 return buff_no;
232
233 if (l > c)
234 l = c;
235
236
237
238 if (dev_type == SND_DEV_AUDIO)
239 {
240 #ifdef linux
241
242 __asm__ ("sti");
243 #endif
244
245 translate_bytes (dsp_ulaw, dmabuf, l);
246 }
247
248 COPY_TO_USER (buf, p, dmabuf, l);
249
250 DMAbuf_rmchars (dev, buff_no, l);
251
252 p += l;
253 c -= l;
254 }
255
256 return count - c;
257 }
258
259 int
260 audio_ioctl (int dev, struct fileinfo *file,
261 unsigned int cmd, unsigned int arg)
262 {
263 int dev_type = dev & 0x0f;
264 dev = dev >> 4;
265
266 switch (cmd)
267 {
268 case SNDCTL_DSP_SYNC:
269 if (wr_buff_no[dev] >= 0)
270 {
271 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
272
273 wr_buff_no[dev] = -1;
274 }
275 return DMAbuf_ioctl (dev, cmd, arg, 0);
276 break;
277
278 case SNDCTL_DSP_POST:
279 if (wr_buff_no[dev] >= 0)
280 {
281 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
282
283 wr_buff_no[dev] = -1;
284 }
285 return 0;
286 break;
287
288 case SNDCTL_DSP_RESET:
289 wr_buff_no[dev] = -1;
290 return DMAbuf_ioctl (dev, cmd, arg, 0);
291 break;
292
293 default:
294 if (dev_type == SND_DEV_AUDIO)
295 return RET_ERROR (EIO);
296
297 return DMAbuf_ioctl (dev, cmd, arg, 0);
298 }
299 }
300
301 long
302 audio_init (long mem_start)
303 {
304 return mem_start;
305 }
306
307 #else
308
309
310 int
311 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
312 {
313 return RET_ERROR (EIO);
314 }
315
316 int
317 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
318 {
319 return RET_ERROR (EIO);
320 }
321
322 int
323 audio_open (int dev, struct fileinfo *file)
324 {
325 return RET_ERROR (ENXIO);
326 }
327
328 void
329 audio_release (int dev, struct fileinfo *file)
330 {
331 };
332 int
333 audio_ioctl (int dev, struct fileinfo *file,
334 unsigned int cmd, unsigned int arg)
335 {
336 return RET_ERROR (EIO);
337 }
338
339 int
340 audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
341 {
342 return RET_ERROR (EIO);
343 }
344
345 long
346 audio_init (long mem_start)
347 {
348 return mem_start;
349 }
350
351 #endif
352
353 #endif