am7930.c revision 1.43
1/* $NetBSD: am7930.c,v 1.43 2000/05/02 06:30:51 augustss 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 "audio.h" 39#if NAUDIO > 0 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/errno.h> 44#include <sys/ioctl.h> 45#include <sys/device.h> 46#include <sys/proc.h> 47 48#include <machine/bus.h> 49#include <machine/autoconf.h> 50#include <machine/cpu.h> 51 52#include <sys/audioio.h> 53#include <dev/audio_if.h> 54 55#include <dev/ic/am7930reg.h> 56#include <dev/ic/am7930var.h> 57 58#ifdef AUDIO_DEBUG 59int am7930debug = 0; 60#define DPRINTF(x) if (am7930debug) printf x 61#else 62#define DPRINTF(x) 63#endif 64 65 66/* The following tables stolen from former (4.4Lite's) sys/sparc/bsd_audio.c */ 67 68/* 69 * gx, gr & stg gains. this table must contain 256 elements with 70 * the 0th being "infinity" (the magic value 9008). The remaining 71 * elements match sun's gain curve (but with higher resolution): 72 * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps. 73 */ 74static const u_short gx_coeff[256] = { 75 0x9008, 0x8e7c, 0x8e51, 0x8e45, 0x8d42, 0x8d3b, 0x8c36, 0x8c33, 76 0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22, 77 0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b, 78 0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb, 79 0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a, 80 0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213, 81 0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231, 82 0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4, 83 0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2, 84 0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa, 85 0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b, 86 0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b, 87 0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd, 88 0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808, 89 0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243, 90 0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224, 91 0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb, 92 0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33, 93 0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32, 94 0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323, 95 0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a, 96 0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23, 97 0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1, 98 0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333, 99 0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227, 100 0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6, 101 0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2, 102 0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba, 103 0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033, 104 0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021, 105 0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012, 106 0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e, 107}; 108 109/* 110 * second stage play gain. 111 */ 112static const u_short ger_coeff[] = { 113 0x431f, /* 5. dB */ 114 0x331f, /* 5.5 dB */ 115 0x40dd, /* 6. dB */ 116 0x11dd, /* 6.5 dB */ 117 0x440f, /* 7. dB */ 118 0x411f, /* 7.5 dB */ 119 0x311f, /* 8. dB */ 120 0x5520, /* 8.5 dB */ 121 0x10dd, /* 9. dB */ 122 0x4211, /* 9.5 dB */ 123 0x410f, /* 10. dB */ 124 0x111f, /* 10.5 dB */ 125 0x600b, /* 11. dB */ 126 0x00dd, /* 11.5 dB */ 127 0x4210, /* 12. dB */ 128 0x110f, /* 13. dB */ 129 0x7200, /* 14. dB */ 130 0x2110, /* 15. dB */ 131 0x2200, /* 15.9 dB */ 132 0x000b, /* 16.9 dB */ 133 0x000f /* 18. dB */ 134#define NGER (sizeof(ger_coeff) / sizeof(ger_coeff[0])) 135}; 136 137 138/* 139 * Reset chip and set boot-time softc defaults. 140 */ 141void 142am7930_init(sc, flag) 143 struct am7930_softc *sc; 144 int flag; 145{ 146 147 DPRINTF(("am7930_init()\n")); 148 149 /* set boot defaults */ 150 sc->sc_rlevel = 128; 151 sc->sc_plevel = 128; 152 sc->sc_mlevel = 0; 153 sc->sc_out_port = AUDIOAMD_SPEAKER_VOL; 154 sc->sc_mic_mute = 0; 155 156 /* disable sample interrupts */ 157 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 0); 158 159 /* initialise voice and data, and disable interrupts */ 160 AM7930_IWRITE(sc, AM7930_IREG_INIT, 161 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE); 162 163 if (flag == AUDIOAMD_DMA_MODE) { 164 165 /* configure PP for serial (SBP) mode */ 166 AM7930_IWRITE(sc, AM7930_IREG_PP_PPCR1, AM7930_PPCR1_SBP); 167 168 /* 169 * Initialise the MUX unit - route the MAP to the PP 170 */ 171 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1, 172 (AM7930_MCRCHAN_BA << 4) | AM7930_MCRCHAN_BD); 173 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, AM7930_MCRCHAN_NC); 174 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, AM7930_MCRCHAN_NC); 175 176 } else { 177 178 /* 179 * Initialize the MUX unit. We use MCR3 to route the MAP 180 * through channel Bb. MCR1 and MCR2 are unused. 181 * Setting the INT enable bit in MCR4 will generate an 182 * interrupt on each converted audio sample. 183 */ 184 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR1, 0); 185 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, 0); 186 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, 187 (AM7930_MCRCHAN_BB << 4) | AM7930_MCRCHAN_BA); 188 AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 189 AM7930_MCR4_INT_ENABLE); 190 } 191 192} 193 194 195int 196am7930_open(addr, flags) 197 void *addr; 198 int flags; 199{ 200 struct am7930_softc *sc = addr; 201 202 DPRINTF(("sa_open: unit %p\n", sc)); 203 204 if (sc->sc_open) 205 return (EBUSY); 206 sc->sc_open = 1; 207 sc->sc_locked = 0; 208 209 sc->sc_glue->onopen(sc); 210 211 DPRINTF(("saopen: ok -> sc=0x%p\n",sc)); 212 213 return (0); 214} 215 216void 217am7930_close(addr) 218 void *addr; 219{ 220 struct am7930_softc *sc = addr; 221 222 DPRINTF(("sa_close: sc=%p\n", sc)); 223 224 sc->sc_glue->onclose(sc); 225 sc->sc_open = 0; 226 227 DPRINTF(("sa_close: closed.\n")); 228} 229 230 231/* 232 * XXX should be extended to handle a few of the more common formats. 233 */ 234int 235am7930_set_params(addr, setmode, usemode, p, r) 236 void *addr; 237 int setmode, usemode; 238 struct audio_params *p, *r; 239{ 240 struct am7930_softc *sc = addr; 241 242 if ((usemode & AUMODE_PLAY) == AUMODE_PLAY) { 243 if (p->sample_rate < 7500 || p->sample_rate > 8500 || 244 p->encoding != AUDIO_ENCODING_ULAW || 245 p->precision != 8 || 246 p->channels != 1) 247 return EINVAL; 248 p->sample_rate = 8000; 249 if (sc->sc_glue->factor > 1) { 250 p->factor = sc->sc_glue->factor; 251 p->sw_code = sc->sc_glue->output_conv; 252 } 253 } 254 if ((usemode & AUMODE_RECORD) == AUMODE_RECORD) { 255 if (r->sample_rate < 7500 || r->sample_rate > 8500 || 256 r->encoding != AUDIO_ENCODING_ULAW || 257 r->precision != 8 || 258 r->channels != 1) 259 return EINVAL; 260 r->sample_rate = 8000; 261 if (sc->sc_glue->factor > 1) { 262 r->factor = sc->sc_glue->factor; 263 r->sw_code = sc->sc_glue->input_conv; 264 } 265 } 266 267 return 0; 268} 269 270int 271am7930_query_encoding(addr, fp) 272 void *addr; 273 struct audio_encoding *fp; 274{ 275 switch (fp->index) { /* ??? */ 276 case 0: 277 strcpy(fp->name, AudioEmulaw); 278 fp->encoding = AUDIO_ENCODING_ULAW; 279 fp->precision = 8; 280 fp->flags = 0; 281 break; 282 default: 283 return(EINVAL); 284 /*NOTREACHED*/ 285 } 286 return(0); 287} 288 289 290int 291am7930_round_blocksize(addr, blk) 292 void *addr; 293 int blk; 294{ 295 return(blk); 296} 297 298 299int 300am7930_commit_settings(addr) 301 void *addr; 302{ 303 struct am7930_softc *sc = addr; 304 u_int16_t ger, gr, gx, stgr; 305 u_int8_t mmr2, mmr3; 306 int s, level; 307 308 DPRINTF(("sa_commit.\n")); 309 310 gx = gx_coeff[sc->sc_rlevel]; 311 stgr = gx_coeff[sc->sc_mlevel]; 312 313 level = (sc->sc_plevel * (256 + NGER)) >> 8; 314 if (level >= 256) { 315 ger = ger_coeff[level - 256]; 316 gr = gx_coeff[255]; 317 } else { 318 ger = ger_coeff[0]; 319 gr = gx_coeff[level]; 320 } 321 322 s = splaudio(); 323 324 mmr2 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR2); 325 if (sc->sc_out_port == AUDIOAMD_SPEAKER_VOL) 326 mmr2 |= AM7930_MMR2_LS; 327 else 328 mmr2 &= ~AM7930_MMR2_LS; 329 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR2, mmr2); 330 331 mmr3 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR3); 332 if (sc->sc_mic_mute) 333 mmr3 |= AM7930_MMR3_MUTE; 334 else 335 mmr3 &= ~AM7930_MMR3_MUTE; 336 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR3, mmr3); 337 338 AM7930_IWRITE(sc, AM7930_IREG_MAP_MMR1, 339 AM7930_MMR1_GX | AM7930_MMR1_GER | 340 AM7930_MMR1_GR | AM7930_MMR1_STG); 341 342 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GX, gx); 343 AM7930_IWRITE16(sc, AM7930_IREG_MAP_STG, stgr); 344 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GR, gr); 345 AM7930_IWRITE16(sc, AM7930_IREG_MAP_GER, ger); 346 347 splx(s); 348 349 return(0); 350} 351 352 353int 354am7930_halt_output(addr) 355 void *addr; 356{ 357 struct am7930_softc *sc = addr; 358 359 /* XXX only halt, if input is also halted ?? */ 360 AM7930_IWRITE(sc, AM7930_IREG_INIT, 361 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE); 362 sc->sc_locked = 0; 363 364 return(0); 365} 366 367 368int 369am7930_halt_input(addr) 370 void *addr; 371{ 372 struct am7930_softc *sc = addr; 373 374 /* XXX only halt, if output is also halted ?? */ 375 AM7930_IWRITE(sc, AM7930_IREG_INIT, 376 AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE); 377 sc->sc_locked = 0; 378 379 return(0); 380} 381 382 383/* 384 * XXX chip is full-duplex, but really attach-dependent. 385 * For now we know of no half-duplex attachments. 386 */ 387int 388am7930_get_props(addr) 389 void *addr; 390{ 391 return AUDIO_PROP_FULLDUPLEX; 392} 393 394/* 395 * Attach-dependent channel set/query 396 */ 397int 398am7930_set_port(addr, cp) 399 void *addr; 400 mixer_ctrl_t *cp; 401{ 402 struct am7930_softc *sc = addr; 403 404 DPRINTF(("am7930_set_port: port=%d", cp->dev)); 405 406 if (cp->dev == AUDIOAMD_RECORD_SOURCE || 407 cp->dev == AUDIOAMD_MONITOR_OUTPUT || 408 cp->dev == AUDIOAMD_MIC_MUTE) { 409 if (cp->type != AUDIO_MIXER_ENUM) 410 return(EINVAL); 411 } else if (cp->type != AUDIO_MIXER_VALUE || 412 cp->un.value.num_channels != 1) { 413 return(EINVAL); 414 } 415 416 switch(cp->dev) { 417 case AUDIOAMD_MIC_VOL: 418 sc->sc_rlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 419 break; 420 case AUDIOAMD_SPEAKER_VOL: 421 case AUDIOAMD_HEADPHONES_VOL: 422 sc->sc_plevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 423 break; 424 case AUDIOAMD_MONITOR_VOL: 425 sc->sc_mlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 426 break; 427 case AUDIOAMD_RECORD_SOURCE: 428 if (cp->un.ord != AUDIOAMD_MIC_VOL) 429 return EINVAL; 430 break; 431 case AUDIOAMD_MIC_MUTE: 432 sc->sc_mic_mute = cp->un.ord; 433 break; 434 case AUDIOAMD_MONITOR_OUTPUT: 435 if (cp->un.ord != AUDIOAMD_SPEAKER_VOL && 436 cp->un.ord != AUDIOAMD_HEADPHONES_VOL) 437 return EINVAL; 438 sc->sc_out_port = cp->un.ord; 439 break; 440 default: 441 return(EINVAL); 442 /* NOTREACHED */ 443 } 444 return 0; 445} 446 447int 448am7930_get_port(addr, cp) 449 void *addr; 450 mixer_ctrl_t *cp; 451{ 452 struct am7930_softc *sc = addr; 453 454 DPRINTF(("am7930_get_port: port=%d\n", cp->dev)); 455 456 if (cp->dev == AUDIOAMD_RECORD_SOURCE || 457 cp->dev == AUDIOAMD_MONITOR_OUTPUT || 458 cp->dev == AUDIOAMD_MIC_MUTE) { 459 if (cp->type != AUDIO_MIXER_ENUM) 460 return(EINVAL); 461 } else if (cp->type != AUDIO_MIXER_VALUE || 462 cp->un.value.num_channels != 1) { 463 return(EINVAL); 464 } 465 466 switch(cp->dev) { 467 case AUDIOAMD_MIC_VOL: 468 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_rlevel; 469 break; 470 case AUDIOAMD_SPEAKER_VOL: 471 case AUDIOAMD_HEADPHONES_VOL: 472 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_plevel; 473 break; 474 case AUDIOAMD_MONITOR_VOL: 475 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_mlevel; 476 break; 477 case AUDIOAMD_RECORD_SOURCE: 478 cp->un.ord = AUDIOAMD_MIC_VOL; 479 break; 480 case AUDIOAMD_MIC_MUTE: 481 cp->un.ord = sc->sc_mic_mute; 482 break; 483 case AUDIOAMD_MONITOR_OUTPUT: 484 cp->un.ord = sc->sc_out_port; 485 break; 486 default: 487 return(EINVAL); 488 /* NOTREACHED */ 489 } 490 return 0; 491} 492 493 494/* 495 * Define mixer control facilities. 496 */ 497int 498am7930_query_devinfo(addr, dip) 499 void *addr; 500 mixer_devinfo_t *dip; 501{ 502 503 DPRINTF(("am7930_query_devinfo()\n")); 504 505 switch(dip->index) { 506 case AUDIOAMD_MIC_VOL: 507 dip->type = AUDIO_MIXER_VALUE; 508 dip->mixer_class = AUDIOAMD_INPUT_CLASS; 509 dip->prev = AUDIO_MIXER_LAST; 510 dip->next = AUDIOAMD_MIC_MUTE; 511 strcpy(dip->label.name, AudioNmicrophone); 512 dip->un.v.num_channels = 1; 513 strcpy(dip->un.v.units.name, AudioNvolume); 514 break; 515 case AUDIOAMD_SPEAKER_VOL: 516 dip->type = AUDIO_MIXER_VALUE; 517 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS; 518 dip->prev = dip->next = AUDIO_MIXER_LAST; 519 strcpy(dip->label.name, AudioNspeaker); 520 dip->un.v.num_channels = 1; 521 strcpy(dip->un.v.units.name, AudioNvolume); 522 break; 523 case AUDIOAMD_HEADPHONES_VOL: 524 dip->type = AUDIO_MIXER_VALUE; 525 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS; 526 dip->prev = dip->next = AUDIO_MIXER_LAST; 527 strcpy(dip->label.name, AudioNheadphone); 528 dip->un.v.num_channels = 1; 529 strcpy(dip->un.v.units.name, AudioNvolume); 530 break; 531 case AUDIOAMD_MONITOR_VOL: 532 dip->type = AUDIO_MIXER_VALUE; 533 dip->mixer_class = AUDIOAMD_MONITOR_CLASS; 534 dip->prev = dip->next = AUDIO_MIXER_LAST; 535 strcpy(dip->label.name, AudioNmonitor); 536 dip->un.v.num_channels = 1; 537 strcpy(dip->un.v.units.name, AudioNvolume); 538 break; 539 case AUDIOAMD_RECORD_SOURCE: 540 dip->type = AUDIO_MIXER_ENUM; 541 dip->mixer_class = AUDIOAMD_RECORD_CLASS; 542 dip->next = dip->prev = AUDIO_MIXER_LAST; 543 strcpy(dip->label.name, AudioNsource); 544 dip->un.e.num_mem = 1; 545 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone); 546 dip->un.e.member[0].ord = AUDIOAMD_MIC_VOL; 547 break; 548 case AUDIOAMD_MONITOR_OUTPUT: 549 dip->type = AUDIO_MIXER_ENUM; 550 dip->mixer_class = AUDIOAMD_MONITOR_CLASS; 551 dip->next = dip->prev = AUDIO_MIXER_LAST; 552 strcpy(dip->label.name, AudioNoutput); 553 dip->un.e.num_mem = 2; 554 strcpy(dip->un.e.member[0].label.name, AudioNspeaker); 555 dip->un.e.member[0].ord = AUDIOAMD_SPEAKER_VOL; 556 strcpy(dip->un.e.member[1].label.name, AudioNheadphone); 557 dip->un.e.member[1].ord = AUDIOAMD_HEADPHONES_VOL; 558 break; 559 case AUDIOAMD_MIC_MUTE: 560 dip->type = AUDIO_MIXER_ENUM; 561 dip->mixer_class = AUDIOAMD_INPUT_CLASS; 562 dip->prev = AUDIOAMD_MIC_VOL; 563 dip->next = AUDIO_MIXER_LAST; 564 strcpy(dip->label.name, AudioNmute); 565 dip->un.e.num_mem = 2; 566 strcpy(dip->un.e.member[0].label.name, AudioNoff); 567 dip->un.e.member[0].ord = 0; 568 strcpy(dip->un.e.member[1].label.name, AudioNon); 569 dip->un.e.member[1].ord = 1; 570 break; 571 case AUDIOAMD_INPUT_CLASS: 572 dip->type = AUDIO_MIXER_CLASS; 573 dip->mixer_class = AUDIOAMD_INPUT_CLASS; 574 dip->next = dip->prev = AUDIO_MIXER_LAST; 575 strcpy(dip->label.name, AudioCinputs); 576 break; 577 case AUDIOAMD_OUTPUT_CLASS: 578 dip->type = AUDIO_MIXER_CLASS; 579 dip->mixer_class = AUDIOAMD_OUTPUT_CLASS; 580 dip->next = dip->prev = AUDIO_MIXER_LAST; 581 strcpy(dip->label.name, AudioCoutputs); 582 break; 583 case AUDIOAMD_RECORD_CLASS: 584 dip->type = AUDIO_MIXER_CLASS; 585 dip->mixer_class = AUDIOAMD_RECORD_CLASS; 586 dip->next = dip->prev = AUDIO_MIXER_LAST; 587 strcpy(dip->label.name, AudioCrecord); 588 break; 589 case AUDIOAMD_MONITOR_CLASS: 590 dip->type = AUDIO_MIXER_CLASS; 591 dip->mixer_class = AUDIOAMD_MONITOR_CLASS; 592 dip->next = dip->prev = AUDIO_MIXER_LAST; 593 strcpy(dip->label.name, AudioCmonitor); 594 break; 595 default: 596 return ENXIO; 597 /*NOTREACHED*/ 598 } 599 600 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 601 602 return(0); 603} 604 605#endif /* NAUDIO */ 606