No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / ic / am7930.c
blobbde4931ff1090c0e3aa578186deb5940ee114126
1 /* $NetBSD: am7930.c,v 1.49 2005/12/11 12:21:25 christos Exp $ */
3 /*
4 * Copyright (c) 1995 Rolf Grossmann
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Rolf Grossmann.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Front-end attachment independent layer for AMD 79c30
35 * audio driver. No ISDN support.
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: am7930.c,v 1.49 2005/12/11 12:21:25 christos Exp $");
41 #include "audio.h"
42 #if NAUDIO > 0
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/errno.h>
47 #include <sys/ioctl.h>
48 #include <sys/device.h>
49 #include <sys/proc.h>
51 #include <sys/bus.h>
52 #include <machine/autoconf.h>
53 #include <sys/cpu.h>
55 #include <sys/audioio.h>
56 #include <dev/audio_if.h>
58 #include <dev/ic/am7930reg.h>
59 #include <dev/ic/am7930var.h>
61 #ifdef AUDIO_DEBUG
62 int am7930debug = 0;
63 #define DPRINTF(x) if (am7930debug) printf x
64 #else
65 #define DPRINTF(x)
66 #endif
69 /* The following tables stolen from former (4.4Lite's) sys/sparc/bsd_audio.c */
72 * gx, gr & stg gains. this table must contain 256 elements with
73 * the 0th being "infinity" (the magic value 9008). The remaining
74 * elements match sun's gain curve (but with higher resolution):
75 * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps.
77 static const uint16_t gx_coeff[256] = {
78 0x9008, 0x8e7c, 0x8e51, 0x8e45, 0x8d42, 0x8d3b, 0x8c36, 0x8c33,
79 0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22,
80 0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b,
81 0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb,
82 0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a,
83 0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213,
84 0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231,
85 0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4,
86 0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2,
87 0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa,
88 0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b,
89 0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b,
90 0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd,
91 0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808,
92 0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243,
93 0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224,
94 0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb,
95 0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33,
96 0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32,
97 0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323,
98 0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a,
99 0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23,
100 0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1,
101 0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333,
102 0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227,
103 0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6,
104 0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2,
105 0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba,
106 0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033,
107 0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021,
108 0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012,
109 0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e,
113 * second stage play gain.
115 static const uint16_t ger_coeff[] = {
116 0x431f, /* 5. dB */
117 0x331f, /* 5.5 dB */
118 0x40dd, /* 6. dB */
119 0x11dd, /* 6.5 dB */
120 0x440f, /* 7. dB */
121 0x411f, /* 7.5 dB */
122 0x311f, /* 8. dB */
123 0x5520, /* 8.5 dB */
124 0x10dd, /* 9. dB */
125 0x4211, /* 9.5 dB */
126 0x410f, /* 10. dB */
127 0x111f, /* 10.5 dB */
128 0x600b, /* 11. dB */
129 0x00dd, /* 11.5 dB */
130 0x4210, /* 12. dB */
131 0x110f, /* 13. dB */
132 0x7200, /* 14. dB */
133 0x2110, /* 15. dB */
134 0x2200, /* 15.9 dB */
135 0x000b, /* 16.9 dB */
136 0x000f /* 18. dB */
137 #define NGER (sizeof(ger_coeff) / sizeof(ger_coeff[0]))
142 * Reset chip and set boot-time softc defaults.
144 void
145 am7930_init(struct am7930_softc *sc, int flag)
148 DPRINTF(("am7930_init()\n"));
150 /* set boot defaults */
151 sc->sc_rlevel = 128;
152 sc->sc_plevel = 128;
153 sc->sc_mlevel = 0;
154 sc->sc_out_port = AUDIOAMD_SPEAKER_VOL;
155 sc->sc_mic_mute = 0;
157 /* disable sample interrupts */
158 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 0);
160 /* initialise voice and data, and disable interrupts */
161 AM7930_IWRITE(sc, AM7930_IREG_INIT,
162 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
164 if (flag == AUDIOAMD_DMA_MODE) {
166 /* configure PP for serial (SBP) mode */
167 AM7930_IWRITE(sc, AM7930_IREG_PP_PPCR1, AM7930_PPCR1_SBP);
170 * Initialise the MUX unit - route the MAP to the PP
172 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1,
173 (AM7930_MCRCHAN_BA << 4) | AM7930_MCRCHAN_BD);
174 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, AM7930_MCRCHAN_NC);
175 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, AM7930_MCRCHAN_NC);
177 } else {
180 * Initialize the MUX unit. We use MCR3 to route the MAP
181 * through channel Bb. MCR1 and MCR2 are unused.
182 * Setting the INT enable bit in MCR4 will generate an
183 * interrupt on each converted audio sample.
185 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1, 0);
186 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, 0);
187 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3,
188 (AM7930_MCRCHAN_BB << 4) | AM7930_MCRCHAN_BA);
189 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4,
190 AM7930_MCR4_INT_ENABLE);
196 am7930_open(void *addr, int flags)
198 struct am7930_softc *sc;
200 sc = addr;
201 DPRINTF(("sa_open: unit %p\n", sc));
202 sc->sc_glue->onopen(sc);
203 DPRINTF(("saopen: ok -> sc=%p\n",sc));
204 return 0;
207 void
208 am7930_close(void *addr)
210 struct am7930_softc *sc;
212 sc = addr;
213 DPRINTF(("sa_close: sc=%p\n", sc));
214 sc->sc_glue->onclose(sc);
215 DPRINTF(("sa_close: closed.\n"));
219 * XXX should be extended to handle a few of the more common formats.
222 am7930_set_params(void *addr, int setmode, int usemode, audio_params_t *p,
223 audio_params_t *r, stream_filter_list_t *pfil, stream_filter_list_t *rfil)
225 audio_params_t hw;
226 struct am7930_softc *sc;
228 sc = addr;
229 if ((usemode & AUMODE_PLAY) == AUMODE_PLAY) {
230 if (p->sample_rate < 7500 || p->sample_rate > 8500 ||
231 p->encoding != AUDIO_ENCODING_ULAW ||
232 p->precision != 8 ||
233 p->channels != 1)
234 return EINVAL;
235 p->sample_rate = 8000;
236 if (sc->sc_glue->output_conv != NULL) {
237 hw = *p;
238 hw.encoding = AUDIO_ENCODING_NONE;
239 hw.precision *= sc->sc_glue->factor;
240 pfil->append(pfil, sc->sc_glue->output_conv, &hw);
243 if ((usemode & AUMODE_RECORD) == AUMODE_RECORD) {
244 if (r->sample_rate < 7500 || r->sample_rate > 8500 ||
245 r->encoding != AUDIO_ENCODING_ULAW ||
246 r->precision != 8 ||
247 r->channels != 1)
248 return EINVAL;
249 r->sample_rate = 8000;
250 if (sc->sc_glue->input_conv != NULL) {
251 hw = *r;
252 hw.encoding = AUDIO_ENCODING_NONE;
253 hw.precision *= sc->sc_glue->factor;
254 pfil->append(rfil, sc->sc_glue->input_conv, &hw);
258 return 0;
262 am7930_query_encoding(void *addr, struct audio_encoding *fp)
264 switch (fp->index) {
265 case 0:
266 strcpy(fp->name, AudioEmulaw);
267 fp->encoding = AUDIO_ENCODING_ULAW;
268 fp->precision = 8;
269 fp->flags = 0;
270 break;
271 default:
272 return EINVAL;
273 /*NOTREACHED*/
275 return 0;
279 am7930_round_blocksize(void *addr, int blk,
280 int mode, const audio_params_t *param)
282 return blk;
286 am7930_commit_settings(void *addr)
288 struct am7930_softc *sc;
289 uint16_t ger, gr, gx, stgr;
290 uint8_t mmr2, mmr3;
291 int s, level;
293 DPRINTF(("sa_commit.\n"));
294 sc = addr;
295 gx = gx_coeff[sc->sc_rlevel];
296 stgr = gx_coeff[sc->sc_mlevel];
298 level = (sc->sc_plevel * (256 + NGER)) >> 8;
299 if (level >= 256) {
300 ger = ger_coeff[level - 256];
301 gr = gx_coeff[255];
302 } else {
303 ger = ger_coeff[0];
304 gr = gx_coeff[level];
307 s = splaudio();
309 mmr2 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR2);
310 if (sc->sc_out_port == AUDIOAMD_SPEAKER_VOL)
311 mmr2 |= AM7930_MMR2_LS;
312 else
313 mmr2 &= ~AM7930_MMR2_LS;
314 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR2, mmr2);
316 mmr3 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR3);
317 if (sc->sc_mic_mute)
318 mmr3 |= AM7930_MMR3_MUTE;
319 else
320 mmr3 &= ~AM7930_MMR3_MUTE;
321 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR3, mmr3);
323 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR1,
324 AM7930_MMR1_GX | AM7930_MMR1_GER |
325 AM7930_MMR1_GR | AM7930_MMR1_STG);
327 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GX, gx);
328 AM7930_IWRITE16(sc, AM7930_IREG_MAP_STG, stgr);
329 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GR, gr);
330 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GER, ger);
332 splx(s);
334 return 0;
338 am7930_halt_output(void *addr)
340 struct am7930_softc *sc;
342 sc = addr;
343 /* XXX only halt, if input is also halted ?? */
344 AM7930_IWRITE(sc, AM7930_IREG_INIT,
345 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
346 return 0;
350 am7930_halt_input(void *addr)
352 struct am7930_softc *sc;
354 sc = addr;
355 /* XXX only halt, if output is also halted ?? */
356 AM7930_IWRITE(sc, AM7930_IREG_INIT,
357 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
358 return 0;
362 * XXX chip is full-duplex, but really attach-dependent.
363 * For now we know of no half-duplex attachments.
366 am7930_get_props(void *addr)
368 return AUDIO_PROP_FULLDUPLEX;
372 * Attach-dependent channel set/query
375 am7930_set_port(void *addr, mixer_ctrl_t *cp)
377 struct am7930_softc *sc;
379 DPRINTF(("am7930_set_port: port=%d", cp->dev));
380 sc = addr;
381 if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
382 cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
383 cp->dev == AUDIOAMD_MIC_MUTE) {
384 if (cp->type != AUDIO_MIXER_ENUM)
385 return EINVAL;
386 } else if (cp->type != AUDIO_MIXER_VALUE ||
387 cp->un.value.num_channels != 1) {
388 return EINVAL;
391 switch(cp->dev) {
392 case AUDIOAMD_MIC_VOL:
393 sc->sc_rlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
394 break;
395 case AUDIOAMD_SPEAKER_VOL:
396 case AUDIOAMD_HEADPHONES_VOL:
397 sc->sc_plevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
398 break;
399 case AUDIOAMD_MONITOR_VOL:
400 sc->sc_mlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
401 break;
402 case AUDIOAMD_RECORD_SOURCE:
403 if (cp->un.ord != AUDIOAMD_MIC_VOL)
404 return EINVAL;
405 break;
406 case AUDIOAMD_MIC_MUTE:
407 sc->sc_mic_mute = cp->un.ord;
408 break;
409 case AUDIOAMD_MONITOR_OUTPUT:
410 if (cp->un.ord != AUDIOAMD_SPEAKER_VOL &&
411 cp->un.ord != AUDIOAMD_HEADPHONES_VOL)
412 return EINVAL;
413 sc->sc_out_port = cp->un.ord;
414 break;
415 default:
416 return EINVAL;
417 /* NOTREACHED */
419 return 0;
423 am7930_get_port(void *addr, mixer_ctrl_t *cp)
425 struct am7930_softc *sc;
427 DPRINTF(("am7930_get_port: port=%d\n", cp->dev));
428 sc = addr;
429 if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
430 cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
431 cp->dev == AUDIOAMD_MIC_MUTE) {
432 if (cp->type != AUDIO_MIXER_ENUM)
433 return EINVAL;
434 } else if (cp->type != AUDIO_MIXER_VALUE ||
435 cp->un.value.num_channels != 1) {
436 return EINVAL;
439 switch(cp->dev) {
440 case AUDIOAMD_MIC_VOL:
441 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_rlevel;
442 break;
443 case AUDIOAMD_SPEAKER_VOL:
444 case AUDIOAMD_HEADPHONES_VOL:
445 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_plevel;
446 break;
447 case AUDIOAMD_MONITOR_VOL:
448 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_mlevel;
449 break;
450 case AUDIOAMD_RECORD_SOURCE:
451 cp->un.ord = AUDIOAMD_MIC_VOL;
452 break;
453 case AUDIOAMD_MIC_MUTE:
454 cp->un.ord = sc->sc_mic_mute;
455 break;
456 case AUDIOAMD_MONITOR_OUTPUT:
457 cp->un.ord = sc->sc_out_port;
458 break;
459 default:
460 return EINVAL;
461 /* NOTREACHED */
463 return 0;
468 * Define mixer control facilities.
471 am7930_query_devinfo(void *addr, mixer_devinfo_t *dip)
474 DPRINTF(("am7930_query_devinfo()\n"));
476 switch(dip->index) {
477 case AUDIOAMD_MIC_VOL:
478 dip->type = AUDIO_MIXER_VALUE;
479 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
480 dip->prev = AUDIO_MIXER_LAST;
481 dip->next = AUDIOAMD_MIC_MUTE;
482 strcpy(dip->label.name, AudioNmicrophone);
483 dip->un.v.num_channels = 1;
484 strcpy(dip->un.v.units.name, AudioNvolume);
485 break;
486 case AUDIOAMD_SPEAKER_VOL:
487 dip->type = AUDIO_MIXER_VALUE;
488 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
489 dip->prev = dip->next = AUDIO_MIXER_LAST;
490 strcpy(dip->label.name, AudioNspeaker);
491 dip->un.v.num_channels = 1;
492 strcpy(dip->un.v.units.name, AudioNvolume);
493 break;
494 case AUDIOAMD_HEADPHONES_VOL:
495 dip->type = AUDIO_MIXER_VALUE;
496 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
497 dip->prev = dip->next = AUDIO_MIXER_LAST;
498 strcpy(dip->label.name, AudioNheadphone);
499 dip->un.v.num_channels = 1;
500 strcpy(dip->un.v.units.name, AudioNvolume);
501 break;
502 case AUDIOAMD_MONITOR_VOL:
503 dip->type = AUDIO_MIXER_VALUE;
504 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
505 dip->prev = dip->next = AUDIO_MIXER_LAST;
506 strcpy(dip->label.name, AudioNmonitor);
507 dip->un.v.num_channels = 1;
508 strcpy(dip->un.v.units.name, AudioNvolume);
509 break;
510 case AUDIOAMD_RECORD_SOURCE:
511 dip->type = AUDIO_MIXER_ENUM;
512 dip->mixer_class = AUDIOAMD_RECORD_CLASS;
513 dip->next = dip->prev = AUDIO_MIXER_LAST;
514 strcpy(dip->label.name, AudioNsource);
515 dip->un.e.num_mem = 1;
516 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
517 dip->un.e.member[0].ord = AUDIOAMD_MIC_VOL;
518 break;
519 case AUDIOAMD_MONITOR_OUTPUT:
520 dip->type = AUDIO_MIXER_ENUM;
521 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
522 dip->next = dip->prev = AUDIO_MIXER_LAST;
523 strcpy(dip->label.name, AudioNoutput);
524 dip->un.e.num_mem = 2;
525 strcpy(dip->un.e.member[0].label.name, AudioNspeaker);
526 dip->un.e.member[0].ord = AUDIOAMD_SPEAKER_VOL;
527 strcpy(dip->un.e.member[1].label.name, AudioNheadphone);
528 dip->un.e.member[1].ord = AUDIOAMD_HEADPHONES_VOL;
529 break;
530 case AUDIOAMD_MIC_MUTE:
531 dip->type = AUDIO_MIXER_ENUM;
532 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
533 dip->prev = AUDIOAMD_MIC_VOL;
534 dip->next = AUDIO_MIXER_LAST;
535 strcpy(dip->label.name, AudioNmute);
536 dip->un.e.num_mem = 2;
537 strcpy(dip->un.e.member[0].label.name, AudioNoff);
538 dip->un.e.member[0].ord = 0;
539 strcpy(dip->un.e.member[1].label.name, AudioNon);
540 dip->un.e.member[1].ord = 1;
541 break;
542 case AUDIOAMD_INPUT_CLASS:
543 dip->type = AUDIO_MIXER_CLASS;
544 dip->mixer_class = AUDIOAMD_INPUT_CLASS;
545 dip->next = dip->prev = AUDIO_MIXER_LAST;
546 strcpy(dip->label.name, AudioCinputs);
547 break;
548 case AUDIOAMD_OUTPUT_CLASS:
549 dip->type = AUDIO_MIXER_CLASS;
550 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS;
551 dip->next = dip->prev = AUDIO_MIXER_LAST;
552 strcpy(dip->label.name, AudioCoutputs);
553 break;
554 case AUDIOAMD_RECORD_CLASS:
555 dip->type = AUDIO_MIXER_CLASS;
556 dip->mixer_class = AUDIOAMD_RECORD_CLASS;
557 dip->next = dip->prev = AUDIO_MIXER_LAST;
558 strcpy(dip->label.name, AudioCrecord);
559 break;
560 case AUDIOAMD_MONITOR_CLASS:
561 dip->type = AUDIO_MIXER_CLASS;
562 dip->mixer_class = AUDIOAMD_MONITOR_CLASS;
563 dip->next = dip->prev = AUDIO_MIXER_LAST;
564 strcpy(dip->label.name, AudioCmonitor);
565 break;
566 default:
567 return ENXIO;
568 /*NOTREACHED*/
571 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
573 return 0;
576 #endif /* NAUDIO */