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_select
- 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 #include "coproc.h"
37
38 #define ON 1
39 #define OFF 0
40
41 static int wr_buff_no[MAX_AUDIO_DEV];
42
43
44
45
46
47 static int wr_buff_size[MAX_AUDIO_DEV], wr_buff_ptr[MAX_AUDIO_DEV];
48
49 static int audio_mode[MAX_AUDIO_DEV];
50 static int dev_nblock[MAX_AUDIO_DEV];
51
52 #define AM_NONE 0
53 #define AM_WRITE 1
54 #define AM_READ 2
55
56 static char *wr_dma_buf[MAX_AUDIO_DEV];
57 static int audio_format[MAX_AUDIO_DEV];
58 static int local_conversion[MAX_AUDIO_DEV];
59
60 static int
61 set_format (int dev, int fmt)
62 {
63 if (fmt != AFMT_QUERY)
64 {
65
66 local_conversion[dev] = 0;
67
68 if (!(audio_devs[dev]->format_mask & fmt))
69 if (fmt == AFMT_MU_LAW)
70 {
71 fmt = AFMT_U8;
72 local_conversion[dev] = AFMT_MU_LAW;
73 }
74 else
75 fmt = AFMT_U8;
76
77 audio_format[dev] = DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, fmt, 1);
78 }
79
80 if (local_conversion[dev])
81 return local_conversion[dev];
82
83 return audio_format[dev];
84 }
85
86 int
87 audio_open (int dev, struct fileinfo *file)
88 {
89 int ret;
90 int bits;
91 int dev_type = dev & 0x0f;
92 int mode = file->mode & O_ACCMODE;
93
94 dev = dev >> 4;
95
96 if (dev_type == SND_DEV_DSP16)
97 bits = 16;
98 else
99 bits = 8;
100
101 if ((ret = DMAbuf_open (dev, mode)) < 0)
102 return ret;
103
104 if (audio_devs[dev]->coproc)
105 if ((ret = audio_devs[dev]->coproc->
106 open (audio_devs[dev]->coproc->devc, COPR_PCM)) < 0)
107 {
108 audio_release (dev, file);
109 printk ("Sound: Can't access coprocessor device\n");
110
111 return ret;
112 }
113
114 local_conversion[dev] = 0;
115
116 if (DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, bits, 1) != bits)
117 {
118 audio_release (dev, file);
119 return RET_ERROR (ENXIO);
120 }
121
122 if (dev_type == SND_DEV_AUDIO)
123 {
124 set_format (dev, AFMT_MU_LAW);
125 }
126 else
127 set_format (dev, bits);
128
129 wr_buff_no[dev] = -1;
130 audio_mode[dev] = AM_NONE;
131 wr_buff_size[dev] = wr_buff_ptr[dev] = 0;
132 dev_nblock[dev] = 0;
133
134 return ret;
135 }
136
137 void
138 audio_release (int dev, struct fileinfo *file)
139 {
140 int mode;
141
142 dev = dev >> 4;
143 mode = file->mode & O_ACCMODE;
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
152 if (audio_devs[dev]->coproc)
153 audio_devs[dev]->coproc->close (audio_devs[dev]->coproc->devc, COPR_PCM);
154 DMAbuf_release (dev, mode);
155 }
156
157 #ifdef NO_INLINE_ASM
158 static void
159 translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
160 {
161 unsigned long i;
162
163 for (i = 0; i < n; ++i)
164 buff[i] = table[buff[i]];
165 }
166
167 #else
168 extern inline void
169 translate_bytes (const void *table, void *buff, unsigned long n)
170 {
171 __asm__ ("cld\n"
172 "1:\tlodsb\n\t"
173 "xlatb\n\t"
174 "stosb\n\t"
175 "loop 1b\n\t":
176 : "b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
177 : "bx", "cx", "di", "si", "ax");
178 }
179
180 #endif
181
182 int
183 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
184 {
185 int c, p, l;
186 int err;
187
188 dev = dev >> 4;
189
190 p = 0;
191 c = count;
192
193 if (audio_mode[dev] == AM_READ)
194
195
196 {
197 wr_buff_no[dev] = -1;
198 }
199
200 audio_mode[dev] = AM_WRITE;
201
202 if (!count)
203
204
205 {
206 if (wr_buff_no[dev] >= 0)
207 {
208 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
209
210 wr_buff_no[dev] = -1;
211 }
212 return 0;
213 }
214
215 while (c)
216 {
217
218
219 if (wr_buff_no[dev] < 0)
220
221
222 {
223 if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev],
224 &wr_buff_size[dev],
225 dev_nblock[dev])) < 0)
226 {
227
228 if (dev_nblock[dev] && wr_buff_no[dev] == RET_ERROR (EAGAIN))
229 return p;
230 return wr_buff_no[dev];
231 }
232 wr_buff_ptr[dev] = 0;
233 }
234
235 l = c;
236 if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
237 l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
238
239 if (!audio_devs[dev]->copy_from_user)
240 {
241
242
243 COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
244 }
245 else
246 audio_devs[dev]->copy_from_user (dev,
247 wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
248
249
250
251
252
253
254 if (local_conversion[dev] == AFMT_MU_LAW)
255 {
256 #ifdef linux
257
258
259
260 __asm__ ("sti");
261 #endif
262 translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
263 }
264
265 c -= l;
266 p += l;
267 wr_buff_ptr[dev] += l;
268
269 if (wr_buff_ptr[dev] >= wr_buff_size[dev])
270 {
271 if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
272 {
273 return err;
274 }
275
276 wr_buff_no[dev] = -1;
277 }
278
279 }
280
281 return count;
282 }
283
284 int
285 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
286 {
287 int c, p, l;
288 char *dmabuf;
289 int buff_no;
290
291 dev = dev >> 4;
292 p = 0;
293 c = count;
294
295 if (audio_mode[dev] == AM_WRITE)
296 {
297 if (wr_buff_no[dev] >= 0)
298 {
299 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
300
301 wr_buff_no[dev] = -1;
302 }
303 }
304
305 audio_mode[dev] = AM_READ;
306
307 while (c)
308 {
309 if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l,
310 dev_nblock[dev])) < 0)
311 {
312
313
314 if (dev_nblock[dev] && buff_no == RET_ERROR (EAGAIN))
315 return p;
316
317 return buff_no;
318 }
319
320 if (l > c)
321 l = c;
322
323
324
325
326
327 if (local_conversion[dev] == AFMT_MU_LAW)
328 {
329 #ifdef linux
330
331
332
333 __asm__ ("sti");
334 #endif
335
336 translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
337 }
338
339 COPY_TO_USER (buf, p, dmabuf, l);
340
341 DMAbuf_rmchars (dev, buff_no, l);
342
343 p += l;
344 c -= l;
345 }
346
347 return count - c;
348 }
349
350 int
351 audio_ioctl (int dev, struct fileinfo *file,
352 unsigned int cmd, unsigned int arg)
353 {
354
355 dev = dev >> 4;
356
357 if (((cmd >> 8) & 0xff) == 'C')
358 {
359 if (audio_devs[dev]->coproc)
360 return audio_devs[dev]->coproc->ioctl (audio_devs[dev]->coproc->devc, cmd, arg, 0);
361 else
362 printk ("/dev/dsp%d: No coprocessor for this device\n", dev);
363
364 return RET_ERROR (EREMOTEIO);
365 }
366 else
367 switch (cmd)
368 {
369 case SNDCTL_DSP_SYNC:
370 if (wr_buff_no[dev] >= 0)
371 {
372 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
373
374 wr_buff_no[dev] = -1;
375 }
376 return DMAbuf_ioctl (dev, cmd, arg, 0);
377 break;
378
379 case SNDCTL_DSP_POST:
380 if (wr_buff_no[dev] >= 0)
381 {
382 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
383
384 wr_buff_no[dev] = -1;
385 }
386 return 0;
387 break;
388
389 case SNDCTL_DSP_RESET:
390 wr_buff_no[dev] = -1;
391 return DMAbuf_ioctl (dev, cmd, arg, 0);
392 break;
393
394 case SNDCTL_DSP_GETFMTS:
395 return IOCTL_OUT (arg, audio_devs[dev]->format_mask);
396 break;
397
398 case SNDCTL_DSP_SETFMT:
399 return IOCTL_OUT (arg, set_format (dev, IOCTL_IN (arg)));
400
401 case SNDCTL_DSP_GETISPACE:
402 if (audio_mode[dev] == AM_WRITE)
403 return RET_ERROR (EBUSY);
404
405 {
406 audio_buf_info info;
407
408 int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
409
410 if (err < 0)
411 return err;
412
413 if (wr_buff_no[dev] != -1)
414 info.bytes += wr_buff_ptr[dev];
415
416 IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
417 return 0;
418 }
419
420 case SNDCTL_DSP_GETOSPACE:
421 if (audio_mode[dev] == AM_READ)
422 return RET_ERROR (EBUSY);
423
424 {
425 audio_buf_info info;
426
427 int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
428
429 if (err < 0)
430 return err;
431
432 if (wr_buff_no[dev] != -1)
433 info.bytes += wr_buff_size[dev] - wr_buff_ptr[dev];
434
435 IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
436 return 0;
437 }
438
439 case SNDCTL_DSP_NONBLOCK:
440 dev_nblock[dev] = 1;
441 return 0;
442 break;
443
444 default:
445 return DMAbuf_ioctl (dev, cmd, arg, 0);
446 }
447 }
448
449 long
450 audio_init (long mem_start)
451 {
452
453
454
455 return mem_start;
456 }
457
458 #ifdef ALLOW_SELECT
459 int
460 audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
461 {
462 int l;
463 char *dmabuf;
464
465 dev = dev >> 4;
466
467 switch (sel_type)
468 {
469 case SEL_IN:
470 if (audio_mode[dev] != AM_READ)
471 return 0;
472
473 if (DMAbuf_getrdbuffer (dev, &dmabuf, &l,
474 1 ) >= 0)
475 return 1;
476
477 return DMAbuf_select (dev, file, sel_type, wait);
478 break;
479
480 case SEL_OUT:
481 if (audio_mode[dev] != AM_WRITE)
482 return 0;
483
484 if (wr_buff_no[dev] != -1)
485 return 1;
486
487 return DMAbuf_select (dev, file, sel_type, wait);
488 break;
489
490 case SEL_EX:
491 return 0;
492 }
493
494 return 0;
495 }
496
497 #endif
498
499 #else
500
501
502
503
504 int
505 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
506 {
507 return RET_ERROR (EIO);
508 }
509
510 int
511 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
512 {
513 return RET_ERROR (EIO);
514 }
515
516 int
517 audio_open (int dev, struct fileinfo *file)
518 {
519 return RET_ERROR (ENXIO);
520 }
521
522 void
523 audio_release (int dev, struct fileinfo *file)
524 {
525 };
526 int
527 audio_ioctl (int dev, struct fileinfo *file,
528 unsigned int cmd, unsigned int arg)
529 {
530 return RET_ERROR (EIO);
531 }
532
533 int
534 audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
535 {
536 return RET_ERROR (EIO);
537 }
538
539 long
540 audio_init (long mem_start)
541 {
542 return mem_start;
543 }
544
545 #endif
546
547 #endif