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