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