eso.c revision 1.1
1/*	$OpenBSD: eso.c,v 1.1 1999/08/04 23:38:03 niklas Exp $	*/
2/*	$NetBSD: eso.c,v 1.3 1999/08/02 17:37:43 augustss Exp $	*/
3
4/*
5 * Copyright (c) 1999 Klaus J. Klein
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * ESS Technology Inc. Solo-1 PCI AudioDrive (ES1938/1946) device driver.
34 */
35
36#ifdef __OpenBSD__
37#define HIDE
38#define MATCH_ARG_2_T void *
39#else
40#define HIDE static
41#define MATCH_ARG_2_T struct cfdata *
42#endif
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/malloc.h>
48#include <sys/device.h>
49#include <sys/proc.h>
50
51#include <dev/pci/pcidevs.h>
52#include <dev/pci/pcivar.h>
53
54#include <sys/audioio.h>
55#include <dev/audio_if.h>
56#include <dev/midi_if.h>
57
58#include <dev/mulaw.h>
59#include <dev/auconv.h>
60
61#ifdef __OpenBSD__
62#include <dev/isa/mpu401var.h> /* XXX should not be ISA! */
63#else
64#include <dev/ic/mpuvar.h>
65#endif
66#include <dev/ic/i8237reg.h>
67#include <dev/pci/esoreg.h>
68#include <dev/pci/esovar.h>
69
70#include <machine/bus.h>
71#include <machine/intr.h>
72
73#ifdef __OpenBSD__
74#include <machine/endian.h>
75#define htopci(x) htole32(x)
76#define pcitoh(x) letoh32(x)
77#else
78#if BYTE_ORDER == BIG_ENDIAN
79#include <machine/bswap.h>
80#define htopci(x) bswap32(x)
81#define pcitoh(x) bswap32(x)
82#else
83#define htopci(x) (x)
84#define pcitoh(x) (x)
85#endif
86#endif
87
88#if defined(AUDIO_DEBUG) || defined(DEBUG)
89#define DPRINTF(x) printf x
90#else
91#define DPRINTF(x)
92#endif
93
94struct eso_dma {
95	bus_dmamap_t		ed_map;
96	caddr_t			ed_addr;
97	bus_dma_segment_t	ed_segs[1];
98	int			ed_nsegs;
99	size_t			ed_size;
100	struct eso_dma *	ed_next;
101};
102
103#define KVADDR(dma)	((void *)(dma)->ed_addr)
104#define DMAADDR(dma)	((dma)->ed_map->dm_segs[0].ds_addr)
105
106/* Autoconfiguration interface */
107HIDE int eso_match __P((struct device *, MATCH_ARG_2_T, void *));
108HIDE void eso_attach __P((struct device *, struct device *, void *));
109HIDE void eso_defer __P((struct device *));
110
111struct cfattach eso_ca = {
112	sizeof (struct eso_softc), eso_match, eso_attach
113};
114
115#ifdef __OpenBSD__
116struct cfdriver eso_cd = {
117	NULL, "eso", DV_DULL
118};
119#endif
120
121/* PCI interface */
122HIDE int eso_intr __P((void *));
123
124/* MI audio layer interface */
125HIDE int	eso_open __P((void *, int));
126HIDE void	eso_close __P((void *));
127HIDE int	eso_query_encoding __P((void *, struct audio_encoding *));
128HIDE int	eso_set_params __P((void *, int, int, struct audio_params *,
129		    struct audio_params *));
130HIDE int	eso_round_blocksize __P((void *, int));
131HIDE int	eso_halt_output __P((void *));
132HIDE int	eso_halt_input __P((void *));
133HIDE int	eso_getdev __P((void *, struct audio_device *));
134HIDE int	eso_set_port __P((void *, mixer_ctrl_t *));
135HIDE int	eso_get_port __P((void *, mixer_ctrl_t *));
136HIDE int	eso_query_devinfo __P((void *, mixer_devinfo_t *));
137#ifdef __OpenBSD__
138void *		eso_allocm __P((void *, u_long, int, int));
139#else
140HIDE void *	eso_allocm __P((void *, int, size_t, int, int));
141#endif
142HIDE void	eso_freem __P((void *, void *, int));
143#ifdef __OpenBSD__
144u_long		eso_round_buffersize __P((void *, u_long));
145#else
146HIDE size_t	eso_round_buffersize __P((void *, int, size_t));
147#endif
148HIDE int	eso_mappage __P((void *, void *, int, int));
149HIDE int	eso_get_props __P((void *));
150HIDE int	eso_trigger_output __P((void *, void *, void *, int,
151		    void (*)(void *), void *, struct audio_params *));
152HIDE int	eso_trigger_input __P((void *, void *, void *, int,
153		    void (*)(void *), void *, struct audio_params *));
154
155HIDE struct audio_hw_if eso_hw_if = {
156	eso_open,
157	eso_close,
158	NULL,			/* drain */
159	eso_query_encoding,
160	eso_set_params,
161	eso_round_blocksize,
162	NULL,			/* commit_settings */
163	NULL,			/* init_output */
164	NULL,			/* init_input */
165	NULL,			/* start_output */
166	NULL,			/* start_input */
167	eso_halt_output,
168	eso_halt_input,
169	NULL,			/* speaker_ctl */
170	eso_getdev,
171	NULL,			/* setfd */
172	eso_set_port,
173	eso_get_port,
174	eso_query_devinfo,
175	eso_allocm,
176	eso_freem,
177	eso_round_buffersize,
178	eso_mappage,
179	eso_get_props,
180	eso_trigger_output,
181	eso_trigger_input
182};
183
184HIDE const char * const eso_rev2model[] = {
185	"ES1938",
186	"ES1946"
187};
188
189
190/*
191 * Utility routines
192 */
193/* Register access etc. */
194HIDE uint8_t	eso_read_ctlreg __P((struct eso_softc *, uint8_t));
195HIDE uint8_t	eso_read_mixreg __P((struct eso_softc *, uint8_t));
196HIDE uint8_t	eso_read_rdr __P((struct eso_softc *));
197HIDE int	eso_reset __P((struct eso_softc *));
198HIDE void	eso_set_gain __P((struct eso_softc *, unsigned int));
199HIDE int	eso_set_recsrc __P((struct eso_softc *, unsigned int));
200HIDE void	eso_write_cmd __P((struct eso_softc *, uint8_t));
201HIDE void	eso_write_ctlreg __P((struct eso_softc *, uint8_t, uint8_t));
202HIDE void	eso_write_mixreg __P((struct eso_softc *, uint8_t, uint8_t));
203/* DMA memory allocation */
204HIDE int	eso_allocmem __P((struct eso_softc *, size_t, size_t, size_t,
205		    int, struct eso_dma *));
206HIDE void	eso_freemem __P((struct eso_softc *, struct eso_dma *));
207
208
209HIDE int
210eso_match(parent, match, aux)
211	struct device *parent;
212	MATCH_ARG_2_T match;
213	void *aux;
214{
215	struct pci_attach_args *pa = aux;
216
217	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ESSTECH &&
218	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ESSTECH_SOLO1)
219		return (1);
220
221	return (0);
222}
223
224HIDE void
225eso_attach(parent, self, aux)
226	struct device *parent, *self;
227	void *aux;
228{
229	struct eso_softc *sc = (struct eso_softc *)self;
230	struct pci_attach_args *pa = aux;
231	struct audio_attach_args aa;
232	pci_intr_handle_t ih;
233	bus_addr_t vcbase;
234	const char *intrstring;
235	int idx;
236	uint8_t a2mode;
237
238	sc->sc_revision = PCI_REVISION(pa->pa_class);
239
240	printf(": ESS Solo-1 PCI AudioDrive ");
241	if (sc->sc_revision <=
242	    sizeof (eso_rev2model) / sizeof (eso_rev2model[0]))
243		printf("%s\n", eso_rev2model[sc->sc_revision]);
244	else
245		printf("(unknown rev. 0x%02x)\n", sc->sc_revision);
246
247	/* Map I/O registers. */
248	if (pci_mapreg_map(pa, ESO_PCI_BAR_IO, PCI_MAPREG_TYPE_IO, 0,
249	    &sc->sc_iot, &sc->sc_ioh, NULL, NULL)) {
250		printf("%s: can't map I/O space\n", sc->sc_dev.dv_xname);
251		return;
252	}
253	if (pci_mapreg_map(pa, ESO_PCI_BAR_SB, PCI_MAPREG_TYPE_IO, 0,
254	    &sc->sc_sb_iot, &sc->sc_sb_ioh, NULL, NULL)) {
255		printf("%s: can't map SB I/O space\n", sc->sc_dev.dv_xname);
256		return;
257	}
258	if (pci_mapreg_map(pa, ESO_PCI_BAR_VC, PCI_MAPREG_TYPE_IO, 0,
259	    &sc->sc_dmac_iot, &sc->sc_dmac_ioh, &vcbase, &sc->sc_vcsize)) {
260		printf("%s: can't map VC I/O space\n", sc->sc_dev.dv_xname);
261		/* Don't bail out yet: we can map it later, see below. */
262		vcbase = 0;
263		sc->sc_vcsize = 0x10; /* From the data sheet. */
264	}
265
266	if (pci_mapreg_map(pa, ESO_PCI_BAR_MPU, PCI_MAPREG_TYPE_IO, 0,
267	    &sc->sc_mpu_iot, &sc->sc_mpu_ioh, NULL, NULL)) {
268		printf("%s: can't map MPU I/O space\n", sc->sc_dev.dv_xname);
269		return;
270	}
271	if (pci_mapreg_map(pa, ESO_PCI_BAR_GAME, PCI_MAPREG_TYPE_IO, 0,
272	    &sc->sc_game_iot, &sc->sc_game_ioh, NULL, NULL)) {
273		printf("%s: can't map Game I/O space\n", sc->sc_dev.dv_xname);
274		return;
275	}
276
277	sc->sc_dmat = pa->pa_dmat;
278	sc->sc_dmas = NULL;
279	sc->sc_dmac_configured = 0;
280
281	/* Enable bus mastering. */
282	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
283	    pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
284	    PCI_COMMAND_MASTER_ENABLE);
285
286	/* Reset the device; bail out upon failure. */
287	if (eso_reset(sc) != 0) {
288		printf("%s: can't reset\n", sc->sc_dev.dv_xname);
289		return;
290	}
291
292	/* Select the DMA/IRQ policy: DDMA, ISA IRQ emulation disabled. */
293	pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C,
294	    pci_conf_read(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C) &
295	    ~(ESO_PCI_S1C_IRQP_MASK | ESO_PCI_S1C_DMAP_MASK));
296
297	/* Enable the relevant DMA interrupts. */
298	bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL,
299	    ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ);
300
301	/* Set up A1's sample rate generator for new-style parameters. */
302	a2mode = eso_read_mixreg(sc, ESO_MIXREG_A2MODE);
303	a2mode |= ESO_MIXREG_A2MODE_NEWA1 | ESO_MIXREG_A2MODE_ASYNC;
304	eso_write_mixreg(sc, ESO_MIXREG_A2MODE, a2mode);
305
306	/* Set mixer regs to something reasonable, needs work. */
307	for (idx = 0; idx < ESO_NGAINDEVS; idx++) {
308		int v;
309
310		switch (idx) {
311 		case ESO_MIC_PLAY_VOL:
312		case ESO_LINE_PLAY_VOL:
313		case ESO_CD_PLAY_VOL:
314		case ESO_MONO_PLAY_VOL:
315		case ESO_AUXB_PLAY_VOL:
316		case ESO_DAC_REC_VOL:
317		case ESO_LINE_REC_VOL:
318		case ESO_SYNTH_REC_VOL:
319		case ESO_CD_REC_VOL:
320		case ESO_MONO_REC_VOL:
321		case ESO_AUXB_REC_VOL:
322		case ESO_SPATIALIZER:
323			v = 0;
324			break;
325		case ESO_MASTER_VOL:
326			v = ESO_GAIN_TO_6BIT(AUDIO_MAX_GAIN / 2);
327			break;
328		default:
329			v = ESO_GAIN_TO_4BIT(AUDIO_MAX_GAIN / 2);
330			break;
331		}
332		sc->sc_gain[idx][ESO_LEFT] = sc->sc_gain[idx][ESO_RIGHT] = v;
333		eso_set_gain(sc, idx);
334	}
335	eso_set_recsrc(sc, ESO_MIXREG_ERS_MIC);
336
337	/* Map and establish the interrupt. */
338	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
339	    pa->pa_intrline, &ih)) {
340		printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
341		return;
342	}
343	intrstring = pci_intr_string(pa->pa_pc, ih);
344#ifdef __OpenBSD__
345	sc->sc_ih  = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, eso_intr, sc,
346	    sc->sc_dev.dv_xname);
347#else
348	sc->sc_ih  = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, eso_intr, sc);
349#endif
350	if (sc->sc_ih == NULL) {
351		printf("%s: couldn't establish interrupt",
352		    sc->sc_dev.dv_xname);
353		if (intrstring != NULL)
354			printf(" at %s", intrstring);
355		printf("\n");
356		return;
357	}
358	printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstring);
359
360	/*
361	 * Set up the DDMA Control register; a suitable I/O region has been
362	 * supposedly mapped in the VC base address register.
363	 *
364	 * The Solo-1 has an ... interesting silicon bug that causes it to
365	 * not respond to I/O space accesses to the Audio 1 DMA controller
366	 * if the latter's mapping base address is aligned on a 1K boundary.
367	 * As a consequence, it is quite possible for the mapping provided
368	 * in the VC BAR to be useless.  To work around this, we defer this
369	 * part until all autoconfiguration on our parent bus is completed
370	 * and then try to map it ourselves in fulfillment of the constraint.
371	 *
372	 * According to the register map we may write to the low 16 bits
373	 * only, but experimenting has shown we're safe.
374	 * -kjk
375	 */
376	if (ESO_VALID_DDMAC_BASE(vcbase)) {
377		pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC,
378		    vcbase | ESO_PCI_DDMAC_DE);
379		sc->sc_dmac_configured = 1;
380
381		printf("%s: mapping Audio 1 DMA using VC I/O space at 0x%lx\n",
382		    sc->sc_dev.dv_xname, (unsigned long)vcbase);
383	} else {
384		DPRINTF(("%s: VC I/O space at 0x%lx not suitable, deferring\n",
385		    sc->sc_dev.dv_xname, (unsigned long)vcbase));
386		sc->sc_pa = *pa;
387#ifdef __OpenBSD__
388		panic("config_defer not implemented");
389#else
390		config_defer(self, eso_defer);
391#endif
392	}
393
394	audio_attach_mi(&eso_hw_if, sc, &sc->sc_dev);
395
396	aa.type = AUDIODEV_TYPE_OPL;
397	aa.hwif = NULL;
398	aa.hdl = NULL;
399	(void)config_found(&sc->sc_dev, &aa, audioprint);
400
401#if 0
402	aa.type = AUDIODEV_TYPE_MPU;
403	aa.hwif = NULL;
404	aa.hdl = NULL;
405	sc->sc_mpudev = config_found(&sc->sc_dev, &aa, audioprint);
406#endif
407}
408
409HIDE void
410eso_defer(self)
411	struct device *self;
412{
413	struct eso_softc *sc = (struct eso_softc *)self;
414	struct pci_attach_args *pa = &sc->sc_pa;
415	bus_addr_t addr, start;
416
417	printf("%s: ", sc->sc_dev.dv_xname);
418
419	/*
420	 * This is outright ugly, but since we must not make assumptions
421	 * on the underlying allocator's behaviour it's the most straight-
422	 * forward way to implement it.  Note that we skip over the first
423	 * 1K region, which is typically occupied by an attached ISA bus.
424	 */
425	for (start = 0x0400; start < 0xffff; start += 0x0400) {
426		if (bus_space_alloc(sc->sc_iot,
427		    start + sc->sc_vcsize, start + 0x0400 - 1,
428		    sc->sc_vcsize, sc->sc_vcsize, 0, 0, &addr,
429		    &sc->sc_dmac_ioh) != 0)
430			continue;
431
432		pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC,
433		    addr | ESO_PCI_DDMAC_DE);
434		sc->sc_dmac_iot = sc->sc_iot;
435		sc->sc_dmac_configured = 1;
436		printf("mapping Audio 1 DMA using I/O space at 0x%lx\n",
437		    (unsigned long)addr);
438
439		return;
440	}
441
442	printf("can't map Audio 1 DMA into I/O space\n");
443}
444
445HIDE void
446eso_write_cmd(sc, cmd)
447	struct eso_softc *sc;
448	uint8_t cmd;
449{
450	int i;
451
452	/* Poll for busy indicator to become clear. */
453	for (i = 0; i < ESO_WDR_TIMEOUT; i++) {
454		if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RSR)
455		    & ESO_SB_RSR_BUSY) == 0) {
456			bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh,
457			    ESO_SB_WDR, cmd);
458			return;
459		} else {
460			delay(10);
461		}
462	}
463
464	printf("%s: WDR timeout\n", sc->sc_dev.dv_xname);
465	return;
466}
467
468/* Write to a controller register */
469HIDE void
470eso_write_ctlreg(sc, reg, val)
471	struct eso_softc *sc;
472	uint8_t reg, val;
473{
474
475	/* DPRINTF(("ctlreg 0x%02x = 0x%02x\n", reg, val)); */
476
477	eso_write_cmd(sc, reg);
478	eso_write_cmd(sc, val);
479}
480
481/* Read out the Read Data Register */
482HIDE uint8_t
483eso_read_rdr(sc)
484	struct eso_softc *sc;
485{
486	int i;
487
488	for (i = 0; i < ESO_RDR_TIMEOUT; i++) {
489		if (bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
490		    ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) {
491			return (bus_space_read_1(sc->sc_sb_iot,
492			    sc->sc_sb_ioh, ESO_SB_RDR));
493		} else {
494			delay(10);
495		}
496	}
497
498	printf("%s: RDR timeout\n", sc->sc_dev.dv_xname);
499	return (-1);
500}
501
502
503HIDE uint8_t
504eso_read_ctlreg(sc, reg)
505	struct eso_softc *sc;
506	uint8_t reg;
507{
508
509	eso_write_cmd(sc, ESO_CMD_RCR);
510	eso_write_cmd(sc, reg);
511	return (eso_read_rdr(sc));
512}
513
514HIDE void
515eso_write_mixreg(sc, reg, val)
516	struct eso_softc *sc;
517	uint8_t reg, val;
518{
519	int s;
520
521	/* DPRINTF(("mixreg 0x%02x = 0x%02x\n", reg, val)); */
522
523	s = splaudio();
524	bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg);
525	bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA, val);
526	splx(s);
527}
528
529HIDE uint8_t
530eso_read_mixreg(sc, reg)
531	struct eso_softc *sc;
532	uint8_t reg;
533{
534	int s;
535	uint8_t val;
536
537	s = splaudio();
538	bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg);
539	val = bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA);
540	splx(s);
541
542	return (val);
543}
544
545HIDE int
546eso_intr(hdl)
547	void *hdl;
548{
549	struct eso_softc *sc = hdl;
550	uint8_t irqctl;
551
552	irqctl = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL);
553
554	/* If it wasn't ours, that's all she wrote. */
555	if ((irqctl & (ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ)) == 0)
556		return (0);
557
558	if (irqctl & ESO_IO_IRQCTL_A1IRQ) {
559		/* Clear interrupt. */
560		(void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
561		    ESO_SB_RBSR);
562
563		if (sc->sc_rintr)
564			sc->sc_rintr(sc->sc_rarg);
565		else
566			wakeup(&sc->sc_rintr);
567	}
568
569	if (irqctl & ESO_IO_IRQCTL_A2IRQ) {
570		/*
571		 * Clear the A2 IRQ latch: the cached value reflects the
572		 * current DAC settings with the IRQ latch bit not set.
573		 */
574		eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2);
575
576		if (sc->sc_pintr)
577			sc->sc_pintr(sc->sc_parg);
578		else
579			wakeup(&sc->sc_pintr);
580	}
581
582#if 0
583	if ((irqctl & ESO_IO_IRQCTL_MPUIRQ) && sc->sc_mpudev != 0)
584		mpu_intr(sc->sc_mpudev);
585#endif
586
587	return (1);
588}
589
590/* Perform a software reset, including DMA FIFOs. */
591HIDE int
592eso_reset(sc)
593	struct eso_softc *sc;
594{
595	int i;
596
597	bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET,
598	    ESO_SB_RESET_SW | ESO_SB_RESET_FIFO);
599	/* `Delay' suggested in the data sheet. */
600	(void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_STATUS);
601	bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET, 0);
602
603	/* Wait for reset to take effect. */
604	for (i = 0; i < ESO_RESET_TIMEOUT; i++) {
605		/* Poll for data to become available. */
606		if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
607		    ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) != 0 &&
608		    bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
609			ESO_SB_RDR) == ESO_SB_RDR_RESETMAGIC) {
610
611			/* Activate Solo-1 extension commands. */
612			eso_write_cmd(sc, ESO_CMD_EXTENB);
613			/* Reset mixer registers. */
614			eso_write_mixreg(sc, ESO_MIXREG_RESET,
615			    ESO_MIXREG_RESET_RESET);
616
617			return (0);
618		} else {
619			delay(1000);
620		}
621	}
622
623	printf("%s: reset timeout\n", sc->sc_dev.dv_xname);
624	return (-1);
625}
626
627
628/* ARGSUSED */
629HIDE int
630eso_open(hdl, flags)
631	void *hdl;
632	int flags;
633{
634	struct eso_softc *sc = hdl;
635
636	DPRINTF(("%s: open\n", sc->sc_dev.dv_xname));
637
638	sc->sc_pintr = NULL;
639	sc->sc_rintr = NULL;
640
641	return (0);
642}
643
644HIDE void
645eso_close(hdl)
646	void *hdl;
647{
648
649	DPRINTF(("%s: close\n", ((struct eso_softc *)hdl)->sc_dev.dv_xname));
650}
651
652HIDE int
653eso_query_encoding(hdl, fp)
654	void *hdl;
655	struct audio_encoding *fp;
656{
657
658	switch (fp->index) {
659	case 0:
660		strcpy(fp->name, AudioEulinear);
661		fp->encoding = AUDIO_ENCODING_ULINEAR;
662		fp->precision = 8;
663		fp->flags = 0;
664		break;
665	case 1:
666		strcpy(fp->name, AudioEmulaw);
667		fp->encoding = AUDIO_ENCODING_ULAW;
668		fp->precision = 8;
669		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
670		break;
671	case 2:
672		strcpy(fp->name, AudioEalaw);
673		fp->encoding = AUDIO_ENCODING_ALAW;
674		fp->precision = 8;
675		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
676		break;
677	case 3:
678		strcpy(fp->name, AudioEslinear);
679		fp->encoding = AUDIO_ENCODING_SLINEAR;
680		fp->precision = 8;
681		fp->flags = 0;
682		break;
683	case 4:
684		strcpy(fp->name, AudioEslinear_le);
685		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
686		fp->precision = 16;
687		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
688		break;
689	case 5:
690		strcpy(fp->name, AudioEulinear_le);
691		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
692		fp->precision = 16;
693		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
694		break;
695	case 6:
696		strcpy(fp->name, AudioEslinear_be);
697		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
698		fp->precision = 16;
699		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
700		break;
701	case 7:
702		strcpy(fp->name, AudioEulinear_be);
703		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
704		fp->precision = 16;
705		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
706		break;
707	default:
708		return (EINVAL);
709	}
710
711	return (0);
712}
713
714HIDE int
715eso_set_params(hdl, setmode, usemode, play, rec)
716	void *hdl;
717	int setmode, usemode;
718	struct audio_params *play, *rec;
719{
720	struct eso_softc *sc = hdl;
721	struct audio_params *p;
722	int mode, r[2], rd[2], clk;
723	unsigned int srg, fltdiv;
724
725	for (mode = AUMODE_RECORD; mode != -1;
726	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
727		if ((setmode & mode) == 0)
728			continue;
729
730		p = (mode == AUMODE_PLAY) ? play : rec;
731
732		if (p->sample_rate < ESO_MINRATE ||
733		    p->sample_rate > ESO_MAXRATE ||
734		    (p->precision != 8 && p->precision != 16) ||
735		    (p->channels != 1 && p->channels != 2))
736			return (EINVAL);
737
738		p->factor = 1;
739		p->sw_code = NULL;
740		switch (p->encoding) {
741		case AUDIO_ENCODING_SLINEAR_BE:
742		case AUDIO_ENCODING_ULINEAR_BE:
743			if (mode == AUMODE_PLAY && p->precision == 16)
744				p->sw_code = swap_bytes;
745			break;
746		case AUDIO_ENCODING_SLINEAR_LE:
747		case AUDIO_ENCODING_ULINEAR_LE:
748			if (mode == AUMODE_RECORD && p->precision == 16)
749				p->sw_code = swap_bytes;
750			break;
751		case AUDIO_ENCODING_ULAW:
752			if (mode == AUMODE_PLAY) {
753				p->factor = 2;
754				p->sw_code = mulaw_to_ulinear16;
755			} else {
756				p->sw_code = ulinear8_to_mulaw;
757			}
758			break;
759		case AUDIO_ENCODING_ALAW:
760			if (mode == AUMODE_PLAY) {
761				p->factor = 2;
762				p->sw_code = alaw_to_ulinear16;
763			} else {
764				p->sw_code = ulinear8_to_alaw;
765			}
766			break;
767		default:
768			return (EINVAL);
769		}
770
771		/*
772		 * We'll compute both possible sample rate dividers and pick
773		 * the one with the least error.
774		 */
775#define ABS(x) ((x) < 0 ? -(x) : (x))
776		r[0] = ESO_CLK0 /
777		    (128 - (rd[0] = 128 - ESO_CLK0 / p->sample_rate));
778		r[1] = ESO_CLK1 /
779		    (128 - (rd[1] = 128 - ESO_CLK1 / p->sample_rate));
780
781		clk = ABS(p->sample_rate - r[0]) > ABS(p->sample_rate - r[1]);
782		srg = rd[clk] | (clk == 1 ? ESO_CLK1_SELECT : 0x00);
783
784		/* Roll-off frequency of 87%, as in the ES1888 driver. */
785		fltdiv = 256 - 200279L / p->sample_rate;
786
787		/* Update to reflect the possibly inexact rate. */
788		p->sample_rate = r[clk];
789
790		if (mode == AUMODE_RECORD) {
791			/* Audio 1 */
792			DPRINTF(("A1 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv));
793			eso_write_ctlreg(sc, ESO_CTLREG_SRG, srg);
794			eso_write_ctlreg(sc, ESO_CTLREG_FLTDIV, fltdiv);
795		} else {
796			/* Audio 2 */
797			DPRINTF(("A2 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv));
798			eso_write_mixreg(sc, ESO_MIXREG_A2SRG, srg);
799			eso_write_mixreg(sc, ESO_MIXREG_A2FLTDIV, fltdiv);
800		}
801#undef ABS
802
803	}
804
805	return (0);
806}
807
808HIDE int
809eso_round_blocksize(hdl, blk)
810	void *hdl;
811	int blk;
812{
813
814	return (blk & -32);	/* keep good alignment; at least 16 req'd */
815}
816
817HIDE int
818eso_halt_output(hdl)
819	void *hdl;
820{
821	struct eso_softc *sc = hdl;
822	int error, s;
823
824	DPRINTF(("%s: halt_output\n", sc->sc_dev.dv_xname));
825
826	/*
827	 * Disable auto-initialize DMA, allowing the FIFO to drain and then
828	 * stop.  The interrupt callback pointer is cleared at this
829	 * point so that an outstanding FIFO interrupt for the remaining data
830	 * will be acknowledged without further processing.
831	 *
832	 * This does not immediately `abort' an operation in progress (c.f.
833	 * audio(9)) but is the method to leave the FIFO behind in a clean
834	 * state with the least hair.  (Besides, that item needs to be
835	 * rephrased for trigger_*()-based DMA environments.)
836	 */
837	s = splaudio();
838	eso_write_mixreg(sc, ESO_MIXREG_A2C1,
839	    ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB);
840	bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM,
841	    ESO_IO_A2DMAM_DMAENB);
842
843	sc->sc_pintr = NULL;
844	error = tsleep(&sc->sc_pintr, PCATCH | PWAIT, "esoho", hz);
845	splx(s);
846
847	/* Shut down DMA completely. */
848	eso_write_mixreg(sc, ESO_MIXREG_A2C1, 0);
849	bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 0);
850
851	return (error == EWOULDBLOCK ? 0 : error);
852}
853
854HIDE int
855eso_halt_input(hdl)
856	void *hdl;
857{
858	struct eso_softc *sc = hdl;
859	int error, s;
860
861	DPRINTF(("%s: halt_input\n", sc->sc_dev.dv_xname));
862
863	/* Just like eso_halt_output(), but for Audio 1. */
864	s = splaudio();
865	eso_write_ctlreg(sc, ESO_CTLREG_A1C2,
866	    ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC |
867	    ESO_CTLREG_A1C2_DMAENB);
868	bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE,
869	    DMA37MD_WRITE | DMA37MD_DEMAND);
870
871	sc->sc_rintr = NULL;
872	error = tsleep(&sc->sc_rintr, PCATCH | PWAIT, "esohi", hz);
873	splx(s);
874
875	/* Shut down DMA completely. */
876	eso_write_ctlreg(sc, ESO_CTLREG_A1C2,
877	    ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC);
878	bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK,
879	    ESO_DMAC_MASK_MASK);
880
881	return (error == EWOULDBLOCK ? 0 : error);
882}
883
884/* ARGSUSED */
885HIDE int
886eso_getdev(hdl, retp)
887	void *hdl;
888	struct audio_device *retp;
889{
890	struct eso_softc *sc = hdl;
891
892	strncpy(retp->name, "ESS Solo-1", sizeof (retp->name));
893#ifdef __OpenBSD__
894	/* This does not overflow. */
895	sprintf(retp->version, "0x%02x", sc->sc_revision);
896#else
897	snprintf(retp->version, sizeof (retp->version), "0x%02x",
898	    sc->sc_revision);
899#endif
900	if (sc->sc_revision <=
901	    sizeof (eso_rev2model) / sizeof (eso_rev2model[0]))
902		strncpy(retp->config, eso_rev2model[sc->sc_revision],
903		    sizeof (retp->config));
904	else
905		strncpy(retp->config, "unknown", sizeof (retp->config));
906
907	return (0);
908}
909
910HIDE int
911eso_set_port(hdl, cp)
912	void *hdl;
913	mixer_ctrl_t *cp;
914{
915	struct eso_softc *sc = hdl;
916	unsigned int lgain, rgain;
917	uint8_t tmp;
918
919	switch (cp->dev) {
920	case ESO_DAC_PLAY_VOL:
921	case ESO_MIC_PLAY_VOL:
922	case ESO_LINE_PLAY_VOL:
923	case ESO_SYNTH_PLAY_VOL:
924	case ESO_CD_PLAY_VOL:
925	case ESO_AUXB_PLAY_VOL:
926	case ESO_RECORD_VOL:
927	case ESO_DAC_REC_VOL:
928	case ESO_MIC_REC_VOL:
929	case ESO_LINE_REC_VOL:
930	case ESO_SYNTH_REC_VOL:
931	case ESO_CD_REC_VOL:
932	case ESO_AUXB_REC_VOL:
933		if (cp->type != AUDIO_MIXER_VALUE)
934			return (EINVAL);
935
936		/*
937		 * Stereo-capable mixer ports: if we get a single-channel
938		 * gain value passed in, then we duplicate it to both left
939		 * and right channels.
940		 */
941		switch (cp->un.value.num_channels) {
942		case 1:
943			lgain = rgain = ESO_GAIN_TO_4BIT(
944			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
945			break;
946		case 2:
947			lgain = ESO_GAIN_TO_4BIT(
948			    cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
949			rgain = ESO_GAIN_TO_4BIT(
950			    cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
951			break;
952		default:
953			return (EINVAL);
954		}
955
956		sc->sc_gain[cp->dev][ESO_LEFT] = lgain;
957		sc->sc_gain[cp->dev][ESO_RIGHT] = rgain;
958		eso_set_gain(sc, cp->dev);
959		break;
960
961	case ESO_MASTER_VOL:
962		if (cp->type != AUDIO_MIXER_VALUE)
963			return (EINVAL);
964
965		/* Like above, but a precision of 6 bits. */
966		switch (cp->un.value.num_channels) {
967		case 1:
968			lgain = rgain = ESO_GAIN_TO_6BIT(
969			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
970			break;
971		case 2:
972			lgain = ESO_GAIN_TO_6BIT(
973			    cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
974			rgain = ESO_GAIN_TO_6BIT(
975			    cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
976			break;
977		default:
978			return (EINVAL);
979		}
980
981		sc->sc_gain[cp->dev][ESO_LEFT] = lgain;
982		sc->sc_gain[cp->dev][ESO_RIGHT] = rgain;
983		eso_set_gain(sc, cp->dev);
984		break;
985
986	case ESO_SPATIALIZER:
987		if (cp->type != AUDIO_MIXER_VALUE ||
988		    cp->un.value.num_channels != 1)
989			return (EINVAL);
990
991		sc->sc_gain[cp->dev][ESO_LEFT] =
992		    sc->sc_gain[cp->dev][ESO_RIGHT] =
993		    ESO_GAIN_TO_6BIT(
994			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
995		eso_set_gain(sc, cp->dev);
996		break;
997
998	case ESO_MONO_PLAY_VOL:
999	case ESO_MONO_REC_VOL:
1000		if (cp->type != AUDIO_MIXER_VALUE ||
1001		    cp->un.value.num_channels != 1)
1002			return (EINVAL);
1003
1004		sc->sc_gain[cp->dev][ESO_LEFT] =
1005		    sc->sc_gain[cp->dev][ESO_RIGHT] =
1006		    ESO_GAIN_TO_4BIT(
1007			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1008		eso_set_gain(sc, cp->dev);
1009		break;
1010
1011	case ESO_PCSPEAKER_VOL:
1012		if (cp->type != AUDIO_MIXER_VALUE ||
1013		    cp->un.value.num_channels != 1)
1014			return (EINVAL);
1015
1016		sc->sc_gain[cp->dev][ESO_LEFT] =
1017		    sc->sc_gain[cp->dev][ESO_RIGHT] =
1018		    ESO_GAIN_TO_3BIT(
1019			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1020		eso_set_gain(sc, cp->dev);
1021		break;
1022
1023	case ESO_SPATIALIZER_ENABLE:
1024		if (cp->type != AUDIO_MIXER_ENUM)
1025			return (EINVAL);
1026
1027		sc->sc_spatializer = (cp->un.ord != 0);
1028
1029		tmp = eso_read_mixreg(sc, ESO_MIXREG_SPAT);
1030		if (sc->sc_spatializer)
1031			tmp |= ESO_MIXREG_SPAT_ENB;
1032		else
1033			tmp &= ~ESO_MIXREG_SPAT_ENB;
1034		eso_write_mixreg(sc, ESO_MIXREG_SPAT,
1035		    tmp | ESO_MIXREG_SPAT_RSTREL);
1036		break;
1037
1038	case ESO_MONOOUT_SOURCE:
1039		if (cp->type != AUDIO_MIXER_ENUM)
1040			return (EINVAL);
1041
1042		sc->sc_monooutsrc = cp->un.ord;
1043
1044		tmp = eso_read_mixreg(sc, ESO_MIXREG_MPM);
1045		tmp &= ~ESO_MIXREG_MPM_MOMASK;
1046		tmp |= sc->sc_monooutsrc;
1047		eso_write_mixreg(sc, ESO_MIXREG_MPM, tmp);
1048		break;
1049
1050	case ESO_RECORD_MONITOR:
1051		if (cp->type != AUDIO_MIXER_ENUM)
1052			return (EINVAL);
1053
1054		sc->sc_recmon = (cp->un.ord != 0);
1055
1056		tmp = eso_read_ctlreg(sc, ESO_CTLREG_ACTL);
1057		if (sc->sc_recmon)
1058			tmp |= ESO_CTLREG_ACTL_RECMON;
1059		else
1060			tmp &= ~ESO_CTLREG_ACTL_RECMON;
1061		eso_write_ctlreg(sc, ESO_CTLREG_ACTL, tmp);
1062		break;
1063
1064	case ESO_RECORD_SOURCE:
1065		if (cp->type != AUDIO_MIXER_ENUM)
1066			return (EINVAL);
1067
1068		return (eso_set_recsrc(sc, cp->un.ord));
1069
1070	case ESO_MIC_PREAMP:
1071		if (cp->type != AUDIO_MIXER_ENUM)
1072			return (EINVAL);
1073
1074		sc->sc_preamp = (cp->un.ord != 0);
1075
1076		tmp = eso_read_mixreg(sc, ESO_MIXREG_MPM);
1077		tmp &= ~ESO_MIXREG_MPM_RESV0;
1078		if (sc->sc_preamp)
1079			tmp |= ESO_MIXREG_MPM_PREAMP;
1080		else
1081			tmp &= ~ESO_MIXREG_MPM_PREAMP;
1082		eso_write_mixreg(sc, ESO_MIXREG_MPM, tmp);
1083		break;
1084
1085	default:
1086		return (EINVAL);
1087	}
1088
1089	return (0);
1090}
1091
1092HIDE int
1093eso_get_port(hdl, cp)
1094	void *hdl;
1095	mixer_ctrl_t *cp;
1096{
1097	struct eso_softc *sc = hdl;
1098
1099	switch (cp->dev) {
1100	case ESO_DAC_PLAY_VOL:
1101	case ESO_MIC_PLAY_VOL:
1102	case ESO_LINE_PLAY_VOL:
1103	case ESO_SYNTH_PLAY_VOL:
1104	case ESO_CD_PLAY_VOL:
1105	case ESO_AUXB_PLAY_VOL:
1106	case ESO_MASTER_VOL:
1107	case ESO_RECORD_VOL:
1108	case ESO_DAC_REC_VOL:
1109	case ESO_MIC_REC_VOL:
1110	case ESO_LINE_REC_VOL:
1111	case ESO_SYNTH_REC_VOL:
1112	case ESO_CD_REC_VOL:
1113	case ESO_AUXB_REC_VOL:
1114		/*
1115		 * Stereo-capable ports: if a single-channel query is made,
1116		 * just return the left channel's value (since single-channel
1117		 * settings themselves are applied to both channels).
1118		 */
1119		switch (cp->un.value.num_channels) {
1120		case 1:
1121			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1122			    sc->sc_gain[cp->dev][ESO_LEFT];
1123			break;
1124		case 2:
1125			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1126			    sc->sc_gain[cp->dev][ESO_LEFT];
1127			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1128			    sc->sc_gain[cp->dev][ESO_RIGHT];
1129			break;
1130		default:
1131			return (EINVAL);
1132		}
1133		break;
1134
1135	case ESO_MONO_PLAY_VOL:
1136	case ESO_PCSPEAKER_VOL:
1137	case ESO_MONO_REC_VOL:
1138	case ESO_SPATIALIZER:
1139		if (cp->un.value.num_channels != 1)
1140			return (EINVAL);
1141		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1142		    sc->sc_gain[cp->dev][ESO_LEFT];
1143		break;
1144
1145	case ESO_RECORD_MONITOR:
1146		cp->un.ord = sc->sc_recmon;
1147		break;
1148
1149	case ESO_RECORD_SOURCE:
1150		cp->un.ord = sc->sc_recsrc;
1151		break;
1152
1153	case ESO_MONOOUT_SOURCE:
1154		cp->un.ord = sc->sc_monooutsrc;
1155		break;
1156
1157	case ESO_SPATIALIZER_ENABLE:
1158		cp->un.ord = sc->sc_spatializer;
1159		break;
1160
1161	case ESO_MIC_PREAMP:
1162		cp->un.ord = sc->sc_preamp;
1163		break;
1164
1165	default:
1166		return (EINVAL);
1167	}
1168
1169
1170	return (0);
1171
1172}
1173
1174HIDE int
1175eso_query_devinfo(hdl, dip)
1176	void *hdl;
1177	mixer_devinfo_t *dip;
1178{
1179
1180	switch (dip->index) {
1181	case ESO_DAC_PLAY_VOL:
1182		dip->mixer_class = ESO_INPUT_CLASS;
1183		dip->next = dip->prev = AUDIO_MIXER_LAST;
1184		strcpy(dip->label.name, AudioNdac);
1185		dip->type = AUDIO_MIXER_VALUE;
1186		dip->un.v.num_channels = 2;
1187		strcpy(dip->un.v.units.name, AudioNvolume);
1188		break;
1189	case ESO_MIC_PLAY_VOL:
1190		dip->mixer_class = ESO_INPUT_CLASS;
1191		dip->next = dip->prev = AUDIO_MIXER_LAST;
1192		strcpy(dip->label.name, AudioNmicrophone);
1193		dip->type = AUDIO_MIXER_VALUE;
1194		dip->un.v.num_channels = 2;
1195		strcpy(dip->un.v.units.name, AudioNvolume);
1196		break;
1197	case ESO_LINE_PLAY_VOL:
1198		dip->mixer_class = ESO_INPUT_CLASS;
1199		dip->next = dip->prev = AUDIO_MIXER_LAST;
1200		strcpy(dip->label.name, AudioNline);
1201		dip->type = AUDIO_MIXER_VALUE;
1202		dip->un.v.num_channels = 2;
1203		strcpy(dip->un.v.units.name, AudioNvolume);
1204		break;
1205	case ESO_SYNTH_PLAY_VOL:
1206		dip->mixer_class = ESO_INPUT_CLASS;
1207		dip->next = dip->prev = AUDIO_MIXER_LAST;
1208		strcpy(dip->label.name, AudioNfmsynth);
1209		dip->type = AUDIO_MIXER_VALUE;
1210		dip->un.v.num_channels = 2;
1211		strcpy(dip->un.v.units.name, AudioNvolume);
1212		break;
1213	case ESO_MONO_PLAY_VOL:
1214		dip->mixer_class = ESO_INPUT_CLASS;
1215		dip->next = dip->prev = AUDIO_MIXER_LAST;
1216		strcpy(dip->label.name, "mono_in");
1217		dip->type = AUDIO_MIXER_VALUE;
1218		dip->un.v.num_channels = 1;
1219		strcpy(dip->un.v.units.name, AudioNvolume);
1220		break;
1221	case ESO_CD_PLAY_VOL:
1222		dip->mixer_class = ESO_INPUT_CLASS;
1223		dip->next = dip->prev = AUDIO_MIXER_LAST;
1224		strcpy(dip->label.name, AudioNcd);
1225		dip->type = AUDIO_MIXER_VALUE;
1226		dip->un.v.num_channels = 2;
1227		strcpy(dip->un.v.units.name, AudioNvolume);
1228		break;
1229	case ESO_AUXB_PLAY_VOL:
1230		dip->mixer_class = ESO_INPUT_CLASS;
1231		dip->next = dip->prev = AUDIO_MIXER_LAST;
1232		strcpy(dip->label.name, "auxb");
1233		dip->type = AUDIO_MIXER_VALUE;
1234		dip->un.v.num_channels = 2;
1235		strcpy(dip->un.v.units.name, AudioNvolume);
1236		break;
1237
1238	case ESO_MIC_PREAMP:
1239		dip->mixer_class = ESO_MICROPHONE_CLASS;
1240		dip->next = dip->prev = AUDIO_MIXER_LAST;
1241		strcpy(dip->label.name, AudioNpreamp);
1242		dip->type = AUDIO_MIXER_ENUM;
1243		dip->un.e.num_mem = 2;
1244		strcpy(dip->un.e.member[0].label.name, AudioNoff);
1245		dip->un.e.member[0].ord = 0;
1246		strcpy(dip->un.e.member[1].label.name, AudioNon);
1247		dip->un.e.member[1].ord = 1;
1248		break;
1249	case ESO_MICROPHONE_CLASS:
1250		dip->mixer_class = ESO_MICROPHONE_CLASS;
1251		dip->next = dip->prev = AUDIO_MIXER_LAST;
1252		strcpy(dip->label.name, AudioNmicrophone);
1253		dip->type = AUDIO_MIXER_CLASS;
1254		break;
1255
1256	case ESO_INPUT_CLASS:
1257		dip->mixer_class = ESO_INPUT_CLASS;
1258		dip->next = dip->prev = AUDIO_MIXER_LAST;
1259		strcpy(dip->label.name, AudioCinputs);
1260		dip->type = AUDIO_MIXER_CLASS;
1261		break;
1262
1263	case ESO_MASTER_VOL:
1264		dip->mixer_class = ESO_OUTPUT_CLASS;
1265		dip->next = dip->prev = AUDIO_MIXER_LAST;
1266		strcpy(dip->label.name, AudioNmaster);
1267		dip->type = AUDIO_MIXER_VALUE;
1268		dip->un.v.num_channels = 2;
1269		strcpy(dip->un.v.units.name, AudioNvolume);
1270		break;
1271	case ESO_PCSPEAKER_VOL:
1272		dip->mixer_class = ESO_OUTPUT_CLASS;
1273		dip->next = dip->prev = AUDIO_MIXER_LAST;
1274		strcpy(dip->label.name, "pc_speaker");
1275		dip->type = AUDIO_MIXER_VALUE;
1276		dip->un.v.num_channels = 1;
1277		strcpy(dip->un.v.units.name, AudioNvolume);
1278		break;
1279	case ESO_MONOOUT_SOURCE:
1280		dip->mixer_class = ESO_OUTPUT_CLASS;
1281		dip->next = dip->prev = AUDIO_MIXER_LAST;
1282		strcpy(dip->label.name, "mono_out");
1283		dip->type = AUDIO_MIXER_ENUM;
1284		dip->un.e.num_mem = 3;
1285		strcpy(dip->un.e.member[0].label.name, AudioNmute);
1286		dip->un.e.member[0].ord = ESO_MIXREG_MPM_MOMUTE;
1287		strcpy(dip->un.e.member[1].label.name, AudioNdac);
1288		dip->un.e.member[1].ord = ESO_MIXREG_MPM_MOA2R;
1289		strcpy(dip->un.e.member[2].label.name, AudioNmixerout);
1290		dip->un.e.member[2].ord = ESO_MIXREG_MPM_MOREC;
1291		break;
1292	case ESO_SPATIALIZER:
1293		dip->mixer_class = ESO_OUTPUT_CLASS;
1294		dip->prev = AUDIO_MIXER_LAST;
1295		dip->next = ESO_SPATIALIZER_ENABLE;
1296		strcpy(dip->label.name, AudioNspatial);
1297		dip->type = AUDIO_MIXER_VALUE;
1298		dip->un.v.num_channels = 1;
1299		strcpy(dip->un.v.units.name, "level");
1300		break;
1301	case ESO_SPATIALIZER_ENABLE:
1302		dip->mixer_class = ESO_OUTPUT_CLASS;
1303		dip->prev = ESO_SPATIALIZER;
1304		dip->next = AUDIO_MIXER_LAST;
1305		strcpy(dip->label.name, "enable");
1306		dip->type = AUDIO_MIXER_ENUM;
1307		dip->un.e.num_mem = 2;
1308		strcpy(dip->un.e.member[0].label.name, AudioNoff);
1309		dip->un.e.member[0].ord = 0;
1310		strcpy(dip->un.e.member[1].label.name, AudioNon);
1311		dip->un.e.member[1].ord = 1;
1312		break;
1313
1314	case ESO_OUTPUT_CLASS:
1315		dip->mixer_class = ESO_OUTPUT_CLASS;
1316		dip->next = dip->prev = AUDIO_MIXER_LAST;
1317		strcpy(dip->label.name, AudioCoutputs);
1318		dip->type = AUDIO_MIXER_CLASS;
1319		break;
1320
1321	case ESO_RECORD_MONITOR:
1322		dip->mixer_class = ESO_MONITOR_CLASS;
1323		dip->next = dip->prev = AUDIO_MIXER_LAST;
1324		strcpy(dip->label.name, AudioNmute);
1325		dip->type = AUDIO_MIXER_ENUM;
1326		dip->un.e.num_mem = 2;
1327		strcpy(dip->un.e.member[0].label.name, AudioNoff);
1328		dip->un.e.member[0].ord = 0;
1329		strcpy(dip->un.e.member[1].label.name, AudioNon);
1330		dip->un.e.member[1].ord = 1;
1331		break;
1332	case ESO_MONITOR_CLASS:
1333		dip->mixer_class = ESO_MONITOR_CLASS;
1334		dip->next = dip->prev = AUDIO_MIXER_LAST;
1335		strcpy(dip->label.name, AudioCmonitor);
1336		dip->type = AUDIO_MIXER_CLASS;
1337		break;
1338
1339	case ESO_RECORD_VOL:
1340		dip->mixer_class = ESO_RECORD_CLASS;
1341		dip->next = dip->prev = AUDIO_MIXER_LAST;
1342		strcpy(dip->label.name, AudioNrecord);
1343		dip->type = AUDIO_MIXER_VALUE;
1344		strcpy(dip->un.v.units.name, AudioNvolume);
1345		break;
1346	case ESO_RECORD_SOURCE:
1347		dip->mixer_class = ESO_RECORD_CLASS;
1348		dip->next = dip->prev = AUDIO_MIXER_LAST;
1349		strcpy(dip->label.name, AudioNsource);
1350		dip->type = AUDIO_MIXER_ENUM;
1351		dip->un.e.num_mem = 4;
1352		strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
1353		dip->un.e.member[0].ord = ESO_MIXREG_ERS_MIC;
1354		strcpy(dip->un.e.member[1].label.name, AudioNline);
1355		dip->un.e.member[1].ord = ESO_MIXREG_ERS_LINE;
1356		strcpy(dip->un.e.member[2].label.name, AudioNcd);
1357		dip->un.e.member[2].ord = ESO_MIXREG_ERS_CD;
1358		strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
1359		dip->un.e.member[3].ord = ESO_MIXREG_ERS_MIXER;
1360		break;
1361	case ESO_DAC_REC_VOL:
1362		dip->mixer_class = ESO_RECORD_CLASS;
1363		dip->next = dip->prev = AUDIO_MIXER_LAST;
1364		strcpy(dip->label.name, AudioNdac);
1365		dip->type = AUDIO_MIXER_VALUE;
1366		dip->un.v.num_channels = 2;
1367		strcpy(dip->un.v.units.name, AudioNvolume);
1368		break;
1369	case ESO_MIC_REC_VOL:
1370		dip->mixer_class = ESO_RECORD_CLASS;
1371		dip->next = dip->prev = AUDIO_MIXER_LAST;
1372		strcpy(dip->label.name, AudioNmicrophone);
1373		dip->type = AUDIO_MIXER_VALUE;
1374		dip->un.v.num_channels = 2;
1375		strcpy(dip->un.v.units.name, AudioNvolume);
1376		break;
1377	case ESO_LINE_REC_VOL:
1378		dip->mixer_class = ESO_RECORD_CLASS;
1379		dip->next = dip->prev = AUDIO_MIXER_LAST;
1380		strcpy(dip->label.name, AudioNline);
1381		dip->type = AUDIO_MIXER_VALUE;
1382		dip->un.v.num_channels = 2;
1383		strcpy(dip->un.v.units.name, AudioNvolume);
1384		break;
1385	case ESO_SYNTH_REC_VOL:
1386		dip->mixer_class = ESO_RECORD_CLASS;
1387		dip->next = dip->prev = AUDIO_MIXER_LAST;
1388		strcpy(dip->label.name, AudioNfmsynth);
1389		dip->type = AUDIO_MIXER_VALUE;
1390		dip->un.v.num_channels = 2;
1391		strcpy(dip->un.v.units.name, AudioNvolume);
1392		break;
1393	case ESO_MONO_REC_VOL:
1394		dip->mixer_class = ESO_RECORD_CLASS;
1395		dip->next = dip->prev = AUDIO_MIXER_LAST;
1396		strcpy(dip->label.name, "mono_in");
1397		dip->type = AUDIO_MIXER_VALUE;
1398		dip->un.v.num_channels = 1; /* No lies */
1399		strcpy(dip->un.v.units.name, AudioNvolume);
1400		break;
1401	case ESO_CD_REC_VOL:
1402		dip->mixer_class = ESO_RECORD_CLASS;
1403		dip->next = dip->prev = AUDIO_MIXER_LAST;
1404		strcpy(dip->label.name, AudioNcd);
1405		dip->type = AUDIO_MIXER_VALUE;
1406		dip->un.v.num_channels = 2;
1407		strcpy(dip->un.v.units.name, AudioNvolume);
1408		break;
1409	case ESO_AUXB_REC_VOL:
1410		dip->mixer_class = ESO_RECORD_CLASS;
1411		dip->next = dip->prev = AUDIO_MIXER_LAST;
1412		strcpy(dip->label.name, "auxb");
1413		dip->type = AUDIO_MIXER_VALUE;
1414		dip->un.v.num_channels = 2;
1415		strcpy(dip->un.v.units.name, AudioNvolume);
1416		break;
1417	case ESO_RECORD_CLASS:
1418		dip->mixer_class = ESO_RECORD_CLASS;
1419		dip->next = dip->prev = AUDIO_MIXER_LAST;
1420		strcpy(dip->label.name, AudioCrecord);
1421		dip->type = AUDIO_MIXER_CLASS;
1422		break;
1423
1424	default:
1425		return (ENXIO);
1426	}
1427
1428	return (0);
1429}
1430
1431HIDE int
1432eso_allocmem(sc, size, align, boundary, flags, ed)
1433	struct eso_softc *sc;
1434	size_t size;
1435	size_t align;
1436	size_t boundary;
1437	int flags;
1438	struct eso_dma *ed;
1439{
1440	int error, wait;
1441
1442	wait = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
1443	ed->ed_size = size;
1444
1445	error = bus_dmamem_alloc(sc->sc_dmat, ed->ed_size, align, boundary,
1446	    ed->ed_segs, sizeof (ed->ed_segs) / sizeof (ed->ed_segs[0]),
1447	    &ed->ed_nsegs, wait);
1448	if (error)
1449		goto out;
1450
1451	error = bus_dmamem_map(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs,
1452	    ed->ed_size, &ed->ed_addr, wait | BUS_DMA_COHERENT);
1453	if (error)
1454		goto free;
1455
1456	error = bus_dmamap_create(sc->sc_dmat, ed->ed_size, 1, ed->ed_size, 0,
1457	    wait, &ed->ed_map);
1458	if (error)
1459		goto unmap;
1460
1461	error = bus_dmamap_load(sc->sc_dmat, ed->ed_map, ed->ed_addr,
1462	    ed->ed_size, NULL, wait);
1463	if (error)
1464		goto destroy;
1465
1466	return (0);
1467
1468 destroy:
1469	bus_dmamap_destroy(sc->sc_dmat, ed->ed_map);
1470 unmap:
1471	bus_dmamem_unmap(sc->sc_dmat, ed->ed_addr, ed->ed_size);
1472 free:
1473	bus_dmamem_free(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs);
1474 out:
1475	return (error);
1476}
1477
1478HIDE void
1479eso_freemem(sc, ed)
1480	struct eso_softc *sc;
1481	struct eso_dma *ed;
1482{
1483
1484	bus_dmamap_unload(sc->sc_dmat, ed->ed_map);
1485	bus_dmamap_destroy(sc->sc_dmat, ed->ed_map);
1486	bus_dmamem_unmap(sc->sc_dmat, ed->ed_addr, ed->ed_size);
1487	bus_dmamem_free(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs);
1488}
1489
1490HIDE void *
1491#ifdef __OpenBSD__
1492eso_allocm(hdl, size, type, flags)
1493#else
1494eso_allocm(hdl, direction, size, type, flags)
1495#endif
1496	void *hdl;
1497#ifdef __OpenBSD__
1498	u_long size;
1499#else
1500	int direction;
1501	size_t size;
1502#endif
1503	int type, flags;
1504{
1505	struct eso_softc *sc = hdl;
1506	struct eso_dma *ed;
1507	size_t boundary;
1508	int error;
1509
1510	if ((ed = malloc(size, type, flags)) == NULL)
1511		return (NULL);
1512
1513	/*
1514	 * Apparently the Audio 1 DMA controller's current address
1515	 * register can't roll over a 64K address boundary, so we have to
1516	 * take care of that ourselves.  The second channel DMA controller
1517	 * doesn't have that restriction, however.
1518	 */
1519#ifdef __OpenBSD__
1520	boundary = 0x10000;
1521#else
1522	if (direction == AUMODE_RECORD)
1523		boundary = 0x10000;
1524	else
1525		boundary = 0;
1526#endif
1527
1528	error = eso_allocmem(sc, size, 32, boundary, flags, ed);
1529	if (error) {
1530		free(ed, type);
1531		return (NULL);
1532	}
1533	ed->ed_next = sc->sc_dmas;
1534	sc->sc_dmas = ed;
1535
1536	return (KVADDR(ed));
1537}
1538
1539HIDE void
1540eso_freem(hdl, addr, type)
1541	void *hdl;
1542	void *addr;
1543	int type;
1544{
1545	struct eso_softc *sc;
1546	struct eso_dma *p, **pp;
1547
1548	for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->ed_next) {
1549		if (KVADDR(p) == addr) {
1550			eso_freemem(sc, p);
1551			*pp = p->ed_next;
1552			free(p, type);
1553			return;
1554		}
1555	}
1556}
1557
1558#ifdef __OpenBSD__
1559u_long
1560eso_round_buffersize(hdl, bufsize)
1561#else
1562HIDE size_t
1563eso_round_buffersize(hdl, direction, bufsize)
1564#endif
1565	void *hdl;
1566#ifdef __OpenBSD__
1567	u_long bufsize;
1568#else
1569	int direction;
1570	size_t bufsize;
1571#endif
1572{
1573
1574	/* 64K restriction: ISA at eleven? */
1575	if (bufsize > 65536)
1576		bufsize = 65536;
1577
1578	return (bufsize);
1579}
1580
1581HIDE int
1582eso_mappage(hdl, addr, offs, prot)
1583	void *hdl;
1584	void *addr;
1585	int offs;
1586	int prot;
1587{
1588	struct eso_softc *sc = hdl;
1589	struct eso_dma *ed;
1590
1591	if (offs < 0)
1592		return (-1);
1593	for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) == addr;
1594	     ed = ed->ed_next)
1595		;
1596	if (ed == NULL)
1597		return (-1);
1598
1599	return (bus_dmamem_mmap(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs,
1600	    offs, prot, BUS_DMA_WAITOK));
1601}
1602
1603/* ARGSUSED */
1604HIDE int
1605eso_get_props(hdl)
1606	void *hdl;
1607{
1608
1609	return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
1610	    AUDIO_PROP_FULLDUPLEX);
1611}
1612
1613HIDE int
1614eso_trigger_output(hdl, start, end, blksize, intr, arg, param)
1615	void *hdl;
1616	void *start, *end;
1617	int blksize;
1618	void (*intr) __P((void *));
1619	void *arg;
1620	struct audio_params *param;
1621{
1622	struct eso_softc *sc = hdl;
1623	struct eso_dma *ed;
1624	uint8_t a2c1;
1625
1626	DPRINTF((
1627	    "%s: trigger_output: start %p, end %p, blksize %d, intr %p(%p)\n",
1628	    sc->sc_dev.dv_xname, start, end, blksize, intr, arg));
1629	DPRINTF(("%s: param: rate %lu, encoding %u, precision %u, channels %u, sw_code %p, factor %d\n",
1630	    sc->sc_dev.dv_xname, param->sample_rate, param->encoding,
1631	    param->precision, param->channels, param->sw_code, param->factor));
1632
1633	/* Find DMA buffer. */
1634	for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) != start;
1635	     ed = ed->ed_next)
1636		;
1637	if (ed == NULL) {
1638		printf("%s: trigger_output: bad addr %p\n",
1639		    sc->sc_dev.dv_xname, start);
1640		return (EINVAL);
1641	}
1642
1643	sc->sc_pintr = intr;
1644	sc->sc_parg = arg;
1645
1646	/* DMA transfer count (in `words'!) reload using 2's complement. */
1647	blksize = -(blksize >> 1);
1648	eso_write_mixreg(sc, ESO_MIXREG_A2TCRLO, blksize & 0xff);
1649	eso_write_mixreg(sc, ESO_MIXREG_A2TCRHI, blksize >> 8);
1650
1651	/* Update DAC to reflect DMA count and audio parameters. */
1652	/* Note: we cache A2C2 in order to avoid r/m/w at interrupt time. */
1653	if (param->precision * param->factor == 16)
1654		sc->sc_a2c2 |= ESO_MIXREG_A2C2_16BIT;
1655	else
1656		sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_16BIT;
1657	if (param->channels == 2)
1658		sc->sc_a2c2 |= ESO_MIXREG_A2C2_STEREO;
1659	else
1660		sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_STEREO;
1661	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1662	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1663		sc->sc_a2c2 |= ESO_MIXREG_A2C2_SIGNED;
1664	else
1665		sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_SIGNED;
1666	/* Unmask IRQ. */
1667	sc->sc_a2c2 |= ESO_MIXREG_A2C2_IRQM;
1668	eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2);
1669
1670	/* Set up DMA controller. */
1671	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAA,
1672	    htopci(DMAADDR(ed)));
1673	bus_space_write_2(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAC,
1674	    htopci((uint8_t *)end - (uint8_t *)start));
1675	bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM,
1676	    ESO_IO_A2DMAM_DMAENB | ESO_IO_A2DMAM_AUTO);
1677
1678	/* Start DMA. */
1679	a2c1 = eso_read_mixreg(sc, ESO_MIXREG_A2C1);
1680	a2c1 &= ~ESO_MIXREG_A2C1_RESV0; /* Paranoia? XXX bit 5 */
1681	a2c1 |= ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB |
1682	    ESO_MIXREG_A2C1_AUTO;
1683	eso_write_mixreg(sc, ESO_MIXREG_A2C1, a2c1);
1684
1685	return (0);
1686}
1687
1688HIDE int
1689eso_trigger_input(hdl, start, end, blksize, intr, arg, param)
1690	void *hdl;
1691	void *start, *end;
1692	int blksize;
1693	void (*intr) __P((void *));
1694	void *arg;
1695	struct audio_params *param;
1696{
1697	struct eso_softc *sc = hdl;
1698	struct eso_dma *ed;
1699	uint8_t actl, a1c1;
1700
1701	DPRINTF((
1702	    "%s: trigger_input: start %p, end %p, blksize %d, intr %p(%p)\n",
1703	    sc->sc_dev.dv_xname, start, end, blksize, intr, arg));
1704	DPRINTF(("%s: param: rate %lu, encoding %u, precision %u, channels %u, sw_code %p, factor %d\n",
1705	    sc->sc_dev.dv_xname, param->sample_rate, param->encoding,
1706	    param->precision, param->channels, param->sw_code, param->factor));
1707
1708	/*
1709	 * If we failed to configure the Audio 1 DMA controller, bail here
1710	 * while retaining availability of the DAC direction (in Audio 2).
1711	 */
1712	if (!sc->sc_dmac_configured)
1713		return (EIO);
1714
1715	/* Find DMA buffer. */
1716	for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) != start;
1717	     ed = ed->ed_next)
1718		;
1719	if (ed == NULL) {
1720		printf("%s: trigger_output: bad addr %p\n",
1721		    sc->sc_dev.dv_xname, start);
1722		return (EINVAL);
1723	}
1724
1725	sc->sc_rintr = intr;
1726	sc->sc_rarg = arg;
1727
1728	/* Set up ADC DMA converter parameters. */
1729	actl = eso_read_ctlreg(sc, ESO_CTLREG_ACTL);
1730	if (param->channels == 2) {
1731		actl &= ~ESO_CTLREG_ACTL_MONO;
1732		actl |= ESO_CTLREG_ACTL_STEREO;
1733	} else {
1734		actl &= ~ESO_CTLREG_ACTL_STEREO;
1735		actl |= ESO_CTLREG_ACTL_MONO;
1736	}
1737	eso_write_ctlreg(sc, ESO_CTLREG_ACTL, actl);
1738
1739	/* Set up Transfer Type: maybe move to attach time? */
1740	eso_write_ctlreg(sc, ESO_CTLREG_A1TT, ESO_CTLREG_A1TT_DEMAND4);
1741
1742	/* DMA transfer count reload using 2's complement. */
1743	blksize = -blksize;
1744	eso_write_ctlreg(sc, ESO_CTLREG_A1TCRLO, blksize & 0xff);
1745	eso_write_ctlreg(sc, ESO_CTLREG_A1TCRHI, blksize >> 8);
1746
1747	/* Set up and enable Audio 1 DMA FIFO. */
1748	a1c1 = ESO_CTLREG_A1C1_RESV1 | ESO_CTLREG_A1C1_FIFOENB;
1749	if (param->precision * param->factor == 16)
1750		a1c1 |= ESO_CTLREG_A1C1_16BIT;
1751	if (param->channels == 2)
1752		a1c1 |= ESO_CTLREG_A1C1_STEREO;
1753	else
1754		a1c1 |= ESO_CTLREG_A1C1_MONO;
1755	if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1756	    param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1757		a1c1 |= ESO_CTLREG_A1C1_SIGNED;
1758	eso_write_ctlreg(sc, ESO_CTLREG_A1C1, a1c1);
1759
1760	/* Set up ADC IRQ/DRQ parameters. */
1761	eso_write_ctlreg(sc, ESO_CTLREG_LAIC,
1762	    ESO_CTLREG_LAIC_PINENB | ESO_CTLREG_LAIC_EXTENB);
1763	eso_write_ctlreg(sc, ESO_CTLREG_DRQCTL,
1764	    ESO_CTLREG_DRQCTL_ENB1 | ESO_CTLREG_DRQCTL_EXTENB);
1765
1766	/* Set up and enable DMA controller. */
1767	bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_CLEAR, 0);
1768	bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK,
1769	    ESO_DMAC_MASK_MASK);
1770	bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE,
1771	    DMA37MD_WRITE | DMA37MD_LOOP | DMA37MD_DEMAND);
1772	bus_space_write_4(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAA,
1773	    htopci(DMAADDR(ed)));
1774	bus_space_write_2(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAC,
1775	    htopci((uint8_t *)end - (uint8_t *)start - 1));
1776	bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 0);
1777
1778	/* Start DMA. */
1779	eso_write_ctlreg(sc, ESO_CTLREG_A1C2,
1780	    ESO_CTLREG_A1C2_DMAENB | ESO_CTLREG_A1C2_READ |
1781	    ESO_CTLREG_A1C2_AUTO | ESO_CTLREG_A1C2_ADC);
1782
1783	return (0);
1784}
1785
1786HIDE int
1787eso_set_recsrc(sc, recsrc)
1788	struct eso_softc *sc;
1789	unsigned int recsrc;
1790{
1791
1792	eso_write_mixreg(sc, ESO_MIXREG_ERS, recsrc);
1793	sc->sc_recsrc = recsrc;
1794	return (0);
1795}
1796
1797HIDE void
1798eso_set_gain(sc, port)
1799	struct eso_softc *sc;
1800	unsigned int port;
1801{
1802	uint8_t mixreg, tmp;
1803
1804	switch (port) {
1805	case ESO_DAC_PLAY_VOL:
1806		mixreg = ESO_MIXREG_PVR_A2;
1807		break;
1808	case ESO_MIC_PLAY_VOL:
1809		mixreg = ESO_MIXREG_PVR_MIC;
1810		break;
1811	case ESO_LINE_PLAY_VOL:
1812		mixreg = ESO_MIXREG_PVR_LINE;
1813		break;
1814	case ESO_SYNTH_PLAY_VOL:
1815		mixreg = ESO_MIXREG_PVR_SYNTH;
1816		break;
1817	case ESO_CD_PLAY_VOL:
1818		mixreg = ESO_MIXREG_PVR_CD;
1819		break;
1820	case ESO_AUXB_PLAY_VOL:
1821		mixreg = ESO_MIXREG_PVR_AUXB;
1822		break;
1823
1824	case ESO_DAC_REC_VOL:
1825		mixreg = ESO_MIXREG_RVR_A2;
1826		break;
1827	case ESO_MIC_REC_VOL:
1828		mixreg = ESO_MIXREG_RVR_MIC;
1829		break;
1830	case ESO_LINE_REC_VOL:
1831		mixreg = ESO_MIXREG_RVR_LINE;
1832		break;
1833	case ESO_SYNTH_REC_VOL:
1834		mixreg = ESO_MIXREG_RVR_SYNTH;
1835		break;
1836	case ESO_CD_REC_VOL:
1837		mixreg = ESO_MIXREG_RVR_CD;
1838		break;
1839	case ESO_AUXB_REC_VOL:
1840		mixreg = ESO_MIXREG_RVR_AUXB;
1841		break;
1842	case ESO_MONO_PLAY_VOL:
1843		mixreg = ESO_MIXREG_PVR_MONO;
1844		break;
1845	case ESO_MONO_REC_VOL:
1846		mixreg = ESO_MIXREG_RVR_MONO;
1847		break;
1848
1849	case ESO_PCSPEAKER_VOL:
1850		/* Special case - only 3-bit, mono, and reserved bits. */
1851		tmp = eso_read_mixreg(sc, ESO_MIXREG_PCSVR);
1852		tmp &= ESO_MIXREG_PCSVR_RESV;
1853		/* Map bits 7:5 -> 2:0. */
1854		tmp |= (sc->sc_gain[port][ESO_LEFT] >> 5);
1855		eso_write_mixreg(sc, ESO_MIXREG_PCSVR, tmp);
1856		return;
1857
1858	case ESO_MASTER_VOL:
1859		/* Special case - separate regs, and 6-bit precision. */
1860		/* Map bits 7:2 -> 5:0. */
1861		eso_write_mixreg(sc, ESO_MIXREG_LMVM,
1862		    sc->sc_gain[port][ESO_LEFT] >> 2);
1863		eso_write_mixreg(sc, ESO_MIXREG_RMVM,
1864		    sc->sc_gain[port][ESO_RIGHT] >> 2);
1865		return;
1866
1867	case ESO_SPATIALIZER:
1868		/* Special case - only `mono', and higher precision. */
1869		eso_write_mixreg(sc, ESO_MIXREG_SPATLVL,
1870		    sc->sc_gain[port][ESO_LEFT]);
1871		return;
1872
1873	case ESO_RECORD_VOL:
1874		/* Very Special case, controller register. */
1875		eso_write_ctlreg(sc, ESO_CTLREG_RECLVL,ESO_4BIT_GAIN_TO_STEREO(
1876		   sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT]));
1877		return;
1878
1879	default:
1880#ifdef DIAGNOSTIC
1881		panic("eso_set_gain: bad port %u", port);
1882		/* NOTREACHED */
1883#else
1884		return;
1885#endif
1886		}
1887
1888	eso_write_mixreg(sc, mixreg, ESO_4BIT_GAIN_TO_STEREO(
1889	    sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT]));
1890}
1891