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