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