summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/sound/soundcard.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/sound/soundcard.c')
-rw-r--r--sys/i386/isa/sound/soundcard.c684
1 files changed, 0 insertions, 684 deletions
diff --git a/sys/i386/isa/sound/soundcard.c b/sys/i386/isa/sound/soundcard.c
deleted file mode 100644
index 3b6db0b..0000000
--- a/sys/i386/isa/sound/soundcard.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * sound/386bsd/soundcard.c
- *
- * Soundcard driver for 386BSD.
- *
- * 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 "opt_devfs.h"
-
-#include <i386/isa/sound/sound_config.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /* DEVFS */
-
-#if NSND > 0 /* from "snd.h" */
-#include "uart.h"
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <sys/mman.h>
-
-#include <i386/isa/isa_device.h>
-
-
-/*
-** Register definitions for DMA controller 1 (channels 0..3):
-*/
-#define DMA1_CHN(c) (IO_DMA1 + 1*(2*(c))) /* addr reg for channel c */
-#define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */
-#define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */
-#define DMA1_FFC (IO_DMA1 + 1*12) /* clear first/last FF */
-
-/*
-** Register definitions for DMA controller 2 (channels 4..7):
-*/
-#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */
-#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */
-#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
-#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
-
-
-#define FIX_RETURN(ret) {if ((ret)<0) return -(ret); else return 0;}
-
-static int soundcards_installed = 0; /* Number of installed soundcards */
-static int soundcard_configured = 0;
-
-static struct fileinfo files[SND_NDEVS];
-struct selinfo selinfo[SND_NDEVS >> 4];
-
-int
-MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait);
-
-int
-audio_poll(int dev, struct fileinfo * file, int events, select_table * wait);
-
-int
-sequencer_poll (int dev, struct fileinfo *file, int events, select_table * wait);
-
-static int sndprobe __P((struct isa_device *));
-static int sndattach __P((struct isa_device *));
-static int sndmmap __P((dev_t dev, int offset, int nprot ));
-
-static d_open_t sndopen;
-static d_close_t sndclose;
-static d_ioctl_t sndioctl;
-static d_read_t sndread;
-static d_write_t sndwrite;
-static d_poll_t sndpoll;
-
-static char driver_name[] = "snd";
-
-#define CDEV_MAJOR 30
-static struct cdevsw snd_cdevsw = {
- sndopen, sndclose, sndread, sndwrite,
- sndioctl, nostop, noreset, nodevtotty,
- sndpoll, sndmmap, nostrategy, driver_name,
- NULL, -1,
-};
-
-
-
-
-static void sound_mem_init(void);
-
-/*
- * for each "device XXX" entry in the config file, we have
- * a struct isa_driver which is linked into isa_devtab_null[]
- *
- * XXX It is a bit stupid to call the generic routine so many times and
- * switch then to the specific one, but the alternative way would be
- * to replicate some code in the probe/attach routines.
- */
-
-struct isa_driver opldriver = {sndprobe, sndattach, "opl"};
-struct isa_driver trixdriver = {sndprobe, sndattach, "trix"};
-struct isa_driver trixsbdriver = {sndprobe, sndattach, "trixsb"};
-struct isa_driver sbdriver = {sndprobe, sndattach, "sb"};
-struct isa_driver sbxvidriver = {sndprobe, sndattach, "sbxvi"};
-struct isa_driver sbmididriver = {sndprobe, sndattach, "sbmidi"};
-struct isa_driver awedriver = {sndprobe, sndattach, "awe"};
-struct isa_driver pasdriver = {sndprobe, sndattach, "pas"};
-struct isa_driver mpudriver = {sndprobe, sndattach, "mpu"};
-struct isa_driver gusdriver = {sndprobe, sndattach, "gus"};
-struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"};
-struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"};
-struct isa_driver uartdriver = {sndprobe, sndattach, "uart"};
-struct isa_driver mssdriver = {sndprobe, sndattach, "mss"};
-struct isa_driver cssdriver = {sndprobe, sndattach, "css"};
-struct isa_driver sscapedriver = {sndprobe, sndattach, "sscape"};
-struct isa_driver sscape_mssdriver = {sndprobe, sndattach, "sscape_mss"};
-
-short ipri_to_irq(u_short ipri);
-
-static ointhand2_t sndintr;
-
-u_long
-get_time(void)
-{
- struct timeval timecopy;
-
- getmicrotime(&timecopy);
- return timecopy.tv_usec / (1000000 / hz) +
- (u_long) timecopy.tv_sec * hz;
-}
-
-static int
-sndmmap( dev_t dev, int offset, int nprot )
-{
- struct dma_buffparms * dmap;
-
- dev = minor(dev) >> 4;
- if (dev > 0 ) return (-1);
-
- dmap = audio_devs[dev]->dmap_out;
-
- if (nprot & PROT_EXEC)
- return( -1 );
- dmap->mapping_flags |= DMA_MAP_MAPPED ;
- return( i386_btop(vtophys(dmap->raw_buf) + offset) );
-}
-
-
-static int
-sndread(dev_t dev, struct uio * buf, int flag)
-{
- int count = buf->uio_resid;
-
- dev = minor(dev);
- FIX_RETURN(sound_read_sw(dev, &files[dev], buf, count));
-}
-
-
-static int
-sndwrite(dev_t dev, struct uio * buf, int flag)
-{
- int count = buf->uio_resid;
-
- dev = minor(dev);
- FIX_RETURN(sound_write_sw(dev, &files[dev], buf, count));
-}
-
-static int
-sndopen(dev_t dev, int flags, int mode, struct proc * p)
-{
- int retval;
- struct fileinfo tmp_file;
-
- dev = minor(dev);
- if (!soundcard_configured && dev) {
- printf("SoundCard Error: soundcard system has not been configured\n");
- return ENODEV ;
- }
- tmp_file.mode = 0;
-
- if (flags & FREAD && flags & FWRITE)
- tmp_file.mode = OPEN_READWRITE;
- else if (flags & FREAD)
- tmp_file.mode = OPEN_READ;
- else if (flags & FWRITE)
- tmp_file.mode = OPEN_WRITE;
-
- selinfo[dev >> 4].si_pid = 0;
- selinfo[dev >> 4].si_flags = 0;
- if ((retval = sound_open_sw(dev, &tmp_file)) < 0)
- FIX_RETURN(retval);
-
- bcopy((char *) &tmp_file, (char *) &files[dev], sizeof(tmp_file));
-
- FIX_RETURN(retval);
-}
-
-
-static int
-sndclose(dev_t dev, int flags, int mode, struct proc * p)
-{
- dev = minor(dev);
- sound_release_sw(dev, &files[dev]);
-
- return 0 ;
-}
-
-static int
-sndioctl(dev_t dev, u_long cmd, caddr_t arg, int mode, struct proc * p)
-{
- dev = minor(dev);
- FIX_RETURN(sound_ioctl_sw(dev, &files[dev], cmd, arg));
-}
-
-int
-sndpoll(dev_t dev, int events, struct proc * p)
-{
- dev = minor(dev);
- dev = minor(dev);
-
- /* printf ("snd_select(dev=%d, rw=%d, pid=%d)\n", dev, rw, p->p_pid); */
-#ifdef ALLOW_POLL
- switch (dev & 0x0f) {
-#ifdef CONFIG_SEQUENCER
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_poll(dev, &files[dev], events, p);
- break;
-#endif
-
-#ifdef CONFIG_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_poll(dev, &files[dev], events, p);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
-
- return audio_poll(dev, &files[dev], events, p);
- break;
-#endif
-
- default:
- return 0;
- }
-
-#endif /* ALLOW_POLL */
- DEB(printf("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
-
- return 0 ;
-}
-
-/* XXX this should become ffs(ipri), perhaps -1 lr 970705 */
-short
-ipri_to_irq(u_short ipri)
-{
- /*
- * Converts the ipri (bitmask) to the corresponding irq number
- */
- int irq;
-
- for (irq = 0; irq < 16; irq++)
- if (ipri == (1 << irq))
- return irq;
-
- return -1; /* Invalid argument */
-}
-
-static int
-driver_to_voxunit(struct isa_driver * driver)
-{
- /*
- * converts a sound driver pointer into the equivalent VoxWare device
- * unit number
- */
- if (driver == &opldriver)
- return (SNDCARD_ADLIB);
- else if (driver == &sbdriver)
- return (SNDCARD_SB);
- else if (driver == &pasdriver)
- return (SNDCARD_PAS);
- else if (driver == &gusdriver)
- return (SNDCARD_GUS);
- else if (driver == &mpudriver)
- return (SNDCARD_MPU401);
- else if (driver == &sbxvidriver)
- return (SNDCARD_SB16);
- else if (driver == &sbmididriver)
- return (SNDCARD_SB16MIDI);
- else if(driver == &awedriver)
- return(SNDCARD_AWE32);
- else if (driver == &uartdriver)
- return (SNDCARD_UART6850);
- else if (driver == &gusdriver)
- return (SNDCARD_GUS16);
- else if (driver == &mssdriver)
- return (SNDCARD_MSS);
- else if (driver == &cssdriver)
- return (SNDCARD_CS4232);
- else if (driver == &sscapedriver)
- return(SNDCARD_SSCAPE);
- else if (driver == &sscape_mssdriver)
- return(SNDCARD_SSCAPE_MSS);
- else if (driver == &trixdriver)
- return (SNDCARD_TRXPRO);
- else if (driver == &trixsbdriver)
- return (SNDCARD_TRXPRO_SB);
- else
- return (0);
-}
-
-/*
- * very dirty: tmp_osp is allocated in sndprobe, and used at the next
- * call in sndattach
- */
-
-static sound_os_info *temp_osp;
-
-/*
- * sndprobe is called for each isa_device. From here, a voxware unit
- * number is determined, and the appropriate probe routine is selected.
- * The parameters from the config line are passed to the hw_config struct.
- */
-
-static int
-sndprobe(struct isa_device * dev)
-{
- struct address_info hw_config;
- int unit;
-
- temp_osp = (sound_os_info *)malloc(sizeof(sound_os_info),
- M_DEVBUF, M_NOWAIT);
- if (!temp_osp)
- panic("SOUND: Cannot allocate memory\n");
-
- /*
- * get config info from the kernel config. These may be overridden
- * by the local autoconfiguration routines though (e.g. pnp stuff).
- */
-
- hw_config.io_base = dev->id_iobase;
- hw_config.irq = ipri_to_irq(dev->id_irq);
- hw_config.dma = dev->id_drq;
-
- /*
- * misuse the flags field for read dma. Note that, to use 0 as
- * read dma channel, one of the high bits should be set. lr970705 XXX
- */
-
- if (dev->id_flags != 0)
- hw_config.dma2 = dev->id_flags & 0x7;
- else
- hw_config.dma2 = -1;
-
- hw_config.always_detect = 0;
- hw_config.name = NULL;
- hw_config.card_subtype = 0;
-
- temp_osp->unit = dev->id_unit;
- hw_config.osp = temp_osp;
- unit = driver_to_voxunit(dev->id_driver);
-
- if (sndtable_probe(unit, &hw_config)) {
- dev->id_iobase = hw_config.io_base;
- dev->id_irq = hw_config.irq == -1 ? 0 : (1 << hw_config.irq);
- dev->id_drq = hw_config.dma;
-
- if (hw_config.dma != hw_config.dma2 && ( hw_config.dma2 != -1))
- dev->id_flags = hw_config.dma2 | 0x100; /* XXX lr */
- else
- dev->id_flags = 0;
- return TRUE;
- }
- return 0;
-}
-
-static int
-sndattach(struct isa_device * dev)
-{
- int unit;
- static int midi_initialized = 0;
- static int seq_initialized = 0;
- struct address_info hw_config;
- char *dname;
- void *tmp;
-
- /*
- * Associate interrupt handlers with devices. XXX this may be incomplete.
- */
- dname = dev->id_driver->name;
-#if defined(CONFIG_AD1848)
- if (strcmp(dname, "css") == 0 || strcmp(dname, "gusxvi") == 0 ||
- strcmp(dname, "mss") == 0)
- dev->id_ointr = adintr;
-#endif
-#ifdef CONFIG_GUS
- if (strcmp(dname, "gus") == 0)
- dev->id_ointr = gusintr;
-#endif
-#ifdef CONFIG_PAS
- if (strcmp(dname, "pas") == 0)
- dev->id_ointr = pasintr;
-#endif
-#if NSB > 0 && (defined(CONFIG_MIDI) || defined(CONFIG_AUDIO))
- if (strcmp(dname, "sb") == 0)
- dev->id_ointr = sbintr;
-#endif
- if (strcmp(dname, "sscape_mss") == 0)
- dev->id_ointr = sndintr;
-#if NSSCAPE > 0
- if (strcmp(dname, "sscape") == 0 || strcmp(dname, "trix") == 0)
- dev->id_ointr = sscapeintr;
-#endif
-#if NUART > 0
- if (strcmp(dname, "uart0") == 0)
- dev->id_ointr = m6850intr;
-#endif
-
- unit = driver_to_voxunit(dev->id_driver);
- hw_config.io_base = dev->id_iobase;
- hw_config.irq = ipri_to_irq(dev->id_irq);
- hw_config.dma = dev->id_drq;
-
- /* misuse the flags field for read dma */
- if (dev->id_flags != 0)
- hw_config.dma2 = dev->id_flags & 0x7;
- else
- hw_config.dma2 = -1;
-
- hw_config.card_subtype = 0;
- hw_config.osp = temp_osp;
-
- if (!unit)
- return FALSE;
-
- if (!(sndtable_init_card(unit, &hw_config))) { /* init card */
- printf(" <Driver not configured>");
- return FALSE;
- }
- /*
- * Init the high level sound driver
- */
-
- if (!(soundcards_installed = sndtable_get_cardcount())) {
- DDB(printf("No drivers actually installed\n"));
- return FALSE; /* No cards detected */
- }
- printf("\n");
-
-#ifdef CONFIG_AUDIO
- if (num_audiodevs) { /* Audio devices present */
- DMAbuf_init();
- sound_mem_init();
- }
- soundcard_configured = 1;
-#endif
-
- if (num_midis && !midi_initialized)
- midi_initialized = 1;
-
- if ((num_midis + num_synths) && !seq_initialized) {
- seq_initialized = 1;
- sequencer_init();
- }
-
- {
- dev_t dev;
-
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev, &snd_cdevsw, NULL);
- }
-#ifdef DEVFS
-#define GID_SND GID_GAMES
-#define UID_SND UID_ROOT
-#define PERM_SND 0660
- /*
- * make links to first successfully probed device, don't do it if
- * duplicate creation of same node failed (ie. bad cookie returned)
- */
- if (dev->id_driver == &opldriver){
- tmp = devfs_add_devswf(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_SEQ,
- DV_CHR, UID_SND, GID_SND, PERM_SND,
- "sequencer%r", dev->id_unit);
- if (tmp) devfs_makelink(tmp, "sequencer");
- } else if (dev->id_driver == &mpudriver ||
- dev->id_driver == &sbmididriver ||
- dev->id_driver == &uartdriver){
- tmp = devfs_add_devswf(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_MIDIN,
- DV_CHR, UID_SND, GID_SND, PERM_SND,
- "midi%r", dev->id_unit);
- if (tmp) devfs_makelink(tmp, "midi");
- } else {
- tmp = devfs_add_devswf(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_DSP,
- DV_CHR, UID_SND, GID_SND, PERM_SND,
- "dsp%r", dev->id_unit);
- if (tmp) devfs_makelink(tmp, "dsp");
- tmp = devfs_add_devswf(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_DSP16,
- DV_CHR, UID_SND, GID_SND, PERM_SND,
- "dspW%r", dev->id_unit);
- if (tmp) devfs_makelink(tmp, "dspW");
- tmp = devfs_add_devswf(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_AUDIO,
- DV_CHR, UID_SND, GID_SND, PERM_SND,
- "audio%r", dev->id_unit);
- if (tmp) devfs_makelink(tmp, "audio");
- tmp = devfs_add_devswf(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_CTL,
- DV_CHR, UID_SND, GID_SND, PERM_SND,
- "mixer%r", dev->id_unit);
- if (tmp) devfs_makelink(tmp, "mixer");
- tmp = devfs_add_devswf(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_STATUS,
- DV_CHR, UID_SND, GID_SND, PERM_SND,
- "sndstat%r", dev->id_unit);
- if (tmp) devfs_makelink(tmp, "sndstat");
- }
-#endif /* DEVFS */
- return TRUE;
-}
-
-
-#ifdef CONFIG_AUDIO
-
-static void
-alloc_dmap(int dev, int chan, struct dma_buffparms * dmap)
-{
- char *tmpbuf;
- int i;
-
- tmpbuf = contigmalloc(audio_devs[dev]->buffsize, M_DEVBUF, M_NOWAIT,
- 0ul, 0xfffffful, 1ul, chan & 4 ? 0x20000ul : 0x10000ul);
- if (tmpbuf == NULL)
- printf("soundcard buffer alloc failed \n");
-
- if (tmpbuf == NULL) {
- printf("snd: Unable to allocate %d bytes of buffer\n",
- 2 * (int) audio_devs[dev]->buffsize);
- return;
- }
- dmap->raw_buf = tmpbuf;
- /*
- * Use virtual address as the physical address, since isa_dmastart
- * performs the phys address computation.
- */
-
- dmap->raw_buf_phys = (uintptr_t) tmpbuf;
- for (i = 0; i < audio_devs[dev]->buffsize; i++) *tmpbuf++ = 0x80;
-
-}
-
-static void
-sound_mem_init(void)
-{
- int dev;
- static u_long dsp_init_mask = 0;
-
- for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */
- if (!(dsp_init_mask & (1 << dev))) /* Not already done */
- if (audio_devs[dev]->dmachan1 >= 0) {
- dsp_init_mask |= (1 << dev);
- audio_devs[dev]->buffsize = DSP_BUFFSIZE;
- /* Now allocate the buffers */
- alloc_dmap(dev, audio_devs[dev]->dmachan1,
- audio_devs[dev]->dmap_out);
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- alloc_dmap(dev, audio_devs[dev]->dmachan2,
- audio_devs[dev]->dmap_in);
- } /* for dev */
-}
-
-#endif
-
-
-int
-snd_ioctl_return(int *addr, int value)
-{
- if (value < 0)
- return value; /* Error */
- suword(addr, value);
- return 0;
-}
-
-#define MAX_UNIT 50
-typedef void (*irq_proc_t) (int irq);
-static irq_proc_t irq_proc[MAX_UNIT] = {NULL};
-static int irq_irq[MAX_UNIT] = {0};
-
-int
-snd_set_irq_handler(int int_lvl, void (*hndlr) (int), sound_os_info * osp)
-{
- if (osp->unit >= MAX_UNIT) {
- printf("Sound error: Unit number too high (%d)\n", osp->unit);
- return 0;
- }
- irq_proc[osp->unit] = hndlr;
- irq_irq[osp->unit] = int_lvl;
- return 1;
-}
-
-static void
-sndintr(int unit)
-{
- if ( (unit >= MAX_UNIT) || (irq_proc[unit] == NULL) )
- return;
-
- irq_proc[unit] (irq_irq[unit]); /* Call the installed handler */
-}
-
-void
-conf_printf(char *name, struct address_info * hw_config)
-{
- if (!trace_init)
- return;
-
- printf("snd0: <%s> ", name);
-#if 0
- if (hw_config->io_base != -1 )
- printf("at 0x%03x", hw_config->io_base);
-
- if (hw_config->irq != -1 )
- printf(" irq %d", hw_config->irq);
-
- if (hw_config->dma != -1 || hw_config->dma2 != -1) {
- printf(" dma %d", hw_config->dma);
- if (hw_config->dma2 != -1)
- printf(",%d", hw_config->dma2);
- }
-#endif
-
-}
-
-void
-conf_printf2(char *name, int base, int irq, int dma, int dma2)
-{
- if (!trace_init)
- return;
-
- printf("snd0: <%s> ", name);
-#if 0
- if (hw_config->io_base != -1 )
- printf("at 0x%03x", hw_config->io_base);
-
- if (irq)
- printf(" irq %d", irq);
-
- if (dma != -1 || dma2 != -1) {
- printf(" dma %d", dma);
- if (dma2 != -1)
- printf(",%d", dma2);
- }
-#endif
-
-}
-
-
-void tenmicrosec (int j)
-{
- int i, k;
- for (k = 0; k < j/10 ; k++) {
- for (i = 0; i < 16; i++)
- inb (0x80);
- }
-}
-
-#endif /* NSND > 0 */
-
-
-
-
OpenPOWER on IntegriCloud