1 /* $NetBSD: am7930.c,v 1.45 2004/07/09 02:07:01 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Rolf Grossmann 5 * All rights reserved. 6 * 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 20 * 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. 31 */ 32 33 /* 34 * Front-end attachment independent layer for AMD 79c30 35 * audio driver. No ISDN support. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: am7930.c,v 1.45 2004/07/09 02:07:01 mycroft Exp $"); 40 41 #include "audio.h" 42 #if NAUDIO > 0 43 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> 50 51 #include <machine/bus.h> 52 #include <machine/autoconf.h> 53 #include <machine/cpu.h> 54 55 #include <sys/audioio.h> 56 #include <dev/audio_if.h> 57 58 #include <dev/ic/am7930reg.h> 59 #include <dev/ic/am7930var.h> 60 61 #ifdef AUDIO_DEBUG 62 int am7930debug = 0; 63 #define DPRINTF(x) if (am7930debug) printf x 64 #else 65 #define DPRINTF(x) 66 #endif 67 68 69 /* The following tables stolen from former (4.4Lite's) sys/sparc/bsd_audio.c */ 70 71 /* 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. 76 */ 77 static const u_short 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, 110 }; 111 112 /* 113 * second stage play gain. 114 */ 115 static const u_short 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])) 138 }; 139 140 141 /* 142 * Reset chip and set boot-time softc defaults. 143 */ 144 void 145 am7930_init(sc, flag) 146 struct am7930_softc *sc; 147 int flag; 148 { 149 150 DPRINTF(("am7930_init()\n")); 151 152 /* set boot defaults */ 153 sc->sc_rlevel = 128; 154 sc->sc_plevel = 128; 155 sc->sc_mlevel = 0; 156 sc->sc_out_port = AUDIOAMD_SPEAKER_VOL; 157 sc->sc_mic_mute = 0; 158 159 /* disable sample interrupts */ 160 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 0); 161 162 /* initialise voice and data, and disable interrupts */ 163 AM7930_IWRITE(sc, AM7930_IREG_INIT, 164 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE); 165 166 if (flag == AUDIOAMD_DMA_MODE) { 167 168 /* configure PP for serial (SBP) mode */ 169 AM7930_IWRITE(sc, AM7930_IREG_PP_PPCR1, AM7930_PPCR1_SBP); 170 171 /* 172 * Initialise the MUX unit - route the MAP to the PP 173 */ 174 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1, 175 (AM7930_MCRCHAN_BA << 4) | AM7930_MCRCHAN_BD); 176 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, AM7930_MCRCHAN_NC); 177 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, AM7930_MCRCHAN_NC); 178 179 } else { 180 181 /* 182 * Initialize the MUX unit. We use MCR3 to route the MAP 183 * through channel Bb. MCR1 and MCR2 are unused. 184 * Setting the INT enable bit in MCR4 will generate an 185 * interrupt on each converted audio sample. 186 */ 187 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1, 0); 188 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, 0); 189 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, 190 (AM7930_MCRCHAN_BB << 4) | AM7930_MCRCHAN_BA); 191 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 192 AM7930_MCR4_INT_ENABLE); 193 } 194 195 } 196 197 198 int 199 am7930_open(addr, flags) 200 void *addr; 201 int flags; 202 { 203 struct am7930_softc *sc = addr; 204 205 DPRINTF(("sa_open: unit %p\n", sc)); 206 207 sc->sc_glue->onopen(sc); 208 209 DPRINTF(("saopen: ok -> sc=0x%p\n",sc)); 210 211 return (0); 212 } 213 214 void 215 am7930_close(addr) 216 void *addr; 217 { 218 struct am7930_softc *sc = addr; 219 220 DPRINTF(("sa_close: sc=%p\n", sc)); 221 222 sc->sc_glue->onclose(sc); 223 224 DPRINTF(("sa_close: closed.\n")); 225 } 226 227 228 /* 229 * XXX should be extended to handle a few of the more common formats. 230 */ 231 int 232 am7930_set_params(addr, setmode, usemode, p, r) 233 void *addr; 234 int setmode, usemode; 235 struct audio_params *p, *r; 236 { 237 struct am7930_softc *sc = addr; 238 239 if ((usemode & AUMODE_PLAY) == AUMODE_PLAY) { 240 if (p->sample_rate < 7500 || p->sample_rate > 8500 || 241 p->encoding != AUDIO_ENCODING_ULAW || 242 p->precision != 8 || 243 p->channels != 1) 244 return EINVAL; 245 p->sample_rate = 8000; 246 if (sc->sc_glue->factor > 1) { 247 p->factor = sc->sc_glue->factor; 248 p->sw_code = sc->sc_glue->output_conv; 249 } 250 } 251 if ((usemode & AUMODE_RECORD) == AUMODE_RECORD) { 252 if (r->sample_rate < 7500 || r->sample_rate > 8500 || 253 r->encoding != AUDIO_ENCODING_ULAW || 254 r->precision != 8 || 255 r->channels != 1) 256 return EINVAL; 257 r->sample_rate = 8000; 258 if (sc->sc_glue->factor > 1) { 259 r->factor = sc->sc_glue->factor; 260 r->sw_code = sc->sc_glue->input_conv; 261 } 262 } 263 264 return 0; 265 } 266 267 int 268 am7930_query_encoding(addr, fp) 269 void *addr; 270 struct audio_encoding *fp; 271 { 272 switch (fp->index) { /* ??? */ 273 case 0: 274 strcpy(fp->name, AudioEmulaw); 275 fp->encoding = AUDIO_ENCODING_ULAW; 276 fp->precision = 8; 277 fp->flags = 0; 278 break; 279 default: 280 return(EINVAL); 281 /*NOTREACHED*/ 282 } 283 return(0); 284 } 285 286 287 int 288 am7930_round_blocksize(addr, blk) 289 void *addr; 290 int blk; 291 { 292 return(blk); 293 } 294 295 296 int 297 am7930_commit_settings(addr) 298 void *addr; 299 { 300 struct am7930_softc *sc = addr; 301 u_int16_t ger, gr, gx, stgr; 302 u_int8_t mmr2, mmr3; 303 int s, level; 304 305 DPRINTF(("sa_commit.\n")); 306 307 gx = gx_coeff[sc->sc_rlevel]; 308 stgr = gx_coeff[sc->sc_mlevel]; 309 310 level = (sc->sc_plevel * (256 + NGER)) >> 8; 311 if (level >= 256) { 312 ger = ger_coeff[level - 256]; 313 gr = gx_coeff[255]; 314 } else { 315 ger = ger_coeff[0]; 316 gr = gx_coeff[level]; 317 } 318 319 s = splaudio(); 320 321 mmr2 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR2); 322 if (sc->sc_out_port == AUDIOAMD_SPEAKER_VOL) 323 mmr2 |= AM7930_MMR2_LS; 324 else 325 mmr2 &= ~AM7930_MMR2_LS; 326 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR2, mmr2); 327 328 mmr3 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR3); 329 if (sc->sc_mic_mute) 330 mmr3 |= AM7930_MMR3_MUTE; 331 else 332 mmr3 &= ~AM7930_MMR3_MUTE; 333 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR3, mmr3); 334 335 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR1, 336 AM7930_MMR1_GX | AM7930_MMR1_GER | 337 AM7930_MMR1_GR | AM7930_MMR1_STG); 338 339 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GX, gx); 340 AM7930_IWRITE16(sc, AM7930_IREG_MAP_STG, stgr); 341 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GR, gr); 342 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GER, ger); 343 344 splx(s); 345 346 return(0); 347 } 348 349 350 int 351 am7930_halt_output(addr) 352 void *addr; 353 { 354 struct am7930_softc *sc = addr; 355 356 /* XXX only halt, if input is also halted ?? */ 357 AM7930_IWRITE(sc, AM7930_IREG_INIT, 358 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE); 359 360 return(0); 361 } 362 363 364 int 365 am7930_halt_input(addr) 366 void *addr; 367 { 368 struct am7930_softc *sc = addr; 369 370 /* XXX only halt, if output is also halted ?? */ 371 AM7930_IWRITE(sc, AM7930_IREG_INIT, 372 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE); 373 374 return(0); 375 } 376 377 378 /* 379 * XXX chip is full-duplex, but really attach-dependent. 380 * For now we know of no half-duplex attachments. 381 */ 382 int 383 am7930_get_props(addr) 384 void *addr; 385 { 386 return AUDIO_PROP_FULLDUPLEX; 387 } 388 389 /* 390 * Attach-dependent channel set/query 391 */ 392 int 393 am7930_set_port(addr, cp) 394 void *addr; 395 mixer_ctrl_t *cp; 396 { 397 struct am7930_softc *sc = addr; 398 399 DPRINTF(("am7930_set_port: port=%d", cp->dev)); 400 401 if (cp->dev == AUDIOAMD_RECORD_SOURCE || 402 cp->dev == AUDIOAMD_MONITOR_OUTPUT || 403 cp->dev == AUDIOAMD_MIC_MUTE) { 404 if (cp->type != AUDIO_MIXER_ENUM) 405 return(EINVAL); 406 } else if (cp->type != AUDIO_MIXER_VALUE || 407 cp->un.value.num_channels != 1) { 408 return(EINVAL); 409 } 410 411 switch(cp->dev) { 412 case AUDIOAMD_MIC_VOL: 413 sc->sc_rlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 414 break; 415 case AUDIOAMD_SPEAKER_VOL: 416 case AUDIOAMD_HEADPHONES_VOL: 417 sc->sc_plevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 418 break; 419 case AUDIOAMD_MONITOR_VOL: 420 sc->sc_mlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 421 break; 422 case AUDIOAMD_RECORD_SOURCE: 423 if (cp->un.ord != AUDIOAMD_MIC_VOL) 424 return EINVAL; 425 break; 426 case AUDIOAMD_MIC_MUTE: 427 sc->sc_mic_mute = cp->un.ord; 428 break; 429 case AUDIOAMD_MONITOR_OUTPUT: 430 if (cp->un.ord != AUDIOAMD_SPEAKER_VOL && 431 cp->un.ord != AUDIOAMD_HEADPHONES_VOL) 432 return EINVAL; 433 sc->sc_out_port = cp->un.ord; 434 break; 435 default: 436 return(EINVAL); 437 /* NOTREACHED */ 438 } 439 return 0; 440 } 441 442 int 443 am7930_get_port(addr, cp) 444 void *addr; 445 mixer_ctrl_t *cp; 446 { 447 struct am7930_softc *sc = addr; 448 449 DPRINTF(("am7930_get_port: port=%d\n", cp->dev)); 450 451 if (cp->dev == AUDIOAMD_RECORD_SOURCE || 452 cp->dev == AUDIOAMD_MONITOR_OUTPUT || 453 cp->dev == AUDIOAMD_MIC_MUTE) { 454 if (cp->type != AUDIO_MIXER_ENUM) 455 return(EINVAL); 456 } else if (cp->type != AUDIO_MIXER_VALUE || 457 cp->un.value.num_channels != 1) { 458 return(EINVAL); 459 } 460 461 switch(cp->dev) { 462 case AUDIOAMD_MIC_VOL: 463 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_rlevel; 464 break; 465 case AUDIOAMD_SPEAKER_VOL: 466 case AUDIOAMD_HEADPHONES_VOL: 467 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_plevel; 468 break; 469 case AUDIOAMD_MONITOR_VOL: 470 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_mlevel; 471 break; 472 case AUDIOAMD_RECORD_SOURCE: 473 cp->un.ord = AUDIOAMD_MIC_VOL; 474 break; 475 case AUDIOAMD_MIC_MUTE: 476 cp->un.ord = sc->sc_mic_mute; 477 break; 478 case AUDIOAMD_MONITOR_OUTPUT: 479 cp->un.ord = sc->sc_out_port; 480 break; 481 default: 482 return(EINVAL); 483 /* NOTREACHED */ 484 } 485 return 0; 486 } 487 488 489 /* 490 * Define mixer control facilities. 491 */ 492 int 493 am7930_query_devinfo(addr, dip) 494 void *addr; 495 mixer_devinfo_t *dip; 496 { 497 498 DPRINTF(("am7930_query_devinfo()\n")); 499 500 switch(dip->index) { 501 case AUDIOAMD_MIC_VOL: 502 dip->type = AUDIO_MIXER_VALUE; 503 dip->mixer_class = AUDIOAMD_INPUT_CLASS; 504 dip->prev = AUDIO_MIXER_LAST; 505 dip->next = AUDIOAMD_MIC_MUTE; 506 strcpy(dip->label.name, AudioNmicrophone); 507 dip->un.v.num_channels = 1; 508 strcpy(dip->un.v.units.name, AudioNvolume); 509 break; 510 case AUDIOAMD_SPEAKER_VOL: 511 dip->type = AUDIO_MIXER_VALUE; 512 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS; 513 dip->prev = dip->next = AUDIO_MIXER_LAST; 514 strcpy(dip->label.name, AudioNspeaker); 515 dip->un.v.num_channels = 1; 516 strcpy(dip->un.v.units.name, AudioNvolume); 517 break; 518 case AUDIOAMD_HEADPHONES_VOL: 519 dip->type = AUDIO_MIXER_VALUE; 520 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS; 521 dip->prev = dip->next = AUDIO_MIXER_LAST; 522 strcpy(dip->label.name, AudioNheadphone); 523 dip->un.v.num_channels = 1; 524 strcpy(dip->un.v.units.name, AudioNvolume); 525 break; 526 case AUDIOAMD_MONITOR_VOL: 527 dip->type = AUDIO_MIXER_VALUE; 528 dip->mixer_class = AUDIOAMD_MONITOR_CLASS; 529 dip->prev = dip->next = AUDIO_MIXER_LAST; 530 strcpy(dip->label.name, AudioNmonitor); 531 dip->un.v.num_channels = 1; 532 strcpy(dip->un.v.units.name, AudioNvolume); 533 break; 534 case AUDIOAMD_RECORD_SOURCE: 535 dip->type = AUDIO_MIXER_ENUM; 536 dip->mixer_class = AUDIOAMD_RECORD_CLASS; 537 dip->next = dip->prev = AUDIO_MIXER_LAST; 538 strcpy(dip->label.name, AudioNsource); 539 dip->un.e.num_mem = 1; 540 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone); 541 dip->un.e.member[0].ord = AUDIOAMD_MIC_VOL; 542 break; 543 case AUDIOAMD_MONITOR_OUTPUT: 544 dip->type = AUDIO_MIXER_ENUM; 545 dip->mixer_class = AUDIOAMD_MONITOR_CLASS; 546 dip->next = dip->prev = AUDIO_MIXER_LAST; 547 strcpy(dip->label.name, AudioNoutput); 548 dip->un.e.num_mem = 2; 549 strcpy(dip->un.e.member[0].label.name, AudioNspeaker); 550 dip->un.e.member[0].ord = AUDIOAMD_SPEAKER_VOL; 551 strcpy(dip->un.e.member[1].label.name, AudioNheadphone); 552 dip->un.e.member[1].ord = AUDIOAMD_HEADPHONES_VOL; 553 break; 554 case AUDIOAMD_MIC_MUTE: 555 dip->type = AUDIO_MIXER_ENUM; 556 dip->mixer_class = AUDIOAMD_INPUT_CLASS; 557 dip->prev = AUDIOAMD_MIC_VOL; 558 dip->next = AUDIO_MIXER_LAST; 559 strcpy(dip->label.name, AudioNmute); 560 dip->un.e.num_mem = 2; 561 strcpy(dip->un.e.member[0].label.name, AudioNoff); 562 dip->un.e.member[0].ord = 0; 563 strcpy(dip->un.e.member[1].label.name, AudioNon); 564 dip->un.e.member[1].ord = 1; 565 break; 566 case AUDIOAMD_INPUT_CLASS: 567 dip->type = AUDIO_MIXER_CLASS; 568 dip->mixer_class = AUDIOAMD_INPUT_CLASS; 569 dip->next = dip->prev = AUDIO_MIXER_LAST; 570 strcpy(dip->label.name, AudioCinputs); 571 break; 572 case AUDIOAMD_OUTPUT_CLASS: 573 dip->type = AUDIO_MIXER_CLASS; 574 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS; 575 dip->next = dip->prev = AUDIO_MIXER_LAST; 576 strcpy(dip->label.name, AudioCoutputs); 577 break; 578 case AUDIOAMD_RECORD_CLASS: 579 dip->type = AUDIO_MIXER_CLASS; 580 dip->mixer_class = AUDIOAMD_RECORD_CLASS; 581 dip->next = dip->prev = AUDIO_MIXER_LAST; 582 strcpy(dip->label.name, AudioCrecord); 583 break; 584 case AUDIOAMD_MONITOR_CLASS: 585 dip->type = AUDIO_MIXER_CLASS; 586 dip->mixer_class = AUDIOAMD_MONITOR_CLASS; 587 dip->next = dip->prev = AUDIO_MIXER_LAST; 588 strcpy(dip->label.name, AudioCmonitor); 589 break; 590 default: 591 return ENXIO; 592 /*NOTREACHED*/ 593 } 594 595 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 596 597 return(0); 598 } 599 600 #endif /* NAUDIO */ 601