Import 2.1.81
[davej-history.git] / drivers / sound / audio.c
blob9b6fa5c1258eeb89093c767f2fbb0b0196cbbad2
1 /*
2 * sound/audio.c
4 * Device file manager for /dev/audio
5 */
7 /*
8 * Copyright (C) by Hannu Savolainen 1993-1997
10 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
11 * Version 2 (June 1991). See the "COPYING" file distributed with this software
12 * for more info.
15 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
18 #include <linux/config.h>
20 #include "sound_config.h"
22 #if defined(CONFIG_AUDIO) || defined(MODULE)
23 #include "ulaw.h"
24 #include "coproc.h"
26 #define NEUTRAL8 0x80
27 #define NEUTRAL16 0x00
29 static int audio_mode[MAX_AUDIO_DEV];
30 static int dev_nblock[MAX_AUDIO_DEV]; /* 1 if in nonblocking mode */
32 #define AM_NONE 0
33 #define AM_WRITE OPEN_WRITE
34 #define AM_READ OPEN_READ
35 int dma_ioctl(int dev, unsigned int cmd, caddr_t arg);
38 static int local_format[MAX_AUDIO_DEV], audio_format[MAX_AUDIO_DEV];
39 static int local_conversion[MAX_AUDIO_DEV];
41 #define CNV_MU_LAW 0x00000001
43 static int set_format(int dev, int fmt)
45 if (fmt != AFMT_QUERY)
47 local_conversion[dev] = 0;
49 if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */
51 if (fmt == AFMT_MU_LAW)
53 fmt = AFMT_U8;
54 local_conversion[dev] = CNV_MU_LAW;
56 else
57 fmt = AFMT_U8; /* This is always supported */
59 audio_format[dev] = audio_devs[dev]->d->set_bits(dev, fmt);
60 local_format[dev] = fmt;
62 else
63 return local_format[dev];
65 return local_format[dev];
68 int audio_open(int dev, struct fileinfo *file)
70 int ret;
71 int bits;
72 int dev_type = dev & 0x0f;
73 int mode = file->mode & O_ACCMODE;
75 dev = dev >> 4;
77 if (dev_type == SND_DEV_DSP16)
78 bits = 16;
79 else
80 bits = 8;
82 if (dev < 0 || dev >= num_audiodevs)
83 return -ENXIO;
85 if ((ret = DMAbuf_open(dev, mode)) < 0)
86 return ret;
88 if (audio_devs[dev]->coproc)
90 if ((ret = audio_devs[dev]->coproc->
91 open(audio_devs[dev]->coproc->devc, COPR_PCM)) < 0)
93 audio_release(dev, file);
94 printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
95 return ret;
99 local_conversion[dev] = 0;
101 if (dev_type == SND_DEV_AUDIO)
102 set_format(dev, AFMT_MU_LAW);
103 else
104 set_format(dev, bits);
106 audio_mode[dev] = AM_NONE;
107 dev_nblock[dev] = 0;
110 return ret;
113 static void sync_output(int dev)
115 int p, i;
116 int l;
117 struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
119 if (dmap->fragment_size <= 0)
120 return;
121 dmap->flags |= DMA_POST;
123 /* Align the write pointer with fragment boundaries */
125 if ((l = dmap->user_counter % dmap->fragment_size) > 0)
127 int len;
128 unsigned long offs = dmap->user_counter % dmap->bytes_in_use;
130 len = dmap->fragment_size - l;
131 memset(dmap->raw_buf + offs, dmap->neutral_byte, len);
132 DMAbuf_move_wrpointer(dev, len);
136 * Clean all unused buffer fragments.
139 p = dmap->qtail;
140 dmap->flags |= DMA_POST;
142 for (i = dmap->qlen + 1; i < dmap->nbufs; i++)
144 p = (p + 1) % dmap->nbufs;
145 if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) >
146 (dmap->raw_buf + dmap->buffsize))
147 printk(KERN_ERR "audio: Buffer error 2\n");
149 memset(dmap->raw_buf + p * dmap->fragment_size,
150 dmap->neutral_byte,
151 dmap->fragment_size);
154 dmap->flags |= DMA_DIRTY;
157 void audio_release(int dev, struct fileinfo *file)
159 int mode;
161 dev = dev >> 4;
162 mode = file->mode & O_ACCMODE;
164 audio_devs[dev]->dmap_out->closing = 1;
165 audio_devs[dev]->dmap_in->closing = 1;
167 sync_output(dev);
169 if (audio_devs[dev]->coproc)
170 audio_devs[dev]->coproc->close(audio_devs[dev]->coproc->devc, COPR_PCM);
171 DMAbuf_release(dev, mode);
174 #if defined(NO_INLINE_ASM) || !defined(i386)
176 static void translate_bytes(const unsigned char *table, unsigned char *buff, int n)
178 unsigned long i;
180 if (n <= 0)
181 return;
183 for (i = 0; i < n; ++i)
184 buff[i] = table[buff[i]];
187 #else
188 extern inline void
189 translate_bytes(const void *table, void *buff, int n)
191 if (n > 0)
193 __asm__("cld\n"
194 "1:\tlodsb\n\t"
195 "xlatb\n\t"
196 "stosb\n\t"
197 "loop 1b\n\t":
198 : "b"((long) table), "c"(n), "D"((long) buff), "S"((long) buff)
199 : "bx", "cx", "di", "si", "ax");
203 #endif
205 int audio_write(int dev, struct fileinfo *file, const char *buf, int count)
207 int c, p, l, buf_size;
208 int err;
209 char *dma_buf;
211 dev = dev >> 4;
213 p = 0;
214 c = count;
216 if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
217 return -EPERM;
219 if (audio_devs[dev]->flags & DMA_DUPLEX)
220 audio_mode[dev] |= AM_WRITE;
221 else
222 audio_mode[dev] = AM_WRITE;
224 if (!count) /* Flush output */
226 sync_output(dev);
227 return 0;
230 while (c)
232 if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, dev_nblock[dev])) < 0)
234 /* Handle nonblocking mode */
235 if (dev_nblock[dev] && err == -EAGAIN)
236 return p; /* No more space. Return # of accepted bytes */
237 return err;
239 l = c;
241 if (l > buf_size)
242 l = buf_size;
244 if (!audio_devs[dev]->d->copy_user)
246 if ((dma_buf + l) >
247 (audio_devs[dev]->dmap_out->raw_buf + audio_devs[dev]->dmap_out->buffsize))
249 printk(KERN_ERR "audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf, l, (long) audio_devs[dev]->dmap_out->raw_buf, (int) audio_devs[dev]->dmap_out->buffsize);
250 return -EDOM;
252 if (dma_buf < audio_devs[dev]->dmap_out->raw_buf)
254 printk(KERN_ERR "audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf);
255 return -EDOM;
257 if(copy_from_user(dma_buf, &(buf)[p], l))
258 return -EFAULT;
260 else audio_devs[dev]->d->copy_user(dev, dma_buf, 0, buf, p, l);
262 if (local_conversion[dev] & CNV_MU_LAW)
265 * This just allows interrupts while the conversion is running
267 sti();
268 translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
270 c -= l;
271 p += l;
272 DMAbuf_move_wrpointer(dev, l);
276 return count;
279 int audio_read(int dev, struct fileinfo *file, char *buf, int count)
281 int c, p, l;
282 char *dmabuf;
283 int buf_no;
285 dev = dev >> 4;
286 p = 0;
287 c = count;
289 if (!(audio_devs[dev]->open_mode & OPEN_READ))
290 return -EPERM;
292 if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
293 sync_output(dev);
295 if (audio_devs[dev]->flags & DMA_DUPLEX)
296 audio_mode[dev] |= AM_READ;
297 else
298 audio_mode[dev] = AM_READ;
300 while(c)
302 if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l,
303 dev_nblock[dev])) < 0)
306 * Nonblocking mode handling. Return current # of bytes
309 if (dev_nblock[dev] && buf_no == -EAGAIN)
310 return p;
312 if (p > 0) /* Avoid throwing away data */
313 return p; /* Return it instead */
315 return buf_no;
317 if (l > c)
318 l = c;
321 * Insert any local processing here.
324 if (local_conversion[dev] & CNV_MU_LAW)
327 * This just allows interrupts while the conversion is running
329 sti();
331 translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
335 char *fixit = dmabuf;
337 if(copy_to_user(&(buf)[p], fixit, l))
338 return -EFAULT;
341 DMAbuf_rmchars(dev, buf_no, l);
343 p += l;
344 c -= l;
347 return count - c;
350 int audio_ioctl(int dev, struct fileinfo *file_must_not_be_used,
351 unsigned int cmd, caddr_t arg)
353 int val = 0, info, count;
354 unsigned long flags;
355 struct dma_buffparms *dmap;
357 dev = dev >> 4;
359 if (((cmd >> 8) & 0xff) == 'C') {
360 if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
361 return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
362 /* else
363 printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
364 return -ENXIO;
366 else switch (cmd)
368 case SNDCTL_DSP_SYNC:
369 if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
370 return 0;
371 if (audio_devs[dev]->dmap_out->fragment_size == 0)
372 return 0;
373 sync_output(dev);
374 DMAbuf_sync(dev);
375 DMAbuf_reset(dev);
376 return 0;
378 case SNDCTL_DSP_POST:
379 if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
380 return 0;
381 if (audio_devs[dev]->dmap_out->fragment_size == 0)
382 return 0;
383 audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
384 sync_output(dev);
385 dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
386 return 0;
388 case SNDCTL_DSP_RESET:
389 audio_mode[dev] = AM_NONE;
390 DMAbuf_reset(dev);
391 return 0;
393 case SNDCTL_DSP_GETFMTS:
394 val = audio_devs[dev]->format_mask;
395 break;
397 case SNDCTL_DSP_SETFMT:
398 if (get_user(val, (int *)arg))
399 return -EFAULT;
400 val = set_format(dev, val);
401 break;
403 case SNDCTL_DSP_GETISPACE:
404 if (!(audio_devs[dev]->open_mode & OPEN_READ))
405 return 0;
406 if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
407 return -EBUSY;
408 return dma_ioctl(dev, cmd, arg);
410 case SNDCTL_DSP_GETOSPACE:
411 if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
412 return -EPERM;
413 if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
414 return -EBUSY;
415 return dma_ioctl(dev, cmd, arg);
417 case SNDCTL_DSP_NONBLOCK:
418 dev_nblock[dev] = 1;
419 return 0;
421 case SNDCTL_DSP_GETCAPS:
422 info = 1 | DSP_CAP_MMAP; /* Revision level of this ioctl() */
423 if (audio_devs[dev]->flags & DMA_DUPLEX &&
424 audio_devs[dev]->open_mode == OPEN_READWRITE)
425 info |= DSP_CAP_DUPLEX;
426 if (audio_devs[dev]->coproc)
427 info |= DSP_CAP_COPROC;
428 if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
429 info |= DSP_CAP_BATCH;
430 if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */
431 info |= DSP_CAP_TRIGGER;
432 break;
434 case SOUND_PCM_WRITE_RATE:
435 if (get_user(val, (int *)arg))
436 return -EFAULT;
437 val = audio_devs[dev]->d->set_speed(dev, val);
438 break;
440 case SOUND_PCM_READ_RATE:
441 val = audio_devs[dev]->d->set_speed(dev, 0);
442 break;
444 case SNDCTL_DSP_STEREO:
445 if (get_user(val, (int *)arg))
446 return -EFAULT;
447 if (val > 1 || val < 0)
448 return -EINVAL;
449 val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
450 break;
452 case SOUND_PCM_WRITE_CHANNELS:
453 if (get_user(val, (int *)arg))
454 return -EFAULT;
455 val = audio_devs[dev]->d->set_channels(dev, val);
456 break;
458 case SOUND_PCM_READ_CHANNELS:
459 val = audio_devs[dev]->d->set_channels(dev, 0);
460 break;
462 case SOUND_PCM_READ_BITS:
463 val = audio_devs[dev]->d->set_bits(dev, 0);
464 break;
466 case SNDCTL_DSP_SETDUPLEX:
467 if (audio_devs[dev]->open_mode != OPEN_READWRITE)
468 return -EPERM;
469 return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
471 case SNDCTL_DSP_PROFILE:
472 if (get_user(val, (int *)arg))
473 return -EFAULT;
474 if (audio_devs[dev]->open_mode & OPEN_WRITE)
475 audio_devs[dev]->dmap_out->applic_profile = val;
476 if (audio_devs[dev]->open_mode & OPEN_READ)
477 audio_devs[dev]->dmap_in->applic_profile = val;
478 return 0;
480 case SNDCTL_DSP_GETODELAY:
481 dmap = audio_devs[dev]->dmap_out;
482 if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
483 return -EINVAL;
484 if (!(dmap->flags & DMA_ALLOC_DONE))
486 val=0;
487 break;
490 save_flags (flags);
491 cli();
492 /* Compute number of bytes that have been played */
493 count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
494 if (count < dmap->fragment_size && dmap->qhead != 0)
495 count += dmap->bytes_in_use; /* Pointer wrap not handled yet */
496 count += dmap->byte_counter;
498 /* Substract current count from the number of bytes written by app */
499 count = dmap->user_counter - count;
500 if (count < 0)
501 count = 0;
502 restore_flags (flags);
503 val = count;
504 break;
506 default:
507 return dma_ioctl(dev, cmd, arg);
509 return put_user(val, (int *)arg);
512 void audio_init_devices(void)
515 * NOTE! This routine could be called several times during boot.
519 #endif
521 void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
524 * This routine breaks the physical device buffers to logical ones.
527 struct audio_operations *dsp_dev = audio_devs[dev];
529 unsigned i, n;
530 unsigned sr, nc, sz, bsz;
532 sr = dsp_dev->d->set_speed(dev, 0);
533 nc = dsp_dev->d->set_channels(dev, 0);
534 sz = dsp_dev->d->set_bits(dev, 0);
536 if (sz == 8)
537 dmap->neutral_byte = NEUTRAL8;
538 else
539 dmap->neutral_byte = NEUTRAL16;
541 if (sr < 1 || nc < 1 || sz < 1)
543 /* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
544 sr = DSP_DEFAULT_SPEED;
545 nc = 1;
546 sz = 8;
549 sz = sr * nc * sz;
551 sz /= 8; /* #bits -> #bytes */
552 dmap->data_rate = sz;
554 if (!dmap->needs_reorg)
555 return;
556 dmap->needs_reorg = 0;
558 if (dmap->fragment_size == 0)
560 /* Compute the fragment size using the default algorithm */
563 * Compute a buffer size for time not exceeding 1 second.
564 * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
565 * of sound (using the current speed, sample size and #channels).
568 bsz = dmap->buffsize;
569 while (bsz > sz)
570 bsz /= 2;
572 if (bsz == dmap->buffsize)
573 bsz /= 2; /* Needs at least 2 buffers */
576 * Split the computed fragment to smaller parts. After 3.5a9
577 * the default subdivision is 4 which should give better
578 * results when recording.
581 if (dmap->subdivision == 0) /* Not already set */
583 dmap->subdivision = 4; /* Init to the default value */
585 if ((bsz / dmap->subdivision) > 4096)
586 dmap->subdivision *= 2;
587 if ((bsz / dmap->subdivision) < 4096)
588 dmap->subdivision = 1;
590 bsz /= dmap->subdivision;
592 if (bsz < 16)
593 bsz = 16; /* Just a sanity check */
595 dmap->fragment_size = bsz;
597 else
600 * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
601 * the buffer size computation has already been done.
603 if (dmap->fragment_size > (dmap->buffsize / 2))
604 dmap->fragment_size = (dmap->buffsize / 2);
605 bsz = dmap->fragment_size;
608 if (audio_devs[dev]->min_fragment)
609 if (bsz < (1 << audio_devs[dev]->min_fragment))
610 bsz = 1 << audio_devs[dev]->min_fragment;
611 if (audio_devs[dev]->max_fragment)
612 if (bsz > (1 << audio_devs[dev]->max_fragment))
613 bsz = 1 << audio_devs[dev]->max_fragment;
614 bsz &= ~0x07; /* Force size which is multiple of 8 bytes */
615 #ifdef OS_DMA_ALIGN_CHECK
616 OS_DMA_ALIGN_CHECK(bsz);
617 #endif
619 n = dmap->buffsize / bsz;
620 if (n > MAX_SUB_BUFFERS)
621 n = MAX_SUB_BUFFERS;
622 if (n > dmap->max_fragments)
623 n = dmap->max_fragments;
625 if (n < 2)
627 n = 2;
628 bsz /= 2;
630 dmap->nbufs = n;
631 dmap->bytes_in_use = n * bsz;
632 dmap->fragment_size = bsz;
633 dmap->max_byte_counter = (dmap->data_rate * 60 * 60) +
634 dmap->bytes_in_use; /* Approximately one hour */
636 if (dmap->raw_buf)
638 memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use);
641 for (i = 0; i < dmap->nbufs; i++)
643 dmap->counts[i] = 0;
646 dmap->flags |= DMA_ALLOC_DONE | DMA_EMPTY;
649 static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
651 if (fact == 0)
653 fact = dmap->subdivision;
654 if (fact == 0)
655 fact = 1;
656 return fact;
658 if (dmap->subdivision != 0 || dmap->fragment_size) /* Too late to change */
659 return -EINVAL;
661 if (fact > MAX_REALTIME_FACTOR)
662 return -EINVAL;
664 if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
665 return -EINVAL;
667 dmap->subdivision = fact;
668 return fact;
671 static int dma_set_fragment(int dev, struct dma_buffparms *dmap, int fact)
673 int bytes, count;
675 if (fact == 0)
676 return -EIO;
678 if (dmap->subdivision != 0 ||
679 dmap->fragment_size) /* Too late to change */
680 return -EINVAL;
682 bytes = fact & 0xffff;
683 count = (fact >> 16) & 0x7fff;
685 if (count == 0)
686 count = MAX_SUB_BUFFERS;
687 else if (count < MAX_SUB_BUFFERS)
688 count++;
690 if (bytes < 4 || bytes > 17) /* <16 || > 512k */
691 return -EINVAL;
693 if (count < 2)
694 return -EINVAL;
696 if (audio_devs[dev]->min_fragment > 0)
697 if (bytes < audio_devs[dev]->min_fragment)
698 bytes = audio_devs[dev]->min_fragment;
700 if (audio_devs[dev]->max_fragment > 0)
701 if (bytes > audio_devs[dev]->max_fragment)
702 bytes = audio_devs[dev]->max_fragment;
704 #ifdef OS_DMA_MINBITS
705 if (bytes < OS_DMA_MINBITS)
706 bytes = OS_DMA_MINBITS;
707 #endif
709 dmap->fragment_size = (1 << bytes);
710 dmap->max_fragments = count;
712 if (dmap->fragment_size > dmap->buffsize)
713 dmap->fragment_size = dmap->buffsize;
715 if (dmap->fragment_size == dmap->buffsize &&
716 audio_devs[dev]->flags & DMA_AUTOMODE)
717 dmap->fragment_size /= 2; /* Needs at least 2 buffers */
719 dmap->subdivision = 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
720 return bytes | ((count - 1) << 16);
723 int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
725 struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
726 struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
727 struct dma_buffparms *dmap;
728 audio_buf_info info;
729 count_info cinfo;
730 int fact, ret, changed, bits, count, err;
731 unsigned long flags;
733 switch (cmd)
735 case SNDCTL_DSP_SUBDIVIDE:
736 ret = 0;
737 if (get_user(fact, (int *)arg))
738 return -EFAULT;
739 if (audio_devs[dev]->open_mode & OPEN_WRITE)
740 ret = dma_subdivide(dev, dmap_out, fact);
741 if (ret < 0)
742 return ret;
743 if (audio_devs[dev]->open_mode != OPEN_WRITE ||
744 (audio_devs[dev]->flags & DMA_DUPLEX &&
745 audio_devs[dev]->open_mode & OPEN_READ))
746 ret = dma_subdivide(dev, dmap_in, fact);
747 if (ret < 0)
748 return ret;
749 break;
751 case SNDCTL_DSP_GETISPACE:
752 case SNDCTL_DSP_GETOSPACE:
753 dmap = dmap_out;
754 if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
755 return -EINVAL;
756 if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
757 return -EINVAL;
758 if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
759 dmap = dmap_in;
760 if (dmap->mapping_flags & DMA_MAP_MAPPED)
761 return -EINVAL;
762 if (!(dmap->flags & DMA_ALLOC_DONE))
763 reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
764 info.fragstotal = dmap->nbufs;
765 if (cmd == SNDCTL_DSP_GETISPACE)
766 info.fragments = dmap->qlen;
767 else
769 if (!DMAbuf_space_in_queue(dev))
770 info.fragments = 0;
771 else
773 info.fragments = DMAbuf_space_in_queue(dev);
774 if (audio_devs[dev]->d->local_qlen)
776 int tmp = audio_devs[dev]->d->local_qlen(dev);
777 if (tmp && info.fragments)
778 tmp--; /*
779 * This buffer has been counted twice
781 info.fragments -= tmp;
785 if (info.fragments < 0)
786 info.fragments = 0;
787 else if (info.fragments > dmap->nbufs)
788 info.fragments = dmap->nbufs;
790 info.fragsize = dmap->fragment_size;
791 info.bytes = info.fragments * dmap->fragment_size;
793 if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
794 info.bytes -= dmap->counts[dmap->qhead];
795 else
797 info.fragments = info.bytes / dmap->fragment_size;
798 info.bytes -= dmap->user_counter % dmap->fragment_size;
800 return copy_to_user(arg, &info, sizeof(info));
802 case SNDCTL_DSP_SETTRIGGER:
803 if (get_user(bits, (int *)arg))
804 return -EFAULT;
805 bits &= audio_devs[dev]->open_mode;
806 if (audio_devs[dev]->d->trigger == NULL)
807 return -EINVAL;
808 if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
809 (bits & PCM_ENABLE_OUTPUT))
810 return -EINVAL;
811 save_flags(flags);
812 cli();
813 changed = audio_devs[dev]->enable_bits ^ bits;
814 if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go)
816 reorganize_buffers(dev, dmap_in, 1);
817 if ((err = audio_devs[dev]->d->prepare_for_input(dev,
818 dmap_in->fragment_size, dmap_in->nbufs)) < 0)
819 return -err;
820 dmap_in->dma_mode = DMODE_INPUT;
821 audio_devs[dev]->enable_bits = bits;
822 DMAbuf_activate_recording(dev, dmap_in);
824 if ((changed & bits) & PCM_ENABLE_OUTPUT &&
825 (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
826 audio_devs[dev]->go)
828 if (!(dmap_out->flags & DMA_ALLOC_DONE))
829 reorganize_buffers(dev, dmap_out, 0);
830 dmap_out->dma_mode = DMODE_OUTPUT;
831 audio_devs[dev]->enable_bits = bits;
832 dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
833 DMAbuf_launch_output(dev, dmap_out);
835 audio_devs[dev]->enable_bits = bits;
836 if (changed && audio_devs[dev]->d->trigger)
837 audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
838 restore_flags(flags);
839 /* Falls through... */
841 case SNDCTL_DSP_GETTRIGGER:
842 ret = audio_devs[dev]->enable_bits;
843 break;
845 case SNDCTL_DSP_SETSYNCRO:
846 if (!audio_devs[dev]->d->trigger)
847 return -EINVAL;
848 audio_devs[dev]->d->trigger(dev, 0);
849 audio_devs[dev]->go = 0;
850 return 0;
852 case SNDCTL_DSP_GETIPTR:
853 if (!(audio_devs[dev]->open_mode & OPEN_READ))
854 return -EINVAL;
855 save_flags(flags);
856 cli();
857 cinfo.bytes = dmap_in->byte_counter;
858 cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
859 if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
860 cinfo.bytes += dmap_in->bytes_in_use; /* Pointer wrap not handled yet */
861 cinfo.blocks = dmap_in->qlen;
862 cinfo.bytes += cinfo.ptr;
863 if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
864 dmap_in->qlen = 0; /* Reset interrupt counter */
865 restore_flags(flags);
866 return copy_to_user(arg, &cinfo, sizeof(cinfo));
868 case SNDCTL_DSP_GETOPTR:
869 if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
870 return -EINVAL;
872 save_flags(flags);
873 cli();
874 cinfo.bytes = dmap_out->byte_counter;
875 cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
876 if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
877 cinfo.bytes += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
878 cinfo.blocks = dmap_out->qlen;
879 cinfo.bytes += cinfo.ptr;
880 if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
881 dmap_out->qlen = 0; /* Reset interrupt counter */
882 restore_flags(flags);
883 return copy_to_user(arg, &cinfo, sizeof(cinfo));
885 case SNDCTL_DSP_GETODELAY:
886 if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
887 return -EINVAL;
888 if (!(dmap_out->flags & DMA_ALLOC_DONE))
890 ret=0;
891 break;
893 save_flags(flags);
894 cli();
895 /* Compute number of bytes that have been played */
896 count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
897 if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
898 count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
899 count += dmap_out->byte_counter;
900 /* Substract current count from the number of bytes written by app */
901 count = dmap_out->user_counter - count;
902 if (count < 0)
903 count = 0;
904 restore_flags (flags);
905 ret = count;
906 break;
908 case SNDCTL_DSP_POST:
909 if (audio_devs[dev]->dmap_out->qlen > 0)
910 if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
911 DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
912 return 0;
914 case SNDCTL_DSP_GETBLKSIZE:
915 dmap = dmap_out;
916 if (audio_devs[dev]->open_mode & OPEN_WRITE)
917 reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
918 if (audio_devs[dev]->open_mode == OPEN_READ ||
919 (audio_devs[dev]->flags & DMA_DUPLEX &&
920 audio_devs[dev]->open_mode & OPEN_READ))
921 reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
922 if (audio_devs[dev]->open_mode == OPEN_READ)
923 dmap = dmap_in;
924 ret = dmap->fragment_size;
925 break;
927 case SNDCTL_DSP_SETFRAGMENT:
928 ret = 0;
929 if (get_user(fact, (int *)arg))
930 return -EFAULT;
931 if (audio_devs[dev]->open_mode & OPEN_WRITE)
932 ret = dma_set_fragment(dev, dmap_out, fact);
933 if (ret < 0)
934 return ret;
935 if (audio_devs[dev]->open_mode == OPEN_READ ||
936 (audio_devs[dev]->flags & DMA_DUPLEX &&
937 audio_devs[dev]->open_mode & OPEN_READ))
938 ret = dma_set_fragment(dev, dmap_in, fact);
939 if (ret < 0)
940 return ret;
941 if (!arg) /* don't know what this is good for, but preserve old semantics */
942 return 0;
943 break;
945 default:
946 if (!audio_devs[dev]->d->ioctl)
947 return -EINVAL;
948 return audio_devs[dev]->d->ioctl(dev, cmd, arg);
950 return put_user(ret, (int *)arg);