xref: /netbsd/sys/dev/isa/ess.c (revision deeec4a8)
1 /*	$NetBSD: ess.c,v 1.90 2022/12/24 15:23:02 andvar 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.90 2022/12/24 15:23:02 andvar 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
ess_printsc(struct ess_softc * sc)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
ess_dump_mixer(struct ess_softc * sc)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
ess_config_addr(struct ess_softc * sc)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
ess_config_irq(struct ess_softc * sc)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
ess_config_drq(struct ess_softc * sc)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
ess_setup(struct ess_softc * sc)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
ess_identify(struct ess_softc * sc)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
ess_setup_sc(struct ess_softc * sc,int doinit)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
essmatch(struct ess_softc * sc)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
essattach(struct ess_softc * sc,int enablejoy)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 	    CFARGS(.iattr = "ess"));
1050 
1051 #if NJOY_ESS > 0
1052 	if (sc->sc_model == ESS_1888 && enablejoy) {
1053 		unsigned char m40;
1054 
1055 		m40 = ess_read_mix_reg(sc, 0x40);
1056 		m40 |= 2;
1057 		ess_write_mix_reg(sc, 0x40, m40);
1058 
1059 		arg.type = AUDIODEV_TYPE_AUX;
1060 		(void)config_found(sc->sc_dev, &arg, audioprint,
1061 		    CFARGS(.iattr = "ess"));
1062 	}
1063 #endif
1064 
1065 #ifdef AUDIO_DEBUG
1066 	if (essdebug > 0)
1067 		ess_printsc(sc);
1068 #endif
1069 
1070 	return;
1071 
1072  fail:
1073 	callout_destroy(&sc->sc_poll1_ch);
1074 	callout_destroy(&sc->sc_poll2_ch);
1075 	mutex_destroy(&sc->sc_lock);
1076 	mutex_destroy(&sc->sc_intr_lock);
1077 }
1078 
1079 /*
1080  * Various routines to interface to higher level audio driver
1081  */
1082 
1083 void
ess_close(void * addr)1084 ess_close(void *addr)
1085 {
1086 	struct ess_softc *sc;
1087 
1088 	sc = addr;
1089 	DPRINTF(("ess_close: sc=%p\n", sc));
1090 
1091 	ess_speaker_off(sc);
1092 	sc->spkr_state = SPKR_OFF;
1093 
1094 	DPRINTF(("ess_close: closed\n"));
1095 }
1096 
1097 /* XXX should use reference count */
1098 int
ess_speaker_ctl(void * addr,int newstate)1099 ess_speaker_ctl(void *addr, int newstate)
1100 {
1101 	struct ess_softc *sc;
1102 
1103 	sc = addr;
1104 	if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
1105 		ess_speaker_on(sc);
1106 		sc->spkr_state = SPKR_ON;
1107 	}
1108 	if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
1109 		ess_speaker_off(sc);
1110 		sc->spkr_state = SPKR_OFF;
1111 	}
1112 	return 0;
1113 }
1114 
1115 int
ess_getdev(void * addr,struct audio_device * retp)1116 ess_getdev(void *addr, struct audio_device *retp)
1117 {
1118 
1119 	*retp = ess_device;
1120 	return 0;
1121 }
1122 
1123 int
ess_query_format(void * addr,audio_format_query_t * afp)1124 ess_query_format(void *addr, audio_format_query_t *afp)
1125 {
1126 
1127 	return audio_query_format(ess_formats, ESS_NFORMATS, afp);
1128 }
1129 
1130 int
ess_set_format(void * addr,int setmode,const audio_params_t * play,const audio_params_t * rec,audio_filter_reg_t * pfil,audio_filter_reg_t * rfil)1131 ess_set_format(void *addr, int setmode,
1132 	const audio_params_t *play, const audio_params_t *rec,
1133 	audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
1134 {
1135 	struct ess_softc *sc;
1136 	int rate;
1137 
1138 	DPRINTF(("%s: set=%d\n", __func__, setmode));
1139 	sc = addr;
1140 
1141 	/* *play and *rec are the identical because !AUDIO_PROP_INDEPENDENT. */
1142 
1143 	rate = play->sample_rate;
1144 	ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(sc, rate));
1145 	ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
1146 
1147 	if (!ESS_USE_AUDIO1(sc->sc_model)) {
1148 		ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE,
1149 		    ess_srtotc(sc, rate));
1150 		ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
1151 	}
1152 
1153 	return 0;
1154 }
1155 
1156 int
ess_audio1_trigger_output(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)1157 ess_audio1_trigger_output(
1158 	void *addr,
1159 	void *start, void *end,
1160 	int blksize,
1161 	void (*intr)(void *),
1162 	void *arg,
1163 	const audio_params_t *param)
1164 {
1165 	struct ess_softc *sc;
1166 	u_int8_t reg;
1167 
1168 	sc = addr;
1169 	DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p "
1170 	    "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1171 
1172 	if (sc->sc_audio1.active)
1173 		panic("ess_audio1_trigger_output: already running");
1174 
1175 	sc->sc_audio1.active = 1;
1176 	sc->sc_audio1.intr = intr;
1177 	sc->sc_audio1.arg = arg;
1178 	if (sc->sc_audio1.polled) {
1179 		sc->sc_audio1.dmapos = 0;
1180 		sc->sc_audio1.buffersize = (char *)end - (char *)start;
1181 		sc->sc_audio1.dmacount = 0;
1182 		sc->sc_audio1.blksize = blksize;
1183 		callout_reset(&sc->sc_poll1_ch, hz / 30,
1184 		    ess_audio1_poll, sc);
1185 	}
1186 
1187 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1188 	if (param->channels == 2) {
1189 		reg &= ~ESS_AUDIO_CTRL_MONO;
1190 		reg |= ESS_AUDIO_CTRL_STEREO;
1191 	} else {
1192 		reg |= ESS_AUDIO_CTRL_MONO;
1193 		reg &= ~ESS_AUDIO_CTRL_STEREO;
1194 	}
1195 	ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1196 
1197 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1198 	if (param->precision == 16)
1199 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1200 	else
1201 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1202 	if (param->channels == 2)
1203 		reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1204 	else
1205 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1206 	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1207 	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1208 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1209 	else
1210 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1211 	reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1212 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1213 
1214 	isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1215 		     (char *)end - (char *)start, NULL,
1216 	    DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1217 
1218 	/* Program transfer count registers with 2's complement of count. */
1219 	blksize = -blksize;
1220 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1221 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1222 
1223 	/* Use 4 bytes per output DMA. */
1224 	ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1225 
1226 	/* Start auto-init DMA */
1227 	ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
1228 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1229 	reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
1230 	reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1231 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1232 
1233 	return 0;
1234 }
1235 
1236 int
ess_audio2_trigger_output(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)1237 ess_audio2_trigger_output(
1238 	void *addr,
1239 	void *start, void *end,
1240 	int blksize,
1241 	void (*intr)(void *),
1242 	void *arg,
1243 	const audio_params_t *param)
1244 {
1245 	struct ess_softc *sc;
1246 	u_int8_t reg;
1247 
1248 	sc = addr;
1249 	DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p "
1250 	    "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1251 
1252 	if (sc->sc_audio2.active)
1253 		panic("ess_audio2_trigger_output: already running");
1254 
1255 	sc->sc_audio2.active = 1;
1256 	sc->sc_audio2.intr = intr;
1257 	sc->sc_audio2.arg = arg;
1258 	if (sc->sc_audio2.polled) {
1259 		sc->sc_audio2.dmapos = 0;
1260 		sc->sc_audio2.buffersize = (char *)end - (char *)start;
1261 		sc->sc_audio2.dmacount = 0;
1262 		sc->sc_audio2.blksize = blksize;
1263 		callout_reset(&sc->sc_poll2_ch, hz / 30,
1264 		    ess_audio2_poll, sc);
1265 	}
1266 
1267 	reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1268 	if (param->precision == 16)
1269 		reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
1270 	else
1271 		reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
1272 	if (param->channels == 2)
1273 		reg |= ESS_AUDIO2_CTRL2_CHANNELS;
1274 	else
1275 		reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
1276 	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1277 	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1278 		reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1279 	else
1280 		reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1281 	ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1282 
1283 	isa_dmastart(sc->sc_ic, sc->sc_audio2.drq, start,
1284 		     (char *)end - (char *)start, NULL,
1285 	    DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1286 
1287 	if (IS16BITDRQ(sc->sc_audio2.drq))
1288 		blksize >>= 1;	/* use word count for 16 bit DMA */
1289 	/* Program transfer count registers with 2's complement of count. */
1290 	blksize = -blksize;
1291 	ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
1292 	ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
1293 
1294 	reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
1295 	if (IS16BITDRQ(sc->sc_audio2.drq))
1296 		reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
1297 	else
1298 		reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
1299 	reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
1300 	reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
1301 	       ESS_AUDIO2_CTRL1_AUTO_INIT;
1302 	ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
1303 
1304 	return (0);
1305 }
1306 
1307 int
ess_audio1_trigger_input(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)1308 ess_audio1_trigger_input(
1309 	void *addr,
1310 	void *start, void *end,
1311 	int blksize,
1312 	void (*intr)(void *),
1313 	void *arg,
1314 	const audio_params_t *param)
1315 {
1316 	struct ess_softc *sc;
1317 	u_int8_t reg;
1318 
1319 	sc = addr;
1320 	DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p "
1321 	    "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1322 
1323 	if (sc->sc_audio1.active)
1324 		panic("ess_audio1_trigger_input: already running");
1325 
1326 	sc->sc_audio1.active = 1;
1327 	sc->sc_audio1.intr = intr;
1328 	sc->sc_audio1.arg = arg;
1329 	if (sc->sc_audio1.polled) {
1330 		sc->sc_audio1.dmapos = 0;
1331 		sc->sc_audio1.buffersize = (char *)end - (char *)start;
1332 		sc->sc_audio1.dmacount = 0;
1333 		sc->sc_audio1.blksize = blksize;
1334 		callout_reset(&sc->sc_poll1_ch, hz / 30,
1335 		    ess_audio1_poll, sc);
1336 	}
1337 
1338 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1339 	if (param->channels == 2) {
1340 		reg &= ~ESS_AUDIO_CTRL_MONO;
1341 		reg |= ESS_AUDIO_CTRL_STEREO;
1342 	} else {
1343 		reg |= ESS_AUDIO_CTRL_MONO;
1344 		reg &= ~ESS_AUDIO_CTRL_STEREO;
1345 	}
1346 	ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1347 
1348 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1349 	if (param->precision == 16)
1350 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1351 	else
1352 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1353 	if (param->channels == 2)
1354 		reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1355 	else
1356 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1357 	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1358 	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1359 		reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1360 	else
1361 		reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1362 	reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1363 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1364 
1365 	isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1366 		     (char *)end - (char *)start, NULL,
1367 	    DMAMODE_READ | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1368 
1369 	/* Program transfer count registers with 2's complement of count. */
1370 	blksize = -blksize;
1371 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1372 	ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1373 
1374 	/* Use 4 bytes per input DMA. */
1375 	ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1376 
1377 	/* Start auto-init DMA */
1378 	ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
1379 	reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1380 	reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
1381 	reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1382 	ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1383 
1384 	return 0;
1385 }
1386 
1387 int
ess_audio1_halt(void * addr)1388 ess_audio1_halt(void *addr)
1389 {
1390 	struct ess_softc *sc;
1391 
1392 	sc = addr;
1393 	DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
1394 
1395 	if (sc->sc_audio1.active) {
1396 		ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
1397 		    ESS_AUDIO1_CTRL2_FIFO_ENABLE);
1398 		isa_dmaabort(sc->sc_ic, sc->sc_audio1.drq);
1399 		if (sc->sc_audio1.polled)
1400 			callout_stop(&sc->sc_poll1_ch);
1401 		sc->sc_audio1.active = 0;
1402 	}
1403 
1404 	return 0;
1405 }
1406 
1407 int
ess_audio2_halt(void * addr)1408 ess_audio2_halt(void *addr)
1409 {
1410 	struct ess_softc *sc;
1411 
1412 	sc = addr;
1413 	DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
1414 
1415 	if (sc->sc_audio2.active) {
1416 		ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
1417 		    ESS_AUDIO2_CTRL1_DAC_ENABLE |
1418 		    ESS_AUDIO2_CTRL1_FIFO_ENABLE);
1419 		isa_dmaabort(sc->sc_ic, sc->sc_audio2.drq);
1420 		if (sc->sc_audio2.polled)
1421 			callout_stop(&sc->sc_poll2_ch);
1422 		sc->sc_audio2.active = 0;
1423 	}
1424 
1425 	return 0;
1426 }
1427 
1428 int
ess_audio1_intr(void * arg)1429 ess_audio1_intr(void *arg)
1430 {
1431 	struct ess_softc *sc;
1432 	uint8_t reg;
1433 	int rv;
1434 
1435 	sc = arg;
1436 	DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
1437 
1438 	mutex_spin_enter(&sc->sc_intr_lock);
1439 
1440 	/* Check and clear interrupt on Audio1. */
1441 	reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
1442 	if ((reg & ESS_DSP_READ_OFLOW) == 0) {
1443 		mutex_spin_exit(&sc->sc_intr_lock);
1444 		return 0;
1445 	}
1446 	reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
1447 
1448 	sc->sc_audio1.nintr++;
1449 
1450 	if (sc->sc_audio1.active) {
1451 		(*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1452 		rv = 1;
1453 	} else
1454 		rv = 0;
1455 
1456 	mutex_spin_exit(&sc->sc_intr_lock);
1457 
1458 	return rv;
1459 }
1460 
1461 int
ess_audio2_intr(void * arg)1462 ess_audio2_intr(void *arg)
1463 {
1464 	struct ess_softc *sc;
1465 	uint8_t reg;
1466 	int rv;
1467 
1468 	sc = arg;
1469 	DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
1470 
1471 	mutex_spin_enter(&sc->sc_intr_lock);
1472 
1473 	/* Check and clear interrupt on Audio2. */
1474 	reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1475 	if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0) {
1476 		mutex_spin_exit(&sc->sc_intr_lock);
1477 		return 0;
1478 	}
1479 	reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
1480 	ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1481 
1482 	sc->sc_audio2.nintr++;
1483 
1484 	if (sc->sc_audio2.active) {
1485 		(*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1486 		rv = 1;
1487 	} else
1488 		rv = 0;
1489 
1490 	mutex_spin_exit(&sc->sc_intr_lock);
1491 
1492 	return rv;
1493 }
1494 
1495 void
ess_audio1_poll(void * addr)1496 ess_audio1_poll(void *addr)
1497 {
1498 	struct ess_softc *sc;
1499 	int dmapos, dmacount;
1500 
1501 	sc = addr;
1502 	mutex_spin_enter(&sc->sc_intr_lock);
1503 
1504 	if (!sc->sc_audio1.active) {
1505 		mutex_spin_exit(&sc->sc_intr_lock);
1506 		return;
1507 	}
1508 
1509 	sc->sc_audio1.nintr++;
1510 
1511 	dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio1.drq);
1512 	dmacount = sc->sc_audio1.dmapos - dmapos;
1513 	if (dmacount < 0)
1514 		dmacount += sc->sc_audio1.buffersize;
1515 	sc->sc_audio1.dmapos = dmapos;
1516 #if 1
1517 	dmacount += sc->sc_audio1.dmacount;
1518 	while (dmacount > sc->sc_audio1.blksize) {
1519 		dmacount -= sc->sc_audio1.blksize;
1520 		(*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1521 	}
1522 	sc->sc_audio1.dmacount = dmacount;
1523 #else
1524 	(*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
1525 #endif
1526 
1527 	mutex_spin_exit(&sc->sc_intr_lock);
1528 	callout_reset(&sc->sc_poll1_ch, hz / 30, ess_audio1_poll, sc);
1529 }
1530 
1531 void
ess_audio2_poll(void * addr)1532 ess_audio2_poll(void *addr)
1533 {
1534 	struct ess_softc *sc;
1535 	int dmapos, dmacount;
1536 
1537 	sc = addr;
1538 	mutex_spin_enter(&sc->sc_intr_lock);
1539 
1540 	if (!sc->sc_audio2.active) {
1541 		mutex_spin_exit(&sc->sc_intr_lock);
1542 		return;
1543 	}
1544 
1545 	sc->sc_audio2.nintr++;
1546 
1547 	dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio2.drq);
1548 	dmacount = sc->sc_audio2.dmapos - dmapos;
1549 	if (dmacount < 0)
1550 		dmacount += sc->sc_audio2.buffersize;
1551 	sc->sc_audio2.dmapos = dmapos;
1552 #if 1
1553 	dmacount += sc->sc_audio2.dmacount;
1554 	while (dmacount > sc->sc_audio2.blksize) {
1555 		dmacount -= sc->sc_audio2.blksize;
1556 		(*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1557 	}
1558 	sc->sc_audio2.dmacount = dmacount;
1559 #else
1560 	(*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
1561 #endif
1562 
1563 	mutex_spin_exit(&sc->sc_intr_lock);
1564 	callout_reset(&sc->sc_poll2_ch, hz / 30, ess_audio2_poll, sc);
1565 }
1566 
1567 int
ess_round_blocksize(void * addr,int blk,int mode,const audio_params_t * param)1568 ess_round_blocksize(void *addr, int blk, int mode,
1569     const audio_params_t *param)
1570 {
1571 
1572 	return blk & -8;	/* round for max DMA size */
1573 }
1574 
1575 int
ess_set_port(void * addr,mixer_ctrl_t * cp)1576 ess_set_port(void *addr, mixer_ctrl_t *cp)
1577 {
1578 	struct ess_softc *sc;
1579 	int lgain, rgain;
1580 
1581 	sc = addr;
1582 	DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
1583 		    cp->dev, cp->un.value.num_channels));
1584 
1585 	switch (cp->dev) {
1586 	/*
1587 	 * The following mixer ports are all stereo. If we get a
1588 	 * single-channel gain value passed in, then we duplicate it
1589 	 * to both left and right channels.
1590 	 */
1591 	case ESS_MASTER_VOL:
1592 	case ESS_DAC_PLAY_VOL:
1593 	case ESS_MIC_PLAY_VOL:
1594 	case ESS_LINE_PLAY_VOL:
1595 	case ESS_SYNTH_PLAY_VOL:
1596 	case ESS_CD_PLAY_VOL:
1597 	case ESS_AUXB_PLAY_VOL:
1598 	case ESS_RECORD_VOL:
1599 		if (cp->type != AUDIO_MIXER_VALUE)
1600 			return EINVAL;
1601 
1602 		switch (cp->un.value.num_channels) {
1603 		case 1:
1604 			lgain = rgain = ESS_4BIT_GAIN(
1605 			  cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1606 			break;
1607 		case 2:
1608 			lgain = ESS_4BIT_GAIN(
1609 			  cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1610 			rgain = ESS_4BIT_GAIN(
1611 			  cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1612 			break;
1613 		default:
1614 			return EINVAL;
1615 		}
1616 
1617 		sc->gain[cp->dev][ESS_LEFT]  = lgain;
1618 		sc->gain[cp->dev][ESS_RIGHT] = rgain;
1619 		ess_set_gain(sc, cp->dev, 1);
1620 		return 0;
1621 
1622 	/*
1623 	 * The PC speaker port is mono. If we get a stereo gain value
1624 	 * passed in, then we return EINVAL.
1625 	 */
1626 	case ESS_PCSPEAKER_VOL:
1627 		if (cp->un.value.num_channels != 1)
1628 			return EINVAL;
1629 
1630 		sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
1631 		  ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1632 		ess_set_gain(sc, cp->dev, 1);
1633 		return 0;
1634 
1635 	case ESS_RECORD_SOURCE:
1636 		if (ESS_USE_AUDIO1(sc->sc_model)) {
1637 			if (cp->type == AUDIO_MIXER_ENUM)
1638 				return ess_set_in_port(sc, cp->un.ord);
1639 			else
1640 				return EINVAL;
1641 		} else {
1642 			if (cp->type == AUDIO_MIXER_SET)
1643 				return ess_set_in_ports(sc, cp->un.mask);
1644 			else
1645 				return EINVAL;
1646 		}
1647 		return 0;
1648 
1649 	case ESS_RECORD_MONITOR:
1650 		if (cp->type != AUDIO_MIXER_ENUM)
1651 			return EINVAL;
1652 
1653 		if (cp->un.ord)
1654 			/* Enable monitor */
1655 			ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1656 					  ESS_AUDIO_CTRL_MONITOR);
1657 		else
1658 			/* Disable monitor */
1659 			ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1660 					    ESS_AUDIO_CTRL_MONITOR);
1661 		return 0;
1662 	}
1663 
1664 	if (ESS_IS_ES18X9(sc->sc_model)) {
1665 
1666 		switch (cp->dev) {
1667 		case ESS_SPATIALIZER:
1668 			if (cp->type != AUDIO_MIXER_VALUE ||
1669 			    cp->un.value.num_channels != 1)
1670 				return EINVAL;
1671 
1672 			sc->gain[cp->dev][ESS_LEFT] =
1673 				sc->gain[cp->dev][ESS_RIGHT] = ESS_6BIT_GAIN(
1674 				    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1675 			ess_set_gain(sc, cp->dev, 1);
1676 			return 0;
1677 
1678 		case ESS_SPATIALIZER_ENABLE:
1679 			if (cp->type != AUDIO_MIXER_ENUM)
1680 				return EINVAL;
1681 
1682 			sc->sc_spatializer = (cp->un.ord != 0);
1683 			if (sc->sc_spatializer)
1684 				ess_set_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
1685 				    ESS_SPATIAL_CTRL_ENABLE);
1686 			else
1687 				ess_clear_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
1688 				    ESS_SPATIAL_CTRL_ENABLE);
1689 			return 0;
1690 		}
1691 	}
1692 
1693 	if (ESS_USE_AUDIO1(sc->sc_model))
1694 		return EINVAL;
1695 
1696 	switch (cp->dev) {
1697 	case ESS_DAC_REC_VOL:
1698 	case ESS_MIC_REC_VOL:
1699 	case ESS_LINE_REC_VOL:
1700 	case ESS_SYNTH_REC_VOL:
1701 	case ESS_CD_REC_VOL:
1702 	case ESS_AUXB_REC_VOL:
1703 		if (cp->type != AUDIO_MIXER_VALUE)
1704 			return EINVAL;
1705 
1706 		switch (cp->un.value.num_channels) {
1707 		case 1:
1708 			lgain = rgain = ESS_4BIT_GAIN(
1709 			  cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1710 			break;
1711 		case 2:
1712 			lgain = ESS_4BIT_GAIN(
1713 			  cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1714 			rgain = ESS_4BIT_GAIN(
1715 			  cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1716 			break;
1717 		default:
1718 			return EINVAL;
1719 		}
1720 
1721 		sc->gain[cp->dev][ESS_LEFT]  = lgain;
1722 		sc->gain[cp->dev][ESS_RIGHT] = rgain;
1723 		ess_set_gain(sc, cp->dev, 1);
1724 		return 0;
1725 
1726 	case ESS_MIC_PREAMP:
1727 		if (cp->type != AUDIO_MIXER_ENUM)
1728 			return EINVAL;
1729 
1730 		if (cp->un.ord)
1731 			/* Enable microphone preamp */
1732 			ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1733 					  ESS_PREAMP_CTRL_ENABLE);
1734 		else
1735 			/* Disable microphone preamp */
1736 			ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1737 					  ESS_PREAMP_CTRL_ENABLE);
1738 		return 0;
1739 	}
1740 
1741 	return EINVAL;
1742 }
1743 
1744 int
ess_get_port(void * addr,mixer_ctrl_t * cp)1745 ess_get_port(void *addr, mixer_ctrl_t *cp)
1746 {
1747 	struct ess_softc *sc;
1748 
1749 	sc = addr;
1750 	DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
1751 
1752 	switch (cp->dev) {
1753 	case ESS_MASTER_VOL:
1754 	case ESS_DAC_PLAY_VOL:
1755 	case ESS_MIC_PLAY_VOL:
1756 	case ESS_LINE_PLAY_VOL:
1757 	case ESS_SYNTH_PLAY_VOL:
1758 	case ESS_CD_PLAY_VOL:
1759 	case ESS_AUXB_PLAY_VOL:
1760 	case ESS_RECORD_VOL:
1761 		switch (cp->un.value.num_channels) {
1762 		case 1:
1763 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1764 				sc->gain[cp->dev][ESS_LEFT];
1765 			break;
1766 		case 2:
1767 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1768 				sc->gain[cp->dev][ESS_LEFT];
1769 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1770 				sc->gain[cp->dev][ESS_RIGHT];
1771 			break;
1772 		default:
1773 			return EINVAL;
1774 		}
1775 		return 0;
1776 
1777 	case ESS_PCSPEAKER_VOL:
1778 		if (cp->un.value.num_channels != 1)
1779 			return EINVAL;
1780 
1781 		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1782 			sc->gain[cp->dev][ESS_LEFT];
1783 		return 0;
1784 
1785 	case ESS_RECORD_SOURCE:
1786 		if (ESS_USE_AUDIO1(sc->sc_model))
1787 			cp->un.ord = sc->in_port;
1788 		else
1789 			cp->un.mask = sc->in_mask;
1790 		return 0;
1791 
1792 	case ESS_RECORD_MONITOR:
1793 		cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
1794 			      ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
1795 		return 0;
1796 	}
1797 
1798 	if (ESS_IS_ES18X9(sc->sc_model)) {
1799 
1800 		switch (cp->dev) {
1801 		case ESS_SPATIALIZER:
1802 			if (cp->un.value.num_channels != 1)
1803 				return EINVAL;
1804 
1805 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1806 				sc->gain[cp->dev][ESS_LEFT];
1807 			return 0;
1808 
1809 		case ESS_SPATIALIZER_ENABLE:
1810 			cp->un.ord = sc->sc_spatializer;
1811 			return 0;
1812 		}
1813 	}
1814 
1815 	if (ESS_USE_AUDIO1(sc->sc_model))
1816 		return EINVAL;
1817 
1818 	switch (cp->dev) {
1819 	case ESS_DAC_REC_VOL:
1820 	case ESS_MIC_REC_VOL:
1821 	case ESS_LINE_REC_VOL:
1822 	case ESS_SYNTH_REC_VOL:
1823 	case ESS_CD_REC_VOL:
1824 	case ESS_AUXB_REC_VOL:
1825 		switch (cp->un.value.num_channels) {
1826 		case 1:
1827 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1828 				sc->gain[cp->dev][ESS_LEFT];
1829 			break;
1830 		case 2:
1831 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1832 				sc->gain[cp->dev][ESS_LEFT];
1833 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1834 				sc->gain[cp->dev][ESS_RIGHT];
1835 			break;
1836 		default:
1837 			return EINVAL;
1838 		}
1839 		return 0;
1840 
1841 	case ESS_MIC_PREAMP:
1842 		cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
1843 			      ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
1844 		return 0;
1845 	}
1846 
1847 	return EINVAL;
1848 }
1849 
1850 int
ess_query_devinfo(void * addr,mixer_devinfo_t * dip)1851 ess_query_devinfo(void *addr, mixer_devinfo_t *dip)
1852 {
1853 	struct ess_softc *sc;
1854 
1855 	sc = addr;
1856 	DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
1857 		    sc->sc_model, dip->index));
1858 
1859 	/*
1860 	 * REVISIT: There are some slight differences between the
1861 	 *          mixers on the different ESS chips, which can
1862 	 *          be sorted out using the chip model rather than a
1863 	 *          separate mixer model.
1864 	 *          This is currently coded assuming an ES1887; we
1865 	 *          need to work out which bits are not applicable to
1866 	 *          the other models (1888 and 888).
1867 	 */
1868 	switch (dip->index) {
1869 	case ESS_DAC_PLAY_VOL:
1870 		dip->mixer_class = ESS_INPUT_CLASS;
1871 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1872 		strcpy(dip->label.name, AudioNdac);
1873 		dip->type = AUDIO_MIXER_VALUE;
1874 		dip->un.v.num_channels = 2;
1875 		strcpy(dip->un.v.units.name, AudioNvolume);
1876 		return 0;
1877 
1878 	case ESS_MIC_PLAY_VOL:
1879 		dip->mixer_class = ESS_INPUT_CLASS;
1880 		dip->prev = AUDIO_MIXER_LAST;
1881 		if (ESS_USE_AUDIO1(sc->sc_model))
1882 			dip->next = AUDIO_MIXER_LAST;
1883 		else
1884 			dip->next = ESS_MIC_PREAMP;
1885 		strcpy(dip->label.name, AudioNmicrophone);
1886 		dip->type = AUDIO_MIXER_VALUE;
1887 		dip->un.v.num_channels = 2;
1888 		strcpy(dip->un.v.units.name, AudioNvolume);
1889 		return 0;
1890 
1891 	case ESS_LINE_PLAY_VOL:
1892 		dip->mixer_class = ESS_INPUT_CLASS;
1893 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1894 		strcpy(dip->label.name, AudioNline);
1895 		dip->type = AUDIO_MIXER_VALUE;
1896 		dip->un.v.num_channels = 2;
1897 		strcpy(dip->un.v.units.name, AudioNvolume);
1898 		return 0;
1899 
1900 	case ESS_SYNTH_PLAY_VOL:
1901 		dip->mixer_class = ESS_INPUT_CLASS;
1902 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1903 		strcpy(dip->label.name, AudioNfmsynth);
1904 		dip->type = AUDIO_MIXER_VALUE;
1905 		dip->un.v.num_channels = 2;
1906 		strcpy(dip->un.v.units.name, AudioNvolume);
1907 		return 0;
1908 
1909 	case ESS_CD_PLAY_VOL:
1910 		dip->mixer_class = ESS_INPUT_CLASS;
1911 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1912 		strcpy(dip->label.name, AudioNcd);
1913 		dip->type = AUDIO_MIXER_VALUE;
1914 		dip->un.v.num_channels = 2;
1915 		strcpy(dip->un.v.units.name, AudioNvolume);
1916 		return 0;
1917 
1918 	case ESS_AUXB_PLAY_VOL:
1919 		dip->mixer_class = ESS_INPUT_CLASS;
1920 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1921 		strcpy(dip->label.name, "auxb");
1922 		dip->type = AUDIO_MIXER_VALUE;
1923 		dip->un.v.num_channels = 2;
1924 		strcpy(dip->un.v.units.name, AudioNvolume);
1925 		return 0;
1926 
1927 	case ESS_INPUT_CLASS:
1928 		dip->mixer_class = ESS_INPUT_CLASS;
1929 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1930 		strcpy(dip->label.name, AudioCinputs);
1931 		dip->type = AUDIO_MIXER_CLASS;
1932 		return 0;
1933 
1934 	case ESS_MASTER_VOL:
1935 		dip->mixer_class = ESS_OUTPUT_CLASS;
1936 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1937 		strcpy(dip->label.name, AudioNmaster);
1938 		dip->type = AUDIO_MIXER_VALUE;
1939 		dip->un.v.num_channels = 2;
1940 		strcpy(dip->un.v.units.name, AudioNvolume);
1941 		return 0;
1942 
1943 	case ESS_PCSPEAKER_VOL:
1944 		dip->mixer_class = ESS_OUTPUT_CLASS;
1945 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1946 		strcpy(dip->label.name, "pc_speaker");
1947 		dip->type = AUDIO_MIXER_VALUE;
1948 		dip->un.v.num_channels = 1;
1949 		strcpy(dip->un.v.units.name, AudioNvolume);
1950 		return 0;
1951 
1952 	case ESS_OUTPUT_CLASS:
1953 		dip->mixer_class = ESS_OUTPUT_CLASS;
1954 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1955 		strcpy(dip->label.name, AudioCoutputs);
1956 		dip->type = AUDIO_MIXER_CLASS;
1957 		return 0;
1958 
1959 	case ESS_RECORD_VOL:
1960 		dip->mixer_class = ESS_RECORD_CLASS;
1961 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1962 		strcpy(dip->label.name, AudioNrecord);
1963 		dip->type = AUDIO_MIXER_VALUE;
1964 		dip->un.v.num_channels = 2;
1965 		strcpy(dip->un.v.units.name, AudioNvolume);
1966 		return 0;
1967 
1968 	case ESS_RECORD_SOURCE:
1969 		dip->mixer_class = ESS_RECORD_CLASS;
1970 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1971 		strcpy(dip->label.name, AudioNsource);
1972 		if (ESS_USE_AUDIO1(sc->sc_model)) {
1973 			/*
1974 			 * The 1788 doesn't use the input mixer control that
1975 			 * the 1888 uses, because it's a pain when you only
1976 			 * have one mixer.
1977 			 * Perhaps it could be emulated by keeping both sets of
1978 			 * gain values, and doing a `context switch' of the
1979 			 * mixer registers when shifting from playing to
1980 			 * recording.
1981 			 */
1982 			dip->type = AUDIO_MIXER_ENUM;
1983 			dip->un.e.num_mem = 4;
1984 			strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
1985 			dip->un.e.member[0].ord = ESS_SOURCE_MIC;
1986 			strcpy(dip->un.e.member[1].label.name, AudioNline);
1987 			dip->un.e.member[1].ord = ESS_SOURCE_LINE;
1988 			strcpy(dip->un.e.member[2].label.name, AudioNcd);
1989 			dip->un.e.member[2].ord = ESS_SOURCE_CD;
1990 			strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
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 			strcpy(dip->un.s.member[0].label.name, AudioNdac);
1996 			dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
1997 			strcpy(dip->un.s.member[1].label.name, AudioNmicrophone);
1998 			dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
1999 			strcpy(dip->un.s.member[2].label.name, AudioNline);
2000 			dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
2001 			strcpy(dip->un.s.member[3].label.name, AudioNfmsynth);
2002 			dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
2003 			strcpy(dip->un.s.member[4].label.name, AudioNcd);
2004 			dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
2005 			strcpy(dip->un.s.member[5].label.name, "auxb");
2006 			dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
2007 		}
2008 		return 0;
2009 
2010 	case ESS_RECORD_CLASS:
2011 		dip->mixer_class = ESS_RECORD_CLASS;
2012 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2013 		strcpy(dip->label.name, AudioCrecord);
2014 		dip->type = AUDIO_MIXER_CLASS;
2015 		return 0;
2016 
2017 	case ESS_RECORD_MONITOR:
2018 		dip->prev = dip->next = AUDIO_MIXER_LAST;
2019 		strcpy(dip->label.name, AudioNmute);
2020 		dip->type = AUDIO_MIXER_ENUM;
2021 		dip->mixer_class = ESS_MONITOR_CLASS;
2022 		dip->un.e.num_mem = 2;
2023 		strcpy(dip->un.e.member[0].label.name, AudioNoff);
2024 		dip->un.e.member[0].ord = 0;
2025 		strcpy(dip->un.e.member[1].label.name, AudioNon);
2026 		dip->un.e.member[1].ord = 1;
2027 		return 0;
2028 
2029 	case ESS_MONITOR_CLASS:
2030 		dip->mixer_class = ESS_MONITOR_CLASS;
2031 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2032 		strcpy(dip->label.name, AudioCmonitor);
2033 		dip->type = AUDIO_MIXER_CLASS;
2034 		return 0;
2035 	}
2036 
2037 	if (ESS_IS_ES18X9(sc->sc_model)) {
2038 
2039 		switch (dip->index) {
2040 		case ESS_SPATIALIZER:
2041 			dip->mixer_class = ESS_OUTPUT_CLASS;
2042 			dip->prev = AUDIO_MIXER_LAST;
2043 			dip->next = ESS_SPATIALIZER_ENABLE;
2044 			strcpy(dip->label.name, AudioNspatial);
2045 			dip->type = AUDIO_MIXER_VALUE;
2046 			dip->un.v.num_channels = 1;
2047 			strcpy(dip->un.v.units.name, "level");
2048 			return 0;
2049 
2050 		case ESS_SPATIALIZER_ENABLE:
2051 			dip->mixer_class = ESS_OUTPUT_CLASS;
2052 			dip->prev = ESS_SPATIALIZER;
2053 			dip->next = AUDIO_MIXER_LAST;
2054 			strcpy(dip->label.name, "enable");
2055 			dip->type = AUDIO_MIXER_ENUM;
2056 			dip->un.e.num_mem = 2;
2057 			strcpy(dip->un.e.member[0].label.name, AudioNoff);
2058 			dip->un.e.member[0].ord = 0;
2059 			strcpy(dip->un.e.member[1].label.name, AudioNon);
2060 			dip->un.e.member[1].ord = 1;
2061 			return 0;
2062 		}
2063 	}
2064 
2065 	if (ESS_USE_AUDIO1(sc->sc_model))
2066 		return ENXIO;
2067 
2068 	switch (dip->index) {
2069 	case ESS_DAC_REC_VOL:
2070 		dip->mixer_class = ESS_RECORD_CLASS;
2071 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2072 		strcpy(dip->label.name, AudioNdac);
2073 		dip->type = AUDIO_MIXER_VALUE;
2074 		dip->un.v.num_channels = 2;
2075 		strcpy(dip->un.v.units.name, AudioNvolume);
2076 		return 0;
2077 
2078 	case ESS_MIC_REC_VOL:
2079 		dip->mixer_class = ESS_RECORD_CLASS;
2080 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2081 		strcpy(dip->label.name, AudioNmicrophone);
2082 		dip->type = AUDIO_MIXER_VALUE;
2083 		dip->un.v.num_channels = 2;
2084 		strcpy(dip->un.v.units.name, AudioNvolume);
2085 		return 0;
2086 
2087 	case ESS_LINE_REC_VOL:
2088 		dip->mixer_class = ESS_RECORD_CLASS;
2089 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2090 		strcpy(dip->label.name, AudioNline);
2091 		dip->type = AUDIO_MIXER_VALUE;
2092 		dip->un.v.num_channels = 2;
2093 		strcpy(dip->un.v.units.name, AudioNvolume);
2094 		return 0;
2095 
2096 	case ESS_SYNTH_REC_VOL:
2097 		dip->mixer_class = ESS_RECORD_CLASS;
2098 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2099 		strcpy(dip->label.name, AudioNfmsynth);
2100 		dip->type = AUDIO_MIXER_VALUE;
2101 		dip->un.v.num_channels = 2;
2102 		strcpy(dip->un.v.units.name, AudioNvolume);
2103 		return 0;
2104 
2105 	case ESS_CD_REC_VOL:
2106 		dip->mixer_class = ESS_RECORD_CLASS;
2107 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2108 		strcpy(dip->label.name, AudioNcd);
2109 		dip->type = AUDIO_MIXER_VALUE;
2110 		dip->un.v.num_channels = 2;
2111 		strcpy(dip->un.v.units.name, AudioNvolume);
2112 		return 0;
2113 
2114 	case ESS_AUXB_REC_VOL:
2115 		dip->mixer_class = ESS_RECORD_CLASS;
2116 		dip->next = dip->prev = AUDIO_MIXER_LAST;
2117 		strcpy(dip->label.name, "auxb");
2118 		dip->type = AUDIO_MIXER_VALUE;
2119 		dip->un.v.num_channels = 2;
2120 		strcpy(dip->un.v.units.name, AudioNvolume);
2121 		return 0;
2122 
2123 	case ESS_MIC_PREAMP:
2124 		dip->mixer_class = ESS_INPUT_CLASS;
2125 		dip->prev = ESS_MIC_PLAY_VOL;
2126 		dip->next = AUDIO_MIXER_LAST;
2127 		strcpy(dip->label.name, AudioNpreamp);
2128 		dip->type = AUDIO_MIXER_ENUM;
2129 		dip->un.e.num_mem = 2;
2130 		strcpy(dip->un.e.member[0].label.name, AudioNoff);
2131 		dip->un.e.member[0].ord = 0;
2132 		strcpy(dip->un.e.member[1].label.name, AudioNon);
2133 		dip->un.e.member[1].ord = 1;
2134 		return 0;
2135 	}
2136 
2137 	return ENXIO;
2138 }
2139 
2140 void *
ess_malloc(void * addr,int direction,size_t size)2141 ess_malloc(void *addr, int direction, size_t size)
2142 {
2143 	struct ess_softc *sc;
2144 	int drq;
2145 
2146 	sc = addr;
2147 	if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
2148 		drq = sc->sc_audio2.drq;
2149 	else
2150 		drq = sc->sc_audio1.drq;
2151 	return (isa_malloc(sc->sc_ic, drq, size, M_DEVBUF, M_WAITOK));
2152 }
2153 
2154 void
ess_free(void * addr,void * ptr,size_t size)2155 ess_free(void *addr, void *ptr, size_t size)
2156 {
2157 
2158 	isa_free(ptr, M_DEVBUF);
2159 }
2160 
2161 size_t
ess_round_buffersize(void * addr,int direction,size_t size)2162 ess_round_buffersize(void *addr, int direction, size_t size)
2163 {
2164 	struct ess_softc *sc;
2165 	bus_size_t maxsize;
2166 
2167 	sc = addr;
2168 	if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
2169 		maxsize = sc->sc_audio2.maxsize;
2170 	else
2171 		maxsize = sc->sc_audio1.maxsize;
2172 
2173 	if (size > maxsize)
2174 		size = maxsize;
2175 	return size;
2176 }
2177 
2178 int
ess_1788_get_props(void * addr)2179 ess_1788_get_props(void *addr)
2180 {
2181 
2182 	return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE;
2183 }
2184 
2185 int
ess_1888_get_props(void * addr)2186 ess_1888_get_props(void *addr)
2187 {
2188 
2189 	return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE |
2190 	    AUDIO_PROP_FULLDUPLEX;
2191 }
2192 
2193 void
ess_get_locks(void * addr,kmutex_t ** intr,kmutex_t ** thread)2194 ess_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread)
2195 {
2196 	struct ess_softc *sc;
2197 
2198 	sc = addr;
2199 	*intr = &sc->sc_intr_lock;
2200 	*thread = &sc->sc_lock;
2201 }
2202 
2203 
2204 /* ============================================
2205  * Generic functions for ess, not used by audio h/w i/f
2206  * =============================================
2207  */
2208 
2209 /*
2210  * Reset the chip.
2211  * Return non-zero if the chip isn't detected.
2212  */
2213 int
ess_reset(struct ess_softc * sc)2214 ess_reset(struct ess_softc *sc)
2215 {
2216 	bus_space_tag_t iot;
2217 	bus_space_handle_t ioh;
2218 
2219 	iot = sc->sc_iot;
2220 	ioh = sc->sc_ioh;
2221 	sc->sc_audio1.active = 0;
2222 	sc->sc_audio2.active = 0;
2223 
2224 	EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
2225 	delay(10000);		/* XXX shouldn't delay so long */
2226 	EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
2227 	if (ess_rdsp(sc) != ESS_MAGIC)
2228 		return 1;
2229 
2230 	/* Enable access to the ESS extension commands. */
2231 	ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
2232 
2233 	return 0;
2234 }
2235 
2236 void
ess_set_gain(struct ess_softc * sc,int port,int on)2237 ess_set_gain(struct ess_softc *sc, int port, int on)
2238 {
2239 	int gain, left, right;
2240 	int mix;
2241 	int src;
2242 	int stereo;
2243 
2244 	/*
2245 	 * Most gain controls are found in the mixer registers and
2246 	 * are stereo. Any that are not, must set mix and stereo as
2247 	 * required.
2248 	 */
2249 	mix = 1;
2250 	stereo = 1;
2251 
2252 	if (ESS_IS_ES18X9(sc->sc_model)) {
2253 		switch (port) {
2254 		case ESS_SPATIALIZER:
2255 			src = ESS_MREG_SPATIAL_LEVEL;
2256 			stereo = -1;
2257 			goto skip;
2258 		case ESS_SPATIALIZER_ENABLE:
2259 			return;
2260 		}
2261 	}
2262 	switch (port) {
2263 	case ESS_MASTER_VOL:
2264 		src = ESS_MREG_VOLUME_MASTER;
2265 		break;
2266 	case ESS_DAC_PLAY_VOL:
2267 		if (ESS_USE_AUDIO1(sc->sc_model))
2268 			src = ESS_MREG_VOLUME_VOICE;
2269 		else
2270 			src = 0x7C;
2271 		break;
2272 	case ESS_MIC_PLAY_VOL:
2273 		src = ESS_MREG_VOLUME_MIC;
2274 		break;
2275 	case ESS_LINE_PLAY_VOL:
2276 		src = ESS_MREG_VOLUME_LINE;
2277 		break;
2278 	case ESS_SYNTH_PLAY_VOL:
2279 		src = ESS_MREG_VOLUME_SYNTH;
2280 		break;
2281 	case ESS_CD_PLAY_VOL:
2282 		src = ESS_MREG_VOLUME_CD;
2283 		break;
2284 	case ESS_AUXB_PLAY_VOL:
2285 		src = ESS_MREG_VOLUME_AUXB;
2286 		break;
2287 	case ESS_PCSPEAKER_VOL:
2288 		src = ESS_MREG_VOLUME_PCSPKR;
2289 		stereo = 0;
2290 		break;
2291 	case ESS_DAC_REC_VOL:
2292 		src = 0x69;
2293 		break;
2294 	case ESS_MIC_REC_VOL:
2295 		src = 0x68;
2296 		break;
2297 	case ESS_LINE_REC_VOL:
2298 		src = 0x6E;
2299 		break;
2300 	case ESS_SYNTH_REC_VOL:
2301 		src = 0x6B;
2302 		break;
2303 	case ESS_CD_REC_VOL:
2304 		src = 0x6A;
2305 		break;
2306 	case ESS_AUXB_REC_VOL:
2307 		src = 0x6C;
2308 		break;
2309 	case ESS_RECORD_VOL:
2310 		src = ESS_XCMD_VOLIN_CTRL;
2311 		mix = 0;
2312 		break;
2313 	default:
2314 		return;
2315 	}
2316 skip:
2317 
2318 	/* 1788 doesn't have a separate recording mixer */
2319 	if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
2320 		return;
2321 
2322 	if (on) {
2323 		left = sc->gain[port][ESS_LEFT];
2324 		right = sc->gain[port][ESS_RIGHT];
2325 	} else {
2326 		left = right = 0;
2327 	}
2328 
2329 	if (stereo == -1)
2330 		gain = ESS_SPATIAL_GAIN(left);
2331 	else if (stereo)
2332 		gain = ESS_STEREO_GAIN(left, right);
2333 	else
2334 		gain = ESS_MONO_GAIN(left);
2335 
2336 	if (mix)
2337 		ess_write_mix_reg(sc, src, gain);
2338 	else
2339 		ess_write_x_reg(sc, src, gain);
2340 }
2341 
2342 /* Set the input device on devices without an input mixer. */
2343 int
ess_set_in_port(struct ess_softc * sc,int ord)2344 ess_set_in_port(struct ess_softc *sc, int ord)
2345 {
2346 	mixer_devinfo_t di;
2347 	int i;
2348 
2349 	DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
2350 
2351 	/*
2352 	 * Get the device info for the record source control,
2353 	 * including the list of available sources.
2354 	 */
2355 	di.index = ESS_RECORD_SOURCE;
2356 	if (ess_query_devinfo(sc, &di))
2357 		return EINVAL;
2358 
2359 	/* See if the given ord value was anywhere in the list. */
2360 	for (i = 0; i < di.un.e.num_mem; i++) {
2361 		if (ord == di.un.e.member[i].ord)
2362 			break;
2363 	}
2364 	if (i == di.un.e.num_mem)
2365 		return EINVAL;
2366 
2367 	ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
2368 
2369 	sc->in_port = ord;
2370 	return 0;
2371 }
2372 
2373 /* Set the input device levels on input-mixer-enabled devices. */
2374 int
ess_set_in_ports(struct ess_softc * sc,int mask)2375 ess_set_in_ports(struct ess_softc *sc, int mask)
2376 {
2377 	mixer_devinfo_t di;
2378 	int i, port;
2379 
2380 	DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
2381 
2382 	/*
2383 	 * Get the device info for the record source control,
2384 	 * including the list of available sources.
2385 	 */
2386 	di.index = ESS_RECORD_SOURCE;
2387 	if (ess_query_devinfo(sc, &di))
2388 		return EINVAL;
2389 
2390 	/*
2391 	 * Set or disable the record volume control for each of the
2392 	 * possible sources.
2393 	 */
2394 	for (i = 0; i < di.un.s.num_mem; i++) {
2395 		/*
2396 		 * Calculate the source port number from its mask.
2397 		 */
2398 		port = ffs(di.un.s.member[i].mask);
2399 
2400 		/*
2401 		 * Set the source gain:
2402 		 *	to the current value if source is enabled
2403 		 *	to zero if source is disabled
2404 		 */
2405 		ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
2406 	}
2407 
2408 	sc->in_mask = mask;
2409 	return 0;
2410 }
2411 
2412 void
ess_speaker_on(struct ess_softc * sc)2413 ess_speaker_on(struct ess_softc *sc)
2414 {
2415 
2416 	/* Unmute the DAC. */
2417 	ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
2418 }
2419 
2420 void
ess_speaker_off(struct ess_softc * sc)2421 ess_speaker_off(struct ess_softc *sc)
2422 {
2423 
2424 	/* Mute the DAC. */
2425 	ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
2426 }
2427 
2428 /*
2429  * Calculate the time constant for the requested sampling rate.
2430  */
2431 u_int
ess_srtotc(struct ess_softc * sc,u_int rate)2432 ess_srtotc(struct ess_softc *sc, u_int rate)
2433 {
2434 	u_int tc;
2435 
2436 	/* The following formulae are from the ESS data sheet. */
2437 	if (ESS_IS_ES18X9(sc->sc_model)) {
2438 		if ((rate % 8000) != 0)
2439 			tc = 128 - 793800L / rate;
2440 		else
2441 			tc = 256 - 768000L / rate;
2442 	} else {
2443 		if (rate <= 22050)
2444 			tc = 128 - 397700L / rate;
2445 		else
2446 			tc = 256 - 795500L / rate;
2447 	}
2448 
2449 	return tc;
2450 }
2451 
2452 
2453 /*
2454  * Calculate the filter constant for the requested sampling rate.
2455  */
2456 u_int
ess_srtofc(u_int rate)2457 ess_srtofc(u_int rate)
2458 {
2459 	/*
2460 	 * The following formula is derived from the information in
2461 	 * the ES1887 data sheet, based on a roll-off frequency of
2462 	 * 87%.
2463 	 */
2464 	return 256 - 200279L / rate;
2465 }
2466 
2467 
2468 /*
2469  * Return the status of the DSP.
2470  */
2471 u_char
ess_get_dsp_status(struct ess_softc * sc)2472 ess_get_dsp_status(struct ess_softc *sc)
2473 {
2474 	return EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
2475 }
2476 
2477 
2478 /*
2479  * Return the read status of the DSP:	1 -> DSP ready for reading
2480  *					0 -> DSP not ready for reading
2481  */
2482 u_char
ess_dsp_read_ready(struct ess_softc * sc)2483 ess_dsp_read_ready(struct ess_softc *sc)
2484 {
2485 
2486 	return (ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0;
2487 }
2488 
2489 
2490 /*
2491  * Return the write status of the DSP:	1 -> DSP ready for writing
2492  *					0 -> DSP not ready for writing
2493  */
2494 u_char
ess_dsp_write_ready(struct ess_softc * sc)2495 ess_dsp_write_ready(struct ess_softc *sc)
2496 {
2497 	return (ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1;
2498 }
2499 
2500 
2501 /*
2502  * Read a byte from the DSP.
2503  */
2504 int
ess_rdsp(struct ess_softc * sc)2505 ess_rdsp(struct ess_softc *sc)
2506 {
2507 	bus_space_tag_t iot;
2508 	bus_space_handle_t ioh;
2509 	int i;
2510 
2511 	iot = sc->sc_iot;
2512 	ioh = sc->sc_ioh;
2513 	for (i = ESS_READ_TIMEOUT; i > 0; --i) {
2514 		if (ess_dsp_read_ready(sc)) {
2515 			i = EREAD1(iot, ioh, ESS_DSP_READ);
2516 			DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
2517 			return i;
2518 		} else
2519 			delay(10);
2520 	}
2521 
2522 	DPRINTF(("ess_rdsp: timed out\n"));
2523 	return -1;
2524 }
2525 
2526 /*
2527  * Write a byte to the DSP.
2528  */
2529 int
ess_wdsp(struct ess_softc * sc,u_char v)2530 ess_wdsp(struct ess_softc *sc, u_char v)
2531 {
2532 	bus_space_tag_t iot;
2533 	bus_space_handle_t ioh;
2534 	int i;
2535 
2536 	DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
2537 
2538 	iot = sc->sc_iot;
2539 	ioh = sc->sc_ioh;
2540 	for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
2541 		if (ess_dsp_write_ready(sc)) {
2542 			EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
2543 			return 0;
2544 		} else
2545 			delay(10);
2546 	}
2547 
2548 	DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
2549 	return -1;
2550 }
2551 
2552 /*
2553  * Write a value to one of the ESS extended registers.
2554  */
2555 int
ess_write_x_reg(struct ess_softc * sc,u_char reg,u_char val)2556 ess_write_x_reg(struct ess_softc *sc, u_char reg, u_char val)
2557 {
2558 	int error;
2559 
2560 	DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
2561 	if ((error = ess_wdsp(sc, reg)) == 0)
2562 		error = ess_wdsp(sc, val);
2563 
2564 	return error;
2565 }
2566 
2567 /*
2568  * Read the value of one of the ESS extended registers.
2569  */
2570 u_char
ess_read_x_reg(struct ess_softc * sc,u_char reg)2571 ess_read_x_reg(struct ess_softc *sc, u_char reg)
2572 {
2573 	int error;
2574 	int val;
2575 
2576 	if ((error = ess_wdsp(sc, 0xC0)) == 0)
2577 		error = ess_wdsp(sc, reg);
2578 	if (error) {
2579 		DPRINTF(("Error reading extended register 0x%02x\n", reg));
2580 	}
2581 /* REVISIT: what if an error is returned above? */
2582 	val = ess_rdsp(sc);
2583 	DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
2584 	return val;
2585 }
2586 
2587 void
ess_clear_xreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2588 ess_clear_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2589 {
2590 	if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1) {
2591 		DPRINTF(("Error clearing bits in extended register 0x%02x\n",
2592 			 reg));
2593 	}
2594 }
2595 
2596 void
ess_set_xreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2597 ess_set_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2598 {
2599 	if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1) {
2600 		DPRINTF(("Error setting bits in extended register 0x%02x\n",
2601 			 reg));
2602 	}
2603 }
2604 
2605 
2606 /*
2607  * Write a value to one of the ESS mixer registers.
2608  */
2609 void
ess_write_mix_reg(struct ess_softc * sc,u_char reg,u_char val)2610 ess_write_mix_reg(struct ess_softc *sc, u_char reg, u_char val)
2611 {
2612 	bus_space_tag_t iot;
2613 	bus_space_handle_t ioh;
2614 
2615 	DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
2616 
2617 	iot = sc->sc_iot;
2618 	ioh = sc->sc_ioh;
2619 	EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2620 	EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
2621 }
2622 
2623 /*
2624  * Read the value of one of the ESS mixer registers.
2625  */
2626 u_char
ess_read_mix_reg(struct ess_softc * sc,u_char reg)2627 ess_read_mix_reg(struct ess_softc *sc, u_char reg)
2628 {
2629 	bus_space_tag_t iot;
2630 	bus_space_handle_t ioh;
2631 	u_char val;
2632 
2633 	iot = sc->sc_iot;
2634 	ioh = sc->sc_ioh;
2635 	EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2636 	val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
2637 
2638 	DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
2639 	return val;
2640 }
2641 
2642 void
ess_clear_mreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2643 ess_clear_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2644 {
2645 
2646 	ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
2647 }
2648 
2649 void
ess_set_mreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2650 ess_set_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2651 {
2652 
2653 	ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
2654 }
2655 
2656 void
ess_read_multi_mix_reg(struct ess_softc * sc,u_char reg,uint8_t * datap,bus_size_t count)2657 ess_read_multi_mix_reg(struct ess_softc *sc, u_char reg,
2658 		       uint8_t *datap, bus_size_t count)
2659 {
2660 	bus_space_tag_t iot;
2661 	bus_space_handle_t ioh;
2662 
2663 	iot = sc->sc_iot;
2664 	ioh = sc->sc_ioh;
2665 	EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2666 	bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
2667 }
2668