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