1 /* $NetBSD: aucc.c,v 1.43 2014/03/22 01:52:44 christos 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.43 2014/03/22 01:52:44 christos 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 int sc_open; /* single use device */ 107 aucc_data_t sc_channel[4]; /* per channel freq, ... */ 108 u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/ 109 int sc_channels; /* # of channels used */ 110 int sc_precision; /* 8 or 16 bits */ 111 int sc_14bit; /* 14bit output enabled */ 112 113 int sc_intrcnt; /* interrupt count */ 114 int sc_channelmask; /* which channels are used ? */ 115 void (*sc_decodefunc)(u_char **, u_char *, int); 116 /* pointer to format conversion routine */ 117 118 kmutex_t sc_lock; 119 kmutex_t sc_intr_lock; 120 }; 121 122 /* interrupt interfaces */ 123 void aucc_inthdl(int); 124 125 /* forward declarations */ 126 static int init_aucc(struct aucc_softc *); 127 static u_int freqtoper(u_int); 128 static u_int pertofreq(u_int); 129 130 /* autoconfiguration driver */ 131 void auccattach(device_t, device_t, void *); 132 int auccmatch(device_t, cfdata_t, void *); 133 134 CFATTACH_DECL_NEW(aucc, sizeof(struct aucc_softc), 135 auccmatch, auccattach, NULL, NULL); 136 137 struct audio_device aucc_device = { 138 "Amiga-audio", 139 "2.0", 140 "aucc" 141 }; 142 143 144 struct aucc_softc *aucc = NULL; 145 146 147 unsigned char mulaw_to_lin[] = { 148 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e, 149 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe, 150 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, 151 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, 152 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 153 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 154 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4, 155 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8, 156 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 157 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 158 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 159 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 160 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 161 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 162 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 163 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 164 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61, 165 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41, 166 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30, 167 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 168 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 169 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 170 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 171 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, 172 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 173 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 174 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 175 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 176 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 180 }; 181 182 /* 183 * Define our interface to the higher level audio driver. 184 */ 185 int aucc_open(void *, int); 186 void aucc_close(void *); 187 int aucc_set_out_sr(void *, u_int); 188 int aucc_query_encoding(void *, struct audio_encoding *); 189 int aucc_round_blocksize(void *, int, int, const audio_params_t *); 190 int aucc_commit_settings(void *); 191 int aucc_start_output(void *, void *, int, void (*)(void *), void *); 192 int aucc_start_input(void *, void *, int, void (*)(void *), void *); 193 int aucc_halt_output(void *); 194 int aucc_halt_input(void *); 195 int aucc_getdev(void *, struct audio_device *); 196 int aucc_set_port(void *, mixer_ctrl_t *); 197 int aucc_get_port(void *, mixer_ctrl_t *); 198 int aucc_query_devinfo(void *, mixer_devinfo_t *); 199 void aucc_encode(int, int, int, int, u_char *, u_short **); 200 int aucc_set_params(void *, int, int, audio_params_t *, audio_params_t *, 201 stream_filter_list_t *, stream_filter_list_t *); 202 int aucc_get_props(void *); 203 void aucc_get_locks(void *, kmutex_t **, kmutex_t **); 204 205 206 static void aucc_decode_slinear8_1ch(u_char **, u_char *, int); 207 static void aucc_decode_slinear8_2ch(u_char **, u_char *, int); 208 static void aucc_decode_slinear8_3ch(u_char **, u_char *, int); 209 static void aucc_decode_slinear8_4ch(u_char **, u_char *, int); 210 211 static void aucc_decode_ulinear8_1ch(u_char **, u_char *, int); 212 static void aucc_decode_ulinear8_2ch(u_char **, u_char *, int); 213 static void aucc_decode_ulinear8_3ch(u_char **, u_char *, int); 214 static void aucc_decode_ulinear8_4ch(u_char **, u_char *, int); 215 216 static void aucc_decode_mulaw_1ch(u_char **, u_char *, int); 217 static void aucc_decode_mulaw_2ch(u_char **, u_char *, int); 218 static void aucc_decode_mulaw_3ch(u_char **, u_char *, int); 219 static void aucc_decode_mulaw_4ch(u_char **, u_char *, int); 220 221 static void aucc_decode_slinear16_1ch(u_char **, u_char *, int); 222 static void aucc_decode_slinear16_2ch(u_char **, u_char *, int); 223 static void aucc_decode_slinear16_3ch(u_char **, u_char *, int); 224 static void aucc_decode_slinear16_4ch(u_char **, u_char *, int); 225 226 static void aucc_decode_slinear16sw_1ch(u_char **, u_char *, int); 227 static void aucc_decode_slinear16sw_2ch(u_char **, u_char *, int); 228 static void aucc_decode_slinear16sw_3ch(u_char **, u_char *, int); 229 static void aucc_decode_slinear16sw_4ch(u_char **, u_char *, int); 230 231 232 233 const struct audio_hw_if sa_hw_if = { 234 aucc_open, 235 aucc_close, 236 NULL, 237 aucc_query_encoding, 238 aucc_set_params, 239 aucc_round_blocksize, 240 aucc_commit_settings, 241 NULL, 242 NULL, 243 aucc_start_output, 244 aucc_start_input, 245 aucc_halt_output, 246 aucc_halt_input, 247 NULL, 248 aucc_getdev, 249 NULL, 250 aucc_set_port, 251 aucc_get_port, 252 aucc_query_devinfo, 253 NULL, 254 NULL, 255 NULL, 256 NULL, 257 aucc_get_props, 258 NULL, 259 NULL, 260 NULL, 261 aucc_get_locks, 262 }; 263 264 /* autoconfig routines */ 265 266 int 267 auccmatch(device_t parent, cfdata_t cf, void *aux) 268 { 269 static int aucc_matched = 0; 270 271 if (!matchname((char *)aux, "aucc") || 272 #ifdef DRACO 273 is_draco() || 274 #endif 275 aucc_matched) 276 return 0; 277 278 aucc_matched = 1; 279 return 1; 280 } 281 282 /* 283 * Audio chip found. 284 */ 285 void 286 auccattach(device_t parent, device_t self, void *args) 287 { 288 struct aucc_softc *sc; 289 int i; 290 291 sc = device_private(self); 292 printf("\n"); 293 294 if ((i=init_aucc(sc))) { 295 printf("audio: no chipmem\n"); 296 return; 297 } 298 299 audio_attach_mi(&sa_hw_if, sc, self); 300 } 301 302 303 static int 304 init_aucc(struct aucc_softc *sc) 305 { 306 int i, err; 307 308 err = 0; 309 /* init values per channel */ 310 for (i = 0; i < 4; i++) { 311 sc->sc_channel[i].nd_freq = 8000; 312 sc->sc_channel[i].nd_per = freqtoper(8000); 313 sc->sc_channel[i].nd_busy = 0; 314 sc->sc_channel[i].nd_dma = alloc_chipmem(AUDIO_BUF_SIZE*2); 315 if (sc->sc_channel[i].nd_dma == NULL) 316 err = 1; 317 sc->sc_channel[i].nd_dmalength = 0; 318 sc->sc_channel[i].nd_volume = 64; 319 sc->sc_channel[i].nd_intr = NULL; 320 sc->sc_channel[i].nd_intrdata = NULL; 321 sc->sc_channel[i].nd_doublebuf = 0; 322 DPRINTF(("DMA buffer for channel %d is %p\n", i, 323 sc->sc_channel[i].nd_dma)); 324 } 325 326 if (err) { 327 for (i = 0; i < 4; i++) 328 if (sc->sc_channel[i].nd_dma) 329 free_chipmem(sc->sc_channel[i].nd_dma); 330 } 331 332 sc->sc_channels = 1; 333 sc->sc_channelmask = 0xf; 334 sc->sc_precision = 8; 335 sc->sc_14bit = 0; 336 sc->sc_encoding = AUDIO_ENCODING_ULAW; 337 sc->sc_decodefunc = aucc_decode_mulaw_1ch; 338 339 /* clear interrupts and DMA: */ 340 custom.intena = AUCC_ALLINTF; 341 custom.dmacon = AUCC_ALLDMAF; 342 343 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 344 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); 345 346 return err; 347 } 348 349 int 350 aucc_open(void *addr, int flags) 351 { 352 struct aucc_softc *sc; 353 int i; 354 355 sc = addr; 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=%p\n",sc)); 369 370 return 0; 371 } 372 373 void 374 aucc_close(void *addr) 375 { 376 struct aucc_softc *sc; 377 378 sc = addr; 379 DPRINTF(("sa_close: sc=%p\n", sc)); 380 /* 381 * halt i/o, clear open flag, and done. 382 */ 383 aucc_halt_output(sc); 384 sc->sc_open = 0; 385 386 DPRINTF(("sa_close: closed.\n")); 387 } 388 389 int 390 aucc_set_out_sr(void *addr, u_int sr) 391 { 392 struct aucc_softc *sc; 393 u_long per; 394 int i; 395 396 sc = addr; 397 per = freqtoper(sr); 398 if (per > 0xffff) 399 return EINVAL; 400 sr = pertofreq(per); 401 402 for (i = 0; i < 4; i++) { 403 sc->sc_channel[i].nd_freq = sr; 404 sc->sc_channel[i].nd_per = per; 405 } 406 407 return 0; 408 } 409 410 int 411 aucc_query_encoding(void *addr, struct audio_encoding *fp) 412 { 413 414 switch (fp->index) { 415 case 0: 416 strcpy(fp->name, AudioEslinear); 417 fp->encoding = AUDIO_ENCODING_SLINEAR; 418 fp->precision = 8; 419 fp->flags = 0; 420 break; 421 case 1: 422 strcpy(fp->name, AudioEmulaw); 423 fp->encoding = AUDIO_ENCODING_ULAW; 424 fp->precision = 8; 425 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 426 break; 427 428 case 2: 429 strcpy(fp->name, AudioEulinear); 430 fp->encoding = AUDIO_ENCODING_ULINEAR; 431 fp->precision = 8; 432 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 433 break; 434 435 case 3: 436 strcpy(fp->name, AudioEslinear); 437 fp->encoding = AUDIO_ENCODING_SLINEAR; 438 fp->precision = 16; 439 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 440 break; 441 442 case 4: 443 strcpy(fp->name, AudioEslinear_be); 444 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 445 fp->precision = 16; 446 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 447 break; 448 449 case 5: 450 strcpy(fp->name, AudioEslinear_le); 451 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 452 fp->precision = 16; 453 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 454 break; 455 456 default: 457 return EINVAL; 458 /*NOTREACHED*/ 459 } 460 return 0; 461 } 462 463 int 464 aucc_set_params(void *addr, int setmode, int usemode, 465 audio_params_t *p, audio_params_t *r, 466 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 467 { 468 struct aucc_softc *sc; 469 470 sc = addr; 471 /* if (setmode & AUMODE_RECORD) 472 return 0 ENXIO*/; 473 474 #ifdef AUCCDEBUG 475 printf("aucc_set_params(setmode 0x%x, usemode 0x%x, " 476 "enc %u, bits %u, chn %u, sr %u)\n", setmode, usemode, 477 p->encoding, p->precision, p->channels, p->sample_rate); 478 #endif 479 480 switch (p->precision) { 481 case 8: 482 switch (p->encoding) { 483 case AUDIO_ENCODING_ULAW: 484 switch (p->channels) { 485 case 1: 486 sc->sc_decodefunc = aucc_decode_mulaw_1ch; 487 break; 488 case 2: 489 sc->sc_decodefunc = aucc_decode_mulaw_2ch; 490 break; 491 case 3: 492 sc->sc_decodefunc = aucc_decode_mulaw_3ch; 493 break; 494 case 4: 495 sc->sc_decodefunc = aucc_decode_mulaw_4ch; 496 break; 497 default: 498 return EINVAL; 499 } 500 break; 501 502 case AUDIO_ENCODING_SLINEAR: 503 case AUDIO_ENCODING_SLINEAR_BE: 504 case AUDIO_ENCODING_SLINEAR_LE: 505 switch (p->channels) { 506 case 1: 507 sc->sc_decodefunc = aucc_decode_slinear8_1ch; 508 break; 509 case 2: 510 sc->sc_decodefunc = aucc_decode_slinear8_2ch; 511 break; 512 case 3: 513 sc->sc_decodefunc = aucc_decode_slinear8_3ch; 514 break; 515 case 4: 516 sc->sc_decodefunc = aucc_decode_slinear8_4ch; 517 break; 518 default: 519 return EINVAL; 520 } 521 break; 522 523 case AUDIO_ENCODING_ULINEAR: 524 case AUDIO_ENCODING_ULINEAR_BE: 525 case AUDIO_ENCODING_ULINEAR_LE: 526 switch (p->channels) { 527 case 1: 528 sc->sc_decodefunc = aucc_decode_ulinear8_1ch; 529 break; 530 case 2: 531 sc->sc_decodefunc = aucc_decode_ulinear8_2ch; 532 break; 533 case 3: 534 sc->sc_decodefunc = aucc_decode_ulinear8_3ch; 535 break; 536 case 4: 537 sc->sc_decodefunc = aucc_decode_ulinear8_4ch; 538 break; 539 default: 540 return EINVAL; 541 } 542 break; 543 544 default: 545 return EINVAL; 546 } 547 break; 548 549 case 16: 550 switch (p->encoding) { 551 #if BYTE_ORDER == BIG_ENDIAN 552 case AUDIO_ENCODING_SLINEAR: 553 #endif 554 case AUDIO_ENCODING_SLINEAR_BE: 555 switch (p->channels) { 556 case 1: 557 sc->sc_decodefunc = aucc_decode_slinear16_1ch; 558 break; 559 560 case 2: 561 sc->sc_decodefunc = aucc_decode_slinear16_2ch; 562 break; 563 case 3: 564 sc->sc_decodefunc = aucc_decode_slinear16_3ch; 565 break; 566 case 4: 567 sc->sc_decodefunc = aucc_decode_slinear16_4ch; 568 break; 569 default: 570 return EINVAL; 571 } 572 break; 573 574 #if BYTE_ORDER == LITTLE_ENDIAN 575 case AUDIO_ENCODING_SLINEAR: 576 #endif 577 case AUDIO_ENCODING_SLINEAR_LE: 578 switch (p->channels) { 579 case 1: 580 sc->sc_decodefunc = aucc_decode_slinear16sw_1ch; 581 break; 582 case 2: 583 sc->sc_decodefunc = aucc_decode_slinear16sw_2ch; 584 break; 585 case 3: 586 sc->sc_decodefunc = aucc_decode_slinear16sw_3ch; 587 break; 588 case 4: 589 sc->sc_decodefunc = aucc_decode_slinear16sw_4ch; 590 break; 591 default: 592 return EINVAL; 593 } 594 break; 595 596 default: 597 return EINVAL; 598 } 599 break; 600 601 default: 602 return EINVAL; 603 } 604 605 sc->sc_encoding = p->encoding; 606 sc->sc_precision = p->precision; 607 sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2)); 608 sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels; 609 610 return aucc_set_out_sr(addr, p->sample_rate); 611 } 612 613 int 614 aucc_round_blocksize(void *addr, int blk, 615 int mode, const audio_params_t *param) 616 { 617 618 /* round up to even size */ 619 return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk; 620 } 621 622 int 623 aucc_commit_settings(void *addr) 624 { 625 struct aucc_softc *sc; 626 int i; 627 628 DPRINTF(("sa_commit.\n")); 629 630 sc = addr; 631 for (i = 0; i < 4; i++) { 632 custom.aud[i].vol = sc->sc_channel[i].nd_volume; 633 custom.aud[i].per = sc->sc_channel[i].nd_per; 634 } 635 636 DPRINTF(("commit done\n")); 637 638 return 0; 639 } 640 641 static int masks[4] = {1,3,7,15}; /* masks for n first channels */ 642 static int masks2[4] = {1,2,4,8}; 643 644 int 645 aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 646 { 647 struct aucc_softc *sc; 648 int mask; 649 int i, j, k, len; 650 u_char *dmap[4]; 651 652 653 sc = addr; 654 mask = sc->sc_channelmask; 655 656 dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL; 657 658 DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg)); 659 660 if (sc->sc_channels > 1) 661 mask &= masks[sc->sc_channels - 1]; 662 /* we use first sc_channels channels */ 663 if (mask == 0) /* active and used channels are disjoint */ 664 return EINVAL; 665 666 for (i = 0; i < 4; i++) { 667 /* channels available ? */ 668 if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy)) 669 return EBUSY; /* channel is busy */ 670 if (channel[i].isaudio == -1) 671 return EBUSY; /* system uses them */ 672 } 673 674 /* enable interrupt on 1st channel */ 675 for (i = j = 0; i < AUCC_MAXINT; i++) { 676 if (masks2[i] & mask) { 677 DPRINTF(("first channel is %d\n",i)); 678 j = i; 679 sc->sc_channel[i].nd_intr = intr; 680 sc->sc_channel[i].nd_intrdata = arg; 681 break; 682 } 683 } 684 685 DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1], 686 dmap[2], dmap[3], mask)); 687 688 /* disable ints, DMA for channels, until all parameters set */ 689 /* XXX dont disable DMA! custom.dmacon=mask;*/ 690 custom.intreq = mask << INTB_AUD0; 691 custom.intena = mask << INTB_AUD0; 692 693 /* copy data to DMA buffer */ 694 695 if (sc->sc_channels == 1) { 696 dmap[0] = 697 dmap[1] = 698 dmap[2] = 699 dmap[3] = (u_char *)sc->sc_channel[j].nd_dma; 700 } else { 701 for (k = 0; k < 4; k++) { 702 if (masks2[k+j] & mask) 703 dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma; 704 } 705 } 706 707 sc->sc_channel[j].nd_doublebuf ^= 1; 708 if (sc->sc_channel[j].nd_doublebuf) { 709 dmap[0] += AUDIO_BUF_SIZE; 710 dmap[1] += AUDIO_BUF_SIZE; 711 dmap[2] += AUDIO_BUF_SIZE; 712 dmap[3] += AUDIO_BUF_SIZE; 713 } 714 715 /* 716 * compute output length in bytes per channel. 717 * divide by two only for 16bit->8bit conversion. 718 */ 719 len = cc / sc->sc_channels; 720 if (!sc->sc_14bit && (sc->sc_precision == 16)) 721 len /= 2; 722 723 /* call audio decoding routine */ 724 sc->sc_decodefunc (dmap, (u_char *)p, len); 725 726 /* DMA buffers: we use same buffer 4 all channels 727 * write DMA location and length 728 */ 729 for (i = k = 0; i < 4; i++) { 730 if (masks2[i] & mask) { 731 DPRINTF(("turning channel %d on\n",i)); 732 /* sc->sc_channel[i].nd_busy=1; */ 733 channel[i].isaudio = 1; 734 channel[i].play_count = 1; 735 channel[i].handler = NULL; 736 custom.aud[i].per = sc->sc_channel[i].nd_per; 737 if (sc->sc_14bit && (i > 1)) 738 custom.aud[i].vol = 1; 739 else 740 custom.aud[i].vol = sc->sc_channel[i].nd_volume; 741 custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]); 742 custom.aud[i].len = len / 2; 743 sc->sc_channel[i].nd_mask = mask; 744 DPRINTF(("per is %d, vol is %d, len is %d\n",\ 745 sc->sc_channel[i].nd_per, 746 sc->sc_channel[i].nd_volume, len)); 747 } 748 } 749 750 channel[j].handler = aucc_inthdl; 751 752 /* enable ints */ 753 custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0); 754 755 DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0))); 756 757 /* enable DMA */ 758 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask; 759 760 DPRINTF(("enabled DMA, mask=0x%x\n",mask)); 761 762 return 0; 763 } 764 765 /* ARGSUSED */ 766 int 767 aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 768 { 769 770 return ENXIO; /* no input */ 771 } 772 773 int 774 aucc_halt_output(void *addr) 775 { 776 struct aucc_softc *sc; 777 int i; 778 779 /* XXX only halt, if input is also halted ?? */ 780 sc = addr; 781 /* stop DMA, etc */ 782 custom.intena = AUCC_ALLINTF; 783 custom.dmacon = AUCC_ALLDMAF; 784 /* mark every busy unit idle */ 785 for (i = 0; i < 4; i++) { 786 sc->sc_channel[i].nd_busy = sc->sc_channel[i].nd_mask = 0; 787 channel[i].isaudio = 0; 788 channel[i].play_count = 0; 789 } 790 791 return 0; 792 } 793 794 int 795 aucc_halt_input(void *addr) 796 { 797 798 /* no input */ 799 return ENXIO; 800 } 801 802 int 803 aucc_getdev(void *addr, struct audio_device *retp) 804 { 805 806 *retp = aucc_device; 807 return 0; 808 } 809 810 int 811 aucc_set_port(void *addr, mixer_ctrl_t *cp) 812 { 813 struct aucc_softc *sc; 814 int i,j; 815 816 DPRINTF(("aucc_set_port: port=%d", cp->dev)); 817 sc = addr; 818 switch (cp->type) { 819 case AUDIO_MIXER_SET: 820 if (cp->dev != AUCC_CHANNELS) 821 return EINVAL; 822 i = cp->un.mask; 823 if ((i < 1) || (i > 15)) 824 return EINVAL; 825 826 sc->sc_channelmask = i; 827 break; 828 829 case AUDIO_MIXER_VALUE: 830 i = cp->un.value.num_channels; 831 if ((i < 1) || (i > 4)) 832 return EINVAL; 833 834 #ifdef __XXXwhatsthat 835 if (cp->dev != AUCC_VOLUME) 836 return EINVAL; 837 #endif 838 839 /* set volume for channel 0..i-1 */ 840 841 /* evil workaround for xanim bug, IMO */ 842 if ((sc->sc_channels == 1) && (i == 2)) { 843 sc->sc_channel[0].nd_volume = 844 sc->sc_channel[3].nd_volume = 845 cp->un.value.level[0] >> 2; 846 sc->sc_channel[1].nd_volume = 847 sc->sc_channel[2].nd_volume = 848 cp->un.value.level[1] >> 2; 849 } else if (i > 1) { 850 for (j = 0; j < i; j++) 851 sc->sc_channel[j].nd_volume = 852 cp->un.value.level[j] >> 2; 853 } else if (sc->sc_channels > 1) 854 for (j = 0; j < sc->sc_channels; j++) 855 sc->sc_channel[j].nd_volume = 856 cp->un.value.level[0] >> 2; 857 else 858 for (j = 0; j < 4; j++) 859 sc->sc_channel[j].nd_volume = 860 cp->un.value.level[0] >> 2; 861 break; 862 863 default: 864 return EINVAL; 865 break; 866 } 867 return 0; 868 } 869 870 871 int 872 aucc_get_port(void *addr, mixer_ctrl_t *cp) 873 { 874 struct aucc_softc *sc; 875 int i,j; 876 877 DPRINTF(("aucc_get_port: port=%d", cp->dev)); 878 sc = addr; 879 switch (cp->type) { 880 case AUDIO_MIXER_SET: 881 if (cp->dev != AUCC_CHANNELS) 882 return EINVAL; 883 cp->un.mask = sc->sc_channelmask; 884 break; 885 886 case AUDIO_MIXER_VALUE: 887 i = cp->un.value.num_channels; 888 if ((i < 1) || (i > 4)) 889 return EINVAL; 890 891 for (j = 0; j < i; j++) 892 cp->un.value.level[j] = 893 (sc->sc_channel[j].nd_volume << 2) + 894 (sc->sc_channel[j].nd_volume >> 4); 895 break; 896 897 default: 898 return EINVAL; 899 } 900 return 0; 901 } 902 903 904 int 905 aucc_get_props(void *addr) 906 { 907 return 0; 908 } 909 910 911 void 912 aucc_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread) 913 { 914 struct aucc_softc *sc = opaque; 915 916 *intr = &sc->sc_intr_lock; 917 *thread = &sc->sc_lock; 918 } 919 920 int 921 aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip) 922 { 923 int i; 924 925 switch(dip->index) { 926 case AUCC_CHANNELS: 927 dip->type = AUDIO_MIXER_SET; 928 dip->mixer_class = AUCC_OUTPUT_CLASS; 929 dip->prev = dip->next = AUDIO_MIXER_LAST; 930 #define setname(a) strlcpy(dip->label.name, (a), sizeof(dip->label.name)) 931 setname(AudioNspeaker); 932 for (i = 0; i < 16; i++) { 933 snprintf(dip->un.s.member[i].label.name, 934 sizeof(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 setname(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 setname(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