Home | History | Annotate | Line # | Download | only in isa
sbdsp.c revision 1.1
      1  1.1  brezak /*	$NetBSD: sbdsp.c,v 1.1 1995/02/21 02:28:08 brezak Exp $	*/
      2  1.1  brezak 
      3  1.1  brezak /*
      4  1.1  brezak  * Copyright (c) 1991-1993 Regents of the University of California.
      5  1.1  brezak  * All rights reserved.
      6  1.1  brezak  *
      7  1.1  brezak  * Redistribution and use in source and binary forms, with or without
      8  1.1  brezak  * modification, are permitted provided that the following conditions
      9  1.1  brezak  * are met:
     10  1.1  brezak  * 1. Redistributions of source code must retain the above copyright
     11  1.1  brezak  *    notice, this list of conditions and the following disclaimer.
     12  1.1  brezak  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  brezak  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  brezak  *    documentation and/or other materials provided with the distribution.
     15  1.1  brezak  * 3. All advertising materials mentioning features or use of this software
     16  1.1  brezak  *    must display the following acknowledgement:
     17  1.1  brezak  *	This product includes software developed by the Computer Systems
     18  1.1  brezak  *	Engineering Group at Lawrence Berkeley Laboratory.
     19  1.1  brezak  * 4. Neither the name of the University nor of the Laboratory may be used
     20  1.1  brezak  *    to endorse or promote products derived from this software without
     21  1.1  brezak  *    specific prior written permission.
     22  1.1  brezak  *
     23  1.1  brezak  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  1.1  brezak  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.1  brezak  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.1  brezak  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  1.1  brezak  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.1  brezak  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.1  brezak  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.1  brezak  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.1  brezak  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.1  brezak  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.1  brezak  * SUCH DAMAGE.
     34  1.1  brezak  *
     35  1.1  brezak  *	$Id: sbdsp.c,v 1.1 1995/02/21 02:28:08 brezak Exp $
     36  1.1  brezak  */
     37  1.1  brezak /*
     38  1.1  brezak  * SoundBlaster Pro code provided by John Kohl, based on lots of
     39  1.1  brezak  * information he gleaned from Steve Haehnichen <steve (at) vigra.com>'s
     40  1.1  brezak  * SBlast driver for 386BSD and DOS driver code from Daniel Sachs
     41  1.1  brezak  * <sachs (at) meibm15.cen.uiuc.edu>.
     42  1.1  brezak  */
     43  1.1  brezak 
     44  1.1  brezak #include <sys/param.h>
     45  1.1  brezak #include <sys/systm.h>
     46  1.1  brezak #include <sys/errno.h>
     47  1.1  brezak #include <sys/ioctl.h>
     48  1.1  brezak #include <sys/syslog.h>
     49  1.1  brezak #include <sys/device.h>
     50  1.1  brezak #include <sys/proc.h>
     51  1.1  brezak #include <sys/buf.h>
     52  1.1  brezak #include <vm/vm.h>
     53  1.1  brezak 
     54  1.1  brezak #include <machine/cpu.h>
     55  1.1  brezak #include <machine/pio.h>
     56  1.1  brezak 
     57  1.1  brezak #include <sys/audioio.h>
     58  1.1  brezak #include <dev/audio_if.h>
     59  1.1  brezak 
     60  1.1  brezak #include <i386/isa/isavar.h>
     61  1.1  brezak #include <i386/isa/dmavar.h>
     62  1.1  brezak #include <i386/isa/icu.h>
     63  1.1  brezak 
     64  1.1  brezak #include <i386/isa/sbreg.h>
     65  1.1  brezak #include <i386/isa/sbdspvar.h>
     66  1.1  brezak 
     67  1.1  brezak #ifdef DEBUG
     68  1.1  brezak extern void Dprintf __P((const char *, ...));
     69  1.1  brezak 
     70  1.1  brezak #define DPRINTF(x)	if (sbdspdebug) printf x
     71  1.1  brezak int	sbdspdebug = 0;
     72  1.1  brezak #else
     73  1.1  brezak #define DPRINTF(x)
     74  1.1  brezak #endif
     75  1.1  brezak 
     76  1.1  brezak #ifndef NEWCONFIG
     77  1.1  brezak #define at_dma(flags, ptr, cc, chan)	isa_dmastart(flags, ptr, cc, chan)
     78  1.1  brezak #endif
     79  1.1  brezak 
     80  1.1  brezak #ifndef SBDSP_NPOLL
     81  1.1  brezak #define SBDSP_NPOLL 3000
     82  1.1  brezak #endif
     83  1.1  brezak 
     84  1.1  brezak struct {
     85  1.1  brezak 	int wdsp;
     86  1.1  brezak 	int rdsp;
     87  1.1  brezak 	int wmidi;
     88  1.1  brezak } sberr;
     89  1.1  brezak 
     90  1.1  brezak extern struct audio_device sb_device;
     91  1.1  brezak 
     92  1.1  brezak #ifdef DEBUG
     93  1.1  brezak void
     94  1.1  brezak sb_printsc(struct sbdsp_softc *sc)
     95  1.1  brezak {
     96  1.1  brezak 	int i;
     97  1.1  brezak 
     98  1.1  brezak 	printf("open %d dmachan %d iobase %x locked %d\n", sc->sc_open, sc->sc_drq,
     99  1.1  brezak 		sc->sc_iobase, sc->sc_locked);
    100  1.1  brezak 	printf("hispeed %d irate %d orate %d encoding %x\n",
    101  1.1  brezak 		sc->sc_adacmode, sc->sc_irate, sc->sc_orate, sc->encoding);
    102  1.1  brezak 	printf("outport %d inport %d spkron %d nintr %d\n",
    103  1.1  brezak 		sc->out_port, sc->in_port, sc->spkr_state, sc->sc_interrupts);
    104  1.1  brezak 	printf("tc %x chans %x scintr %x arg %x\n", sc->sc_adactc, sc->sc_chans,
    105  1.1  brezak 		sc->sc_intr, sc->sc_arg);
    106  1.1  brezak 	printf("gain: ");
    107  1.1  brezak 	for (i = 0; i < SB_NDEVS; i++)
    108  1.1  brezak 	    printf("%d ", sc->gain[i]);
    109  1.1  brezak 	printf("\n");
    110  1.1  brezak }
    111  1.1  brezak #endif
    112  1.1  brezak 
    113  1.1  brezak /*
    114  1.1  brezak  * Probe / attach routines.
    115  1.1  brezak  */
    116  1.1  brezak 
    117  1.1  brezak /*
    118  1.1  brezak  * Probe for the soundblaster hardware.
    119  1.1  brezak  */
    120  1.1  brezak int
    121  1.1  brezak sbdsp_probe(sc)
    122  1.1  brezak 	struct sbdsp_softc *sc;
    123  1.1  brezak {
    124  1.1  brezak 	register u_short iobase = sc->sc_iobase;
    125  1.1  brezak 
    126  1.1  brezak 	if (sbdsp_reset(sc) < 0) {
    127  1.1  brezak 		DPRINTF(("sbdsp: couldn't reset card\n"));
    128  1.1  brezak 		return 0;
    129  1.1  brezak 	}
    130  1.1  brezak 	sc->sc_model = sbversion(sc);
    131  1.1  brezak 
    132  1.1  brezak 	return 1;
    133  1.1  brezak }
    134  1.1  brezak 
    135  1.1  brezak /*
    136  1.1  brezak  * Attach hardware to driver, attach hardware driver to audio
    137  1.1  brezak  * pseudo-device driver .
    138  1.1  brezak  */
    139  1.1  brezak void
    140  1.1  brezak sbdsp_attach(sc)
    141  1.1  brezak 	struct sbdsp_softc *sc;
    142  1.1  brezak {
    143  1.1  brezak 	register u_short iobase = sc->sc_iobase;
    144  1.1  brezak 
    145  1.1  brezak 	sc->sc_locked = 0;
    146  1.1  brezak 
    147  1.1  brezak #ifdef NEWCONFIG
    148  1.1  brezak 	/*
    149  1.1  brezak 	 * We limit DMA transfers to a page, and use the generic DMA handling
    150  1.1  brezak 	 * code in isa.c.  This code can end up copying a buffer, but since
    151  1.1  brezak 	 * the audio driver uses relative small buffers this isn't likely.
    152  1.1  brezak 	 *
    153  1.1  brezak 	 * This allocation scheme means that the maximum transfer is limited
    154  1.1  brezak 	 * by the page size (rather than 64k).  This is reasonable.  For 4K
    155  1.1  brezak 	 * pages, the transfer time at 48KHz is 4096 / 48000 = 85ms.  This
    156  1.1  brezak 	 * is plenty long enough to amortize any fixed time overhead.
    157  1.1  brezak 	 */
    158  1.1  brezak 	at_setup_dmachan(sc->sc_drq, NBPG);
    159  1.1  brezak #endif
    160  1.1  brezak 
    161  1.1  brezak 	/* Set defaults */
    162  1.1  brezak 	if (ISSBPROCLASS(sc))
    163  1.1  brezak 	    sc->sc_irate = sc->sc_orate = 45454;
    164  1.1  brezak   	else
    165  1.1  brezak 	    sc->sc_irate = sc->sc_orate = 14925;
    166  1.1  brezak 	sc->sc_chans = 1;
    167  1.1  brezak 	sc->encoding = AUDIO_ENCODING_LINEAR;
    168  1.1  brezak 
    169  1.1  brezak 	(void) sbdsp_set_in_sr_real((caddr_t)sc, sc->sc_irate);
    170  1.1  brezak 	(void) sbdsp_set_out_sr_real((caddr_t)sc, sc->sc_orate);
    171  1.1  brezak 
    172  1.1  brezak 	(void) sbdsp_set_in_port((caddr_t)sc, SB_MIC_PORT);
    173  1.1  brezak 	(void) sbdsp_set_out_port((caddr_t)sc, SB_SPEAKER);
    174  1.1  brezak 
    175  1.1  brezak 	if (ISSBPROCLASS(sc)) {
    176  1.1  brezak 		int i;
    177  1.1  brezak 
    178  1.1  brezak 		/* set mixer to default levels, by sending a mixer
    179  1.1  brezak                    reset command. */
    180  1.1  brezak 		sbdsp_mix_write(sc, SBP_MIX_RESET, SBP_MIX_RESET);
    181  1.1  brezak 		/* then some adjustments :) */
    182  1.1  brezak 		sbdsp_mix_write(sc, SBP_CD_VOL,
    183  1.1  brezak 				sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
    184  1.1  brezak 		sbdsp_mix_write(sc, SBP_DAC_VOL,
    185  1.1  brezak 				sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
    186  1.1  brezak 		sbdsp_mix_write(sc, SBP_MASTER_VOL,
    187  1.1  brezak 				sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
    188  1.1  brezak 		sbdsp_mix_write(sc, SBP_LINE_VOL,
    189  1.1  brezak 				sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
    190  1.1  brezak 		for (i = 0; i < SB_NDEVS; i++)
    191  1.1  brezak 		    sc->gain[i] = sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL);
    192  1.1  brezak 	}
    193  1.1  brezak 	printf(": dsp v%d.%d\n",
    194  1.1  brezak 	       SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model));
    195  1.1  brezak 	sb_device.version[0] = '0' + SBVER_MAJOR(sc->sc_model);
    196  1.1  brezak 	sb_device.version[1] = '.';
    197  1.1  brezak 	sb_device.version[2] = '0' + SBVER_MINOR(sc->sc_model);
    198  1.1  brezak 	sb_device.version[3] = '\0';
    199  1.1  brezak }
    200  1.1  brezak 
    201  1.1  brezak /*
    202  1.1  brezak  * Various routines to interface to higher level audio driver
    203  1.1  brezak  */
    204  1.1  brezak 
    205  1.1  brezak void
    206  1.1  brezak sbdsp_mix_write(sc, mixerport, val)
    207  1.1  brezak 	struct sbdsp_softc *sc;
    208  1.1  brezak 	int mixerport;
    209  1.1  brezak 	int val;
    210  1.1  brezak {
    211  1.1  brezak 	int iobase = sc->sc_iobase;
    212  1.1  brezak 	outb(iobase + SBP_MIXER_ADDR, mixerport);
    213  1.1  brezak 	delay(10);
    214  1.1  brezak 	outb(iobase + SBP_MIXER_DATA, val);
    215  1.1  brezak 	delay(30);
    216  1.1  brezak }
    217  1.1  brezak 
    218  1.1  brezak int
    219  1.1  brezak sbdsp_mix_read(sc, mixerport)
    220  1.1  brezak 	struct sbdsp_softc *sc;
    221  1.1  brezak 	int mixerport;
    222  1.1  brezak {
    223  1.1  brezak 	int iobase = sc->sc_iobase;
    224  1.1  brezak 	outb(iobase + SBP_MIXER_ADDR, mixerport);
    225  1.1  brezak 	delay(10);
    226  1.1  brezak 	return inb(iobase + SBP_MIXER_DATA);
    227  1.1  brezak }
    228  1.1  brezak 
    229  1.1  brezak int
    230  1.1  brezak sbdsp_set_in_sr(addr, sr)
    231  1.1  brezak 	caddr_t addr;
    232  1.1  brezak 	u_long sr;
    233  1.1  brezak {
    234  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    235  1.1  brezak 
    236  1.1  brezak 	sc->sc_irate = sr;
    237  1.1  brezak 
    238  1.1  brezak 	return 0;
    239  1.1  brezak }
    240  1.1  brezak 
    241  1.1  brezak int
    242  1.1  brezak sbdsp_set_in_sr_real(addr, sr)
    243  1.1  brezak 	caddr_t addr;
    244  1.1  brezak 	u_long sr;
    245  1.1  brezak {
    246  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    247  1.1  brezak 	int rval;
    248  1.1  brezak 
    249  1.1  brezak 	if (rval = sbdsp_set_sr(sc, &sr, SB_INPUT_RATE))
    250  1.1  brezak 		return rval;
    251  1.1  brezak 	sc->sc_irate = sr;
    252  1.1  brezak 	sc->sc_dmain_inprogress = 0;		/* do it again on next DMA out */
    253  1.1  brezak 	sc->sc_dmaout_inprogress = 0;
    254  1.1  brezak 	return(0);
    255  1.1  brezak }
    256  1.1  brezak 
    257  1.1  brezak u_long
    258  1.1  brezak sbdsp_get_in_sr(addr)
    259  1.1  brezak 	caddr_t addr;
    260  1.1  brezak {
    261  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    262  1.1  brezak 
    263  1.1  brezak 	return(sc->sc_irate);
    264  1.1  brezak }
    265  1.1  brezak 
    266  1.1  brezak int
    267  1.1  brezak sbdsp_set_out_sr(addr, sr)
    268  1.1  brezak 	caddr_t addr;
    269  1.1  brezak 	u_long sr;
    270  1.1  brezak {
    271  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    272  1.1  brezak 
    273  1.1  brezak 	sc->sc_orate = sr;
    274  1.1  brezak 	return(0);
    275  1.1  brezak }
    276  1.1  brezak 
    277  1.1  brezak int
    278  1.1  brezak sbdsp_set_out_sr_real(addr, sr)
    279  1.1  brezak 	caddr_t addr;
    280  1.1  brezak 	u_long sr;
    281  1.1  brezak {
    282  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    283  1.1  brezak 	int rval;
    284  1.1  brezak 
    285  1.1  brezak 	if (rval = sbdsp_set_sr(sc, &sr, SB_OUTPUT_RATE))
    286  1.1  brezak 		return rval;
    287  1.1  brezak 	sc->sc_orate = sr;
    288  1.1  brezak 	sc->sc_dmain_inprogress = 0;		/* do it again on next DMA out */
    289  1.1  brezak 	return(0);
    290  1.1  brezak }
    291  1.1  brezak 
    292  1.1  brezak u_long
    293  1.1  brezak sbdsp_get_out_sr(addr)
    294  1.1  brezak 	caddr_t addr;
    295  1.1  brezak {
    296  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    297  1.1  brezak 
    298  1.1  brezak 	return(sc->sc_orate);
    299  1.1  brezak }
    300  1.1  brezak 
    301  1.1  brezak int
    302  1.1  brezak sbdsp_query_encoding(addr, fp)
    303  1.1  brezak     caddr_t addr;
    304  1.1  brezak     struct audio_encoding *fp;
    305  1.1  brezak {
    306  1.1  brezak     register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    307  1.1  brezak 
    308  1.1  brezak     switch (fp->index) {
    309  1.1  brezak     case 0:
    310  1.1  brezak 	strcpy(fp->name, "MU-Law");
    311  1.1  brezak 	fp->format_id = AUDIO_ENCODING_ULAW;
    312  1.1  brezak 	break;
    313  1.1  brezak     case 2:
    314  1.1  brezak 	strcpy(fp->name, "pcm16");
    315  1.1  brezak 	fp->format_id = AUDIO_ENCODING_PCM16;
    316  1.1  brezak 	break;
    317  1.1  brezak     default:
    318  1.1  brezak 	return(EINVAL);
    319  1.1  brezak 	/*NOTREACHED*/
    320  1.1  brezak     }
    321  1.1  brezak     return (0);
    322  1.1  brezak }
    323  1.1  brezak 
    324  1.1  brezak int
    325  1.1  brezak sbdsp_set_encoding(addr, enc)
    326  1.1  brezak 	caddr_t addr;
    327  1.1  brezak 	u_int enc;
    328  1.1  brezak {
    329  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    330  1.1  brezak 
    331  1.1  brezak 	switch(enc){
    332  1.1  brezak 	case AUDIO_ENCODING_ULAW:
    333  1.1  brezak 		sc->encoding = AUDIO_ENCODING_ULAW;
    334  1.1  brezak 		break;
    335  1.1  brezak 	case AUDIO_ENCODING_LINEAR:
    336  1.1  brezak 		sc->encoding = AUDIO_ENCODING_LINEAR;
    337  1.1  brezak 		break;
    338  1.1  brezak 	default:
    339  1.1  brezak 		return (EINVAL);
    340  1.1  brezak 	}
    341  1.1  brezak 	return (0);
    342  1.1  brezak }
    343  1.1  brezak 
    344  1.1  brezak int
    345  1.1  brezak sbdsp_get_encoding(addr)
    346  1.1  brezak 	caddr_t addr;
    347  1.1  brezak {
    348  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    349  1.1  brezak 
    350  1.1  brezak 	return(sc->encoding);
    351  1.1  brezak }
    352  1.1  brezak 
    353  1.1  brezak int
    354  1.1  brezak sbdsp_set_precision(addr, prec)
    355  1.1  brezak 	caddr_t addr;
    356  1.1  brezak 	u_int prec;
    357  1.1  brezak {
    358  1.1  brezak 
    359  1.1  brezak 	if (prec != 8)
    360  1.1  brezak 		return(EINVAL);
    361  1.1  brezak 	return(0);
    362  1.1  brezak }
    363  1.1  brezak 
    364  1.1  brezak int
    365  1.1  brezak sbdsp_get_precision(addr)
    366  1.1  brezak 	caddr_t addr;
    367  1.1  brezak {
    368  1.1  brezak 	return(8);
    369  1.1  brezak }
    370  1.1  brezak 
    371  1.1  brezak int
    372  1.1  brezak sbdsp_set_channels(addr, chans)
    373  1.1  brezak 	caddr_t addr;
    374  1.1  brezak 	int chans;
    375  1.1  brezak {
    376  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    377  1.1  brezak 	int rval;
    378  1.1  brezak 
    379  1.1  brezak 	if (ISSBPROCLASS(sc)) {
    380  1.1  brezak 		if (chans != 1 && chans != 2)
    381  1.1  brezak 			return(EINVAL);
    382  1.1  brezak 
    383  1.1  brezak 		sc->sc_chans = chans;
    384  1.1  brezak 		if (rval = sbdsp_set_in_sr_real(addr, sc->sc_irate))
    385  1.1  brezak 		    return rval;
    386  1.1  brezak 		sbdsp_mix_write(sc, SBP_STEREO,
    387  1.1  brezak 				(sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
    388  1.1  brezak 				(chans == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
    389  1.1  brezak 		/* recording channels needs to be done right when we start
    390  1.1  brezak 		   DMA recording.  Just record number of channels for now
    391  1.1  brezak 		   and set stereo when ready. */
    392  1.1  brezak 	}
    393  1.1  brezak 	else {
    394  1.1  brezak 		if (chans != 1)
    395  1.1  brezak 			return(EINVAL);
    396  1.1  brezak 		sc->sc_chans = 1;
    397  1.1  brezak 	}
    398  1.1  brezak 
    399  1.1  brezak 	return(0);
    400  1.1  brezak }
    401  1.1  brezak 
    402  1.1  brezak int
    403  1.1  brezak sbdsp_get_channels(addr)
    404  1.1  brezak 	caddr_t addr;
    405  1.1  brezak {
    406  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    407  1.1  brezak 
    408  1.1  brezak #if 0
    409  1.1  brezak 	/* recording stereo may frob the mixer output */
    410  1.1  brezak 	if (ISSBPROCLASS(sc)) {
    411  1.1  brezak 		if ((sbdsp_mix_read(sc, SBP_STEREO) & SBP_PLAYMODE_MASK) == SBP_PLAYMODE_STEREO) {
    412  1.1  brezak 			sc->sc_chans = 2;
    413  1.1  brezak 		}
    414  1.1  brezak 		else {
    415  1.1  brezak 			sc->sc_chans = 1;
    416  1.1  brezak 		}
    417  1.1  brezak 	}
    418  1.1  brezak 	else {
    419  1.1  brezak 		sc->sc_chans = 1;
    420  1.1  brezak 	}
    421  1.1  brezak #endif
    422  1.1  brezak 
    423  1.1  brezak 	return(sc->sc_chans);
    424  1.1  brezak }
    425  1.1  brezak 
    426  1.1  brezak int
    427  1.1  brezak sbdsp_set_out_port(addr, port)
    428  1.1  brezak 	caddr_t addr;
    429  1.1  brezak 	int port;
    430  1.1  brezak {
    431  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    432  1.1  brezak 
    433  1.1  brezak 	sc->out_port = port; /* Just record it */
    434  1.1  brezak 
    435  1.1  brezak 	return(0);
    436  1.1  brezak }
    437  1.1  brezak 
    438  1.1  brezak int
    439  1.1  brezak sbdsp_get_out_port(addr)
    440  1.1  brezak 	caddr_t addr;
    441  1.1  brezak {
    442  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    443  1.1  brezak 
    444  1.1  brezak 	return(sc->out_port);
    445  1.1  brezak }
    446  1.1  brezak 
    447  1.1  brezak 
    448  1.1  brezak int
    449  1.1  brezak sbdsp_set_in_port(addr, port)
    450  1.1  brezak 	caddr_t addr;
    451  1.1  brezak 	int port;
    452  1.1  brezak {
    453  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    454  1.1  brezak 	int mixport, sbport;
    455  1.1  brezak 
    456  1.1  brezak 	switch (port) {
    457  1.1  brezak 	case SB_MIC_PORT:
    458  1.1  brezak 	    sbport = SBP_FROM_MIC;
    459  1.1  brezak 	    mixport = SBP_MIC_VOL;
    460  1.1  brezak 	    break;
    461  1.1  brezak 	}
    462  1.1  brezak 
    463  1.1  brezak 	if (ISSBPROCLASS(sc)) {
    464  1.1  brezak 	    switch (port) {
    465  1.1  brezak 	    case SB_LINE_IN_PORT:
    466  1.1  brezak 		sbport = SBP_FROM_LINE;
    467  1.1  brezak 		mixport = SBP_LINE_VOL;
    468  1.1  brezak 		break;
    469  1.1  brezak 	    case SB_CD_PORT:
    470  1.1  brezak 		sbport = SBP_FROM_CD;
    471  1.1  brezak 		mixport = SBP_CD_VOL;
    472  1.1  brezak 		break;
    473  1.1  brezak 	    case SB_DAC_PORT:
    474  1.1  brezak 	    case SB_FM_PORT:
    475  1.1  brezak 	    default:
    476  1.1  brezak 		return(EINVAL);
    477  1.1  brezak 		/*NOTREACHED*/
    478  1.1  brezak 	    }
    479  1.1  brezak 	}
    480  1.1  brezak 	else {
    481  1.1  brezak 	    return(EINVAL);
    482  1.1  brezak 	    /*NOTREACHED*/
    483  1.1  brezak 	}
    484  1.1  brezak 
    485  1.1  brezak 	sc->in_port = port;	/* Just record it */
    486  1.1  brezak 
    487  1.1  brezak 	if (ISSBPROCLASS(sc)) {
    488  1.1  brezak 		/* record from that port */
    489  1.1  brezak 		sbdsp_mix_write(sc, SBP_RECORD_SOURCE,
    490  1.1  brezak 				SBP_RECORD_FROM(sbport, SBP_FILTER_OFF,
    491  1.1  brezak 						SBP_FILTER_HIGH));
    492  1.1  brezak 		/* fetch gain from that port */
    493  1.1  brezak 		sc->gain[port] = sbdsp_mix_read(sc, mixport);
    494  1.1  brezak 	}
    495  1.1  brezak 
    496  1.1  brezak 	return(0);
    497  1.1  brezak }
    498  1.1  brezak 
    499  1.1  brezak int
    500  1.1  brezak sbdsp_get_in_port(addr)
    501  1.1  brezak 	caddr_t addr;
    502  1.1  brezak {
    503  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    504  1.1  brezak 
    505  1.1  brezak 	return(sc->in_port);
    506  1.1  brezak }
    507  1.1  brezak 
    508  1.1  brezak 
    509  1.1  brezak int
    510  1.1  brezak sbdsp_speaker_ctl(addr, newstate)
    511  1.1  brezak 	caddr_t addr;
    512  1.1  brezak 	int newstate;
    513  1.1  brezak {
    514  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    515  1.1  brezak 
    516  1.1  brezak 	if ((newstate == SPKR_ON) &&
    517  1.1  brezak 	    (sc->spkr_state == SPKR_OFF)) {
    518  1.1  brezak 		sbdsp_spkron(sc);
    519  1.1  brezak 		sc->spkr_state = SPKR_ON;
    520  1.1  brezak 	}
    521  1.1  brezak 	if ((newstate == SPKR_OFF) &&
    522  1.1  brezak 	    (sc->spkr_state == SPKR_ON)) {
    523  1.1  brezak 		sbdsp_spkroff(sc);
    524  1.1  brezak 		sc->spkr_state = SPKR_OFF;
    525  1.1  brezak 	}
    526  1.1  brezak 	return(0);
    527  1.1  brezak }
    528  1.1  brezak 
    529  1.1  brezak int
    530  1.1  brezak sbdsp_round_blocksize(addr, blk)
    531  1.1  brezak 	caddr_t addr;
    532  1.1  brezak 	int blk;
    533  1.1  brezak {
    534  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    535  1.1  brezak 
    536  1.1  brezak 	sc->sc_last_hsr_size = sc->sc_last_hsw_size = 0;
    537  1.1  brezak 
    538  1.1  brezak 	/* Higher speeds need bigger blocks to avoid popping and silence gaps. */
    539  1.1  brezak 	if ((sc->sc_orate > 8000 || sc->sc_irate > 8000) &&
    540  1.1  brezak 	    (blk > NBPG/2 || blk < NBPG/4))
    541  1.1  brezak 		blk = NBPG/2;
    542  1.1  brezak 	/* don't try to DMA too much at once, though. */
    543  1.1  brezak 	if (blk > NBPG) blk = NBPG;
    544  1.1  brezak 	if (sc->sc_chans == 2)
    545  1.1  brezak 		return (blk & ~1); /* must be even to preserve stereo separation */
    546  1.1  brezak 	else
    547  1.1  brezak 		return(blk);	/* Anything goes :-) */
    548  1.1  brezak }
    549  1.1  brezak 
    550  1.1  brezak int
    551  1.1  brezak sbdsp_commit_settings(addr)
    552  1.1  brezak 	caddr_t addr;
    553  1.1  brezak {
    554  1.1  brezak 	/* due to potentially unfortunate ordering in the above layers,
    555  1.1  brezak 	   re-do a few sets which may be important--input gains
    556  1.1  brezak 	   (adjust the proper channels), number of input channels (hit the
    557  1.1  brezak 	   record rate and set mode) */
    558  1.1  brezak 
    559  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    560  1.1  brezak 
    561  1.1  brezak 	if (ISSBPROCLASS(sc)) {
    562  1.1  brezak #ifdef not_anymore
    563  1.1  brezak 		sbdsp_set_in_gain_real(addr, sc->in_gain, sc->in_balance);
    564  1.1  brezak 		sbdsp_set_out_gain_real(addr, sc->out_gain, sc->out_balance);
    565  1.1  brezak #endif
    566  1.1  brezak 		sbdsp_set_out_sr_real(addr, sc->sc_orate);
    567  1.1  brezak 		sbdsp_set_in_sr_real(addr, sc->sc_irate);
    568  1.1  brezak 	}
    569  1.1  brezak 	sc->sc_last_hsw_size = sc->sc_last_hsr_size = 0;
    570  1.1  brezak 	return(0);
    571  1.1  brezak }
    572  1.1  brezak 
    573  1.1  brezak 
    574  1.1  brezak int
    575  1.1  brezak sbdsp_open(sc, dev, flags)
    576  1.1  brezak 	register struct sbdsp_softc *sc;
    577  1.1  brezak 	dev_t dev;
    578  1.1  brezak 	int flags;
    579  1.1  brezak {
    580  1.1  brezak         DPRINTF(("sbdsp_open: sc=0x%x\n", sc));
    581  1.1  brezak 
    582  1.1  brezak 	if (sc->sc_open != 0 || sbdsp_reset(sc) != 0)
    583  1.1  brezak 		return ENXIO;
    584  1.1  brezak 
    585  1.1  brezak 	sc->sc_open = 1;
    586  1.1  brezak 	sc->sc_mintr = 0;
    587  1.1  brezak 	sc->sc_intr = 0;
    588  1.1  brezak 	sc->sc_arg = 0;
    589  1.1  brezak 	sc->sc_locked = 0;
    590  1.1  brezak 	if (ISSBPROCLASS(sc) &&
    591  1.1  brezak 	    sbdsp_wdsp(sc->sc_iobase, SB_DSP_RECORD_MONO) < 0) {
    592  1.1  brezak 		DPRINTF(("sbdsp_open: can't set mono mode\n"));
    593  1.1  brezak 		/* we'll readjust when it's time for DMA. */
    594  1.1  brezak 	}
    595  1.1  brezak 	sc->sc_dmain_inprogress = 0;
    596  1.1  brezak 	sc->sc_dmaout_inprogress = 0;
    597  1.1  brezak 
    598  1.1  brezak 	/*
    599  1.1  brezak 	 * Leave most things as they were; users must change things if
    600  1.1  brezak 	 * the previous process didn't leave it they way they wanted.
    601  1.1  brezak 	 * Looked at another way, it's easy to set up a configuration
    602  1.1  brezak 	 * in one program and leave it for another to inherit.
    603  1.1  brezak 	 */
    604  1.1  brezak 	DPRINTF(("sbdsp_open: opened\n"));
    605  1.1  brezak 
    606  1.1  brezak 	return 0;
    607  1.1  brezak }
    608  1.1  brezak 
    609  1.1  brezak void
    610  1.1  brezak sbdsp_close(addr)
    611  1.1  brezak 	caddr_t addr;
    612  1.1  brezak {
    613  1.1  brezak 	struct sbdsp_softc *sc = (struct sbdsp_softc *) addr;
    614  1.1  brezak 
    615  1.1  brezak         DPRINTF(("sbdsp_close: sc=0x%x\n", sc));
    616  1.1  brezak 
    617  1.1  brezak 	sc->sc_open = 0;
    618  1.1  brezak 	sbdsp_spkroff(sc);
    619  1.1  brezak 	sc->spkr_state = SPKR_OFF;
    620  1.1  brezak 	sc->sc_intr = 0;
    621  1.1  brezak 	sc->sc_mintr = 0;
    622  1.1  brezak 	/* XXX this will turn off any dma */
    623  1.1  brezak 	sbdsp_reset(sc);
    624  1.1  brezak 
    625  1.1  brezak 	DPRINTF(("sbdsp_close: closed\n"));
    626  1.1  brezak }
    627  1.1  brezak 
    628  1.1  brezak /*
    629  1.1  brezak  * Lower-level routines
    630  1.1  brezak  */
    631  1.1  brezak 
    632  1.1  brezak /*
    633  1.1  brezak  * Reset the card.
    634  1.1  brezak  * Return non-zero if the card isn't detected.
    635  1.1  brezak  */
    636  1.1  brezak int
    637  1.1  brezak sbdsp_reset(sc)
    638  1.1  brezak 	register struct sbdsp_softc *sc;
    639  1.1  brezak {
    640  1.1  brezak 	register u_short iobase = sc->sc_iobase;
    641  1.1  brezak 
    642  1.1  brezak 	/*
    643  1.1  brezak 	 * erase any memory of last transfer size.
    644  1.1  brezak 	 */
    645  1.1  brezak 	sc->sc_last_hsr_size = sc->sc_last_hsw_size = 0;
    646  1.1  brezak 	/*
    647  1.1  brezak 	 * See SBK, section 11.3.
    648  1.1  brezak 	 * We pulse a reset signal into the card.
    649  1.1  brezak 	 * Gee, what a brilliant hardware design.
    650  1.1  brezak 	 */
    651  1.1  brezak 	outb(iobase + SBP_DSP_RESET, 1);
    652  1.1  brezak 	delay(3);
    653  1.1  brezak 	outb(iobase + SBP_DSP_RESET, 0);
    654  1.1  brezak 	if (sbdsp_rdsp(iobase) != SB_MAGIC)
    655  1.1  brezak 		return -1;
    656  1.1  brezak 	return 0;
    657  1.1  brezak }
    658  1.1  brezak 
    659  1.1  brezak /*
    660  1.1  brezak  * Write a byte to the dsp.
    661  1.1  brezak  * XXX We are at the mercy of the card as we use a
    662  1.1  brezak  * polling loop and wait until it can take the byte.
    663  1.1  brezak  */
    664  1.1  brezak int
    665  1.1  brezak sbdsp_wdsp(u_short iobase, int v)
    666  1.1  brezak {
    667  1.1  brezak 	register int i;
    668  1.1  brezak 
    669  1.1  brezak 	for (i = SBDSP_NPOLL; --i >= 0; ) {
    670  1.1  brezak 		if ((inb(iobase + SBP_DSP_WSTAT) & SB_DSP_BUSY) != 0) {
    671  1.1  brezak 			delay(10); continue;
    672  1.1  brezak 		}
    673  1.1  brezak 		outb(iobase + SBP_DSP_WRITE, v);
    674  1.1  brezak 		return 0;
    675  1.1  brezak 	}
    676  1.1  brezak 	++sberr.wdsp;
    677  1.1  brezak 	return -1;
    678  1.1  brezak }
    679  1.1  brezak 
    680  1.1  brezak /*
    681  1.1  brezak  * Read a byte from the DSP, using polling.
    682  1.1  brezak  */
    683  1.1  brezak int
    684  1.1  brezak sbdsp_rdsp(u_short iobase)
    685  1.1  brezak {
    686  1.1  brezak 	register int i;
    687  1.1  brezak 
    688  1.1  brezak 	for (i = SBDSP_NPOLL; --i >= 0; ) {
    689  1.1  brezak 		if ((inb(iobase + SBP_DSP_RSTAT) & SB_DSP_READY) == 0)
    690  1.1  brezak 			continue;
    691  1.1  brezak 		return inb(iobase + SBP_DSP_READ);
    692  1.1  brezak 	}
    693  1.1  brezak 	++sberr.rdsp;
    694  1.1  brezak 	return -1;
    695  1.1  brezak }
    696  1.1  brezak 
    697  1.1  brezak /*
    698  1.1  brezak  * Doing certain things (like toggling the speaker) make
    699  1.1  brezak  * the SB hardware go away for a while, so pause a little.
    700  1.1  brezak  */
    701  1.1  brezak void
    702  1.1  brezak sbdsp_to(arg)
    703  1.1  brezak 	void *arg;
    704  1.1  brezak {
    705  1.1  brezak 	wakeup(arg);
    706  1.1  brezak }
    707  1.1  brezak 
    708  1.1  brezak void
    709  1.1  brezak sbdsp_pause(sc)
    710  1.1  brezak 	struct sbdsp_softc *sc;
    711  1.1  brezak {
    712  1.1  brezak 	extern int hz;
    713  1.1  brezak 
    714  1.1  brezak 	timeout(sbdsp_to, sbdsp_to, hz/8);
    715  1.1  brezak 	(void)tsleep((caddr_t)sbdsp_to, PWAIT, "sbpause", 0);
    716  1.1  brezak }
    717  1.1  brezak 
    718  1.1  brezak /*
    719  1.1  brezak  * Turn on the speaker.  The SBK documention says this operation
    720  1.1  brezak  * can take up to 1/10 of a second.  Higher level layers should
    721  1.1  brezak  * probably let the task sleep for this amount of time after
    722  1.1  brezak  * calling here.  Otherwise, things might not work (because
    723  1.1  brezak  * sbdsp_wdsp() and sbdsp_rdsp() will probably timeout.)
    724  1.1  brezak  *
    725  1.1  brezak  * These engineers had their heads up their ass when
    726  1.1  brezak  * they designed this card.
    727  1.1  brezak  */
    728  1.1  brezak void
    729  1.1  brezak sbdsp_spkron(sc)
    730  1.1  brezak 	struct sbdsp_softc *sc;
    731  1.1  brezak {
    732  1.1  brezak 	(void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_ON);
    733  1.1  brezak 	sbdsp_pause(sc);
    734  1.1  brezak }
    735  1.1  brezak 
    736  1.1  brezak /*
    737  1.1  brezak  * Turn off the speaker; see comment above.
    738  1.1  brezak  */
    739  1.1  brezak void
    740  1.1  brezak sbdsp_spkroff(sc)
    741  1.1  brezak 	struct sbdsp_softc *sc;
    742  1.1  brezak {
    743  1.1  brezak 	(void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_OFF);
    744  1.1  brezak 	sbdsp_pause(sc);
    745  1.1  brezak }
    746  1.1  brezak 
    747  1.1  brezak /*
    748  1.1  brezak  * Read the version number out of the card.  Return major code
    749  1.1  brezak  * in high byte, and minor code in low byte.
    750  1.1  brezak  */
    751  1.1  brezak short
    752  1.1  brezak sbversion(sc)
    753  1.1  brezak 	struct sbdsp_softc *sc;
    754  1.1  brezak {
    755  1.1  brezak 	register u_short iobase = sc->sc_iobase;
    756  1.1  brezak 	short v;
    757  1.1  brezak 
    758  1.1  brezak 	if (sbdsp_wdsp(iobase, SB_DSP_VERSION) < 0)
    759  1.1  brezak 		return 0;
    760  1.1  brezak 	v = sbdsp_rdsp(iobase) << 8;
    761  1.1  brezak 	v |= sbdsp_rdsp(iobase);
    762  1.1  brezak 	return ((v >= 0) ? v : 0);
    763  1.1  brezak }
    764  1.1  brezak 
    765  1.1  brezak /*
    766  1.1  brezak  * Halt a DMA in progress.  A low-speed transfer can be
    767  1.1  brezak  * resumed with sbdsp_contdma().
    768  1.1  brezak  */
    769  1.1  brezak int
    770  1.1  brezak sbdsp_haltdma(addr)
    771  1.1  brezak 	caddr_t addr;
    772  1.1  brezak {
    773  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc*) addr;
    774  1.1  brezak 
    775  1.1  brezak 	DPRINTF(("sbdsp_haltdma: sc=0x%x\n", sc));
    776  1.1  brezak 
    777  1.1  brezak 	if (sc->sc_locked)
    778  1.1  brezak 		sbdsp_reset(sc);
    779  1.1  brezak 	else
    780  1.1  brezak 		(void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_HALT);
    781  1.1  brezak 
    782  1.1  brezak 	isa_dmaabort(sc->sc_drq);
    783  1.1  brezak 	sc->dmaaddr = 0;
    784  1.1  brezak 	sc->dmacnt = 0;
    785  1.1  brezak 	sc->sc_locked = 0;
    786  1.1  brezak 	sc->dmaflags = 0;
    787  1.1  brezak 	sc->sc_dmain_inprogress = sc->sc_dmaout_inprogress = 0;
    788  1.1  brezak 	return(0);
    789  1.1  brezak }
    790  1.1  brezak 
    791  1.1  brezak int
    792  1.1  brezak sbdsp_contdma(addr)
    793  1.1  brezak 	caddr_t addr;
    794  1.1  brezak {
    795  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc*) addr;
    796  1.1  brezak 
    797  1.1  brezak 	DPRINTF(("sbdsp_contdma: sc=0x%x\n", sc));
    798  1.1  brezak 
    799  1.1  brezak 	/* XXX how do we reinitialize the DMA controller state?  do we care? */
    800  1.1  brezak 	(void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_CONT);
    801  1.1  brezak 	return(0);
    802  1.1  brezak }
    803  1.1  brezak 
    804  1.1  brezak /*
    805  1.1  brezak  * Time constant routines follow.  See SBK, section 12.
    806  1.1  brezak  * Although they don't come out and say it (in the docs),
    807  1.1  brezak  * the card clearly uses a 1MHz countdown timer, as the
    808  1.1  brezak  * low-speed formula (p. 12-4) is:
    809  1.1  brezak  *	tc = 256 - 10^6 / sr
    810  1.1  brezak  * In high-speed mode, the constant is the upper byte of a 16-bit counter,
    811  1.1  brezak  * and a 256MHz clock is used:
    812  1.1  brezak  *	tc = 65536 - 256 * 10^ 6 / sr
    813  1.1  brezak  * Since we can only use the upper byte of the HS TC, the two formulae
    814  1.1  brezak  * are equivalent.  (Why didn't they say so?)  E.g.,
    815  1.1  brezak  * 	(65536 - 256 * 10 ^ 6 / x) >> 8 = 256 - 10^6 / x
    816  1.1  brezak  *
    817  1.1  brezak  * The crossover point (from low- to high-speed modes) is different
    818  1.1  brezak  * for the SBPRO and SB20.  The table on p. 12-5 gives the following data:
    819  1.1  brezak  *
    820  1.1  brezak  *				SBPRO			SB20
    821  1.1  brezak  *				-----			--------
    822  1.1  brezak  * input ls min			4	KHz		4	KHz
    823  1.1  brezak  * input ls max			23	KHz		13	KHz
    824  1.1  brezak  * input hs max			44.1	KHz		15	KHz
    825  1.1  brezak  * output ls min		4	KHz		4	KHz
    826  1.1  brezak  * output ls max		23	KHz		23	KHz
    827  1.1  brezak  * output hs max		44.1	KHz		44.1	KHz
    828  1.1  brezak  */
    829  1.1  brezak #define SB_LS_MIN	0x06	/* 4000 Hz */
    830  1.1  brezak #define SBPRO_ADC_LS_MAX	0xd4	/* 22727 Hz */
    831  1.1  brezak #define SBPRO_ADC_HS_MAX	0xea	/* 45454 Hz */
    832  1.1  brezak #define SBCLA_ADC_LS_MAX	0xb3	/* 12987 Hz */
    833  1.1  brezak #define SBCLA_ADC_HS_MAX	0xbd	/* 14925 Hz */
    834  1.1  brezak #define SB_DAC_LS_MAX	0xd4	/* 22727 Hz */
    835  1.1  brezak #define SB_DAC_HS_MAX	0xea	/* 45454 Hz */
    836  1.1  brezak 
    837  1.1  brezak /*
    838  1.1  brezak  * Convert a linear sampling rate into the DAC time constant.
    839  1.1  brezak  * Set *mode to indicate the high/low-speed DMA operation.
    840  1.1  brezak  * Because of limitations of the card, not all rates are possible.
    841  1.1  brezak  * We return the time constant of the closest possible rate.
    842  1.1  brezak  * The sampling rate limits are different for the DAC and ADC,
    843  1.1  brezak  * so isdac indicates output, and !isdac indicates input.
    844  1.1  brezak  */
    845  1.1  brezak int
    846  1.1  brezak sbdsp_srtotc(sc, sr, mode, isdac)
    847  1.1  brezak 	register struct sbdsp_softc *sc;
    848  1.1  brezak 	int sr;
    849  1.1  brezak 	int *mode;
    850  1.1  brezak 	int isdac;
    851  1.1  brezak {
    852  1.1  brezak 	int adc_ls_max, adc_hs_max;
    853  1.1  brezak 	register int tc;
    854  1.1  brezak 
    855  1.1  brezak 	if (sr == 0) {
    856  1.1  brezak 		*mode = SB_ADAC_LS;
    857  1.1  brezak 		return SB_LS_MIN;
    858  1.1  brezak 	}
    859  1.1  brezak 	tc = 256 - 1000000 / sr;
    860  1.1  brezak 
    861  1.1  brezak 	/* XXX use better rounding--compare distance to nearest tc on both
    862  1.1  brezak 	   sides of requested speed */
    863  1.1  brezak 	if (ISSBPROCLASS(sc)) {
    864  1.1  brezak 		adc_ls_max = SBPRO_ADC_LS_MAX;
    865  1.1  brezak 		adc_hs_max = SBPRO_ADC_HS_MAX;
    866  1.1  brezak 	}
    867  1.1  brezak 	else {
    868  1.1  brezak 		adc_ls_max = SBCLA_ADC_LS_MAX;
    869  1.1  brezak 		adc_hs_max = SBCLA_ADC_HS_MAX;
    870  1.1  brezak 	}
    871  1.1  brezak 
    872  1.1  brezak 	if (tc < SB_LS_MIN) {
    873  1.1  brezak 		tc = SB_LS_MIN;
    874  1.1  brezak 		*mode = SB_ADAC_LS;
    875  1.1  brezak 	} else if (isdac) {
    876  1.1  brezak 		if (tc <= SB_DAC_LS_MAX)
    877  1.1  brezak 			*mode = SB_ADAC_LS;
    878  1.1  brezak 		else {
    879  1.1  brezak 			*mode = SB_ADAC_HS;
    880  1.1  brezak 			if (tc > SB_DAC_HS_MAX)
    881  1.1  brezak 				tc = SB_DAC_HS_MAX;
    882  1.1  brezak 		}
    883  1.1  brezak 	} else {
    884  1.1  brezak 		if (tc <= adc_ls_max)
    885  1.1  brezak 			*mode = SB_ADAC_LS;
    886  1.1  brezak 		else {
    887  1.1  brezak 			*mode = SB_ADAC_HS;
    888  1.1  brezak 			if (tc > adc_hs_max)
    889  1.1  brezak 				tc = adc_hs_max;
    890  1.1  brezak 		}
    891  1.1  brezak 	}
    892  1.1  brezak 	return tc;
    893  1.1  brezak }
    894  1.1  brezak 
    895  1.1  brezak /*
    896  1.1  brezak  * Convert a DAC time constant to a sampling rate.
    897  1.1  brezak  * See SBK, section 12.
    898  1.1  brezak  */
    899  1.1  brezak int
    900  1.1  brezak sbdsp_tctosr(sc, tc)
    901  1.1  brezak 	register struct sbdsp_softc *sc;
    902  1.1  brezak 	int tc;
    903  1.1  brezak {
    904  1.1  brezak 	int adc;
    905  1.1  brezak 
    906  1.1  brezak 	if (ISSBPROCLASS(sc))
    907  1.1  brezak 		adc = SBPRO_ADC_HS_MAX;
    908  1.1  brezak 	else
    909  1.1  brezak 		adc = SBCLA_ADC_HS_MAX;
    910  1.1  brezak 
    911  1.1  brezak 	if (tc > adc)
    912  1.1  brezak 		tc = adc;
    913  1.1  brezak 
    914  1.1  brezak 	return (1000000 / (256 - tc));
    915  1.1  brezak }
    916  1.1  brezak 
    917  1.1  brezak int
    918  1.1  brezak sbdsp_set_sr(sc, srp, isdac)
    919  1.1  brezak 	register struct sbdsp_softc *sc;
    920  1.1  brezak 	u_long *srp;
    921  1.1  brezak 	int isdac;
    922  1.1  brezak {
    923  1.1  brezak 	register int tc;
    924  1.1  brezak 	int mode;
    925  1.1  brezak 	int sr = *srp;
    926  1.1  brezak 	register u_short iobase;
    927  1.1  brezak 
    928  1.1  brezak 	/*
    929  1.1  brezak 	 * A SBPro in stereo mode uses time constants at double the
    930  1.1  brezak 	 * actual rate.
    931  1.1  brezak 	 */
    932  1.1  brezak 	if (ISSBPRO(sc) && sc->sc_chans == 2) {
    933  1.1  brezak 		if (sr > 22727)
    934  1.1  brezak 			sr = 22727;	/* Can't bounce it...order of
    935  1.1  brezak 					   operations may yield bogus
    936  1.1  brezak 					   sr here. */
    937  1.1  brezak 		sr *= 2;
    938  1.1  brezak 	}
    939  1.1  brezak 	else if (!ISSBPROCLASS(sc) && sc->sc_chans != 1)
    940  1.1  brezak 		return EINVAL;
    941  1.1  brezak 
    942  1.1  brezak 	tc = sbdsp_srtotc(sc, sr, &mode, isdac);
    943  1.1  brezak 	DPRINTF(("sbdsp_set_sr: sc=0x%x sr=%d mode=0x%x\n", sc, sr, mode));
    944  1.1  brezak 
    945  1.1  brezak 	iobase = sc->sc_iobase;
    946  1.1  brezak 	if (sbdsp_wdsp(iobase, SB_DSP_TIMECONST) < 0 ||
    947  1.1  brezak 	    sbdsp_wdsp(iobase, tc) < 0)
    948  1.1  brezak 		return EIO;
    949  1.1  brezak 
    950  1.1  brezak 	sr = sbdsp_tctosr(sc, tc);
    951  1.1  brezak 	if (ISSBPRO(sc) && sc->sc_chans == 2)
    952  1.1  brezak 		*srp = sr / 2;
    953  1.1  brezak 	else
    954  1.1  brezak 		*srp = sr;
    955  1.1  brezak 
    956  1.1  brezak 	sc->sc_adacmode = mode;
    957  1.1  brezak 	sc->sc_adactc = tc;
    958  1.1  brezak 	return 0;
    959  1.1  brezak }
    960  1.1  brezak 
    961  1.1  brezak int
    962  1.1  brezak sbdsp_dma_input(addr, p, cc, intr, arg)
    963  1.1  brezak 	caddr_t addr;
    964  1.1  brezak 	void *p;
    965  1.1  brezak 	int cc;
    966  1.1  brezak 	void (*intr)();
    967  1.1  brezak 	void *arg;
    968  1.1  brezak {
    969  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
    970  1.1  brezak 	register u_short iobase;
    971  1.1  brezak 	u_int phys;
    972  1.1  brezak 
    973  1.1  brezak #ifdef DEBUG
    974  1.1  brezak 	if (sbdspdebug > 1)
    975  1.1  brezak 		Dprintf("sbdsp_dma_input: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
    976  1.1  brezak #endif
    977  1.1  brezak 	if (sc->sc_chans == 2 && (cc & 1)) {
    978  1.1  brezak 		DPRINTF(("sbdsp_dma_input: stereo input, odd bytecnt\n"));
    979  1.1  brezak 		return EIO;
    980  1.1  brezak 	}
    981  1.1  brezak 	iobase = sc->sc_iobase;
    982  1.1  brezak 	if (ISSBPROCLASS(sc) && !sc->sc_dmain_inprogress) {
    983  1.1  brezak 		if (sc->sc_chans == 2) {
    984  1.1  brezak 			if (sbdsp_wdsp(iobase, SB_DSP_RECORD_STEREO) < 0)
    985  1.1  brezak 				goto badmode;
    986  1.1  brezak 			sbdsp_mix_write(sc, SBP_STEREO,
    987  1.1  brezak 					sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK);
    988  1.1  brezak 			sbdsp_mix_write(sc, SBP_INFILTER,
    989  1.1  brezak 					sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
    990  1.1  brezak 		}
    991  1.1  brezak 		else {
    992  1.1  brezak 			if (sbdsp_wdsp(iobase, SB_DSP_RECORD_MONO) < 0)
    993  1.1  brezak 				goto badmode;
    994  1.1  brezak 			sbdsp_mix_write(sc, SBP_STEREO,
    995  1.1  brezak 					sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK);
    996  1.1  brezak 			sbdsp_mix_write(sc, SBP_INFILTER,
    997  1.1  brezak 					sc->sc_irate <= 8000 ?
    998  1.1  brezak 					sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_FILTER_MASK :
    999  1.1  brezak 					sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
   1000  1.1  brezak 		}
   1001  1.1  brezak 		sc->sc_dmain_inprogress = 1;
   1002  1.1  brezak 		sc->sc_last_hsr_size = 0;	/* restarting */
   1003  1.1  brezak 	}
   1004  1.1  brezak 	sc->sc_dmaout_inprogress = 0;
   1005  1.1  brezak 
   1006  1.1  brezak 	at_dma(B_READ, p, cc, sc->sc_drq);
   1007  1.1  brezak 	sc->sc_intr = intr;
   1008  1.1  brezak 	sc->sc_arg = arg;
   1009  1.1  brezak 	sc->dmaflags = B_READ;
   1010  1.1  brezak 	sc->dmaaddr = p;
   1011  1.1  brezak 	sc->dmacnt = --cc;		/* DMA controller is strange...? */
   1012  1.1  brezak 	if (sc->sc_adacmode == SB_ADAC_LS) {
   1013  1.1  brezak 		if (sbdsp_wdsp(iobase, SB_DSP_RDMA) < 0 ||
   1014  1.1  brezak 		    sbdsp_wdsp(iobase, cc) < 0 ||
   1015  1.1  brezak 		    sbdsp_wdsp(iobase, cc >> 8) < 0) {
   1016  1.1  brezak 			goto giveup;
   1017  1.1  brezak 		}
   1018  1.1  brezak 	}
   1019  1.1  brezak 	else {
   1020  1.1  brezak 		if (cc != sc->sc_last_hsr_size) {
   1021  1.1  brezak 			if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 ||
   1022  1.1  brezak 			    sbdsp_wdsp(iobase, cc) < 0 ||
   1023  1.1  brezak 			    sbdsp_wdsp(iobase, cc >> 8) < 0)
   1024  1.1  brezak 				goto giveup;
   1025  1.1  brezak 		}
   1026  1.1  brezak 		if (sbdsp_wdsp(iobase, SB_DSP_HS_INPUT) < 0)
   1027  1.1  brezak 			goto giveup;
   1028  1.1  brezak 		sc->sc_last_hsr_size = cc;
   1029  1.1  brezak 		sc->sc_locked = 1;
   1030  1.1  brezak 	}
   1031  1.1  brezak 	return 0;
   1032  1.1  brezak 
   1033  1.1  brezak giveup:
   1034  1.1  brezak 	isa_dmaabort(sc->sc_drq);
   1035  1.1  brezak 	sbdsp_reset(sc);
   1036  1.1  brezak 	sc->sc_intr = 0;
   1037  1.1  brezak 	sc->sc_arg = 0;
   1038  1.1  brezak 	return EIO;
   1039  1.1  brezak badmode:
   1040  1.1  brezak 	DPRINTF(("sbdsp_dma_input: can't set %s mode\n",
   1041  1.1  brezak 		 sc->sc_chans == 2 ? "stereo" : "mono"));
   1042  1.1  brezak 	return EIO;
   1043  1.1  brezak }
   1044  1.1  brezak 
   1045  1.1  brezak int
   1046  1.1  brezak sbdsp_dma_output(addr, p, cc, intr, arg)
   1047  1.1  brezak 	caddr_t addr;
   1048  1.1  brezak 	void *p;
   1049  1.1  brezak 	int cc;
   1050  1.1  brezak 	void (*intr)();
   1051  1.1  brezak 	void *arg;
   1052  1.1  brezak {
   1053  1.1  brezak 	register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
   1054  1.1  brezak 	register u_short iobase;
   1055  1.1  brezak 
   1056  1.1  brezak #ifdef DEBUG
   1057  1.1  brezak 	if (sbdspdebug > 1)
   1058  1.1  brezak 		Dprintf("sbdsp_dma_output: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
   1059  1.1  brezak #endif
   1060  1.1  brezak 	if (sc->sc_chans == 2 && cc & 1) {
   1061  1.1  brezak 		DPRINTF(("stereo playback odd bytes (%d)\n", cc));
   1062  1.1  brezak 		return EIO;
   1063  1.1  brezak 	}
   1064  1.1  brezak 
   1065  1.1  brezak 	if (ISSBPROCLASS(sc) && !sc->sc_dmaout_inprogress) {
   1066  1.1  brezak 		/* make sure we re-set stereo mixer bit when we start
   1067  1.1  brezak 		   output. */
   1068  1.1  brezak 		sbdsp_mix_write(sc, SBP_STEREO,
   1069  1.1  brezak 				(sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
   1070  1.1  brezak 				(sc->sc_chans == 2 ?
   1071  1.1  brezak 				 SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
   1072  1.1  brezak 		sc->sc_dmaout_inprogress = 1;
   1073  1.1  brezak 		sc->sc_last_hsw_size = 0;	/* restarting */
   1074  1.1  brezak 	}
   1075  1.1  brezak 	sc->sc_dmain_inprogress = 0;
   1076  1.1  brezak 	at_dma(B_WRITE, p, cc, sc->sc_drq);
   1077  1.1  brezak 	sc->sc_intr = intr;
   1078  1.1  brezak 	sc->sc_arg = arg;
   1079  1.1  brezak 	sc->dmaflags = B_WRITE;
   1080  1.1  brezak 	sc->dmaaddr = p;
   1081  1.1  brezak 	sc->dmacnt = --cc;	/* a vagary of how DMA works, apparently. */
   1082  1.1  brezak 
   1083  1.1  brezak 	iobase = sc->sc_iobase;
   1084  1.1  brezak 	if (sc->sc_adacmode == SB_ADAC_LS) {
   1085  1.1  brezak 		if (sbdsp_wdsp(iobase, SB_DSP_WDMA) < 0 ||
   1086  1.1  brezak 		    sbdsp_wdsp(iobase, cc) < 0 ||
   1087  1.1  brezak 		    sbdsp_wdsp(iobase, cc >> 8) < 0) {
   1088  1.1  brezak 		        DPRINTF(("sbdsp_dma_output: LS DMA start failed\n"));
   1089  1.1  brezak 			goto giveup;
   1090  1.1  brezak 		}
   1091  1.1  brezak 	}
   1092  1.1  brezak 	else {
   1093  1.1  brezak 		if (cc != sc->sc_last_hsw_size) {
   1094  1.1  brezak 			if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0) {
   1095  1.1  brezak 				/* sometimes fails initial startup?? */
   1096  1.1  brezak 				delay(100);
   1097  1.1  brezak 				if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0) {
   1098  1.1  brezak 					DPRINTF(("sbdsp_dma_output: BLOCKSIZE failed\n"));
   1099  1.1  brezak 					goto giveup;
   1100  1.1  brezak 				}
   1101  1.1  brezak 			}
   1102  1.1  brezak 			if (sbdsp_wdsp(iobase, cc) < 0 ||
   1103  1.1  brezak 			    sbdsp_wdsp(iobase, cc >> 8) < 0) {
   1104  1.1  brezak 				DPRINTF(("sbdsp_dma_output: HS DMA start failed\n"));
   1105  1.1  brezak 				goto giveup;
   1106  1.1  brezak 			}
   1107  1.1  brezak 			sc->sc_last_hsw_size = cc;
   1108  1.1  brezak 		}
   1109  1.1  brezak 		if (sbdsp_wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
   1110  1.1  brezak 			delay(100);
   1111  1.1  brezak 			if (sbdsp_wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
   1112  1.1  brezak 				DPRINTF(("sbdsp_dma_output: HS DMA restart failed\n"));
   1113  1.1  brezak 				goto giveup;
   1114  1.1  brezak 			}
   1115  1.1  brezak 		}
   1116  1.1  brezak 		sc->sc_locked = 1;
   1117  1.1  brezak 	}
   1118  1.1  brezak 
   1119  1.1  brezak 	return 0;
   1120  1.1  brezak 
   1121  1.1  brezak  giveup:
   1122  1.1  brezak 	isa_dmaabort(sc->sc_drq);
   1123  1.1  brezak 	sbdsp_reset(sc);
   1124  1.1  brezak 	sc->sc_intr = 0;
   1125  1.1  brezak 	sc->sc_arg = 0;
   1126  1.1  brezak 	return EIO;
   1127  1.1  brezak }
   1128  1.1  brezak 
   1129  1.1  brezak /*
   1130  1.1  brezak  * Only the DSP unit on the sound blaster generates interrupts.
   1131  1.1  brezak  * There are three cases of interrupt: reception of a midi byte
   1132  1.1  brezak  * (when mode is enabled), completion of dma transmission, or
   1133  1.1  brezak  * completion of a dma reception.  The three modes are mutually
   1134  1.1  brezak  * exclusive so we know a priori which event has occurred.
   1135  1.1  brezak  */
   1136  1.1  brezak int
   1137  1.1  brezak sbdsp_intr(sc)
   1138  1.1  brezak 	register struct sbdsp_softc *sc;
   1139  1.1  brezak {
   1140  1.1  brezak 
   1141  1.1  brezak #ifdef DEBUG
   1142  1.1  brezak 	if (sbdspdebug > 1)
   1143  1.1  brezak 		Dprintf("sbdsp_intr: intr=0x%x\n", sc->sc_intr);
   1144  1.1  brezak #endif
   1145  1.1  brezak 	sc->sc_interrupts++;
   1146  1.1  brezak 	sc->sc_locked = 0;
   1147  1.1  brezak 	/* clear interrupt */
   1148  1.1  brezak 	inb(sc->sc_iobase + SBP_DSP_RSTAT);
   1149  1.1  brezak #if 0
   1150  1.1  brezak 	if (sc->sc_mintr != 0) {
   1151  1.1  brezak 		int c = sbdsp_rdsp(sc->sc_iobase);
   1152  1.1  brezak 		(*sc->sc_mintr)(sc->sc_arg, c);
   1153  1.1  brezak 	} else
   1154  1.1  brezak #endif
   1155  1.1  brezak 	if (sc->sc_intr != 0) {
   1156  1.1  brezak 	    /*
   1157  1.1  brezak 	     * The SBPro used to develop and test this driver often
   1158  1.1  brezak 	     * generated dma underruns--it interrupted to signal
   1159  1.1  brezak 	     * completion of the DMA input recording block, but the
   1160  1.1  brezak 	     * ISA DMA controller didn't think the channel was
   1161  1.1  brezak 	     * finished.  Maybe this is just a bus speed issue, I dunno,
   1162  1.1  brezak 	     * but it seems strange and leads to channel-flipping with stereo
   1163  1.1  brezak 	     * recording.  Sigh.
   1164  1.1  brezak 	     */
   1165  1.1  brezak 		isa_dmadone(sc->dmaflags, sc->dmaaddr, sc->dmacnt,
   1166  1.1  brezak 			    sc->sc_drq);
   1167  1.1  brezak 		sc->dmaflags = 0;
   1168  1.1  brezak 		sc->dmaaddr = 0;
   1169  1.1  brezak 		sc->dmacnt = 0;
   1170  1.1  brezak 		(*sc->sc_intr)(sc->sc_arg);
   1171  1.1  brezak 	}
   1172  1.1  brezak 	else
   1173  1.1  brezak 		return 0;
   1174  1.1  brezak 	return 1;
   1175  1.1  brezak }
   1176  1.1  brezak 
   1177  1.1  brezak #if 0
   1178  1.1  brezak /*
   1179  1.1  brezak  * Enter midi uart mode and arrange for read interrupts
   1180  1.1  brezak  * to vector to `intr'.  This puts the card in a mode
   1181  1.1  brezak  * which allows only midi I/O; the card must be reset
   1182  1.1  brezak  * to leave this mode.  Unfortunately, the card does not
   1183  1.1  brezak  * use transmit interrupts, so bytes must be output
   1184  1.1  brezak  * using polling.  To keep the polling overhead to a
   1185  1.1  brezak  * minimum, output should be driven off a timer.
   1186  1.1  brezak  * This is a little tricky since only 320us separate
   1187  1.1  brezak  * consecutive midi bytes.
   1188  1.1  brezak  */
   1189  1.1  brezak void
   1190  1.1  brezak sbdsp_set_midi_mode(sc, intr, arg)
   1191  1.1  brezak 	struct sbdsp_softc *sc;
   1192  1.1  brezak 	void (*intr)();
   1193  1.1  brezak 	void *arg;
   1194  1.1  brezak {
   1195  1.1  brezak 
   1196  1.1  brezak 	sbdsp_wdsp(sc->sc_iobase, SB_MIDI_UART_INTR);
   1197  1.1  brezak 	sc->sc_mintr = intr;
   1198  1.1  brezak 	sc->sc_intr = 0;
   1199  1.1  brezak 	sc->sc_arg = arg;
   1200  1.1  brezak }
   1201  1.1  brezak 
   1202  1.1  brezak /*
   1203  1.1  brezak  * Write a byte to the midi port, when in midi uart mode.
   1204  1.1  brezak  */
   1205  1.1  brezak void
   1206  1.1  brezak sbdsp_midi_output(sc, v)
   1207  1.1  brezak 	struct sbdsp_softc *sc;
   1208  1.1  brezak 	int v;
   1209  1.1  brezak {
   1210  1.1  brezak 
   1211  1.1  brezak 	if (sbdsp_wdsp(sc->sc_iobase, v) < 0)
   1212  1.1  brezak 		++sberr.wmidi;
   1213  1.1  brezak }
   1214  1.1  brezak #endif
   1215  1.1  brezak 
   1216  1.1  brezak u_int
   1217  1.1  brezak sbdsp_get_silence(enc)
   1218  1.1  brezak     int enc;
   1219  1.1  brezak {
   1220  1.1  brezak #define ULAW_SILENCE	0x7f
   1221  1.1  brezak #define LINEAR_SILENCE	0
   1222  1.1  brezak     u_int auzero;
   1223  1.1  brezak 
   1224  1.1  brezak     switch (enc) {
   1225  1.1  brezak     case AUDIO_ENCODING_ULAW:
   1226  1.1  brezak 	auzero = ULAW_SILENCE;
   1227  1.1  brezak 	break;
   1228  1.1  brezak     case AUDIO_ENCODING_PCM16:
   1229  1.1  brezak     default:
   1230  1.1  brezak 	auzero = LINEAR_SILENCE;
   1231  1.1  brezak 	break;
   1232  1.1  brezak     }
   1233  1.1  brezak 
   1234  1.1  brezak     return(auzero);
   1235  1.1  brezak }
   1236  1.1  brezak 
   1237  1.1  brezak static u_char mulawtolin[256] = {
   1238  1.1  brezak 	128, 4, 8, 12, 16, 20, 24, 28,
   1239  1.1  brezak 	32, 36, 40, 44, 48, 52, 56, 60,
   1240  1.1  brezak 	64, 66, 68, 70, 72, 74, 76, 78,
   1241  1.1  brezak 	80, 82, 84, 86, 88, 90, 92, 94,
   1242  1.1  brezak 	96, 97, 98, 99, 100, 101, 102, 103,
   1243  1.1  brezak 	104, 105, 106, 107, 108, 109, 110, 111,
   1244  1.1  brezak 	112, 112, 113, 113, 114, 114, 115, 115,
   1245  1.1  brezak 	116, 116, 117, 117, 118, 118, 119, 119,
   1246  1.1  brezak 	120, 120, 120, 121, 121, 121, 121, 122,
   1247  1.1  brezak 	122, 122, 122, 123, 123, 123, 123, 124,
   1248  1.1  brezak 	124, 124, 124, 124, 125, 125, 125, 125,
   1249  1.1  brezak 	125, 125, 125, 125, 126, 126, 126, 126,
   1250  1.1  brezak 	126, 126, 126, 126, 126, 126, 126, 126,
   1251  1.1  brezak 	127, 127, 127, 127, 127, 127, 127, 127,
   1252  1.1  brezak 	127, 127, 127, 127, 127, 127, 127, 127,
   1253  1.1  brezak 	127, 127, 127, 127, 127, 127, 127, 127,
   1254  1.1  brezak 	255, 251, 247, 243, 239, 235, 231, 227,
   1255  1.1  brezak 	223, 219, 215, 211, 207, 203, 199, 195,
   1256  1.1  brezak 	191, 189, 187, 185, 183, 181, 179, 177,
   1257  1.1  brezak 	175, 173, 171, 169, 167, 165, 163, 161,
   1258  1.1  brezak 	159, 158, 157, 156, 155, 154, 153, 152,
   1259  1.1  brezak 	151, 150, 149, 148, 147, 146, 145, 144,
   1260  1.1  brezak 	143, 143, 142, 142, 141, 141, 140, 140,
   1261  1.1  brezak 	139, 139, 138, 138, 137, 137, 136, 136,
   1262  1.1  brezak 	135, 135, 135, 134, 134, 134, 134, 133,
   1263  1.1  brezak 	133, 133, 133, 132, 132, 132, 132, 131,
   1264  1.1  brezak 	131, 131, 131, 131, 130, 130, 130, 130,
   1265  1.1  brezak 	130, 130, 130, 130, 129, 129, 129, 129,
   1266  1.1  brezak 	129, 129, 129, 129, 129, 129, 129, 129,
   1267  1.1  brezak 	128, 128, 128, 128, 128, 128, 128, 128,
   1268  1.1  brezak 	128, 128, 128, 128, 128, 128, 128, 128,
   1269  1.1  brezak 	128, 128, 128, 128, 128, 128, 128, 128,
   1270  1.1  brezak };
   1271  1.1  brezak 
   1272  1.1  brezak static u_char lintomulaw[256] = {
   1273  1.1  brezak 	0, 0, 0, 0, 0, 1, 1, 1,
   1274  1.1  brezak 	1, 2, 2, 2, 2, 3, 3, 3,
   1275  1.1  brezak 	3, 4, 4, 4, 4, 5, 5, 5,
   1276  1.1  brezak 	5, 6, 6, 6, 6, 7, 7, 7,
   1277  1.1  brezak 	7, 8, 8, 8, 8, 9, 9, 9,
   1278  1.1  brezak 	9, 10, 10, 10, 10, 11, 11, 11,
   1279  1.1  brezak 	11, 12, 12, 12, 12, 13, 13, 13,
   1280  1.1  brezak 	13, 14, 14, 14, 14, 15, 15, 15,
   1281  1.1  brezak 	15, 16, 16, 17, 17, 18, 18, 19,
   1282  1.1  brezak 	19, 20, 20, 21, 21, 22, 22, 23,
   1283  1.1  brezak 	23, 24, 24, 25, 25, 26, 26, 27,
   1284  1.1  brezak 	27, 28, 28, 29, 29, 30, 30, 31,
   1285  1.1  brezak 	31, 32, 33, 34, 35, 36, 37, 38,
   1286  1.1  brezak 	39, 40, 41, 42, 43, 44, 45, 46,
   1287  1.1  brezak 	47, 48, 50, 52, 54, 56, 58, 60,
   1288  1.1  brezak 	62, 65, 69, 73, 77, 83, 91, 103,
   1289  1.1  brezak 	255, 231, 219, 211, 205, 201, 197, 193,
   1290  1.1  brezak 	190, 188, 186, 184, 182, 180, 178, 176,
   1291  1.1  brezak 	175, 174, 173, 172, 171, 170, 169, 168,
   1292  1.1  brezak 	167, 166, 165, 164, 163, 162, 161, 160,
   1293  1.1  brezak 	159, 159, 158, 158, 157, 157, 156, 156,
   1294  1.1  brezak 	155, 155, 154, 154, 153, 153, 152, 152,
   1295  1.1  brezak 	151, 151, 150, 150, 149, 149, 148, 148,
   1296  1.1  brezak 	147, 147, 146, 146, 145, 145, 144, 144,
   1297  1.1  brezak 	143, 143, 143, 143, 142, 142, 142, 142,
   1298  1.1  brezak 	141, 141, 141, 141, 140, 140, 140, 140,
   1299  1.1  brezak 	139, 139, 139, 139, 138, 138, 138, 138,
   1300  1.1  brezak 	137, 137, 137, 137, 136, 136, 136, 136,
   1301  1.1  brezak 	135, 135, 135, 135, 134, 134, 134, 134,
   1302  1.1  brezak 	133, 133, 133, 133, 132, 132, 132, 132,
   1303  1.1  brezak 	131, 131, 131, 131, 130, 130, 130, 130,
   1304  1.1  brezak 	129, 129, 129, 129, 128, 128, 128, 128,
   1305  1.1  brezak };
   1306  1.1  brezak 
   1307  1.1  brezak void
   1308  1.1  brezak sbdsp_compress(e, p, cc)
   1309  1.1  brezak 	int e;
   1310  1.1  brezak 	u_char *p;
   1311  1.1  brezak 	int cc;
   1312  1.1  brezak {
   1313  1.1  brezak 	u_char *tab;
   1314  1.1  brezak 
   1315  1.1  brezak 	switch (e) {
   1316  1.1  brezak 	case AUDIO_ENCODING_ULAW:
   1317  1.1  brezak 		tab = lintomulaw;
   1318  1.1  brezak 		break;
   1319  1.1  brezak 	default:
   1320  1.1  brezak 		return;
   1321  1.1  brezak 	}
   1322  1.1  brezak 
   1323  1.1  brezak 	while (--cc >= 0) {
   1324  1.1  brezak 		*p = tab[*p];
   1325  1.1  brezak 		++p;
   1326  1.1  brezak 	}
   1327  1.1  brezak }
   1328  1.1  brezak 
   1329  1.1  brezak void
   1330  1.1  brezak sbdsp_expand(e, p, cc)
   1331  1.1  brezak 	int e;
   1332  1.1  brezak 	u_char *p;
   1333  1.1  brezak 	int cc;
   1334  1.1  brezak {
   1335  1.1  brezak 	u_char *tab;
   1336  1.1  brezak 
   1337  1.1  brezak 	switch (e) {
   1338  1.1  brezak 	case AUDIO_ENCODING_ULAW:
   1339  1.1  brezak 		tab = mulawtolin;
   1340  1.1  brezak 		break;
   1341  1.1  brezak 	default:
   1342  1.1  brezak 		return;
   1343  1.1  brezak 	}
   1344  1.1  brezak 
   1345  1.1  brezak 	while (--cc >= 0) {
   1346  1.1  brezak 		*p = tab[*p];
   1347  1.1  brezak 		++p;
   1348  1.1  brezak 	}
   1349  1.1  brezak }
   1350  1.1  brezak 
   1351  1.1  brezak int
   1352  1.1  brezak sbdsp_setfd(addr, flag)
   1353  1.1  brezak 	caddr_t addr;
   1354  1.1  brezak 	int flag;
   1355  1.1  brezak {
   1356  1.1  brezak 	/* Can't do full-duplex */
   1357  1.1  brezak 	return(ENOTTY);
   1358  1.1  brezak }
   1359  1.1  brezak 
   1360  1.1  brezak int
   1361  1.1  brezak sbdsp_mixer_set_port(addr, cp)
   1362  1.1  brezak     caddr_t addr;
   1363  1.1  brezak     mixer_ctrl_t *cp;
   1364  1.1  brezak {
   1365  1.1  brezak     register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
   1366  1.1  brezak     int error = 0;
   1367  1.1  brezak     int src, gain;
   1368  1.1  brezak     int left, right;
   1369  1.1  brezak 
   1370  1.1  brezak     DPRINTF(("sbdsp_mixer_set_port: port=%d num_channels=%d\n", cp->dev, cp->un.value.num_channels));
   1371  1.1  brezak 
   1372  1.1  brezak     /*
   1373  1.1  brezak      * Everything is a value except for SBPro special OUTPUT_MODE and
   1374  1.1  brezak      * RECORD_SOURCE
   1375  1.1  brezak      */
   1376  1.1  brezak     if (cp->type != AUDIO_MIXER_VALUE) {
   1377  1.1  brezak 	if (!ISSBPROCLASS(sc) || (cp->dev != SB_OUTPUT_MODE &&
   1378  1.1  brezak 				  cp->dev != SB_RECORD_SOURCE))
   1379  1.1  brezak 	    return EINVAL;
   1380  1.1  brezak     }
   1381  1.1  brezak     else {
   1382  1.1  brezak 	/*
   1383  1.1  brezak 	 * All the mixer ports are stereo except for the microphone.
   1384  1.1  brezak 	 * If we get a single-channel gain value passed in, then we
   1385  1.1  brezak 	 * duplicate it to both left and right channels.
   1386  1.1  brezak 	 */
   1387  1.1  brezak     if (cp->un.value.num_channels == 2) {
   1388  1.1  brezak 	left  = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
   1389  1.1  brezak 	right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
   1390  1.1  brezak     }
   1391  1.1  brezak     else
   1392  1.1  brezak 	    left = right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
   1393  1.1  brezak     }
   1394  1.1  brezak 
   1395  1.1  brezak     if (ISSBPROCLASS(sc)) {
   1396  1.1  brezak 	/* The _PORT things are all signal inputs to the mixer.
   1397  1.1  brezak 	 * Here we are tweaking their mixing level.
   1398  1.1  brezak 	 *
   1399  1.1  brezak 	 * We can also tweak the output stage volume (MASTER_VOL)
   1400  1.1  brezak 	 */
   1401  1.1  brezak 	gain = sbdsp_stereo_vol(SBP_AGAIN_TO_SBGAIN(left),
   1402  1.1  brezak 				SBP_AGAIN_TO_SBGAIN(right));
   1403  1.1  brezak 	switch(cp->dev) {
   1404  1.1  brezak         case SB_MIC_PORT:
   1405  1.1  brezak 	    src = SBP_MIC_VOL;
   1406  1.1  brezak 	    if (cp->un.value.num_channels != 1)
   1407  1.1  brezak 		error = EINVAL;
   1408  1.1  brezak 	    else
   1409  1.1  brezak 		/* handle funny microphone gain */
   1410  1.1  brezak 		gain = SBP_AGAIN_TO_MICGAIN(left);
   1411  1.1  brezak 	    break;
   1412  1.1  brezak         case SB_LINE_IN_PORT:
   1413  1.1  brezak 	    src = SBP_LINE_VOL;
   1414  1.1  brezak 	    break;
   1415  1.1  brezak         case SB_DAC_PORT:
   1416  1.1  brezak 	    src = SBP_DAC_VOL;
   1417  1.1  brezak 	    break;
   1418  1.1  brezak         case SB_FM_PORT:
   1419  1.1  brezak 	    src = SBP_FM_VOL;
   1420  1.1  brezak 	    break;
   1421  1.1  brezak         case SB_CD_PORT:
   1422  1.1  brezak 	    src = SBP_CD_VOL;
   1423  1.1  brezak 	    break;
   1424  1.1  brezak 	case SB_SPEAKER:
   1425  1.1  brezak 	    cp->dev = SB_MASTER_VOL;
   1426  1.1  brezak         case SB_MASTER_VOL:
   1427  1.1  brezak 	    src = SBP_MASTER_VOL;
   1428  1.1  brezak 	    break;
   1429  1.1  brezak #if 0
   1430  1.1  brezak 	case SB_OUTPUT_MODE:
   1431  1.1  brezak 	    if (cp->type == AUDIO_MIXER_ENUM)
   1432  1.1  brezak 		return sbdsp_set_channels(addr, cp->un.ord);
   1433  1.1  brezak 	    /* fall through...carefully! */
   1434  1.1  brezak #endif
   1435  1.1  brezak 	case SB_RECORD_SOURCE:
   1436  1.1  brezak 	    if (cp->type == AUDIO_MIXER_ENUM)
   1437  1.1  brezak 		return sbdsp_set_in_port(addr, cp->un.ord);
   1438  1.1  brezak 	    /* else fall through: bad input */
   1439  1.1  brezak         case SB_TREBLE:
   1440  1.1  brezak         case SB_BASS:
   1441  1.1  brezak         default:
   1442  1.1  brezak 	    error =  EINVAL;
   1443  1.1  brezak 	    break;
   1444  1.1  brezak 	}
   1445  1.1  brezak 	if (!error)
   1446  1.1  brezak 	sbdsp_mix_write(sc, src, gain);
   1447  1.1  brezak     }
   1448  1.1  brezak     else if (cp->dev != SB_MIC_PORT &&
   1449  1.1  brezak 	     cp->dev != SB_SPEAKER)
   1450  1.1  brezak 	error = EINVAL;
   1451  1.1  brezak 
   1452  1.1  brezak     if (!error)
   1453  1.1  brezak 	sc->gain[cp->dev] = gain;
   1454  1.1  brezak 
   1455  1.1  brezak     return(error);
   1456  1.1  brezak }
   1457  1.1  brezak 
   1458  1.1  brezak int
   1459  1.1  brezak sbdsp_mixer_get_port(addr, cp)
   1460  1.1  brezak     caddr_t addr;
   1461  1.1  brezak     mixer_ctrl_t *cp;
   1462  1.1  brezak {
   1463  1.1  brezak     register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
   1464  1.1  brezak     int error = 0;
   1465  1.1  brezak     int done = 0;
   1466  1.1  brezak 
   1467  1.1  brezak     DPRINTF(("sbdsp_mixer_get_port: port=%d", cp->dev));
   1468  1.1  brezak 
   1469  1.1  brezak     if (ISSBPROCLASS(sc))
   1470  1.1  brezak     switch(cp->dev) {
   1471  1.1  brezak     case SB_MIC_PORT:
   1472  1.1  brezak 	    if (cp->un.value.num_channels == 1) {
   1473  1.1  brezak 		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
   1474  1.1  brezak 		    SBP_MICGAIN_TO_AGAIN(sc->gain[cp->dev]);
   1475  1.1  brezak 		return 0;
   1476  1.1  brezak     }
   1477  1.1  brezak 	    else
   1478  1.1  brezak 		return EINVAL;
   1479  1.1  brezak 	    break;
   1480  1.1  brezak 	case SB_LINE_IN_PORT:
   1481  1.1  brezak         case SB_DAC_PORT:
   1482  1.1  brezak         case SB_FM_PORT:
   1483  1.1  brezak         case SB_CD_PORT:
   1484  1.1  brezak         case SB_MASTER_VOL:
   1485  1.1  brezak 	    break;
   1486  1.1  brezak 	case SB_SPEAKER:
   1487  1.1  brezak 	    cp->dev = SB_MASTER_VOL;
   1488  1.1  brezak 	    break;
   1489  1.1  brezak         default:
   1490  1.1  brezak 	    error =  EINVAL;
   1491  1.1  brezak 	    break;
   1492  1.1  brezak 	}
   1493  1.1  brezak     else {
   1494  1.1  brezak 	if (cp->un.value.num_channels != 1) /* no stereo on SB classic */
   1495  1.1  brezak 	    error = EINVAL;
   1496  1.1  brezak     else
   1497  1.1  brezak 	    switch(cp->dev) {
   1498  1.1  brezak 	    case SB_MIC_PORT:
   1499  1.1  brezak 		break;
   1500  1.1  brezak 	    case SB_SPEAKER:
   1501  1.1  brezak 		break;
   1502  1.1  brezak 	    default:
   1503  1.1  brezak 	error = EINVAL;
   1504  1.1  brezak 		break;
   1505  1.1  brezak 	    }
   1506  1.1  brezak     }
   1507  1.1  brezak     if (error == 0) {
   1508  1.1  brezak 	if (cp->un.value.num_channels == 1) {
   1509  1.1  brezak 	    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
   1510  1.1  brezak 		SBP_SBGAIN_TO_AGAIN(sc->gain[cp->dev]);
   1511  1.1  brezak 	}
   1512  1.1  brezak 	else if (cp->un.value.num_channels == 2) {
   1513  1.1  brezak 	    cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
   1514  1.1  brezak 		SBP_LEFTGAIN(sc->gain[cp->dev]);
   1515  1.1  brezak 	    cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
   1516  1.1  brezak 		SBP_RIGHTGAIN(sc->gain[cp->dev]);
   1517  1.1  brezak 	} else
   1518  1.1  brezak 	    return EINVAL;
   1519  1.1  brezak     }
   1520  1.1  brezak     return(error);
   1521  1.1  brezak }
   1522  1.1  brezak 
   1523  1.1  brezak int
   1524  1.1  brezak sbdsp_mixer_query_devinfo(addr, dip)
   1525  1.1  brezak     caddr_t addr;
   1526  1.1  brezak     register mixer_devinfo_t *dip;
   1527  1.1  brezak {
   1528  1.1  brezak     register struct sbdsp_softc *sc = (struct sbdsp_softc *)addr;
   1529  1.1  brezak     int done = 0;
   1530  1.1  brezak 
   1531  1.1  brezak     DPRINTF(("sbdsp_mixer_query_devinfo: index=%d\n", dip->index));
   1532  1.1  brezak 
   1533  1.1  brezak     switch (dip->index) {
   1534  1.1  brezak     case SB_MIC_PORT:
   1535  1.1  brezak 	dip->type = AUDIO_MIXER_VALUE;
   1536  1.1  brezak 	dip->mixer_class = SB_INPUT_CLASS;
   1537  1.1  brezak 	dip->prev = AUDIO_MIXER_LAST;
   1538  1.1  brezak 	dip->next = AUDIO_MIXER_LAST;
   1539  1.1  brezak 	strcpy(dip->label.name, AudioNmicrophone);
   1540  1.1  brezak 	dip->un.v.num_channels = 1;
   1541  1.1  brezak 	strcpy(dip->un.v.units.name, AudioNvolume);
   1542  1.1  brezak 	done = 1;
   1543  1.1  brezak 	break;
   1544  1.1  brezak     case SB_SPEAKER:
   1545  1.1  brezak 	dip->type = AUDIO_MIXER_VALUE;
   1546  1.1  brezak 	dip->mixer_class = SB_OUTPUT_CLASS;
   1547  1.1  brezak 	dip->prev = AUDIO_MIXER_LAST;
   1548  1.1  brezak 	dip->next = AUDIO_MIXER_LAST;
   1549  1.1  brezak 	strcpy(dip->label.name, AudioNspeaker);
   1550  1.1  brezak 	dip->un.v.num_channels = 1;
   1551  1.1  brezak 	strcpy(dip->un.v.units.name, AudioNvolume);
   1552  1.1  brezak 	done = 1;
   1553  1.1  brezak 	break;
   1554  1.1  brezak     case SB_INPUT_CLASS:
   1555  1.1  brezak 	dip->type = AUDIO_MIXER_CLASS;
   1556  1.1  brezak 	dip->mixer_class = SB_INPUT_CLASS;
   1557  1.1  brezak 	dip->next = dip->prev = AUDIO_MIXER_LAST;
   1558  1.1  brezak 	strcpy(dip->label.name, AudioCInputs);
   1559  1.1  brezak 	done = 1;
   1560  1.1  brezak 	break;
   1561  1.1  brezak     case SB_OUTPUT_CLASS:
   1562  1.1  brezak 	dip->type = AUDIO_MIXER_CLASS;
   1563  1.1  brezak 	dip->mixer_class = SB_OUTPUT_CLASS;
   1564  1.1  brezak 	dip->next = dip->prev = AUDIO_MIXER_LAST;
   1565  1.1  brezak 	strcpy(dip->label.name, AudioCOutputs);
   1566  1.1  brezak 	done = 1;
   1567  1.1  brezak 	break;
   1568  1.1  brezak     }
   1569  1.1  brezak 
   1570  1.1  brezak     if (!done) {
   1571  1.1  brezak     if (ISSBPROCLASS(sc))
   1572  1.1  brezak 	switch(dip->index) {
   1573  1.1  brezak 	case SB_LINE_IN_PORT:
   1574  1.1  brezak 	    dip->type = AUDIO_MIXER_VALUE;
   1575  1.1  brezak 	    dip->mixer_class = SB_INPUT_CLASS;
   1576  1.1  brezak 	    dip->prev = AUDIO_MIXER_LAST;
   1577  1.1  brezak 	    dip->next = AUDIO_MIXER_LAST;
   1578  1.1  brezak 	    strcpy(dip->label.name, AudioNline);
   1579  1.1  brezak 	    dip->un.v.num_channels = 2;
   1580  1.1  brezak 	    strcpy(dip->un.v.units.name, AudioNvolume);
   1581  1.1  brezak 	    break;
   1582  1.1  brezak 	case SB_DAC_PORT:
   1583  1.1  brezak 	    dip->type = AUDIO_MIXER_VALUE;
   1584  1.1  brezak 	    dip->mixer_class = SB_INPUT_CLASS;
   1585  1.1  brezak 	    dip->prev = AUDIO_MIXER_LAST;
   1586  1.1  brezak 	    dip->next = AUDIO_MIXER_LAST;
   1587  1.1  brezak 	    strcpy(dip->label.name, AudioNdac);
   1588  1.1  brezak 	    dip->un.v.num_channels = 2;
   1589  1.1  brezak 	    strcpy(dip->un.v.units.name, AudioNvolume);
   1590  1.1  brezak 	    break;
   1591  1.1  brezak 	case SB_CD_PORT:
   1592  1.1  brezak 	    dip->type = AUDIO_MIXER_VALUE;
   1593  1.1  brezak 	    dip->mixer_class = SB_INPUT_CLASS;
   1594  1.1  brezak 	    dip->prev = AUDIO_MIXER_LAST;
   1595  1.1  brezak 	    dip->next = AUDIO_MIXER_LAST;
   1596  1.1  brezak 	    strcpy(dip->label.name, AudioNcd);
   1597  1.1  brezak 	    dip->un.v.num_channels = 2;
   1598  1.1  brezak 	    strcpy(dip->un.v.units.name, AudioNvolume);
   1599  1.1  brezak 	    break;
   1600  1.1  brezak 	case SB_FM_PORT:
   1601  1.1  brezak 	    dip->type = AUDIO_MIXER_VALUE;
   1602  1.1  brezak 	    dip->mixer_class = SB_INPUT_CLASS;
   1603  1.1  brezak 	    dip->prev = AUDIO_MIXER_LAST;
   1604  1.1  brezak 	    dip->next = AUDIO_MIXER_LAST;
   1605  1.1  brezak 	    strcpy(dip->label.name, "fmsynth");	/* XXX move to audioio.h */
   1606  1.1  brezak 	    dip->un.v.num_channels = 2;
   1607  1.1  brezak 	    strcpy(dip->un.v.units.name, AudioNvolume);
   1608  1.1  brezak 	    break;
   1609  1.1  brezak 	case SB_MASTER_VOL:
   1610  1.1  brezak 	    dip->type = AUDIO_MIXER_VALUE;
   1611  1.1  brezak 	    dip->mixer_class = SB_OUTPUT_CLASS;
   1612  1.1  brezak 	    dip->prev = AUDIO_MIXER_LAST;
   1613  1.1  brezak 	    dip->next = SB_OUTPUT_MODE;
   1614  1.1  brezak 	    strcpy(dip->label.name, AudioNvolume);
   1615  1.1  brezak 	    dip->un.v.num_channels = 2;
   1616  1.1  brezak 	    strcpy(dip->un.v.units.name, AudioNvolume);
   1617  1.1  brezak 	    break;
   1618  1.1  brezak #if 0
   1619  1.1  brezak 	case SB_OUTPUT_MODE:
   1620  1.1  brezak 	    dip->mixer_class = SB_OUTPUT_CLASS;
   1621  1.1  brezak 	    dip->type = AUDIO_MIXER_ENUM;
   1622  1.1  brezak 	    dip->prev = SB_MASTER_VOL;
   1623  1.1  brezak 	    dip->next = AUDIO_MIXER_LAST;
   1624  1.1  brezak 	    strcpy(dip->label.name, AudioNmode);
   1625  1.1  brezak 	    dip->un.e.num_mem = 2;
   1626  1.1  brezak 	    strcpy(dip->un.e.member[0].label.name, AudioNmono);
   1627  1.1  brezak 	    dip->un.e.member[0].ord = 1; /* nchans */
   1628  1.1  brezak 	    strcpy(dip->un.e.member[1].label.name, AudioNstereo);
   1629  1.1  brezak 	    dip->un.e.member[1].ord = 2; /* nchans */
   1630  1.1  brezak 	    break;
   1631  1.1  brezak #endif
   1632  1.1  brezak 	case SB_RECORD_SOURCE:
   1633  1.1  brezak 	    dip->mixer_class = SB_RECORD_CLASS;
   1634  1.1  brezak 	    dip->type = AUDIO_MIXER_ENUM;
   1635  1.1  brezak 	    dip->prev = AUDIO_MIXER_LAST;
   1636  1.1  brezak 	    dip->next = AUDIO_MIXER_LAST;
   1637  1.1  brezak 	    strcpy(dip->label.name, AudioNsource);
   1638  1.1  brezak 	    dip->un.e.num_mem = 3;
   1639  1.1  brezak 	    strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
   1640  1.1  brezak 	    dip->un.e.member[0].ord = SB_MIC_PORT;
   1641  1.1  brezak 	    strcpy(dip->un.e.member[1].label.name, AudioNcd);
   1642  1.1  brezak 	    dip->un.e.member[1].ord = SB_CD_PORT;
   1643  1.1  brezak 	    strcpy(dip->un.e.member[2].label.name, AudioNline);
   1644  1.1  brezak 	    dip->un.e.member[2].ord = SB_LINE_IN_PORT;
   1645  1.1  brezak 	    break;
   1646  1.1  brezak 	case SB_BASS:
   1647  1.1  brezak 	case SB_TREBLE:
   1648  1.1  brezak 	default:
   1649  1.1  brezak 	    return ENXIO;
   1650  1.1  brezak 	    /*NOTREACHED*/
   1651  1.1  brezak 	}
   1652  1.1  brezak     else
   1653  1.1  brezak 	return ENXIO;
   1654  1.1  brezak     }
   1655  1.1  brezak 
   1656  1.1  brezak     DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
   1657  1.1  brezak 
   1658  1.1  brezak     return 0;
   1659  1.1  brezak }
   1660