xref: /netbsd-src/sys/dev/ic/interwave.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: interwave.c,v 1.34 2009/03/14 15:36:17 dsl Exp $	*/
2 
3 /*
4  * Copyright (c) 1997, 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Author: Kari Mettinen
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: interwave.c,v 1.34 2009/03/14 15:36:17 dsl Exp $");
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/errno.h>
37 #include <sys/ioctl.h>
38 #include <sys/syslog.h>
39 #include <sys/device.h>
40 #include <sys/proc.h>
41 #include <sys/buf.h>
42 #include <sys/fcntl.h>
43 #include <sys/malloc.h>
44 #include <sys/kernel.h>
45 
46 #include <sys/cpu.h>
47 #include <sys/intr.h>
48 #include <machine/pio.h>
49 #include <sys/audioio.h>
50 #include <dev/audio_if.h>
51 #include <dev/mulaw.h>
52 
53 #include <dev/isa/isavar.h>
54 #include <dev/isa/isadmavar.h>
55 
56 #include <dev/ic/interwavereg.h>
57 #include <dev/ic/interwavevar.h>
58 
59 
60 static void iwreset(struct iw_softc *, int);
61 
62 static int iw_set_speed(struct iw_softc *, u_long, char);
63 static u_long iw_set_format(struct iw_softc *, u_long, int);
64 static void iw_mixer_line_level(struct iw_softc *, int, int, int);
65 static void iw_trigger_dma(struct iw_softc *, u_char);
66 static void iw_stop_dma(struct iw_softc *, u_char, u_char);
67 static void iw_dma_count(struct iw_softc *, u_short, int);
68 static int iwintr(void *);
69 static void iw_meminit(struct iw_softc *);
70 static void iw_mempoke(struct iw_softc *, u_long, u_char);
71 static u_char iw_mempeek(struct iw_softc *, u_long);
72 
73 #ifdef USE_WAVETABLE
74 static void iw_set_voice_place(struct iw_softc *, u_char, u_long);
75 static void iw_voice_pan(struct iw_softc *, u_char, u_short, u_short);
76 static void iw_voice_freq(struct iw_softc *, u_char, u_long);
77 static void iw_set_loopmode(struct iw_softc *, u_char, u_char, u_char);
78 static void iw_set_voice_pos(struct iw_softc *, u_short, u_long, u_long);
79 static void iw_start_voice(struct iw_softc *, u_char);
80 static void iw_play_voice(struct iw_softc *, u_long, u_long, u_short);
81 static void iw_stop_voice(struct iw_softc *, u_char);
82 static void iw_move_voice_end(struct iw_softc *, u_short, u_long);
83 static void iw_initvoices(struct iw_softc *);
84 #endif
85 
86 struct audio_device iw_device = {
87 	"Am78C201",
88 	"0.1",
89 	"guspnp"
90 };
91 
92 #ifdef AUDIO_DEBUG
93 int iw_debug;
94 #define DPRINTF(p)       if (iw_debug) printf p
95 #else
96 #define DPRINTF(p)
97 #endif
98 
99 static int      iw_cc = 1;
100 #ifdef DIAGNOSTIC
101 static int      outputs = 0;
102 static int      iw_ints = 0;
103 static int      inputs = 0;
104 static int      iw_inints = 0;
105 #endif
106 
107 int
108 iwintr(void *arg)
109 {
110 	struct	iw_softc *sc;
111 	int	val;
112 	u_char	intrs;
113 
114 	sc = arg;
115 	val = 0;
116 	intrs = 0;
117 	IW_READ_DIRECT_1(6, sc->p2xr_h, intrs);	/* UISR */
118 
119 	/* codec ints */
120 
121 	/*
122 	 * The proper order to do this seems to be to read CSR3 to get the
123 	 * int cause and fifo over underrrun status, then deal with the ints
124 	 * (new DMA set up), and to clear ints by writing the respective bit
125 	 * to 0.
126 	 */
127 
128 	/* read what ints happened */
129 
130 	IW_READ_CODEC_1(CSR3I, intrs);
131 
132 	/* clear them */
133 
134 	IW_WRITE_DIRECT_1(2, sc->codec_index_h, 0x00);
135 
136 	/* and process them */
137 
138 	if (intrs & 0x20) {
139 #ifdef DIAGNOSTIC
140 		iw_inints++;
141 #endif
142 		if (sc->sc_recintr != 0)
143 			sc->sc_recintr(sc->sc_recarg);
144 		val = 1;
145 	}
146 	if (intrs & 0x10) {
147 #ifdef DIAGNOSTIC
148 		iw_ints++;
149 #endif
150 		if (sc->sc_playintr != 0)
151 			sc->sc_playintr(sc->sc_playarg);
152 		val = 1;
153 	}
154 	return val;
155 
156 }
157 
158 void
159 iwattach(struct iw_softc *sc)
160 {
161 	int	got_irq;
162 
163 	DPRINTF(("iwattach sc %p\n", sc));
164 	got_irq = 0;
165 
166 	sc->cdatap = 1;		/* relative offsets in region */
167 	sc->csr1r = 2;
168 	sc->cxdr = 3;		/* CPDR or CRDR */
169 
170 	sc->gmxr = 0;		/* sc->p3xr */
171 	sc->gmxdr = 1;		/* GMTDR or GMRDR */
172 	sc->svsr = 2;
173 	sc->igidxr = 3;
174 	sc->i16dp = 4;
175 	sc->i8dp = 5;
176 	sc->lmbdr = 7;
177 
178 	sc->rec_precision = sc->play_precision = 8;
179 	sc->rec_channels = sc->play_channels = 1;
180 	sc->rec_encoding = sc->play_encoding = AUDIO_ENCODING_ULAW;
181 	sc->sc_irate = 8000;
182 	sc->sc_orate = 8000;
183 
184 	sc->sc_fullduplex = 1;
185 
186 	sc->sc_dma_flags = 0;
187 
188 	/*
189 	 * We can only use a few selected irqs, see if we got one from pnp
190 	 * code that suits us.
191 	 */
192 
193 	if (sc->sc_irq > 0) {
194 		sc->sc_ih = isa_intr_establish(sc->sc_p2xr_ic,
195 		    sc->sc_irq, IST_EDGE, IPL_AUDIO, iwintr, sc);
196 		got_irq = 1;
197 	}
198 	if (!got_irq) {
199 		printf("\niwattach: couldn't get a suitable irq\n");
200 		return;
201 	}
202 	printf("\n");
203 	iwreset(sc, 0);
204 	iw_set_format(sc, AUDIO_ENCODING_ULAW, 0);
205 	iw_set_format(sc, AUDIO_ENCODING_ULAW, 1);
206 	printf("%s: interwave version %s\n",
207 	    device_xname(&sc->sc_dev), iw_device.version);
208 	audio_attach_mi(sc->iw_hw_if, sc, &sc->sc_dev);
209 }
210 
211 int
212 iwopen(struct iw_softc *sc, int flags)
213 {
214 
215 	DPRINTF(("iwopen: sc %p\n", sc));
216 
217 #ifdef DIAGNOSTIC
218 	outputs = 0;
219 	iw_ints = 0;
220 	inputs = 0;
221 	iw_inints = 0;
222 #endif
223 
224 	iwreset(sc, 1);
225 
226 	return 0;
227 }
228 
229 void
230 iwclose(void *addr)
231 {
232 
233 	DPRINTF(("iwclose sc %p\n", addr));
234 #ifdef DIAGNOSTIC
235 	DPRINTF(("iwclose: outputs %d ints %d inputs %d in_ints %d\n",
236 		outputs, iw_ints, inputs, iw_inints));
237 #endif
238 }
239 
240 #define RAM_STEP	64*1024
241 
242 static void
243 iw_mempoke(struct iw_softc *sc, u_long addy, u_char val)
244 {
245 
246 	IW_WRITE_GENERAL_2(LMALI, (u_short) addy);
247 	IW_WRITE_GENERAL_1(LMAHI, (u_char) (addy >> 16));
248 
249 	/* Write byte to LMBDR */
250 	IW_WRITE_DIRECT_1(sc->p3xr + 7, sc->p3xr_h, val);
251 }
252 
253 static u_char
254 iw_mempeek(struct iw_softc *sc, u_long addy)
255 {
256 	u_char	ret;
257 
258 	IW_WRITE_GENERAL_2(LMALI, (u_short) addy);
259 	IW_WRITE_GENERAL_1(LMAHI, (u_char) (addy >> 16));
260 
261 	IW_READ_DIRECT_1(sc->p3xr + 7, sc->p3xr_h, ret);
262 	return ret;		/* return byte from LMBDR */
263 }
264 
265 static void
266 iw_meminit(struct iw_softc *sc)
267 {
268 	u_long	bank[4] = {0L, 0L, 0L, 0L};
269 	u_long	addr, base, cnt;
270 	u_char	i, ram /* ,memval=0 */ ;
271 	u_short	lmcfi;
272 	u_long	temppi;
273 	u_long	*lpbanks;
274 
275 	addr = 0L;
276 	base = 0L;
277 	cnt = 0L;
278 	ram = 0;
279 	lpbanks = &temppi;
280 
281 	IW_WRITE_GENERAL_1(LDMACI, 0x00);
282 
283 	IW_READ_GENERAL_2(LMCFI, lmcfi);	/* 0x52 */
284 	lmcfi |= 0x0A0C;
285 	IW_WRITE_GENERAL_2(LMCFI, lmcfi);	/* max addr span */
286 	IW_WRITE_GENERAL_1(LMCI, 0x00);
287 
288 	/* fifo addresses */
289 
290 	IW_WRITE_GENERAL_2(LMRFAI, ((4 * 1024 * 1024) >> 8));
291 	IW_WRITE_GENERAL_2(LMPFAI, ((4 * 1024 * 1024 + 16 * 1024) >> 8));
292 
293 	IW_WRITE_GENERAL_2(LMFSI, 0x000);
294 
295 	IW_WRITE_GENERAL_2(LDICI, 0x0000);
296 
297 	while (addr < (16 * 1024 * 1024)) {
298 		iw_mempoke(sc, addr, 0x00);
299 		addr += RAM_STEP;
300 	}
301 
302 	printf("%s:", device_xname(&sc->sc_dev));
303 
304 	for (i = 0; i < 4; i++) {
305 		iw_mempoke(sc, base, 0xAA);	/* mark start of bank */
306 		iw_mempoke(sc, base + 1L, 0x55);
307 		if (iw_mempeek(sc, base) == 0xAA  &&
308 		    iw_mempeek(sc, base + 1L) == 0x55)
309 			ram = 1;
310 		if (ram) {
311 			while (cnt < (4 * 1024 * 1024)) {
312 				bank[i] += RAM_STEP;
313 				cnt += RAM_STEP;
314 				addr = base + cnt;
315 				if (iw_mempeek(sc, addr) == 0xAA)
316 					break;
317 			}
318 		}
319 		if (lpbanks != NULL) {
320 			*lpbanks = bank[i];
321 			lpbanks++;
322 		}
323 		bank[i] = bank[i] >> 10;
324 		printf("%s bank[%d]: %ldK", i ? "," : "", i, bank[i]);
325 		base += 4 * 1024 * 1024;
326 		cnt = 0L;
327 		ram = 0;
328 	}
329 
330 	printf("\n");
331 
332 	/*
333 	 * this is not really useful since GUS PnP supports memory
334 	 * configurations that aren't really supported by Interwave...beware
335 	 * of holes! Also, we don't use the memory for anything in this
336 	 * version of the driver.
337 	 *
338 	 * we've configured for 4M-4M-4M-4M
339 	 */
340 }
341 
342 static void
343 iwreset(struct iw_softc *sc, int warm)
344 {
345 	u_char	reg, cmode, val, mixer_image;
346 
347 	val = 0;
348 	mixer_image = 0;
349 	reg = 0;		/* XXX gcc -Wall */
350 
351 	cmode = 0x6c;		/* enhanced codec mode (full duplex) */
352 
353 	/* reset */
354 
355 	IW_WRITE_GENERAL_1(URSTI, 0x00);
356 	delay(10);
357 	IW_WRITE_GENERAL_1(URSTI, 0x07);
358 	IW_WRITE_GENERAL_1(ICMPTI, 0x1f);	/* disable DSP and uici and
359 						 * udci writes */
360 	IW_WRITE_GENERAL_1(IDECI, 0x7f);	/* enable ints to ISA and
361 						 * codec access */
362 	IW_READ_GENERAL_1(IVERI, reg);
363 	IW_WRITE_GENERAL_1(IVERI, reg | 0x01);	/* hidden reg lock disable */
364 	IW_WRITE_GENERAL_1(UASBCI, 0x00);
365 
366 	/* synth enhanced mode (default), 0 active voices, disable ints */
367 
368 	IW_WRITE_GENERAL_1(SGMI_WR, 0x01);	/* enhanced mode, LFOs
369 						 * disabled */
370 	for (val = 0; val < 32; val++) {
371 		/* set each synth sound volume to 0 */
372 		IW_WRITE_DIRECT_1(sc->p3xr + 2, sc->p3xr_h, val);
373 		IW_WRITE_GENERAL_1(SVSI_WR, 0x00);
374 		IW_WRITE_GENERAL_2(SASLI_WR, 0x0000);
375 		IW_WRITE_GENERAL_2(SASHI_WR, 0x0000);
376 		IW_WRITE_GENERAL_2(SAELI_WR, 0x0000);
377 		IW_WRITE_GENERAL_2(SAEHI_WR, 0x0000);
378 		IW_WRITE_GENERAL_2(SFCI_WR, 0x0000);
379 		IW_WRITE_GENERAL_1(SACI_WR, 0x02);
380 		IW_WRITE_GENERAL_1(SVSI_WR, 0x00);
381 		IW_WRITE_GENERAL_1(SVEI_WR, 0x00);
382 		IW_WRITE_GENERAL_2(SVLI_WR, 0x0000);
383 		IW_WRITE_GENERAL_1(SVCI_WR, 0x02);
384 		IW_WRITE_GENERAL_1(SMSI_WR, 0x02);
385 	}
386 
387 	IW_WRITE_GENERAL_1(SAVI_WR, 0x00);
388 
389 	/* codec mode/init */
390 
391 	/* first change mode to 1 */
392 
393 	IW_WRITE_CODEC_1(CMODEI, 0x00);
394 
395 	/* and mode 3 */
396 
397 	IW_WRITE_CODEC_1(CMODEI, cmode);
398 
399 	IW_READ_CODEC_1(CMODEI, reg);
400 
401 	DPRINTF(("cmode %x\n", reg));
402 
403 	sc->revision = ((reg & 0x80) >> 3) | (reg & 0x0f);
404 
405 	IW_WRITE_DIRECT_1(sc->codec_index + 2, sc->p2xr_h, 0x00);
406 
407 	IW_WRITE_CODEC_1(CFIG1I | IW_MCE, 0x00);	/* DMA 2 chan access */
408 	IW_WRITE_CODEC_1(CEXTI, 0x00);	/* disable ints for now */
409 
410 
411 	IW_WRITE_CODEC_1(CLPCTI, 0x00);	/* reset playback sample counters */
412 	IW_WRITE_CODEC_1(CUPCTI, 0x00);	/* always upper byte last */
413 	IW_WRITE_CODEC_1(CFIG2I, 0x80);	/* full voltage range, enable record
414 					 * and playback sample counters, and
415 					 * don't center output in case or
416 					 * FIFO underrun */
417 	IW_WRITE_CODEC_1(CFIG3I, 0xc0);	/* enable record/playback irq (still
418 					 * turned off from CEXTI), max DMA
419 					 * rate */
420 	IW_WRITE_CODEC_1(CSR3I, 0x00);	/* clear status 3 reg */
421 
422 
423 	IW_WRITE_CODEC_1(CLRCTI, 0x00);	/* reset record sample counters */
424 	IW_WRITE_CODEC_1(CURCTI, 0x00);	/* always upper byte last */
425 
426 
427 	IW_READ_GENERAL_1(IVERI, reg);
428 
429 	sc->vers = reg >> 4;
430 	if (!warm)
431 		snprintf(iw_device.version, sizeof(iw_device.version), "%d.%d",
432 		    sc->vers, sc->revision);
433 
434 	IW_WRITE_GENERAL_1(IDECI, 0x7f);	/* irqs and codec decode
435 						 * enable */
436 
437 
438 	/* ports */
439 
440 	if (!warm) {
441 		iw_mixer_line_level(sc, IW_LINE_OUT, 255, 255);
442 		iw_mixer_line_level(sc, IW_LINE_IN, 0, 0);
443 		iw_mixer_line_level(sc, IW_AUX1, 0, 0);
444 		iw_mixer_line_level(sc, IW_AUX2, 200, 200); /* CD */
445 		sc->sc_dac.off = 0;
446 		iw_mixer_line_level(sc, IW_DAC, 200, 200);
447 
448 		iw_mixer_line_level(sc, IW_MIC_IN, 0, 0);
449 		iw_mixer_line_level(sc, IW_REC, 0, 0);
450 		iw_mixer_line_level(sc, IW_LOOPBACK, 0, 0);
451 		iw_mixer_line_level(sc, IW_MONO_IN, 0, 0);
452 
453 		/* mem stuff */
454 		iw_meminit(sc);
455 
456 	}
457 	IW_WRITE_CODEC_1(CEXTI, 0x02);	/* codec int enable */
458 
459 	/* clear _LDMACI */
460 
461 	IW_WRITE_GENERAL_1(LDMACI, 0x00);
462 
463 	/* enable mixer paths */
464 	mixer_image = 0x0c;
465 	IW_WRITE_DIRECT_1(sc->p2xr, sc->p2xr_h, mixer_image);
466 	/*
467 	 * enable output, line in. disable mic in bit 0 = 0 -> line in on
468 	 * (from codec?) bit 1 = 0 -> output on bit 2 = 1 -> mic in on bit 3
469 	 * = 1 -> irq&drq pin enable bit 4 = 1 -> channel interrupts to chan
470 	 * 1 bit 5 = 1 -> enable midi loop back bit 6 = 0 -> irq latches
471 	 * URCR[2:0] bit 6 = 1 -> DMA latches URCR[2:0]
472 	 */
473 
474 
475 	IW_READ_DIRECT_1(sc->p2xr, sc->p2xr_h, mixer_image);
476 #ifdef AUDIO_DEBUG
477 	if (!warm)
478 		DPRINTF(("mix image %x \n", mixer_image));
479 #endif
480 }
481 
482 struct iw_codec_freq {
483 	u_long	freq;
484 	u_char	bits;
485 };
486 
487 int
488 iw_set_speed(struct iw_softc *sc, u_long freq, char in)
489 {
490 	u_char	var, cfig3, reg;
491 
492 	static struct iw_codec_freq iw_cf[17] = {
493 #define FREQ_1 24576000
494 #define FREQ_2 16934400
495 #define XTAL1 0
496 #define XTAL2 1
497 		{5510, 0x00 | XTAL2}, {6620, 0x0E | XTAL2},
498 		{8000, 0x00 | XTAL1}, {9600, 0x0E | XTAL1},
499 		{11025, 0x02 | XTAL2}, {16000, 0x02 | XTAL1},
500 		{18900, 0x04 | XTAL2}, {22050, 0x06 | XTAL2},
501 		{27420, 0x04 | XTAL1}, {32000, 0x06 | XTAL1},
502 		{33075, 0x0C | XTAL2}, {37800, 0x08 | XTAL2},
503 		{38400, 0x0A | XTAL1}, {44100, 0x0A | XTAL2},
504 		{44800, 0x08 | XTAL1}, {48000, 0x0C | XTAL1},
505 		{48000, 0x0C | XTAL1}	/* really a dummy for indexing later */
506 #undef XTAL1
507 #undef XTAL2
508 	};
509 
510 	cfig3 = 0;		/* XXX gcc -Wall */
511 
512 	/*
513 	 * if the frequency is between 3493 Hz and 32 kHz we can use a more
514 	 * accurate frequency than the ones listed above base on the formula
515 	 * FREQ/((16*(48+x))) where FREQ is either FREQ_1 (24576000Hz) or
516 	 * FREQ_2 (16934400Hz) and x is the value to be written to either
517 	 * CPVFI or CRVFI. To enable this option, bit 2 in CFIG3 needs to be
518 	 * set high
519 	 *
520 	 * NOT IMPLEMENTED!
521 	 *
522 	 * Note that if you have a 'bad' XTAL_1 (higher than 18.5 MHz), 44.8 kHz
523 	 * and 38.4 kHz modes will provide wrong frequencies to output.
524 	 */
525 
526 
527 	if (freq > 48000)
528 		freq = 48000;
529 	if (freq < 5510)
530 		freq = 5510;
531 
532 	/* reset CFIG3[2] */
533 
534 	IW_READ_CODEC_1(CFIG3I, cfig3);
535 
536 	cfig3 |= 0xc0;		/* not full fifo treshhold */
537 
538 	DPRINTF(("cfig3i = %x -> ", cfig3));
539 
540 	cfig3 &= ~0x04;
541 	IW_WRITE_CODEC_1(CFIG3I, cfig3);
542 	IW_READ_CODEC_1(CFIG3I, cfig3);
543 
544 	DPRINTF(("%x\n", cfig3));
545 
546 	for (var = 0; var < 16; var++)	/* select closest frequency */
547 		if (freq <= iw_cf[var].freq)
548 			break;
549 	if (var != 16)
550 		if (abs(freq - iw_cf[var].freq) > abs(iw_cf[var + 1].freq - freq))
551 			var++;
552 
553 	if (in)
554 		IW_WRITE_CODEC_1(CRDFI | IW_MCE, sc->recfmtbits | iw_cf[var].bits);
555 	else
556 		IW_WRITE_CODEC_1(CPDFI | IW_MCE, sc->playfmtbits | iw_cf[var].bits);
557 	freq = iw_cf[var].freq;
558 	DPRINTF(("setting %s frequency to %d bits %x \n",
559 	       in ? "in" : "out", (int) freq, iw_cf[var].bits));
560 
561 	IW_READ_CODEC_1(CPDFI, reg);
562 
563 	DPRINTF((" CPDFI %x ", reg));
564 
565 	IW_READ_CODEC_1(CRDFI, reg);
566 
567 	DPRINTF((" CRDFI %x ", reg));
568 
569 	return freq;
570 }
571 
572 /* Encoding. */
573 int
574 iw_query_encoding(void *addr, audio_encoding_t *fp)
575 {
576 	/*
577 	 * LINEAR, ALAW, ULAW, ADPCM in HW, we'll use linear unsigned
578 	 * hardware mode for all 8-bit modes due to buggy (?) codec.
579 	 */
580 
581 	/*
582 	 * except in wavetable synth. there we have only mu-law and 8 and 16
583 	 * bit linear data
584 	 */
585 
586 	switch (fp->index) {
587 	case 0:
588 		strcpy(fp->name, AudioEulinear);
589 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
590 		fp->precision = 8;
591 		fp->flags = 0;
592 		break;
593 	case 1:
594 		strcpy(fp->name, AudioEmulaw);
595 		fp->encoding = AUDIO_ENCODING_ULAW;
596 		fp->precision = 8;
597 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
598 		break;
599 	case 2:
600 		strcpy(fp->name, AudioEalaw);
601 		fp->encoding = AUDIO_ENCODING_ALAW;
602 		fp->precision = 8;
603 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
604 		break;
605 	case 3:
606 		strcpy(fp->name, AudioEadpcm);
607 		fp->encoding = AUDIO_ENCODING_ADPCM;
608 		fp->precision = 8;	/* really 4 bit */
609 		fp->flags = 0;
610 		break;
611 	case 4:
612 		strcpy(fp->name, AudioEslinear_le);
613 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
614 		fp->precision = 16;
615 		fp->flags = 0;
616 		break;
617 	case 5:
618 		strcpy(fp->name, AudioEslinear_be);
619 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
620 		fp->precision = 16;
621 		fp->flags = 0;
622 		break;
623 	default:
624 		return EINVAL;
625 		/* NOTREACHED */
626 	}
627 	return 0;
628 }
629 
630 u_long
631 iw_set_format(struct iw_softc *sc, u_long precision, int in)
632 {
633 	u_char	data;
634 	int	encoding, channels;
635 
636 	encoding = in ? sc->rec_encoding : sc->play_encoding;
637 	channels = in ? sc->rec_channels : sc->play_channels;
638 
639 	DPRINTF(("iw_set_format\n"));
640 
641 	switch (encoding) {
642 	case AUDIO_ENCODING_ULAW:
643 		data = 0x00;
644 		break;
645 
646 	case AUDIO_ENCODING_ALAW:
647 		data = 0x00;
648 		break;
649 
650 	case AUDIO_ENCODING_SLINEAR_LE:
651 		if (precision == 16)
652 			data = 0x40;	/* little endian. 0xc0 is big endian */
653 		else
654 			data = 0x00;
655 		break;
656 
657 	case AUDIO_ENCODING_SLINEAR_BE:
658 		if (precision == 16)
659 			data = 0xc0;
660 		else
661 			data = 0x00;
662 		break;
663 
664 	case AUDIO_ENCODING_ADPCM:
665 		data = 0xa0;
666 		break;
667 
668 	default:
669 		return -1;
670 	}
671 
672 	if (channels == 2)
673 		data |= 0x10;	/* stereo */
674 
675 	if (in) {
676 		/* in */
677 		sc->recfmtbits = data;
678 		/* This will zero the normal codec frequency,
679 		 * iw_set_speed should always be called afterwards.
680 		 */
681 		IW_WRITE_CODEC_1(CRDFI | IW_MCE, data);
682 	} else {
683 		/* out */
684 		sc->playfmtbits = data;
685 		IW_WRITE_CODEC_1(CPDFI | IW_MCE, data);
686 	}
687 
688 	DPRINTF(("formatbits %s %x", in ? "in" : "out", data));
689 
690 	return encoding;
691 }
692 
693 int
694 iw_set_params(void *addr, int setmode, int usemode, audio_params_t *p,
695     audio_params_t *q, stream_filter_list_t *pfil, stream_filter_list_t *rfil)
696 {
697 	audio_params_t phw, rhw;
698 	struct iw_softc *sc;
699 	stream_filter_factory_t *swcode;
700 
701 	DPRINTF(("iw_setparams: code %u, prec %u, rate %u, chan %u\n",
702 	    p->encoding, p->precision, p->sample_rate, p->channels));
703 	sc = addr;
704 	swcode = NULL;
705 	phw = *p;
706 	rhw = *q;
707 	switch (p->encoding) {
708 	case AUDIO_ENCODING_ULAW:
709 		if (p->precision != 8)
710 			return EINVAL;
711 		phw.encoding = AUDIO_ENCODING_ULINEAR_LE;
712 		rhw.encoding = AUDIO_ENCODING_ULINEAR_LE;
713 		swcode = setmode & AUMODE_PLAY ? mulaw_to_linear8 : linear8_to_mulaw;
714 		break;
715 	case AUDIO_ENCODING_ALAW:
716 		if (p->precision != 8)
717 			return EINVAL;
718 		phw.encoding = AUDIO_ENCODING_ULINEAR_LE;
719 		rhw.encoding = AUDIO_ENCODING_ULINEAR_LE;
720 		swcode = setmode & AUMODE_PLAY ? alaw_to_linear8 : linear8_to_alaw;
721 		break;
722 	case AUDIO_ENCODING_ADPCM:
723 		if (p->precision != 8)
724 			return EINVAL;
725 		else
726 			break;
727 
728 	case AUDIO_ENCODING_SLINEAR_LE:
729 	case AUDIO_ENCODING_SLINEAR_BE:
730 		if (p->precision != 8 && p->precision != 16)
731 			return EINVAL;
732 		else
733 			break;
734 
735 	default:
736 		return EINVAL;
737 
738 	}
739 
740 	if (setmode & AUMODE_PLAY) {
741 		sc->play_channels = p->channels;
742 		sc->play_encoding = p->encoding;
743 		sc->play_precision = p->precision;
744 		iw_set_format(sc, p->precision, 0);
745 		q->sample_rate = p->sample_rate = sc->sc_orate =
746 			iw_set_speed(sc, p->sample_rate, 0);
747 		if (swcode != NULL) {
748 			phw.sample_rate = p->sample_rate;
749 			pfil->append(pfil, swcode, &phw);
750 		}
751 	} else {
752 #if 0
753 		q->channels = sc->rec_channels = p->channels;
754 		q->encoding = sc->rec_encoding = p->encoding;
755 		q->precision = sc->rec_precision = p->precision;
756 #endif
757 		sc->rec_channels = q->channels;
758 		sc->rec_encoding = q->encoding;
759 		sc->rec_precision = q->precision;
760 
761 		iw_set_format(sc, p->precision, 1);
762 		q->sample_rate = sc->sc_irate =
763 			iw_set_speed(sc, q->sample_rate, 1);
764 		if (swcode != NULL) {
765 			rhw.sample_rate = q->sample_rate;
766 			rfil->append(rfil, swcode, &rhw);
767 		}
768 	}
769 	return 0;
770 }
771 
772 
773 int
774 iw_round_blocksize(void *addr, int blk, int mode,
775     const audio_params_t *param)
776 {
777 
778 	/* Round to a multiple of the biggest sample size. */
779 	return blk &= -4;
780 }
781 
782 void
783 iw_mixer_line_level(struct iw_softc *sc, int line, int levl, int levr)
784 {
785 	u_char	gainl, gainr, attenl, attenr;
786 
787 	switch (line) {
788 	case IW_REC:
789 		gainl = sc->sc_recsrcbits | (levl >> 4);
790 		gainr = sc->sc_recsrcbits | (levr >> 4);
791 		DPRINTF(("recording with %x", gainl));
792 		IW_WRITE_CODEC_1(CLICI, gainl);
793 		IW_WRITE_CODEC_1(CRICI, gainr);
794 		sc->sc_rec.voll = levl & 0xf0;
795 		sc->sc_rec.volr = levr & 0xf0;
796 		break;
797 
798 	case IW_AUX1:
799 
800 		gainl = (255 - levl) >> 3;
801 		gainr = (255 - levr) >> 3;
802 
803 		/* mute if 0 level */
804 		if (levl == 0)
805 			gainl |= 0x80;
806 		if (levr == 0)
807 			gainr |= 0x80;
808 
809 		IW_WRITE_CODEC_1(IW_LEFT_AUX1_PORT, gainl);
810 		IW_WRITE_CODEC_1(IW_RIGHT_AUX1_PORT, gainr);
811 		sc->sc_aux1.voll = levl & 0xf8;
812 		sc->sc_aux1.volr = levr & 0xf8;
813 
814 		break;
815 
816 	case IW_AUX2:
817 
818 		gainl = (255 - levl) >> 3;
819 		gainr = (255 - levr) >> 3;
820 
821 		/* mute if 0 level */
822 		if (levl == 0)
823 			gainl |= 0x80;
824 		if (levr == 0)
825 			gainr |= 0x80;
826 
827 		IW_WRITE_CODEC_1(IW_LEFT_AUX2_PORT, gainl);
828 		IW_WRITE_CODEC_1(IW_RIGHT_AUX2_PORT, gainr);
829 		sc->sc_aux2.voll = levl & 0xf8;
830 		sc->sc_aux2.volr = levr & 0xf8;
831 		break;
832 	case IW_DAC:
833 		attenl = ((255 - levl) >> 2) | ((levl && !sc->sc_dac.off) ? 0 : 0x80);
834 		attenr = ((255 - levr) >> 2) | ((levr && !sc->sc_dac.off) ? 0 : 0x80);
835 		IW_WRITE_CODEC_1(CLDACI, attenl);
836 		IW_WRITE_CODEC_1(CRDACI, attenr);
837 		sc->sc_dac.voll = levl & 0xfc;
838 		sc->sc_dac.volr = levr & 0xfc;
839 		break;
840 	case IW_LOOPBACK:
841 		attenl = ((255 - levl) & 0xfc) | (levl ? 0x01 : 0);
842 		IW_WRITE_CODEC_1(CLCI, attenl);
843 		sc->sc_loopback.voll = levl & 0xfc;
844 		break;
845 	case IW_LINE_IN:
846 		gainl = (levl >> 3) | (levl ? 0 : 0x80);
847 		gainr = (levr >> 3) | (levr ? 0 : 0x80);
848 		IW_WRITE_CODEC_1(CLLICI, gainl);
849 		IW_WRITE_CODEC_1(CRLICI, gainr);
850 		sc->sc_linein.voll = levl & 0xf8;
851 		sc->sc_linein.volr = levr & 0xf8;
852 		break;
853 	case IW_MIC_IN:
854 		gainl = ((255 - levl) >> 3) | (levl ? 0 : 0x80);
855 		gainr = ((255 - levr) >> 3) | (levr ? 0 : 0x80);
856 		IW_WRITE_CODEC_1(CLMICI, gainl);
857 		IW_WRITE_CODEC_1(CRMICI, gainr);
858 		sc->sc_mic.voll = levl & 0xf8;
859 		sc->sc_mic.volr = levr & 0xf8;
860 		break;
861 	case IW_LINE_OUT:
862 		attenl = ((255 - levl) >> 3) | (levl ? 0 : 0x80);
863 		attenr = ((255 - levr) >> 3) | (levr ? 0 : 0x80);
864 		IW_WRITE_CODEC_1(CLOAI, attenl);
865 		IW_WRITE_CODEC_1(CROAI, attenr);
866 		sc->sc_lineout.voll = levl & 0xf8;
867 		sc->sc_lineout.volr = levr & 0xf8;
868 		break;
869 	case IW_MONO_IN:
870 		attenl = ((255 - levl) >> 4) | (levl ? 0 : 0xc0);	/* in/out mute */
871 		IW_WRITE_CODEC_1(CMONOI, attenl);
872 		sc->sc_monoin.voll = levl & 0xf0;
873 		break;
874 	}
875 }
876 
877 int
878 iw_commit_settings(void *addr)
879 {
880 
881 	return 0;
882 }
883 
884 void
885 iw_trigger_dma(struct iw_softc *sc, u_char io)
886 {
887 	u_char	reg;
888 	int	s;
889 
890 	s = splaudio();
891 
892 	IW_READ_CODEC_1(CSR3I, reg);
893 	IW_WRITE_CODEC_1(CSR3I, reg & ~(io == IW_DMA_PLAYBACK ? 0x10 : 0x20));
894 
895 	IW_READ_CODEC_1(CFIG1I, reg);
896 
897 	IW_WRITE_CODEC_1(CFIG1I, reg | io);
898 
899 	/* let the counter run */
900 	IW_READ_CODEC_1(CFIG2I, reg);
901 	IW_WRITE_CODEC_1(CFIG2I, reg & ~(io << 4));
902 
903 	splx(s);
904 }
905 
906 void
907 iw_stop_dma(struct iw_softc *sc, u_char io, u_char hard)
908 {
909 	u_char	reg;
910 
911 	/* just stop the counter, no need to flush the fifo */
912 	IW_READ_CODEC_1(CFIG2I, reg);
913 	IW_WRITE_CODEC_1(CFIG2I, (reg | (io << 4)));
914 
915 	if (hard) {
916 		/* unless we're closing the device */
917 		IW_READ_CODEC_1(CFIG1I, reg);
918 		IW_WRITE_CODEC_1(CFIG1I, reg & ~io);
919 	}
920 }
921 
922 void
923 iw_dma_count(struct iw_softc *sc, u_short count, int io)
924 {
925 
926 	if (io == IW_DMA_PLAYBACK) {
927 		IW_WRITE_CODEC_1(CLPCTI, (u_char) (count & 0x00ff));
928 		IW_WRITE_CODEC_1(CUPCTI, (u_char) ((count >> 8) & 0x00ff));
929 	} else {
930 		IW_WRITE_CODEC_1(CLRCTI, (u_char) (count & 0x00ff));
931 		IW_WRITE_CODEC_1(CURCTI, (u_char) ((count >> 8) & 0x00ff));
932 	}
933 }
934 
935 int
936 iw_init_output(void *addr, void *sbuf, int cc)
937 {
938 	struct iw_softc *sc = (struct iw_softc *) addr;
939 
940 	DPRINTF(("iw_init_output\n"));
941 
942 	isa_dmastart(sc->sc_ic, sc->sc_playdrq, sbuf,
943 		     cc, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
944 	return 0;
945 }
946 
947 int
948 iw_init_input(void *addr, void *sbuf, int cc)
949 {
950 	struct	iw_softc *sc;
951 
952 	DPRINTF(("iw_init_input\n"));
953 	sc = (struct iw_softc *) addr;
954 	isa_dmastart(sc->sc_ic, sc->sc_recdrq, sbuf,
955 		     cc, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT);
956 	return 0;
957 }
958 
959 
960 int
961 iw_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
962 {
963 	struct	iw_softc *sc;
964 
965 #ifdef DIAGNOSTIC
966 	if (!intr) {
967 		printf("iw_start_output: no callback!\n");
968 		return 1;
969 	}
970 #endif
971 	sc = addr;
972 	sc->sc_playintr = intr;
973 	sc->sc_playarg = arg;
974 	sc->sc_dma_flags |= DMAMODE_WRITE;
975 	sc->sc_playdma_bp = p;
976 
977 	isa_dmastart(sc->sc_ic, sc->sc_playdrq, sc->sc_playdma_bp,
978 	    cc, NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
979 
980 
981 	if (sc->play_encoding == AUDIO_ENCODING_ADPCM)
982 		cc >>= 2;
983 	if (sc->play_precision == 16)
984 		cc >>= 1;
985 
986 	if (sc->play_channels == 2 && sc->play_encoding != AUDIO_ENCODING_ADPCM)
987 		cc >>= 1;
988 
989 	cc -= iw_cc;
990 
991 	/* iw_dma_access(sc,1); */
992 	if (cc != sc->sc_playdma_cnt) {
993 		iw_dma_count(sc, (u_short) cc, IW_DMA_PLAYBACK);
994 		sc->sc_playdma_cnt = cc;
995 
996 		iw_trigger_dma(sc, IW_DMA_PLAYBACK);
997 	}
998 
999 #ifdef DIAGNOSTIC
1000 	if (outputs != iw_ints)
1001 		printf("iw_start_output: out %d, int %d\n", outputs, iw_ints);
1002 	outputs++;
1003 #endif
1004 
1005 	return 0;
1006 }
1007 
1008 
1009 int
1010 iw_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
1011 {
1012 	struct	iw_softc *sc;
1013 
1014 #ifdef DIAGNOSTIC
1015 	if (!intr) {
1016 		printf("iw_start_input: no callback!\n");
1017 		return 1;
1018 	}
1019 #endif
1020 	sc = addr;
1021 	sc->sc_recintr = intr;
1022 	sc->sc_recarg = arg;
1023 	sc->sc_dma_flags |= DMAMODE_READ;
1024 	sc->sc_recdma_bp = p;
1025 
1026 	isa_dmastart(sc->sc_ic, sc->sc_recdrq, sc->sc_recdma_bp,
1027 	    cc, NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
1028 
1029 
1030 	if (sc->rec_encoding == AUDIO_ENCODING_ADPCM)
1031 		cc >>= 2;
1032 	if (sc->rec_precision == 16)
1033 		cc >>= 1;
1034 
1035 	if (sc->rec_channels == 2 && sc->rec_encoding != AUDIO_ENCODING_ADPCM)
1036 		cc >>= 1;
1037 
1038 	cc -= iw_cc;
1039 
1040 	/* iw_dma_access(sc,0); */
1041 	if (sc->sc_recdma_cnt != cc) {
1042 		iw_dma_count(sc, (u_short) cc, IW_DMA_RECORD);
1043 		sc->sc_recdma_cnt = cc;
1044 		/* iw_dma_ctrl(sc, IW_DMA_RECORD); */
1045 		iw_trigger_dma(sc, IW_DMA_RECORD);
1046 	}
1047 
1048 #ifdef DIAGNOSTIC
1049 	if ((inputs != iw_inints))
1050 		printf("iw_start_input: in %d, inints %d\n", inputs, iw_inints);
1051 	inputs++;
1052 #endif
1053 
1054 	return 0;
1055 }
1056 
1057 
1058 int
1059 iw_halt_output(void *addr)
1060 {
1061 	struct	iw_softc *sc;
1062 
1063 	sc = addr;
1064 	iw_stop_dma(sc, IW_DMA_PLAYBACK, 0);
1065 	return 0;
1066 }
1067 
1068 
1069 int
1070 iw_halt_input(void *addr)
1071 {
1072 	struct	iw_softc *sc;
1073 
1074 	sc = addr;
1075 	iw_stop_dma(sc, IW_DMA_RECORD, 0);
1076 	return 0;
1077 }
1078 
1079 int
1080 iw_speaker_ctl(void *addr, int newstate)
1081 {
1082 	struct iw_softc *sc;
1083 	u_char reg;
1084 
1085 	sc = addr;
1086 	if (newstate == SPKR_ON) {
1087 		sc->sc_dac.off = 0;
1088 		IW_READ_CODEC_1(CLDACI, reg);
1089 		IW_WRITE_CODEC_1(CLDACI, reg & 0x7f);
1090 		IW_READ_CODEC_1(CRDACI, reg);
1091 		IW_WRITE_CODEC_1(CRDACI, reg & 0x7f);
1092 	} else {
1093 		/* SPKR_OFF */
1094 		sc->sc_dac.off = 1;
1095 		IW_READ_CODEC_1(CLDACI, reg);
1096 		IW_WRITE_CODEC_1(CLDACI, reg | 0x80);
1097 		IW_READ_CODEC_1(CRDACI, reg);
1098 		IW_WRITE_CODEC_1(CRDACI, reg | 0x80);
1099 	}
1100 	return 0;
1101 }
1102 
1103 int
1104 iw_getdev(void *addr, struct audio_device *retp)
1105 {
1106 
1107 	*retp = iw_device;
1108 	return 0;
1109 }
1110 
1111 int
1112 iw_setfd(void *addr, int flag)
1113 {
1114 
1115 	return 0;
1116 }
1117 
1118 /* Mixer (in/out ports) */
1119 int
1120 iw_set_port(void *addr, mixer_ctrl_t *cp)
1121 {
1122 	struct iw_softc *sc;
1123 	u_char vall, valr;
1124 	int error;
1125 
1126 	sc = addr;
1127 	vall = 0;
1128 	valr = 0;
1129 	error = EINVAL;
1130 	switch (cp->dev) {
1131 	case IW_MIC_IN_LVL:
1132 		if (cp->type == AUDIO_MIXER_VALUE) {
1133 			error = 0;
1134 			if (cp->un.value.num_channels == 1) {
1135 				vall = valr = cp->un.value.level[0];
1136 			} else {
1137 				vall = cp->un.value.level[0];
1138 				valr = cp->un.value.level[1];
1139 			}
1140 			sc->sc_mic.voll = vall;
1141 			sc->sc_mic.volr = valr;
1142 			iw_mixer_line_level(sc, IW_MIC_IN, vall, valr);
1143 		}
1144 		break;
1145 	case IW_AUX1_LVL:
1146 		if (cp->type == AUDIO_MIXER_VALUE) {
1147 			error = 0;
1148 			if (cp->un.value.num_channels == 1) {
1149 				vall = valr = cp->un.value.level[0];
1150 			} else {
1151 				vall = cp->un.value.level[0];
1152 				valr = cp->un.value.level[1];
1153 			}
1154 			sc->sc_aux1.voll = vall;
1155 			sc->sc_aux1.volr = valr;
1156 			iw_mixer_line_level(sc, IW_AUX1, vall, valr);
1157 		}
1158 		break;
1159 	case IW_AUX2_LVL:
1160 		if (cp->type == AUDIO_MIXER_VALUE) {
1161 			error = 0;
1162 			if (cp->un.value.num_channels == 1) {
1163 				vall = valr = cp->un.value.level[0];
1164 			} else {
1165 				vall = cp->un.value.level[0];
1166 				valr = cp->un.value.level[1];
1167 			}
1168 			sc->sc_aux2.voll = vall;
1169 			sc->sc_aux2.volr = valr;
1170 			iw_mixer_line_level(sc, IW_AUX2, vall, valr);
1171 		}
1172 		break;
1173 	case IW_LINE_IN_LVL:
1174 		if (cp->type == AUDIO_MIXER_VALUE) {
1175 			error = 0;
1176 			if (cp->un.value.num_channels == 1) {
1177 				vall = valr = cp->un.value.level[0];
1178 			} else {
1179 				vall = cp->un.value.level[0];
1180 				valr = cp->un.value.level[1];
1181 			}
1182 			sc->sc_linein.voll = vall;
1183 			sc->sc_linein.volr = valr;
1184 			iw_mixer_line_level(sc, IW_LINE_IN, vall, valr);
1185 		}
1186 		break;
1187 	case IW_LINE_OUT_LVL:
1188 		if (cp->type == AUDIO_MIXER_VALUE) {
1189 			error = 0;
1190 			if (cp->un.value.num_channels == 1) {
1191 				vall = valr = cp->un.value.level[0];
1192 			} else {
1193 				vall = cp->un.value.level[0];
1194 				valr = cp->un.value.level[1];
1195 			}
1196 			sc->sc_lineout.voll = vall;
1197 			sc->sc_lineout.volr = valr;
1198 			iw_mixer_line_level(sc, IW_LINE_OUT, vall, valr);
1199 		}
1200 		break;
1201 	case IW_REC_LVL:
1202 		if (cp->type == AUDIO_MIXER_VALUE) {
1203 			error = 0;
1204 			if (cp->un.value.num_channels == 1) {
1205 				vall = valr = cp->un.value.level[0];
1206 			} else {
1207 				vall = cp->un.value.level[0];
1208 				valr = cp->un.value.level[1];
1209 			}
1210 			sc->sc_rec.voll = vall;
1211 			sc->sc_rec.volr = valr;
1212 			iw_mixer_line_level(sc, IW_REC, vall, valr);
1213 		}
1214 		break;
1215 
1216 	case IW_DAC_LVL:
1217 		if (cp->type == AUDIO_MIXER_VALUE) {
1218 			error = 0;
1219 			if (cp->un.value.num_channels == 1) {
1220 				vall = valr = cp->un.value.level[0];
1221 			} else {
1222 				vall = cp->un.value.level[0];
1223 				valr = cp->un.value.level[1];
1224 			}
1225 			sc->sc_dac.voll = vall;
1226 			sc->sc_dac.volr = valr;
1227 			iw_mixer_line_level(sc, IW_DAC, vall, valr);
1228 		}
1229 		break;
1230 
1231 	case IW_LOOPBACK_LVL:
1232 		if (cp->type == AUDIO_MIXER_VALUE) {
1233 			error = 0;
1234 			if (cp->un.value.num_channels != 1) {
1235 				return EINVAL;
1236 			} else {
1237 				valr = vall = cp->un.value.level[0];
1238 			}
1239 			sc->sc_loopback.voll = vall;
1240 			sc->sc_loopback.volr = valr;
1241 			iw_mixer_line_level(sc, IW_LOOPBACK, vall, valr);
1242 		}
1243 		break;
1244 
1245 	case IW_MONO_IN_LVL:
1246 		if (cp->type == AUDIO_MIXER_VALUE) {
1247 			error = 0;
1248 			if (cp->un.value.num_channels != 1) {
1249 				return EINVAL;
1250 			} else {
1251 				valr = vall = cp->un.value.level[0];
1252 			}
1253 			sc->sc_monoin.voll = vall;
1254 			sc->sc_monoin.volr = valr;
1255 			iw_mixer_line_level(sc, IW_MONO_IN, vall, valr);
1256 		}
1257 		break;
1258 	case IW_RECORD_SOURCE:
1259 		error = 0;
1260 		sc->sc_recsrcbits = cp->un.ord << 6;
1261 		DPRINTF(("record source %d bits %x\n", cp->un.ord, sc->sc_recsrcbits));
1262 		iw_mixer_line_level(sc, IW_REC, sc->sc_rec.voll, sc->sc_rec.volr);
1263 		break;
1264 	}
1265 
1266 	return error;
1267 }
1268 
1269 
1270 int
1271 iw_get_port(void *addr, mixer_ctrl_t *cp)
1272 {
1273 	struct iw_softc *sc;
1274 	int error;
1275 
1276 	sc = addr;
1277 	error = EINVAL;
1278 	switch (cp->dev) {
1279 	case IW_MIC_IN_LVL:
1280 		if (cp->type == AUDIO_MIXER_VALUE) {
1281 			cp->un.value.num_channels = 2;
1282 			cp->un.value.level[0] = sc->sc_mic.voll;
1283 			cp->un.value.level[1] = sc->sc_mic.volr;
1284 			error = 0;
1285 		}
1286 		break;
1287 	case IW_AUX1_LVL:
1288 		if (cp->type == AUDIO_MIXER_VALUE) {
1289 			cp->un.value.num_channels = 2;
1290 			cp->un.value.level[0] = sc->sc_aux1.voll;
1291 			cp->un.value.level[1] = sc->sc_aux1.volr;
1292 			error = 0;
1293 		}
1294 		break;
1295 	case IW_AUX2_LVL:
1296 		if (cp->type == AUDIO_MIXER_VALUE) {
1297 			cp->un.value.num_channels = 2;
1298 			cp->un.value.level[0] = sc->sc_aux2.voll;
1299 			cp->un.value.level[1] = sc->sc_aux2.volr;
1300 			error = 0;
1301 		}
1302 		break;
1303 	case IW_LINE_OUT_LVL:
1304 		if (cp->type == AUDIO_MIXER_VALUE) {
1305 			cp->un.value.num_channels = 2;
1306 			cp->un.value.level[0] = sc->sc_lineout.voll;
1307 			cp->un.value.level[1] = sc->sc_lineout.volr;
1308 			error = 0;
1309 		}
1310 		break;
1311 	case IW_LINE_IN_LVL:
1312 		if (cp->type == AUDIO_MIXER_VALUE) {
1313 			cp->un.value.num_channels = 2;
1314 			cp->un.value.level[0] = sc->sc_linein.voll;
1315 			cp->un.value.level[1] = sc->sc_linein.volr;
1316 			error = 0;
1317 		}
1318 	case IW_REC_LVL:
1319 		if (cp->type == AUDIO_MIXER_VALUE) {
1320 			cp->un.value.num_channels = 2;
1321 			cp->un.value.level[0] = sc->sc_rec.voll;
1322 			cp->un.value.level[1] = sc->sc_rec.volr;
1323 			error = 0;
1324 		}
1325 		break;
1326 
1327 	case IW_DAC_LVL:
1328 		if (cp->type == AUDIO_MIXER_VALUE) {
1329 			cp->un.value.num_channels = 2;
1330 			cp->un.value.level[0] = sc->sc_dac.voll;
1331 			cp->un.value.level[1] = sc->sc_dac.volr;
1332 			error = 0;
1333 		}
1334 		break;
1335 
1336 	case IW_LOOPBACK_LVL:
1337 		if (cp->type == AUDIO_MIXER_VALUE) {
1338 			cp->un.value.num_channels = 1;
1339 			cp->un.value.level[0] = sc->sc_loopback.voll;
1340 			error = 0;
1341 		}
1342 		break;
1343 
1344 	case IW_MONO_IN_LVL:
1345 		if (cp->type == AUDIO_MIXER_VALUE) {
1346 			cp->un.value.num_channels = 1;
1347 			cp->un.value.level[0] = sc->sc_monoin.voll;
1348 			error = 0;
1349 		}
1350 		break;
1351 	case IW_RECORD_SOURCE:
1352 		cp->un.ord = sc->sc_recsrcbits >> 6;
1353 		error = 0;
1354 		break;
1355 	}
1356 
1357 	return error;
1358 }
1359 
1360 
1361 
1362 int
1363 iw_query_devinfo(void *addr, mixer_devinfo_t *dip)
1364 {
1365 
1366 	switch (dip->index) {
1367 	case IW_MIC_IN_LVL:	/* Microphone */
1368 		dip->type = AUDIO_MIXER_VALUE;
1369 		dip->mixer_class = IW_INPUT_CLASS;
1370 		dip->prev = AUDIO_MIXER_LAST;
1371 		dip->next = AUDIO_MIXER_LAST;
1372 		strcpy(dip->label.name, AudioNmicrophone);
1373 		dip->un.v.num_channels = 2;
1374 		strcpy(dip->un.v.units.name, AudioNvolume);
1375 		break;
1376 	case IW_AUX1_LVL:
1377 		dip->type = AUDIO_MIXER_VALUE;
1378 		dip->mixer_class = IW_INPUT_CLASS;
1379 		dip->prev = AUDIO_MIXER_LAST;
1380 		dip->next = AUDIO_MIXER_LAST;
1381 		strcpy(dip->label.name, AudioNline);
1382 		dip->un.v.num_channels = 2;
1383 		strcpy(dip->un.v.units.name, AudioNvolume);
1384 		break;
1385 	case IW_AUX2_LVL:
1386 		dip->type = AUDIO_MIXER_VALUE;
1387 		dip->mixer_class = IW_INPUT_CLASS;
1388 		dip->prev = AUDIO_MIXER_LAST;
1389 		dip->next = AUDIO_MIXER_LAST;
1390 		strcpy(dip->label.name, AudioNcd);
1391 		dip->un.v.num_channels = 2;
1392 		strcpy(dip->un.v.units.name, AudioNvolume);
1393 		break;
1394 	case IW_LINE_OUT_LVL:
1395 		dip->type = AUDIO_MIXER_VALUE;
1396 		dip->mixer_class = IW_OUTPUT_CLASS;
1397 		dip->prev = AUDIO_MIXER_LAST;
1398 		dip->next = AUDIO_MIXER_LAST;
1399 		strcpy(dip->label.name, AudioNline);
1400 		dip->un.v.num_channels = 2;
1401 		strcpy(dip->un.v.units.name, AudioNvolume);
1402 		break;
1403 	case IW_DAC_LVL:
1404 		dip->type = AUDIO_MIXER_VALUE;
1405 		dip->mixer_class = IW_OUTPUT_CLASS;
1406 		dip->prev = AUDIO_MIXER_LAST;
1407 		dip->next = AUDIO_MIXER_LAST;
1408 		strcpy(dip->label.name, AudioNdac);
1409 		dip->un.v.num_channels = 2;
1410 		strcpy(dip->un.v.units.name, AudioNvolume);
1411 		break;
1412 	case IW_LINE_IN_LVL:
1413 		dip->type = AUDIO_MIXER_VALUE;
1414 		dip->mixer_class = IW_INPUT_CLASS;
1415 		dip->prev = AUDIO_MIXER_LAST;
1416 		dip->next = AUDIO_MIXER_LAST;
1417 		strcpy(dip->label.name, AudioNinput);
1418 		dip->un.v.num_channels = 2;
1419 		strcpy(dip->un.v.units.name, AudioNvolume);
1420 		break;
1421 	case IW_MONO_IN_LVL:
1422 		dip->type = AUDIO_MIXER_VALUE;
1423 		dip->mixer_class = IW_INPUT_CLASS;
1424 		dip->prev = AUDIO_MIXER_LAST;
1425 		dip->next = AUDIO_MIXER_LAST;
1426 		strcpy(dip->label.name, AudioNmono);
1427 		dip->un.v.num_channels = 1;
1428 		strcpy(dip->un.v.units.name, AudioNvolume);
1429 		break;
1430 
1431 	case IW_REC_LVL:	/* record level */
1432 		dip->type = AUDIO_MIXER_VALUE;
1433 		dip->mixer_class = IW_RECORD_CLASS;
1434 		dip->prev = AUDIO_MIXER_LAST;
1435 		dip->next = AUDIO_MIXER_LAST;
1436 		strcpy(dip->label.name, AudioNrecord);
1437 		dip->un.v.num_channels = 2;
1438 		strcpy(dip->un.v.units.name, AudioNvolume);
1439 		break;
1440 
1441 	case IW_LOOPBACK_LVL:
1442 		dip->type = AUDIO_MIXER_VALUE;
1443 		dip->mixer_class = IW_RECORD_CLASS;
1444 		dip->prev = AUDIO_MIXER_LAST;
1445 		dip->next = AUDIO_MIXER_LAST;
1446 		strcpy(dip->label.name, "filter");
1447 		dip->un.v.num_channels = 1;
1448 		strcpy(dip->un.v.units.name, AudioNvolume);
1449 		break;
1450 
1451 	case IW_RECORD_SOURCE:
1452 		dip->mixer_class = IW_RECORD_CLASS;
1453 		dip->type = AUDIO_MIXER_ENUM;
1454 		dip->prev = AUDIO_MIXER_LAST;
1455 		dip->next = AUDIO_MIXER_LAST;
1456 		strcpy(dip->label.name, AudioNsource);
1457 		dip->un.e.num_mem = 4;
1458 		strcpy(dip->un.e.member[0].label.name, AudioNline);
1459 		dip->un.e.member[0].ord = IW_LINE_IN_SRC;
1460 		strcpy(dip->un.e.member[1].label.name, "aux1");
1461 		dip->un.e.member[1].ord = IW_AUX1_SRC;
1462 		strcpy(dip->un.e.member[2].label.name, AudioNmicrophone);
1463 		dip->un.e.member[2].ord = IW_MIC_IN_SRC;
1464 		strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
1465 		dip->un.e.member[3].ord = IW_MIX_OUT_SRC;
1466 		break;
1467 	case IW_INPUT_CLASS:
1468 		dip->type = AUDIO_MIXER_CLASS;
1469 		dip->mixer_class = IW_INPUT_CLASS;
1470 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1471 		strcpy(dip->label.name, AudioCinputs);
1472 		break;
1473 	case IW_OUTPUT_CLASS:
1474 		dip->type = AUDIO_MIXER_CLASS;
1475 		dip->mixer_class = IW_OUTPUT_CLASS;
1476 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1477 		strcpy(dip->label.name, AudioCoutputs);
1478 		break;
1479 	case IW_RECORD_CLASS:	/* record source class */
1480 		dip->type = AUDIO_MIXER_CLASS;
1481 		dip->mixer_class = IW_RECORD_CLASS;
1482 		dip->next = dip->prev = AUDIO_MIXER_LAST;
1483 		strcpy(dip->label.name, AudioCrecord);
1484 		return 0;
1485 	default:
1486 		return ENXIO;
1487 	}
1488 	return 0;
1489 }
1490 
1491 
1492 void *
1493 iw_malloc(void *addr, int direction, size_t size,
1494     struct malloc_type *pool, int flags)
1495 {
1496 	struct iw_softc *sc;
1497 	int drq;
1498 
1499 	sc = addr;
1500 	if (direction == AUMODE_PLAY)
1501 		drq = sc->sc_playdrq;
1502 	else
1503 		drq = sc->sc_recdrq;
1504 	return isa_malloc(sc->sc_ic, drq, size, pool, flags);
1505 }
1506 
1507 void
1508 iw_free(void *addr, void *ptr, struct malloc_type *pool)
1509 {
1510 	isa_free(ptr, pool);
1511 }
1512 
1513 size_t
1514 iw_round_buffersize(void *addr, int direction, size_t size)
1515 {
1516 	struct iw_softc *sc;
1517 	bus_size_t maxsize;
1518 
1519 	sc = addr;
1520 	if (direction == AUMODE_PLAY)
1521 		maxsize = sc->sc_play_maxsize;
1522 	else
1523 		maxsize = sc->sc_rec_maxsize;
1524 
1525 	if (size > maxsize)
1526 		size = maxsize;
1527 	return size;
1528 }
1529 
1530 paddr_t
1531 iw_mappage(void *addr, void *mem, off_t off, int prot)
1532 {
1533 
1534 	return isa_mappage(mem, off, prot);
1535 }
1536 
1537 int
1538 iw_get_props(void *addr)
1539 {
1540 	struct iw_softc *sc;
1541 
1542 	sc = addr;
1543 	return AUDIO_PROP_MMAP |
1544 		(sc->sc_fullduplex ? AUDIO_PROP_FULLDUPLEX : 0);
1545 }
1546