these belong in dev/isa; they're being moved there now.

This commit is contained in:
cgd 1995-04-17 15:22:27 +00:00
parent c0caf19aac
commit cf1c3ea213
13 changed files with 0 additions and 7641 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,201 +0,0 @@
/* $NetBSD: ad1848reg.h,v 1.1 1995/02/21 02:26:41 brezak Exp $ */
/*
* Copyright (c) 1994 John Brezak
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: ad1848reg.h,v 1.1 1995/02/21 02:26:41 brezak Exp $
*/
/*
* Copyright (c) 1993 Analog Devices Inc. All rights reserved
*/
#define AD1848_BASE_VALID(base) ((base) == 0x530)
/* ad1848 direct registers */
#define AD1848_IADDR 0x04
#define AD1848_IDATA 0x05
#define AD1848_STATUS 0x06
#define AD1848_PIO 0x07
/* Gain constants */
#define GAIN_0 0x00
#define GAIN_1_5 0x01
#define GAIN_3 0x02
#define GAIN_4_5 0x03
#define GAIN_6 0x04
#define GAIN_7_5 0x05
#define GAIN_9 0x06
#define GAIN_10_5 0x07
#define GAIN_12 0x08
#define GAIN_13_5 0x09
#define GAIN_15 0x0a
#define GAIN_16_5 0x0b
#define GAIN_18 0x0c
#define GAIN_19_5 0x0d
#define GAIN_21 0x0e
#define GAIN_22_5 0x0f
#define MUTE 0XFFFF
/* Attenuation constants */
#define ATTEN_0 0x00
#define ATTEN_1_5 0x01
#define ATTEN_3 0x02
#define ATTEN_4_5 0x03
#define ATTEN_6 0x04
#define ATTEN_7_5 0x05
#define ATTEN_9 0x06
#define ATTEN_10_5 0x07
#define ATTEN_12 0x08
#define ATTEN_13_5 0x09
#define ATTEN_15 0x0a
#define ATTEN_16_5 0x0b
#define ATTEN_18 0x0c
#define ATTEN_19_5 0x0d
#define ATTEN_21 0x0e
#define ATTEN_22_5 0x0f
/* 1848 Sound Port bit defines */
#define SP_IN_INIT 0x80
#define MODE_CHANGE_ENABLE 0x40
#define MODE_CHANGE_MASK 0xbf
#define TRANSFER_DISABLE 0x20
#define TRANSFER_DISABLE_MASK 0xdf
#define ADDRESS_MASK 0xf0
/* Status bits */
#define INTERRUPT_STATUS 0x01
#define PLAYBACK_READY 0x02
#define PLAYBACK_LEFT 0x04
/* pbright is not left */
#define PLAYBACK_UPPER 0x08
/* bplower is not upper */
#define SAMPLE_OVERRUN 0x10
#define SAMPLE_UNDERRUN 0x10
#define CAPTURE_READY 0x20
#define CAPTURE_LEFT 0x40
/* cpright is not left */
#define CAPTURE_UPPER 0x08
/* cplower is not upper */
/* Input & Output regs bits */
#define LINE_INPUT 0x00
#define AUX_INPUT 0x40
#define MIC_INPUT 0x80
#define MIXED_DAC_INPUT 0xC0
#define INPUT_GAIN_MASK 0xf0
#define INPUT_MIC_GAIN_ENABLE 0x20
#define INPUT_MIC_GAIN_MASK 0xdf
#define INPUT_SOURCE_MASK 0x3f
#define AUX_INPUT_ATTEN_BITS 0x1f
#define AUX_INPUT_ATTEN_MASK 0xe0
#define AUX_INPUT_MUTE 0x80
#define AUX_INPUT_MUTE_MASK 0x7f
#define OUTPUT_MUTE 0x80
#define OUTPUT_MUTE_MASK 0x7f
#define OUTPUT_ATTEN_BITS 0x3f
#define OUTPUT_ATTEN_MASK 0xc0
/* Clock and Data format reg bits */
#define CLOCK_SELECT_MASK 0xfe
#define CLOCK_XTAL2 0x01
#define CLOCK_XTAL1 0x00
#define CLOCK_FREQ_MASK 0xf1
#define STEREO_MONO_MASK 0xef
#define FMT_STEREO 0x10
#define RMT_MONO 0x00
#define LINEAR_COMP_MASK 0xdf
#define LINEAR 0x00
#define COMPANDED 0x20
#define FORMAT_MASK 0xbf
#define PCM 0x00
#define ULAW 0x00
#define TWOS_COMP 0x40
#define ALAW 0x40
/* Interface Configuration reg bits */
#define PLAYBACK_ENABLE 0x01
#define PLAYBACK_ENABLE_MASK 0xfe
#define CAPTURE_ENABLE 0x02
#define CAPTURE_ENABLE_MASK 0xfd
#define SINGLE_DMA 0x04
#define SINGLE_DMA_MASK 0xfb
#define DUAL_DMA 0x00
#define AUTO_CAL_ENABLE 0x08
#define AUTO_CAL_DISABLE_MASK 0xf7
#define PLAYBACK_PIO_ENABLE 0x40
#define PLAYBACK_DMA_MASK 0xbf
#define CAPTURE_PIO_ENABLE 0x80
#define CAPTURE_DMA_MASK 0x7f
/* Pin control bits */
#define INTERRUPT_ENABLE 0x02
#define INTERRUPT_MASK 0xfd
#define XCTL0_ENABLE 0x40
#define XCTL1_ENABLE 0x80
/* Test and init reg bits */
#define OVERRANGE_LEFT_MASK 0xfc
#define OVERRANGE_RIGHT_MASK 0xf3
#define DATA_REQUEST_STATUS 0x10
#define AUTO_CAL_IN_PROG 0x20
#define PLAYBACK_UNDERRUN 0x40
#define CAPTURE_UNDERRUN 0x80
/* Miscellaneous Control reg bits */
#define ID_MASK 0xf0
/* Digital Mix Control reg bits */
#define DIGITAL_MIX1_MUTE_MASK 0xfe
#define DIGITAL_MIX1_ENABLE 0x01
#define MIX_ATTEN_MASK 0xfc
/* 1848 Sound Port reg defines */
#define SP_LEFT_INPUT_CONTROL 0x0
#define SP_RIGHT_INPUT_CONTROL 0x1
#define SP_LEFT_AUX1_CONTROL 0x2
#define SP_RIGHT_AUX1_CONTROL 0x3
#define SP_LEFT_AUX2_CONTROL 0x4
#define SP_RIGHT_AUX2_CONTROL 0x5
#define SP_LEFT_OUTPUT_CONTROL 0x6
#define SP_RIGHT_OUTPUT_CONTROL 0x7
#define SP_CLOCK_DATA_FORMAT 0x8
#define SP_INTERFACE_CONFIG 0x9
#define SP_PIN_CONTROL 0xA
#define SP_TEST_AND_INIT 0xB
#define SP_MISC_INFO 0xC
#define SP_DIGITAL_MIX 0xD
#define SP_UPPER_BASE_COUNT 0xE
#define SP_LOWER_BASE_COUNT 0xF

View File

@ -1,153 +0,0 @@
/* $NetBSD: ad1848var.h,v 1.4 1995/04/17 12:06:57 cgd Exp $ */
/*
* Copyright (c) 1994 John Brezak
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: ad1848var.h,v 1.4 1995/04/17 12:06:57 cgd Exp $
*/
#define AD1848_NPORT 8
struct ad1848_volume {
u_char left;
u_char right;
};
struct ad1848_softc {
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
void *sc_ih; /* interrupt vectoring */
void *parent;
u_short sc_locked; /* true when doing HS DMA */
u_int sc_lastcc; /* size of last DMA xfer */
int sc_mode; /* half-duplex record/play */
#ifndef NEWCONFIG
int sc_dma_flags;
void *sc_dma_bp;
u_int sc_dma_cnt;
#endif
u_short sc_iobase; /* I/O port base address */
u_short sc_irq; /* interrupt */
u_short sc_drq; /* DMA */
u_long sc_irate; /* Sample rate for input */
u_long sc_orate; /* ...and output */
/* We keep track of these */
struct ad1848_volume rec_gain, aux1_gain, aux2_gain, out_gain, mon_gain;
u_int encoding; /* ulaw/linear -- keep track */
u_int precision; /* 8/16 bits */
int rec_port; /* recording port */
int channels;
/* ad1848 */
u_char MCE_bit;
char *chip_name;
int rev;
int mode;
int speed;
u_char speed_bits;
u_char format_bits;
u_long sc_interrupts; /* number of interrupts taken */
void (*sc_intr)(void *); /* dma completion intr handler */
void *sc_arg; /* arg for sc_intr() */
};
/*
* Ad1848 ports
*/
#define MIC_IN_PORT 0
#define LINE_IN_PORT 1
#define AUX1_IN_PORT 2
#define DAC_IN_PORT 3
#ifdef _KERNEL
int ad1848_probe __P((struct ad1848_softc *));
void ad1848_attach __P((struct ad1848_softc *));
int ad1848_open __P((struct ad1848_softc *, dev_t, int));
void ad1848_close __P((void *));
void ad1848_forceintr __P((struct ad1848_softc *));
int ad1848_set_in_sr __P((void *, u_long));
u_long ad1848_get_in_sr __P((void *));
int ad1848_set_out_sr __P((void *, u_long));
u_long ad1848_get_out_sr __P((void *));
int ad1848_query_encoding __P((void *, struct audio_encoding *));
int ad1848_set_encoding __P((void *, u_int));
int ad1848_get_encoding __P((void *));
int ad1848_set_precision __P((void *, u_int));
int ad1848_get_precision __P((void *));
int ad1848_set_channels __P((void *, int));
int ad1848_get_channels __P((void *));
int ad1848_round_blocksize __P((void *, int));
int ad1848_dma_output __P((void *, void *, int, void (*)(), void*));
int ad1848_dma_input __P((void *, void *, int, void (*)(), void*));
int ad1848_commit_settings __P((void *));
u_int ad1848_get_silence __P((int));
int ad1848_halt_in_dma __P((void *));
int ad1848_halt_out_dma __P((void *));
int ad1848_cont_in_dma __P((void *));
int ad1848_cont_out_dma __P((void *));
int ad1848_intr __P((void *));
int ad1848_set_rec_port __P((struct ad1848_softc *, int));
int ad1848_get_rec_port __P((struct ad1848_softc *));
int ad1848_set_aux1_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_get_aux1_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_set_aux2_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_get_aux2_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_set_out_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_get_out_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_set_rec_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_get_rec_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_set_mon_gain __P((struct ad1848_softc *, struct ad1848_volume *));
int ad1848_get_mon_gain __P((struct ad1848_softc *, struct ad1848_volume *));
#endif

View File

@ -1,495 +0,0 @@
/* $NetBSD: pas.c,v 1.5 1995/04/17 12:07:23 cgd Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: pas.c,v 1.5 1995/04/17 12:07:23 cgd Exp $
*/
/*
* Todo:
* - look at other PAS drivers (for PAS native suport)
* - use common sb.c once emulation is setup
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/proc.h>
#include <machine/cpu.h>
#include <machine/pio.h>
#include <sys/audioio.h>
#include <dev/audio_if.h>
#include <dev/isa/isavar.h>
#include <dev/isa/isadmavar.h>
#include <i386/isa/icu.h>
#include <i386/isa/sbdspvar.h>
#include <i386/isa/sbreg.h>
#define DEFINE_TRANSLATIONS
#include <i386/isa/pasreg.h>
#define DEBUG /*XXX*/
#ifdef DEBUG
#define DPRINTF(x) if (pasdebug) printf x
int pasdebug = 0;
#else
#define DPRINTF(x)
#endif
/*
* Software state, per SoundBlaster card.
* The soundblaster has multiple functionality, which we must demultiplex.
* One approach is to have one major device number for the soundblaster card,
* and use different minor numbers to indicate which hardware function
* we want. This would make for one large driver. Instead our approach
* is to partition the design into a set of drivers that share an underlying
* piece of hardware. Most things are hard to share, for example, the audio
* and midi ports. For audio, we might want to mix two processes' signals,
* and for midi we might want to merge streams (this is hard due to
* running status). Moreover, we should be able to re-use the high-level
* modules with other kinds of hardware. In this module, we only handle the
* most basic communications with the sb card.
*/
struct pas_softc {
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
void *sc_ih; /* interrupt vectoring */
u_short sc_iobase; /* PAS iobase */
u_short sc_irq; /* PAS irq */
u_short sc_drq; /* PAS drq */
int model;
int rev;
struct sbdsp_softc sc_sbdsp;
};
int pasopen __P((dev_t, int));
int pasprobe();
void pasattach();
int pas_getdev __P((void *, struct audio_device *));
/*
* Define our interface to the higher level audio driver.
*/
struct audio_hw_if pas_hw_if = {
pasopen,
sbdsp_close,
NULL,
sbdsp_set_in_sr,
sbdsp_get_in_sr,
sbdsp_set_out_sr,
sbdsp_get_out_sr,
sbdsp_query_encoding,
sbdsp_set_encoding,
sbdsp_get_encoding,
sbdsp_set_precision,
sbdsp_get_precision,
sbdsp_set_channels,
sbdsp_get_channels,
sbdsp_round_blocksize,
sbdsp_set_out_port,
sbdsp_get_out_port,
sbdsp_set_in_port,
sbdsp_get_in_port,
sbdsp_commit_settings,
sbdsp_get_silence,
sbdsp_expand,
sbdsp_compress,
sbdsp_dma_output,
sbdsp_dma_input,
sbdsp_haltdma,
sbdsp_haltdma,
sbdsp_contdma,
sbdsp_contdma,
sbdsp_speaker_ctl,
pas_getdev,
sbdsp_setfd,
sbdsp_mixer_set_port,
sbdsp_mixer_get_port,
sbdsp_mixer_query_devinfo,
0, /* not full-duplex */
0
};
/* The Address Translation code is used to convert I/O register addresses to
be relative to the given base -register */
static char *pasnames[] = {
"",
"Plus",
"CDPC",
"16",
"16Basic"
};
static struct audio_device pas_device = {
"PAS,??",
"",
"pas"
};
/*XXX assume default I/O base address */
#define pasread(p) inb(p)
#define paswrite(d, p) outb(p, d)
void
pasconf(int model, int sbbase, int sbirq, int sbdrq)
{
int i;
paswrite(0x00, INTERRUPT_MASK);
/* Local timer control register */
paswrite(0x36, SAMPLE_COUNTER_CONTROL);
/* Sample rate timer (16 bit) */
paswrite(0x36, SAMPLE_RATE_TIMER);
paswrite(0, SAMPLE_RATE_TIMER);
/* Local timer control register */
paswrite(0x74, SAMPLE_COUNTER_CONTROL);
/* Sample count register (16 bit) */
paswrite(0x74, SAMPLE_BUFFER_COUNTER);
paswrite(0, SAMPLE_BUFFER_COUNTER);
paswrite(P_C_PCM_MONO | P_C_PCM_DAC_MODE |
P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R,
PCM_CONTROL);
paswrite(S_M_PCM_RESET | S_M_FM_RESET |
S_M_SB_RESET | S_M_MIXER_RESET, SERIAL_MIXER);
/*XXX*/
paswrite(I_C_1_BOOT_RESET_ENABLE|1, IO_CONFIGURATION_1);
paswrite(I_C_2_PCM_DMA_DISABLED, IO_CONFIGURATION_2);
paswrite(I_C_3_PCM_IRQ_DISABLED, IO_CONFIGURATION_3);
#ifdef BROKEN_BUS_CLOCK
paswrite(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND |
S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
#else
paswrite(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND,
SYSTEM_CONFIGURATION_1);
#endif
/*XXX*/
paswrite(0, SYSTEM_CONFIGURATION_2);
paswrite(0, SYSTEM_CONFIGURATION_3);
/* Sets mute off and selects filter rate of 17.897 kHz */
paswrite(F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY);
if (model == PAS_16 || model == PAS_16BASIC)
paswrite(8, PRESCALE_DIVIDER);
else
paswrite(0, PRESCALE_DIVIDER);
paswrite(P_M_MV508_ADDRESS | P_M_MV508_PCM, PARALLEL_MIXER);
paswrite(5, PARALLEL_MIXER);
/*
* Setup SoundBlaster emulation.
*/
paswrite((sbbase >> 4) & 0xf, EMULATION_ADDRESS);
paswrite(E_C_SB_IRQ_translate[sbirq] | E_C_SB_DMA_translate[sbdrq],
EMULATION_CONFIGURATION);
paswrite(C_E_SB_ENABLE, COMPATIBILITY_ENABLE);
/*
* Set mid-range levels.
*/
paswrite(P_M_MV508_ADDRESS | P_M_MV508_MODE, PARALLEL_MIXER);
paswrite(P_M_MV508_LOUDNESS | P_M_MV508_ENHANCE_NONE, PARALLEL_MIXER);
paswrite(P_M_MV508_ADDRESS | P_M_MV508_MASTER_A, PARALLEL_MIXER);
paswrite(50, PARALLEL_MIXER);
paswrite(P_M_MV508_ADDRESS | P_M_MV508_MASTER_B, PARALLEL_MIXER);
paswrite(50, PARALLEL_MIXER);
paswrite(P_M_MV508_ADDRESS | P_M_MV508_MIXER | P_M_MV508_SB, PARALLEL_MIXER);
paswrite(P_M_MV508_OUTPUTMIX | 30, PARALLEL_MIXER);
paswrite(P_M_MV508_ADDRESS | P_M_MV508_MIXER | P_M_MV508_MIC, PARALLEL_MIXER);
paswrite(P_M_MV508_INPUTMIX | 30, PARALLEL_MIXER);
}
struct cfdriver pascd = {
NULL, "pas", pasprobe, pasattach, DV_DULL, sizeof(struct pas_softc)
};
/*
* Probe / attach routines.
*/
/*
* Probe for the soundblaster hardware.
*/
int
pasprobe(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct pas_softc *sc = (void *)self;
register struct isa_attach_args *ia = aux;
register u_short iobase;
u_char id, t;
/*
* WARNING: Setting an option like W:1 or so that disables
* warm boot reset of the card will screw up this detect code
* something fierce. Adding code to handle this means possibly
* interfering with other cards on the bus if you have something
* on base port 0x388. SO be forewarned.
*/
/* Talk to first board */
outb(MASTER_DECODE, 0xbc);
/* Set base address */
#if 0
/* XXX Need to setup pseudo device */
/* XXX What are good io addrs ? */
if (iobase != PAS_DEFAULT_BASE) {
printf("pas: configured iobase %d invalid\n", iobase);
return 0;
}
#else
/* Start out talking to native PAS */
iobase = PAS_DEFAULT_BASE;
#endif
outb(MASTER_DECODE, iobase >> 2);
/* One wait-state */
paswrite(1, WAIT_STATE);
id = pasread(INTERRUPT_MASK);
if (id == 0xff || id == 0xfe) {
/* sanity */
DPRINTF(("pas: bogus card id\n"));
return 0;
}
/*
* We probably have a PAS-series board, now check for a
* PAS2-series board by trying to change the board revision
* bits. PAS2-series hardware won't let you do this because
* the bits are read-only.
*/
t = id ^ 0xe0;
paswrite(t, INTERRUPT_MASK);
t = inb(INTERRUPT_MASK);
paswrite(id, INTERRUPT_MASK);
if (t != id) {
/* Not a PAS2 */
printf("pas: detected card but PAS2 test failed\n");
return 0;
}
/*XXX*/
t = pasread(OPERATION_MODE_1) & 0xf;
sc->model = O_M_1_to_card[t];
if (sc->model != 0) {
sc->rev = pasread(BOARD_REV_ID);
}
else {
DPRINTF(("pas: bogus model id\n"));
return 0;
}
if (sc->model >= 0) {
int irq = ia->ia_irq;
if (irq == IRQUNK) {
printf("pas: sb emulation requires known irq\n");
return (0);
}
irq = ia->ia_irq;
pasconf(sc->model, ia->ia_iobase, irq, 1);
} else {
DPRINTF(("pas: could not probe pas\n"));
return (0);
}
/* Now a SoundBlaster */
sc->sc_iobase = ia->ia_iobase;
/* and set the SB iobase into the DSP as well ... */
sc->sc_sbdsp.sc_iobase = ia->ia_iobase;
if (sbdsp_reset(&sc->sc_sbdsp) < 0) {
DPRINTF(("pas: couldn't reset card\n"));
return 0;
}
/*
* Cannot auto-discover DMA channel.
*/
if (!SB_DRQ_VALID(ia->ia_drq)) {
printf("pas: configured dma chan %d invalid\n", ia->ia_drq);
return 0;
}
#ifdef NEWCONFIG
/*
* If the IRQ wasn't compiled in, auto-detect it.
*/
if (ia->ia_irq == IRQUNK) {
ia->ia_irq = isa_discoverintr(pasforceintr, aux);
sbdsp_reset(&sc->sc_sbdsp);
if (!SB_IRQ_VALID(ia->ia_irq)) {
printf("pas: couldn't auto-detect interrupt");
return 0;
}
} else
#endif
if (!SB_IRQ_VALID(ia->ia_irq)) {
int irq = ia->ia_irq;
printf("pas: configured irq %d invalid\n", irq);
return 0;
}
sc->sc_sbdsp.sc_irq = ia->ia_irq;
sc->sc_sbdsp.sc_drq = ia->ia_drq;
if (sbdsp_probe(&sc->sc_sbdsp) == 0) {
DPRINTF(("pas: sbdsp probe failed\n"));
return 0;
}
ia->ia_iosize = SB_NPORT;
return 1;
}
#ifdef NEWCONFIG
void
pasforceintr(aux)
void *aux;
{
static char dmabuf;
struct isa_attach_args *ia = aux;
u_short iobase = ia->ia_iobase;
/*
* Set up a DMA read of one byte.
* XXX Note that at this point we haven't called
* at_setup_dmachan(). This is okay because it just
* allocates a buffer in case it needs to make a copy,
* and it won't need to make a copy for a 1 byte buffer.
* (I think that calling at_setup_dmachan() should be optional;
* if you don't call it, it will be called the first time
* it is needed (and you pay the latency). Also, you might
* never need the buffer anyway.)
*/
at_dma(1, &dmabuf, 1, ia->ia_drq);
if (pas_wdsp(iobase, SB_DSP_RDMA) == 0) {
(void)pas_wdsp(iobase, 0);
(void)pas_wdsp(iobase, 0);
}
}
#endif
/*
* Attach hardware to driver, attach hardware driver to audio
* pseudo-device driver .
*/
void
pasattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct pas_softc *sc = (struct pas_softc *)self;
struct isa_attach_args *ia = (struct isa_attach_args *)aux;
register u_short iobase = ia->ia_iobase;
sc->sc_iobase = iobase;
#ifdef NEWCONFIG
isa_establish(&sc->sc_id, &sc->sc_dev);
#endif
sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_BIO,
sbdsp_intr, &sc->sc_sbdsp);
#ifdef NEWCONFIG
/*
* We limit DMA transfers to a page, and use the generic DMA handling
* code in isa.c. This code can end up copying a buffer, but since
* the audio driver uses relative small buffers this isn't likely.
*
* This allocation scheme means that the maximum transfer is limited
* by the page size (rather than 64k). This is reasonable. For 4K
* pages, the transfer time at 48KHz is 4096 / 48000 = 85ms. This
* is plenty long enough to amortize any fixed time overhead.
*/
at_setup_dmachan(sc->sc_dmachan, NBPG);
#endif
printf(" ProAudio Spectrum %s [rev %d] ", pasnames[sc->model], sc->rev);
sbdsp_attach(&sc->sc_sbdsp);
sprintf(pas_device.name, "pas,%s", pasnames[sc->model]);
sprintf(pas_device.version, "%d", sc->rev);
if (audio_hardware_attach(&pas_hw_if, &sc->sc_sbdsp) != 0)
printf("pas: could not attach to audio pseudo-device driver\n");
}
int
pasopen(dev, flags)
dev_t dev;
int flags;
{
struct pas_softc *sc;
int unit = AUDIOUNIT(dev);
if (unit >= pascd.cd_ndevs)
return ENODEV;
sc = pascd.cd_devs[unit];
if (!sc)
return ENXIO;
return sbdsp_open(&sc->sc_sbdsp, dev, flags);
}
int
pas_getdev(addr, retp)
void *addr;
struct audio_device *retp;
{
*retp = pas_device;
return 0;
}

View File

@ -1,254 +0,0 @@
/* $NetBSD: pasreg.h,v 1.2 1995/03/15 18:45:58 brezak Exp $ */
/* Port addresses and bit fields for the Media Vision Pro AudioSpectrum
* second generation sound cards.
*
* Feel free to use this header file in any application you create that
* has support for the Media Vision Pro AudioSpectrum second generation
* sound cards. Other uses prohibited without prior permission.
*
* - cmetz@thor.tjhsst.edu
*
* Notes:
*
* - All of these ports go into the MVD101 multimedia controller chip,
* which then signals the other chips to do the actual work. Many
* ports like the FM ones functionally attach directly to the
* destination chip though they don't actually have a direct connection.
* - The PAS2 series cards have an MVD101 multimedia controller chip,
* the original PAS cards don't. The original PAS cards are pretty
* defunct now, so no attempt is made here to support them.
* - The PAS2 series cards are all really different at the hardware level,
* though the MVD101 hides some of the incompatibilities, there still
* are differences that need to be accounted for.
*
* Card CD-ROM interface PCM chip Mixer chip FM chip
* PAS Plus Sony proprietary (Crystal?) 8-bit DAC National OPL3
* PAS 16 Zilog SCSI MVA416 16-bit Codec MVA508 OPL3
* CDPC Sony proprietary Sony 16-bit Codec National OPL3
* Fusion CD 16 Sony proprietary MVA416 16-bit Codec MVA508 OPL3
* Fusion CD Sony proprietary (Crystal?) 8-bit DAC National OPL3
*
*/
#define PAS_DEFAULT_BASE 0x388
/* Symbolic Name Value R W Subsystem Description */
#define SPEAKER_CONTROL 0x61 /* W PC speaker Control register */
#define SPEAKER_CONTROL_GHOST 0x738B /* R W PC speaker Control ghost register */
#define SPEAKER_TIMER_CONTROL 0x43 /* W PC speaker Timer control register */
#define SPEAKER_TIMER_CONTROL_GHOST 0x778B /* R W PC speaker Timer control register ghost */
#define SPEAKER_TIMER_DATA 0x42 /* W PC speaker Timer data register */
#define SPEAKER_TIMER_DATA_GHOST 0x138A /* R W PC speaker Timer data register ghost */
#define WARM_BOOT 0x41 /* W Control Used to detect system warm boot */
#define WARM_BOOT_GHOST 0x7789 /* ? W Control Use to get the card to fake warm boot */
#define MASTER_DECODE 0x9A01 /* W Control Address >> 2 of card base address */
#define PRESCALE_DIVIDER 0xBF8A /* R W PCM Ration between Codec clock and master clock */
#define WAIT_STATE 0xBF88 /* R W Control Four-bit bus wait-state count (~140ns ea.) */
#define BOARD_REV_ID 0x2789 /* R Control Extended Board Revision ID */
#define SYSTEM_CONFIGURATION_1 0x8388 /* R W Control */
#define S_C_1_PCS_ENABLE 0x01 /* R W PC speaker 1=enable, 0=disable PC speaker emulation */
#define S_C_1_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=14.31818Mhz/12, 0=28.224Mhz master clock */
#define S_C_1_FM_EMULATE_CLOCK 0x04 /* R W FM 1=use 28.224Mhz/2, 0=use 14.31818Mhz clock */
#define S_C_1_PCS_STEREO 0x10 /* R W PC speaker 1=enable PC speaker stereo effect, 0=disable */
#define S_C_1_PCS_REALSOUND 0x20 /* R W PC speaker 1=enable RealSound enhancement, 0=disable */
#define S_C_1_FORCE_EXT_RESET 0x40 /* R W Control Force external reset */
#define S_C_1_FORCE_INT_RESET 0x80 /* R W Control Force internal reset */
#define SYSTEM_CONFIGURATION_2 0x8389 /* R W Control */
#define S_C_2_PCM_OVERSAMPLING 0x03 /* R W PCM 00=0x, 01=2x, 10=4x, 11=reserved */
#define S_C_2_PCM_16_BIT 0x04 /* R W PCM 1=16-bit, 0=8-bit samples */
#define SYSTEM_CONFIGURATION_3 0x838A /* R W Control */
#define S_C_3_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=use 1.008Mhz clock for PCM, 0=don't */
#define SYSTEM_CONFIGURATION_4 0x838B /* R W Control CD-ROM interface controls */
#define IO_CONFIGURATION_1 0xF388 /* R W Control */
#define I_C_1_BOOT_RESET_ENABLE 0x80 /* R W Control 1=reset board on warm boot, 0=don't */
#define IO_CONFIGURATION_2 0xF389 /* R W Control */
#define I_C_2_PCM_DMA_DISABLED 0x00 /* R W PCM PCM DMA disabled */
#define IO_CONFIGURATION_3 0xF38A /* R W Control */
#define I_C_3_PCM_IRQ_DISABLED 0x00 /* R W PCM PCM IRQ disabled */
#define COMPATIBILITY_ENABLE 0xF788 /* R W Control */
#define C_E_MPU401_ENABLE 0x01 /* R W MIDI 1=enable, 0=disable MPU401 MIDI emulation */
#define C_E_SB_ENABLE 0x02 /* R W PCM 1=enable, 0=disable Sound Blaster emulation */
#define C_E_SB_ACTIVE 0x04 /* R PCM "Sound Blaster Interrupt active" */
#define C_E_MPU401_ACTIVE 0x08 /* R MIDI "MPU UART mode active" */
#define C_E_PCM_COMPRESSION 0x10 /* R W PCM 1=enable, 0=disabled compression */
#define EMULATION_ADDRESS 0xF789 /* R W Control */
#define E_A_SB_BASE 0x0f /* R W PCM bits A4-A7 for SB base port */
#define E_A_MPU401_BASE 0xf0 /* R W MIDI bits A4-A7 for MPU401 base port */
#define EMULATION_CONFIGURATION 0xFB8A /* R W ***** Only valid on newer PAS2 cards (?) ***** */
#define E_C_MPU401_IRQ 0x07 /* R W MIDI MPU401 emulation IRQ */
#define E_C_SB_IRQ 0x38 /* R W PCM SB emulation IRQ */
#define E_C_SB_DMA 0xC0 /* R W PCM SB emulation DMA */
#define OPERATION_MODE_1 0xEF8B /* R Control */
#define O_M_1_CDROM_TYPE 0x03 /* R CD-ROM 3=SCSI, 2=Sony, 0=no CD-ROM interface */
#define O_M_1_FM_TYPE 0x04 /* R FM 1=sterero, 0=mono FM chip */
#define O_M_1_PCM_TYPE 0x08 /* R PCM 1=16-bit Codec, 0=8-bit DAC */
#define OPERATION_MODE_2 0xFF8B /* R Control */
#define O_M_2_PCS_ENABLED 0x02 /* R PC speaker PC speaker emulation 1=enabled, 0=disabled */
#define O_M_2_BUS_TIMING 0x10 /* R Control 1=AT bus timing, 0=XT bus timing */
#define O_M_2_BOARD_REVISION 0xe0 /* R Control Board revision */
#define INTERRUPT_MASK 0x0B8B /* R W Control */
#define I_M_FM_LEFT_IRQ_ENABLE 0x01 /* R W FM Enable FM left interrupt */
#define I_M_FM_RIGHT_IRQ_ENABLE 0x02 /* R W FM Enable FM right interrupt */
#define I_M_PCM_RATE_IRQ_ENABLE 0x04 /* R W PCM Enable Sample Rate interrupt */
#define I_M_PCM_BUFFER_IRQ_ENABLE 0x08 /* R W PCM Enable Sample Buffer interrupt */
#define I_M_MIDI_IRQ_ENABLE 0x10 /* R W MIDI Enable MIDI interrupt */
#define I_M_BOARD_REV 0xE0 /* R Control Board revision */
#define INTERRUPT_STATUS 0x0B89 /* R W Control */
#define I_S_FM_LEFT_IRQ 0x01 /* R W FM Left FM Interrupt Pending */
#define I_S_FM_RIGHT_IRQ 0x02 /* R W FM Right FM Interrupt Pending */
#define I_S_PCM_SAMPLE_RATE_IRQ 0x04 /* R W PCM Sample Rate Interrupt Pending */
#define I_S_PCM_SAMPLE_BUFFER_IRQ 0x08 /* R W PCM Sample Buffer Interrupt Pending */
#define I_S_MIDI_IRQ 0x10 /* R W MIDI MIDI Interrupt Pending */
#define I_S_PCM_CHANNEL 0x20 /* R W PCM 1=right, 0=left */
#define I_S_RESET_ACTIVE 0x40 /* R W Control Reset is active (Timed pulse not finished) */
#define I_S_PCM_CLIPPING 0x80 /* R W PCM Clipping has occurred */
#define FILTER_FREQUENCY 0x0B8A /* R W Control */
#define F_F_FILTER_DISABLED 0x00 /* R W Mixer No filter */
#if 0
struct { /* R W Mixer Filter translation */
unsigned int freq:24;
unsigned int value:8;
} F_F_FILTER_translate[] =
{ { 73500, 0x01 }, /* 73500Hz - divide by 16 */
{ 65333, 0x02 }, /* 65333Hz - divide by 18 */
{ 49000, 0x09 }, /* 49000Hz - divide by 24 */
{ 36750, 0x11 }, /* 36750Hz - divide by 32 */
{ 24500, 0x19 }, /* 24500Hz - divide by 48 */
{ 18375, 0x07 }, /* 18375Hz - divide by 64 */
{ 12783, 0x0f }, /* 12783Hz - divide by 92 */
{ 12250, 0x04 }, /* 12250Hz - divide by 96 */
{ 9188, 0x17 }, /* 9188Hz - divide by 128 */
{ 6125, 0x1f }, /* 6125Hz - divide by 192 */
};
#endif
#define F_F_MIXER_UNMUTE 0x20 /* R W Mixer 1=disable, 0=enable board mute */
#define F_F_PCM_RATE_COUNTER 0x40 /* R W PCM 1=enable, 0=disable sample rate counter */
#define F_F_PCM_BUFFER_COUNTER 0x80 /* R W PCM 1=enable, 0=disable sample buffer counter */
#define PAS_NONE 0
#define PAS_PLUS 1
#define PAS_CDPC 2
#define PAS_16 3
#define PAS_16BASIC 4 /* no CDrom */
#ifdef DEFINE_TRANSLATIONS
char I_C_2_PCM_DMA_translate[] = /* R W PCM PCM DMA channel value translations */
{ 4, 1, 2, 3, 0, 5, 6, 7 };
char I_C_3_PCM_IRQ_translate[] = /* R W PCM PCM IRQ level value translation */
{ 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 };
char E_C_MPU401_IRQ_translate[] = /* R W MIDI MPU401 emulation IRQ value translation */
{ 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x05, 0x06, 0x07 };
char E_C_SB_IRQ_translate[] = /* R W PCM SB emulation IRQ translate */
{ 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x28, 0x30, 0x38 };
char E_C_SB_DMA_translate[] = /* R W PCM SB emulation DMA translate */
{ 0x00, 0x40, 0x80, 0xC0 };
char O_M_1_to_card[] = /* R W Control Translate (OM1 & 0x0f) to card type */
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 2, 3 };
#else
extern char I_C_2_PCM_DMA_translate[]; /* R W PCM PCM DMA channel value translations */
extern char I_C_3_PCM_IRQ_translate[]; /* R W PCM PCM IRQ level value translation */
extern char E_C_MPU401_IRQ_translate[]; /* R W MIDI MPU401 emulation IRQ value translation */
extern char E_C_SB_IRQ_translate[]; /* R W PCM SB emulation IRQ translate */
extern char E_C_SB_DMA_translate[]; /* R W PCM SB emulation DMA translate */
extern char O_M_1_to_card[]; /* R W Control Translate (OM1 & 0x0f) to card type */
#endif
#define PARALLEL_MIXER 0x078B /* W Mixer Documented for MVD101 as FM Mono Right decode?? */
#define P_M_MV508_ADDRESS 0x80 /* W Mixer MVD508 Address/mixer select */
#define P_M_MV508_DATA 0x00
#define P_M_MV508_LEFT 0x20 /* W Mixer MVD508 Left channel select */
#define P_M_MV508_RIGHT 0x40 /* W Mixer MVD508 Right channel select */
#define P_M_MV508_BOTH 0x00 /* W Mixer MVD508 Both channel select */
#define P_M_MV508_MIXER 0x10 /* W Mixer MVD508 Select a mixer (rather than a volume) */
#define P_M_MV508_VOLUME 0x00
#define P_M_MV508_INPUTMIX 0x20 /* W Mixer MVD508 Select mixer A */
#define P_M_MV508_OUTPUTMIX 0x00 /* W Mixer MVD508 Select mixer B */
#define P_M_MV508_MASTER_A 0x01 /* W Mixer MVD508 Master volume control A (output) */
#define P_M_MV508_MASTER_B 0x02 /* W Mixer MVD508 Master volume control B (DSP input) */
#define P_M_MV508_BASS 0x03 /* W Mixer MVD508 Bass control */
#define P_M_MV508_TREBLE 0x04 /* W Mixer MVD508 Treble control */
#define P_M_MV508_MODE 0x05 /* W Mixer MVD508 Master mode control */
#define P_M_MV508_LOUDNESS 0x04 /* W Mixer MVD508 Mode control - Loudness filter */
#define P_M_MV508_ENHANCE_NONE 0x00 /* W Mixer MVD508 Mode control - No stereo enhancement */
#define P_M_MV508_ENHANCE_40 0x01 /* W Mixer MVD508 Mode control - 40% stereo enhancement */
#define P_M_MV508_ENHANCE_60 0x02 /* W Mixer MVD508 Mode control - 60% stereo enhancement */
#define P_M_MV508_ENHANCE_80 0x03 /* W Mixer MVD508 Mode control - 80% stereo enhancement */
#define P_M_MV508_FM 0x00 /* W Mixer MVD508 Channel 0 - FM */
#define P_M_MV508_IMIXER 0x01 /* W Mixer MVD508 Channel 1 - Input mixer (rec monitor) */
#define P_M_MV508_LINE 0x02 /* W Mixer MVD508 Channel 2 - Line in */
#define P_M_MV508_CDROM 0x03 /* W Mixer MVD508 Channel 3 - CD-ROM */
#define P_M_MV508_MIC 0x04 /* W Mixer MVD508 Channel 4 - Microphone */
#define P_M_MV508_PCM 0x05 /* W Mixer MVD508 Channel 5 - PCM */
#define P_M_MV508_SPEAKER 0x06 /* W Mixer MVD508 Channel 6 - PC Speaker */
#define P_M_MV508_SB 0x07 /* W Mixer MVD508 Channel 7 - SB DSP */
#define SERIAL_MIXER 0xB88 /* R W Control Serial mixer control (used other ways) */
#define S_M_PCM_RESET 0x01 /* R W PCM Codec/DSP reset */
#define S_M_FM_RESET 0x02 /* R W FM FM chip reset */
#define S_M_SB_RESET 0x04 /* R W PCM SB emulation chip reset */
#define S_M_MIXER_RESET 0x10 /* R W Mixer Mixer chip reset */
#define S_M_INTEGRATOR_ENABLE 0x40 /* R W Speaker Enable PC speaker integrator (FORCE RealSound) */
#define PCM_CONTROL 0xF8A /* R W PCM PCM Control Register */
#define P_C_MIXER_CROSS_FIELD 0x0f
#define P_C_MIXER_CROSS_R_TO_R 0x01 /* R W Mixer Connect Right to Right */
#define P_C_MIXER_CROSS_L_TO_R 0x02 /* R W Mixer Connect Left to Right */
#define P_C_MIXER_CROSS_R_TO_L 0x04 /* R W Mixer Connect Right to Left */
#define P_C_MIXER_CROSS_L_TO_L 0x08 /* R W Mixer Connect Left to Left */
#define P_C_PCM_DAC_MODE 0x10 /* R W PCM Playback (DAC) mode */
#define P_C_PCM_ADC_MODE 0x00 /* R W PCM Record (ADC) mode */
#define P_C_PCM_MONO 0x20 /* R W PCM Mono mode */
#define P_C_PCM_STEREO 0x00 /* R W PCM Stereo mode */
#define P_C_PCM_ENABLE 0x40 /* R W PCM Enable PCM engine */
#define P_C_PCM_DMA_ENABLE 0x80 /* R W PCM Enable DRQ */
#define SAMPLE_COUNTER_CONTROL 0x138B /* R W PCM Sample counter control register */
#define S_C_C_SQUARE_WAVE 0x04 /* R W PCM Square wave generator (use for sample rate) */
#define S_C_C_RATE 0x06 /* R W PCM Rate generator (use for sample buffer count) */
#define S_C_C_LSB_THEN_MSB 0x30 /* R W PCM Change all 16 bits, LSB first, then MSB */
/* MVD101 and SDK documentations have S_C_C_SAMPLE_RATE and S_C_C_SAMPLE_BUFFER transposed. Only one works :-) */
#define S_C_C_SAMPLE_RATE 0x00 /* R W PCM Select sample rate timer */
#define S_C_C_SAMPLE_BUFFER 0x40 /* R W PCM Select sample buffer counter */
#define S_C_C_PC_SPEAKER 0x80 /* R W PCM Select PC speaker counter */
#define SAMPLE_RATE_TIMER 0x1388 /* W PCM Sample rate timer register (PCM wait interval) */
#define SAMPLE_BUFFER_COUNTER 0x1389 /* R W PCM Sample buffer counter (DMA buffer size) */
#define MIDI_CONTROL 0x178b /* R W MIDI Midi control register */
#define M_C_ENA_TSTAMP_IRQ 0x01 /* R W MIDI Enable Time Stamp Interrupts */
#define M_C_ENA_TME_COMP_IRQ 0x02 /* R W MIDI Enable time compare interrupts */
#define M_C_ENA_INPUT_IRQ 0x04 /* R W MIDI Enable input FIFO interrupts */
#define M_C_ENA_OUTPUT_IRQ 0x08 /* R W MIDI Enable output FIFO interrupts */
#define M_C_ENA_OUTPUT_HALF_IRQ 0x10 /* R W MIDI Enable output FIFO half full interrupts */
#define M_C_RESET_INPUT_FIFO 0x20 /* R W MIDI Reset input FIFO pointer */
#define M_C_RESET_OUTPUT_FIFO 0x40 /* R W MIDI Reset output FIFO pointer */
#define M_C_ENA_THRU_MODE 0x80 /* R W MIDI Echo input to output (THRU) */
#define MIDI_STATUS 0x1B88 /* R W MIDI Midi (interrupt) status register */
#define M_S_TIMESTAMP 0x01 /* R W MIDI Midi time stamp interrupt occurred */
#define M_S_COMPARE 0x02 /* R W MIDI Midi compare time interrupt occurred */
#define M_S_INPUT_AVAIL 0x04 /* R W MIDI Midi input data available interrupt occurred */
#define M_S_OUTPUT_EMPTY 0x08 /* R W MIDI Midi output FIFO empty interrupt occurred */
#define M_S_OUTPUT_HALF_EMPTY 0x10 /* R W MIDI Midi output FIFO half empty interrupt occurred */
#define M_S_INPUT_OVERRUN 0x20 /* R W MIDI Midi input overrun error occurred */
#define M_S_OUTPUT_OVERRUN 0x40 /* R W MIDI Midi output overrun error occurred */
#define M_S_FRAMING_ERROR 0x80 /* R W MIDI Midi input framing error occurred */
#define MIDI_FIFO_STATUS 0x1B89 /* R W MIDI Midi fifo status */
#define MIDI_DATA 0x178A /* R W MIDI Midi data register */

File diff suppressed because it is too large Load Diff

View File

@ -1,165 +0,0 @@
/* $NetBSD: pssreg.h,v 1.1 1995/02/21 04:15:04 brezak Exp $ */
/*
* Copyright (c) 1994 John Brezak
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: pssreg.h,v 1.1 1995/02/21 04:15:04 brezak Exp $
*/
/*
* Copyright (c) 1993 Analog Devices Inc. All rights reserved
*/
/*
* Macros to detect valid hardware configuration data.
*/
#define PSS_BASE_VALID(base) ((base) == 0x220 || (base) == 0x240)
/*
* ESC614 Interface chip
*/
#define ADDR_MASK 0x003f
#define INT_MASK 0xffc7
#define INT_3_BITS 0x0008
#define INT_5_BITS 0x0010
#define INT_7_BITS 0x0018
#define INT_9_BITS 0x0020
#define INT_10_BITS 0x0028
#define INT_11_BITS 0x0030
#define INT_12_BITS 0x0038
#define INT_TEST_BIT 0x0200
#define INT_TEST_PASS 0x0100
#define INT_TEST_BIT_MASK 0xFDFF
#define DMA_MASK 0xfff8
#define DMA_0_BITS 0x0001
#define DMA_1_BITS 0x0002
#define DMA_3_BITS 0x0003
#define DMA_5_BITS 0x0004
#define DMA_6_BITS 0x0005
#define DMA_7_BITS 0x0006
#define DMA_TEST_BIT 0x0080
#define DMA_TEST_PASS 0x0040
#define DMA_TEST_BIT_MASK 0xFF7F
/* Echo DSP Flags */
#define DSP_FLAG3 0x10
#define DSP_FLAG2 0x08
#define DSP_FLAG1 0x80
#define DSP_FLAG0 0x40
/* ESC614 register offsets */
#define PSS_NPORT 32
#define PSS_DATA 0x00
#define PSS_STATUS 0x02
#define PSS_CONTROL 0x02
#define PSS_ID_VERS 0x04
#define PSS_IRQ_ACK 0x04
#define PSS_CONFIG 0x10
#define PSS_WSS_CONFIG 0x12
#define SB_CONFIG 0x14
#define CD_CONFIG 0x16
#define MIDI_CONFIG 0x18
#define UART_CONFIG 0x1a
/* PSS control register */
#define PSS_WEIE 0x8000
#define PSS_RFIE 0x4000
#define PSS_RESET 0x2000
#define PSS_FLAG1 0x1000
#define PSS_FLAG0 0x0800
/* PSS status register */
#define PSS_WRITE_EMPTY 0x8000
#define PSS_READ_FULL 0x4000
#define PSS_IRQ 0x2000
#define PSS_DMQ_TC 0x1000
#define PSS_FLAG3 0x0800
#define PSS_FLAG2 0x0400
/* Game control register */
#define GAME_BIT 0x0400
#define GAME_BIT_MASK 0xfbff
/* MPU registers */
#define MIDI_NPORT 8
#define MIDI_DATA_REG 0x00
#define MIDI_STATUS_REG 0x01
#define MIDI_COMMAND_REG 0x01
#define MIDI_SR_RF 0x80
#define MIDI_SR_TE 0x40
/* CD Interface registers */
#define CD_NPORT 16
#define CD_POL_MASK 0xFFBF
#define CD_POL_BIT 0x0040
/* Phillips amplifier controls: only via DSP */
/* DSP commands */
#define SET_MASTER_COMMAND 0x0010
#define MASTER_VOLUME_LEFT 0x0000
#define MASTER_VOLUME_RIGHT 0x0100
#define MASTER_BASS 0x0200
#define MASTER_TREBLE 0x0300
#define MASTER_SWITCH 0x0800
#define PSS_STEREO 0x00ce
#define PSS_PSEUDO 0x00d6
#define PSS_SPATIAL 0x00de
#define PSS_MONO 0x00c6
#define PHILLIPS_VOL_MIN -64
#define PHILLIPS_VOL_MAX 6
#define PHILLIPS_VOL_DELTA 70
#define PHILLIPS_VOL_INITIAL -20
#define PHILLIPS_VOL_CONSTANT 252
#define PHILLIPS_VOL_STEP 2
#define PHILLIPS_BASS_MIN -12
#define PHILLIPS_BASS_MAX 15
#define PHILLIPS_BASS_DELTA 27
#define PHILLIPS_BASS_INITIAL 0
#define PHILLIPS_BASS_CONSTANT 246
#define PHILLIPS_BASS_STEP 2
#define PHILLIPS_TREBLE_MIN -12
#define PHILLIPS_TREBLE_MAX 12
#define PHILLIPS_TREBLE_DELTA 24
#define PHILLIPS_TREBLE_INITIAL 0
#define PHILLIPS_TREBLE_CONSTANT 246
#define PHILLIPS_TREBLE_STEP 2

View File

@ -1,322 +0,0 @@
/* $NetBSD: sb.c,v 1.23 1995/04/17 12:07:37 cgd Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: sb.c,v 1.23 1995/04/17 12:07:37 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/proc.h>
#include <machine/cpu.h>
#include <machine/pio.h>
#include <sys/audioio.h>
#include <dev/audio_if.h>
#include <dev/isa/isavar.h>
#include <dev/isa/isadmavar.h>
#include <i386/isa/icu.h>
#include <i386/isa/sbdspvar.h>
#include <i386/isa/sbreg.h>
#define DEBUG /*XXX*/
#ifdef DEBUG
#define DPRINTF(x) if (sbdebug) printf x
int sbdebug = 0;
#else
#define DPRINTF(x)
#endif
struct sb_softc {
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
void *sc_ih; /* interrupt vectoring */
struct sbdsp_softc sc_sbdsp;
};
int sbprobe();
void sbattach __P((struct device *, struct device *, void *));
struct cfdriver sbcd = {
NULL, "sb", sbprobe, sbattach, DV_DULL, sizeof(struct sb_softc)
};
struct audio_device sb_device = {
"SoundBlaster",
"x",
"sb"
};
int sbopen __P((dev_t, int));
int sbprobe();
void sbattach();
int sb_getdev __P((void *, struct audio_device *));
/*
* Define our interface to the higher level audio driver.
*/
struct audio_hw_if sb_hw_if = {
sbopen,
sbdsp_close,
NULL,
sbdsp_set_in_sr,
sbdsp_get_in_sr,
sbdsp_set_out_sr,
sbdsp_get_out_sr,
sbdsp_query_encoding,
sbdsp_set_encoding,
sbdsp_get_encoding,
sbdsp_set_precision,
sbdsp_get_precision,
sbdsp_set_channels,
sbdsp_get_channels,
sbdsp_round_blocksize,
sbdsp_set_out_port,
sbdsp_get_out_port,
sbdsp_set_in_port,
sbdsp_get_in_port,
sbdsp_commit_settings,
sbdsp_get_silence,
sbdsp_expand,
sbdsp_compress,
sbdsp_dma_output,
sbdsp_dma_input,
sbdsp_haltdma,
sbdsp_haltdma,
sbdsp_contdma,
sbdsp_contdma,
sbdsp_speaker_ctl,
sb_getdev,
sbdsp_setfd,
sbdsp_mixer_set_port,
sbdsp_mixer_get_port,
sbdsp_mixer_query_devinfo,
0, /* not full-duplex */
0
};
/*
* Probe / attach routines.
*/
/*
* Probe for the soundblaster hardware.
*/
int
sbprobe(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct sb_softc *sc = (void *)self;
register struct isa_attach_args *ia = aux;
register u_short iobase = ia->ia_iobase;
static u_char irq_conf[11] = {
-1, -1, 0x01, -1, -1, 0x02, -1, 0x04, -1, 0x01, 0x08
};
if (!SB_BASE_VALID(ia->ia_iobase)) {
printf("sb: configured iobase %d invalid\n", ia->ia_iobase);
return 0;
}
sc->sc_sbdsp.sc_iobase = iobase;
if (sbdsp_probe(&sc->sc_sbdsp) == 0) {
DPRINTF(("sb: sbdsp probe failed\n"));
return 0;
}
/*
* Cannot auto-discover DMA channel.
*/
if (ISSBPROCLASS(&sc->sc_sbdsp)) {
if (!SBP_DRQ_VALID(ia->ia_drq)) {
printf("sb: configured dma chan %d invalid\n", ia->ia_drq);
return 0;
}
if (ISSB16CLASS(&sc->sc_sbdsp)) {
sbdsp_mix_write(&sc->sc_sbdsp, SBP_SET_DRQ,
1 << ia->ia_drq);
}
}
else {
if (!SB_DRQ_VALID(ia->ia_drq)) {
printf("sb: configured dma chan %d invalid\n", ia->ia_drq);
return 0;
}
}
#ifdef NEWCONFIG
/*
* If the IRQ wasn't compiled in, auto-detect it.
*/
if (ia->ia_irq == IRQUNK) {
ia->ia_irq = isa_discoverintr(sbforceintr, aux);
sbdsp_reset(&sc->sc_sbdsp);
if (ISSBPROCLASS(&sc->sc_sbdsp)) {
if (!SBP_IRQ_VALID(ia->ia_irq)) {
printf("sb: couldn't auto-detect interrupt");
return 0;
}
}
else {
if (!SB_IRQ_VALID(ia->ia_irq)) {
printf("sb: couldn't auto-detect interrupt");
return 0;
}
}
} else
#endif
if (ISSBPROCLASS(&sc->sc_sbdsp)) {
if (!SBP_IRQ_VALID(ia->ia_irq)) {
printf("sb: configured irq %d invalid\n", ia->ia_irq);
return 0;
}
if (ISSB16CLASS(&sc->sc_sbdsp)) {
sbdsp_mix_write(&sc->sc_sbdsp, SBP_SET_IRQ,
irq_conf[ia->ia_irq]);
}
}
else {
if (!SB_IRQ_VALID(ia->ia_irq)) {
printf("sb: configured irq %d invalid\n", ia->ia_irq);
return 0;
}
}
sc->sc_sbdsp.sc_irq = ia->ia_irq;
sc->sc_sbdsp.sc_drq = ia->ia_drq;
if (ISSBPROCLASS(&sc->sc_sbdsp))
ia->ia_iosize = SBP_NPORT;
else
ia->ia_iosize = SB_NPORT;
return 1;
}
#ifdef NEWCONFIG
void
sbforceintr(aux)
void *aux;
{
static char dmabuf;
struct isa_attach_args *ia = aux;
u_short iobase = ia->ia_iobase;
/*
* Set up a DMA read of one byte.
* XXX Note that at this point we haven't called
* at_setup_dmachan(). This is okay because it just
* allocates a buffer in case it needs to make a copy,
* and it won't need to make a copy for a 1 byte buffer.
* (I think that calling at_setup_dmachan() should be optional;
* if you don't call it, it will be called the first time
* it is needed (and you pay the latency). Also, you might
* never need the buffer anyway.)
*/
at_dma(B_READ, &dmabuf, 1, ia->ia_drq);
if (sbdsp_wdsp(iobase, SB_DSP_RDMA) == 0) {
(void)sbdsp_wdsp(iobase, 0);
(void)sbdsp_wdsp(iobase, 0);
}
}
#endif
/*
* Attach hardware to driver, attach hardware driver to audio
* pseudo-device driver .
*/
void
sbattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct sb_softc *sc = (struct sb_softc *)self;
struct isa_attach_args *ia = (struct isa_attach_args *)aux;
register u_short iobase = ia->ia_iobase;
#ifdef NEWCONFIG
isa_establish(&sc->sc_id, &sc->sc_dev);
#endif
sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_BIO,
sbdsp_intr, &sc->sc_sbdsp);
sbdsp_attach(&sc->sc_sbdsp);
sprintf(sb_device.version, "%d.%d",
SBVER_MAJOR(sc->sc_sbdsp.sc_model),
SBVER_MINOR(sc->sc_sbdsp.sc_model));
if (audio_hardware_attach(&sb_hw_if, &sc->sc_sbdsp) != 0)
printf("sb: could not attach to audio pseudo-device driver\n");
}
/*
* Various routines to interface to higher level audio driver
*/
int
sbopen(dev, flags)
dev_t dev;
int flags;
{
struct sb_softc *sc;
int unit = AUDIOUNIT(dev);
if (unit >= sbcd.cd_ndevs)
return ENODEV;
sc = sbcd.cd_devs[unit];
if (!sc)
return ENXIO;
return sbdsp_open(&sc->sc_sbdsp, dev, flags);
}
int
sb_getdev(addr, retp)
void *addr;
struct audio_device *retp;
{
*retp = sb_device;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,200 +0,0 @@
/* $NetBSD: sbdspvar.h,v 1.5 1995/04/17 12:07:44 cgd Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: sbdspvar.h,v 1.5 1995/04/17 12:07:44 cgd Exp $
*/
#define SB_MIC_PORT 0
#define SB_SPEAKER 1
#define SB_LINE_IN_PORT 2
#define SB_DAC_PORT 3
#define SB_FM_PORT 4
#define SB_CD_PORT 5
#define SB_MASTER_VOL 6
#define SB_TREBLE 7
#define SB_BASS 8
#define SB_NDEVS 9
#define SB_OUTPUT_MODE 9
#define SB_SPKR_MONO 0
#define SB_SPKR_STEREO 1
#define SB_RECORD_SOURCE 10
#define SB_INPUT_CLASS 11
#define SB_OUTPUT_CLASS 12
#define SB_RECORD_CLASS 13
/*
* Software state, per SoundBlaster card.
* The soundblaster has multiple functionality, which we must demultiplex.
* One approach is to have one major device number for the soundblaster card,
* and use different minor numbers to indicate which hardware function
* we want. This would make for one large driver. Instead our approach
* is to partition the design into a set of drivers that share an underlying
* piece of hardware. Most things are hard to share, for example, the audio
* and midi ports. For audio, we might want to mix two processes' signals,
* and for midi we might want to merge streams (this is hard due to
* running status). Moreover, we should be able to re-use the high-level
* modules with other kinds of hardware. In this module, we only handle the
* most basic communications with the sb card.
*/
struct sbdsp_softc {
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
void *sc_ih; /* interrupt vectoring */
u_short sc_iobase; /* I/O port base address */
u_short sc_irq; /* interrupt */
u_short sc_drq; /* DMA */
u_short sc_open; /* reference count of open calls */
u_short sc_locked; /* true when doing HS DMA */
u_short sc_adacmode; /* low/high speed mode indicator */
u_long sc_irate; /* Sample rate for input */
u_long sc_orate; /* ...and output */
u_int gain[SB_NDEVS]; /* kept in SB levels: right/left each
in a nibble */
u_int encoding; /* ulaw/linear -- keep track */
u_int out_port; /* output port */
u_int in_port; /* input port */
u_int spkr_state; /* non-null is on */
#define SB_ADAC_LS 0
#define SB_ADAC_HS 1
u_short sc_adactc; /* current adac time constant */
u_long sc_interrupts; /* number of interrupts taken */
void (*sc_intr)(void*); /* dma completion intr handler */
void (*sc_mintr)(void*, int);/* midi input intr handler */
void *sc_arg; /* arg for sc_intr() */
int dmaflags;
caddr_t dmaaddr;
vm_size_t dmacnt;
int sc_last_hsw_size; /* last HS dma size */
int sc_last_hsr_size; /* last HS dma size */
int sc_chans; /* # of channels */
char sc_dmain_inprogress; /* DMA input in progress? */
char sc_dmaout_inprogress; /* DMA output in progress? */
u_int sc_model; /* DSP model */
#define SBVER_MAJOR(v) ((v)>>8)
#define SBVER_MINOR(v) ((v)&0xff)
};
#define ISSBPRO(sc) \
(SBVER_MAJOR((sc)->sc_model) == 3)
#define ISSBPROCLASS(sc) \
(SBVER_MAJOR((sc)->sc_model) > 2)
#define ISSB16CLASS(sc) \
(SBVER_MAJOR((sc)->sc_model) > 3)
#ifdef _KERNEL
int sbdsp_open __P((struct sbdsp_softc *, dev_t, int));
void sbdsp_close __P((void *));
int sbdsp_probe __P((struct sbdsp_softc *));
void sbdsp_attach __P((struct sbdsp_softc *));
int sbdsp_set_in_gain __P((void *, u_int, u_char));
int sbdsp_set_in_gain_real __P((void *, u_int, u_char));
int sbdsp_get_in_gain __P((void *));
int sbdsp_set_out_gain __P((void *, u_int, u_char));
int sbdsp_set_out_gain_real __P((void *, u_int, u_char));
int sbdsp_get_out_gain __P((void *));
int sbdsp_set_monitor_gain __P((void *, u_int));
int sbdsp_get_monitor_gain __P((void *));
int sbdsp_set_in_sr __P((void *, u_long));
int sbdsp_set_in_sr_real __P((void *, u_long));
u_long sbdsp_get_in_sr __P((void *));
int sbdsp_set_out_sr __P((void *, u_long));
int sbdsp_set_out_sr_real __P((void *, u_long));
u_long sbdsp_get_out_sr __P((void *));
int sbdsp_query_encoding __P((void *, struct audio_encoding *));
int sbdsp_set_encoding __P((void *, u_int));
int sbdsp_get_encoding __P((void *));
int sbdsp_set_precision __P((void *, u_int));
int sbdsp_get_precision __P((void *));
int sbdsp_set_channels __P((void *, int));
int sbdsp_get_channels __P((void *));
int sbdsp_round_blocksize __P((void *, int));
int sbdsp_set_out_port __P((void *, int));
int sbdsp_get_out_port __P((void *));
int sbdsp_set_in_port __P((void *, int));
int sbdsp_get_in_port __P((void *));
int sbdsp_get_avail_in_ports __P((void *));
int sbdsp_get_avail_out_ports __P((void *));
int sbdsp_speaker_ctl __P((void *, int));
int sbdsp_commit_settings __P((void *));
int sbdsp_dma_output __P((void *, void *, int, void (*)(), void*));
int sbdsp_dma_input __P((void *, void *, int, void (*)(), void*));
int sbdsp_haltdma __P((void *));
int sbdsp_contdma __P((void *));
u_int sbdsp_get_silence __P((int));
void sbdsp_compress __P((int, u_char *, int));
void sbdsp_expand __P((int, u_char *, int));
int sbdsp_reset __P((struct sbdsp_softc *));
void sbdsp_spkron __P((struct sbdsp_softc *));
void sbdsp_spkroff __P((struct sbdsp_softc *));
int sbdsp_wdsp(u_short iobase, int v);
int sbdsp_rdsp(u_short iobase);
int sbdsp_intr __P((void *));
short sbversion __P((struct sbdsp_softc *));
int sbdsp_set_sr __P((struct sbdsp_softc *, u_long *, int));
int sbdsp_setfd __P((void *, int));
void sbdsp_mix_write __P((struct sbdsp_softc *, int, int));
int sbdsp_mix_read __P((struct sbdsp_softc *, int));
int sbdsp_mixer_set_port __P((void *, mixer_ctrl_t *));
int sbdsp_mixer_get_port __P((void *, mixer_ctrl_t *));
int sbdsp_mixer_query_devinfo __P((void *, mixer_devinfo_t *));
#endif

View File

@ -1,191 +0,0 @@
/* $NetBSD: sbreg.h,v 1.11 1995/03/15 16:43:13 glass Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* From: Header: sbreg.h,v 1.3 93/07/18 14:07:28 mccanne Exp (LBL)
* $Id: sbreg.h,v 1.11 1995/03/15 16:43:13 glass Exp $
*/
/*
* SoundBlaster register definitions.
* See "The Developer Kit for Sound Blaster Series, User's Guide" for more
* complete information (avialable from Creative Labs, Inc.). We refer
* to this documentation as "SBK".
*
* We handle two types of cards: the basic SB version 2.0+, and
* the SB PRO. There are several distinct pieces of the hardware:
*
* joystick port (independent of I/O base address)
* FM synth (stereo on PRO)
* mixer (PRO only)
* DSP (sic)
* CD-ROM (PRO only)
*
* The MIDI capabilities are handled by the DSP unit.
*/
/*
* Address map. The SoundBlaster can be configured (via jumpers) for
* either base I/O address 0x220 or 0x240. The encodings below give
* the offsets to specific SB ports. SBP stands for SB port offset.
*/
#define SBP_LFM_STATUS 0 /* R left FM status port */
#define SBP_LFM_ADDR 0 /* W left FM address register */
#define SBP_LFM_DATA 1 /* RW left FM data port */
#define SBP_RFM_STATUS 2 /* R right FM status port */
#define SBP_RFM_ADDR 2 /* W right FM address register */
#define SBP_RFM_DATA 3 /* RW right FM data port */
#define SBP_FM_STATUS 8 /* R FM status port */
#define SBP_FM_ADDR 8 /* W FM address register */
#define SBP_FM_DATA 9 /* RW FM data port */
#define SBP_MIXER_ADDR 4 /* W mixer address register */
#define SBP_MIXER_DATA 5 /* RW mixer data port */
#define SBP_MIX_RESET 0 /* mixer reset port, value */
#define SBP_MASTER_VOL 0x22
#define SBP_FM_VOL 0x26
#define SBP_CD_VOL 0x28
#define SBP_LINE_VOL 0x2E
#define SBP_DAC_VOL 0x04
#define SBP_MIC_VOL 0x0A /* warning: only one channel of
volume... */
#define SBP_SPEAKER_VOL 0x42
#define SBP_TREBLE_EQ 0x44
#define SBP_BASS_EQ 0x46
#define SBP_SET_IRQ 0x80 /* Soft-configured irq (SB16-) */
#define SBP_SET_DRQ 0x81 /* Soft-configured drq (SB16-) */
#define SBP_RECORD_SOURCE 0x0C
#define SBP_STEREO 0x0E
#define SBP_PLAYMODE_STEREO 0x2
#define SBP_PLAYMODE_MONO 0x0
#define SBP_PLAYMODE_MASK 0x2
#define SBP_OUTFILTER 0x0E
#define SBP_INFILTER 0x0C
#define SBP_RECORD_FROM(src, filteron, high) ((src) | (filteron) | (high))
#define SBP_FILTER_ON 0x0
#define SBP_FILTER_OFF 0x20
#define SBP_FILTER_MASK 0x20
#define SBP_FILTER_LOW 0
#define SBP_FILTER_HIGH 0x08
#define SBP_FROM_MIC 0x00
#define SBP_FROM_CD 0x02
#define SBP_FROM_LINE 0x06
#define sbdsp_stereo_vol(left, right) (((left) << 4) | (right))
#define SBP_MAXVOL 0xf /* per channel */
#define SBP_MINVOL 0x0 /* per channel */
#define SBP_AGAIN_TO_SBGAIN(again) ((again) >> 4) /* per channel */
#define SBP_AGAIN_TO_MICGAIN(again) ((again) >> 5) /* mic has only 3 bits,
sorry! */
#define SBP_LEFTGAIN(sbgain) (sbgain & 0xf0) /* left channel */
#define SBP_RIGHTGAIN(sbgain) ((sbgain & 0xf) << 4) /* right channel */
#define SBP_SBGAIN_TO_AGAIN(sbgain) SBP_LEFTGAIN(sbgain)
#define SBP_MICGAIN_TO_AGAIN(micgain) (micgain << 5)
#define SBP_DSP_RESET 6 /* W reset port */
#define SB_MAGIC 0xaa /* card outputs on successful reset */
#define SBP_DSP_READ 10 /* R read port */
#define SBP_DSP_WRITE 12 /* W write port */
#define SBP_DSP_WSTAT 12 /* R write status */
#define SBP_DSP_RSTAT 14 /* R read status */
#define SB_DSP_BUSY 0x80
#define SB_DSP_READY 0x80
#define SBP_CDROM_DATA 16 /* RW send cmds/recv data */
#define SBP_CDROM_STATUS 17 /* R status port */
#define SBP_CDROM_RESET 18 /* W reset register */
#define SBP_CDROM_ENABLE 19 /* W enable register */
#define SBP_NPORT 24
#define SB_NPORT 16
/*
* DSP commands. This unit handles MIDI and audio capabilities.
* The DSP can be reset, data/commands can be read or written to it,
* and it can generate interrupts. Interrupts are generated for MIDI
* input or DMA completion. They seem to have neglected the fact
* that it would be nice to have a MIDI transmission complete interrupt.
* Worse, the DMA engine is half-duplex. This means you need to do
* (timed) programmed I/O to be able to record and play simulataneously.
*/
#define SB_DSP_DACWRITE 0x10 /* programmed I/O write to DAC */
#define SB_DSP_WDMA 0x14 /* begin 8-bit linear DMA output */
#define SB_DSP_WDMA_2 0x16 /* begin 2-bit ADPCM DMA output */
#define SB_DSP_ADCREAD 0x20 /* programmed I/O read from ADC */
#define SB_DSP_RDMA 0x24 /* begin 8-bit linear DMA input */
#define SB_MIDI_POLL 0x30 /* initiate a polling read for MIDI */
#define SB_MIDI_READ 0x31 /* read a MIDI byte on recv intr */
#define SB_MIDI_UART_POLL 0x34 /* enter UART mode w/ read polling */
#define SB_MIDI_UART_INTR 0x35 /* enter UART mode w/ read intrs */
#define SB_MIDI_WRITE 0x38 /* write a MIDI byte (non-UART mode) */
#define SB_DSP_TIMECONST 0x40 /* set ADAC time constant */
#define SB_DSP_BLOCKSIZE 0x48 /* set blk size for high speed xfer */
#define SB_DSP_WDMA_4 0x74 /* begin 4-bit ADPCM DMA output */
#define SB_DSP_WDMA_2_6 0x76 /* begin 2.6-bit ADPCM DMA output */
#define SB_DSP_SILENCE 0x80 /* send a block of silence */
#define SB_DSP_HS_OUTPUT 0x91 /* set high speed mode for wdma */
#define SB_DSP_HS_INPUT 0x99 /* set high speed mode for rdma */
#define SB_DSP_RECORD_MONO 0xA0 /* set mono recording */
#define SB_DSP_RECORD_STEREO 0xA8 /* set stereo recording */
#define SB_DSP_HALT 0xd0 /* temporarilty suspend DMA */
#define SB_DSP_SPKR_ON 0xd1 /* turn speaker on */
#define SB_DSP_SPKR_OFF 0xd3 /* turn speaker off */
#define SB_DSP_CONT 0xd4 /* continue suspended DMA */
#define SB_DSP_RD_SPKR 0xd8 /* get speaker status */
#define SB_SPKR_OFF 0x00
#define SB_SPKR_ON 0xff
#define SB_DSP_VERSION 0xe1 /* get version number */
/*
* The ADPCM encodings are differential, meaning each sample represents
* a difference to add to a running sum. The inital value is called the
* reference, or reference byte. Any of the ADPCM DMA transfers can specify
* that the given transfer begins with a reference byte by or'ing
* in the bit below.
*/
#define SB_DSP_REFERENCE 1
/*
* Macros to detect valid hardware configuration data.
*/
#define SBP_IRQ_VALID(irq) ((irq) == 5 || (irq) == 7 || (irq) == 9 || (irq) == 10)
#define SB_IRQ_VALID(irq) ((irq) == 3 || (irq) == 5 || (irq) == 7 || (irq) == 9)
#define SBP_DRQ_VALID(chan) ((chan) == 0 || (chan) == 1 || (chan) == 3)
#define SB_DRQ_VALID(chan) ((chan) == 1)
#define SB_BASE_VALID(base) ((base) == 0x220 || (base) == 0x240)
#define SB_INPUT_RATE 0
#define SB_OUTPUT_RATE 1

View File

@ -1,717 +0,0 @@
/* $NetBSD: wss.c,v 1.3 1995/04/17 12:07:50 cgd Exp $ */
/*
* Copyright (c) 1994 John Brezak
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: wss.c,v 1.3 1995/04/17 12:07:50 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/buf.h>
#include <machine/cpu.h>
#include <machine/pio.h>
#include <sys/audioio.h>
#include <dev/audio_if.h>
#include <dev/isa/isavar.h>
#include <dev/isa/isadmavar.h>
#include <i386/isa/icu.h>
#include <i386/isa/ad1848var.h>
#include <i386/isa/ad1848reg.h>
#include <i386/isa/wssreg.h>
/*
* Mixer devices
*/
#define WSS_MIC_IN_LVL 0
#define WSS_LINE_IN_LVL 1
#define WSS_DAC_LVL 2
#define WSS_REC_LVL 3
#define WSS_MON_LVL 4
#define WSS_MIC_IN_MUTE 5
#define WSS_LINE_IN_MUTE 6
#define WSS_DAC_MUTE 7
#define WSS_RECORD_SOURCE 8
/* Classes */
#define WSS_INPUT_CLASS 9
#define WSS_RECORD_CLASS 10
#define WSS_MONITOR_CLASS 11
#define DEBUG /*XXX*/
#ifdef DEBUG
#define DPRINTF(x) if (wssdebug) printf x
int wssdebug = 0;
#else
#define DPRINTF(x)
#endif
struct wss_softc {
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
void *sc_ih; /* interrupt vectoring */
struct ad1848_softc sc_ad1848;
#define wss_iobase sc_ad1848.sc_iobase
#define wss_irq sc_ad1848.sc_irq
#define wss_drq sc_ad1848.sc_drq
int mic_mute, cd_mute, dac_mute;
};
struct audio_device wss_device = {
"wss,ad1848",
"",
"WSS"
};
int wssprobe();
void wssattach();
int wssopen __P((dev_t, int));
int wss_getdev __P((void *, struct audio_device *));
int wss_setfd __P((void *, int));
int wss_set_out_port __P((void *, int));
int wss_get_out_port __P((void *));
int wss_set_in_port __P((void *, int));
int wss_get_in_port __P((void *));
int wss_mixer_set_port __P((void *, mixer_ctrl_t *));
int wss_mixer_get_port __P((void *, mixer_ctrl_t *));
int wss_query_devinfo __P((void *, mixer_devinfo_t *));
/*
* Define our interface to the higher level audio driver.
*/
struct audio_hw_if wss_hw_if = {
wssopen,
ad1848_close,
NULL,
ad1848_set_in_sr,
ad1848_get_in_sr,
ad1848_set_out_sr,
ad1848_get_out_sr,
ad1848_query_encoding,
ad1848_set_encoding,
ad1848_get_encoding,
ad1848_set_precision,
ad1848_get_precision,
ad1848_set_channels,
ad1848_get_channels,
ad1848_round_blocksize,
wss_set_out_port,
wss_get_out_port,
wss_set_in_port,
wss_get_in_port,
ad1848_commit_settings,
ad1848_get_silence,
NULL,
NULL,
ad1848_dma_output,
ad1848_dma_input,
ad1848_halt_out_dma,
ad1848_halt_in_dma,
ad1848_cont_out_dma,
ad1848_cont_in_dma,
NULL,
wss_getdev,
wss_setfd,
wss_mixer_set_port,
wss_mixer_get_port,
wss_query_devinfo,
0, /* not full-duplex */
0
};
#ifndef NEWCONFIG
#define at_dma(flags, ptr, cc, chan) isa_dmastart(flags, ptr, cc, chan)
#endif
struct cfdriver wsscd = {
NULL, "wss", wssprobe, wssattach, DV_DULL, sizeof(struct wss_softc)
};
/*
* Probe for the Microsoft Sound System hardware.
*/
int
wssprobe(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct wss_softc *sc = (void *)self;
register struct isa_attach_args *ia = aux;
register u_short iobase = ia->ia_iobase;
static u_char interrupt_bits[12] = {
-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
};
static u_char dma_bits[4] = {1, 2, 0, 3};
char bits;
if (!WSS_BASE_VALID(ia->ia_iobase)) {
printf("wss: configured iobase %d invalid\n", ia->ia_iobase);
return 0;
}
sc->wss_iobase = iobase;
/* Is there an ad1848 chip at the WSS iobase ? */
if (ad1848_probe(&sc->sc_ad1848) == 0)
return 0;
#ifdef NEWCONFIG
/*
* If the IRQ wasn't compiled in, auto-detect it.
*/
if (ia->ia_irq == IRQUNK) {
ia->ia_irq = isa_discoverintr(ad1848_forceintr, &sc->sc_ad1848);
if (!WSS_IRQ_VALID(ia->ia_irq)) {
printf("wss: couldn't auto-detect interrupt");
return 0;
}
}
else
#endif
ia->ia_iosize = WSS_NPORT;
/* Setup WSS interrupt and DMA */
if ((bits = interrupt_bits[sc->wss_irq]) == -1) {
printf("wss: invalid interrupt configuration (irq=%d)\n", sc->wss_irq);
return 0;
}
#if 0
/* XXX Dual-DMA */
outb(sc->wss_iobase+WSS_CONFIG, (bits | 0x40));
if ((inb(sc->wss_iobase+WSS_STATUS) & 0x40) == 0)
printf("wss: IRQ?\n");
#endif
outb(sc->wss_iobase+WSS_CONFIG, (bits | dma_bits[sc->wss_drq]));
return 1;
}
/*
* Attach hardware to driver, attach hardware driver to audio
* pseudo-device driver .
*/
void
wssattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct wss_softc *sc = (struct wss_softc *)self;
struct isa_attach_args *ia = (struct isa_attach_args *)aux;
register u_short iobase = ia->ia_iobase;
sc->wss_iobase = iobase;
sc->wss_drq = ia->ia_drq;
#ifdef NEWCONFIG
isa_establish(&sc->sc_id, &sc->sc_dev);
#endif
sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_BIO,
ad1848_intr, &sc->sc_ad1848);
ad1848_attach(&sc->sc_ad1848);
printf(" (vers %d)", inb(sc->wss_iobase+WSS_STATUS) & 0x1f);
printf("\n");
sc->sc_ad1848.parent = sc;
if (audio_hardware_attach(&wss_hw_if, &sc->sc_ad1848) != 0)
printf("wss: could not attach to audio pseudo-device driver\n");
}
static int
wss_to_vol(cp, vol)
mixer_ctrl_t *cp;
struct ad1848_volume *vol;
{
if (cp->un.value.num_channels == 1) {
vol->left = vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
return(1);
}
else if (cp->un.value.num_channels == 2) {
vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
return(1);
}
return(0);
}
static int
wss_from_vol(cp, vol)
mixer_ctrl_t *cp;
struct ad1848_volume *vol;
{
if (cp->un.value.num_channels == 1) {
cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
return(1);
}
else if (cp->un.value.num_channels == 2) {
cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
return(1);
}
return(0);
}
int
wssopen(dev, flags)
dev_t dev;
int flags;
{
struct wss_softc *sc;
int unit = AUDIOUNIT(dev);
if (unit >= wsscd.cd_ndevs)
return ENODEV;
sc = wsscd.cd_devs[unit];
if (!sc)
return ENXIO;
return ad1848_open(&sc->sc_ad1848, dev, flags);
}
int
wss_getdev(addr, retp)
void *addr;
struct audio_device *retp;
{
*retp = wss_device;
return 0;
}
int
wss_setfd(addr, flag)
void *addr;
int flag;
{
/* Can't do full-duplex */
return(ENOTTY);
}
int
wss_set_out_port(addr, port)
void *addr;
int port;
{
DPRINTF(("wss_set_out_port:\n"));
return(EINVAL);
}
int
wss_get_out_port(addr)
void *addr;
{
DPRINTF(("wss_get_out_port:\n"));
return(EINVAL);
}
int
wss_set_in_port(addr, port)
void *addr;
int port;
{
register struct ad1848_softc *ac = addr;
register struct wss_softc *sc = ac->parent;
DPRINTF(("wss_set_in_port: %d\n", port));
switch(port) {
case WSS_MIC_IN_LVL:
port = MIC_IN_PORT;
break;
case WSS_LINE_IN_LVL:
port = LINE_IN_PORT;
break;
case WSS_DAC_LVL:
port = DAC_IN_PORT;
break;
default:
return(EINVAL);
/*NOTREACHED*/
}
return(ad1848_set_rec_port(ac, port));
}
int
wss_get_in_port(addr)
void *addr;
{
register struct ad1848_softc *ac = addr;
register struct wss_softc *sc = ac->parent;
int port = WSS_MIC_IN_LVL;
switch(ad1848_get_rec_port(ac)) {
case MIC_IN_PORT:
port = WSS_MIC_IN_LVL;
break;
case LINE_IN_PORT:
port = WSS_LINE_IN_LVL;
break;
case DAC_IN_PORT:
port = WSS_DAC_LVL;
break;
}
DPRINTF(("wss_get_in_port: %d\n", port));
return(port);
}
int
wss_mixer_set_port(addr, cp)
void *addr;
mixer_ctrl_t *cp;
{
register struct ad1848_softc *ac = addr;
register struct wss_softc *sc = ac->parent;
struct ad1848_volume vol;
u_char eq;
int error = EINVAL;
DPRINTF(("wss_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
switch (cp->dev) {
case WSS_MIC_IN_LVL: /* Microphone */
if (cp->type == AUDIO_MIXER_VALUE) {
if (wss_to_vol(cp, &vol))
error = ad1848_set_aux2_gain(ac, &vol);
}
break;
case WSS_MIC_IN_MUTE: /* Microphone */
if (cp->type == AUDIO_MIXER_ENUM) {
sc->mic_mute = cp->un.ord;
DPRINTF(("mic mute %d\n", cp->un.ord));
error = 0;
}
break;
case WSS_LINE_IN_LVL: /* linein/CD */
if (cp->type == AUDIO_MIXER_VALUE) {
if (wss_to_vol(cp, &vol))
error = ad1848_set_aux1_gain(ac, &vol);
}
break;
case WSS_LINE_IN_MUTE: /* linein/CD */
if (cp->type == AUDIO_MIXER_ENUM) {
sc->cd_mute = cp->un.ord;
DPRINTF(("CD mute %d\n", cp->un.ord));
error = 0;
}
break;
case WSS_DAC_LVL: /* dac out */
if (cp->type == AUDIO_MIXER_VALUE) {
if (wss_to_vol(cp, &vol))
error = ad1848_set_out_gain(ac, &vol);
}
break;
case WSS_DAC_MUTE: /* dac out */
if (cp->type == AUDIO_MIXER_ENUM) {
sc->dac_mute = cp->un.ord;
DPRINTF(("DAC mute %d\n", cp->un.ord));
error = 0;
}
break;
case WSS_REC_LVL: /* record level */
if (cp->type == AUDIO_MIXER_VALUE) {
if (wss_to_vol(cp, &vol))
error = ad1848_set_rec_gain(ac, &vol);
}
break;
case WSS_RECORD_SOURCE:
if (cp->type == AUDIO_MIXER_ENUM) {
error = ad1848_set_rec_port(ac, cp->un.ord);
}
break;
case WSS_MON_LVL:
if (cp->type == AUDIO_MIXER_VALUE && cp->un.value.num_channels == 1) {
vol.left = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
error = ad1848_set_mon_gain(ac, &vol);
}
break;
default:
return ENXIO;
/*NOTREACHED*/
}
return 0;
}
int
wss_mixer_get_port(addr, cp)
void *addr;
mixer_ctrl_t *cp;
{
register struct ad1848_softc *ac = addr;
register struct wss_softc *sc = ac->parent;
struct ad1848_volume vol;
u_char eq;
int error = EINVAL;
DPRINTF(("wss_mixer_get_port: port=%d\n", cp->dev));
switch (cp->dev) {
case WSS_MIC_IN_LVL: /* Microphone */
if (cp->type == AUDIO_MIXER_VALUE) {
error = ad1848_get_aux2_gain(ac, &vol);
if (!error)
wss_from_vol(cp, &vol);
}
break;
case WSS_MIC_IN_MUTE:
if (cp->type == AUDIO_MIXER_ENUM) {
cp->un.ord = sc->mic_mute;
error = 0;
}
break;
case WSS_LINE_IN_LVL: /* linein/CD */
if (cp->type == AUDIO_MIXER_VALUE) {
error = ad1848_get_aux1_gain(ac, &vol);
if (!error)
wss_from_vol(cp, &vol);
}
break;
case WSS_LINE_IN_MUTE:
if (cp->type == AUDIO_MIXER_ENUM) {
cp->un.ord = sc->cd_mute;
error = 0;
}
break;
case WSS_DAC_LVL: /* dac out */
if (cp->type == AUDIO_MIXER_VALUE) {
error = ad1848_get_out_gain(ac, &vol);
if (!error)
wss_from_vol(cp, &vol);
}
break;
case WSS_DAC_MUTE:
if (cp->type == AUDIO_MIXER_ENUM) {
cp->un.ord = sc->dac_mute;
error = 0;
}
break;
case WSS_REC_LVL: /* record level */
if (cp->type == AUDIO_MIXER_VALUE) {
error = ad1848_get_rec_gain(ac, &vol);
if (!error)
wss_from_vol(cp, &vol);
}
break;
case WSS_RECORD_SOURCE:
if (cp->type == AUDIO_MIXER_ENUM) {
cp->un.ord = ad1848_get_rec_port(ac);
error = 0;
}
break;
case WSS_MON_LVL: /* monitor level */
if (cp->type == AUDIO_MIXER_VALUE && cp->un.value.num_channels == 1) {
error = ad1848_get_mon_gain(ac, &vol);
if (!error)
cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol.left;
}
break;
default:
error = ENXIO;
break;
}
return(error);
}
int
wss_query_devinfo(addr, dip)
void *addr;
register mixer_devinfo_t *dip;
{
register struct ad1848_softc *ac = addr;
register struct wss_softc *sc = ac->parent;
DPRINTF(("wss_query_devinfo: index=%d\n", dip->index));
switch(dip->index) {
case WSS_MIC_IN_LVL: /* Microphone */
dip->type = AUDIO_MIXER_VALUE;
dip->mixer_class = WSS_INPUT_CLASS;
dip->prev = AUDIO_MIXER_LAST;
dip->next = WSS_MIC_IN_MUTE;
strcpy(dip->label.name, AudioNmicrophone);
dip->un.v.num_channels = 2;
strcpy(dip->un.v.units.name, AudioNvolume);
break;
case WSS_LINE_IN_LVL: /* line/CD */
dip->type = AUDIO_MIXER_VALUE;
dip->mixer_class = WSS_INPUT_CLASS;
dip->prev = AUDIO_MIXER_LAST;
dip->next = WSS_LINE_IN_MUTE;
strcpy(dip->label.name, AudioNcd);
dip->un.v.num_channels = 2;
strcpy(dip->un.v.units.name, AudioNvolume);
break;
case WSS_DAC_LVL: /* dacout */
dip->type = AUDIO_MIXER_VALUE;
dip->mixer_class = WSS_INPUT_CLASS;
dip->prev = AUDIO_MIXER_LAST;
dip->next = WSS_DAC_MUTE;
strcpy(dip->label.name, AudioNdac);
dip->un.v.num_channels = 2;
strcpy(dip->un.v.units.name, AudioNvolume);
break;
case WSS_REC_LVL: /* record level */
dip->type = AUDIO_MIXER_VALUE;
dip->mixer_class = WSS_RECORD_CLASS;
dip->prev = AUDIO_MIXER_LAST;
dip->next = WSS_RECORD_SOURCE;
strcpy(dip->label.name, AudioNrecord);
dip->un.v.num_channels = 2;
strcpy(dip->un.v.units.name, AudioNvolume);
break;
case WSS_MON_LVL: /* monitor level */
dip->type = AUDIO_MIXER_VALUE;
dip->mixer_class = WSS_MONITOR_CLASS;
dip->next = dip->prev = AUDIO_MIXER_LAST;
strcpy(dip->label.name, AudioNmonitor);
dip->un.v.num_channels = 1;
strcpy(dip->un.v.units.name, AudioNvolume);
break;
case WSS_INPUT_CLASS: /* input class descriptor */
dip->type = AUDIO_MIXER_CLASS;
dip->mixer_class = WSS_INPUT_CLASS;
dip->next = dip->prev = AUDIO_MIXER_LAST;
strcpy(dip->label.name, AudioCInputs);
break;
case WSS_MONITOR_CLASS: /* monitor class descriptor */
dip->type = AUDIO_MIXER_CLASS;
dip->mixer_class = WSS_MONITOR_CLASS;
dip->next = dip->prev = AUDIO_MIXER_LAST;
strcpy(dip->label.name, AudioNmonitor);
break;
case WSS_RECORD_CLASS: /* record source class */
dip->type = AUDIO_MIXER_CLASS;
dip->mixer_class = WSS_RECORD_CLASS;
dip->next = dip->prev = AUDIO_MIXER_LAST;
strcpy(dip->label.name, AudioNrecord);
break;
case WSS_MIC_IN_MUTE:
dip->mixer_class = WSS_INPUT_CLASS;
dip->type = AUDIO_MIXER_ENUM;
dip->prev = WSS_MIC_IN_LVL;
dip->next = AUDIO_MIXER_LAST;
goto mute;
case WSS_LINE_IN_MUTE:
dip->mixer_class = WSS_INPUT_CLASS;
dip->type = AUDIO_MIXER_ENUM;
dip->prev = WSS_LINE_IN_LVL;
dip->next = AUDIO_MIXER_LAST;
goto mute;
case WSS_DAC_MUTE:
dip->mixer_class = WSS_INPUT_CLASS;
dip->type = AUDIO_MIXER_ENUM;
dip->prev = WSS_DAC_LVL;
dip->next = AUDIO_MIXER_LAST;
mute:
strcpy(dip->label.name, AudioNmute);
dip->un.e.num_mem = 2;
strcpy(dip->un.e.member[0].label.name, AudioNoff);
dip->un.e.member[0].ord = 0;
strcpy(dip->un.e.member[1].label.name, AudioNon);
dip->un.e.member[1].ord = 1;
break;
case WSS_RECORD_SOURCE:
dip->mixer_class = WSS_RECORD_CLASS;
dip->type = AUDIO_MIXER_ENUM;
dip->prev = WSS_REC_LVL;
dip->next = AUDIO_MIXER_LAST;
strcpy(dip->label.name, AudioNsource);
dip->un.e.num_mem = 3;
strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
dip->un.e.member[0].ord = WSS_MIC_IN_LVL;
strcpy(dip->un.e.member[1].label.name, AudioNcd);
dip->un.e.member[1].ord = WSS_LINE_IN_LVL;
strcpy(dip->un.e.member[2].label.name, AudioNdac);
dip->un.e.member[2].ord = WSS_DAC_LVL;
break;
default:
return ENXIO;
/*NOTREACHED*/
}
DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
return 0;
}

View File

@ -1,62 +0,0 @@
/* $NetBSD: wssreg.h,v 1.1 1995/02/21 02:28:43 brezak Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $Id: wssreg.h,v 1.1 1995/02/21 02:28:43 brezak Exp $
*/
/*
* Copyright (c) 1993 Analog Devices Inc. All rights reserved
*/
#define WSS_NPORT 8
/*
* Macros to detect valid hardware configuration data.
*/
#define WSS_IRQ_VALID(mask) ((mask) & 0x00ac) /* IRQ 2,3,5,7 */
#define WSS_BASE_VALID(base) ((base) == 0x0530 || \
(base) == 0x0604 || \
(base) == 0x0e80 || \
(base) == 0x0f40)
/* Default WSS base */
/* WSS registers */
#define WSS_BASE_ADDRESS 0x0530
/* WSS registers */
#define WSS_CONFIG 0x00
#define WSS_STATUS 0x03
#define WSS_VERS 0x04
#define WSS_16SLOT 0x80
#define WSS_DUALDMA 0x40