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