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