1 /* $NetBSD: aucc.c,v 1.28 2001/10/03 00:04:47 augustss Exp $ */ 2 3 /* 4 * Copyright (c) 1999 Bernardo Innocenti 5 * All rights reserved. 6 * 7 * Copyright (c) 1997 Stephan Thesing 8 * All rights reserved. 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Stephan Thesing. 21 * 4. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* TODO: 37 * 38 * - ulaw -> 14bit conversion 39 * - channel allocation is wrong for 14bit mono 40 * - convert the... err... conversion routines to 68k asm for best performance 41 * XXX: NO. aucc audio is limited by chipmem speed, anyway. You dont 42 * want to make life difficult for amigappc work. 43 * -is 44 * 45 * - rely on auconv.c routines for ulaw/alaw conversions 46 * - perhaps use a calibration table for better 14bit output 47 * - set 31KHz AGA video mode to allow 44.1KHz even if grfcc is missing 48 * in the kernel 49 * - 14bit output requires maximum volume 50 */ 51 52 #include "aucc.h" 53 #if NAUCC > 0 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/errno.h> 58 #include <sys/ioctl.h> 59 #include <sys/device.h> 60 #include <sys/proc.h> 61 #include <machine/cpu.h> 62 63 #include <sys/audioio.h> 64 #include <dev/audio_if.h> 65 #include <amiga/amiga/cc.h> 66 #include <amiga/amiga/custom.h> 67 #include <amiga/amiga/device.h> 68 #include <amiga/dev/auccvar.h> 69 70 #include "opt_lev6_defer.h" 71 72 73 #ifdef LEV6_DEFER 74 #define AUCC_MAXINT 3 75 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2) 76 #else 77 #define AUCC_MAXINT 4 78 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3) 79 #endif 80 /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */ 81 #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3) 82 83 #ifdef AUDIO_DEBUG 84 /*extern printf __P((const char *,...));*/ 85 int auccdebug = 1; 86 #define DPRINTF(x) if (auccdebug) printf x 87 #else 88 #define DPRINTF(x) 89 #endif 90 91 #ifdef splaudio 92 #undef splaudio 93 #endif 94 95 #define splaudio() spl4(); 96 97 /* clock frequency.. */ 98 extern int eclockfreq; 99 100 101 /* hw audio ch */ 102 extern struct audio_channel channel[4]; 103 104 105 /* 106 * Software state. 107 */ 108 struct aucc_softc { 109 struct device sc_dev; /* base device */ 110 111 int sc_open; /* single use device */ 112 aucc_data_t sc_channel[4]; /* per channel freq, ... */ 113 u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/ 114 int sc_channels; /* # of channels used */ 115 int sc_precision; /* 8 or 16 bits */ 116 int sc_14bit; /* 14bit output enabled */ 117 118 int sc_intrcnt; /* interrupt count */ 119 int sc_channelmask; /* which channels are used ? */ 120 void (*sc_decodefunc) __P((u_char **, u_char *, int)); 121 /* pointer to format conversion routine */ 122 }; 123 124 /* interrupt interfaces */ 125 void aucc_inthdl __P((int)); 126 127 /* forward declarations */ 128 static int init_aucc __P((struct aucc_softc *)); 129 static u_int freqtoper __P((u_int)); 130 static u_int pertofreq __P((u_int)); 131 132 /* autoconfiguration driver */ 133 void auccattach __P((struct device *, struct device *, void *)); 134 int auccmatch __P((struct device *, struct cfdata *, void *)); 135 136 struct cfattach aucc_ca = { 137 sizeof(struct aucc_softc), 138 auccmatch, 139 auccattach 140 }; 141 142 struct audio_device aucc_device = { 143 "Amiga-audio", 144 "2.0", 145 "aucc" 146 }; 147 148 149 struct aucc_softc *aucc=NULL; 150 151 152 unsigned char ulaw_to_lin[] = { 153 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e, 154 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe, 155 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, 156 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, 157 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 158 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 159 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4, 160 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8, 161 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 162 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 163 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 164 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 165 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 166 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 167 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 168 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 169 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61, 170 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41, 171 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30, 172 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 173 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 174 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 175 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 176 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, 177 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 178 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 179 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 180 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 181 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 185 }; 186 187 /* 188 * Define our interface to the higher level audio driver. 189 */ 190 int aucc_open __P((void *, int)); 191 void aucc_close __P((void *)); 192 int aucc_set_out_sr __P((void *, u_long)); 193 int aucc_query_encoding __P((void *, struct audio_encoding *)); 194 int aucc_round_blocksize __P((void *, int)); 195 int aucc_commit_settings __P((void *)); 196 int aucc_start_output __P((void *, void *, int, void (*)(void *), 197 void *)); 198 int aucc_start_input __P((void *, void *, int, void (*)(void *), 199 void *)); 200 int aucc_halt_output __P((void *)); 201 int aucc_halt_input __P((void *)); 202 int aucc_getdev __P((void *, struct audio_device *)); 203 int aucc_set_port __P((void *, mixer_ctrl_t *)); 204 int aucc_get_port __P((void *, mixer_ctrl_t *)); 205 int aucc_query_devinfo __P((void *, mixer_devinfo_t *)); 206 void aucc_encode __P((int, int, int, int, u_char *, u_short **)); 207 int aucc_set_params __P((void *, int, int, 208 struct audio_params *, struct audio_params *)); 209 int aucc_get_props __P((void *)); 210 211 212 static void aucc_decode_slinear8_1ch __P((u_char **, u_char *, int)); 213 static void aucc_decode_slinear8_2ch __P((u_char **, u_char *, int)); 214 static void aucc_decode_slinear8_3ch __P((u_char **, u_char *, int)); 215 static void aucc_decode_slinear8_4ch __P((u_char **, u_char *, int)); 216 217 static void aucc_decode_ulinear8_1ch __P((u_char **, u_char *, int)); 218 static void aucc_decode_ulinear8_2ch __P((u_char **, u_char *, int)); 219 static void aucc_decode_ulinear8_3ch __P((u_char **, u_char *, int)); 220 static void aucc_decode_ulinear8_4ch __P((u_char **, u_char *, int)); 221 222 static void aucc_decode_ulaw_1ch __P((u_char **, u_char *, int)); 223 static void aucc_decode_ulaw_2ch __P((u_char **, u_char *, int)); 224 static void aucc_decode_ulaw_3ch __P((u_char **, u_char *, int)); 225 static void aucc_decode_ulaw_4ch __P((u_char **, u_char *, int)); 226 227 static void aucc_decode_slinear16_1ch __P((u_char **, u_char *, int)); 228 static void aucc_decode_slinear16_2ch __P((u_char **, u_char *, int)); 229 static void aucc_decode_slinear16_3ch __P((u_char **, u_char *, int)); 230 static void aucc_decode_slinear16_4ch __P((u_char **, u_char *, int)); 231 232 static void aucc_decode_slinear16sw_1ch __P((u_char **, u_char *, int)); 233 static void aucc_decode_slinear16sw_2ch __P((u_char **, u_char *, int)); 234 static void aucc_decode_slinear16sw_3ch __P((u_char **, u_char *, int)); 235 static void aucc_decode_slinear16sw_4ch __P((u_char **, u_char *, int)); 236 237 238 239 struct audio_hw_if sa_hw_if = { 240 aucc_open, 241 aucc_close, 242 NULL, 243 aucc_query_encoding, 244 aucc_set_params, 245 aucc_round_blocksize, 246 aucc_commit_settings, 247 NULL, 248 NULL, 249 aucc_start_output, 250 aucc_start_input, 251 aucc_halt_output, 252 aucc_halt_input, 253 NULL, 254 aucc_getdev, 255 NULL, 256 aucc_set_port, 257 aucc_get_port, 258 aucc_query_devinfo, 259 NULL, 260 NULL, 261 NULL, 262 NULL, 263 aucc_get_props, 264 NULL, 265 NULL, 266 NULL, 267 }; 268 269 /* autoconfig routines */ 270 271 int 272 auccmatch(pdp, cfp, aux) 273 struct device *pdp; 274 struct cfdata *cfp; 275 void *aux; 276 { 277 static int aucc_matched = 0; 278 279 if (!matchname((char *)aux, "aucc") || 280 #ifdef DRACO 281 is_draco() || 282 #endif 283 aucc_matched) 284 return 0; 285 286 aucc_matched = 1; 287 return 1; 288 } 289 290 /* 291 * Audio chip found. 292 */ 293 void 294 auccattach(parent, self, args) 295 struct device *parent, *self; 296 void *args; 297 { 298 register struct aucc_softc *sc = (struct aucc_softc *)self; 299 register int i; 300 301 printf("\n"); 302 303 if((i=init_aucc(sc))) { 304 printf("audio: no chipmem\n"); 305 return; 306 } 307 308 audio_attach_mi(&sa_hw_if, sc, &sc->sc_dev); 309 } 310 311 312 static int 313 init_aucc(sc) 314 struct aucc_softc *sc; 315 { 316 register int i, err=0; 317 318 /* init values per channel */ 319 for (i=0;i<4;i++) { 320 sc->sc_channel[i].nd_freq=8000; 321 sc->sc_channel[i].nd_per=freqtoper(8000); 322 sc->sc_channel[i].nd_busy=0; 323 sc->sc_channel[i].nd_dma=alloc_chipmem(AUDIO_BUF_SIZE*2); 324 if (sc->sc_channel[i].nd_dma==NULL) 325 err=1; 326 sc->sc_channel[i].nd_dmalength=0; 327 sc->sc_channel[i].nd_volume=64; 328 sc->sc_channel[i].nd_intr=NULL; 329 sc->sc_channel[i].nd_intrdata=NULL; 330 sc->sc_channel[i].nd_doublebuf=0; 331 DPRINTF(("dma buffer for channel %d is %p\n", i, 332 sc->sc_channel[i].nd_dma)); 333 } 334 335 if (err) { 336 for(i=0;i<4;i++) 337 if (sc->sc_channel[i].nd_dma) 338 free_chipmem(sc->sc_channel[i].nd_dma); 339 } 340 341 sc->sc_channels=1; 342 sc->sc_channelmask=0xf; 343 sc->sc_precision=8; 344 sc->sc_14bit = 0; 345 sc->sc_encoding=AUDIO_ENCODING_ULAW; 346 sc->sc_decodefunc = aucc_decode_ulaw_1ch; 347 348 /* clear interrupts and dma: */ 349 custom.intena = AUCC_ALLINTF; 350 custom.dmacon = AUCC_ALLDMAF; 351 352 return err; 353 } 354 355 int 356 aucc_open(addr, flags) 357 void *addr; 358 int flags; 359 { 360 struct aucc_softc *sc = addr; 361 int i; 362 363 DPRINTF(("sa_open: unit %p\n",sc)); 364 365 if (sc->sc_open) 366 return (EBUSY); 367 sc->sc_open = 1; 368 for (i=0;i<AUCC_MAXINT;i++) { 369 sc->sc_channel[i].nd_intr=NULL; 370 sc->sc_channel[i].nd_intrdata=NULL; 371 } 372 aucc=sc; 373 sc->sc_channelmask=0xf; 374 375 DPRINTF(("saopen: ok -> sc=0x%p\n",sc)); 376 377 return (0); 378 } 379 380 void 381 aucc_close(addr) 382 void *addr; 383 { 384 register struct aucc_softc *sc = addr; 385 386 DPRINTF(("sa_close: sc=0x%p\n", sc)); 387 /* 388 * halt i/o, clear open flag, and done. 389 */ 390 aucc_halt_output(sc); 391 sc->sc_open = 0; 392 393 DPRINTF(("sa_close: closed.\n")); 394 } 395 396 int 397 aucc_set_out_sr(addr, sr) 398 void *addr; 399 u_long sr; 400 { 401 struct aucc_softc *sc=addr; 402 u_long per; 403 register int i; 404 405 per=freqtoper(sr); 406 if (per>0xffff) 407 return EINVAL; 408 sr=pertofreq(per); 409 410 for (i=0;i<4;i++) { 411 sc->sc_channel[i].nd_freq=sr; 412 sc->sc_channel[i].nd_per=per; 413 } 414 415 return(0); 416 } 417 418 int 419 aucc_query_encoding(addr, fp) 420 void *addr; 421 struct audio_encoding *fp; 422 { 423 switch (fp->index) { 424 case 0: 425 strcpy(fp->name, AudioEslinear); 426 fp->encoding = AUDIO_ENCODING_SLINEAR; 427 fp->precision = 8; 428 fp->flags = 0; 429 break; 430 case 1: 431 strcpy(fp->name, AudioEmulaw); 432 fp->encoding = AUDIO_ENCODING_ULAW; 433 fp->precision = 8; 434 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 435 break; 436 437 case 2: 438 strcpy(fp->name, AudioEulinear); 439 fp->encoding = AUDIO_ENCODING_ULINEAR; 440 fp->precision = 8; 441 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 442 break; 443 444 case 3: 445 strcpy(fp->name, AudioEslinear); 446 fp->encoding = AUDIO_ENCODING_SLINEAR; 447 fp->precision = 16; 448 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 449 break; 450 451 case 4: 452 strcpy(fp->name, AudioEslinear_be); 453 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 454 fp->precision = 16; 455 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 456 break; 457 458 case 5: 459 strcpy(fp->name, AudioEslinear_le); 460 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 461 fp->precision = 16; 462 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 463 break; 464 465 default: 466 return(EINVAL); 467 /*NOTREACHED*/ 468 } 469 return(0); 470 } 471 472 int 473 aucc_set_params(addr, setmode, usemode, p, r) 474 void *addr; 475 int setmode, usemode; 476 struct audio_params *p, *r; 477 { 478 struct aucc_softc *sc = addr; 479 480 /* if (setmode & AUMODE_RECORD) 481 return 0 ENXIO*/; 482 483 #ifdef AUCCDEBUG 484 printf("aucc_set_params(setmode 0x%x, usemode 0x%x, " 485 "enc %d, bits %d, chn %d, sr %ld)\n", setmode, usemode, 486 p->encoding, p->precision, p->channels, p->sample_rate); 487 #endif 488 489 switch (p->precision) { 490 case 8: 491 switch (p->encoding) { 492 case AUDIO_ENCODING_ULAW: 493 switch (p->channels) { 494 case 1: 495 sc->sc_decodefunc = aucc_decode_ulaw_1ch; 496 break; 497 case 2: 498 sc->sc_decodefunc = aucc_decode_ulaw_2ch; 499 break; 500 case 3: 501 sc->sc_decodefunc = aucc_decode_ulaw_3ch; 502 break; 503 case 4: 504 sc->sc_decodefunc = aucc_decode_ulaw_4ch; 505 break; 506 default: 507 return EINVAL; 508 } 509 break; 510 511 case AUDIO_ENCODING_SLINEAR: 512 case AUDIO_ENCODING_SLINEAR_BE: 513 case AUDIO_ENCODING_SLINEAR_LE: 514 switch (p->channels) { 515 case 1: 516 sc->sc_decodefunc = aucc_decode_slinear8_1ch; 517 break; 518 case 2: 519 sc->sc_decodefunc = aucc_decode_slinear8_2ch; 520 break; 521 case 3: 522 sc->sc_decodefunc = aucc_decode_slinear8_3ch; 523 break; 524 case 4: 525 sc->sc_decodefunc = aucc_decode_slinear8_4ch; 526 break; 527 default: 528 return EINVAL; 529 } 530 break; 531 532 case AUDIO_ENCODING_ULINEAR: 533 case AUDIO_ENCODING_ULINEAR_BE: 534 case AUDIO_ENCODING_ULINEAR_LE: 535 switch (p->channels) { 536 case 1: 537 sc->sc_decodefunc = aucc_decode_ulinear8_1ch; 538 break; 539 case 2: 540 sc->sc_decodefunc = aucc_decode_ulinear8_2ch; 541 break; 542 case 3: 543 sc->sc_decodefunc = aucc_decode_ulinear8_3ch; 544 break; 545 case 4: 546 sc->sc_decodefunc = aucc_decode_ulinear8_4ch; 547 break; 548 default: 549 return EINVAL; 550 } 551 break; 552 553 default: 554 return EINVAL; 555 } 556 break; 557 558 case 16: 559 switch (p->encoding) { 560 #if BYTE_ORDER == BIG_ENDIAN 561 case AUDIO_ENCODING_SLINEAR: 562 #endif 563 case AUDIO_ENCODING_SLINEAR_BE: 564 switch (p->channels) { 565 case 1: 566 sc->sc_decodefunc = aucc_decode_slinear16_1ch; 567 break; 568 569 case 2: 570 sc->sc_decodefunc = aucc_decode_slinear16_2ch; 571 break; 572 case 3: 573 sc->sc_decodefunc = aucc_decode_slinear16_3ch; 574 break; 575 case 4: 576 sc->sc_decodefunc = aucc_decode_slinear16_4ch; 577 break; 578 default: 579 return EINVAL; 580 } 581 break; 582 583 #if BYTE_ORDER == LITTLE_ENDIAN 584 case AUDIO_ENCODING_SLINEAR: 585 #endif 586 case AUDIO_ENCODING_SLINEAR_LE: 587 switch (p->channels) { 588 case 1: 589 sc->sc_decodefunc = aucc_decode_slinear16sw_1ch; 590 break; 591 case 2: 592 sc->sc_decodefunc = aucc_decode_slinear16sw_2ch; 593 break; 594 case 3: 595 sc->sc_decodefunc = aucc_decode_slinear16sw_3ch; 596 break; 597 case 4: 598 sc->sc_decodefunc = aucc_decode_slinear16sw_4ch; 599 break; 600 default: 601 return EINVAL; 602 } 603 break; 604 605 default: 606 return EINVAL; 607 } 608 break; 609 610 default: 611 return EINVAL; 612 } 613 614 sc->sc_encoding = p->encoding; 615 sc->sc_precision = p->precision; 616 sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2)); 617 sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels; 618 619 return aucc_set_out_sr(addr, p->sample_rate); 620 } 621 622 int 623 aucc_round_blocksize(addr, blk) 624 void *addr; 625 int blk; 626 { 627 /* round up to even size */ 628 return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk; 629 } 630 631 int 632 aucc_commit_settings(addr) 633 void *addr; 634 { 635 register struct aucc_softc *sc = addr; 636 register int i; 637 638 DPRINTF(("sa_commit.\n")); 639 640 for (i=0;i<4;i++) { 641 custom.aud[i].vol=sc->sc_channel[i].nd_volume; 642 custom.aud[i].per=sc->sc_channel[i].nd_per; 643 } 644 645 DPRINTF(("commit done\n")); 646 647 return(0); 648 } 649 650 static int masks[4] = {1,3,7,15}; /* masks for n first channels */ 651 static int masks2[4] = {1,2,4,8}; 652 653 int 654 aucc_start_output(addr, p, cc, intr, arg) 655 void *addr; 656 void *p; 657 int cc; 658 void (*intr) __P((void *)); 659 void *arg; 660 { 661 struct aucc_softc *sc; 662 int mask; 663 int i, j, k, len; 664 u_char *dmap[4]; 665 666 667 sc = addr; 668 mask = sc->sc_channelmask; 669 670 dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL; 671 672 DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg)); 673 674 if (sc->sc_channels > 1) 675 mask &= masks[sc->sc_channels - 1]; 676 /* we use first sc_channels channels */ 677 if (mask == 0) /* active and used channels are disjoint */ 678 return EINVAL; 679 680 for (i=0;i<4;i++) { 681 /* channels available ? */ 682 if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy)) 683 return EBUSY; /* channel is busy */ 684 if (channel[i].isaudio == -1) 685 return EBUSY; /* system uses them */ 686 } 687 688 /* enable interrupt on 1st channel */ 689 for (i = j = 0; i < AUCC_MAXINT; i++) { 690 if (masks2[i] & mask) { 691 DPRINTF(("first channel is %d\n",i)); 692 j=i; 693 sc->sc_channel[i].nd_intr=intr; 694 sc->sc_channel[i].nd_intrdata=arg; 695 break; 696 } 697 } 698 699 DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1], 700 dmap[2], dmap[3], mask)); 701 702 /* disable ints, dma for channels, until all parameters set */ 703 /* XXX dont disable DMA! custom.dmacon=mask;*/ 704 custom.intreq = mask << INTB_AUD0; 705 custom.intena = mask << INTB_AUD0; 706 707 /* copy data to dma buffer */ 708 709 if (sc->sc_channels == 1) { 710 dmap[0] = 711 dmap[1] = 712 dmap[2] = 713 dmap[3] = (u_char *)sc->sc_channel[j].nd_dma; 714 } 715 else { 716 for (k=0; k<4; k++) { 717 if (masks2[k+j] & mask) 718 dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma; 719 } 720 } 721 722 sc->sc_channel[j].nd_doublebuf ^= 1; 723 if (sc->sc_channel[j].nd_doublebuf) { 724 dmap[0] += AUDIO_BUF_SIZE; 725 dmap[1] += AUDIO_BUF_SIZE; 726 dmap[2] += AUDIO_BUF_SIZE; 727 dmap[3] += AUDIO_BUF_SIZE; 728 } 729 730 /* compute output length in bytes per channel. 731 * divide by two only for 16bit->8bit conversion. 732 */ 733 len = cc / sc->sc_channels; 734 if (!sc->sc_14bit && (sc->sc_precision == 16)) 735 len /= 2; 736 737 /* call audio decoding routine */ 738 sc->sc_decodefunc (dmap, (u_char *)p, len); 739 740 /* dma buffers: we use same buffer 4 all channels 741 * write dma location and length 742 */ 743 for (i = k = 0; i < 4; i++) { 744 if (masks2[i] & mask) { 745 DPRINTF(("turning channel %d on\n",i)); 746 /* sc->sc_channel[i].nd_busy=1; */ 747 channel[i].isaudio = 1; 748 channel[i].play_count = 1; 749 channel[i].handler = NULL; 750 custom.aud[i].per = sc->sc_channel[i].nd_per; 751 if (sc->sc_14bit && (i > 1)) 752 custom.aud[i].vol = 1; 753 else 754 custom.aud[i].vol = sc->sc_channel[i].nd_volume; 755 custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]); 756 custom.aud[i].len = len / 2; 757 sc->sc_channel[i].nd_mask = mask; 758 DPRINTF(("per is %d, vol is %d, len is %d\n",\ 759 sc->sc_channel[i].nd_per, 760 sc->sc_channel[i].nd_volume, len)); 761 } 762 } 763 764 channel[j].handler=aucc_inthdl; 765 766 /* enable ints */ 767 custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0); 768 769 DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0))); 770 771 /* enable dma */ 772 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask; 773 774 DPRINTF(("enabled dma, mask=0x%x\n",mask)); 775 776 return(0); 777 } 778 779 /* ARGSUSED */ 780 int 781 aucc_start_input(addr, p, cc, intr, arg) 782 void *addr; 783 void *p; 784 int cc; 785 void (*intr) __P((void *)); 786 void *arg; 787 { 788 789 return ENXIO; /* no input */ 790 } 791 792 int 793 aucc_halt_output(addr) 794 void *addr; 795 { 796 register struct aucc_softc *sc = addr; 797 register int i; 798 799 /* XXX only halt, if input is also halted ?? */ 800 /* stop dma, etc */ 801 custom.intena = AUCC_ALLINTF; 802 custom.dmacon = AUCC_ALLDMAF; 803 /* mark every busy unit idle */ 804 for (i=0;i<4;i++) { 805 sc->sc_channel[i].nd_busy=sc->sc_channel[i].nd_mask=0; 806 channel[i].isaudio=0; 807 channel[i].play_count=0; 808 } 809 810 return(0); 811 } 812 813 int 814 aucc_halt_input(addr) 815 void *addr; 816 { 817 /* no input */ 818 819 return ENXIO; 820 } 821 822 int 823 aucc_getdev(addr, retp) 824 void *addr; 825 struct audio_device *retp; 826 { 827 *retp = aucc_device; 828 return 0; 829 } 830 831 int 832 aucc_set_port(addr, cp) 833 void *addr; 834 mixer_ctrl_t *cp; 835 { 836 register struct aucc_softc *sc = addr; 837 register int i,j; 838 839 DPRINTF(("aucc_set_port: port=%d", cp->dev)); 840 841 switch (cp->type) { 842 case AUDIO_MIXER_SET: 843 if (cp->dev!=AUCC_CHANNELS) 844 return EINVAL; 845 i=cp->un.mask; 846 if ((i<1) || (i>15)) 847 return EINVAL; 848 849 sc->sc_channelmask=i; 850 break; 851 852 case AUDIO_MIXER_VALUE: 853 i=cp->un.value.num_channels; 854 if ((i<1) || (i>4)) 855 return EINVAL; 856 857 #ifdef __XXXwhatsthat 858 if (cp->dev!=AUCC_VOLUME) 859 return EINVAL; 860 #endif 861 862 /* set volume for channel 0..i-1 */ 863 864 /* evil workaround for xanim bug, IMO */ 865 if ((sc->sc_channels == 1) && (i == 2)) { 866 sc->sc_channel[0].nd_volume = 867 sc->sc_channel[3].nd_volume = 868 cp->un.value.level[0]>>2; 869 sc->sc_channel[1].nd_volume = 870 sc->sc_channel[2].nd_volume = 871 cp->un.value.level[1]>>2; 872 } else if (i>1) { 873 for (j=0;j<i;j++) 874 sc->sc_channel[j].nd_volume = 875 cp->un.value.level[j]>>2; 876 } else if (sc->sc_channels > 1) 877 for (j=0; j<sc->sc_channels; j++) 878 sc->sc_channel[j].nd_volume = 879 cp->un.value.level[0]>>2; 880 else 881 for (j=0; j<4; j++) 882 sc->sc_channel[j].nd_volume = 883 cp->un.value.level[0]>>2; 884 break; 885 886 default: 887 return EINVAL; 888 break; 889 } 890 return 0; 891 } 892 893 894 int 895 aucc_get_port(addr, cp) 896 void *addr; 897 mixer_ctrl_t *cp; 898 { 899 register struct aucc_softc *sc = addr; 900 register int i,j; 901 902 DPRINTF(("aucc_get_port: port=%d", cp->dev)); 903 904 switch (cp->type) { 905 case AUDIO_MIXER_SET: 906 if (cp->dev!=AUCC_CHANNELS) 907 return EINVAL; 908 cp->un.mask=sc->sc_channelmask; 909 break; 910 911 case AUDIO_MIXER_VALUE: 912 i = cp->un.value.num_channels; 913 if ((i<1)||(i>4)) 914 return EINVAL; 915 916 for (j=0;j<i;j++) 917 cp->un.value.level[j] = 918 (sc->sc_channel[j].nd_volume<<2) + 919 (sc->sc_channel[j].nd_volume>>4); 920 break; 921 922 default: 923 return EINVAL; 924 } 925 return 0; 926 } 927 928 929 int 930 aucc_get_props(addr) 931 void *addr; 932 { 933 return 0; 934 } 935 936 int 937 aucc_query_devinfo(addr, dip) 938 void *addr; 939 register mixer_devinfo_t *dip; 940 { 941 register int i; 942 943 switch(dip->index) { 944 case AUCC_CHANNELS: 945 dip->type = AUDIO_MIXER_SET; 946 dip->mixer_class = AUCC_OUTPUT_CLASS; 947 dip->prev = dip->next = AUDIO_MIXER_LAST; 948 strcpy(dip->label.name, AudioNspeaker); 949 for (i=0;i<16;i++) { 950 sprintf(dip->un.s.member[i].label.name, 951 "channelmask%d", i); 952 dip->un.s.member[i].mask = i; 953 } 954 dip->un.s.num_mem = 16; 955 break; 956 957 case AUCC_VOLUME: 958 dip->type = AUDIO_MIXER_VALUE; 959 dip->mixer_class = AUCC_OUTPUT_CLASS; 960 dip->prev = dip->next = AUDIO_MIXER_LAST; 961 strcpy(dip->label.name, AudioNmaster); 962 dip->un.v.num_channels = 4; 963 strcpy(dip->un.v.units.name, AudioNvolume); 964 break; 965 966 case AUCC_OUTPUT_CLASS: 967 dip->type = AUDIO_MIXER_CLASS; 968 dip->mixer_class = AUCC_OUTPUT_CLASS; 969 dip->next = dip->prev = AUDIO_MIXER_LAST; 970 strcpy(dip->label.name, AudioCoutputs); 971 break; 972 973 default: 974 return ENXIO; 975 } 976 977 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 978 979 return(0); 980 } 981 982 983 /* audio int handler */ 984 void 985 aucc_inthdl(int ch) 986 { 987 register int i; 988 register int mask=aucc->sc_channel[ch].nd_mask; 989 990 /* for all channels in this maskgroup: 991 disable dma, int 992 mark idle */ 993 DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask)); 994 995 custom.intreq=mask<<INTB_AUD0; /* clear request */ 996 /* 997 * XXX: maybe we can leave ints and/or DMA on, 998 * if another sample has to be played? 999 */ 1000 custom.intena=mask<<INTB_AUD0; 1001 /* 1002 * XXX custom.dmacon=mask; NO!!! 1003 */ 1004 for (i=0; i<4; i++) { 1005 if (masks2[i]&&mask) { 1006 DPRINTF(("marking channel %d idle\n",i)); 1007 aucc->sc_channel[i].nd_busy=0; 1008 aucc->sc_channel[i].nd_mask=0; 1009 channel[i].isaudio=channel[i].play_count=0; 1010 } 1011 } 1012 1013 /* call handler */ 1014 if (aucc->sc_channel[ch].nd_intr) { 1015 DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr)); 1016 (*(aucc->sc_channel[ch].nd_intr)) 1017 (aucc->sc_channel[ch].nd_intrdata); 1018 } 1019 else 1020 DPRINTF(("zero int handler\n")); 1021 DPRINTF(("ints done\n")); 1022 } 1023 1024 1025 1026 1027 /* transform frequency to period, adjust bounds */ 1028 static u_int 1029 freqtoper(u_int freq) { 1030 u_int per=eclockfreq*5/freq; 1031 1032 if (per<124) 1033 per=124; /* must have at least 124 ticks between samples */ 1034 1035 return per; 1036 } 1037 1038 /* transform period to frequency */ 1039 static u_int 1040 pertofreq(u_int per) { 1041 u_int freq=eclockfreq*5/per; 1042 1043 return freq; 1044 } 1045 1046 static void aucc_decode_slinear8_1ch (u_char **dmap, u_char *p, int i) { 1047 memcpy (dmap[0], p, i); 1048 } 1049 1050 static void aucc_decode_slinear8_2ch (u_char **dmap, u_char *p, int i) { 1051 u_char *ch0 = dmap[0]; 1052 u_char *ch1 = dmap[1]; 1053 1054 while (i--) { 1055 *ch0++ = *p++; 1056 *ch1++ = *p++; 1057 } 1058 } 1059 1060 static void aucc_decode_slinear8_3ch (u_char **dmap, u_char *p, int i) { 1061 u_char *ch0 = dmap[0]; 1062 u_char *ch1 = dmap[1]; 1063 u_char *ch2 = dmap[2]; 1064 1065 while (i--) { 1066 *ch0++ = *p++; 1067 *ch1++ = *p++; 1068 *ch2++ = *p++; 1069 } 1070 } 1071 1072 static void aucc_decode_slinear8_4ch (u_char **dmap, u_char *p, int i) { 1073 u_char *ch0 = dmap[0]; 1074 u_char *ch1 = dmap[1]; 1075 u_char *ch2 = dmap[2]; 1076 u_char *ch3 = dmap[3]; 1077 1078 while (i--) { 1079 *ch0++ = *p++; 1080 *ch1++ = *p++; 1081 *ch2++ = *p++; 1082 *ch3++ = *p++; 1083 } 1084 } 1085 1086 static void 1087 aucc_decode_ulinear8_1ch (dmap, p, i) 1088 u_char **dmap; 1089 u_char *p; 1090 int i; 1091 { 1092 u_char *ch0 = dmap[0]; 1093 1094 while (i--) 1095 *ch0++ = *p++ - 128; 1096 } 1097 1098 static void 1099 aucc_decode_ulinear8_2ch(dmap, p, i) 1100 u_char **dmap; 1101 u_char *p; 1102 int i; 1103 { 1104 u_char *ch0 = dmap[0]; 1105 u_char *ch1 = dmap[1]; 1106 1107 while (i--) { 1108 *ch0++ = *p++ - 128; 1109 *ch1++ = *p++ - 128; 1110 } 1111 } 1112 1113 static void 1114 aucc_decode_ulinear8_3ch(dmap, p, i) 1115 u_char **dmap; 1116 u_char *p; 1117 int i; 1118 { 1119 u_char *ch0 = dmap[0]; 1120 u_char *ch1 = dmap[1]; 1121 u_char *ch2 = dmap[2]; 1122 1123 while (i--) { 1124 *ch0++ = *p++ - 128; 1125 *ch1++ = *p++ - 128; 1126 *ch2++ = *p++ - 128; 1127 } 1128 } 1129 1130 static void 1131 aucc_decode_ulinear8_4ch(dmap, p, i) 1132 u_char **dmap; 1133 u_char *p; 1134 int i; 1135 { 1136 u_char *ch0 = dmap[0]; 1137 u_char *ch1 = dmap[1]; 1138 u_char *ch2 = dmap[2]; 1139 u_char *ch3 = dmap[3]; 1140 1141 while (i--) { 1142 *ch0++ = *p++ - 128; 1143 *ch1++ = *p++ - 128; 1144 *ch2++ = *p++ - 128; 1145 *ch3++ = *p++ - 128; 1146 } 1147 } 1148 1149 1150 static void 1151 aucc_decode_ulaw_1ch (dmap, p, i) 1152 u_char **dmap; 1153 u_char *p; 1154 int i; 1155 { 1156 u_char *ch0 = dmap[0]; 1157 1158 while (i--) 1159 *ch0++ = ulaw_to_lin[*p++]; 1160 } 1161 1162 static void 1163 aucc_decode_ulaw_2ch(dmap, p, i) 1164 u_char **dmap; 1165 u_char *p; 1166 int i; 1167 { 1168 u_char *ch0 = dmap[0]; 1169 u_char *ch1 = dmap[1]; 1170 1171 while (i--) { 1172 *ch0++ = ulaw_to_lin[*p++]; 1173 *ch1++ = ulaw_to_lin[*p++]; 1174 } 1175 } 1176 1177 static void 1178 aucc_decode_ulaw_3ch(dmap, p, i) 1179 u_char **dmap; 1180 u_char *p; 1181 int i; 1182 { 1183 u_char *ch0 = dmap[0]; 1184 u_char *ch1 = dmap[1]; 1185 u_char *ch2 = dmap[2]; 1186 1187 while (i--) { 1188 *ch0++ = ulaw_to_lin[*p++]; 1189 *ch1++ = ulaw_to_lin[*p++]; 1190 *ch2++ = ulaw_to_lin[*p++]; 1191 } 1192 } 1193 1194 static void 1195 aucc_decode_ulaw_4ch(dmap, p, i) 1196 u_char **dmap; 1197 u_char *p; 1198 int i; 1199 { 1200 u_char *ch0 = dmap[0]; 1201 u_char *ch1 = dmap[1]; 1202 u_char *ch2 = dmap[2]; 1203 u_char *ch3 = dmap[3]; 1204 1205 while (i--) { 1206 *ch0++ = ulaw_to_lin[*p++]; 1207 *ch1++ = ulaw_to_lin[*p++]; 1208 *ch2++ = ulaw_to_lin[*p++]; 1209 *ch3++ = ulaw_to_lin[*p++]; 1210 } 1211 } 1212 1213 1214 /* 14bit output */ 1215 static void 1216 aucc_decode_slinear16_1ch(dmap, p, i) 1217 u_char **dmap; 1218 u_char *p; 1219 int i; 1220 { 1221 u_char *ch0 = dmap[0]; 1222 u_char *ch3 = dmap[1]; /* XXX should be 3 */ 1223 1224 while (i--) { 1225 *ch0++ = *p++; 1226 *ch3++ = *p++ >> 2; 1227 } 1228 } 1229 1230 /* 14bit stereo output */ 1231 static void 1232 aucc_decode_slinear16_2ch(dmap, p, i) 1233 u_char **dmap; 1234 u_char *p; 1235 int i; 1236 { 1237 u_char *ch0 = dmap[0]; 1238 u_char *ch1 = dmap[1]; 1239 u_char *ch2 = dmap[2]; 1240 u_char *ch3 = dmap[3]; 1241 1242 while (i--) { 1243 *ch0++ = *p++; 1244 *ch3++ = *p++ >> 2; 1245 *ch1++ = *p++; 1246 *ch2++ = *p++ >> 2; 1247 } 1248 } 1249 1250 static void 1251 aucc_decode_slinear16_3ch(dmap, p, i) 1252 u_char **dmap; 1253 u_char *p; 1254 int i; 1255 { 1256 u_char *ch0 = dmap[0]; 1257 u_char *ch1 = dmap[1]; 1258 u_char *ch2 = dmap[2]; 1259 1260 while (i--) { 1261 *ch0++ = *p++; p++; 1262 *ch1++ = *p++; p++; 1263 *ch2++ = *p++; p++; 1264 } 1265 } 1266 1267 static void 1268 aucc_decode_slinear16_4ch (dmap, p, i) 1269 u_char **dmap; 1270 u_char *p; 1271 int i; 1272 { 1273 u_char *ch0 = dmap[0]; 1274 u_char *ch1 = dmap[1]; 1275 u_char *ch2 = dmap[2]; 1276 u_char *ch3 = dmap[3]; 1277 1278 while (i--) { 1279 *ch0++ = *p++; p++; 1280 *ch1++ = *p++; p++; 1281 *ch2++ = *p++; p++; 1282 *ch3++ = *p++; p++; 1283 } 1284 } 1285 1286 /* 14bit output, swap bytes */ 1287 static void 1288 aucc_decode_slinear16sw_1ch(dmap, p, i) 1289 u_char **dmap; 1290 u_char *p; 1291 int i; 1292 { 1293 u_char *ch0 = dmap[0]; 1294 u_char *ch3 = dmap[1]; /* XXX should be 3 */ 1295 1296 while (i--) { 1297 *ch3++ = *p++ >> 2; 1298 *ch0++ = *p++; 1299 } 1300 } 1301 1302 static void 1303 aucc_decode_slinear16sw_2ch(dmap, p, i) 1304 u_char **dmap; 1305 u_char *p; 1306 int i; 1307 { 1308 u_char *ch0 = dmap[0]; 1309 u_char *ch1 = dmap[1]; 1310 u_char *ch2 = dmap[2]; 1311 u_char *ch3 = dmap[3]; 1312 1313 while (i--) { 1314 *ch3++ = *p++ >> 2; 1315 *ch0++ = *p++; 1316 *ch2++ = *p++ >> 2; 1317 *ch1++ = *p++; 1318 } 1319 } 1320 1321 static void 1322 aucc_decode_slinear16sw_3ch(dmap, p, i) 1323 u_char **dmap; 1324 u_char *p; 1325 int i; 1326 { 1327 u_char *ch0 = dmap[0]; 1328 u_char *ch1 = dmap[1]; 1329 u_char *ch2 = dmap[2]; 1330 1331 while (i--) { 1332 p++; *ch0++ = *p++; 1333 p++; *ch1++ = *p++; 1334 p++; *ch2++ = *p++; 1335 } 1336 } 1337 1338 static void 1339 aucc_decode_slinear16sw_4ch(dmap, p, i) 1340 u_char **dmap; 1341 u_char *p; 1342 int i; 1343 { 1344 u_char *ch0 = dmap[0]; 1345 u_char *ch1 = dmap[1]; 1346 u_char *ch2 = dmap[2]; 1347 u_char *ch3 = dmap[3]; 1348 1349 while (i--) { 1350 p++; *ch0++ = *p++; 1351 p++; *ch1++ = *p++; 1352 p++; *ch2++ = *p++; 1353 p++; *ch3++ = *p++; 1354 } 1355 } 1356 1357 1358 #endif /* NAUCC > 0 */ 1359