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