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