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