Home | History | Annotate | Line # | Download | only in isa
ess.c revision 1.59
      1  1.59    itojun /*	$NetBSD: ess.c,v 1.59 2004/04/22 00:17:11 itojun Exp $	*/
      2   1.1  augustss 
      3   1.1  augustss /*
      4   1.1  augustss  * Copyright 1997
      5   1.1  augustss  * Digital Equipment Corporation. All rights reserved.
      6   1.1  augustss  *
      7   1.1  augustss  * This software is furnished under license and may be used and
      8   1.1  augustss  * copied only in accordance with the following terms and conditions.
      9   1.1  augustss  * Subject to these conditions, you may download, copy, install,
     10   1.1  augustss  * use, modify and distribute this software in source and/or binary
     11   1.1  augustss  * form. No title or ownership is transferred hereby.
     12   1.1  augustss  *
     13   1.1  augustss  * 1) Any source code used, modified or distributed must reproduce
     14   1.1  augustss  *    and retain this copyright notice and list of conditions as
     15   1.1  augustss  *    they appear in the source file.
     16   1.1  augustss  *
     17   1.1  augustss  * 2) No right is granted to use any trade name, trademark, or logo of
     18   1.1  augustss  *    Digital Equipment Corporation. Neither the "Digital Equipment
     19   1.1  augustss  *    Corporation" name nor any trademark or logo of Digital Equipment
     20   1.1  augustss  *    Corporation may be used to endorse or promote products derived
     21   1.1  augustss  *    from this software without the prior written permission of
     22   1.1  augustss  *    Digital Equipment Corporation.
     23   1.1  augustss  *
     24   1.1  augustss  * 3) This software is provided "AS-IS" and any express or implied
     25   1.1  augustss  *    warranties, including but not limited to, any implied warranties
     26   1.1  augustss  *    of merchantability, fitness for a particular purpose, or
     27   1.1  augustss  *    non-infringement are disclaimed. In no event shall DIGITAL be
     28   1.1  augustss  *    liable for any damages whatsoever, and in particular, DIGITAL
     29   1.1  augustss  *    shall not be liable for special, indirect, consequential, or
     30   1.1  augustss  *    incidental damages or damages for lost profits, loss of
     31   1.1  augustss  *    revenue or loss of use, whether such damages arise in contract,
     32   1.1  augustss  *    negligence, tort, under statute, in equity, at law or otherwise,
     33   1.1  augustss  *    even if advised of the possibility of such damage.
     34   1.1  augustss  */
     35   1.1  augustss 
     36   1.1  augustss /*
     37   1.1  augustss **++
     38   1.1  augustss **
     39   1.1  augustss **  ess.c
     40   1.1  augustss **
     41   1.1  augustss **  FACILITY:
     42   1.1  augustss **
     43   1.1  augustss **	DIGITAL Network Appliance Reference Design (DNARD)
     44   1.1  augustss **
     45   1.1  augustss **  MODULE DESCRIPTION:
     46   1.1  augustss **
     47   1.1  augustss **      This module contains the device driver for the ESS
     48   1.1  augustss **      Technologies 1888/1887/888 sound chip. The code in sbdsp.c was
     49   1.1  augustss **	used as a reference point when implementing this driver.
     50   1.1  augustss **
     51   1.1  augustss **  AUTHORS:
     52   1.1  augustss **
     53   1.1  augustss **	Blair Fidler	Software Engineering Australia
     54   1.1  augustss **			Gold Coast, Australia.
     55   1.1  augustss **
     56   1.1  augustss **  CREATION DATE:
     57   1.1  augustss **
     58   1.1  augustss **	March 10, 1997.
     59   1.1  augustss **
     60   1.1  augustss **  MODIFICATION HISTORY:
     61   1.1  augustss **
     62  1.19   mycroft **	Heavily modified by Lennart Augustsson and Charles M. Hannum for
     63  1.19   mycroft **	bus_dma, changes to audio interface, and many bug fixes.
     64  1.34   mycroft **	ESS1788 support by Nathan J. Williams and Charles M. Hannum.
     65   1.1  augustss **--
     66   1.1  augustss */
     67  1.55     lukem 
     68  1.55     lukem #include <sys/cdefs.h>
     69  1.59    itojun __KERNEL_RCSID(0, "$NetBSD: ess.c,v 1.59 2004/04/22 00:17:11 itojun Exp $");
     70   1.1  augustss 
     71   1.1  augustss #include <sys/param.h>
     72   1.1  augustss #include <sys/systm.h>
     73   1.1  augustss #include <sys/errno.h>
     74   1.1  augustss #include <sys/ioctl.h>
     75   1.1  augustss #include <sys/syslog.h>
     76   1.1  augustss #include <sys/device.h>
     77   1.1  augustss #include <sys/proc.h>
     78  1.42   mycroft #include <sys/kernel.h>
     79   1.1  augustss 
     80   1.1  augustss #include <machine/cpu.h>
     81   1.1  augustss #include <machine/intr.h>
     82   1.6  augustss #include <machine/bus.h>
     83   1.1  augustss 
     84   1.1  augustss #include <sys/audioio.h>
     85   1.1  augustss #include <dev/audio_if.h>
     86   1.1  augustss #include <dev/auconv.h>
     87   1.1  augustss #include <dev/mulaw.h>
     88   1.1  augustss 
     89   1.1  augustss #include <dev/isa/isavar.h>
     90   1.1  augustss #include <dev/isa/isadmavar.h>
     91   1.1  augustss 
     92   1.1  augustss #include <dev/isa/essvar.h>
     93   1.1  augustss #include <dev/isa/essreg.h>
     94   1.1  augustss 
     95   1.1  augustss #ifdef AUDIO_DEBUG
     96   1.1  augustss #define DPRINTF(x)	if (essdebug) printf x
     97   1.2  augustss #define DPRINTFN(n,x)	if (essdebug>(n)) printf x
     98   1.1  augustss int	essdebug = 0;
     99   1.1  augustss #else
    100   1.1  augustss #define DPRINTF(x)
    101   1.2  augustss #define DPRINTFN(n,x)
    102   1.1  augustss #endif
    103   1.1  augustss 
    104   1.2  augustss #if 0
    105   1.2  augustss unsigned uuu;
    106   1.2  augustss #define EREAD1(t, h, a) (uuu=bus_space_read_1(t, h, a),printf("EREAD  %02x=%02x\n", ((int)h&0xfff)+a, uuu),uuu)
    107   1.2  augustss #define EWRITE1(t, h, a, d) (printf("EWRITE %02x=%02x\n", ((int)h & 0xfff)+a, d), bus_space_write_1(t, h, a, d))
    108   1.2  augustss #else
    109   1.2  augustss #define EREAD1(t, h, a) bus_space_read_1(t, h, a)
    110   1.2  augustss #define EWRITE1(t, h, a, d) bus_space_write_1(t, h, a, d)
    111   1.2  augustss #endif
    112   1.1  augustss 
    113   1.2  augustss 
    114   1.2  augustss int	ess_setup_sc __P((struct ess_softc *, int));
    115   1.1  augustss 
    116   1.1  augustss int	ess_open __P((void *, int));
    117  1.33   nathanw void	ess_1788_close __P((void *));
    118  1.33   nathanw void	ess_1888_close __P((void *));
    119   1.1  augustss int	ess_getdev __P((void *, struct audio_device *));
    120   1.1  augustss int	ess_drain __P((void *));
    121   1.1  augustss 
    122   1.1  augustss int	ess_query_encoding __P((void *, struct audio_encoding *));
    123   1.1  augustss 
    124   1.1  augustss int	ess_set_params __P((void *, int, int, struct audio_params *,
    125  1.19   mycroft 	    struct audio_params *));
    126   1.1  augustss 
    127   1.1  augustss int	ess_round_blocksize __P((void *, int));
    128   1.1  augustss 
    129  1.36   mycroft int	ess_audio1_trigger_output __P((void *, void *, void *, int,
    130  1.34   mycroft 	    void (*)(void *), void *, struct audio_params *));
    131  1.36   mycroft int	ess_audio2_trigger_output __P((void *, void *, void *, int,
    132  1.34   mycroft 	    void (*)(void *), void *, struct audio_params *));
    133  1.36   mycroft int	ess_audio1_trigger_input __P((void *, void *, void *, int,
    134  1.34   mycroft 	    void (*)(void *), void *, struct audio_params *));
    135  1.39   mycroft int	ess_audio1_halt __P((void *));
    136  1.39   mycroft int	ess_audio2_halt __P((void *));
    137  1.36   mycroft int	ess_audio1_intr __P((void *));
    138  1.36   mycroft int	ess_audio2_intr __P((void *));
    139  1.42   mycroft void	ess_audio1_poll __P((void *));
    140  1.42   mycroft void	ess_audio2_poll __P((void *));
    141   1.1  augustss 
    142   1.1  augustss int	ess_speaker_ctl __P((void *, int));
    143   1.1  augustss 
    144   1.1  augustss int	ess_getdev __P((void *, struct audio_device *));
    145   1.1  augustss 
    146   1.1  augustss int	ess_set_port __P((void *, mixer_ctrl_t *));
    147   1.1  augustss int	ess_get_port __P((void *, mixer_ctrl_t *));
    148   1.1  augustss 
    149  1.56   thorpej void   *ess_malloc __P((void *, int, size_t, struct malloc_type *, int));
    150  1.56   thorpej void	ess_free __P((void *, void *, struct malloc_type *));
    151  1.30   mycroft size_t	ess_round_buffersize __P((void *, int, size_t));
    152  1.52    simonb paddr_t	ess_mappage __P((void *, void *, off_t, int));
    153   1.4  augustss 
    154   1.4  augustss 
    155   1.1  augustss int	ess_query_devinfo __P((void *, mixer_devinfo_t *));
    156  1.36   mycroft int	ess_1788_get_props __P((void *));
    157  1.36   mycroft int	ess_1888_get_props __P((void *));
    158   1.1  augustss 
    159   1.4  augustss void	ess_speaker_on __P((struct ess_softc *));
    160   1.4  augustss void	ess_speaker_off __P((struct ess_softc *));
    161   1.1  augustss 
    162   1.4  augustss void	ess_config_irq __P((struct ess_softc *));
    163   1.4  augustss void	ess_config_drq __P((struct ess_softc *));
    164   1.4  augustss void	ess_setup __P((struct ess_softc *));
    165   1.1  augustss int	ess_identify __P((struct ess_softc *));
    166   1.1  augustss 
    167   1.1  augustss int	ess_reset __P((struct ess_softc *));
    168   1.1  augustss void	ess_set_gain __P((struct ess_softc *, int, int));
    169  1.33   nathanw int	ess_set_in_port __P((struct ess_softc *, int));
    170   1.1  augustss int	ess_set_in_ports __P((struct ess_softc *, int));
    171   1.1  augustss u_int	ess_srtotc __P((u_int));
    172   1.1  augustss u_int	ess_srtofc __P((u_int));
    173   1.1  augustss u_char	ess_get_dsp_status __P((struct ess_softc *));
    174   1.1  augustss u_char	ess_dsp_read_ready __P((struct ess_softc *));
    175  1.46  augustss u_char	ess_dsp_write_ready __P((struct ess_softc *));
    176   1.1  augustss int	ess_rdsp __P((struct ess_softc *));
    177   1.1  augustss int	ess_wdsp __P((struct ess_softc *, u_char));
    178   1.1  augustss u_char	ess_read_x_reg __P((struct ess_softc *, u_char));
    179   1.1  augustss int	ess_write_x_reg __P((struct ess_softc *, u_char, u_char));
    180   1.1  augustss void	ess_clear_xreg_bits __P((struct ess_softc *, u_char, u_char));
    181   1.1  augustss void	ess_set_xreg_bits __P((struct ess_softc *, u_char, u_char));
    182   1.1  augustss u_char	ess_read_mix_reg __P((struct ess_softc *, u_char));
    183   1.1  augustss void	ess_write_mix_reg __P((struct ess_softc *, u_char, u_char));
    184   1.1  augustss void	ess_clear_mreg_bits __P((struct ess_softc *, u_char, u_char));
    185   1.1  augustss void	ess_set_mreg_bits __P((struct ess_softc *, u_char, u_char));
    186  1.46  augustss void	ess_read_multi_mix_reg __P((struct ess_softc *, u_char, u_int8_t *, bus_size_t));
    187   1.1  augustss 
    188   1.1  augustss static char *essmodel[] = {
    189   1.1  augustss 	"unsupported",
    190   1.1  augustss 	"1888",
    191   1.1  augustss 	"1887",
    192  1.33   nathanw 	"888",
    193  1.46  augustss 	"1788",
    194  1.46  augustss 	"1869",
    195  1.46  augustss 	"1879",
    196  1.46  augustss 	"1868",
    197  1.46  augustss 	"1878",
    198   1.1  augustss };
    199   1.1  augustss 
    200   1.1  augustss struct audio_device ess_device = {
    201   1.1  augustss 	"ESS Technology",
    202   1.1  augustss 	"x",
    203   1.1  augustss 	"ess"
    204   1.1  augustss };
    205   1.1  augustss 
    206   1.1  augustss /*
    207   1.1  augustss  * Define our interface to the higher level audio driver.
    208   1.1  augustss  */
    209   1.1  augustss 
    210  1.33   nathanw struct audio_hw_if ess_1788_hw_if = {
    211   1.1  augustss 	ess_open,
    212  1.33   nathanw 	ess_1788_close,
    213   1.6  augustss 	ess_drain,
    214   1.1  augustss 	ess_query_encoding,
    215   1.1  augustss 	ess_set_params,
    216   1.1  augustss 	ess_round_blocksize,
    217   1.1  augustss 	NULL,
    218  1.19   mycroft 	NULL,
    219  1.19   mycroft 	NULL,
    220  1.19   mycroft 	NULL,
    221  1.19   mycroft 	NULL,
    222  1.39   mycroft 	ess_audio1_halt,
    223  1.39   mycroft 	ess_audio1_halt,
    224   1.1  augustss 	ess_speaker_ctl,
    225   1.1  augustss 	ess_getdev,
    226   1.1  augustss 	NULL,
    227   1.1  augustss 	ess_set_port,
    228   1.1  augustss 	ess_get_port,
    229   1.1  augustss 	ess_query_devinfo,
    230   1.4  augustss 	ess_malloc,
    231   1.4  augustss 	ess_free,
    232  1.30   mycroft 	ess_round_buffersize,
    233  1.33   nathanw 	ess_mappage,
    234  1.36   mycroft 	ess_1788_get_props,
    235  1.36   mycroft 	ess_audio1_trigger_output,
    236  1.36   mycroft 	ess_audio1_trigger_input,
    237  1.54  augustss 	NULL,
    238  1.33   nathanw };
    239  1.33   nathanw 
    240  1.33   nathanw struct audio_hw_if ess_1888_hw_if = {
    241  1.33   nathanw 	ess_open,
    242  1.33   nathanw 	ess_1888_close,
    243  1.33   nathanw 	ess_drain,
    244  1.33   nathanw 	ess_query_encoding,
    245  1.33   nathanw 	ess_set_params,
    246  1.33   nathanw 	ess_round_blocksize,
    247  1.33   nathanw 	NULL,
    248  1.33   nathanw 	NULL,
    249  1.33   nathanw 	NULL,
    250  1.33   nathanw 	NULL,
    251  1.33   nathanw 	NULL,
    252  1.39   mycroft 	ess_audio2_halt,
    253  1.39   mycroft 	ess_audio1_halt,
    254  1.33   nathanw 	ess_speaker_ctl,
    255  1.33   nathanw 	ess_getdev,
    256  1.33   nathanw 	NULL,
    257  1.33   nathanw 	ess_set_port,
    258  1.33   nathanw 	ess_get_port,
    259  1.33   nathanw 	ess_query_devinfo,
    260  1.33   nathanw 	ess_malloc,
    261  1.33   nathanw 	ess_free,
    262  1.33   nathanw 	ess_round_buffersize,
    263  1.33   nathanw 	ess_mappage,
    264  1.36   mycroft 	ess_1888_get_props,
    265  1.36   mycroft 	ess_audio2_trigger_output,
    266  1.36   mycroft 	ess_audio1_trigger_input,
    267  1.54  augustss 	NULL,
    268   1.1  augustss };
    269   1.1  augustss 
    270   1.1  augustss #ifdef AUDIO_DEBUG
    271   1.1  augustss void ess_printsc __P((struct ess_softc *));
    272   1.1  augustss void ess_dump_mixer __P((struct ess_softc *));
    273   1.1  augustss 
    274   1.1  augustss void
    275   1.1  augustss ess_printsc(sc)
    276   1.1  augustss 	struct ess_softc *sc;
    277   1.1  augustss {
    278   1.1  augustss 	int i;
    279   1.1  augustss 
    280   1.1  augustss 	printf("open %d iobase 0x%x outport %u inport %u speaker %s\n",
    281   1.1  augustss 	       (int)sc->sc_open, sc->sc_iobase, sc->out_port,
    282   1.1  augustss 	       sc->in_port, sc->spkr_state ? "on" : "off");
    283   1.1  augustss 
    284  1.57       wiz 	printf("audio1: DMA chan %d irq %d nintr %lu intr %p arg %p\n",
    285  1.34   mycroft 	       sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr,
    286  1.34   mycroft 	       sc->sc_audio1.intr, sc->sc_audio1.arg);
    287   1.1  augustss 
    288  1.46  augustss 	if (!ESS_USE_AUDIO1(sc->sc_model)) {
    289  1.57       wiz 		printf("audio2: DMA chan %d irq %d nintr %lu intr %p arg %p\n",
    290  1.34   mycroft 		       sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr,
    291  1.34   mycroft 		       sc->sc_audio2.intr, sc->sc_audio2.arg);
    292  1.35   mycroft 	}
    293   1.1  augustss 
    294   1.1  augustss 	printf("gain:");
    295  1.33   nathanw 	for (i = 0; i < sc->ndevs; i++)
    296   1.1  augustss 		printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]);
    297   1.1  augustss 	printf("\n");
    298   1.1  augustss }
    299   1.1  augustss 
    300   1.1  augustss void
    301   1.1  augustss ess_dump_mixer(sc)
    302   1.1  augustss 	struct ess_softc *sc;
    303   1.1  augustss {
    304   1.1  augustss 	printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
    305  1.34   mycroft 	       0x7C, ess_read_mix_reg(sc, 0x7C));
    306   1.1  augustss 	printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
    307   1.1  augustss 	       0x1A, ess_read_mix_reg(sc, 0x1A));
    308   1.1  augustss 	printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
    309   1.1  augustss 	       0x3E, ess_read_mix_reg(sc, 0x3E));
    310   1.1  augustss 	printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
    311   1.1  augustss 	       0x36, ess_read_mix_reg(sc, 0x36));
    312   1.1  augustss 	printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
    313   1.1  augustss 	       0x38, ess_read_mix_reg(sc, 0x38));
    314   1.1  augustss 	printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
    315   1.1  augustss 	       0x3A, ess_read_mix_reg(sc, 0x3A));
    316   1.1  augustss 	printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n",
    317   1.1  augustss 	       0x32, ess_read_mix_reg(sc, 0x32));
    318   1.1  augustss 	printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n",
    319   1.1  augustss 	       0x3C, ess_read_mix_reg(sc, 0x3C));
    320   1.1  augustss 	printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n",
    321   1.1  augustss 	       0x69, ess_read_mix_reg(sc, 0x69));
    322   1.1  augustss 	printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n",
    323   1.1  augustss 	       0x68, ess_read_mix_reg(sc, 0x68));
    324   1.1  augustss 	printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n",
    325   1.1  augustss 	       0x6E, ess_read_mix_reg(sc, 0x6E));
    326   1.1  augustss 	printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n",
    327   1.1  augustss 	       0x6B, ess_read_mix_reg(sc, 0x6B));
    328   1.1  augustss 	printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n",
    329   1.1  augustss 	       0x6A, ess_read_mix_reg(sc, 0x6A));
    330   1.1  augustss 	printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n",
    331   1.1  augustss 	       0x6C, ess_read_mix_reg(sc, 0x6C));
    332   1.1  augustss 	printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n",
    333   1.1  augustss 	       0xB4, ess_read_x_reg(sc, 0xB4));
    334   1.1  augustss 	printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n",
    335   1.1  augustss 	       0x14, ess_read_mix_reg(sc, 0x14));
    336   1.1  augustss 
    337   1.1  augustss 	printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n",
    338   1.1  augustss 	       ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL));
    339   1.1  augustss 	printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n",
    340   1.1  augustss 	       ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL));
    341   1.1  augustss 	printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n",
    342  1.34   mycroft 	       ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE),
    343  1.34   mycroft 	       ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2));
    344   1.1  augustss }
    345   1.1  augustss 
    346   1.1  augustss #endif
    347   1.1  augustss 
    348   1.1  augustss /*
    349   1.1  augustss  * Configure the ESS chip for the desired audio base address.
    350   1.1  augustss  */
    351   1.1  augustss int
    352   1.1  augustss ess_config_addr(sc)
    353   1.1  augustss 	struct ess_softc *sc;
    354   1.1  augustss {
    355   1.1  augustss 	int iobase = sc->sc_iobase;
    356   1.1  augustss 	bus_space_tag_t iot = sc->sc_iot;
    357   1.1  augustss 
    358   1.1  augustss 	/*
    359   1.1  augustss 	 * Configure using the System Control Register method.  This
    360   1.1  augustss 	 * method is used when the AMODE line is tied high, which is
    361   1.1  augustss 	 * the case for the Shark, but not for the evaluation board.
    362   1.1  augustss 	 */
    363   1.1  augustss 
    364   1.1  augustss 	bus_space_handle_t scr_access_ioh;
    365   1.1  augustss 	bus_space_handle_t scr_ioh;
    366   1.1  augustss 	u_short scr_value;
    367   1.1  augustss 
    368   1.1  augustss 	/*
    369   1.1  augustss 	 * Set the SCR bit to enable audio.
    370   1.1  augustss 	 */
    371   1.1  augustss 	scr_value = ESS_SCR_AUDIO_ENABLE;
    372   1.1  augustss 
    373   1.1  augustss 	/*
    374   1.1  augustss 	 * Set the SCR bits necessary to select the specified audio
    375   1.1  augustss 	 * base address.
    376   1.1  augustss 	 */
    377   1.1  augustss 	switch(iobase) {
    378   1.1  augustss 	case 0x220:
    379   1.1  augustss 		scr_value |= ESS_SCR_AUDIO_220;
    380   1.1  augustss 		break;
    381   1.1  augustss 	case 0x230:
    382   1.1  augustss 		scr_value |= ESS_SCR_AUDIO_230;
    383   1.1  augustss 		break;
    384   1.1  augustss 	case 0x240:
    385   1.1  augustss 		scr_value |= ESS_SCR_AUDIO_240;
    386   1.1  augustss 		break;
    387   1.1  augustss 	case 0x250:
    388   1.1  augustss 		scr_value |= ESS_SCR_AUDIO_250;
    389   1.1  augustss 		break;
    390   1.1  augustss 	default:
    391   1.1  augustss 		printf("ess: configured iobase 0x%x invalid\n", iobase);
    392   1.1  augustss 		return (1);
    393   1.1  augustss 		break;
    394   1.1  augustss 	}
    395   1.1  augustss 
    396   1.1  augustss 	/*
    397   1.1  augustss 	 * Get a mapping for the System Control Register (SCR) access
    398   1.1  augustss 	 * registers and the SCR data registers.
    399   1.1  augustss 	 */
    400   1.1  augustss 	if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS,
    401   1.1  augustss 			  0, &scr_access_ioh)) {
    402   1.1  augustss 		printf("ess: can't map SCR access registers\n");
    403   1.1  augustss 		return (1);
    404   1.1  augustss 	}
    405   1.1  augustss 	if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS,
    406   1.1  augustss 			  0, &scr_ioh)) {
    407   1.1  augustss 		printf("ess: can't map SCR registers\n");
    408   1.1  augustss 		bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
    409   1.1  augustss 		return (1);
    410   1.1  augustss 	}
    411   1.1  augustss 
    412   1.1  augustss 	/* Unlock the SCR. */
    413   1.2  augustss 	EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0);
    414   1.1  augustss 
    415   1.1  augustss 	/* Write the base address information into SCR[0]. */
    416   1.2  augustss 	EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0);
    417   1.2  augustss 	EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value);
    418   1.1  augustss 
    419   1.1  augustss 	/* Lock the SCR. */
    420   1.2  augustss 	EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0);
    421   1.1  augustss 
    422   1.1  augustss 	/* Unmap the SCR access ports and the SCR data ports. */
    423   1.1  augustss 	bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
    424   1.1  augustss 	bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS);
    425   1.1  augustss 
    426   1.1  augustss 	return 0;
    427   1.1  augustss }
    428   1.1  augustss 
    429   1.1  augustss 
    430   1.1  augustss /*
    431   1.1  augustss  * Configure the ESS chip for the desired IRQ and DMA channels.
    432   1.2  augustss  * ESS  ISA
    433   1.2  augustss  * --------
    434   1.2  augustss  * IRQA irq9
    435   1.2  augustss  * IRQB irq5
    436   1.2  augustss  * IRQC irq7
    437   1.2  augustss  * IRQD irq10
    438   1.2  augustss  * IRQE irq15
    439   1.4  augustss  *
    440   1.2  augustss  * DRQA drq0
    441   1.2  augustss  * DRQB drq1
    442   1.2  augustss  * DRQC drq3
    443   1.2  augustss  * DRQD drq5
    444   1.1  augustss  */
    445   1.1  augustss void
    446   1.4  augustss ess_config_irq(sc)
    447   1.1  augustss 	struct ess_softc *sc;
    448   1.1  augustss {
    449   1.4  augustss 	int v;
    450   1.1  augustss 
    451   1.4  augustss 	DPRINTFN(2,("ess_config_irq\n"));
    452   1.4  augustss 
    453  1.34   mycroft 	if (sc->sc_model == ESS_1887 &&
    454  1.42   mycroft 	    sc->sc_audio1.irq == sc->sc_audio2.irq &&
    455  1.42   mycroft 	    sc->sc_audio1.irq != -1) {
    456   1.4  augustss 		/* Use new method, both interrupts are the same. */
    457   1.4  augustss 		v = ESS_IS_SELECT_IRQ;	/* enable intrs */
    458  1.42   mycroft 		switch (sc->sc_audio1.irq) {
    459   1.4  augustss 		case 5:
    460   1.4  augustss 			v |= ESS_IS_INTRB;
    461   1.4  augustss 			break;
    462   1.4  augustss 		case 7:
    463   1.4  augustss 			v |= ESS_IS_INTRC;
    464   1.4  augustss 			break;
    465   1.4  augustss 		case 9:
    466   1.4  augustss 			v |= ESS_IS_INTRA;
    467   1.4  augustss 			break;
    468   1.4  augustss 		case 10:
    469   1.4  augustss 			v |= ESS_IS_INTRD;
    470   1.4  augustss 			break;
    471   1.4  augustss 		case 15:
    472   1.4  augustss 			v |= ESS_IS_INTRE;
    473   1.4  augustss 			break;
    474   1.4  augustss #ifdef DIAGNOSTIC
    475   1.4  augustss 		default:
    476   1.4  augustss 			printf("ess_config_irq: configured irq %d not supported for Audio 1\n",
    477  1.34   mycroft 			       sc->sc_audio1.irq);
    478   1.4  augustss 			return;
    479   1.4  augustss #endif
    480   1.4  augustss 		}
    481   1.4  augustss 		/* Set the IRQ */
    482   1.4  augustss 		ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v);
    483  1.34   mycroft 		return;
    484  1.34   mycroft 	}
    485  1.34   mycroft 
    486  1.42   mycroft 	if (sc->sc_model == ESS_1887) {
    487  1.42   mycroft 		/* Tell the 1887 to use the old interrupt method. */
    488  1.42   mycroft 		ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888);
    489  1.42   mycroft 	}
    490  1.42   mycroft 
    491  1.42   mycroft 	if (sc->sc_audio1.polled) {
    492  1.42   mycroft 		/* Turn off Audio1 interrupts. */
    493  1.42   mycroft 		v = 0;
    494  1.42   mycroft 	} else {
    495  1.42   mycroft 		/* Configure Audio 1 for the appropriate IRQ line. */
    496  1.42   mycroft 		v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT; /* All intrs on */
    497  1.42   mycroft 		switch (sc->sc_audio1.irq) {
    498  1.42   mycroft 		case 5:
    499  1.42   mycroft 			v |= ESS_IRQ_CTRL_INTRB;
    500  1.42   mycroft 			break;
    501  1.42   mycroft 		case 7:
    502  1.42   mycroft 			v |= ESS_IRQ_CTRL_INTRC;
    503  1.42   mycroft 			break;
    504  1.42   mycroft 		case 9:
    505  1.42   mycroft 			v |= ESS_IRQ_CTRL_INTRA;
    506  1.42   mycroft 			break;
    507  1.42   mycroft 		case 10:
    508  1.42   mycroft 			v |= ESS_IRQ_CTRL_INTRD;
    509  1.42   mycroft 			break;
    510  1.34   mycroft #ifdef DIAGNOSTIC
    511  1.42   mycroft 		default:
    512  1.42   mycroft 			printf("ess: configured irq %d not supported for Audio 1\n",
    513  1.42   mycroft 			       sc->sc_audio1.irq);
    514  1.42   mycroft 			return;
    515  1.34   mycroft #endif
    516  1.42   mycroft 		}
    517   1.4  augustss 	}
    518  1.34   mycroft 	ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v);
    519  1.34   mycroft 
    520  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model))
    521  1.34   mycroft 		return;
    522  1.34   mycroft 
    523  1.42   mycroft 	if (sc->sc_audio2.polled) {
    524  1.42   mycroft 		/* Turn off Audio2 interrupts. */
    525  1.42   mycroft 		ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
    526  1.42   mycroft 				    ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
    527  1.42   mycroft 	} else {
    528  1.42   mycroft 		/* Audio2 is hardwired to INTRE in this mode. */
    529  1.42   mycroft 		ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
    530  1.42   mycroft 				  ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
    531  1.42   mycroft 	}
    532   1.4  augustss }
    533   1.4  augustss 
    534   1.4  augustss 
    535   1.4  augustss void
    536   1.4  augustss ess_config_drq(sc)
    537   1.4  augustss 	struct ess_softc *sc;
    538   1.4  augustss {
    539   1.4  augustss 	int v;
    540   1.4  augustss 
    541   1.4  augustss 	DPRINTFN(2,("ess_config_drq\n"));
    542   1.4  augustss 
    543   1.4  augustss 	/* Configure Audio 1 (record) for DMA on the appropriate channel. */
    544   1.4  augustss 	v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT;
    545  1.34   mycroft 	switch (sc->sc_audio1.drq) {
    546   1.4  augustss 	case 0:
    547   1.4  augustss 		v |= ESS_DRQ_CTRL_DRQA;
    548   1.1  augustss 		break;
    549   1.4  augustss 	case 1:
    550   1.4  augustss 		v |= ESS_DRQ_CTRL_DRQB;
    551   1.1  augustss 		break;
    552   1.4  augustss 	case 3:
    553   1.4  augustss 		v |= ESS_DRQ_CTRL_DRQC;
    554   1.1  augustss 		break;
    555   1.2  augustss #ifdef DIAGNOSTIC
    556   1.1  augustss 	default:
    557  1.57       wiz 		printf("ess_config_drq: configured DMA chan %d not supported for Audio 1\n",
    558  1.34   mycroft 		       sc->sc_audio1.drq);
    559   1.1  augustss 		return;
    560   1.5  augustss #endif
    561   1.4  augustss 	}
    562   1.4  augustss 	/* Set DRQ1 */
    563   1.4  augustss 	ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v);
    564   1.4  augustss 
    565  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model))
    566  1.34   mycroft 		return;
    567  1.34   mycroft 
    568  1.34   mycroft 	/* Configure DRQ2 */
    569  1.34   mycroft 	v = ESS_AUDIO2_CTRL3_DRQ_PD;
    570  1.34   mycroft 	switch (sc->sc_audio2.drq) {
    571  1.34   mycroft 	case 0:
    572  1.34   mycroft 		v |= ESS_AUDIO2_CTRL3_DRQA;
    573  1.34   mycroft 		break;
    574  1.34   mycroft 	case 1:
    575  1.34   mycroft 		v |= ESS_AUDIO2_CTRL3_DRQB;
    576  1.34   mycroft 		break;
    577  1.34   mycroft 	case 3:
    578  1.34   mycroft 		v |= ESS_AUDIO2_CTRL3_DRQC;
    579  1.34   mycroft 		break;
    580  1.34   mycroft 	case 5:
    581  1.37   mycroft 		v |= ESS_AUDIO2_CTRL3_DRQD;
    582  1.34   mycroft 		break;
    583   1.2  augustss #ifdef DIAGNOSTIC
    584  1.34   mycroft 	default:
    585  1.57       wiz 		printf("ess_config_drq: configured DMA chan %d not supported for Audio 2\n",
    586  1.34   mycroft 		       sc->sc_audio2.drq);
    587  1.34   mycroft 		return;
    588   1.5  augustss #endif
    589   1.1  augustss 	}
    590  1.34   mycroft 	ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v);
    591  1.34   mycroft 	/* Enable DMA 2 */
    592  1.34   mycroft 	ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
    593  1.34   mycroft 			  ESS_AUDIO2_CTRL2_DMA_ENABLE);
    594   1.4  augustss }
    595   1.4  augustss 
    596   1.4  augustss /*
    597   1.4  augustss  * Set up registers after a reset.
    598   1.4  augustss  */
    599   1.4  augustss void
    600   1.4  augustss ess_setup(sc)
    601   1.4  augustss 	struct ess_softc *sc;
    602   1.4  augustss {
    603  1.18   mycroft 
    604   1.4  augustss 	ess_config_irq(sc);
    605   1.4  augustss 	ess_config_drq(sc);
    606   1.2  augustss 
    607   1.4  augustss 	DPRINTFN(2,("ess_setup: done\n"));
    608   1.1  augustss }
    609   1.1  augustss 
    610   1.1  augustss /*
    611   1.1  augustss  * Determine the model of ESS chip we are talking to.  Currently we
    612   1.1  augustss  * only support ES1888, ES1887 and ES888.  The method of determining
    613   1.1  augustss  * the chip is based on the information on page 27 of the ES1887 data
    614   1.1  augustss  * sheet.
    615   1.1  augustss  *
    616   1.1  augustss  * This routine sets the values of sc->sc_model and sc->sc_version.
    617   1.1  augustss  */
    618   1.1  augustss int
    619   1.1  augustss ess_identify(sc)
    620   1.1  augustss 	struct ess_softc *sc;
    621   1.1  augustss {
    622   1.1  augustss 	u_char reg1;
    623   1.1  augustss 	u_char reg2;
    624   1.1  augustss 	u_char reg3;
    625  1.46  augustss 	u_int8_t ident[4];
    626   1.1  augustss 
    627   1.1  augustss 	sc->sc_model = ESS_UNSUPPORTED;
    628   1.1  augustss 	sc->sc_version = 0;
    629   1.1  augustss 
    630  1.46  augustss 	memset(ident, 0, sizeof(ident));
    631   1.1  augustss 
    632   1.1  augustss 	/*
    633   1.1  augustss 	 * 1. Check legacy ID bytes.  These should be 0x68 0x8n, where
    634   1.1  augustss 	 *    n >= 8 for an ES1887 or an ES888.  Other values indicate
    635   1.1  augustss 	 *    earlier (unsupported) chips.
    636   1.1  augustss 	 */
    637   1.1  augustss 	ess_wdsp(sc, ESS_ACMD_LEGACY_ID);
    638   1.1  augustss 
    639   1.1  augustss 	if ((reg1 = ess_rdsp(sc)) != 0x68) {
    640   1.1  augustss 		printf("ess: First ID byte wrong (0x%02x)\n", reg1);
    641   1.1  augustss 		return 1;
    642   1.1  augustss 	}
    643   1.1  augustss 
    644   1.1  augustss 	reg2 = ess_rdsp(sc);
    645   1.1  augustss 	if (((reg2 & 0xf0) != 0x80) ||
    646   1.1  augustss 	    ((reg2 & 0x0f) < 8)) {
    647   1.1  augustss 		printf("ess: Second ID byte wrong (0x%02x)\n", reg2);
    648   1.1  augustss 		return 1;
    649   1.1  augustss 	}
    650   1.1  augustss 
    651   1.1  augustss 	/*
    652   1.1  augustss 	 * Store the ID bytes as the version.
    653   1.1  augustss 	 */
    654   1.1  augustss 	sc->sc_version = (reg1 << 8) + reg2;
    655   1.1  augustss 
    656   1.1  augustss 
    657   1.1  augustss 	/*
    658   1.1  augustss 	 * 2. Verify we can change bit 2 in mixer register 0x64.  This
    659   1.1  augustss 	 *    should be possible on all supported chips.
    660   1.1  augustss 	 */
    661  1.33   nathanw 	reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
    662   1.1  augustss 	reg2 = reg1 ^ 0x04;  /* toggle bit 2 */
    663   1.1  augustss 
    664  1.33   nathanw 	ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
    665   1.1  augustss 
    666  1.33   nathanw 	if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) {
    667   1.1  augustss 		printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n");
    668   1.1  augustss 		return 1;
    669   1.1  augustss 	}
    670   1.1  augustss 
    671   1.1  augustss 	/*
    672   1.1  augustss 	 * Restore the original value of mixer register 0x64.
    673   1.1  augustss 	 */
    674  1.33   nathanw 	ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
    675   1.1  augustss 
    676   1.1  augustss 
    677   1.1  augustss 	/*
    678   1.4  augustss 	 * 3. Verify we can change the value of mixer register
    679   1.4  augustss 	 *    ESS_MREG_SAMPLE_RATE.
    680  1.33   nathanw 	 *    This is possible on the 1888/1887/888, but not on the 1788.
    681   1.4  augustss 	 *    It is not necessary to restore the value of this mixer register.
    682   1.1  augustss 	 */
    683   1.4  augustss 	reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE);
    684   1.1  augustss 	reg2 = reg1 ^ 0xff;  /* toggle all bits */
    685   1.1  augustss 
    686   1.4  augustss 	ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2);
    687   1.1  augustss 
    688   1.4  augustss 	if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) {
    689  1.34   mycroft 		/* If we got this far before failing, it's a 1788. */
    690  1.34   mycroft 		sc->sc_model = ESS_1788;
    691  1.46  augustss 
    692  1.46  augustss 		/*
    693  1.46  augustss 		 * Identify ESS model for ES18[67]8.
    694  1.46  augustss 		 */
    695  1.46  augustss 		ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
    696  1.46  augustss 		if(ident[0] == 0x18) {
    697  1.46  augustss 			switch(ident[1]) {
    698  1.46  augustss 			case 0x68:
    699  1.46  augustss 				sc->sc_model = ESS_1868;
    700  1.46  augustss 				break;
    701  1.46  augustss 			case 0x78:
    702  1.46  augustss 				sc->sc_model = ESS_1878;
    703  1.46  augustss 				break;
    704  1.46  augustss 			}
    705  1.46  augustss 		}
    706   1.1  augustss 	} else {
    707   1.1  augustss 		/*
    708  1.33   nathanw 		 * 4. Determine if we can change bit 5 in mixer register 0x64.
    709  1.33   nathanw 		 *    This determines whether we have an ES1887:
    710   1.1  augustss 		 *
    711  1.33   nathanw 		 *    - can change indicates ES1887
    712  1.33   nathanw 		 *    - can't change indicates ES1888 or ES888
    713   1.1  augustss 		 */
    714  1.33   nathanw 		reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
    715  1.33   nathanw 		reg2 = reg1 ^ 0x20;  /* toggle bit 5 */
    716  1.33   nathanw 
    717  1.33   nathanw 		ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
    718  1.33   nathanw 
    719  1.33   nathanw 		if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) {
    720  1.33   nathanw 			sc->sc_model = ESS_1887;
    721   1.1  augustss 
    722  1.33   nathanw 			/*
    723  1.33   nathanw 			 * Restore the original value of mixer register 0x64.
    724  1.33   nathanw 			 */
    725  1.33   nathanw 			ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
    726  1.46  augustss 
    727  1.46  augustss 			/*
    728  1.46  augustss 			 * Identify ESS model for ES18[67]9.
    729  1.46  augustss 			 */
    730  1.46  augustss 			ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
    731  1.46  augustss 			if(ident[0] == 0x18) {
    732  1.46  augustss 				switch(ident[1]) {
    733  1.46  augustss 				case 0x69:
    734  1.46  augustss 					sc->sc_model = ESS_1869;
    735  1.46  augustss 					break;
    736  1.46  augustss 				case 0x79:
    737  1.46  augustss 					sc->sc_model = ESS_1879;
    738  1.46  augustss 					break;
    739  1.46  augustss 				}
    740  1.46  augustss 			}
    741  1.33   nathanw 		} else {
    742  1.33   nathanw 			/*
    743  1.33   nathanw 			 * 5. Determine if we can change the value of mixer
    744  1.33   nathanw 			 *    register 0x69 independently of mixer register
    745  1.33   nathanw 			 *    0x68. This determines which chip we have:
    746  1.33   nathanw 			 *
    747  1.33   nathanw 			 *    - can modify idependently indicates ES888
    748  1.33   nathanw 			 *    - register 0x69 is an alias of 0x68 indicates ES1888
    749  1.33   nathanw 			 */
    750  1.33   nathanw 			reg1 = ess_read_mix_reg(sc, 0x68);
    751  1.33   nathanw 			reg2 = ess_read_mix_reg(sc, 0x69);
    752  1.33   nathanw 			reg3 = reg2 ^ 0xff;  /* toggle all bits */
    753  1.33   nathanw 
    754  1.33   nathanw 			/*
    755  1.33   nathanw 			 * Write different values to each register.
    756  1.33   nathanw 			 */
    757  1.33   nathanw 			ess_write_mix_reg(sc, 0x68, reg2);
    758  1.33   nathanw 			ess_write_mix_reg(sc, 0x69, reg3);
    759  1.33   nathanw 
    760  1.34   mycroft 			if (ess_read_mix_reg(sc, 0x68) == reg2 &&
    761  1.34   mycroft 			    ess_read_mix_reg(sc, 0x69) == reg3)
    762  1.33   nathanw 				sc->sc_model = ESS_888;
    763  1.33   nathanw 			else
    764  1.33   nathanw 				sc->sc_model = ESS_1888;
    765   1.1  augustss 
    766  1.33   nathanw 			/*
    767  1.33   nathanw 			 * Restore the original value of the registers.
    768  1.33   nathanw 			 */
    769  1.33   nathanw 			ess_write_mix_reg(sc, 0x68, reg1);
    770  1.33   nathanw 			ess_write_mix_reg(sc, 0x69, reg2);
    771  1.33   nathanw 		}
    772   1.1  augustss 	}
    773   1.1  augustss 
    774   1.1  augustss 	return 0;
    775   1.1  augustss }
    776   1.1  augustss 
    777   1.1  augustss 
    778   1.1  augustss int
    779   1.2  augustss ess_setup_sc(sc, doinit)
    780   1.1  augustss 	struct ess_softc *sc;
    781   1.1  augustss 	int doinit;
    782   1.1  augustss {
    783  1.51   thorpej 
    784  1.51   thorpej 	callout_init(&sc->sc_poll1_ch);
    785  1.51   thorpej 	callout_init(&sc->sc_poll2_ch);
    786  1.51   thorpej 
    787   1.1  augustss 	/* Reset the chip. */
    788   1.4  augustss 	if (ess_reset(sc) != 0) {
    789   1.4  augustss 		DPRINTF(("ess_setup_sc: couldn't reset chip\n"));
    790   1.1  augustss 		return (1);
    791   1.1  augustss 	}
    792   1.1  augustss 
    793   1.1  augustss 	/* Identify the ESS chip, and check that it is supported. */
    794   1.1  augustss 	if (ess_identify(sc)) {
    795   1.1  augustss 		DPRINTF(("ess_setup_sc: couldn't identify\n"));
    796   1.1  augustss 		return (1);
    797   1.1  augustss 	}
    798   1.1  augustss 
    799   1.1  augustss 	return (0);
    800   1.1  augustss }
    801   1.1  augustss 
    802   1.1  augustss /*
    803   1.1  augustss  * Probe for the ESS hardware.
    804   1.1  augustss  */
    805   1.1  augustss int
    806   1.2  augustss essmatch(sc)
    807   1.2  augustss 	struct ess_softc *sc;
    808   1.1  augustss {
    809   1.2  augustss 	if (!ESS_BASE_VALID(sc->sc_iobase)) {
    810   1.2  augustss 		printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase);
    811   1.1  augustss 		return (0);
    812   1.1  augustss 	}
    813   1.4  augustss 
    814   1.2  augustss 	if (ess_setup_sc(sc, 1))
    815   1.2  augustss 		return (0);
    816   1.1  augustss 
    817   1.1  augustss 	if (sc->sc_model == ESS_UNSUPPORTED) {
    818   1.1  augustss 		DPRINTF(("ess: Unsupported model\n"));
    819   1.4  augustss 		return (0);
    820   1.1  augustss 	}
    821   1.1  augustss 
    822   1.1  augustss 	/* Check that requested DMA channels are valid and different. */
    823  1.34   mycroft 	if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) {
    824  1.34   mycroft 		printf("ess: record drq %d invalid\n", sc->sc_audio1.drq);
    825   1.4  augustss 		return (0);
    826   1.1  augustss 	}
    827  1.40   mycroft 	if (!isa_drq_isfree(sc->sc_ic, sc->sc_audio1.drq))
    828  1.40   mycroft 		return (0);
    829  1.46  augustss 	if (!ESS_USE_AUDIO1(sc->sc_model)) {
    830  1.44   mycroft 		if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) {
    831  1.34   mycroft 			printf("ess: play drq %d invalid\n", sc->sc_audio2.drq);
    832  1.33   nathanw 			return (0);
    833  1.33   nathanw 		}
    834  1.34   mycroft 		if (sc->sc_audio1.drq == sc->sc_audio2.drq) {
    835  1.34   mycroft 			printf("ess: play and record drq both %d\n",
    836  1.34   mycroft 			       sc->sc_audio1.drq);
    837  1.33   nathanw 			return (0);
    838  1.33   nathanw 		}
    839  1.40   mycroft 		if (!isa_drq_isfree(sc->sc_ic, sc->sc_audio2.drq))
    840  1.40   mycroft 			return (0);
    841  1.34   mycroft 	}
    842   1.1  augustss 
    843  1.34   mycroft 	/*
    844  1.34   mycroft 	 * The 1887 has an additional IRQ mode where both channels are mapped
    845  1.34   mycroft 	 * to the same IRQ.
    846  1.34   mycroft 	 */
    847  1.34   mycroft 	if (sc->sc_model == ESS_1887 &&
    848  1.34   mycroft 	    sc->sc_audio1.irq == sc->sc_audio2.irq &&
    849  1.42   mycroft 	    sc->sc_audio1.irq != -1 &&
    850  1.34   mycroft 	    ESS_IRQ12_VALID(sc->sc_audio1.irq))
    851  1.34   mycroft 		goto irq_not1888;
    852  1.34   mycroft 
    853  1.34   mycroft 	/* Check that requested IRQ lines are valid and different. */
    854  1.42   mycroft 	if (sc->sc_audio1.irq != -1 &&
    855  1.42   mycroft 	    !ESS_IRQ1_VALID(sc->sc_audio1.irq)) {
    856  1.34   mycroft 		printf("ess: record irq %d invalid\n", sc->sc_audio1.irq);
    857  1.34   mycroft 		return (0);
    858  1.33   nathanw 	}
    859  1.46  augustss 	if (!ESS_USE_AUDIO1(sc->sc_model)) {
    860  1.42   mycroft 		if (sc->sc_audio2.irq != -1 &&
    861  1.42   mycroft 		    !ESS_IRQ2_VALID(sc->sc_audio2.irq)) {
    862  1.34   mycroft 			printf("ess: play irq %d invalid\n", sc->sc_audio2.irq);
    863  1.33   nathanw 			return (0);
    864  1.33   nathanw 		}
    865  1.42   mycroft 		if (sc->sc_audio1.irq == sc->sc_audio2.irq &&
    866  1.42   mycroft 		    sc->sc_audio1.irq != -1) {
    867  1.34   mycroft 			printf("ess: play and record irq both %d\n",
    868  1.34   mycroft 			       sc->sc_audio1.irq);
    869   1.4  augustss 			return (0);
    870   1.4  augustss 		}
    871   1.4  augustss 	}
    872   1.1  augustss 
    873  1.34   mycroft irq_not1888:
    874   1.1  augustss 	/* XXX should we check IRQs as well? */
    875   1.1  augustss 
    876   1.2  augustss 	return (1);
    877   1.1  augustss }
    878   1.1  augustss 
    879   1.1  augustss 
    880   1.1  augustss /*
    881   1.1  augustss  * Attach hardware to driver, attach hardware driver to audio
    882   1.4  augustss  * pseudo-device driver.
    883   1.1  augustss  */
    884   1.1  augustss void
    885   1.2  augustss essattach(sc)
    886   1.2  augustss 	struct ess_softc *sc;
    887   1.1  augustss {
    888  1.24  augustss 	struct audio_attach_args arg;
    889   1.1  augustss 	struct audio_params pparams, rparams;
    890  1.34   mycroft 	int i;
    891  1.34   mycroft 	u_int v;
    892   1.1  augustss 
    893   1.2  augustss 	if (ess_setup_sc(sc, 0)) {
    894  1.42   mycroft 		printf(": setup failed\n");
    895   1.1  augustss 		return;
    896   1.1  augustss 	}
    897   1.1  augustss 
    898  1.42   mycroft 	printf(": ESS Technology ES%s [version 0x%04x]\n",
    899  1.42   mycroft 	       essmodel[sc->sc_model], sc->sc_version);
    900  1.43   mycroft 
    901  1.42   mycroft 	sc->sc_audio1.polled = sc->sc_audio1.irq == -1;
    902  1.42   mycroft 	if (!sc->sc_audio1.polled) {
    903  1.42   mycroft 		sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic,
    904  1.42   mycroft 		    sc->sc_audio1.irq, sc->sc_audio1.ist, IPL_AUDIO,
    905  1.42   mycroft 		    ess_audio1_intr, sc);
    906  1.42   mycroft 		printf("%s: audio1 interrupting at irq %d\n",
    907  1.42   mycroft 		    sc->sc_dev.dv_xname, sc->sc_audio1.irq);
    908  1.42   mycroft 	} else
    909  1.42   mycroft 		printf("%s: audio1 polled\n", sc->sc_dev.dv_xname);
    910  1.50   thorpej 	sc->sc_audio1.maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_audio1.drq);
    911  1.58      fvdl 
    912  1.58      fvdl 	if (isa_drq_alloc(sc->sc_ic, sc->sc_audio1.drq) != 0) {
    913  1.58      fvdl 		printf("%s: can't reserve drq %d\n",
    914  1.58      fvdl 		    sc->sc_dev.dv_xname, sc->sc_audio1.drq);
    915  1.58      fvdl 		return;
    916  1.58      fvdl 	}
    917  1.58      fvdl 
    918  1.34   mycroft 	if (isa_dmamap_create(sc->sc_ic, sc->sc_audio1.drq,
    919  1.50   thorpej 	    sc->sc_audio1.maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
    920   1.1  augustss 		printf("%s: can't create map for drq %d\n",
    921  1.34   mycroft 		       sc->sc_dev.dv_xname, sc->sc_audio1.drq);
    922   1.1  augustss 		return;
    923   1.1  augustss 	}
    924  1.33   nathanw 
    925  1.46  augustss 	if (!ESS_USE_AUDIO1(sc->sc_model)) {
    926  1.42   mycroft 		sc->sc_audio2.polled = sc->sc_audio2.irq == -1;
    927  1.42   mycroft 		if (!sc->sc_audio2.polled) {
    928  1.42   mycroft 			sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic,
    929  1.42   mycroft 			    sc->sc_audio2.irq, sc->sc_audio2.ist, IPL_AUDIO,
    930  1.42   mycroft 			    ess_audio2_intr, sc);
    931  1.42   mycroft 			printf("%s: audio2 interrupting at irq %d\n",
    932  1.42   mycroft 			    sc->sc_dev.dv_xname, sc->sc_audio2.irq);
    933  1.42   mycroft 		} else
    934  1.42   mycroft 			printf("%s: audio2 polled\n", sc->sc_dev.dv_xname);
    935  1.50   thorpej 		sc->sc_audio2.maxsize = isa_dmamaxsize(sc->sc_ic,
    936  1.50   thorpej 		    sc->sc_audio2.drq);
    937  1.58      fvdl 
    938  1.58      fvdl 		if (isa_drq_alloc(sc->sc_ic, sc->sc_audio2.drq) != 0) {
    939  1.58      fvdl 			printf("%s: can't reserve drq %d\n",
    940  1.58      fvdl 			    sc->sc_dev.dv_xname, sc->sc_audio2.drq);
    941  1.58      fvdl 			return;
    942  1.58      fvdl 		}
    943  1.58      fvdl 
    944  1.34   mycroft 		if (isa_dmamap_create(sc->sc_ic, sc->sc_audio2.drq,
    945  1.50   thorpej 		    sc->sc_audio2.maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
    946  1.33   nathanw 			printf("%s: can't create map for drq %d\n",
    947  1.34   mycroft 			       sc->sc_dev.dv_xname, sc->sc_audio2.drq);
    948  1.33   nathanw 			return;
    949  1.33   nathanw 		}
    950   1.1  augustss 	}
    951   1.1  augustss 
    952   1.1  augustss 	/*
    953   1.1  augustss 	 * Set record and play parameters to default values defined in
    954   1.1  augustss 	 * generic audio driver.
    955   1.1  augustss 	 */
    956   1.1  augustss 	pparams = audio_default;
    957   1.1  augustss 	rparams = audio_default;
    958  1.34   mycroft 	ess_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
    959   1.1  augustss 
    960   1.1  augustss 	/* Do a hardware reset on the mixer. */
    961   1.1  augustss 	ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET);
    962   1.1  augustss 
    963  1.34   mycroft 	/*
    964  1.34   mycroft 	 * Set volume of Audio 1 to zero and disable Audio 1 DAC input
    965  1.34   mycroft 	 * to playback mixer, since playback is always through Audio 2.
    966  1.34   mycroft 	 */
    967  1.46  augustss 	if (!ESS_USE_AUDIO1(sc->sc_model))
    968  1.34   mycroft 		ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0);
    969  1.34   mycroft 	ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
    970   1.1  augustss 
    971  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model)) {
    972  1.34   mycroft 		ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
    973  1.34   mycroft 		sc->in_port = ESS_SOURCE_MIC;
    974  1.34   mycroft 		sc->ndevs = ESS_1788_NDEVS;
    975  1.33   nathanw 	} else {
    976  1.33   nathanw 		/*
    977  1.33   nathanw 		 * Set hardware record source to use output of the record
    978  1.33   nathanw 		 * mixer. We do the selection of record source in software by
    979  1.33   nathanw 		 * setting the gain of the unused sources to zero. (See
    980  1.33   nathanw 		 * ess_set_in_ports.)
    981  1.33   nathanw 		 */
    982  1.33   nathanw 		ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER);
    983  1.34   mycroft 		sc->in_mask = 1 << ESS_MIC_REC_VOL;
    984  1.34   mycroft 		sc->ndevs = ESS_1888_NDEVS;
    985  1.34   mycroft 		ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10);
    986  1.34   mycroft 		ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08);
    987  1.33   nathanw 	}
    988   1.1  augustss 
    989   1.1  augustss 	/*
    990   1.1  augustss 	 * Set gain on each mixer device to a sensible value.
    991   1.1  augustss 	 * Devices not normally used are turned off, and other devices
    992  1.25  augustss 	 * are set to 50% volume.
    993   1.1  augustss 	 */
    994  1.33   nathanw 	for (i = 0; i < sc->ndevs; i++) {
    995  1.34   mycroft 		switch (i) {
    996   1.1  augustss 		case ESS_MIC_PLAY_VOL:
    997   1.1  augustss 		case ESS_LINE_PLAY_VOL:
    998   1.1  augustss 		case ESS_CD_PLAY_VOL:
    999   1.1  augustss 		case ESS_AUXB_PLAY_VOL:
   1000   1.1  augustss 		case ESS_DAC_REC_VOL:
   1001   1.1  augustss 		case ESS_LINE_REC_VOL:
   1002   1.1  augustss 		case ESS_SYNTH_REC_VOL:
   1003   1.1  augustss 		case ESS_CD_REC_VOL:
   1004   1.1  augustss 		case ESS_AUXB_REC_VOL:
   1005   1.1  augustss 			v = 0;
   1006   1.1  augustss 			break;
   1007   1.1  augustss 		default:
   1008  1.25  augustss 			v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
   1009   1.1  augustss 			break;
   1010   1.1  augustss 		}
   1011   1.1  augustss 		sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
   1012   1.1  augustss 		ess_set_gain(sc, i, 1);
   1013   1.1  augustss 	}
   1014   1.1  augustss 
   1015   1.4  augustss 	ess_setup(sc);
   1016   1.2  augustss 
   1017   1.1  augustss 	/* Disable the speaker until the device is opened.  */
   1018   1.1  augustss 	ess_speaker_off(sc);
   1019   1.1  augustss 	sc->spkr_state = SPKR_OFF;
   1020   1.1  augustss 
   1021  1.59    itojun 	snprintf(ess_device.name, sizeof(ess_device.name), "ES%s",
   1022  1.59    itojun 	    essmodel[sc->sc_model]);
   1023  1.59    itojun 	snprintf(ess_device.version, sizeof(ess_device.version), "0x%04x",
   1024  1.59    itojun 	    sc->sc_version);
   1025   1.1  augustss 
   1026  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model))
   1027  1.34   mycroft 		audio_attach_mi(&ess_1788_hw_if, sc, &sc->sc_dev);
   1028  1.33   nathanw 	else
   1029  1.34   mycroft 		audio_attach_mi(&ess_1888_hw_if, sc, &sc->sc_dev);
   1030  1.24  augustss 
   1031  1.24  augustss 	arg.type = AUDIODEV_TYPE_OPL;
   1032  1.24  augustss 	arg.hwif = 0;
   1033  1.24  augustss 	arg.hdl = 0;
   1034  1.24  augustss 	(void)config_found(&sc->sc_dev, &arg, audioprint);
   1035   1.2  augustss 
   1036   1.2  augustss #ifdef AUDIO_DEBUG
   1037  1.26  augustss 	if (essdebug > 0)
   1038  1.26  augustss 		ess_printsc(sc);
   1039   1.2  augustss #endif
   1040   1.1  augustss }
   1041   1.1  augustss 
   1042   1.1  augustss /*
   1043   1.1  augustss  * Various routines to interface to higher level audio driver
   1044   1.1  augustss  */
   1045   1.1  augustss 
   1046   1.1  augustss int
   1047   1.1  augustss ess_open(addr, flags)
   1048   1.1  augustss 	void *addr;
   1049   1.1  augustss 	int flags;
   1050   1.1  augustss {
   1051   1.1  augustss 	struct ess_softc *sc = addr;
   1052  1.48  augustss 	int i;
   1053   1.1  augustss 
   1054  1.34   mycroft 	DPRINTF(("ess_open: sc=%p\n", sc));
   1055   1.1  augustss 
   1056   1.1  augustss 	if (sc->sc_open != 0 || ess_reset(sc) != 0)
   1057   1.1  augustss 		return ENXIO;
   1058   1.1  augustss 
   1059   1.6  augustss 	ess_setup(sc);		/* because we did a reset */
   1060   1.1  augustss 
   1061  1.48  augustss 	/* Set all mixer controls again since some change at reset. */
   1062  1.48  augustss 	for (i = 0; i < ESS_MAX_NDEVS; i++)
   1063  1.48  augustss 		ess_set_gain(sc, i, 1);
   1064  1.48  augustss 
   1065   1.1  augustss 	sc->sc_open = 1;
   1066   1.1  augustss 
   1067   1.1  augustss 	DPRINTF(("ess_open: opened\n"));
   1068   1.1  augustss 
   1069   1.1  augustss 	return (0);
   1070   1.1  augustss }
   1071   1.1  augustss 
   1072   1.1  augustss void
   1073  1.33   nathanw ess_1788_close(addr)
   1074   1.1  augustss 	void *addr;
   1075   1.1  augustss {
   1076   1.1  augustss 	struct ess_softc *sc = addr;
   1077   1.1  augustss 
   1078  1.33   nathanw 	DPRINTF(("ess_1788_close: sc=%p\n", sc));
   1079   1.1  augustss 
   1080   1.1  augustss 	ess_speaker_off(sc);
   1081   1.1  augustss 	sc->spkr_state = SPKR_OFF;
   1082  1.34   mycroft 
   1083  1.39   mycroft 	ess_audio1_halt(sc);
   1084  1.34   mycroft 
   1085  1.33   nathanw 	sc->sc_open = 0;
   1086  1.34   mycroft 	DPRINTF(("ess_1788_close: closed\n"));
   1087  1.33   nathanw }
   1088  1.33   nathanw 
   1089  1.33   nathanw void
   1090  1.33   nathanw ess_1888_close(addr)
   1091  1.33   nathanw 	void *addr;
   1092  1.33   nathanw {
   1093  1.33   nathanw 	struct ess_softc *sc = addr;
   1094  1.31   mycroft 
   1095  1.34   mycroft 	DPRINTF(("ess_1888_close: sc=%p\n", sc));
   1096  1.31   mycroft 
   1097  1.33   nathanw 	ess_speaker_off(sc);
   1098  1.33   nathanw 	sc->spkr_state = SPKR_OFF;
   1099  1.34   mycroft 
   1100  1.39   mycroft 	ess_audio1_halt(sc);
   1101  1.39   mycroft 	ess_audio2_halt(sc);
   1102  1.34   mycroft 
   1103  1.31   mycroft 	sc->sc_open = 0;
   1104  1.34   mycroft 	DPRINTF(("ess_1888_close: closed\n"));
   1105   1.1  augustss }
   1106   1.1  augustss 
   1107   1.6  augustss /*
   1108   1.6  augustss  * Wait for FIFO to drain, and analog section to settle.
   1109  1.33   nathanw  * XXX should check FIFO empty bit.
   1110   1.6  augustss  */
   1111   1.6  augustss int
   1112   1.6  augustss ess_drain(addr)
   1113   1.6  augustss 	void *addr;
   1114   1.6  augustss {
   1115   1.9   mycroft 	tsleep(addr, PWAIT | PCATCH, "essdr", hz/20); /* XXX */
   1116   1.6  augustss 	return (0);
   1117   1.6  augustss }
   1118   1.6  augustss 
   1119  1.25  augustss /* XXX should use reference count */
   1120   1.1  augustss int
   1121   1.4  augustss ess_speaker_ctl(addr, newstate)
   1122   1.4  augustss 	void *addr;
   1123   1.4  augustss 	int newstate;
   1124   1.4  augustss {
   1125   1.4  augustss 	struct ess_softc *sc = addr;
   1126   1.4  augustss 
   1127   1.4  augustss 	if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
   1128   1.4  augustss 		ess_speaker_on(sc);
   1129   1.4  augustss 		sc->spkr_state = SPKR_ON;
   1130   1.4  augustss 	}
   1131   1.4  augustss 	if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
   1132   1.4  augustss 		ess_speaker_off(sc);
   1133   1.4  augustss 		sc->spkr_state = SPKR_OFF;
   1134   1.4  augustss 	}
   1135   1.4  augustss 	return (0);
   1136   1.4  augustss }
   1137   1.4  augustss 
   1138   1.4  augustss int
   1139   1.1  augustss ess_getdev(addr, retp)
   1140   1.1  augustss 	void *addr;
   1141   1.1  augustss 	struct audio_device *retp;
   1142   1.1  augustss {
   1143   1.1  augustss 	*retp = ess_device;
   1144   1.1  augustss 	return (0);
   1145   1.1  augustss }
   1146   1.1  augustss 
   1147   1.1  augustss int
   1148   1.1  augustss ess_query_encoding(addr, fp)
   1149   1.1  augustss 	void *addr;
   1150   1.1  augustss 	struct audio_encoding *fp;
   1151   1.1  augustss {
   1152   1.1  augustss 	/*struct ess_softc *sc = addr;*/
   1153   1.1  augustss 
   1154   1.1  augustss 	switch (fp->index) {
   1155   1.1  augustss 	case 0:
   1156   1.1  augustss 		strcpy(fp->name, AudioEulinear);
   1157   1.1  augustss 		fp->encoding = AUDIO_ENCODING_ULINEAR;
   1158   1.1  augustss 		fp->precision = 8;
   1159   1.1  augustss 		fp->flags = 0;
   1160   1.1  augustss 		return (0);
   1161   1.1  augustss 	case 1:
   1162   1.1  augustss 		strcpy(fp->name, AudioEmulaw);
   1163   1.1  augustss 		fp->encoding = AUDIO_ENCODING_ULAW;
   1164   1.1  augustss 		fp->precision = 8;
   1165   1.1  augustss 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   1166   1.1  augustss 		return (0);
   1167   1.1  augustss 	case 2:
   1168   1.1  augustss 		strcpy(fp->name, AudioEalaw);
   1169   1.4  augustss 		fp->encoding = AUDIO_ENCODING_ALAW;
   1170   1.1  augustss 		fp->precision = 8;
   1171   1.1  augustss 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   1172   1.1  augustss 		return (0);
   1173   1.1  augustss 	case 3:
   1174   1.4  augustss 		strcpy(fp->name, AudioEslinear);
   1175   1.4  augustss 		fp->encoding = AUDIO_ENCODING_SLINEAR;
   1176   1.1  augustss 		fp->precision = 8;
   1177   1.1  augustss 		fp->flags = 0;
   1178   1.1  augustss 		return (0);
   1179  1.33   nathanw 	case 4:
   1180   1.1  augustss 		strcpy(fp->name, AudioEslinear_le);
   1181   1.1  augustss 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
   1182   1.1  augustss 		fp->precision = 16;
   1183   1.1  augustss 		fp->flags = 0;
   1184   1.1  augustss 		return (0);
   1185   1.1  augustss 	case 5:
   1186   1.1  augustss 		strcpy(fp->name, AudioEulinear_le);
   1187   1.1  augustss 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
   1188   1.1  augustss 		fp->precision = 16;
   1189   1.1  augustss 		fp->flags = 0;
   1190   1.1  augustss 		return (0);
   1191   1.1  augustss 	case 6:
   1192   1.1  augustss 		strcpy(fp->name, AudioEslinear_be);
   1193   1.1  augustss 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
   1194   1.1  augustss 		fp->precision = 16;
   1195   1.1  augustss 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   1196   1.1  augustss 		return (0);
   1197   1.1  augustss 	case 7:
   1198   1.1  augustss 		strcpy(fp->name, AudioEulinear_be);
   1199   1.1  augustss 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
   1200   1.1  augustss 		fp->precision = 16;
   1201   1.1  augustss 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
   1202   1.1  augustss 		return (0);
   1203   1.1  augustss 	default:
   1204   1.1  augustss 		return EINVAL;
   1205   1.1  augustss 	}
   1206   1.1  augustss 	return (0);
   1207   1.1  augustss }
   1208   1.1  augustss 
   1209   1.1  augustss int
   1210   1.8   mycroft ess_set_params(addr, setmode, usemode, play, rec)
   1211   1.1  augustss 	void *addr;
   1212   1.8   mycroft 	int setmode, usemode;
   1213   1.8   mycroft 	struct audio_params *play, *rec;
   1214   1.1  augustss {
   1215   1.1  augustss 	struct ess_softc *sc = addr;
   1216   1.8   mycroft 	struct audio_params *p;
   1217   1.8   mycroft 	int mode;
   1218  1.19   mycroft 	int rate;
   1219   1.1  augustss 
   1220   1.4  augustss 	DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode));
   1221   1.4  augustss 
   1222  1.15   mycroft 	/*
   1223  1.15   mycroft 	 * The ES1887 manual (page 39, `Full-Duplex DMA Mode') claims that in
   1224  1.15   mycroft 	 * full-duplex operation the sample rates must be the same for both
   1225  1.16   mycroft 	 * channels.  This appears to be false; the only bit in common is the
   1226  1.16   mycroft 	 * clock source selection.  However, we'll be conservative here.
   1227  1.16   mycroft 	 * - mycroft
   1228  1.15   mycroft 	 */
   1229  1.19   mycroft 	if (play->sample_rate != rec->sample_rate &&
   1230  1.19   mycroft 	    usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
   1231  1.19   mycroft 		if (setmode == AUMODE_PLAY) {
   1232  1.13   mycroft 			rec->sample_rate = play->sample_rate;
   1233  1.13   mycroft 			setmode |= AUMODE_RECORD;
   1234  1.19   mycroft 		} else if (setmode == AUMODE_RECORD) {
   1235  1.13   mycroft 			play->sample_rate = rec->sample_rate;
   1236  1.13   mycroft 			setmode |= AUMODE_PLAY;
   1237  1.13   mycroft 		} else
   1238  1.13   mycroft 			return (EINVAL);
   1239  1.13   mycroft 	}
   1240  1.13   mycroft 
   1241  1.17   mycroft 	for (mode = AUMODE_RECORD; mode != -1;
   1242  1.17   mycroft 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
   1243   1.1  augustss 		if ((setmode & mode) == 0)
   1244   1.1  augustss 			continue;
   1245   1.1  augustss 
   1246   1.8   mycroft 		p = mode == AUMODE_PLAY ? play : rec;
   1247   1.1  augustss 
   1248  1.17   mycroft 		if (p->sample_rate < ESS_MINRATE ||
   1249  1.17   mycroft 		    p->sample_rate > ESS_MAXRATE ||
   1250  1.17   mycroft 		    (p->precision != 8 && p->precision != 16) ||
   1251  1.17   mycroft 		    (p->channels != 1 && p->channels != 2))
   1252  1.17   mycroft 			return (EINVAL);
   1253   1.1  augustss 
   1254  1.17   mycroft 		p->factor = 1;
   1255  1.17   mycroft 		p->sw_code = 0;
   1256   1.1  augustss 		switch (p->encoding) {
   1257   1.1  augustss 		case AUDIO_ENCODING_SLINEAR_BE:
   1258  1.17   mycroft 		case AUDIO_ENCODING_ULINEAR_BE:
   1259   1.1  augustss 			if (p->precision == 16)
   1260  1.17   mycroft 				p->sw_code = swap_bytes;
   1261  1.17   mycroft 			break;
   1262   1.1  augustss 		case AUDIO_ENCODING_SLINEAR_LE:
   1263   1.1  augustss 		case AUDIO_ENCODING_ULINEAR_LE:
   1264   1.1  augustss 			break;
   1265   1.1  augustss 		case AUDIO_ENCODING_ULAW:
   1266  1.17   mycroft 			if (mode == AUMODE_PLAY) {
   1267  1.17   mycroft 				p->factor = 2;
   1268  1.47  augustss 				p->sw_code = mulaw_to_ulinear16_le;
   1269  1.17   mycroft 			} else
   1270  1.17   mycroft 				p->sw_code = ulinear8_to_mulaw;
   1271  1.17   mycroft 			break;
   1272   1.1  augustss 		case AUDIO_ENCODING_ALAW:
   1273  1.17   mycroft 			if (mode == AUMODE_PLAY) {
   1274  1.17   mycroft 				p->factor = 2;
   1275  1.47  augustss 				p->sw_code = alaw_to_ulinear16_le;
   1276  1.17   mycroft 			} else
   1277  1.17   mycroft 				p->sw_code = ulinear8_to_alaw;
   1278  1.17   mycroft 			break;
   1279   1.1  augustss 		default:
   1280  1.17   mycroft 			return (EINVAL);
   1281  1.17   mycroft 		}
   1282  1.19   mycroft 	}
   1283  1.17   mycroft 
   1284  1.19   mycroft 	if (usemode == AUMODE_RECORD)
   1285  1.19   mycroft 		rate = rec->sample_rate;
   1286  1.19   mycroft 	else
   1287  1.19   mycroft 		rate = play->sample_rate;
   1288  1.19   mycroft 
   1289  1.34   mycroft 	ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
   1290  1.34   mycroft 	ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
   1291  1.34   mycroft 
   1292  1.46  augustss 	if (!ESS_USE_AUDIO1(sc->sc_model)) {
   1293  1.33   nathanw 		ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
   1294  1.33   nathanw 		ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
   1295  1.33   nathanw 	}
   1296   1.1  augustss 
   1297   1.1  augustss 	return (0);
   1298   1.1  augustss }
   1299   1.1  augustss 
   1300   1.1  augustss int
   1301  1.36   mycroft ess_audio1_trigger_output(addr, start, end, blksize, intr, arg, param)
   1302  1.33   nathanw 	void *addr;
   1303  1.33   nathanw 	void *start, *end;
   1304  1.33   nathanw 	int blksize;
   1305  1.33   nathanw 	void (*intr) __P((void *));
   1306  1.33   nathanw 	void *arg;
   1307  1.33   nathanw 	struct audio_params *param;
   1308  1.33   nathanw {
   1309  1.33   nathanw 	struct ess_softc *sc = addr;
   1310  1.39   mycroft 	u_int8_t reg;
   1311  1.33   nathanw 
   1312  1.36   mycroft 	DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
   1313  1.34   mycroft 	    addr, start, end, blksize, intr, arg));
   1314  1.33   nathanw 
   1315  1.34   mycroft 	if (sc->sc_audio1.active)
   1316  1.36   mycroft 		panic("ess_audio1_trigger_output: already running");
   1317  1.39   mycroft 
   1318  1.34   mycroft 	sc->sc_audio1.active = 1;
   1319  1.34   mycroft 	sc->sc_audio1.intr = intr;
   1320  1.34   mycroft 	sc->sc_audio1.arg = arg;
   1321  1.42   mycroft 	if (sc->sc_audio1.polled) {
   1322  1.43   mycroft 		sc->sc_audio1.dmapos = 0;
   1323  1.43   mycroft 		sc->sc_audio1.buffersize = (char *)end - (char *)start;
   1324  1.42   mycroft 		sc->sc_audio1.dmacount = 0;
   1325  1.42   mycroft 		sc->sc_audio1.blksize = blksize;
   1326  1.51   thorpej 		callout_reset(&sc->sc_poll1_ch, hz / 30,
   1327  1.51   thorpej 		    ess_audio1_poll, sc);
   1328  1.42   mycroft 	}
   1329  1.33   nathanw 
   1330  1.39   mycroft 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
   1331  1.34   mycroft 	if (param->channels == 2) {
   1332  1.39   mycroft 		reg &= ~ESS_AUDIO_CTRL_MONO;
   1333  1.39   mycroft 		reg |= ESS_AUDIO_CTRL_STEREO;
   1334  1.33   nathanw 	} else {
   1335  1.39   mycroft 		reg |= ESS_AUDIO_CTRL_MONO;
   1336  1.39   mycroft 		reg &= ~ESS_AUDIO_CTRL_STEREO;
   1337  1.33   nathanw 	}
   1338  1.39   mycroft 	ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
   1339  1.33   nathanw 
   1340  1.39   mycroft 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
   1341  1.39   mycroft 	if (param->precision * param->factor == 16)
   1342  1.39   mycroft 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
   1343  1.39   mycroft 	else
   1344  1.39   mycroft 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
   1345  1.39   mycroft 	if (param->channels == 2)
   1346  1.39   mycroft 		reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
   1347  1.39   mycroft 	else
   1348  1.39   mycroft 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
   1349  1.34   mycroft 	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
   1350  1.34   mycroft 	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
   1351  1.39   mycroft 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
   1352  1.34   mycroft 	else
   1353  1.39   mycroft 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
   1354  1.39   mycroft 	reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
   1355  1.39   mycroft 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
   1356  1.33   nathanw 
   1357  1.34   mycroft 	isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
   1358  1.34   mycroft 		     (char *)end - (char *)start, NULL,
   1359  1.34   mycroft 	    DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
   1360  1.33   nathanw 
   1361  1.33   nathanw 	/* Program transfer count registers with 2's complement of count. */
   1362  1.33   nathanw 	blksize = -blksize;
   1363  1.33   nathanw 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
   1364  1.33   nathanw 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
   1365  1.33   nathanw 
   1366  1.38   mycroft 	/* Use 4 bytes per output DMA. */
   1367  1.39   mycroft 	ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
   1368  1.33   nathanw 
   1369  1.33   nathanw 	/* Start auto-init DMA */
   1370  1.34   mycroft   	ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
   1371  1.39   mycroft 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
   1372  1.39   mycroft 	reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
   1373  1.39   mycroft 	reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
   1374  1.39   mycroft 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
   1375  1.33   nathanw 
   1376  1.33   nathanw 	return (0);
   1377  1.33   nathanw }
   1378  1.33   nathanw 
   1379  1.33   nathanw int
   1380  1.36   mycroft ess_audio2_trigger_output(addr, start, end, blksize, intr, arg, param)
   1381   1.1  augustss 	void *addr;
   1382  1.19   mycroft 	void *start, *end;
   1383  1.19   mycroft 	int blksize;
   1384  1.19   mycroft 	void (*intr) __P((void *));
   1385  1.19   mycroft 	void *arg;
   1386  1.19   mycroft 	struct audio_params *param;
   1387   1.1  augustss {
   1388   1.1  augustss 	struct ess_softc *sc = addr;
   1389  1.39   mycroft 	u_int8_t reg;
   1390   1.1  augustss 
   1391  1.36   mycroft 	DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
   1392  1.34   mycroft 	    addr, start, end, blksize, intr, arg));
   1393  1.19   mycroft 
   1394  1.34   mycroft 	if (sc->sc_audio2.active)
   1395  1.36   mycroft 		panic("ess_audio2_trigger_output: already running");
   1396  1.39   mycroft 
   1397  1.34   mycroft 	sc->sc_audio2.active = 1;
   1398  1.34   mycroft 	sc->sc_audio2.intr = intr;
   1399  1.34   mycroft 	sc->sc_audio2.arg = arg;
   1400  1.42   mycroft 	if (sc->sc_audio2.polled) {
   1401  1.43   mycroft 		sc->sc_audio2.dmapos = 0;
   1402  1.43   mycroft 		sc->sc_audio2.buffersize = (char *)end - (char *)start;
   1403  1.42   mycroft 		sc->sc_audio2.dmacount = 0;
   1404  1.42   mycroft 		sc->sc_audio2.blksize = blksize;
   1405  1.51   thorpej 		callout_reset(&sc->sc_poll2_ch, hz / 30,
   1406  1.51   thorpej 		    ess_audio2_poll, sc);
   1407  1.42   mycroft 	}
   1408   1.1  augustss 
   1409  1.39   mycroft 	reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
   1410  1.19   mycroft 	if (param->precision * param->factor == 16)
   1411  1.39   mycroft 		reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
   1412  1.17   mycroft 	else
   1413  1.39   mycroft 		reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
   1414  1.19   mycroft 	if (param->channels == 2)
   1415  1.39   mycroft 		reg |= ESS_AUDIO2_CTRL2_CHANNELS;
   1416  1.17   mycroft 	else
   1417  1.39   mycroft 		reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
   1418  1.19   mycroft 	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
   1419  1.34   mycroft 	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
   1420  1.39   mycroft 		reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
   1421  1.17   mycroft 	else
   1422  1.39   mycroft 		reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
   1423  1.39   mycroft 	ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
   1424   1.6  augustss 
   1425  1.34   mycroft 	isa_dmastart(sc->sc_ic, sc->sc_audio2.drq, start,
   1426  1.34   mycroft 		     (char *)end - (char *)start, NULL,
   1427  1.34   mycroft 	    DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
   1428   1.1  augustss 
   1429  1.34   mycroft 	if (IS16BITDRQ(sc->sc_audio2.drq))
   1430  1.19   mycroft 		blksize >>= 1;	/* use word count for 16 bit DMA */
   1431   1.6  augustss 	/* Program transfer count registers with 2's complement of count. */
   1432  1.19   mycroft 	blksize = -blksize;
   1433  1.19   mycroft 	ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
   1434  1.19   mycroft 	ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
   1435   1.1  augustss 
   1436  1.39   mycroft 	reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
   1437  1.34   mycroft 	if (IS16BITDRQ(sc->sc_audio2.drq))
   1438  1.39   mycroft 		reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
   1439  1.18   mycroft 	else
   1440  1.39   mycroft 		reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
   1441  1.39   mycroft 	reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
   1442  1.39   mycroft 	reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
   1443  1.39   mycroft 	       ESS_AUDIO2_CTRL1_AUTO_INIT;
   1444  1.39   mycroft 	ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
   1445  1.34   mycroft 
   1446  1.33   nathanw 	return (0);
   1447  1.33   nathanw }
   1448  1.33   nathanw 
   1449  1.33   nathanw int
   1450  1.36   mycroft ess_audio1_trigger_input(addr, start, end, blksize, intr, arg, param)
   1451  1.33   nathanw 	void *addr;
   1452  1.33   nathanw 	void *start, *end;
   1453  1.33   nathanw 	int blksize;
   1454  1.33   nathanw 	void (*intr) __P((void *));
   1455  1.33   nathanw 	void *arg;
   1456  1.33   nathanw 	struct audio_params *param;
   1457  1.33   nathanw {
   1458  1.33   nathanw 	struct ess_softc *sc = addr;
   1459  1.39   mycroft 	u_int8_t reg;
   1460  1.33   nathanw 
   1461  1.36   mycroft 	DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
   1462  1.34   mycroft 	    addr, start, end, blksize, intr, arg));
   1463  1.33   nathanw 
   1464  1.34   mycroft 	if (sc->sc_audio1.active)
   1465  1.36   mycroft 		panic("ess_audio1_trigger_input: already running");
   1466  1.39   mycroft 
   1467  1.34   mycroft 	sc->sc_audio1.active = 1;
   1468  1.34   mycroft 	sc->sc_audio1.intr = intr;
   1469  1.34   mycroft 	sc->sc_audio1.arg = arg;
   1470  1.42   mycroft 	if (sc->sc_audio1.polled) {
   1471  1.43   mycroft 		sc->sc_audio1.dmapos = 0;
   1472  1.43   mycroft 		sc->sc_audio1.buffersize = (char *)end - (char *)start;
   1473  1.42   mycroft 		sc->sc_audio1.dmacount = 0;
   1474  1.42   mycroft 		sc->sc_audio1.blksize = blksize;
   1475  1.51   thorpej 		callout_reset(&sc->sc_poll1_ch, hz / 30,
   1476  1.51   thorpej 		    ess_audio1_poll, sc);
   1477  1.42   mycroft 	}
   1478  1.19   mycroft 
   1479  1.39   mycroft 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
   1480  1.19   mycroft 	if (param->channels == 2) {
   1481  1.39   mycroft 		reg &= ~ESS_AUDIO_CTRL_MONO;
   1482  1.39   mycroft 		reg |= ESS_AUDIO_CTRL_STEREO;
   1483  1.17   mycroft 	} else {
   1484  1.39   mycroft 		reg |= ESS_AUDIO_CTRL_MONO;
   1485  1.39   mycroft 		reg &= ~ESS_AUDIO_CTRL_STEREO;
   1486  1.17   mycroft 	}
   1487  1.39   mycroft 	ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
   1488  1.17   mycroft 
   1489  1.39   mycroft 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
   1490  1.39   mycroft 	if (param->precision * param->factor == 16)
   1491  1.39   mycroft 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
   1492  1.39   mycroft 	else
   1493  1.39   mycroft 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
   1494  1.39   mycroft 	if (param->channels == 2)
   1495  1.39   mycroft 		reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
   1496  1.39   mycroft 	else
   1497  1.39   mycroft 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
   1498  1.19   mycroft 	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
   1499  1.34   mycroft 	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
   1500  1.39   mycroft 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
   1501  1.17   mycroft 	else
   1502  1.39   mycroft 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
   1503  1.39   mycroft 	reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
   1504  1.39   mycroft 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
   1505  1.17   mycroft 
   1506  1.34   mycroft 	isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
   1507  1.34   mycroft 		     (char *)end - (char *)start, NULL,
   1508  1.34   mycroft 	    DMAMODE_READ | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
   1509  1.11   mycroft 
   1510  1.10   mycroft 	/* Program transfer count registers with 2's complement of count. */
   1511  1.19   mycroft 	blksize = -blksize;
   1512  1.19   mycroft 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
   1513  1.19   mycroft 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
   1514   1.1  augustss 
   1515  1.18   mycroft 	/* Use 4 bytes per input DMA. */
   1516  1.39   mycroft 	ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
   1517  1.18   mycroft 
   1518  1.10   mycroft 	/* Start auto-init DMA */
   1519  1.39   mycroft   	ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
   1520  1.39   mycroft 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
   1521  1.39   mycroft 	reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
   1522  1.39   mycroft 	reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
   1523  1.39   mycroft 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
   1524   1.1  augustss 
   1525   1.1  augustss 	return (0);
   1526   1.1  augustss }
   1527   1.1  augustss 
   1528  1.34   mycroft int
   1529  1.39   mycroft ess_audio1_halt(addr)
   1530  1.33   nathanw 	void *addr;
   1531  1.33   nathanw {
   1532  1.33   nathanw 	struct ess_softc *sc = addr;
   1533  1.33   nathanw 
   1534  1.39   mycroft 	DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
   1535  1.34   mycroft 
   1536  1.34   mycroft 	if (sc->sc_audio1.active) {
   1537  1.34   mycroft 		ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
   1538  1.34   mycroft 		    ESS_AUDIO1_CTRL2_FIFO_ENABLE);
   1539  1.34   mycroft 		isa_dmaabort(sc->sc_ic, sc->sc_audio1.drq);
   1540  1.42   mycroft 		if (sc->sc_audio1.polled)
   1541  1.51   thorpej 			callout_stop(&sc->sc_poll1_ch);
   1542  1.34   mycroft 		sc->sc_audio1.active = 0;
   1543  1.33   nathanw 	}
   1544  1.33   nathanw 
   1545  1.33   nathanw 	return (0);
   1546  1.33   nathanw }
   1547  1.33   nathanw 
   1548   1.1  augustss int
   1549  1.39   mycroft ess_audio2_halt(addr)
   1550   1.1  augustss 	void *addr;
   1551   1.1  augustss {
   1552   1.1  augustss 	struct ess_softc *sc = addr;
   1553   1.1  augustss 
   1554  1.39   mycroft 	DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
   1555  1.34   mycroft 
   1556  1.34   mycroft 	if (sc->sc_audio2.active) {
   1557  1.31   mycroft 		ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
   1558  1.31   mycroft 		    ESS_AUDIO2_CTRL1_DAC_ENABLE |
   1559  1.31   mycroft 		    ESS_AUDIO2_CTRL1_FIFO_ENABLE);
   1560  1.34   mycroft 		isa_dmaabort(sc->sc_ic, sc->sc_audio2.drq);
   1561  1.42   mycroft 		if (sc->sc_audio2.polled)
   1562  1.51   thorpej 			callout_stop(&sc->sc_poll2_ch);
   1563  1.34   mycroft 		sc->sc_audio2.active = 0;
   1564  1.33   nathanw 	}
   1565  1.33   nathanw 
   1566  1.33   nathanw 	return (0);
   1567  1.33   nathanw }
   1568  1.33   nathanw 
   1569  1.33   nathanw int
   1570  1.36   mycroft ess_audio1_intr(arg)
   1571   1.1  augustss 	void *arg;
   1572   1.1  augustss {
   1573   1.1  augustss 	struct ess_softc *sc = arg;
   1574  1.41   mycroft 	u_int8_t reg;
   1575   1.1  augustss 
   1576  1.36   mycroft 	DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
   1577   1.1  augustss 
   1578  1.41   mycroft 	/* Check and clear interrupt on Audio1. */
   1579  1.41   mycroft 	reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
   1580  1.41   mycroft 	if ((reg & ESS_DSP_READ_OFLOW) == 0)
   1581  1.41   mycroft 		return (0);
   1582  1.41   mycroft 	reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
   1583  1.10   mycroft 
   1584  1.36   mycroft 	sc->sc_audio1.nintr++;
   1585   1.1  augustss 
   1586  1.39   mycroft 	if (sc->sc_audio1.active) {
   1587  1.36   mycroft 		(*sc->sc_audio1.intr)(sc->sc_audio1.arg);
   1588  1.39   mycroft 		return (1);
   1589  1.39   mycroft 	} else
   1590  1.34   mycroft 		return (0);
   1591   1.1  augustss }
   1592   1.1  augustss 
   1593   1.1  augustss int
   1594  1.36   mycroft ess_audio2_intr(arg)
   1595   1.1  augustss 	void *arg;
   1596   1.1  augustss {
   1597   1.1  augustss 	struct ess_softc *sc = arg;
   1598  1.41   mycroft 	u_int8_t reg;
   1599  1.34   mycroft 
   1600  1.36   mycroft 	DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
   1601  1.34   mycroft 
   1602  1.41   mycroft 	/* Check and clear interrupt on Audio2. */
   1603  1.41   mycroft 	reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
   1604  1.41   mycroft 	if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0)
   1605  1.41   mycroft 		return (0);
   1606  1.41   mycroft 	reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
   1607  1.41   mycroft 	ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
   1608   1.1  augustss 
   1609  1.36   mycroft 	sc->sc_audio2.nintr++;
   1610   1.1  augustss 
   1611  1.39   mycroft 	if (sc->sc_audio2.active) {
   1612  1.36   mycroft 		(*sc->sc_audio2.intr)(sc->sc_audio2.arg);
   1613  1.39   mycroft 		return (1);
   1614  1.39   mycroft 	} else
   1615  1.33   nathanw 		return (0);
   1616  1.42   mycroft }
   1617  1.42   mycroft 
   1618  1.42   mycroft void
   1619  1.42   mycroft ess_audio1_poll(addr)
   1620  1.42   mycroft 	void *addr;
   1621  1.42   mycroft {
   1622  1.42   mycroft 	struct ess_softc *sc = addr;
   1623  1.42   mycroft 	int dmapos, dmacount;
   1624  1.42   mycroft 
   1625  1.42   mycroft 	if (!sc->sc_audio1.active)
   1626  1.42   mycroft 		return;
   1627  1.42   mycroft 
   1628  1.42   mycroft 	sc->sc_audio1.nintr++;
   1629  1.42   mycroft 
   1630  1.42   mycroft 	dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio1.drq);
   1631  1.43   mycroft 	dmacount = sc->sc_audio1.dmapos - dmapos;
   1632  1.43   mycroft 	if (dmacount < 0)
   1633  1.42   mycroft 		dmacount += sc->sc_audio1.buffersize;
   1634  1.43   mycroft 	sc->sc_audio1.dmapos = dmapos;
   1635  1.43   mycroft #if 1
   1636  1.43   mycroft 	dmacount += sc->sc_audio1.dmacount;
   1637  1.42   mycroft 	while (dmacount > sc->sc_audio1.blksize) {
   1638  1.42   mycroft 		dmacount -= sc->sc_audio1.blksize;
   1639  1.42   mycroft 		(*sc->sc_audio1.intr)(sc->sc_audio1.arg);
   1640  1.42   mycroft 	}
   1641  1.42   mycroft 	sc->sc_audio1.dmacount = dmacount;
   1642  1.43   mycroft #else
   1643  1.43   mycroft 	(*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
   1644  1.43   mycroft #endif
   1645  1.42   mycroft 
   1646  1.51   thorpej 	callout_reset(&sc->sc_poll1_ch, hz / 30, ess_audio1_poll, sc);
   1647  1.42   mycroft }
   1648  1.42   mycroft 
   1649  1.42   mycroft void
   1650  1.42   mycroft ess_audio2_poll(addr)
   1651  1.42   mycroft 	void *addr;
   1652  1.42   mycroft {
   1653  1.42   mycroft 	struct ess_softc *sc = addr;
   1654  1.42   mycroft 	int dmapos, dmacount;
   1655  1.42   mycroft 
   1656  1.42   mycroft 	if (!sc->sc_audio2.active)
   1657  1.42   mycroft 		return;
   1658  1.42   mycroft 
   1659  1.42   mycroft 	sc->sc_audio2.nintr++;
   1660  1.42   mycroft 
   1661  1.42   mycroft 	dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio2.drq);
   1662  1.43   mycroft 	dmacount = sc->sc_audio2.dmapos - dmapos;
   1663  1.43   mycroft 	if (dmacount < 0)
   1664  1.42   mycroft 		dmacount += sc->sc_audio2.buffersize;
   1665  1.43   mycroft 	sc->sc_audio2.dmapos = dmapos;
   1666  1.43   mycroft #if 1
   1667  1.43   mycroft 	dmacount += sc->sc_audio2.dmacount;
   1668  1.42   mycroft 	while (dmacount > sc->sc_audio2.blksize) {
   1669  1.42   mycroft 		dmacount -= sc->sc_audio2.blksize;
   1670  1.42   mycroft 		(*sc->sc_audio2.intr)(sc->sc_audio2.arg);
   1671  1.42   mycroft 	}
   1672  1.42   mycroft 	sc->sc_audio2.dmacount = dmacount;
   1673  1.43   mycroft #else
   1674  1.43   mycroft 	(*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
   1675  1.43   mycroft #endif
   1676  1.42   mycroft 
   1677  1.51   thorpej 	callout_reset(&sc->sc_poll2_ch, hz / 30, ess_audio2_poll, sc);
   1678   1.1  augustss }
   1679   1.1  augustss 
   1680   1.1  augustss int
   1681   1.1  augustss ess_round_blocksize(addr, blk)
   1682   1.1  augustss 	void *addr;
   1683   1.1  augustss 	int blk;
   1684   1.1  augustss {
   1685   1.4  augustss 	return (blk & -8);	/* round for max DMA size */
   1686   1.1  augustss }
   1687   1.1  augustss 
   1688   1.1  augustss int
   1689   1.1  augustss ess_set_port(addr, cp)
   1690   1.1  augustss 	void *addr;
   1691   1.1  augustss 	mixer_ctrl_t *cp;
   1692   1.1  augustss {
   1693   1.1  augustss 	struct ess_softc *sc = addr;
   1694   1.1  augustss 	int lgain, rgain;
   1695   1.1  augustss 
   1696   1.4  augustss 	DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
   1697   1.4  augustss 		    cp->dev, cp->un.value.num_channels));
   1698   1.1  augustss 
   1699   1.1  augustss 	switch (cp->dev) {
   1700   1.1  augustss 	/*
   1701   1.1  augustss 	 * The following mixer ports are all stereo. If we get a
   1702   1.1  augustss 	 * single-channel gain value passed in, then we duplicate it
   1703   1.1  augustss 	 * to both left and right channels.
   1704   1.1  augustss 	 */
   1705   1.1  augustss 	case ESS_MASTER_VOL:
   1706   1.1  augustss 	case ESS_DAC_PLAY_VOL:
   1707   1.1  augustss 	case ESS_MIC_PLAY_VOL:
   1708   1.1  augustss 	case ESS_LINE_PLAY_VOL:
   1709   1.1  augustss 	case ESS_SYNTH_PLAY_VOL:
   1710   1.1  augustss 	case ESS_CD_PLAY_VOL:
   1711   1.1  augustss 	case ESS_AUXB_PLAY_VOL:
   1712   1.1  augustss 	case ESS_RECORD_VOL:
   1713   1.1  augustss 		if (cp->type != AUDIO_MIXER_VALUE)
   1714   1.1  augustss 			return EINVAL;
   1715   1.1  augustss 
   1716   1.1  augustss 		switch (cp->un.value.num_channels) {
   1717   1.1  augustss 		case 1:
   1718   1.1  augustss 			lgain = rgain = ESS_4BIT_GAIN(
   1719   1.1  augustss 			  cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
   1720   1.1  augustss 			break;
   1721   1.1  augustss 		case 2:
   1722   1.1  augustss 			lgain = ESS_4BIT_GAIN(
   1723   1.1  augustss 			  cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
   1724   1.1  augustss 			rgain = ESS_4BIT_GAIN(
   1725   1.1  augustss 			  cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
   1726   1.1  augustss 			break;
   1727   1.1  augustss 		default:
   1728   1.1  augustss 			return EINVAL;
   1729   1.1  augustss 		}
   1730   1.1  augustss 
   1731   1.1  augustss 		sc->gain[cp->dev][ESS_LEFT]  = lgain;
   1732   1.1  augustss 		sc->gain[cp->dev][ESS_RIGHT] = rgain;
   1733   1.1  augustss 		ess_set_gain(sc, cp->dev, 1);
   1734  1.34   mycroft 		return (0);
   1735   1.1  augustss 
   1736   1.1  augustss 	/*
   1737   1.1  augustss 	 * The PC speaker port is mono. If we get a stereo gain value
   1738   1.1  augustss 	 * passed in, then we return EINVAL.
   1739   1.1  augustss 	 */
   1740   1.1  augustss 	case ESS_PCSPEAKER_VOL:
   1741   1.1  augustss 		if (cp->un.value.num_channels != 1)
   1742   1.1  augustss 			return EINVAL;
   1743   1.1  augustss 
   1744  1.34   mycroft 		sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
   1745   1.1  augustss 		  ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
   1746   1.1  augustss 		ess_set_gain(sc, cp->dev, 1);
   1747  1.34   mycroft 		return (0);
   1748   1.1  augustss 
   1749   1.1  augustss 	case ESS_RECORD_SOURCE:
   1750  1.46  augustss 		if (ESS_USE_AUDIO1(sc->sc_model)) {
   1751  1.34   mycroft 			if (cp->type == AUDIO_MIXER_ENUM)
   1752  1.34   mycroft 				return (ess_set_in_port(sc, cp->un.ord));
   1753  1.34   mycroft 			else
   1754  1.34   mycroft 				return (EINVAL);
   1755  1.34   mycroft 		} else {
   1756  1.34   mycroft 			if (cp->type == AUDIO_MIXER_SET)
   1757  1.34   mycroft 				return (ess_set_in_ports(sc, cp->un.mask));
   1758  1.34   mycroft 			else
   1759  1.34   mycroft 				return (EINVAL);
   1760  1.34   mycroft 		}
   1761  1.34   mycroft 		return (0);
   1762   1.1  augustss 
   1763   1.1  augustss 	case ESS_RECORD_MONITOR:
   1764   1.1  augustss 		if (cp->type != AUDIO_MIXER_ENUM)
   1765   1.1  augustss 			return EINVAL;
   1766   1.1  augustss 
   1767   1.1  augustss 		if (cp->un.ord)
   1768   1.1  augustss 			/* Enable monitor */
   1769   1.1  augustss 			ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
   1770   1.1  augustss 					  ESS_AUDIO_CTRL_MONITOR);
   1771   1.1  augustss 		else
   1772   1.1  augustss 			/* Disable monitor */
   1773   1.1  augustss 			ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
   1774   1.1  augustss 					    ESS_AUDIO_CTRL_MONITOR);
   1775  1.34   mycroft 		return (0);
   1776   1.1  augustss 	}
   1777   1.1  augustss 
   1778  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model))
   1779  1.34   mycroft 		return (EINVAL);
   1780   1.1  augustss 
   1781   1.1  augustss 	switch (cp->dev) {
   1782  1.33   nathanw 	case ESS_DAC_REC_VOL:
   1783  1.33   nathanw 	case ESS_MIC_REC_VOL:
   1784  1.33   nathanw 	case ESS_LINE_REC_VOL:
   1785  1.33   nathanw 	case ESS_SYNTH_REC_VOL:
   1786  1.33   nathanw 	case ESS_CD_REC_VOL:
   1787  1.33   nathanw 	case ESS_AUXB_REC_VOL:
   1788  1.34   mycroft 		if (cp->type != AUDIO_MIXER_VALUE)
   1789  1.33   nathanw 			return EINVAL;
   1790  1.34   mycroft 
   1791  1.34   mycroft 		switch (cp->un.value.num_channels) {
   1792  1.34   mycroft 		case 1:
   1793  1.34   mycroft 			lgain = rgain = ESS_4BIT_GAIN(
   1794  1.34   mycroft 			  cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
   1795  1.34   mycroft 			break;
   1796  1.34   mycroft 		case 2:
   1797  1.34   mycroft 			lgain = ESS_4BIT_GAIN(
   1798  1.34   mycroft 			  cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
   1799  1.34   mycroft 			rgain = ESS_4BIT_GAIN(
   1800  1.34   mycroft 			  cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
   1801  1.34   mycroft 			break;
   1802  1.34   mycroft 		default:
   1803  1.34   mycroft 			return EINVAL;
   1804  1.34   mycroft 		}
   1805  1.34   mycroft 
   1806  1.34   mycroft 		sc->gain[cp->dev][ESS_LEFT]  = lgain;
   1807  1.34   mycroft 		sc->gain[cp->dev][ESS_RIGHT] = rgain;
   1808  1.34   mycroft 		ess_set_gain(sc, cp->dev, 1);
   1809  1.34   mycroft 		return (0);
   1810  1.34   mycroft 
   1811  1.34   mycroft 	case ESS_MIC_PREAMP:
   1812  1.34   mycroft 		if (cp->type != AUDIO_MIXER_ENUM)
   1813  1.34   mycroft 			return EINVAL;
   1814  1.34   mycroft 
   1815  1.34   mycroft 		if (cp->un.ord)
   1816  1.34   mycroft 			/* Enable microphone preamp */
   1817  1.34   mycroft 			ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
   1818  1.34   mycroft 					  ESS_PREAMP_CTRL_ENABLE);
   1819  1.34   mycroft 		else
   1820  1.34   mycroft 			/* Disable microphone preamp */
   1821  1.34   mycroft 			ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
   1822  1.34   mycroft 					  ESS_PREAMP_CTRL_ENABLE);
   1823  1.34   mycroft 		return (0);
   1824  1.34   mycroft 	}
   1825  1.34   mycroft 
   1826  1.34   mycroft 	return (EINVAL);
   1827  1.34   mycroft }
   1828  1.34   mycroft 
   1829  1.34   mycroft int
   1830  1.34   mycroft ess_get_port(addr, cp)
   1831  1.34   mycroft 	void *addr;
   1832  1.34   mycroft 	mixer_ctrl_t *cp;
   1833  1.34   mycroft {
   1834  1.34   mycroft 	struct ess_softc *sc = addr;
   1835  1.34   mycroft 
   1836  1.34   mycroft 	DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
   1837  1.34   mycroft 
   1838  1.34   mycroft 	switch (cp->dev) {
   1839  1.34   mycroft 	case ESS_MASTER_VOL:
   1840   1.1  augustss 	case ESS_DAC_PLAY_VOL:
   1841   1.1  augustss 	case ESS_MIC_PLAY_VOL:
   1842   1.1  augustss 	case ESS_LINE_PLAY_VOL:
   1843   1.1  augustss 	case ESS_SYNTH_PLAY_VOL:
   1844   1.1  augustss 	case ESS_CD_PLAY_VOL:
   1845   1.1  augustss 	case ESS_AUXB_PLAY_VOL:
   1846   1.1  augustss 	case ESS_RECORD_VOL:
   1847   1.1  augustss 		switch (cp->un.value.num_channels) {
   1848   1.1  augustss 		case 1:
   1849   1.1  augustss 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
   1850   1.1  augustss 				sc->gain[cp->dev][ESS_LEFT];
   1851   1.1  augustss 			break;
   1852   1.1  augustss 		case 2:
   1853   1.1  augustss 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
   1854   1.1  augustss 				sc->gain[cp->dev][ESS_LEFT];
   1855   1.1  augustss 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
   1856   1.1  augustss 				sc->gain[cp->dev][ESS_RIGHT];
   1857   1.1  augustss 			break;
   1858   1.1  augustss 		default:
   1859   1.1  augustss 			return EINVAL;
   1860   1.1  augustss 		}
   1861  1.34   mycroft 		return (0);
   1862   1.1  augustss 
   1863  1.34   mycroft 	case ESS_PCSPEAKER_VOL:
   1864  1.34   mycroft 		if (cp->un.value.num_channels != 1)
   1865  1.33   nathanw 			return EINVAL;
   1866  1.34   mycroft 
   1867  1.34   mycroft 		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
   1868  1.34   mycroft 			sc->gain[cp->dev][ESS_LEFT];
   1869  1.34   mycroft 		return (0);
   1870   1.1  augustss 
   1871   1.1  augustss 	case ESS_RECORD_SOURCE:
   1872  1.46  augustss 		if (ESS_USE_AUDIO1(sc->sc_model))
   1873  1.33   nathanw 			cp->un.ord = sc->in_port;
   1874  1.33   nathanw 		else
   1875  1.33   nathanw 			cp->un.mask = sc->in_mask;
   1876  1.34   mycroft 		return (0);
   1877   1.1  augustss 
   1878   1.1  augustss 	case ESS_RECORD_MONITOR:
   1879   1.1  augustss 		cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
   1880   1.1  augustss 			      ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
   1881  1.34   mycroft 		return (0);
   1882  1.34   mycroft 	}
   1883  1.34   mycroft 
   1884  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model))
   1885  1.34   mycroft 		return (EINVAL);
   1886  1.34   mycroft 
   1887  1.34   mycroft 	switch (cp->dev) {
   1888  1.34   mycroft 	case ESS_DAC_REC_VOL:
   1889  1.34   mycroft 	case ESS_MIC_REC_VOL:
   1890  1.34   mycroft 	case ESS_LINE_REC_VOL:
   1891  1.34   mycroft 	case ESS_SYNTH_REC_VOL:
   1892  1.34   mycroft 	case ESS_CD_REC_VOL:
   1893  1.34   mycroft 	case ESS_AUXB_REC_VOL:
   1894  1.34   mycroft 		switch (cp->un.value.num_channels) {
   1895  1.34   mycroft 		case 1:
   1896  1.34   mycroft 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
   1897  1.34   mycroft 				sc->gain[cp->dev][ESS_LEFT];
   1898  1.34   mycroft 			break;
   1899  1.34   mycroft 		case 2:
   1900  1.34   mycroft 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
   1901  1.34   mycroft 				sc->gain[cp->dev][ESS_LEFT];
   1902  1.34   mycroft 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
   1903  1.34   mycroft 				sc->gain[cp->dev][ESS_RIGHT];
   1904  1.34   mycroft 			break;
   1905  1.34   mycroft 		default:
   1906  1.34   mycroft 			return EINVAL;
   1907  1.34   mycroft 		}
   1908  1.34   mycroft 		return (0);
   1909   1.1  augustss 
   1910  1.34   mycroft 	case ESS_MIC_PREAMP:
   1911  1.34   mycroft 		cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
   1912  1.34   mycroft 			      ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
   1913  1.34   mycroft 		return (0);
   1914   1.1  augustss 	}
   1915   1.1  augustss 
   1916  1.34   mycroft 	return (EINVAL);
   1917   1.1  augustss }
   1918   1.1  augustss 
   1919   1.1  augustss int
   1920   1.1  augustss ess_query_devinfo(addr, dip)
   1921   1.1  augustss 	void *addr;
   1922   1.1  augustss 	mixer_devinfo_t *dip;
   1923   1.1  augustss {
   1924   1.1  augustss 	struct ess_softc *sc = addr;
   1925   1.1  augustss 
   1926   1.4  augustss 	DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
   1927   1.4  augustss 		    sc->sc_model, dip->index));
   1928   1.1  augustss 
   1929   1.1  augustss 	/*
   1930   1.1  augustss 	 * REVISIT: There are some slight differences between the
   1931   1.1  augustss 	 *          mixers on the different ESS chips, which can
   1932   1.1  augustss 	 *          be sorted out using the chip model rather than a
   1933   1.1  augustss 	 *          separate mixer model.
   1934   1.1  augustss 	 *          This is currently coded assuming an ES1887; we
   1935   1.1  augustss 	 *          need to work out which bits are not applicable to
   1936   1.1  augustss 	 *          the other models (1888 and 888).
   1937   1.1  augustss 	 */
   1938   1.1  augustss 	switch (dip->index) {
   1939   1.1  augustss 	case ESS_DAC_PLAY_VOL:
   1940   1.1  augustss 		dip->mixer_class = ESS_INPUT_CLASS;
   1941  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   1942   1.1  augustss 		strcpy(dip->label.name, AudioNdac);
   1943  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   1944   1.1  augustss 		dip->un.v.num_channels = 2;
   1945   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   1946   1.1  augustss 		return (0);
   1947   1.1  augustss 
   1948   1.1  augustss 	case ESS_MIC_PLAY_VOL:
   1949   1.1  augustss 		dip->mixer_class = ESS_INPUT_CLASS;
   1950   1.1  augustss 		dip->prev = AUDIO_MIXER_LAST;
   1951  1.46  augustss 		if (ESS_USE_AUDIO1(sc->sc_model))
   1952  1.33   nathanw 			dip->next = AUDIO_MIXER_LAST;
   1953  1.33   nathanw 		else
   1954  1.33   nathanw 			dip->next = ESS_MIC_PREAMP;
   1955   1.1  augustss 		strcpy(dip->label.name, AudioNmicrophone);
   1956  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   1957   1.1  augustss 		dip->un.v.num_channels = 2;
   1958   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   1959   1.1  augustss 		return (0);
   1960   1.1  augustss 
   1961   1.1  augustss 	case ESS_LINE_PLAY_VOL:
   1962   1.1  augustss 		dip->mixer_class = ESS_INPUT_CLASS;
   1963  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   1964   1.1  augustss 		strcpy(dip->label.name, AudioNline);
   1965  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   1966   1.1  augustss 		dip->un.v.num_channels = 2;
   1967   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   1968   1.1  augustss 		return (0);
   1969   1.1  augustss 
   1970   1.1  augustss 	case ESS_SYNTH_PLAY_VOL:
   1971   1.1  augustss 		dip->mixer_class = ESS_INPUT_CLASS;
   1972  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   1973   1.1  augustss 		strcpy(dip->label.name, AudioNfmsynth);
   1974  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   1975   1.1  augustss 		dip->un.v.num_channels = 2;
   1976   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   1977   1.1  augustss 		return (0);
   1978   1.1  augustss 
   1979   1.1  augustss 	case ESS_CD_PLAY_VOL:
   1980   1.1  augustss 		dip->mixer_class = ESS_INPUT_CLASS;
   1981  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   1982   1.1  augustss 		strcpy(dip->label.name, AudioNcd);
   1983  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   1984   1.1  augustss 		dip->un.v.num_channels = 2;
   1985   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   1986   1.1  augustss 		return (0);
   1987   1.1  augustss 
   1988   1.1  augustss 	case ESS_AUXB_PLAY_VOL:
   1989   1.1  augustss 		dip->mixer_class = ESS_INPUT_CLASS;
   1990  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   1991   1.1  augustss 		strcpy(dip->label.name, "auxb");
   1992  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   1993   1.1  augustss 		dip->un.v.num_channels = 2;
   1994   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   1995   1.1  augustss 		return (0);
   1996   1.1  augustss 
   1997   1.1  augustss 	case ESS_INPUT_CLASS:
   1998   1.1  augustss 		dip->mixer_class = ESS_INPUT_CLASS;
   1999   1.1  augustss 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2000   1.1  augustss 		strcpy(dip->label.name, AudioCinputs);
   2001  1.27   mycroft 		dip->type = AUDIO_MIXER_CLASS;
   2002   1.1  augustss 		return (0);
   2003   1.1  augustss 
   2004   1.1  augustss 	case ESS_MASTER_VOL:
   2005   1.1  augustss 		dip->mixer_class = ESS_OUTPUT_CLASS;
   2006  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2007   1.1  augustss 		strcpy(dip->label.name, AudioNmaster);
   2008  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2009   1.1  augustss 		dip->un.v.num_channels = 2;
   2010   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   2011   1.1  augustss 		return (0);
   2012   1.1  augustss 
   2013   1.1  augustss 	case ESS_PCSPEAKER_VOL:
   2014   1.1  augustss 		dip->mixer_class = ESS_OUTPUT_CLASS;
   2015  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2016   1.1  augustss 		strcpy(dip->label.name, "pc_speaker");
   2017  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2018   1.1  augustss 		dip->un.v.num_channels = 1;
   2019   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   2020   1.1  augustss 		return (0);
   2021   1.1  augustss 
   2022   1.1  augustss 	case ESS_OUTPUT_CLASS:
   2023   1.1  augustss 		dip->mixer_class = ESS_OUTPUT_CLASS;
   2024   1.1  augustss 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2025   1.1  augustss 		strcpy(dip->label.name, AudioCoutputs);
   2026  1.27   mycroft 		dip->type = AUDIO_MIXER_CLASS;
   2027   1.1  augustss 		return (0);
   2028   1.1  augustss 
   2029   1.1  augustss 	case ESS_RECORD_VOL:
   2030   1.1  augustss 		dip->mixer_class = ESS_RECORD_CLASS;
   2031  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2032   1.1  augustss 		strcpy(dip->label.name, AudioNrecord);
   2033  1.27   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2034   1.1  augustss 		dip->un.v.num_channels = 2;
   2035   1.1  augustss 		strcpy(dip->un.v.units.name, AudioNvolume);
   2036   1.1  augustss 		return (0);
   2037   1.1  augustss 
   2038   1.1  augustss 	case ESS_RECORD_SOURCE:
   2039  1.34   mycroft 		dip->mixer_class = ESS_RECORD_CLASS;
   2040  1.27   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2041   1.1  augustss 		strcpy(dip->label.name, AudioNsource);
   2042  1.46  augustss 		if (ESS_USE_AUDIO1(sc->sc_model)) {
   2043  1.34   mycroft 			/*
   2044  1.34   mycroft 			 * The 1788 doesn't use the input mixer control that
   2045  1.34   mycroft 			 * the 1888 uses, because it's a pain when you only
   2046  1.34   mycroft 			 * have one mixer.
   2047  1.34   mycroft 			 * Perhaps it could be emulated by keeping both sets of
   2048  1.34   mycroft 			 * gain values, and doing a `context switch' of the
   2049  1.34   mycroft 			 * mixer registers when shifting from playing to
   2050  1.34   mycroft 			 * recording.
   2051  1.33   nathanw 			 */
   2052  1.33   nathanw 			dip->type = AUDIO_MIXER_ENUM;
   2053  1.33   nathanw 			dip->un.e.num_mem = 4;
   2054  1.33   nathanw 			strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
   2055  1.33   nathanw 			dip->un.e.member[0].ord = ESS_SOURCE_MIC;
   2056  1.33   nathanw 			strcpy(dip->un.e.member[1].label.name, AudioNline);
   2057  1.33   nathanw 			dip->un.e.member[1].ord = ESS_SOURCE_LINE;
   2058  1.33   nathanw 			strcpy(dip->un.e.member[2].label.name, AudioNcd);
   2059  1.33   nathanw 			dip->un.e.member[2].ord = ESS_SOURCE_CD;
   2060  1.33   nathanw 			strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
   2061  1.33   nathanw 			dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
   2062  1.33   nathanw 		} else {
   2063  1.33   nathanw 			dip->type = AUDIO_MIXER_SET;
   2064  1.33   nathanw 			dip->un.s.num_mem = 6;
   2065  1.33   nathanw 			strcpy(dip->un.s.member[0].label.name, AudioNdac);
   2066  1.33   nathanw 			dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
   2067  1.33   nathanw 			strcpy(dip->un.s.member[1].label.name, AudioNmicrophone);
   2068  1.33   nathanw 			dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
   2069  1.33   nathanw 			strcpy(dip->un.s.member[2].label.name, AudioNline);
   2070  1.33   nathanw 			dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
   2071  1.33   nathanw 			strcpy(dip->un.s.member[3].label.name, AudioNfmsynth);
   2072  1.33   nathanw 			dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
   2073  1.33   nathanw 			strcpy(dip->un.s.member[4].label.name, AudioNcd);
   2074  1.33   nathanw 			dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
   2075  1.33   nathanw 			strcpy(dip->un.s.member[5].label.name, "auxb");
   2076  1.33   nathanw 			dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
   2077  1.33   nathanw 		}
   2078   1.1  augustss 		return (0);
   2079   1.1  augustss 
   2080   1.1  augustss 	case ESS_RECORD_CLASS:
   2081   1.1  augustss 		dip->mixer_class = ESS_RECORD_CLASS;
   2082   1.1  augustss 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2083   1.1  augustss 		strcpy(dip->label.name, AudioCrecord);
   2084  1.27   mycroft 		dip->type = AUDIO_MIXER_CLASS;
   2085   1.1  augustss 		return (0);
   2086   1.1  augustss 
   2087   1.1  augustss 	case ESS_RECORD_MONITOR:
   2088   1.1  augustss 		dip->prev = dip->next = AUDIO_MIXER_LAST;
   2089  1.45   nathanw 		strcpy(dip->label.name, AudioNmute);
   2090   1.1  augustss 		dip->type = AUDIO_MIXER_ENUM;
   2091  1.27   mycroft 		dip->mixer_class = ESS_MONITOR_CLASS;
   2092   1.1  augustss 		dip->un.e.num_mem = 2;
   2093   1.1  augustss 		strcpy(dip->un.e.member[0].label.name, AudioNoff);
   2094   1.1  augustss 		dip->un.e.member[0].ord = 0;
   2095   1.1  augustss 		strcpy(dip->un.e.member[1].label.name, AudioNon);
   2096   1.1  augustss 		dip->un.e.member[1].ord = 1;
   2097   1.1  augustss 		return (0);
   2098   1.1  augustss 
   2099   1.1  augustss 	case ESS_MONITOR_CLASS:
   2100   1.1  augustss 		dip->mixer_class = ESS_MONITOR_CLASS;
   2101   1.1  augustss 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2102   1.1  augustss 		strcpy(dip->label.name, AudioCmonitor);
   2103  1.27   mycroft 		dip->type = AUDIO_MIXER_CLASS;
   2104   1.1  augustss 		return (0);
   2105   1.1  augustss 	}
   2106   1.1  augustss 
   2107  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model))
   2108  1.34   mycroft 		return (ENXIO);
   2109  1.34   mycroft 
   2110  1.34   mycroft 	switch (dip->index) {
   2111  1.34   mycroft 	case ESS_DAC_REC_VOL:
   2112  1.34   mycroft 		dip->mixer_class = ESS_RECORD_CLASS;
   2113  1.34   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2114  1.34   mycroft 		strcpy(dip->label.name, AudioNdac);
   2115  1.34   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2116  1.34   mycroft 		dip->un.v.num_channels = 2;
   2117  1.34   mycroft 		strcpy(dip->un.v.units.name, AudioNvolume);
   2118  1.34   mycroft 		return (0);
   2119  1.34   mycroft 
   2120  1.34   mycroft 	case ESS_MIC_REC_VOL:
   2121  1.34   mycroft 		dip->mixer_class = ESS_RECORD_CLASS;
   2122  1.34   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2123  1.34   mycroft 		strcpy(dip->label.name, AudioNmicrophone);
   2124  1.34   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2125  1.34   mycroft 		dip->un.v.num_channels = 2;
   2126  1.34   mycroft 		strcpy(dip->un.v.units.name, AudioNvolume);
   2127  1.34   mycroft 		return (0);
   2128  1.34   mycroft 
   2129  1.34   mycroft 	case ESS_LINE_REC_VOL:
   2130  1.34   mycroft 		dip->mixer_class = ESS_RECORD_CLASS;
   2131  1.34   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2132  1.34   mycroft 		strcpy(dip->label.name, AudioNline);
   2133  1.34   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2134  1.34   mycroft 		dip->un.v.num_channels = 2;
   2135  1.34   mycroft 		strcpy(dip->un.v.units.name, AudioNvolume);
   2136  1.34   mycroft 		return (0);
   2137  1.34   mycroft 
   2138  1.34   mycroft 	case ESS_SYNTH_REC_VOL:
   2139  1.34   mycroft 		dip->mixer_class = ESS_RECORD_CLASS;
   2140  1.34   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2141  1.34   mycroft 		strcpy(dip->label.name, AudioNfmsynth);
   2142  1.34   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2143  1.34   mycroft 		dip->un.v.num_channels = 2;
   2144  1.34   mycroft 		strcpy(dip->un.v.units.name, AudioNvolume);
   2145  1.34   mycroft 		return (0);
   2146  1.34   mycroft 
   2147  1.34   mycroft 	case ESS_CD_REC_VOL:
   2148  1.34   mycroft 		dip->mixer_class = ESS_RECORD_CLASS;
   2149  1.34   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2150  1.34   mycroft 		strcpy(dip->label.name, AudioNcd);
   2151  1.34   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2152  1.34   mycroft 		dip->un.v.num_channels = 2;
   2153  1.34   mycroft 		strcpy(dip->un.v.units.name, AudioNvolume);
   2154  1.34   mycroft 		return (0);
   2155  1.34   mycroft 
   2156  1.34   mycroft 	case ESS_AUXB_REC_VOL:
   2157  1.34   mycroft 		dip->mixer_class = ESS_RECORD_CLASS;
   2158  1.34   mycroft 		dip->next = dip->prev = AUDIO_MIXER_LAST;
   2159  1.34   mycroft 		strcpy(dip->label.name, "auxb");
   2160  1.34   mycroft 		dip->type = AUDIO_MIXER_VALUE;
   2161  1.34   mycroft 		dip->un.v.num_channels = 2;
   2162  1.34   mycroft 		strcpy(dip->un.v.units.name, AudioNvolume);
   2163  1.34   mycroft 		return (0);
   2164  1.34   mycroft 
   2165  1.34   mycroft 	case ESS_MIC_PREAMP:
   2166  1.34   mycroft 		dip->mixer_class = ESS_INPUT_CLASS;
   2167  1.34   mycroft 		dip->prev = ESS_MIC_PLAY_VOL;
   2168  1.34   mycroft 		dip->next = AUDIO_MIXER_LAST;
   2169  1.34   mycroft 		strcpy(dip->label.name, AudioNpreamp);
   2170  1.34   mycroft 		dip->type = AUDIO_MIXER_ENUM;
   2171  1.34   mycroft 		dip->un.e.num_mem = 2;
   2172  1.34   mycroft 		strcpy(dip->un.e.member[0].label.name, AudioNoff);
   2173  1.34   mycroft 		dip->un.e.member[0].ord = 0;
   2174  1.34   mycroft 		strcpy(dip->un.e.member[1].label.name, AudioNon);
   2175  1.34   mycroft 		dip->un.e.member[1].ord = 1;
   2176  1.34   mycroft 		return (0);
   2177  1.34   mycroft 	}
   2178  1.34   mycroft 
   2179   1.4  augustss 	return (ENXIO);
   2180   1.4  augustss }
   2181   1.4  augustss 
   2182   1.4  augustss void *
   2183  1.30   mycroft ess_malloc(addr, direction, size, pool, flags)
   2184   1.4  augustss 	void *addr;
   2185  1.30   mycroft 	int direction;
   2186  1.30   mycroft 	size_t size;
   2187  1.56   thorpej 	struct malloc_type *pool;
   2188  1.56   thorpej 	int flags;
   2189   1.4  augustss {
   2190   1.4  augustss 	struct ess_softc *sc = addr;
   2191  1.30   mycroft 	int drq;
   2192   1.4  augustss 
   2193  1.46  augustss 	if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
   2194  1.34   mycroft 		drq = sc->sc_audio2.drq;
   2195  1.30   mycroft 	else
   2196  1.34   mycroft 		drq = sc->sc_audio1.drq;
   2197  1.30   mycroft 	return (isa_malloc(sc->sc_ic, drq, size, pool, flags));
   2198   1.4  augustss }
   2199   1.4  augustss 
   2200   1.4  augustss void
   2201   1.4  augustss ess_free(addr, ptr, pool)
   2202   1.4  augustss 	void *addr;
   2203   1.4  augustss 	void *ptr;
   2204  1.56   thorpej 	struct malloc_type *pool;
   2205   1.4  augustss {
   2206   1.4  augustss 	isa_free(ptr, pool);
   2207   1.4  augustss }
   2208   1.4  augustss 
   2209  1.30   mycroft size_t
   2210  1.30   mycroft ess_round_buffersize(addr, direction, size)
   2211   1.4  augustss 	void *addr;
   2212  1.30   mycroft 	int direction;
   2213  1.30   mycroft 	size_t size;
   2214   1.4  augustss {
   2215  1.50   thorpej 	struct ess_softc *sc = addr;
   2216  1.50   thorpej 	bus_size_t maxsize;
   2217  1.50   thorpej 
   2218  1.50   thorpej 	if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
   2219  1.50   thorpej 		maxsize = sc->sc_audio2.maxsize;
   2220  1.50   thorpej 	else
   2221  1.50   thorpej 		maxsize = sc->sc_audio1.maxsize;
   2222  1.50   thorpej 
   2223  1.50   thorpej 	if (size > maxsize)
   2224  1.50   thorpej 		size = maxsize;
   2225  1.30   mycroft 	return (size);
   2226   1.4  augustss }
   2227   1.4  augustss 
   2228  1.52    simonb paddr_t
   2229   1.4  augustss ess_mappage(addr, mem, off, prot)
   2230   1.4  augustss 	void *addr;
   2231  1.34   mycroft 	void *mem;
   2232  1.52    simonb 	off_t off;
   2233   1.4  augustss 	int prot;
   2234   1.4  augustss {
   2235   1.4  augustss 	return (isa_mappage(mem, off, prot));
   2236   1.1  augustss }
   2237   1.1  augustss 
   2238   1.1  augustss int
   2239  1.36   mycroft ess_1788_get_props(addr)
   2240  1.36   mycroft 	void *addr;
   2241  1.36   mycroft {
   2242  1.36   mycroft 
   2243  1.36   mycroft 	return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT);
   2244  1.36   mycroft }
   2245  1.36   mycroft 
   2246  1.36   mycroft int
   2247  1.36   mycroft ess_1888_get_props(addr)
   2248   1.1  augustss 	void *addr;
   2249   1.1  augustss {
   2250  1.14   mycroft 
   2251  1.36   mycroft 	return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
   2252   1.1  augustss }
   2253   1.1  augustss 
   2254   1.1  augustss /* ============================================
   2255   1.1  augustss  * Generic functions for ess, not used by audio h/w i/f
   2256   1.1  augustss  * =============================================
   2257   1.1  augustss  */
   2258   1.1  augustss 
   2259   1.1  augustss /*
   2260   1.1  augustss  * Reset the chip.
   2261   1.1  augustss  * Return non-zero if the chip isn't detected.
   2262   1.1  augustss  */
   2263   1.1  augustss int
   2264   1.1  augustss ess_reset(sc)
   2265   1.1  augustss 	struct ess_softc *sc;
   2266   1.1  augustss {
   2267   1.1  augustss 	bus_space_tag_t iot = sc->sc_iot;
   2268   1.1  augustss 	bus_space_handle_t ioh = sc->sc_ioh;
   2269   1.1  augustss 
   2270  1.40   mycroft 	sc->sc_audio1.active = 0;
   2271  1.40   mycroft 	sc->sc_audio2.active = 0;
   2272   1.1  augustss 
   2273   1.4  augustss 	EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
   2274  1.48  augustss 	delay(10000);		/* XXX shouldn't delay so long */
   2275   1.2  augustss 	EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
   2276   1.1  augustss 	if (ess_rdsp(sc) != ESS_MAGIC)
   2277   1.4  augustss 		return (1);
   2278   1.1  augustss 
   2279   1.4  augustss 	/* Enable access to the ESS extension commands. */
   2280   1.1  augustss 	ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
   2281   1.1  augustss 
   2282   1.1  augustss 	return (0);
   2283   1.1  augustss }
   2284   1.1  augustss 
   2285   1.1  augustss void
   2286   1.1  augustss ess_set_gain(sc, port, on)
   2287   1.1  augustss 	struct ess_softc *sc;
   2288   1.1  augustss 	int port;
   2289   1.1  augustss 	int on;
   2290   1.1  augustss {
   2291   1.1  augustss 	int gain, left, right;
   2292   1.1  augustss 	int mix;
   2293   1.1  augustss 	int src;
   2294   1.1  augustss 	int stereo;
   2295   1.1  augustss 
   2296   1.1  augustss 	/*
   2297   1.1  augustss 	 * Most gain controls are found in the mixer registers and
   2298   1.1  augustss 	 * are stereo. Any that are not, must set mix and stereo as
   2299   1.1  augustss 	 * required.
   2300   1.1  augustss 	 */
   2301   1.1  augustss 	mix = 1;
   2302   1.1  augustss 	stereo = 1;
   2303   1.1  augustss 
   2304   1.1  augustss 	switch (port) {
   2305   1.1  augustss 	case ESS_MASTER_VOL:
   2306  1.33   nathanw 		src = ESS_MREG_VOLUME_MASTER;
   2307   1.1  augustss 		break;
   2308   1.1  augustss 	case ESS_DAC_PLAY_VOL:
   2309  1.46  augustss 		if (ESS_USE_AUDIO1(sc->sc_model))
   2310  1.33   nathanw 			src = ESS_MREG_VOLUME_VOICE;
   2311  1.33   nathanw 		else
   2312  1.33   nathanw 			src = 0x7C;
   2313   1.1  augustss 		break;
   2314   1.1  augustss 	case ESS_MIC_PLAY_VOL:
   2315  1.33   nathanw 		src = ESS_MREG_VOLUME_MIC;
   2316   1.1  augustss 		break;
   2317   1.1  augustss 	case ESS_LINE_PLAY_VOL:
   2318  1.33   nathanw 		src = ESS_MREG_VOLUME_LINE;
   2319   1.1  augustss 		break;
   2320   1.1  augustss 	case ESS_SYNTH_PLAY_VOL:
   2321  1.33   nathanw 		src = ESS_MREG_VOLUME_SYNTH;
   2322   1.1  augustss 		break;
   2323   1.1  augustss 	case ESS_CD_PLAY_VOL:
   2324  1.33   nathanw 		src = ESS_MREG_VOLUME_CD;
   2325   1.1  augustss 		break;
   2326   1.1  augustss 	case ESS_AUXB_PLAY_VOL:
   2327  1.33   nathanw 		src = ESS_MREG_VOLUME_AUXB;
   2328   1.1  augustss 		break;
   2329   1.1  augustss 	case ESS_PCSPEAKER_VOL:
   2330  1.33   nathanw 		src = ESS_MREG_VOLUME_PCSPKR;
   2331   1.1  augustss 		stereo = 0;
   2332   1.1  augustss 		break;
   2333   1.1  augustss 	case ESS_DAC_REC_VOL:
   2334   1.1  augustss 		src = 0x69;
   2335   1.1  augustss 		break;
   2336   1.1  augustss 	case ESS_MIC_REC_VOL:
   2337   1.1  augustss 		src = 0x68;
   2338   1.1  augustss 		break;
   2339   1.1  augustss 	case ESS_LINE_REC_VOL:
   2340   1.1  augustss 		src = 0x6E;
   2341   1.1  augustss 		break;
   2342   1.1  augustss 	case ESS_SYNTH_REC_VOL:
   2343   1.1  augustss 		src = 0x6B;
   2344   1.1  augustss 		break;
   2345   1.1  augustss 	case ESS_CD_REC_VOL:
   2346   1.1  augustss 		src = 0x6A;
   2347   1.1  augustss 		break;
   2348   1.1  augustss 	case ESS_AUXB_REC_VOL:
   2349   1.1  augustss 		src = 0x6C;
   2350   1.1  augustss 		break;
   2351   1.1  augustss 	case ESS_RECORD_VOL:
   2352  1.33   nathanw 		src = ESS_XCMD_VOLIN_CTRL;
   2353   1.1  augustss 		mix = 0;
   2354   1.1  augustss 		break;
   2355   1.1  augustss 	default:
   2356   1.1  augustss 		return;
   2357   1.1  augustss 	}
   2358   1.1  augustss 
   2359  1.33   nathanw 	/* 1788 doesn't have a separate recording mixer */
   2360  1.46  augustss 	if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
   2361  1.34   mycroft 		return;
   2362  1.33   nathanw 
   2363   1.1  augustss 	if (on) {
   2364   1.1  augustss 		left = sc->gain[port][ESS_LEFT];
   2365   1.1  augustss 		right = sc->gain[port][ESS_RIGHT];
   2366   1.1  augustss 	} else {
   2367   1.1  augustss 		left = right = 0;
   2368   1.1  augustss 	}
   2369   1.1  augustss 
   2370   1.1  augustss 	if (stereo)
   2371   1.1  augustss 		gain = ESS_STEREO_GAIN(left, right);
   2372   1.1  augustss 	else
   2373   1.1  augustss 		gain = ESS_MONO_GAIN(left);
   2374   1.1  augustss 
   2375   1.1  augustss 	if (mix)
   2376   1.1  augustss 		ess_write_mix_reg(sc, src, gain);
   2377   1.1  augustss 	else
   2378   1.1  augustss 		ess_write_x_reg(sc, src, gain);
   2379   1.1  augustss }
   2380   1.1  augustss 
   2381  1.33   nathanw /* Set the input device on devices without an input mixer. */
   2382  1.33   nathanw int
   2383  1.33   nathanw ess_set_in_port(sc, ord)
   2384  1.33   nathanw 	struct ess_softc *sc;
   2385  1.33   nathanw 	int ord;
   2386  1.33   nathanw {
   2387  1.33   nathanw 	mixer_devinfo_t di;
   2388  1.34   mycroft 	int i;
   2389  1.33   nathanw 
   2390  1.33   nathanw 	DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
   2391  1.33   nathanw 
   2392  1.33   nathanw 	/*
   2393  1.33   nathanw 	 * Get the device info for the record source control,
   2394  1.33   nathanw 	 * including the list of available sources.
   2395  1.33   nathanw 	 */
   2396  1.33   nathanw 	di.index = ESS_RECORD_SOURCE;
   2397  1.33   nathanw 	if (ess_query_devinfo(sc, &di))
   2398  1.33   nathanw 		return EINVAL;
   2399  1.33   nathanw 
   2400  1.34   mycroft 	/* See if the given ord value was anywhere in the list. */
   2401  1.33   nathanw 	for (i = 0; i < di.un.e.num_mem; i++) {
   2402  1.34   mycroft 		if (ord == di.un.e.member[i].ord)
   2403  1.33   nathanw 			break;
   2404  1.33   nathanw 	}
   2405  1.34   mycroft 	if (i == di.un.e.num_mem)
   2406  1.34   mycroft 		return EINVAL;
   2407  1.33   nathanw 
   2408  1.34   mycroft 	ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
   2409  1.33   nathanw 
   2410  1.34   mycroft 	sc->in_port = ord;
   2411  1.33   nathanw 	return (0);
   2412  1.33   nathanw }
   2413  1.33   nathanw 
   2414  1.33   nathanw /* Set the input device levels on input-mixer-enabled devices. */
   2415   1.1  augustss int
   2416   1.1  augustss ess_set_in_ports(sc, mask)
   2417   1.1  augustss 	struct ess_softc *sc;
   2418   1.1  augustss 	int mask;
   2419   1.1  augustss {
   2420   1.1  augustss 	mixer_devinfo_t di;
   2421  1.34   mycroft 	int i, port;
   2422   1.1  augustss 
   2423   1.1  augustss 	DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
   2424   1.1  augustss 
   2425   1.1  augustss 	/*
   2426   1.1  augustss 	 * Get the device info for the record source control,
   2427   1.1  augustss 	 * including the list of available sources.
   2428   1.1  augustss 	 */
   2429   1.1  augustss 	di.index = ESS_RECORD_SOURCE;
   2430   1.1  augustss 	if (ess_query_devinfo(sc, &di))
   2431   1.1  augustss 		return EINVAL;
   2432   1.1  augustss 
   2433   1.1  augustss 	/*
   2434   1.1  augustss 	 * Set or disable the record volume control for each of the
   2435   1.1  augustss 	 * possible sources.
   2436   1.1  augustss 	 */
   2437  1.33   nathanw 	for (i = 0; i < di.un.s.num_mem; i++) {
   2438   1.1  augustss 		/*
   2439   1.1  augustss 		 * Calculate the source port number from its mask.
   2440   1.1  augustss 		 */
   2441  1.34   mycroft 		port = ffs(di.un.s.member[i].mask);
   2442   1.1  augustss 
   2443   1.1  augustss 		/*
   2444   1.1  augustss 		 * Set the source gain:
   2445   1.1  augustss 		 *	to the current value if source is enabled
   2446   1.1  augustss 		 *	to zero if source is disabled
   2447   1.1  augustss 		 */
   2448   1.1  augustss 		ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
   2449   1.1  augustss 	}
   2450   1.1  augustss 
   2451   1.1  augustss 	sc->in_mask = mask;
   2452   1.1  augustss 	return (0);
   2453   1.1  augustss }
   2454   1.1  augustss 
   2455   1.1  augustss void
   2456   1.1  augustss ess_speaker_on(sc)
   2457   1.1  augustss 	struct ess_softc *sc;
   2458   1.1  augustss {
   2459  1.49   mycroft 	/* Unmute the DAC. */
   2460  1.49   mycroft 	ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
   2461   1.1  augustss }
   2462   1.1  augustss 
   2463   1.1  augustss void
   2464   1.1  augustss ess_speaker_off(sc)
   2465   1.1  augustss 	struct ess_softc *sc;
   2466   1.1  augustss {
   2467  1.49   mycroft 	/* Mute the DAC. */
   2468  1.49   mycroft 	ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
   2469   1.1  augustss }
   2470   1.1  augustss 
   2471   1.1  augustss /*
   2472   1.1  augustss  * Calculate the time constant for the requested sampling rate.
   2473   1.1  augustss  */
   2474   1.1  augustss u_int
   2475   1.1  augustss ess_srtotc(rate)
   2476   1.1  augustss 	u_int rate;
   2477   1.1  augustss {
   2478   1.1  augustss 	u_int tc;
   2479   1.1  augustss 
   2480   1.1  augustss 	/* The following formulae are from the ESS data sheet. */
   2481  1.12   mycroft 	if (rate <= 22050)
   2482   1.1  augustss 		tc = 128 - 397700L / rate;
   2483   1.1  augustss 	else
   2484   1.1  augustss 		tc = 256 - 795500L / rate;
   2485   1.1  augustss 
   2486   1.1  augustss 	return (tc);
   2487   1.1  augustss }
   2488   1.1  augustss 
   2489   1.1  augustss 
   2490   1.1  augustss /*
   2491   1.1  augustss  * Calculate the filter constant for the reuqested sampling rate.
   2492   1.1  augustss  */
   2493   1.1  augustss u_int
   2494   1.1  augustss ess_srtofc(rate)
   2495   1.1  augustss 	u_int rate;
   2496   1.1  augustss {
   2497   1.1  augustss 	/*
   2498   1.1  augustss 	 * The following formula is derived from the information in
   2499   1.1  augustss 	 * the ES1887 data sheet, based on a roll-off frequency of
   2500   1.1  augustss 	 * 87%.
   2501   1.1  augustss 	 */
   2502   1.1  augustss 	return (256 - 200279L / rate);
   2503   1.1  augustss }
   2504   1.1  augustss 
   2505   1.1  augustss 
   2506   1.1  augustss /*
   2507   1.1  augustss  * Return the status of the DSP.
   2508   1.1  augustss  */
   2509   1.1  augustss u_char
   2510   1.1  augustss ess_get_dsp_status(sc)
   2511   1.1  augustss 	struct ess_softc *sc;
   2512   1.1  augustss {
   2513  1.34   mycroft 	return (EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS));
   2514   1.1  augustss }
   2515   1.1  augustss 
   2516   1.1  augustss 
   2517   1.1  augustss /*
   2518   1.1  augustss  * Return the read status of the DSP:	1 -> DSP ready for reading
   2519   1.1  augustss  *					0 -> DSP not ready for reading
   2520   1.1  augustss  */
   2521   1.1  augustss u_char
   2522   1.1  augustss ess_dsp_read_ready(sc)
   2523   1.1  augustss 	struct ess_softc *sc;
   2524   1.1  augustss {
   2525  1.34   mycroft 	return ((ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0);
   2526   1.1  augustss }
   2527   1.1  augustss 
   2528   1.1  augustss 
   2529   1.1  augustss /*
   2530   1.1  augustss  * Return the write status of the DSP:	1 -> DSP ready for writing
   2531   1.1  augustss  *					0 -> DSP not ready for writing
   2532   1.1  augustss  */
   2533   1.1  augustss u_char
   2534   1.1  augustss ess_dsp_write_ready(sc)
   2535   1.1  augustss 	struct ess_softc *sc;
   2536   1.1  augustss {
   2537  1.34   mycroft 	return ((ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1);
   2538   1.1  augustss }
   2539   1.1  augustss 
   2540   1.1  augustss 
   2541   1.1  augustss /*
   2542   1.1  augustss  * Read a byte from the DSP.
   2543   1.1  augustss  */
   2544   1.1  augustss int
   2545   1.1  augustss ess_rdsp(sc)
   2546   1.1  augustss 	struct ess_softc *sc;
   2547   1.1  augustss {
   2548   1.1  augustss 	bus_space_tag_t iot = sc->sc_iot;
   2549   1.1  augustss 	bus_space_handle_t ioh = sc->sc_ioh;
   2550   1.1  augustss 	int i;
   2551   1.1  augustss 
   2552   1.1  augustss 	for (i = ESS_READ_TIMEOUT; i > 0; --i) {
   2553   1.1  augustss 		if (ess_dsp_read_ready(sc)) {
   2554   1.2  augustss 			i = EREAD1(iot, ioh, ESS_DSP_READ);
   2555   1.2  augustss 			DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
   2556   1.1  augustss 			return i;
   2557   1.1  augustss 		} else
   2558   1.1  augustss 			delay(10);
   2559   1.1  augustss 	}
   2560   1.1  augustss 
   2561   1.1  augustss 	DPRINTF(("ess_rdsp: timed out\n"));
   2562   1.1  augustss 	return (-1);
   2563   1.1  augustss }
   2564   1.1  augustss 
   2565   1.1  augustss /*
   2566   1.1  augustss  * Write a byte to the DSP.
   2567   1.1  augustss  */
   2568   1.1  augustss int
   2569   1.1  augustss ess_wdsp(sc, v)
   2570   1.1  augustss 	struct ess_softc *sc;
   2571   1.1  augustss 	u_char v;
   2572   1.1  augustss {
   2573   1.1  augustss 	bus_space_tag_t iot = sc->sc_iot;
   2574   1.1  augustss 	bus_space_handle_t ioh = sc->sc_ioh;
   2575   1.1  augustss 	int i;
   2576   1.2  augustss 
   2577   1.2  augustss 	DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
   2578   1.2  augustss 
   2579   1.1  augustss 	for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
   2580   1.1  augustss 		if (ess_dsp_write_ready(sc)) {
   2581   1.2  augustss 			EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
   2582   1.1  augustss 			return (0);
   2583   1.1  augustss 		} else
   2584   1.1  augustss 			delay(10);
   2585   1.1  augustss 	}
   2586   1.1  augustss 
   2587   1.1  augustss 	DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
   2588   1.1  augustss 	return (-1);
   2589   1.1  augustss }
   2590   1.1  augustss 
   2591   1.1  augustss /*
   2592   1.1  augustss  * Write a value to one of the ESS extended registers.
   2593   1.1  augustss  */
   2594   1.1  augustss int
   2595   1.1  augustss ess_write_x_reg(sc, reg, val)
   2596   1.1  augustss 	struct ess_softc *sc;
   2597   1.1  augustss 	u_char reg;
   2598   1.1  augustss 	u_char val;
   2599   1.1  augustss {
   2600   1.1  augustss 	int error;
   2601   1.1  augustss 
   2602   1.2  augustss 	DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
   2603   1.1  augustss 	if ((error = ess_wdsp(sc, reg)) == 0)
   2604   1.1  augustss 		error = ess_wdsp(sc, val);
   2605   1.1  augustss 
   2606   1.1  augustss 	return error;
   2607   1.1  augustss }
   2608   1.1  augustss 
   2609   1.1  augustss /*
   2610   1.1  augustss  * Read the value of one of the ESS extended registers.
   2611   1.1  augustss  */
   2612   1.1  augustss u_char
   2613   1.1  augustss ess_read_x_reg(sc, reg)
   2614   1.1  augustss 	struct ess_softc *sc;
   2615   1.1  augustss 	u_char reg;
   2616   1.1  augustss {
   2617   1.1  augustss 	int error;
   2618   1.2  augustss 	int val;
   2619   1.1  augustss 
   2620   1.1  augustss 	if ((error = ess_wdsp(sc, 0xC0)) == 0)
   2621   1.1  augustss 		error = ess_wdsp(sc, reg);
   2622   1.1  augustss 	if (error)
   2623   1.1  augustss 		DPRINTF(("Error reading extended register 0x%02x\n", reg));
   2624   1.1  augustss /* REVISIT: what if an error is returned above? */
   2625   1.2  augustss 	val = ess_rdsp(sc);
   2626  1.33   nathanw 	DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
   2627   1.2  augustss 	return val;
   2628   1.1  augustss }
   2629   1.1  augustss 
   2630   1.1  augustss void
   2631   1.1  augustss ess_clear_xreg_bits(sc, reg, mask)
   2632   1.1  augustss 	struct ess_softc *sc;
   2633   1.1  augustss 	u_char reg;
   2634   1.1  augustss 	u_char mask;
   2635   1.1  augustss {
   2636   1.1  augustss 	if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1)
   2637   1.1  augustss 		DPRINTF(("Error clearing bits in extended register 0x%02x\n",
   2638   1.1  augustss 			 reg));
   2639   1.1  augustss }
   2640   1.1  augustss 
   2641   1.1  augustss void
   2642   1.1  augustss ess_set_xreg_bits(sc, reg, mask)
   2643   1.1  augustss 	struct ess_softc *sc;
   2644   1.1  augustss 	u_char reg;
   2645   1.1  augustss 	u_char mask;
   2646   1.1  augustss {
   2647   1.1  augustss 	if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1)
   2648   1.1  augustss 		DPRINTF(("Error setting bits in extended register 0x%02x\n",
   2649   1.1  augustss 			 reg));
   2650   1.1  augustss }
   2651   1.1  augustss 
   2652   1.1  augustss 
   2653   1.1  augustss /*
   2654   1.1  augustss  * Write a value to one of the ESS mixer registers.
   2655   1.1  augustss  */
   2656   1.1  augustss void
   2657   1.1  augustss ess_write_mix_reg(sc, reg, val)
   2658   1.1  augustss 	struct ess_softc *sc;
   2659   1.1  augustss 	u_char reg;
   2660   1.1  augustss 	u_char val;
   2661   1.1  augustss {
   2662   1.1  augustss 	bus_space_tag_t iot = sc->sc_iot;
   2663   1.1  augustss 	bus_space_handle_t ioh = sc->sc_ioh;
   2664   1.1  augustss 	int s;
   2665   1.1  augustss 
   2666   1.2  augustss 	DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
   2667   1.4  augustss 
   2668   1.1  augustss 	s = splaudio();
   2669   1.2  augustss 	EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
   2670   1.2  augustss 	EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
   2671   1.1  augustss 	splx(s);
   2672   1.1  augustss }
   2673   1.1  augustss 
   2674   1.1  augustss /*
   2675   1.1  augustss  * Read the value of one of the ESS mixer registers.
   2676   1.1  augustss  */
   2677   1.1  augustss u_char
   2678   1.1  augustss ess_read_mix_reg(sc, reg)
   2679   1.1  augustss 	struct ess_softc *sc;
   2680   1.1  augustss 	u_char reg;
   2681   1.1  augustss {
   2682   1.1  augustss 	bus_space_tag_t iot = sc->sc_iot;
   2683   1.1  augustss 	bus_space_handle_t ioh = sc->sc_ioh;
   2684   1.1  augustss 	int s;
   2685   1.1  augustss 	u_char val;
   2686   1.1  augustss 
   2687   1.1  augustss 	s = splaudio();
   2688   1.2  augustss 	EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
   2689   1.2  augustss 	val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
   2690   1.4  augustss 	splx(s);
   2691   1.1  augustss 
   2692   1.2  augustss 	DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
   2693   1.1  augustss 	return val;
   2694   1.1  augustss }
   2695   1.1  augustss 
   2696   1.1  augustss void
   2697   1.1  augustss ess_clear_mreg_bits(sc, reg, mask)
   2698   1.1  augustss 	struct ess_softc *sc;
   2699   1.1  augustss 	u_char reg;
   2700   1.1  augustss 	u_char mask;
   2701   1.1  augustss {
   2702   1.1  augustss 	ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
   2703   1.1  augustss }
   2704   1.1  augustss 
   2705   1.1  augustss void
   2706   1.1  augustss ess_set_mreg_bits(sc, reg, mask)
   2707   1.1  augustss 	struct ess_softc *sc;
   2708   1.1  augustss 	u_char reg;
   2709   1.1  augustss 	u_char mask;
   2710   1.1  augustss {
   2711   1.1  augustss 	ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
   2712  1.46  augustss }
   2713  1.46  augustss 
   2714  1.46  augustss void
   2715  1.46  augustss ess_read_multi_mix_reg(sc, reg, datap, count)
   2716  1.46  augustss 	struct ess_softc *sc;
   2717  1.46  augustss 	u_char reg;
   2718  1.46  augustss 	u_int8_t *datap;
   2719  1.46  augustss 	bus_size_t count;
   2720  1.46  augustss {
   2721  1.46  augustss 	bus_space_tag_t iot = sc->sc_iot;
   2722  1.46  augustss 	bus_space_handle_t ioh = sc->sc_ioh;
   2723  1.46  augustss 	int s;
   2724  1.46  augustss 
   2725  1.46  augustss 	s = splaudio();
   2726  1.46  augustss 	EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
   2727  1.46  augustss 	bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
   2728  1.46  augustss 	splx(s);
   2729   1.1  augustss }
   2730