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, p, i;
132 char *dma_buf;
133 struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
134
135 if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
136 {
137 DMAbuf_start_output (dev, buf_no, buf_ptr);
138 }
139
140
141
142
143
144 p = dmap->qtail;
145
146 for (i = dmap->qlen; i < dmap->nbufs; i++)
147 {
148 memset (dmap->raw_buf + p * dmap->fragment_size,
149 dmap->neutral_byte,
150 dmap->fragment_size);
151
152 p = (p + 1) % dmap->nbufs;
153 }
154
155 dmap->flags |= DMA_CLEAN;
156 }
157
158 void
159 audio_release (int dev, struct fileinfo *file)
160 {
161 int mode;
162
163 dev = dev >> 4;
164 mode = file->mode & O_ACCMODE;
165
166 audio_devs[dev]->dmap_out->closing = 1;
167 audio_devs[dev]->dmap_in->closing = 1;
168
169 sync_output (dev);
170
171 if (audio_devs[dev]->coproc)
172 audio_devs[dev]->coproc->close (audio_devs[dev]->coproc->devc, COPR_PCM);
173 DMAbuf_release (dev, mode);
174 }
175
176 #if defined(NO_INLINE_ASM) || !defined(i386)
177 static void
178 translate_bytes (const unsigned char *table, unsigned char *buff, int n)
179 {
180 unsigned long i;
181
182 if (n <= 0)
183 return;
184
185 for (i = 0; i < n; ++i)
186 buff[i] = table[buff[i]];
187 }
188
189 #else
190 extern inline void
191 translate_bytes (const void *table, void *buff, int n)
192 {
193 if (n > 0)
194 {
195 __asm__ ("cld\n"
196 "1:\tlodsb\n\t"
197 "xlatb\n\t"
198 "stosb\n\t"
199 "loop 1b\n\t":
200 : "b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
201 : "bx", "cx", "di", "si", "ax");
202 }
203 }
204
205 #endif
206
207 int
208 audio_write (int dev, struct fileinfo *file, const char *buf, int count)
209 {
210 int c, p, l, buf_no, buf_ptr, buf_size;
211 int err;
212 char *dma_buf;
213
214 dev = dev >> 4;
215
216 p = 0;
217 c = count;
218
219 if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
220 {
221 }
222
223 if (audio_devs[dev]->flags & DMA_DUPLEX)
224 audio_mode[dev] |= AM_WRITE;
225 else
226 audio_mode[dev] = AM_WRITE;
227
228 if (!count)
229 {
230 sync_output (dev);
231 return 0;
232 }
233
234 while (c)
235 {
236 if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) < 0)
237 {
238 if ((buf_no = DMAbuf_getwrbuffer (dev, &dma_buf,
239 &buf_size,
240 dev_nblock[dev])) < 0)
241 {
242
243 if (dev_nblock[dev] && buf_no == -EAGAIN)
244 return p;
245 return buf_no;
246 }
247 buf_ptr = 0;
248 }
249
250 l = c;
251 if (l > (buf_size - buf_ptr))
252 l = (buf_size - buf_ptr);
253
254 if (!audio_devs[dev]->copy_from_user)
255 {
256
257
258 memcpy_fromfs (&dma_buf[buf_ptr], &((buf)[p]), l);
259 }
260 else
261 audio_devs[dev]->copy_from_user (dev,
262 dma_buf, buf_ptr, buf, p, l);
263
264 if (local_conversion[dev] == AFMT_MU_LAW)
265 {
266
267
268
269 sti ();
270 translate_bytes (ulaw_dsp, (unsigned char *) &dma_buf[buf_ptr], l);
271 }
272
273 c -= l;
274 p += l;
275 buf_ptr += l;
276
277 if (buf_ptr >= buf_size)
278 {
279 if ((err = DMAbuf_start_output (dev, buf_no, buf_ptr)) < 0)
280 {
281 return err;
282 }
283
284 }
285 else
286 DMAbuf_set_count (dev, buf_no, buf_ptr);
287
288 }
289
290 return count;
291 }
292
293 int
294 audio_read (int dev, struct fileinfo *file, char *buf, int count)
295 {
296 int c, p, l;
297 char *dmabuf;
298 int buf_no;
299
300 dev = dev >> 4;
301 p = 0;
302 c = count;
303
304 if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
305 {
306 sync_output (dev);
307 }
308
309 if (audio_devs[dev]->flags & DMA_DUPLEX)
310 audio_mode[dev] |= AM_READ;
311 else
312 audio_mode[dev] = AM_READ;
313
314 while (c)
315 {
316 if ((buf_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l,
317 dev_nblock[dev])) < 0)
318 {
319
320
321 if (dev_nblock[dev] && buf_no == -EAGAIN)
322 return p;
323
324 return buf_no;
325 }
326
327 if (l > c)
328 l = c;
329
330
331
332
333
334 if (local_conversion[dev] == AFMT_MU_LAW)
335 {
336
337
338
339 sti ();
340
341 translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
342 }
343
344 memcpy_tofs (&((buf)[p]), dmabuf, l);
345
346 DMAbuf_rmchars (dev, buf_no, l);
347
348 p += l;
349 c -= l;
350 }
351
352 return count - c;
353 }
354
355 int
356 audio_ioctl (int dev, struct fileinfo *file,
357 unsigned int cmd, caddr_t arg)
358 {
359
360 dev = dev >> 4;
361
362 if (((cmd >> 8) & 0xff) == 'C')
363 {
364 if (audio_devs[dev]->coproc)
365 return audio_devs[dev]->coproc->ioctl (audio_devs[dev]->coproc->devc, cmd, arg, 0);
366 else
367 printk ("/dev/dsp%d: No coprocessor for this device\n", dev);
368
369 return -ENXIO;
370 }
371 else
372 switch (cmd)
373 {
374 case SNDCTL_DSP_SYNC:
375 sync_output (dev);
376 return DMAbuf_ioctl (dev, cmd, arg, 0);
377 break;
378
379 case SNDCTL_DSP_POST:
380 sync_output (dev);
381 return 0;
382 break;
383
384 case SNDCTL_DSP_RESET:
385 audio_mode[dev] = AM_NONE;
386 return DMAbuf_ioctl (dev, cmd, arg, 0);
387 break;
388
389 case SNDCTL_DSP_GETFMTS:
390 return snd_ioctl_return ((int *) arg, audio_devs[dev]->format_mask | AFMT_MU_LAW);
391 break;
392
393 case SNDCTL_DSP_SETFMT:
394 return snd_ioctl_return ((int *) arg, set_format (dev, get_fs_long ((long *) arg)));
395
396 case SNDCTL_DSP_GETISPACE:
397 if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
398 return -EBUSY;
399
400 {
401 audio_buf_info info;
402
403 int err = DMAbuf_ioctl (dev, cmd, (caddr_t) & info, 1);
404
405 if (err < 0)
406 return err;
407
408 memcpy_tofs ((&((char *) arg)[0]), (char *) &info, sizeof (info));
409 return 0;
410 }
411
412 case SNDCTL_DSP_GETOSPACE:
413 if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
414 return -EBUSY;
415
416 {
417 audio_buf_info info;
418 char *dma_buf;
419 int buf_no, buf_ptr, buf_size;
420
421 int err = DMAbuf_ioctl (dev, cmd, (caddr_t) & info, 1);
422
423 if (err < 0)
424 return err;
425
426 if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
427 info.bytes += buf_size - buf_ptr;
428
429 memcpy_tofs ((&((char *) arg)[0]), (char *) &info, sizeof (info));
430 return 0;
431 }
432
433 case SNDCTL_DSP_NONBLOCK:
434 dev_nblock[dev] = 1;
435 return 0;
436 break;
437
438 case SNDCTL_DSP_GETCAPS:
439 {
440 int info = 1;
441
442 if (audio_devs[dev]->flags & DMA_DUPLEX)
443 info |= DSP_CAP_DUPLEX;
444
445 if (audio_devs[dev]->coproc)
446 info |= DSP_CAP_COPROC;
447
448 if (audio_devs[dev]->local_qlen)
449 info |= DSP_CAP_BATCH;
450
451 if (audio_devs[dev]->trigger)
452 info |= DSP_CAP_TRIGGER;
453
454 info |= DSP_CAP_MMAP;
455
456 memcpy_tofs ((&((char *) arg)[0]), (char *) &info, sizeof (info));
457 return 0;
458 }
459 break;
460
461 default:
462 return DMAbuf_ioctl (dev, cmd, arg, 0);
463 }
464 }
465
466 long
467 audio_init (long mem_start)
468 {
469
470
471
472 return mem_start;
473 }
474
475 int
476 audio_select (int dev, struct fileinfo *file, int sel_type, select_table_handle * wait)
477 {
478 char *dma_buf;
479 int buf_no, buf_ptr, buf_size;
480
481 dev = dev >> 4;
482
483 switch (sel_type)
484 {
485 case SEL_IN:
486 if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
487 {
488 return 0;
489 }
490
491 return DMAbuf_select (dev, file, sel_type, wait);
492 break;
493
494 case SEL_OUT:
495 if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX))
496 {
497 return 0;
498 }
499
500 if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
501 {
502 return 1;
503 }
504
505 return DMAbuf_select (dev, file, sel_type, wait);
506 break;
507
508 case SEL_EX:
509 return 0;
510 }
511
512 return 0;
513 }
514
515
516 #endif