1 /* $NetBSD: aria.c,v 1.15 2002/10/02 03:10:45 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1995, 1996, 1998 Roland C. Dowdeswell. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Roland C. Dowdeswell. 17 * 4. The name of the authors may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /*- 33 * TODO: 34 * o Test the driver on cards other than a single 35 * Prometheus Aria 16. 36 * o Look into where aria_prometheus_kludge() belongs. 37 * o Add some dma code. It accomplishes its goal by 38 * direct IO at the moment. 39 * o Different programs should be able to open the device 40 * with O_RDONLY and O_WRONLY at the same time. But I 41 * do not see support for this in /sys/dev/audio.c, so 42 * I cannot effectively code it. 43 * o We should nicely deal with the cards that can do mulaw 44 * and alaw output. 45 * o Rework the mixer interface. 46 * o Deal with the lvls better. We need to do better mapping 47 * between logarithmic scales and the one byte that 48 * we are passed. 49 * o Deal better with cards that have no mixer. 50 */ 51 52 #include <sys/cdefs.h> 53 __KERNEL_RCSID(0, "$NetBSD: aria.c,v 1.15 2002/10/02 03:10:45 thorpej Exp $"); 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/errno.h> 58 #include <sys/ioctl.h> 59 #include <sys/syslog.h> 60 #include <sys/device.h> 61 #include <sys/proc.h> 62 #include <sys/buf.h> 63 64 #include <machine/cpu.h> 65 #include <machine/bus.h> 66 67 #include <sys/audioio.h> 68 #include <dev/audio_if.h> 69 #include <dev/auconv.h> 70 71 #include <dev/mulaw.h> 72 #include <dev/isa/isavar.h> 73 #include <i386/isa/icu.h> 74 75 #include <dev/isa/ariareg.h> 76 77 #define FREAD 1 78 #define FWRITE 2 79 80 #ifdef AUDIO_DEBUG 81 #define DPRINTF(x) printf x 82 int ariadebug = 0; 83 #else 84 #define DPRINTF(x) 85 #endif 86 87 struct aria_mixdev_info { 88 u_char num_channels; 89 u_char level[2]; 90 u_char mute; 91 }; 92 93 struct aria_mixmaster { 94 u_char num_channels; 95 u_char level[2]; 96 u_char treble[2]; 97 u_char bass[2]; 98 }; 99 100 struct aria_softc { 101 struct device sc_dev; /* base device */ 102 void *sc_ih; /* interrupt vectoring */ 103 bus_space_tag_t sc_iot; /* Tag on 'da bus. */ 104 bus_space_handle_t sc_ioh; /* Handle of iospace */ 105 isa_chipset_tag_t sc_ic; /* ISA chipset info */ 106 107 u_short sc_open; /* reference count of open calls */ 108 u_short sc_play; /* non-paused play chans 2**chan */ 109 u_short sc_record; /* non-paused record chans 2**chan */ 110 /* XXX -- keep this? */ 111 u_short sc_gain[2]; /* left/right gain (play) */ 112 113 u_long sc_rate; /* Sample rate for input and output */ 114 u_int sc_encoding; /* audio encoding -- ulaw/linear */ 115 int sc_chans; /* # of channels */ 116 int sc_precision; /* # bits per sample */ 117 118 u_long sc_interrupts; /* number of interrupts taken */ 119 void (*sc_rintr)(void*); /* record transfer completion intr handler */ 120 void (*sc_pintr)(void*); /* play transfer completion intr handler */ 121 void *sc_rarg; /* arg for sc_rintr() */ 122 void *sc_parg; /* arg for sc_pintr() */ 123 124 int sc_blocksize; /* literal dio block size */ 125 void *sc_rdiobuffer; /* record: where the next samples should be */ 126 void *sc_pdiobuffer; /* play: where the next samples are */ 127 128 u_short sc_hardware; /* bit field of hardware present */ 129 #define ARIA_TELEPHONE 0x0001 /* has telephone input */ 130 #define ARIA_MIXER 0x0002 /* has SC18075 digital mixer */ 131 #define ARIA_MODEL 0x0004 /* is SC18025 (=0) or SC18026 (=1) */ 132 133 struct aria_mixdev_info aria_mix[6]; 134 struct aria_mixmaster ariamix_master; 135 u_char aria_mix_source; 136 137 int sc_sendcmd_err; 138 }; 139 140 int ariaprobe __P((struct device *, struct cfdata *, void *)); 141 void ariaattach __P((struct device *, struct device *, void *)); 142 void ariaclose __P((void *)); 143 int ariaopen __P((void *, int)); 144 int ariareset __P((bus_space_tag_t, bus_space_handle_t)); 145 int aria_reset __P((struct aria_softc *)); 146 int aria_getdev __P((void *, struct audio_device *)); 147 148 void aria_do_kludge __P((bus_space_tag_t, bus_space_handle_t, 149 bus_space_handle_t, 150 u_short, u_short, u_short, u_short)); 151 void aria_prometheus_kludge __P((struct isa_attach_args *, 152 bus_space_handle_t)); 153 154 int aria_query_encoding __P((void *, struct audio_encoding *)); 155 int aria_round_blocksize __P((void *, int)); 156 int aria_speaker_ctl __P((void *, int)); 157 int aria_commit_settings __P((void *)); 158 int aria_set_params __P((void *, int, int, 159 struct audio_params *, struct audio_params *)); 160 int aria_get_props __P((void *)); 161 162 int aria_start_output __P((void *, void *, int, 163 void (*) __P((void *)), void*)); 164 int aria_start_input __P((void *, void *, int, 165 void (*) __P((void *)), void*)); 166 167 int aria_halt_input __P((void *)); 168 int aria_halt_output __P((void *)); 169 170 int aria_sendcmd __P((struct aria_softc *, u_short, int, int, int)); 171 172 u_short aria_getdspmem __P((struct aria_softc *, u_short)); 173 void aria_putdspmem __P((struct aria_softc *, u_short, u_short)); 174 175 int aria_intr __P((void *)); 176 short ariaversion __P((struct aria_softc *)); 177 178 void aria_set_mixer __P((struct aria_softc *, int)); 179 180 void aria_mix_write __P((struct aria_softc *, int, int)); 181 int aria_mix_read __P((struct aria_softc *, int)); 182 183 int aria_mixer_set_port __P((void *, mixer_ctrl_t *)); 184 int aria_mixer_get_port __P((void *, mixer_ctrl_t *)); 185 int aria_mixer_query_devinfo __P((void *, mixer_devinfo_t *)); 186 187 CFATTACH_DECL(aria, sizeof(struct aria_softc), 188 ariaprobe, ariaattach, NULL, NULL); 189 190 /* XXX temporary test for 1.3 */ 191 #ifndef AudioNaux 192 /* 1.3 */ 193 struct cfdriver aria_cd = { 194 NULL, "aria", DV_DULL 195 }; 196 #endif 197 198 struct audio_device aria_device = { 199 "Aria 16(se)", 200 "x", 201 "aria" 202 }; 203 204 /* 205 * Define our interface to the higher level audio driver. 206 */ 207 208 struct audio_hw_if aria_hw_if = { 209 ariaopen, 210 ariaclose, 211 NULL, 212 aria_query_encoding, 213 aria_set_params, 214 aria_round_blocksize, 215 aria_commit_settings, 216 NULL, 217 NULL, 218 aria_start_output, 219 aria_start_input, 220 aria_halt_input, 221 aria_halt_output, 222 NULL, 223 aria_getdev, 224 NULL, 225 aria_mixer_set_port, 226 aria_mixer_get_port, 227 aria_mixer_query_devinfo, 228 NULL, 229 NULL, 230 NULL, 231 NULL, 232 aria_get_props, 233 NULL, 234 NULL, 235 NULL, 236 }; 237 238 /* 239 * Probe / attach routines. 240 */ 241 242 /* 243 * Probe for the aria hardware. 244 */ 245 int 246 ariaprobe(parent, cf, aux) 247 struct device *parent; 248 struct cfdata *cf; 249 void *aux; 250 { 251 bus_space_handle_t ioh; 252 struct isa_attach_args *ia = aux; 253 254 if (ia->ia_nio < 1) 255 return (0); 256 if (ia->ia_nirq < 1) 257 return (0); 258 259 if (ISA_DIRECT_CONFIG(ia)) 260 return (0); 261 262 if (!ARIA_BASE_VALID(ia->ia_io[0].ir_addr)) { 263 printf("aria: configured iobase %d invalid\n", 264 ia->ia_io[0].ir_addr); 265 return 0; 266 } 267 268 if (!ARIA_IRQ_VALID(ia->ia_irq[0].ir_irq)) { 269 printf("aria: configured irq %d invalid\n", 270 ia->ia_irq[0].ir_irq); 271 return 0; 272 } 273 274 if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT, 275 0, &ioh)) { 276 DPRINTF(("aria: aria probe failed\n")); 277 return 0; 278 } 279 280 if (cf->cf_flags & 1) 281 aria_prometheus_kludge(ia, ioh); 282 283 if (ariareset(ia->ia_iot, ioh) != 0) { 284 DPRINTF(("aria: aria probe failed\n")); 285 bus_space_unmap(ia->ia_iot, ioh, ARIADSP_NPORT); 286 return 0; 287 } 288 289 bus_space_unmap(ia->ia_iot, ioh, ARIADSP_NPORT); 290 291 ia->ia_nio = 1; 292 ia->ia_io[0].ir_size = ARIADSP_NPORT; 293 294 ia->ia_nirq = 1; 295 296 ia->ia_niomem = 0; 297 ia->ia_ndrq = 0; 298 299 DPRINTF(("aria: aria probe succeeded\n")); 300 return 1; 301 } 302 303 /* 304 * I didn't call this a kludge for 305 * nothing. This is cribbed from 306 * ariainit, the author of that 307 * disassembled some code to discover 308 * how to set up the initial values of 309 * the card. Without this, the card 310 * is dead. (It will not respond to _any_ 311 * input at all.) 312 * 313 * ariainit can be found (ftp) at: 314 * ftp://ftp.wi.leidenuniv.nl/pub/audio/aria/programming/contrib/ariainit.zip 315 * currently. 316 */ 317 318 void 319 aria_prometheus_kludge(ia, ioh1) 320 struct isa_attach_args *ia; 321 bus_space_handle_t ioh1; 322 { 323 bus_space_tag_t iot; 324 bus_space_handle_t ioh; 325 u_short end; 326 327 DPRINTF(("aria: begin aria_prometheus_kludge\n")); 328 329 /* Begin Config Sequence */ 330 331 iot = ia->ia_iot; 332 bus_space_map(iot, 0x200, 8, 0, &ioh); 333 334 bus_space_write_1(iot, ioh, 4, 0x4c); 335 bus_space_write_1(iot, ioh, 5, 0x42); 336 bus_space_write_1(iot, ioh, 6, 0x00); 337 bus_space_write_2(iot, ioh, 0, 0x0f); 338 bus_space_write_1(iot, ioh, 1, 0x00); 339 bus_space_write_2(iot, ioh, 0, 0x02); 340 bus_space_write_1(iot, ioh, 1, ia->ia_io[0].ir_addr>>2); 341 342 /* 343 * These next three lines set up the iobase 344 * and the irq; and disable the drq. 345 */ 346 347 aria_do_kludge(iot, ioh, ioh1, 0x111, 348 ((ia->ia_io[0].ir_addr-0x280)>>2)+0xA0, 0xbf, 0xa0); 349 aria_do_kludge(iot, ioh, ioh1, 0x011, 350 ia->ia_irq[0].ir_irq-6, 0xf8, 0x00); 351 aria_do_kludge(iot, ioh, ioh1, 0x011, 0x00, 0xef, 0x00); 352 353 /* The rest of these lines just disable everything else */ 354 355 aria_do_kludge(iot, ioh, ioh1, 0x113, 0x00, 0x88, 0x00); 356 aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xf8, 0x00); 357 aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xef, 0x00); 358 aria_do_kludge(iot, ioh, ioh1, 0x117, 0x00, 0x88, 0x00); 359 aria_do_kludge(iot, ioh, ioh1, 0x017, 0x00, 0xff, 0x00); 360 361 /* End Sequence */ 362 363 bus_space_write_1(iot, ioh, 0, 0x0f); 364 end = bus_space_read_1(iot, ioh1, 0); 365 bus_space_write_2(iot, ioh, 0, 0x0f); 366 bus_space_write_1(iot, ioh, 1, end|0x80); 367 bus_space_read_1(iot, ioh, 0); 368 369 bus_space_unmap(iot, ioh, 8); 370 /* 371 * This delay is necessary for some reason, 372 * at least it would crash, and sometimes not 373 * probe properly if it did not exist. 374 */ 375 delay(1000000); 376 } 377 378 void 379 aria_do_kludge(iot, ioh, ioh1, func, bits, and, or) 380 bus_space_tag_t iot; 381 bus_space_handle_t ioh; 382 bus_space_handle_t ioh1; 383 u_short func; 384 u_short bits; 385 u_short and; 386 u_short or; 387 { 388 u_int i; 389 if (func & 0x100) { 390 func &= ~0x100; 391 if (bits) { 392 bus_space_write_2(iot, ioh, 0, func-1); 393 bus_space_write_1(iot, ioh, 1, bits); 394 } 395 } else 396 or |= bits; 397 398 bus_space_write_1(iot, ioh, 0, func); 399 i = bus_space_read_1(iot, ioh1, 0); 400 bus_space_write_2(iot, ioh, 0, func); 401 bus_space_write_1(iot, ioh, 1, (i&and) | or); 402 } 403 404 /* 405 * Attach hardware to driver, attach hardware driver to audio 406 * pseudo-device driver. 407 */ 408 void 409 ariaattach(parent, self, aux) 410 struct device *parent, *self; 411 void *aux; 412 { 413 bus_space_handle_t ioh; 414 struct aria_softc *sc = (void *)self; 415 struct isa_attach_args *ia = aux; 416 u_short i; 417 418 if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT, 419 0, &ioh)) 420 panic("%s: can map io port range", self->dv_xname); 421 422 sc->sc_iot = ia->ia_iot; 423 sc->sc_ioh = ioh; 424 sc->sc_ic = ia->ia_ic; 425 426 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, 427 IST_EDGE, IPL_AUDIO, aria_intr, sc); 428 429 DPRINTF(("isa_intr_establish() returns (%x)\n", (unsigned) sc->sc_ih)); 430 431 i = aria_getdspmem(sc, ARIAA_HARDWARE_A); 432 433 sc->sc_hardware = 0; 434 sc->sc_hardware |= ((i>>13)&0x01)==1 ? ARIA_TELEPHONE:0; 435 sc->sc_hardware |= (((i>>5)&0x07))==0x04 ? ARIA_MIXER:0; 436 sc->sc_hardware |= (aria_getdspmem(sc, ARIAA_MODEL_A)>=1)?ARIA_MODEL:0; 437 438 sc->sc_open = 0; 439 sc->sc_play = 0; 440 sc->sc_record = 0; 441 sc->sc_rate = 7875; 442 sc->sc_chans = 1; 443 sc->sc_blocksize = 1024; 444 sc->sc_precision = 8; 445 sc->sc_rintr = 0; 446 sc->sc_rarg = 0; 447 sc->sc_pintr = 0; 448 sc->sc_parg = 0; 449 sc->sc_gain[0] = 127; 450 sc->sc_gain[1] = 127; 451 452 for (i=0; i<6; i++) { 453 if (i == ARIAMIX_TEL_LVL) 454 sc->aria_mix[i].num_channels = 1; 455 else 456 sc->aria_mix[i].num_channels = 2; 457 sc->aria_mix[i].level[0] = 127; 458 sc->aria_mix[i].level[1] = 127; 459 } 460 461 sc->ariamix_master.num_channels = 2; 462 sc->ariamix_master.level[0] = 222; 463 sc->ariamix_master.level[1] = 222; 464 sc->ariamix_master.bass[0] = 127; 465 sc->ariamix_master.bass[1] = 127; 466 sc->ariamix_master.treble[0] = 127; 467 sc->ariamix_master.treble[1] = 127; 468 sc->aria_mix_source = 0; 469 470 aria_commit_settings(sc); 471 472 printf(": dsp %s", (ARIA_MODEL&sc->sc_hardware)?"SC18026":"SC18025"); 473 if (ARIA_TELEPHONE&sc->sc_hardware) 474 printf(", tel"); 475 if (ARIA_MIXER&sc->sc_hardware) 476 printf(", SC18075 mixer"); 477 printf("\n"); 478 479 sprintf(aria_device.version, "%s", 480 ARIA_MODEL & sc->sc_hardware ? "SC18026" : "SC18025"); 481 482 audio_attach_mi(&aria_hw_if, (void *)sc, &sc->sc_dev); 483 } 484 485 /* 486 * Various routines to interface to higher level audio driver 487 */ 488 489 int 490 ariaopen(addr, flags) 491 void *addr; 492 int flags; 493 { 494 struct aria_softc *sc = addr; 495 496 DPRINTF(("ariaopen() called\n")); 497 498 if (!sc) 499 return ENXIO; 500 if ((flags&FREAD) && (sc->sc_open & ARIAR_OPEN_RECORD)) 501 return ENXIO; 502 if ((flags&FWRITE) && (sc->sc_open & ARIAR_OPEN_PLAY)) 503 return ENXIO; 504 505 if (flags&FREAD) 506 sc->sc_open |= ARIAR_OPEN_RECORD; 507 if (flags&FWRITE) 508 sc->sc_open |= ARIAR_OPEN_PLAY; 509 sc->sc_play = 0; 510 sc->sc_record= 0; 511 sc->sc_rintr = 0; 512 sc->sc_rarg = 0; 513 sc->sc_pintr = 0; 514 sc->sc_parg = 0; 515 516 return 0; 517 } 518 519 int 520 aria_getdev(addr, retp) 521 void *addr; 522 struct audio_device *retp; 523 { 524 *retp = aria_device; 525 return 0; 526 } 527 528 /* 529 * Various routines to interface to higher level audio driver 530 */ 531 532 int 533 aria_query_encoding(addr, fp) 534 void *addr; 535 struct audio_encoding *fp; 536 { 537 struct aria_softc *sc = addr; 538 539 switch (fp->index) { 540 case 0: 541 strcpy(fp->name, AudioEmulaw); 542 fp->encoding = AUDIO_ENCODING_ULAW; 543 fp->precision = 8; 544 if ((ARIA_MODEL&sc->sc_hardware) == 0) 545 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 546 break; 547 case 1: 548 strcpy(fp->name, AudioEalaw); 549 fp->encoding = AUDIO_ENCODING_ALAW; 550 fp->precision = 8; 551 if ((ARIA_MODEL&sc->sc_hardware) == 0) 552 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 553 break; 554 case 2: 555 strcpy(fp->name, AudioEslinear); 556 fp->encoding = AUDIO_ENCODING_SLINEAR; 557 fp->precision = 8; 558 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 559 break; 560 case 3: 561 strcpy(fp->name, AudioEslinear_le); 562 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 563 fp->precision = 16; 564 fp->flags = 0; 565 break; 566 case 4: 567 strcpy(fp->name, AudioEslinear_be); 568 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 569 fp->precision = 16; 570 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 571 break; 572 case 5: 573 strcpy(fp->name, AudioEulinear); 574 fp->encoding = AUDIO_ENCODING_ULINEAR; 575 fp->precision = 8; 576 fp->flags = 0; 577 break; 578 case 6: 579 strcpy(fp->name, AudioEulinear_le); 580 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 581 fp->precision = 16; 582 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 583 break; 584 case 7: 585 strcpy(fp->name, AudioEulinear_be); 586 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 587 fp->precision = 16; 588 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 589 break; 590 default: 591 return(EINVAL); 592 /*NOTREACHED*/ 593 } 594 595 return (0); 596 } 597 598 /* 599 * Store blocksize in bytes. 600 */ 601 602 int 603 aria_round_blocksize(addr, blk) 604 void *addr; 605 int blk; 606 { 607 int i; 608 #if 0 /* XXX -- this is being a tad bit of a problem... */ 609 for (i=64; i<1024; i*=2) 610 if (blk <= i) 611 break; 612 #else 613 i = 1024; 614 #endif 615 return(i); 616 } 617 618 int 619 aria_get_props(addr) 620 void *addr; 621 { 622 return AUDIO_PROP_FULLDUPLEX; 623 } 624 625 int 626 aria_set_params(addr, setmode, usemode, p, r) 627 void *addr; 628 int setmode, usemode; 629 struct audio_params *p, *r; 630 { 631 struct aria_softc *sc = addr; 632 633 switch(p->encoding) { 634 case AUDIO_ENCODING_ULAW: 635 case AUDIO_ENCODING_ALAW: 636 case AUDIO_ENCODING_SLINEAR: 637 case AUDIO_ENCODING_SLINEAR_LE: 638 case AUDIO_ENCODING_SLINEAR_BE: 639 case AUDIO_ENCODING_ULINEAR: 640 case AUDIO_ENCODING_ULINEAR_LE: 641 case AUDIO_ENCODING_ULINEAR_BE: 642 break; 643 default: 644 return (EINVAL); 645 } 646 647 if (p->sample_rate <= 9450) 648 p->sample_rate = 7875; 649 else if (p->sample_rate <= 13387) 650 p->sample_rate = 11025; 651 else if (p->sample_rate <= 18900) 652 p->sample_rate = 15750; 653 else if (p->sample_rate <= 26775) 654 p->sample_rate = 22050; 655 else if (p->sample_rate <= 37800) 656 p->sample_rate = 31500; 657 else 658 p->sample_rate = 44100; 659 660 sc->sc_encoding = p->encoding; 661 sc->sc_precision = p->precision; 662 sc->sc_chans = p->channels; 663 sc->sc_rate = p->sample_rate; 664 665 switch(p->encoding) { 666 case AUDIO_ENCODING_ULAW: 667 if ((ARIA_MODEL&sc->sc_hardware) == 0) { 668 p->sw_code = mulaw_to_ulinear8; 669 r->sw_code = ulinear8_to_mulaw; 670 } 671 break; 672 case AUDIO_ENCODING_ALAW: 673 if ((ARIA_MODEL&sc->sc_hardware) == 0) { 674 p->sw_code = alaw_to_ulinear8; 675 r->sw_code = ulinear8_to_alaw; 676 } 677 break; 678 case AUDIO_ENCODING_SLINEAR: 679 p->sw_code = r->sw_code = change_sign8; 680 break; 681 case AUDIO_ENCODING_ULINEAR_LE: 682 p->sw_code = r->sw_code = change_sign16_le; 683 break; 684 case AUDIO_ENCODING_SLINEAR_BE: 685 p->sw_code = r->sw_code = swap_bytes; 686 break; 687 case AUDIO_ENCODING_ULINEAR_BE: 688 p->sw_code = r->sw_code = swap_bytes_change_sign16_le; 689 break; 690 } 691 692 return 0; 693 } 694 695 /* 696 * This is where all of the twiddling goes on. 697 */ 698 699 int 700 aria_commit_settings(addr) 701 void *addr; 702 { 703 struct aria_softc *sc = addr; 704 bus_space_tag_t iot = sc->sc_iot; 705 bus_space_handle_t ioh = sc->sc_ioh; 706 static u_char tones[16] = 707 { 7, 6, 5, 4, 3, 2, 1, 0, 8, 9, 10, 11, 12, 13, 14, 15 }; 708 u_short format; 709 u_short left, right; 710 u_short samp; 711 u_char i; 712 713 DPRINTF(("aria_commit_settings\n")); 714 715 switch (sc->sc_rate) { 716 case 7875: format = 0x00; samp = 0x60; break; 717 case 11025: format = 0x00; samp = 0x40; break; 718 case 15750: format = 0x10; samp = 0x60; break; 719 case 22050: format = 0x10; samp = 0x40; break; 720 case 31500: format = 0x10; samp = 0x20; break; 721 case 44100: format = 0x20; samp = 0x00; break; 722 default: format = 0x00; samp = 0x40; break;/* XXX can we get here? */ 723 } 724 725 if ((ARIA_MODEL&sc->sc_hardware) != 0) { 726 format |= (sc->sc_encoding==AUDIO_ENCODING_ULAW)?0x06:0x00; 727 format |= (sc->sc_encoding==AUDIO_ENCODING_ALAW)?0x08:0x00; 728 } 729 730 format |= (sc->sc_precision==16)?0x02:0x00; 731 format |= (sc->sc_chans==2)?1:0; 732 samp |= bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ~0x60; 733 734 aria_sendcmd(sc, ARIADSPC_FORMAT, format, -1, -1); 735 bus_space_write_2(iot, ioh, ARIADSP_CONTROL, samp); 736 737 if (sc->sc_hardware&ARIA_MIXER) { 738 for (i = 0; i < 6; i++) 739 aria_set_mixer(sc, i); 740 741 if (sc->sc_chans==2) { 742 aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN, 743 ((sc->sc_gain[0]+sc->sc_gain[1])/2)<<7, 744 -1); 745 aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN, 746 (sc->sc_gain[0]-sc->sc_gain[1])/4+0x40, 747 -1); 748 } else { 749 aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN, 750 sc->sc_gain[0]<<7, -1); 751 aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN, 752 0x40, -1); 753 } 754 755 aria_sendcmd(sc, ARIADSPC_MASMONMODE, 756 sc->ariamix_master.num_channels != 2, -1, -1); 757 758 aria_sendcmd(sc, ARIADSPC_MIXERVOL, 0x0004, 759 sc->ariamix_master.level[0] << 7, 760 sc->ariamix_master.level[1] << 7); 761 762 /* Convert treble/bass from byte to soundcard style */ 763 764 left = (tones[(sc->ariamix_master.treble[0]>>4)&0x0f]<<8) | 765 tones[(sc->ariamix_master.bass[0]>>4)&0x0f]; 766 right = (tones[(sc->ariamix_master.treble[1]>>4)&0x0f]<<8) | 767 tones[(sc->ariamix_master.bass[1]>>4)&0x0f]; 768 769 aria_sendcmd(sc, ARIADSPC_TONE, left, right, -1); 770 } 771 772 aria_sendcmd(sc, ARIADSPC_BLOCKSIZE, sc->sc_blocksize/2, -1, -1); 773 774 /* 775 * If we think that the card is recording or playing, start it up again here. 776 * Some of the previous commands turn the channels off. 777 */ 778 779 if (sc->sc_record&(1<<ARIAR_RECORD_CHAN)) 780 aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1); 781 782 if (sc->sc_play&(1<<ARIAR_PLAY_CHAN)) 783 aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1); 784 785 return(0); 786 } 787 788 void 789 aria_set_mixer(sc, i) 790 struct aria_softc *sc; 791 int i; 792 { 793 u_char source; 794 switch(i) { 795 case ARIAMIX_MIC_LVL: source = 0x0001; break; 796 case ARIAMIX_CD_LVL: source = 0x0002; break; 797 case ARIAMIX_LINE_IN_LVL: source = 0x0008; break; 798 case ARIAMIX_TEL_LVL: source = 0x0020; break; 799 case ARIAMIX_AUX_LVL: source = 0x0010; break; 800 case ARIAMIX_DAC_LVL: source = 0x0004; break; 801 default: source = 0x0000; break; 802 } 803 804 if (source != 0x0000 && source != 0x0004) { 805 if (sc->aria_mix[i].mute == 1) 806 aria_sendcmd(sc, ARIADSPC_INPMONMODE, source, 3, -1); 807 else 808 aria_sendcmd(sc, ARIADSPC_INPMONMODE, source, 809 sc->aria_mix[i].num_channels != 2, -1); 810 811 aria_sendcmd(sc, ARIADSPC_INPMONMODE, 0x8000|source, 812 sc->aria_mix[i].num_channels != 2, -1); 813 aria_sendcmd(sc, ARIADSPC_MIXERVOL, source, 814 sc->aria_mix[i].level[0] << 7, 815 sc->aria_mix[i].level[1] << 7); 816 } 817 818 if (sc->aria_mix_source == i) { 819 aria_sendcmd(sc, ARIADSPC_ADCSOURCE, source, -1, -1); 820 821 if (sc->sc_open & ARIAR_OPEN_RECORD) 822 aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 1, -1, -1); 823 else 824 aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 0, -1, -1); 825 } 826 } 827 828 void 829 ariaclose(addr) 830 void *addr; 831 { 832 struct aria_softc *sc = addr; 833 834 DPRINTF(("aria_close sc=0x%x\n", (unsigned) sc)); 835 836 sc->sc_rintr = 0; 837 sc->sc_pintr = 0; 838 sc->sc_rdiobuffer = 0; 839 sc->sc_pdiobuffer = 0; 840 841 if (sc->sc_play&(1<<ARIAR_PLAY_CHAN) && 842 sc->sc_open & ARIAR_OPEN_PLAY) { 843 aria_sendcmd(sc, ARIADSPC_STOP_PLAY, ARIAR_PLAY_CHAN, -1, -1); 844 sc->sc_play &= ~(1<<ARIAR_PLAY_CHAN); 845 } 846 847 if (sc->sc_record&(1<<ARIAR_RECORD_CHAN) && 848 sc->sc_open & ARIAR_OPEN_RECORD) { 849 aria_sendcmd(sc, ARIADSPC_STOP_REC, ARIAR_RECORD_CHAN, -1, -1); 850 sc->sc_record &= ~(1<<ARIAR_RECORD_CHAN); 851 } 852 853 sc->sc_open = 0; 854 855 if (aria_reset(sc) != 0) { 856 delay(500); 857 aria_reset(sc); 858 } 859 } 860 861 /* 862 * Reset the hardware. 863 */ 864 865 int ariareset(iot, ioh) 866 bus_space_tag_t iot; 867 bus_space_handle_t ioh; 868 { 869 struct aria_softc tmp, *sc = &tmp; 870 871 sc->sc_iot = iot; 872 sc->sc_ioh = ioh; 873 return aria_reset(sc); 874 } 875 876 int 877 aria_reset(sc) 878 struct aria_softc *sc; 879 { 880 bus_space_tag_t iot = sc->sc_iot; 881 bus_space_handle_t ioh = sc->sc_ioh; 882 int fail=0; 883 int i; 884 885 bus_space_write_2(iot, ioh, ARIADSP_CONTROL, 886 ARIAR_ARIA_SYNTH | ARIAR_SR22K|ARIAR_DSPINTWR); 887 aria_putdspmem(sc, 0x6102, 0); 888 889 fail |= aria_sendcmd(sc, ARIADSPC_SYSINIT, 0x0000, 0x0000, 0x0000); 890 891 for (i=0; i < ARIAR_NPOLL; i++) 892 if (aria_getdspmem(sc, ARIAA_TASK_A) == 1) 893 break; 894 895 bus_space_write_2(iot, ioh, ARIADSP_CONTROL, 896 ARIAR_ARIA_SYNTH|ARIAR_SR22K | ARIAR_DSPINTWR | 897 ARIAR_PCINTWR); 898 fail |= aria_sendcmd(sc, ARIADSPC_MODE, ARIAV_MODE_NO_SYNTH,-1,-1); 899 900 return (fail); 901 } 902 903 /* 904 * Lower-level routines 905 */ 906 907 void 908 aria_putdspmem(sc, loc, val) 909 struct aria_softc *sc; 910 u_short loc; 911 u_short val; 912 { 913 bus_space_tag_t iot = sc->sc_iot; 914 bus_space_handle_t ioh = sc->sc_ioh; 915 bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc); 916 bus_space_write_2(iot, ioh, ARIADSP_DMADATA, val); 917 } 918 919 u_short 920 aria_getdspmem(sc, loc) 921 struct aria_softc *sc; 922 u_short loc; 923 { 924 bus_space_tag_t iot = sc->sc_iot; 925 bus_space_handle_t ioh = sc->sc_ioh; 926 bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc); 927 return bus_space_read_2(iot, ioh, ARIADSP_DMADATA); 928 } 929 930 /* 931 * aria_sendcmd() 932 * each full DSP command is unified into this 933 * function. 934 */ 935 936 #define ARIASEND(data, flag) \ 937 for (i = ARIAR_NPOLL; \ 938 (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) && i>0; \ 939 i--) \ 940 ; \ 941 if (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) \ 942 fail |= flag; \ 943 bus_space_write_2(iot, ioh, ARIADSP_WRITE, (u_short)data) 944 945 int 946 aria_sendcmd(sc, command, arg1, arg2, arg3) 947 struct aria_softc *sc; 948 u_short command; 949 int arg1; 950 int arg2; 951 int arg3; 952 { 953 bus_space_tag_t iot = sc->sc_iot; 954 bus_space_handle_t ioh = sc->sc_ioh; 955 int i, fail = 0; 956 957 ARIASEND(command, 1); 958 if (arg1 != -1) { 959 ARIASEND(arg1, 2); 960 } 961 if (arg2 != -1) { 962 ARIASEND(arg2, 4); 963 } 964 if (arg3 != -1) { 965 ARIASEND(arg3, 8); 966 } 967 ARIASEND(ARIADSPC_TERM, 16); 968 969 if (fail) { 970 sc->sc_sendcmd_err++; 971 #ifdef AUDIO_DEBUG 972 DPRINTF(("aria_sendcmd: failure=(%d) cmd=(0x%x) fail=(0x%x)\n", 973 sc->sc_sendcmd_err, command, fail)); 974 #endif 975 return -1; 976 } 977 978 return 0; 979 } 980 #undef ARIASEND 981 982 int 983 aria_halt_input(addr) 984 void *addr; 985 { 986 struct aria_softc *sc = addr; 987 988 DPRINTF(("aria_halt_input\n")); 989 990 if (sc->sc_record & (1<<0)) { 991 aria_sendcmd(sc, ARIADSPC_STOP_REC, 0, -1, -1); 992 sc->sc_record &= ~(1<<0); 993 } 994 995 return(0); 996 } 997 998 int 999 aria_halt_output(addr) 1000 void *addr; 1001 { 1002 struct aria_softc *sc = addr; 1003 1004 DPRINTF(("aria_halt_output\n")); 1005 1006 if (sc->sc_play & (1<<1)) { 1007 aria_sendcmd(sc, ARIADSPC_STOP_PLAY, 1, -1, -1); 1008 sc->sc_play &= ~(1<<1); 1009 } 1010 1011 return(0); 1012 } 1013 1014 /* 1015 * Here we just set up the buffers. If we receive 1016 * an interrupt without these set, it is ignored. 1017 */ 1018 1019 int 1020 aria_start_input(addr, p, cc, intr, arg) 1021 void *addr; 1022 void *p; 1023 int cc; 1024 void (*intr) __P((void *)); 1025 void *arg; 1026 { 1027 struct aria_softc *sc = addr; 1028 1029 DPRINTF(("aria_start_input %d @ %x\n", cc, (unsigned) p)); 1030 1031 if (cc != sc->sc_blocksize) { 1032 DPRINTF(("aria_start_input reqsize %d not sc_blocksize %d\n", 1033 cc, sc->sc_blocksize)); 1034 return EINVAL; 1035 } 1036 1037 sc->sc_rarg = arg; 1038 sc->sc_rintr = intr; 1039 sc->sc_rdiobuffer = p; 1040 1041 if (!(sc->sc_record&(1<<ARIAR_RECORD_CHAN))) { 1042 aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1); 1043 sc->sc_record |= (1<<ARIAR_RECORD_CHAN); 1044 } 1045 1046 return 0; 1047 } 1048 1049 int 1050 aria_start_output(addr, p, cc, intr, arg) 1051 void *addr; 1052 void *p; 1053 int cc; 1054 void (*intr) __P((void *)); 1055 void *arg; 1056 { 1057 struct aria_softc *sc = addr; 1058 1059 DPRINTF(("aria_start_output %d @ %x\n", cc, (unsigned) p)); 1060 1061 if (cc != sc->sc_blocksize) { 1062 DPRINTF(("aria_start_output reqsize %d not sc_blocksize %d\n", 1063 cc, sc->sc_blocksize)); 1064 return EINVAL; 1065 } 1066 1067 sc->sc_parg = arg; 1068 sc->sc_pintr = intr; 1069 sc->sc_pdiobuffer = p; 1070 1071 if (!(sc->sc_play&(1<<ARIAR_PLAY_CHAN))) { 1072 aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1); 1073 sc->sc_play |= (1<<ARIAR_PLAY_CHAN); 1074 } 1075 1076 return 0; 1077 } 1078 1079 /* 1080 * Process an interrupt. This should be a 1081 * request (from the card) to write or read 1082 * samples. 1083 */ 1084 int 1085 aria_intr(arg) 1086 void *arg; 1087 { 1088 struct aria_softc *sc = arg; 1089 bus_space_tag_t iot = sc->sc_iot; 1090 bus_space_handle_t ioh = sc->sc_ioh; 1091 u_short *pdata = sc->sc_pdiobuffer; 1092 u_short *rdata = sc->sc_rdiobuffer; 1093 u_short address; 1094 1095 #if 0 /* XXX -- BAD BAD BAD (That this is #define'd out */ 1096 DPRINTF(("Checking to see if this is our intr\n")); 1097 1098 if ((inw(iobase) & 1) != 0x1) 1099 return 0; /* not for us */ 1100 #endif 1101 1102 sc->sc_interrupts++; 1103 1104 DPRINTF(("aria_intr\n")); 1105 1106 if ((sc->sc_open & ARIAR_OPEN_PLAY) && (pdata!=NULL)) { 1107 DPRINTF(("aria_intr play=(%x)\n", (unsigned) pdata)); 1108 address = 0x8000 - 2*(sc->sc_blocksize); 1109 address+= aria_getdspmem(sc, ARIAA_PLAY_FIFO_A); 1110 bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address); 1111 bus_space_write_multi_2(iot, ioh, ARIADSP_DMADATA, pdata, 1112 sc->sc_blocksize / 2); 1113 if (sc->sc_pintr != NULL) 1114 (*sc->sc_pintr)(sc->sc_parg); 1115 } 1116 1117 if ((sc->sc_open & ARIAR_OPEN_RECORD) && (rdata!=NULL)) { 1118 DPRINTF(("aria_intr record=(%x)\n", (unsigned) rdata)); 1119 address = 0x8000 - (sc->sc_blocksize); 1120 address+= aria_getdspmem(sc, ARIAA_REC_FIFO_A); 1121 bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address); 1122 bus_space_read_multi_2(iot, ioh, ARIADSP_DMADATA, rdata, 1123 sc->sc_blocksize / 2); 1124 if (sc->sc_rintr != NULL) 1125 (*sc->sc_rintr)(sc->sc_rarg); 1126 } 1127 1128 aria_sendcmd(sc, ARIADSPC_TRANSCOMPLETE, -1, -1, -1); 1129 1130 return 1; 1131 } 1132 1133 int 1134 aria_mixer_set_port(addr, cp) 1135 void *addr; 1136 mixer_ctrl_t *cp; 1137 { 1138 struct aria_softc *sc = addr; 1139 int error = EINVAL; 1140 1141 DPRINTF(("aria_mixer_set_port\n")); 1142 1143 /* This could be done better, no mixer still has some controls. */ 1144 if (!(ARIA_MIXER & sc->sc_hardware)) 1145 return ENXIO; 1146 1147 if (cp->type == AUDIO_MIXER_VALUE) { 1148 mixer_level_t *mv = &cp->un.value; 1149 switch (cp->dev) { 1150 case ARIAMIX_MIC_LVL: 1151 if (mv->num_channels == 1 || mv->num_channels == 2) { 1152 sc->aria_mix[ARIAMIX_MIC_LVL].num_channels = 1153 mv->num_channels; 1154 sc->aria_mix[ARIAMIX_MIC_LVL].level[0] = 1155 mv->level[0]; 1156 sc->aria_mix[ARIAMIX_MIC_LVL].level[1] = 1157 mv->level[1]; 1158 error = 0; 1159 } 1160 break; 1161 1162 case ARIAMIX_LINE_IN_LVL: 1163 if (mv->num_channels == 1 || mv->num_channels == 2) { 1164 sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels= 1165 mv->num_channels; 1166 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0] = 1167 mv->level[0]; 1168 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1] = 1169 mv->level[1]; 1170 error = 0; 1171 } 1172 break; 1173 1174 case ARIAMIX_CD_LVL: 1175 if (mv->num_channels == 1 || mv->num_channels == 2) { 1176 sc->aria_mix[ARIAMIX_CD_LVL].num_channels = 1177 mv->num_channels; 1178 sc->aria_mix[ARIAMIX_CD_LVL].level[0] = 1179 mv->level[0]; 1180 sc->aria_mix[ARIAMIX_CD_LVL].level[1] = 1181 mv->level[1]; 1182 error = 0; 1183 } 1184 break; 1185 1186 case ARIAMIX_TEL_LVL: 1187 if (mv->num_channels == 1) { 1188 sc->aria_mix[ARIAMIX_TEL_LVL].num_channels = 1189 mv->num_channels; 1190 sc->aria_mix[ARIAMIX_TEL_LVL].level[0] = 1191 mv->level[0]; 1192 error = 0; 1193 } 1194 break; 1195 1196 case ARIAMIX_DAC_LVL: 1197 if (mv->num_channels == 1 || mv->num_channels == 2) { 1198 sc->aria_mix[ARIAMIX_DAC_LVL].num_channels = 1199 mv->num_channels; 1200 sc->aria_mix[ARIAMIX_DAC_LVL].level[0] = 1201 mv->level[0]; 1202 sc->aria_mix[ARIAMIX_DAC_LVL].level[1] = 1203 mv->level[1]; 1204 error = 0; 1205 } 1206 break; 1207 1208 case ARIAMIX_AUX_LVL: 1209 if (mv->num_channels == 1 || mv->num_channels == 2) { 1210 sc->aria_mix[ARIAMIX_AUX_LVL].num_channels = 1211 mv->num_channels; 1212 sc->aria_mix[ARIAMIX_AUX_LVL].level[0] = 1213 mv->level[0]; 1214 sc->aria_mix[ARIAMIX_AUX_LVL].level[1] = 1215 mv->level[1]; 1216 error = 0; 1217 } 1218 break; 1219 1220 case ARIAMIX_MASTER_LVL: 1221 if (mv->num_channels == 1 || mv->num_channels == 2) { 1222 sc->ariamix_master.num_channels = 1223 mv->num_channels; 1224 sc->ariamix_master.level[0] = mv->level[0]; 1225 sc->ariamix_master.level[1] = mv->level[1]; 1226 error = 0; 1227 } 1228 break; 1229 1230 case ARIAMIX_MASTER_TREBLE: 1231 if (mv->num_channels == 2) { 1232 sc->ariamix_master.treble[0] = 1233 mv->level[0] == 0 ? 1 : mv->level[0]; 1234 sc->ariamix_master.treble[1] = 1235 mv->level[1] == 0 ? 1 : mv->level[1]; 1236 error = 0; 1237 } 1238 break; 1239 case ARIAMIX_MASTER_BASS: 1240 if (mv->num_channels == 2) { 1241 sc->ariamix_master.bass[0] = 1242 mv->level[0] == 0 ? 1 : mv->level[0]; 1243 sc->ariamix_master.bass[1] = 1244 mv->level[1] == 0 ? 1 : mv->level[1]; 1245 error = 0; 1246 } 1247 break; 1248 case ARIAMIX_OUT_LVL: 1249 if (mv->num_channels == 1 || mv->num_channels == 2) { 1250 sc->sc_gain[0] = mv->level[0]; 1251 sc->sc_gain[1] = mv->level[1]; 1252 error = 0; 1253 } 1254 break; 1255 default: 1256 } 1257 } 1258 1259 if (cp->type == AUDIO_MIXER_ENUM) 1260 switch(cp->dev) { 1261 case ARIAMIX_RECORD_SOURCE: 1262 if (cp->un.ord>=0 && cp->un.ord<=6) { 1263 sc->aria_mix_source = cp->un.ord; 1264 error = 0; 1265 } 1266 break; 1267 1268 case ARIAMIX_MIC_MUTE: 1269 if (cp->un.ord == 0 || cp->un.ord == 1) { 1270 sc->aria_mix[ARIAMIX_MIC_LVL].mute =cp->un.ord; 1271 error = 0; 1272 } 1273 break; 1274 1275 case ARIAMIX_LINE_IN_MUTE: 1276 if (cp->un.ord == 0 || cp->un.ord == 1) { 1277 sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute = 1278 cp->un.ord; 1279 error = 0; 1280 } 1281 break; 1282 1283 case ARIAMIX_CD_MUTE: 1284 if (cp->un.ord == 0 || cp->un.ord == 1) { 1285 sc->aria_mix[ARIAMIX_CD_LVL].mute = cp->un.ord; 1286 error = 0; 1287 } 1288 break; 1289 1290 case ARIAMIX_DAC_MUTE: 1291 if (cp->un.ord == 0 || cp->un.ord == 1) { 1292 sc->aria_mix[ARIAMIX_DAC_LVL].mute =cp->un.ord; 1293 error = 0; 1294 } 1295 break; 1296 1297 case ARIAMIX_AUX_MUTE: 1298 if (cp->un.ord == 0 || cp->un.ord == 1) { 1299 sc->aria_mix[ARIAMIX_AUX_LVL].mute =cp->un.ord; 1300 error = 0; 1301 } 1302 break; 1303 1304 case ARIAMIX_TEL_MUTE: 1305 if (cp->un.ord == 0 || cp->un.ord == 1) { 1306 sc->aria_mix[ARIAMIX_TEL_LVL].mute =cp->un.ord; 1307 error = 0; 1308 } 1309 break; 1310 1311 default: 1312 /* NOTREACHED */ 1313 return ENXIO; 1314 } 1315 1316 return(error); 1317 } 1318 1319 int 1320 aria_mixer_get_port(addr, cp) 1321 void *addr; 1322 mixer_ctrl_t *cp; 1323 { 1324 struct aria_softc *sc = addr; 1325 int error = EINVAL; 1326 1327 DPRINTF(("aria_mixer_get_port\n")); 1328 1329 /* This could be done better, no mixer still has some controls. */ 1330 if (!(ARIA_MIXER&sc->sc_hardware)) 1331 return ENXIO; 1332 1333 switch (cp->dev) { 1334 case ARIAMIX_MIC_LVL: 1335 if (cp->type == AUDIO_MIXER_VALUE) { 1336 cp->un.value.num_channels = 1337 sc->aria_mix[ARIAMIX_MIC_LVL].num_channels; 1338 cp->un.value.level[0] = 1339 sc->aria_mix[ARIAMIX_MIC_LVL].level[0]; 1340 cp->un.value.level[1] = 1341 sc->aria_mix[ARIAMIX_MIC_LVL].level[1]; 1342 error = 0; 1343 } 1344 break; 1345 1346 case ARIAMIX_LINE_IN_LVL: 1347 if (cp->type == AUDIO_MIXER_VALUE) { 1348 cp->un.value.num_channels = 1349 sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels; 1350 cp->un.value.level[0] = 1351 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0]; 1352 cp->un.value.level[1] = 1353 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1]; 1354 error = 0; 1355 } 1356 break; 1357 1358 case ARIAMIX_CD_LVL: 1359 if (cp->type == AUDIO_MIXER_VALUE) { 1360 cp->un.value.num_channels = 1361 sc->aria_mix[ARIAMIX_CD_LVL].num_channels; 1362 cp->un.value.level[0] = 1363 sc->aria_mix[ARIAMIX_CD_LVL].level[0]; 1364 cp->un.value.level[1] = 1365 sc->aria_mix[ARIAMIX_CD_LVL].level[1]; 1366 error = 0; 1367 } 1368 break; 1369 1370 case ARIAMIX_TEL_LVL: 1371 if (cp->type == AUDIO_MIXER_VALUE) { 1372 cp->un.value.num_channels = 1373 sc->aria_mix[ARIAMIX_TEL_LVL].num_channels; 1374 cp->un.value.level[0] = 1375 sc->aria_mix[ARIAMIX_TEL_LVL].level[0]; 1376 error = 0; 1377 } 1378 break; 1379 case ARIAMIX_DAC_LVL: 1380 if (cp->type == AUDIO_MIXER_VALUE) { 1381 cp->un.value.num_channels = 1382 sc->aria_mix[ARIAMIX_DAC_LVL].num_channels; 1383 cp->un.value.level[0] = 1384 sc->aria_mix[ARIAMIX_DAC_LVL].level[0]; 1385 cp->un.value.level[1] = 1386 sc->aria_mix[ARIAMIX_DAC_LVL].level[1]; 1387 error = 0; 1388 } 1389 break; 1390 1391 case ARIAMIX_AUX_LVL: 1392 if (cp->type == AUDIO_MIXER_VALUE) { 1393 cp->un.value.num_channels = 1394 sc->aria_mix[ARIAMIX_AUX_LVL].num_channels; 1395 cp->un.value.level[0] = 1396 sc->aria_mix[ARIAMIX_AUX_LVL].level[0]; 1397 cp->un.value.level[1] = 1398 sc->aria_mix[ARIAMIX_AUX_LVL].level[1]; 1399 error = 0; 1400 } 1401 break; 1402 1403 case ARIAMIX_MIC_MUTE: 1404 if (cp->type == AUDIO_MIXER_ENUM) { 1405 cp->un.ord = sc->aria_mix[ARIAMIX_MIC_LVL].mute; 1406 error = 0; 1407 } 1408 break; 1409 1410 case ARIAMIX_LINE_IN_MUTE: 1411 if (cp->type == AUDIO_MIXER_ENUM) { 1412 cp->un.ord = sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute; 1413 error = 0; 1414 } 1415 break; 1416 1417 case ARIAMIX_CD_MUTE: 1418 if (cp->type == AUDIO_MIXER_ENUM) { 1419 cp->un.ord = sc->aria_mix[ARIAMIX_CD_LVL].mute; 1420 error = 0; 1421 } 1422 break; 1423 1424 case ARIAMIX_DAC_MUTE: 1425 if (cp->type == AUDIO_MIXER_ENUM) { 1426 cp->un.ord = sc->aria_mix[ARIAMIX_DAC_LVL].mute; 1427 error = 0; 1428 } 1429 break; 1430 1431 case ARIAMIX_AUX_MUTE: 1432 if (cp->type == AUDIO_MIXER_ENUM) { 1433 cp->un.ord = sc->aria_mix[ARIAMIX_AUX_LVL].mute; 1434 error = 0; 1435 } 1436 break; 1437 1438 case ARIAMIX_TEL_MUTE: 1439 if (cp->type == AUDIO_MIXER_ENUM) { 1440 cp->un.ord = sc->aria_mix[ARIAMIX_TEL_LVL].mute; 1441 error = 0; 1442 } 1443 break; 1444 1445 case ARIAMIX_MASTER_LVL: 1446 if (cp->type == AUDIO_MIXER_VALUE) { 1447 cp->un.value.num_channels = 1448 sc->ariamix_master.num_channels; 1449 cp->un.value.level[0] = sc->ariamix_master.level[0]; 1450 cp->un.value.level[1] = sc->ariamix_master.level[1]; 1451 error = 0; 1452 } 1453 break; 1454 1455 case ARIAMIX_MASTER_TREBLE: 1456 if (cp->type == AUDIO_MIXER_VALUE) { 1457 cp->un.value.num_channels = 2; 1458 cp->un.value.level[0] = sc->ariamix_master.treble[0]; 1459 cp->un.value.level[1] = sc->ariamix_master.treble[1]; 1460 error = 0; 1461 } 1462 break; 1463 1464 case ARIAMIX_MASTER_BASS: 1465 if (cp->type == AUDIO_MIXER_VALUE) { 1466 cp->un.value.num_channels = 2; 1467 cp->un.value.level[0] = sc->ariamix_master.bass[0]; 1468 cp->un.value.level[1] = sc->ariamix_master.bass[1]; 1469 error = 0; 1470 } 1471 break; 1472 1473 case ARIAMIX_OUT_LVL: 1474 if (cp->type == AUDIO_MIXER_VALUE) { 1475 cp->un.value.num_channels = sc->sc_chans; 1476 cp->un.value.level[0] = sc->sc_gain[0]; 1477 cp->un.value.level[1] = sc->sc_gain[1]; 1478 error = 0; 1479 } 1480 break; 1481 case ARIAMIX_RECORD_SOURCE: 1482 if (cp->type == AUDIO_MIXER_ENUM) { 1483 cp->un.ord = sc->aria_mix_source; 1484 error = 0; 1485 } 1486 break; 1487 1488 default: 1489 return ENXIO; 1490 /* NOT REACHED */ 1491 } 1492 1493 return(error); 1494 } 1495 1496 int 1497 aria_mixer_query_devinfo(addr, dip) 1498 void *addr; 1499 mixer_devinfo_t *dip; 1500 { 1501 1502 struct aria_softc *sc = addr; 1503 1504 DPRINTF(("aria_mixer_query_devinfo\n")); 1505 1506 /* This could be done better, no mixer still has some controls. */ 1507 if (!(ARIA_MIXER & sc->sc_hardware)) 1508 return ENXIO; 1509 1510 dip->prev = dip->next = AUDIO_MIXER_LAST; 1511 1512 switch(dip->index) { 1513 case ARIAMIX_MIC_LVL: 1514 dip->type = AUDIO_MIXER_VALUE; 1515 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1516 dip->next = ARIAMIX_MIC_MUTE; 1517 strcpy(dip->label.name, AudioNmicrophone); 1518 dip->un.v.num_channels = 2; 1519 strcpy(dip->un.v.units.name, AudioNvolume); 1520 break; 1521 1522 case ARIAMIX_LINE_IN_LVL: 1523 dip->type = AUDIO_MIXER_VALUE; 1524 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1525 dip->next = ARIAMIX_LINE_IN_MUTE; 1526 strcpy(dip->label.name, AudioNline); 1527 dip->un.v.num_channels = 2; 1528 strcpy(dip->un.v.units.name, AudioNvolume); 1529 break; 1530 1531 case ARIAMIX_CD_LVL: 1532 dip->type = AUDIO_MIXER_VALUE; 1533 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1534 dip->next = ARIAMIX_CD_MUTE; 1535 strcpy(dip->label.name, AudioNcd); 1536 dip->un.v.num_channels = 2; 1537 strcpy(dip->un.v.units.name, AudioNvolume); 1538 break; 1539 1540 case ARIAMIX_TEL_LVL: 1541 dip->type = AUDIO_MIXER_VALUE; 1542 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1543 dip->next = ARIAMIX_TEL_MUTE; 1544 strcpy(dip->label.name, "telephone"); 1545 dip->un.v.num_channels = 1; 1546 strcpy(dip->un.v.units.name, AudioNvolume); 1547 break; 1548 1549 case ARIAMIX_DAC_LVL: 1550 dip->type = AUDIO_MIXER_VALUE; 1551 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1552 dip->next = ARIAMIX_DAC_MUTE; 1553 strcpy(dip->label.name, AudioNdac); 1554 dip->un.v.num_channels = 1; 1555 strcpy(dip->un.v.units.name, AudioNvolume); 1556 break; 1557 1558 case ARIAMIX_AUX_LVL: 1559 dip->type = AUDIO_MIXER_VALUE; 1560 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1561 dip->next = ARIAMIX_AUX_MUTE; 1562 strcpy(dip->label.name, AudioNoutput); 1563 dip->un.v.num_channels = 1; 1564 strcpy(dip->un.v.units.name, AudioNvolume); 1565 break; 1566 1567 case ARIAMIX_MIC_MUTE: 1568 dip->prev = ARIAMIX_MIC_LVL; 1569 goto mute; 1570 1571 case ARIAMIX_LINE_IN_MUTE: 1572 dip->prev = ARIAMIX_LINE_IN_LVL; 1573 goto mute; 1574 1575 case ARIAMIX_CD_MUTE: 1576 dip->prev = ARIAMIX_CD_LVL; 1577 goto mute; 1578 1579 case ARIAMIX_DAC_MUTE: 1580 dip->prev = ARIAMIX_DAC_LVL; 1581 goto mute; 1582 1583 case ARIAMIX_AUX_MUTE: 1584 dip->prev = ARIAMIX_AUX_LVL; 1585 goto mute; 1586 1587 case ARIAMIX_TEL_MUTE: 1588 dip->prev = ARIAMIX_TEL_LVL; 1589 goto mute; 1590 1591 mute: 1592 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1593 dip->type = AUDIO_MIXER_ENUM; 1594 strcpy(dip->label.name, AudioNmute); 1595 dip->un.e.num_mem = 2; 1596 strcpy(dip->un.e.member[0].label.name, AudioNoff); 1597 dip->un.e.member[0].ord = 0; 1598 strcpy(dip->un.e.member[1].label.name, AudioNon); 1599 dip->un.e.member[1].ord = 1; 1600 break; 1601 1602 case ARIAMIX_MASTER_LVL: 1603 dip->type = AUDIO_MIXER_VALUE; 1604 dip->mixer_class = ARIAMIX_OUTPUT_CLASS; 1605 dip->next = AUDIO_MIXER_LAST; 1606 strcpy(dip->label.name, AudioNvolume); 1607 dip->un.v.num_channels = 2; 1608 strcpy(dip->un.v.units.name, AudioNvolume); 1609 break; 1610 1611 case ARIAMIX_MASTER_TREBLE: 1612 dip->type = AUDIO_MIXER_VALUE; 1613 dip->mixer_class = ARIAMIX_EQ_CLASS; 1614 strcpy(dip->label.name, AudioNtreble); 1615 dip->un.v.num_channels = 2; 1616 strcpy(dip->un.v.units.name, AudioNtreble); 1617 break; 1618 1619 case ARIAMIX_MASTER_BASS: 1620 dip->type = AUDIO_MIXER_VALUE; 1621 dip->mixer_class = ARIAMIX_EQ_CLASS; 1622 strcpy(dip->label.name, AudioNbass); 1623 dip->un.v.num_channels = 2; 1624 strcpy(dip->un.v.units.name, AudioNbass); 1625 break; 1626 1627 case ARIAMIX_OUT_LVL: 1628 dip->type = AUDIO_MIXER_VALUE; 1629 dip->mixer_class = ARIAMIX_OUTPUT_CLASS; 1630 strcpy(dip->label.name, AudioNoutput); 1631 dip->un.v.num_channels = 2; 1632 strcpy(dip->un.v.units.name, AudioNvolume); 1633 break; 1634 1635 case ARIAMIX_RECORD_SOURCE: 1636 dip->mixer_class = ARIAMIX_RECORD_CLASS; 1637 dip->type = AUDIO_MIXER_ENUM; 1638 strcpy(dip->label.name, AudioNsource); 1639 dip->un.e.num_mem = 6; 1640 strcpy(dip->un.e.member[0].label.name, AudioNoutput); 1641 dip->un.e.member[0].ord = ARIAMIX_AUX_LVL; 1642 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone); 1643 dip->un.e.member[1].ord = ARIAMIX_MIC_LVL; 1644 strcpy(dip->un.e.member[2].label.name, AudioNdac); 1645 dip->un.e.member[2].ord = ARIAMIX_DAC_LVL; 1646 strcpy(dip->un.e.member[3].label.name, AudioNline); 1647 dip->un.e.member[3].ord = ARIAMIX_LINE_IN_LVL; 1648 strcpy(dip->un.e.member[4].label.name, AudioNcd); 1649 dip->un.e.member[4].ord = ARIAMIX_CD_LVL; 1650 strcpy(dip->un.e.member[5].label.name, "telephone"); 1651 dip->un.e.member[5].ord = ARIAMIX_TEL_LVL; 1652 break; 1653 1654 case ARIAMIX_INPUT_CLASS: 1655 dip->type = AUDIO_MIXER_CLASS; 1656 dip->mixer_class = ARIAMIX_INPUT_CLASS; 1657 strcpy(dip->label.name, AudioCinputs); 1658 break; 1659 1660 case ARIAMIX_OUTPUT_CLASS: 1661 dip->type = AUDIO_MIXER_CLASS; 1662 dip->mixer_class = ARIAMIX_OUTPUT_CLASS; 1663 strcpy(dip->label.name, AudioCoutputs); 1664 break; 1665 1666 case ARIAMIX_RECORD_CLASS: 1667 dip->type = AUDIO_MIXER_CLASS; 1668 dip->mixer_class = ARIAMIX_RECORD_CLASS; 1669 strcpy(dip->label.name, AudioCrecord); 1670 break; 1671 1672 case ARIAMIX_EQ_CLASS: 1673 dip->type = AUDIO_MIXER_CLASS; 1674 dip->mixer_class = ARIAMIX_EQ_CLASS; 1675 strcpy(dip->label.name, AudioCequalization); 1676 break; 1677 1678 default: 1679 return ENXIO; 1680 /*NOTREACHED*/ 1681 } 1682 return 0; 1683 } 1684