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