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