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