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