This source file includes following definitions.
- set_format
- 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_AUDIO_DEV];
41
42
43
44
45 static int wr_buff_size[MAX_AUDIO_DEV], wr_buff_ptr[MAX_AUDIO_DEV];
46
47 static int audio_mode[MAX_AUDIO_DEV];
48
49 #define AM_NONE 0
50 #define AM_WRITE 1
51 #define AM_READ 2
52
53 static char *wr_dma_buf[MAX_AUDIO_DEV];
54 static int audio_format[MAX_AUDIO_DEV];
55 static int local_conversion[MAX_AUDIO_DEV];
56
57 static int
58 set_format (int dev, int fmt)
59 {
60 if (fmt != AFMT_QUERY)
61 {
62
63 local_conversion[dev] = 0;
64
65 if (!(audio_devs[dev]->format_mask & fmt))
66 if (fmt == AFMT_MU_LAW)
67 {
68 fmt = AFMT_U8;
69 local_conversion[dev] = AFMT_MU_LAW;
70 }
71 else
72 fmt = AFMT_U8;
73
74 audio_format[dev] = DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, fmt, 1);
75 }
76
77 if (local_conversion[dev])
78 return local_conversion[dev];
79
80 return audio_format[dev];
81 }
82
83 int
84 audio_open (int dev, struct fileinfo *file)
85 {
86 int ret;
87 int bits;
88 int dev_type = dev & 0x0f;
89 int mode = file->mode & O_ACCMODE;
90
91 dev = dev >> 4;
92
93 if (dev_type == SND_DEV_DSP16)
94 bits = 16;
95 else
96 bits = 8;
97
98 if ((ret = DMAbuf_open (dev, mode)) < 0)
99 return ret;
100
101 local_conversion[dev] = 0;
102
103 if (DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, bits, 1) != bits)
104 {
105 audio_release (dev, file);
106 return RET_ERROR (ENXIO);
107 }
108
109 if (dev_type == SND_DEV_AUDIO)
110 {
111 set_format (dev, AFMT_MU_LAW);
112 }
113 else
114 set_format (dev, bits);
115
116 wr_buff_no[dev] = -1;
117 audio_mode[dev] = AM_NONE;
118
119 return ret;
120 }
121
122 void
123 audio_release (int dev, struct fileinfo *file)
124 {
125 int mode;
126
127 dev = dev >> 4;
128 mode = file->mode & O_ACCMODE;
129
130 if (wr_buff_no[dev] >= 0)
131 {
132 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
133
134 wr_buff_no[dev] = -1;
135 }
136
137 DMAbuf_release (dev, mode);
138 }
139
140 #ifdef NO_INLINE_ASM
141 static void
142 translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
143 {
144 unsigned long i;
145
146 for (i = 0; i < n; ++i)
147 buff[i] = table[buff[i]];
148 }
149
150 #else
151 extern inline void
152 translate_bytes (const void *table, void *buff, unsigned long n)
153 {
154 __asm__ ("cld\n"
155 "1:\tlodsb\n\t"
156 "xlatb\n\t"
157 "stosb\n\t"
158 "loop 1b\n\t":
159 :"b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
160 :"bx", "cx", "di", "si", "ax");
161 }
162
163 #endif
164
165 int
166 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
167 {
168 int c, p, l;
169 int err;
170
171 dev = dev >> 4;
172
173 p = 0;
174 c = count;
175
176 if (audio_mode[dev] == AM_READ)
177
178
179 {
180 wr_buff_no[dev] = -1;
181 }
182
183 audio_mode[dev] = AM_WRITE;
184
185 if (!count)
186
187
188 {
189 if (wr_buff_no[dev] >= 0)
190 {
191 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
192
193 wr_buff_no[dev] = -1;
194 }
195 return 0;
196 }
197
198 while (c)
199 {
200
201
202 if (wr_buff_no[dev] < 0)
203
204
205 {
206 if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev], &wr_buff_size[dev])) < 0)
207 {
208 return wr_buff_no[dev];
209 }
210 wr_buff_ptr[dev] = 0;
211 }
212
213 l = c;
214 if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
215 l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
216
217 if (!audio_devs[dev]->copy_from_user)
218 {
219
220
221 COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
222 }
223 else
224 audio_devs[dev]->copy_from_user (dev,
225 wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
226
227
228
229
230
231
232 if (local_conversion[dev] == AFMT_MU_LAW)
233 {
234 #ifdef linux
235
236
237
238 __asm__ ("sti");
239 #endif
240 translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
241 }
242
243 c -= l;
244 p += l;
245 wr_buff_ptr[dev] += l;
246
247 if (wr_buff_ptr[dev] >= wr_buff_size[dev])
248 {
249 if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
250 {
251 return err;
252 }
253
254 wr_buff_no[dev] = -1;
255 }
256
257 }
258
259 return count;
260 }
261
262 int
263 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
264 {
265 int c, p, l;
266 char *dmabuf;
267 int buff_no;
268
269 dev = dev >> 4;
270 p = 0;
271 c = count;
272
273 if (audio_mode[dev] == AM_WRITE)
274 {
275 if (wr_buff_no[dev] >= 0)
276 {
277 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
278
279 wr_buff_no[dev] = -1;
280 }
281 }
282
283 audio_mode[dev] = AM_READ;
284
285 while (c)
286 {
287 if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l)) < 0)
288 return buff_no;
289
290 if (l > c)
291 l = c;
292
293
294
295
296
297 if (local_conversion[dev] == AFMT_MU_LAW)
298 {
299 #ifdef linux
300
301
302
303 __asm__ ("sti");
304 #endif
305
306 translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
307 }
308
309 COPY_TO_USER (buf, p, dmabuf, l);
310
311 DMAbuf_rmchars (dev, buff_no, l);
312
313 p += l;
314 c -= l;
315 }
316
317 return count - c;
318 }
319
320 int
321 audio_ioctl (int dev, struct fileinfo *file,
322 unsigned int cmd, unsigned int arg)
323 {
324
325 dev = dev >> 4;
326
327 switch (cmd)
328 {
329 case SNDCTL_DSP_SYNC:
330 if (wr_buff_no[dev] >= 0)
331 {
332 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
333
334 wr_buff_no[dev] = -1;
335 }
336 return DMAbuf_ioctl (dev, cmd, arg, 0);
337 break;
338
339 case SNDCTL_DSP_POST:
340 if (wr_buff_no[dev] >= 0)
341 {
342 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
343
344 wr_buff_no[dev] = -1;
345 }
346 return 0;
347 break;
348
349 case SNDCTL_DSP_RESET:
350 wr_buff_no[dev] = -1;
351 return DMAbuf_ioctl (dev, cmd, arg, 0);
352 break;
353
354 case SNDCTL_DSP_GETFMTS:
355 return IOCTL_OUT (arg, audio_devs[dev]->format_mask);
356 break;
357
358 case SNDCTL_DSP_SETFMT:
359 return IOCTL_OUT (arg, set_format (dev, IOCTL_IN (arg)));
360
361 default:
362 return DMAbuf_ioctl (dev, cmd, arg, 0);
363 break;
364 }
365 }
366
367 long
368 audio_init (long mem_start)
369 {
370
371
372
373 return mem_start;
374 }
375
376 #else
377
378
379
380
381 int
382 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
383 {
384 return RET_ERROR (EIO);
385 }
386
387 int
388 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
389 {
390 return RET_ERROR (EIO);
391 }
392
393 int
394 audio_open (int dev, struct fileinfo *file)
395 {
396 return RET_ERROR (ENXIO);
397 }
398
399 void
400 audio_release (int dev, struct fileinfo *file)
401 {
402 };
403 int
404 audio_ioctl (int dev, struct fileinfo *file,
405 unsigned int cmd, unsigned int arg)
406 {
407 return RET_ERROR (EIO);
408 }
409
410 int
411 audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
412 {
413 return RET_ERROR (EIO);
414 }
415
416 long
417 audio_init (long mem_start)
418 {
419 return mem_start;
420 }
421
422 #endif
423
424 #endif