summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/sound/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/sound/audio.c')
-rw-r--r--sys/i386/isa/sound/audio.c440
1 files changed, 0 insertions, 440 deletions
diff --git a/sys/i386/isa/sound/audio.c b/sys/i386/isa/sound/audio.c
deleted file mode 100644
index c526857..0000000
--- a/sys/i386/isa/sound/audio.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * sound/audio.c
- *
- * Device file manager for /dev/audio
- *
- * Copyright by Hannu Savolainen 1993
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer. 2.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#ifdef CONFIG_AUDIO
-
-#include <i386/isa/sound/ulaw.h>
-#include <i386/isa/sound/coproc.h>
-
-#define ON 1
-#define OFF 0
-int
-DMAbuf_poll(int dev, struct fileinfo * file, int events, select_table * wait);
-
-int
-audio_poll(int dev, struct fileinfo * file, int events, select_table * wait);
-
-static int wr_buff_no[MAX_AUDIO_DEV];
- /* != -1, if there is a incomplete output block in the queue. */
-static int wr_buff_size[MAX_AUDIO_DEV], wr_buff_ptr[MAX_AUDIO_DEV];
-
-static int audio_mode[MAX_AUDIO_DEV];
-static int dev_nblock[MAX_AUDIO_DEV]; /* 1 if in noblocking mode */
-
-#define AM_NONE 0
-#define AM_WRITE 1
-#define AM_READ 2
-
-static char *wr_dma_buf[MAX_AUDIO_DEV];
-static int audio_format[MAX_AUDIO_DEV];
-static int local_conversion[MAX_AUDIO_DEV];
-
-static int
-set_format(int dev, int fmt)
-{
- if (fmt != AFMT_QUERY) {
-
- local_conversion[dev] = 0;
-
- if (!(audio_devs[dev]->format_mask & fmt)) { /* Not supported */
- if (fmt == AFMT_MU_LAW) {
- fmt = AFMT_U8;
- local_conversion[dev] = AFMT_MU_LAW;
- } else
- fmt = AFMT_U8; /* This is always supported */
- }
- audio_format[dev] = DMAbuf_ioctl(dev, SNDCTL_DSP_SETFMT,
- (ioctl_arg) fmt, 1);
- }
- if (local_conversion[dev]) /* This shadows the HW format */
- return local_conversion[dev];
-
- return audio_format[dev];
-}
-
-int
-audio_open(int dev, struct fileinfo * file)
-{
- int ret;
- int bits;
- int dev_type = dev & 0x0f;
- int mode = file->mode & O_ACCMODE;
-
- dev = dev >> 4;
-
- bits = (dev_type == SND_DEV_DSP16) ? 16 : 8 ;
-
- if ((ret = DMAbuf_open(dev, mode)) < 0)
- return ret;
-
- if (audio_devs[dev]->coproc)
- if ((ret = audio_devs[dev]->coproc->
- open(audio_devs[dev]->coproc->devc, COPR_PCM)) < 0) {
- audio_release(dev, file);
- printf("Sound: Can't access coprocessor device\n");
-
- return ret;
- }
- local_conversion[dev] = 0;
-
- if (DMAbuf_ioctl(dev, SNDCTL_DSP_SETFMT, (ioctl_arg) bits, 1) != bits) {
- audio_release(dev, file);
- return -(ENXIO);
- }
-
- set_format(dev, (dev_type == SND_DEV_AUDIO) ? AFMT_MU_LAW : bits ) ;
-
- wr_buff_no[dev] = -1;
- audio_mode[dev] = AM_NONE;
- wr_buff_size[dev] = wr_buff_ptr[dev] = 0;
- dev_nblock[dev] = 0;
-
- return ret;
-}
-
-void
-audio_release(int dev, struct fileinfo * file)
-{
- int mode;
-
- dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
-
- if (wr_buff_no[dev] >= 0) {
- DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
- wr_buff_no[dev] = -1;
- }
- if (audio_devs[dev]->coproc)
- audio_devs[dev]->coproc->close(audio_devs[dev]->coproc->devc,COPR_PCM);
- DMAbuf_release(dev, mode);
- audio_devs[dev]->dmap_out->mapping_flags &= ~DMA_MAP_MAPPED ;
-
-}
-
-static void
-translate_bytes(const u_char *table, u_char *buff, int n)
-{
- u_long i;
-
- if (n <= 0)
- return;
-
- for (i = 0; i < n; ++i)
- buff[i] = table[buff[i]];
-}
-
-int
-audio_write(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
-{
- int c, p, l;
- int err;
-
- dev = dev >> 4;
-
- p = 0;
- c = count;
- if ((audio_mode[dev] & AM_READ) &&
- !(audio_devs[dev]->flags & DMA_DUPLEX)) { /* Direction change */
- wr_buff_no[dev] = -1;
- }
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- audio_mode[dev] |= AM_WRITE;
- else
- audio_mode[dev] = AM_WRITE;
-
- if (!count) { /* Flush output */
- if (wr_buff_no[dev] >= 0) {
- DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
- wr_buff_no[dev] = -1;
- }
- return 0;
- }
- while (c) { /* Perform output blocking */
- if (wr_buff_no[dev] < 0) {
- /* There is no incomplete buffers */
- if ((wr_buff_no[dev] = DMAbuf_getwrbuffer(dev,
- &wr_dma_buf[dev], &wr_buff_size[dev],
- dev_nblock[dev])) < 0) {
- /* Handle nonblocking mode */
- if (dev_nblock[dev] && wr_buff_no[dev] == -(EAGAIN))
- return p; /* No more space. Return # of accepted bytes */
- return wr_buff_no[dev];
- }
- wr_buff_ptr[dev] = 0;
- }
- l = c;
- if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
- l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
-
- if (!audio_devs[dev]->copy_from_user) { /* No device specific
- * copy routine */
-
- if (uiomove(&wr_dma_buf[dev][wr_buff_ptr[dev]], l, buf)) {
- printf("sb: Bad copyin()!\n");
- };
- } else
- audio_devs[dev]->copy_from_user(dev,
- wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
-
-
- /*
- * Insert local processing here
- */
-
- if (local_conversion[dev] == AFMT_MU_LAW) {
- translate_bytes(ulaw_dsp,
- (u_char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
- }
- c -= l;
- p += l;
- wr_buff_ptr[dev] += l;
-
- if (wr_buff_ptr[dev] >= wr_buff_size[dev]) {
- if ((err = DMAbuf_start_output(dev, wr_buff_no[dev],
- wr_buff_ptr[dev])) < 0) {
- return err;
- }
- wr_buff_no[dev] = -1;
- }
- }
- return count;
-}
-
-int
-audio_read(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
-{
- int c, p, l;
- char *dmabuf;
- int buff_no;
-
- dev = dev >> 4;
- p = 0;
- c = count;
- if ((audio_mode[dev] & AM_WRITE) &&
- !(audio_devs[dev]->flags & DMA_DUPLEX)) {
- if (wr_buff_no[dev] >= 0) {
- DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
-
- if (!(audio_devs[dev]->flags & DMA_DUPLEX))
- wr_buff_no[dev] = -1;
- }
- }
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- audio_mode[dev] |= AM_READ;
- else
- audio_mode[dev] = AM_READ;
-
- while (c) {
- if ((buff_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l,
- dev_nblock[dev])) < 0) {
- /*
- * Nonblocking mode handling. Return current # of bytes
- */
-
- if (dev_nblock[dev] && buff_no == -(EAGAIN))
- return p;
-
- return buff_no;
- }
- if (l > c)
- l = c;
-
- /*
- * Insert any local processing here.
- */
-
- if (local_conversion[dev] == AFMT_MU_LAW) {
- translate_bytes(dsp_ulaw, (u_char *) dmabuf, l);
- }
- if (uiomove(dmabuf, l, buf)) {
- printf("sb: Bad copyout()!\n");
- };
-
- DMAbuf_rmchars(dev, buff_no, l);
-
- p += l;
- c -= l;
- }
- return count - c;
-}
-
-int
-audio_ioctl(int dev, struct fileinfo * file, u_int cmd, ioctl_arg arg)
-{
- dev = dev >> 4;
- if (((cmd >> 8) & 0xff) == 'C') {
- if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
- return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
- else
- printf("/dev/dsp%d: No coprocessor for this device\n", dev);
-
- return -(ENXIO);
- } else
- switch (cmd) {
-
- case SNDCTL_DSP_SYNC:
- if (wr_buff_no[dev] >= 0) {
- DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
- wr_buff_no[dev] = -1;
- }
- return DMAbuf_ioctl(dev, cmd, arg, 0);
- break;
-
- case SNDCTL_DSP_POST:
- if (wr_buff_no[dev] >= 0) {
- DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
- wr_buff_no[dev] = -1;
- }
- return 0;
- break;
-
- case SNDCTL_DSP_RESET:
- wr_buff_no[dev] = -1;
- audio_mode[dev] = AM_NONE;
- return DMAbuf_ioctl(dev, cmd, arg, 0);
- break;
-
- case SNDCTL_DSP_GETFMTS:
- return *(int *) arg = audio_devs[dev]->format_mask;
- break;
-
- case SNDCTL_DSP_SETFMT:
- return *(int *) arg = set_format(dev, (*(int *) arg));
-
- case SNDCTL_DSP_GETISPACE:
- if ((audio_mode[dev] & AM_WRITE) &&
- !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -(EBUSY);
-
- else {
- audio_buf_info info;
- int err = DMAbuf_ioctl(dev, cmd, (ioctl_arg) & info, 1);
-
- if (err < 0)
- return err;
-
- bcopy((char *) &info, &(((char *) arg)[0]), sizeof(info));
- return 0;
- }
-
- case SNDCTL_DSP_GETOSPACE:
- if ((audio_mode[dev] & AM_READ) &&
- !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -(EBUSY);
- else {
- audio_buf_info info;
- int err = DMAbuf_ioctl(dev, cmd, (ioctl_arg) & info, 1);
-
- if (err < 0)
- return err;
-
- if (wr_buff_no[dev] != -1)
- info.bytes += wr_buff_size[dev] - wr_buff_ptr[dev];
-
- bcopy((char *) &info, &(((char *) arg)[0]), sizeof(info));
- return 0;
- }
-
- case SNDCTL_DSP_NONBLOCK:
- dev_nblock[dev] = 1;
- return 0;
- break;
-
- case SNDCTL_DSP_GETCAPS:
- {
- int info = 1; /* Revision level of this ioctl() */
-
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- info |= DSP_CAP_DUPLEX;
-
- if (audio_devs[dev]->coproc)
- info |= DSP_CAP_COPROC;
-
- if (audio_devs[dev]->local_qlen) /* Dev. has hidden buffs */
- info |= DSP_CAP_BATCH;
-
- if (audio_devs[dev]->trigger) /* Supports SETTRIGGER */
- info |= DSP_CAP_TRIGGER;
-
- info |= DSP_CAP_MMAP;
- bcopy((char *) &info, &(((char *) arg)[0]), sizeof(info));
- return 0;
- }
- break;
-
-
- case FIOASYNC:
- return *(int *) arg = 1;
-
- case FIONBIO:
- return *(int *) arg = 1;
-
- default:
- return DMAbuf_ioctl(dev, cmd, arg, 0);
- }
-}
-
-#ifdef ALLOW_POLL
-/*
- * XXX should we use spltty() in the select calls ? - lr970714
- *
- */
-
-int
-audio_poll(int dev, struct fileinfo * file, int events, select_table * wait)
-{
- dev = dev >> 4;
-
- if (events & (POLLIN | POLLRDNORM)) {
- if ((audio_mode[dev] & AM_WRITE) &&
- !(audio_devs[dev]->flags & DMA_DUPLEX))
- return 0; /* Not recording */
-
-
- return (DMAbuf_poll(dev, file, events, wait));
- }
-
- if (events & (POLLOUT | POLLWRNORM)) {
- if ((audio_mode[dev] & AM_READ) &&
- !(audio_devs[dev]->flags & DMA_DUPLEX))
- return 0; /* Wrong direction */
-
- if (wr_buff_no[dev] != -1)
- return 1; /* There is space in the current buffer */
-
- return ( DMAbuf_poll(dev, file, events, wait) );
-
- }
- return 0;
-}
-#endif /* ALLOW_POLL */
-
-#endif
OpenPOWER on IntegriCloud