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