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