1 /* $NetBSD: aucc.c,v 1.48 2020/02/29 06:03:55 isaki 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 * - channel allocation is wrong for 14bit mono 39 * - perhaps use a calibration table for better 14bit output 40 * - set 31 kHz AGA video mode to allow 44.1 kHz even if grfcc is missing 41 * in the kernel 42 * - 14bit output requires maximum volume 43 */ 44 45 #include "aucc.h" 46 #if NAUCC > 0 47 48 #include <sys/cdefs.h> 49 __KERNEL_RCSID(0, "$NetBSD: aucc.c,v 1.48 2020/02/29 06:03:55 isaki Exp $"); 50 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/errno.h> 54 #include <sys/ioctl.h> 55 #include <sys/device.h> 56 #include <sys/proc.h> 57 #include <machine/cpu.h> 58 59 #include <sys/audioio.h> 60 #include <dev/audio/audio_if.h> 61 #include <dev/audio/audiovar.h> /* for AUDIO_MIN_FREQUENCY */ 62 63 #include <amiga/amiga/cc.h> 64 #include <amiga/amiga/custom.h> 65 #include <amiga/amiga/device.h> 66 #include <amiga/dev/auccvar.h> 67 68 #include "opt_lev6_defer.h" 69 70 71 #ifdef LEV6_DEFER 72 #define AUCC_MAXINT 3 73 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2) 74 #else 75 #define AUCC_MAXINT 4 76 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3) 77 #endif 78 /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */ 79 #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3) 80 81 #ifdef AUDIO_DEBUG 82 /*extern printf(const char *,...);*/ 83 int auccdebug = 1; 84 #define DPRINTF(x) if (auccdebug) printf x 85 #else 86 #define DPRINTF(x) 87 #endif 88 89 /* clock frequency.. */ 90 extern int eclockfreq; 91 92 93 /* hw audio ch */ 94 extern struct audio_channel channel[4]; 95 96 97 /* 98 * Software state. 99 */ 100 struct aucc_softc { 101 aucc_data_t sc_channel[4]; /* per channel freq, ... */ 102 u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/ 103 int sc_channels; /* # of channels used */ 104 int sc_precision; /* 8 or 16 bits */ 105 int sc_14bit; /* 14bit output enabled */ 106 107 int sc_intrcnt; /* interrupt count */ 108 int sc_channelmask; /* which channels are used ? */ 109 void (*sc_decodefunc)(u_char **, u_char *, int); 110 /* pointer to format conversion routine */ 111 112 kmutex_t sc_lock; 113 kmutex_t sc_intr_lock; 114 }; 115 116 /* interrupt interfaces */ 117 void aucc_inthdl(int); 118 119 /* forward declarations */ 120 static int init_aucc(struct aucc_softc *); 121 static u_int freqtoper(u_int); 122 static u_int pertofreq(u_int); 123 124 /* autoconfiguration driver */ 125 void auccattach(device_t, device_t, void *); 126 int auccmatch(device_t, cfdata_t, void *); 127 128 CFATTACH_DECL_NEW(aucc, sizeof(struct aucc_softc), 129 auccmatch, auccattach, NULL, NULL); 130 131 struct audio_device aucc_device = { 132 "Amiga-audio", 133 "2.0", 134 "aucc" 135 }; 136 137 138 struct aucc_softc *aucc = NULL; 139 140 141 /* 142 * Define our interface to the higher level audio driver. 143 */ 144 int aucc_open(void *, int); 145 void aucc_close(void *); 146 int aucc_set_out_sr(void *, u_int); 147 int aucc_query_format(void *, audio_format_query_t *); 148 int aucc_round_blocksize(void *, int, int, const audio_params_t *); 149 int aucc_commit_settings(void *); 150 int aucc_start_output(void *, void *, int, void (*)(void *), void *); 151 int aucc_start_input(void *, void *, int, void (*)(void *), void *); 152 int aucc_halt_output(void *); 153 int aucc_halt_input(void *); 154 int aucc_getdev(void *, struct audio_device *); 155 int aucc_set_port(void *, mixer_ctrl_t *); 156 int aucc_get_port(void *, mixer_ctrl_t *); 157 int aucc_query_devinfo(void *, mixer_devinfo_t *); 158 void aucc_encode(int, int, int, int, u_char *, u_short **); 159 int aucc_set_format(void *, int, 160 const audio_params_t *, const audio_params_t *, 161 audio_filter_reg_t *, audio_filter_reg_t *); 162 int aucc_get_props(void *); 163 void aucc_get_locks(void *, kmutex_t **, kmutex_t **); 164 165 166 static void aucc_decode_slinear16_1ch(u_char **, u_char *, int); 167 static void aucc_decode_slinear16_2ch(u_char **, u_char *, int); 168 static void aucc_decode_slinear16_3ch(u_char **, u_char *, int); 169 static void aucc_decode_slinear16_4ch(u_char **, u_char *, int); 170 171 172 const struct audio_hw_if sa_hw_if = { 173 .open = aucc_open, 174 .close = aucc_close, 175 .query_format = aucc_query_format, 176 .set_format = aucc_set_format, 177 .round_blocksize = aucc_round_blocksize, 178 .commit_settings = aucc_commit_settings, 179 .start_output = aucc_start_output, 180 .start_input = aucc_start_input, 181 .halt_output = aucc_halt_output, 182 .halt_input = aucc_halt_input, 183 .getdev = aucc_getdev, 184 .set_port = aucc_set_port, 185 .get_port = aucc_get_port, 186 .query_devinfo = aucc_query_devinfo, 187 .get_props = aucc_get_props, 188 .get_locks = aucc_get_locks, 189 }; 190 191 /* 192 * XXX *1 How lower limit of frequency should be? same as audio(4)? 193 * XXX *2 Should avoid a magic number at the upper limit of frequency. 194 * XXX *3 In fact, there is a number in this range that have minimal errors. 195 * It would be better if there is a mechanism which such frequency 196 * is prioritized. 197 * XXX *4 3/4ch modes use 8bits, 1/2ch modes use 14bits, 198 * so I imagined that 1/2ch modes are better. 199 */ 200 #define AUCC_FORMAT(prio, ch, chmask) \ 201 { \ 202 .mode = AUMODE_PLAY, \ 203 .priority = (prio), \ 204 .encoding = AUDIO_ENCODING_SLINEAR_BE, \ 205 .validbits = 16, \ 206 .precision = 16, \ 207 .channels = (ch), \ 208 .channel_mask = (chmask), \ 209 .frequency_type = 0, \ 210 .frequency = { AUDIO_MIN_FREQUENCY, 28867 }, \ 211 } 212 static const struct audio_format aucc_formats[] = { 213 AUCC_FORMAT(1, 1, AUFMT_MONAURAL), 214 AUCC_FORMAT(1, 2, AUFMT_STEREO), 215 AUCC_FORMAT(0, 3, AUFMT_UNKNOWN_POSITION), 216 AUCC_FORMAT(0, 4, AUFMT_UNKNOWN_POSITION), 217 }; 218 #define AUCC_NFORMATS __arraycount(aucc_formats) 219 220 /* autoconfig routines */ 221 222 int 223 auccmatch(device_t parent, cfdata_t cf, void *aux) 224 { 225 static int aucc_matched = 0; 226 227 if (!matchname((char *)aux, "aucc") || 228 #ifdef DRACO 229 is_draco() || 230 #endif 231 aucc_matched) 232 return 0; 233 234 aucc_matched = 1; 235 return 1; 236 } 237 238 /* 239 * Audio chip found. 240 */ 241 void 242 auccattach(device_t parent, device_t self, void *args) 243 { 244 struct aucc_softc *sc; 245 int i; 246 247 sc = device_private(self); 248 printf("\n"); 249 250 if ((i=init_aucc(sc))) { 251 printf("audio: no chipmem\n"); 252 return; 253 } 254 255 audio_attach_mi(&sa_hw_if, sc, self); 256 } 257 258 259 static int 260 init_aucc(struct aucc_softc *sc) 261 { 262 int i, err; 263 264 err = 0; 265 /* init values per channel */ 266 for (i = 0; i < 4; i++) { 267 sc->sc_channel[i].nd_freq = 8000; 268 sc->sc_channel[i].nd_per = freqtoper(8000); 269 sc->sc_channel[i].nd_busy = 0; 270 sc->sc_channel[i].nd_dma = alloc_chipmem(AUDIO_BUF_SIZE*2); 271 if (sc->sc_channel[i].nd_dma == NULL) 272 err = 1; 273 sc->sc_channel[i].nd_dmalength = 0; 274 sc->sc_channel[i].nd_volume = 64; 275 sc->sc_channel[i].nd_intr = NULL; 276 sc->sc_channel[i].nd_intrdata = NULL; 277 sc->sc_channel[i].nd_doublebuf = 0; 278 DPRINTF(("DMA buffer for channel %d is %p\n", i, 279 sc->sc_channel[i].nd_dma)); 280 } 281 282 if (err) { 283 for (i = 0; i < 4; i++) 284 if (sc->sc_channel[i].nd_dma) 285 free_chipmem(sc->sc_channel[i].nd_dma); 286 } 287 288 sc->sc_channels = 1; 289 sc->sc_channelmask = 0xf; 290 sc->sc_precision = 16; 291 sc->sc_14bit = 1; 292 sc->sc_encoding = AUDIO_ENCODING_SLINEAR_BE; 293 sc->sc_decodefunc = aucc_decode_slinear16_2ch; 294 295 /* clear interrupts and DMA: */ 296 custom.intena = AUCC_ALLINTF; 297 custom.dmacon = AUCC_ALLDMAF; 298 299 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 300 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); 301 302 return err; 303 } 304 305 int 306 aucc_open(void *addr, int flags) 307 { 308 struct aucc_softc *sc; 309 int i; 310 311 sc = addr; 312 DPRINTF(("sa_open: unit %p\n",sc)); 313 314 for (i = 0; i < AUCC_MAXINT; i++) { 315 sc->sc_channel[i].nd_intr = NULL; 316 sc->sc_channel[i].nd_intrdata = NULL; 317 } 318 aucc = sc; 319 sc->sc_channelmask = 0xf; 320 321 DPRINTF(("saopen: ok -> sc=%p\n",sc)); 322 323 return 0; 324 } 325 326 void 327 aucc_close(void *addr) 328 { 329 330 DPRINTF(("sa_close: closed.\n")); 331 } 332 333 int 334 aucc_set_out_sr(void *addr, u_int sr) 335 { 336 struct aucc_softc *sc; 337 u_long per; 338 int i; 339 340 sc = addr; 341 per = freqtoper(sr); 342 if (per > 0xffff) 343 return EINVAL; 344 sr = pertofreq(per); 345 346 for (i = 0; i < 4; i++) { 347 sc->sc_channel[i].nd_freq = sr; 348 sc->sc_channel[i].nd_per = per; 349 } 350 351 return 0; 352 } 353 354 int 355 aucc_query_format(void *addr, audio_format_query_t *afp) 356 { 357 358 return audio_query_format(aucc_formats, AUCC_NFORMATS, afp); 359 } 360 361 int 362 aucc_set_format(void *addr, int setmode, 363 const audio_params_t *p, const audio_params_t *r, 364 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 365 { 366 struct aucc_softc *sc; 367 368 sc = addr; 369 KASSERT((setmode & AUMODE_RECORD) == 0); 370 371 #ifdef AUCCDEBUG 372 printf("%s(setmode 0x%x," 373 "enc %u bits %u, chn %u, sr %u)\n", setmode, 374 p->encoding, p->precision, p->channels, p->sample_rate); 375 #endif 376 377 switch (p->channels) { 378 case 1: 379 sc->sc_decodefunc = aucc_decode_slinear16_1ch; 380 break; 381 case 2: 382 sc->sc_decodefunc = aucc_decode_slinear16_2ch; 383 break; 384 case 3: 385 sc->sc_decodefunc = aucc_decode_slinear16_3ch; 386 break; 387 case 4: 388 sc->sc_decodefunc = aucc_decode_slinear16_4ch; 389 break; 390 default: 391 return EINVAL; 392 } 393 394 sc->sc_encoding = p->encoding; 395 sc->sc_precision = p->precision; 396 sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2)); 397 sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels; 398 399 return aucc_set_out_sr(addr, p->sample_rate); 400 } 401 402 int 403 aucc_round_blocksize(void *addr, int blk, 404 int mode, const audio_params_t *param) 405 { 406 407 if (blk > AUDIO_BUF_SIZE) 408 blk = AUDIO_BUF_SIZE; 409 410 blk = rounddown(blk, param->channels * param->precision / NBBY); 411 return blk; 412 } 413 414 int 415 aucc_commit_settings(void *addr) 416 { 417 struct aucc_softc *sc; 418 int i; 419 420 DPRINTF(("sa_commit.\n")); 421 422 sc = addr; 423 for (i = 0; i < 4; i++) { 424 custom.aud[i].vol = sc->sc_channel[i].nd_volume; 425 custom.aud[i].per = sc->sc_channel[i].nd_per; 426 } 427 428 DPRINTF(("commit done\n")); 429 430 return 0; 431 } 432 433 static int masks[4] = {1,3,7,15}; /* masks for n first channels */ 434 static int masks2[4] = {1,2,4,8}; 435 436 int 437 aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 438 { 439 struct aucc_softc *sc; 440 int mask; 441 int i, j, k, len; 442 u_char *dmap[4]; 443 444 445 sc = addr; 446 mask = sc->sc_channelmask; 447 448 dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL; 449 450 DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg)); 451 452 if (sc->sc_channels > 1) 453 mask &= masks[sc->sc_channels - 1]; 454 /* we use first sc_channels channels */ 455 if (mask == 0) /* active and used channels are disjoint */ 456 return EINVAL; 457 458 for (i = 0; i < 4; i++) { 459 /* channels available ? */ 460 if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy)) 461 return EBUSY; /* channel is busy */ 462 if (channel[i].isaudio == -1) 463 return EBUSY; /* system uses them */ 464 } 465 466 /* enable interrupt on 1st channel */ 467 for (i = j = 0; i < AUCC_MAXINT; i++) { 468 if (masks2[i] & mask) { 469 DPRINTF(("first channel is %d\n",i)); 470 j = i; 471 sc->sc_channel[i].nd_intr = intr; 472 sc->sc_channel[i].nd_intrdata = arg; 473 break; 474 } 475 } 476 477 DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1], 478 dmap[2], dmap[3], mask)); 479 480 /* disable ints, DMA for channels, until all parameters set */ 481 /* XXX dont disable DMA! custom.dmacon=mask;*/ 482 custom.intreq = mask << INTB_AUD0; 483 custom.intena = mask << INTB_AUD0; 484 485 /* copy data to DMA buffer */ 486 487 if (sc->sc_channels == 1) { 488 dmap[0] = 489 dmap[1] = 490 dmap[2] = 491 dmap[3] = (u_char *)sc->sc_channel[j].nd_dma; 492 } else { 493 for (k = 0; k < 4; k++) { 494 if (masks2[k+j] & mask) 495 dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma; 496 } 497 } 498 499 sc->sc_channel[j].nd_doublebuf ^= 1; 500 if (sc->sc_channel[j].nd_doublebuf) { 501 dmap[0] += AUDIO_BUF_SIZE; 502 dmap[1] += AUDIO_BUF_SIZE; 503 dmap[2] += AUDIO_BUF_SIZE; 504 dmap[3] += AUDIO_BUF_SIZE; 505 } 506 507 /* 508 * compute output length in bytes per channel. 509 * divide by two only for 16bit->8bit conversion. 510 */ 511 len = cc / sc->sc_channels; 512 if (!sc->sc_14bit && (sc->sc_precision == 16)) 513 len /= 2; 514 515 /* call audio decoding routine */ 516 sc->sc_decodefunc (dmap, (u_char *)p, len); 517 518 /* DMA buffers: we use same buffer 4 all channels 519 * write DMA location and length 520 */ 521 for (i = k = 0; i < 4; i++) { 522 if (masks2[i] & mask) { 523 DPRINTF(("turning channel %d on\n",i)); 524 /* sc->sc_channel[i].nd_busy=1; */ 525 channel[i].isaudio = 1; 526 channel[i].play_count = 1; 527 channel[i].handler = NULL; 528 custom.aud[i].per = sc->sc_channel[i].nd_per; 529 if (sc->sc_14bit && (i > 1)) 530 custom.aud[i].vol = 1; 531 else 532 custom.aud[i].vol = sc->sc_channel[i].nd_volume; 533 custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]); 534 custom.aud[i].len = len / 2; 535 sc->sc_channel[i].nd_mask = mask; 536 DPRINTF(("per is %d, vol is %d, len is %d\n",\ 537 sc->sc_channel[i].nd_per, 538 sc->sc_channel[i].nd_volume, len)); 539 } 540 } 541 542 channel[j].handler = aucc_inthdl; 543 544 /* enable ints */ 545 custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0); 546 547 DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0))); 548 549 /* enable DMA */ 550 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask; 551 552 DPRINTF(("enabled DMA, mask=0x%x\n",mask)); 553 554 return 0; 555 } 556 557 /* ARGSUSED */ 558 int 559 aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 560 { 561 562 return ENXIO; /* no input */ 563 } 564 565 int 566 aucc_halt_output(void *addr) 567 { 568 struct aucc_softc *sc; 569 int i; 570 571 /* XXX only halt, if input is also halted ?? */ 572 sc = addr; 573 /* stop DMA, etc */ 574 custom.intena = AUCC_ALLINTF; 575 custom.dmacon = AUCC_ALLDMAF; 576 /* mark every busy unit idle */ 577 for (i = 0; i < 4; i++) { 578 sc->sc_channel[i].nd_busy = sc->sc_channel[i].nd_mask = 0; 579 channel[i].isaudio = 0; 580 channel[i].play_count = 0; 581 } 582 583 return 0; 584 } 585 586 int 587 aucc_halt_input(void *addr) 588 { 589 590 /* no input */ 591 return ENXIO; 592 } 593 594 int 595 aucc_getdev(void *addr, struct audio_device *retp) 596 { 597 598 *retp = aucc_device; 599 return 0; 600 } 601 602 int 603 aucc_set_port(void *addr, mixer_ctrl_t *cp) 604 { 605 struct aucc_softc *sc; 606 int i,j; 607 608 DPRINTF(("aucc_set_port: port=%d", cp->dev)); 609 sc = addr; 610 switch (cp->type) { 611 case AUDIO_MIXER_SET: 612 if (cp->dev != AUCC_CHANNELS) 613 return EINVAL; 614 i = cp->un.mask; 615 if ((i < 1) || (i > 15)) 616 return EINVAL; 617 618 sc->sc_channelmask = i; 619 break; 620 621 case AUDIO_MIXER_VALUE: 622 i = cp->un.value.num_channels; 623 if ((i < 1) || (i > 4)) 624 return EINVAL; 625 626 #ifdef __XXXwhatsthat 627 if (cp->dev != AUCC_VOLUME) 628 return EINVAL; 629 #endif 630 631 /* set volume for channel 0..i-1 */ 632 633 /* evil workaround for xanim bug, IMO */ 634 if ((sc->sc_channels == 1) && (i == 2)) { 635 sc->sc_channel[0].nd_volume = 636 sc->sc_channel[3].nd_volume = 637 cp->un.value.level[0] >> 2; 638 sc->sc_channel[1].nd_volume = 639 sc->sc_channel[2].nd_volume = 640 cp->un.value.level[1] >> 2; 641 } else if (i > 1) { 642 for (j = 0; j < i; j++) 643 sc->sc_channel[j].nd_volume = 644 cp->un.value.level[j] >> 2; 645 } else if (sc->sc_channels > 1) 646 for (j = 0; j < sc->sc_channels; j++) 647 sc->sc_channel[j].nd_volume = 648 cp->un.value.level[0] >> 2; 649 else 650 for (j = 0; j < 4; j++) 651 sc->sc_channel[j].nd_volume = 652 cp->un.value.level[0] >> 2; 653 break; 654 655 default: 656 return EINVAL; 657 break; 658 } 659 return 0; 660 } 661 662 663 int 664 aucc_get_port(void *addr, mixer_ctrl_t *cp) 665 { 666 struct aucc_softc *sc; 667 int i,j; 668 669 DPRINTF(("aucc_get_port: port=%d", cp->dev)); 670 sc = addr; 671 switch (cp->type) { 672 case AUDIO_MIXER_SET: 673 if (cp->dev != AUCC_CHANNELS) 674 return EINVAL; 675 cp->un.mask = sc->sc_channelmask; 676 break; 677 678 case AUDIO_MIXER_VALUE: 679 i = cp->un.value.num_channels; 680 if ((i < 1) || (i > 4)) 681 return EINVAL; 682 683 for (j = 0; j < i; j++) 684 cp->un.value.level[j] = 685 (sc->sc_channel[j].nd_volume << 2) + 686 (sc->sc_channel[j].nd_volume >> 4); 687 break; 688 689 default: 690 return EINVAL; 691 } 692 return 0; 693 } 694 695 696 int 697 aucc_get_props(void *addr) 698 { 699 700 return AUDIO_PROP_PLAYBACK; 701 } 702 703 704 void 705 aucc_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread) 706 { 707 struct aucc_softc *sc = opaque; 708 709 *intr = &sc->sc_intr_lock; 710 *thread = &sc->sc_lock; 711 } 712 713 int 714 aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip) 715 { 716 int i; 717 718 switch(dip->index) { 719 case AUCC_CHANNELS: 720 dip->type = AUDIO_MIXER_SET; 721 dip->mixer_class = AUCC_OUTPUT_CLASS; 722 dip->prev = dip->next = AUDIO_MIXER_LAST; 723 #define setname(a) strlcpy(dip->label.name, (a), sizeof(dip->label.name)) 724 setname(AudioNspeaker); 725 for (i = 0; i < 16; i++) { 726 snprintf(dip->un.s.member[i].label.name, 727 sizeof(dip->un.s.member[i].label.name), 728 "channelmask%d", i); 729 dip->un.s.member[i].mask = i; 730 } 731 dip->un.s.num_mem = 16; 732 break; 733 734 case AUCC_VOLUME: 735 dip->type = AUDIO_MIXER_VALUE; 736 dip->mixer_class = AUCC_OUTPUT_CLASS; 737 dip->prev = dip->next = AUDIO_MIXER_LAST; 738 setname(AudioNmaster); 739 dip->un.v.num_channels = 4; 740 strcpy(dip->un.v.units.name, AudioNvolume); 741 break; 742 743 case AUCC_OUTPUT_CLASS: 744 dip->type = AUDIO_MIXER_CLASS; 745 dip->mixer_class = AUCC_OUTPUT_CLASS; 746 dip->next = dip->prev = AUDIO_MIXER_LAST; 747 setname(AudioCoutputs); 748 break; 749 750 default: 751 return ENXIO; 752 } 753 754 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 755 756 return 0; 757 } 758 759 /* audio int handler */ 760 void 761 aucc_inthdl(int ch) 762 { 763 int i; 764 int mask; 765 766 mutex_spin_enter(&aucc->sc_intr_lock); 767 mask = aucc->sc_channel[ch].nd_mask; 768 /* 769 * for all channels in this maskgroup: 770 * disable DMA, int 771 * mark idle 772 */ 773 DPRINTF(("inthandler called, channel %d, mask 0x%x\n", ch, mask)); 774 775 custom.intreq = mask << INTB_AUD0; /* clear request */ 776 /* 777 * XXX: maybe we can leave ints and/or DMA on, 778 * if another sample has to be played? 779 */ 780 custom.intena = mask << INTB_AUD0; 781 /* 782 * XXX custom.dmacon=mask; NO!!! 783 */ 784 for (i = 0; i < 4; i++) { 785 if (masks2[i] && mask) { 786 DPRINTF(("marking channel %d idle\n",i)); 787 aucc->sc_channel[i].nd_busy = 0; 788 aucc->sc_channel[i].nd_mask = 0; 789 channel[i].isaudio = channel[i].play_count = 0; 790 } 791 } 792 793 /* call handler */ 794 if (aucc->sc_channel[ch].nd_intr) { 795 DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr)); 796 (*(aucc->sc_channel[ch].nd_intr)) 797 (aucc->sc_channel[ch].nd_intrdata); 798 } else 799 DPRINTF(("zero int handler\n")); 800 mutex_spin_exit(&aucc->sc_intr_lock); 801 DPRINTF(("ints done\n")); 802 } 803 804 /* transform frequency to period, adjust bounds */ 805 static u_int 806 freqtoper(u_int freq) 807 { 808 u_int per; 809 810 per = eclockfreq * 5 / freq; 811 if (per < 124) 812 per = 124; /* must have at least 124 ticks between samples */ 813 814 return per; 815 } 816 817 /* transform period to frequency */ 818 static u_int 819 pertofreq(u_int per) 820 { 821 822 return eclockfreq * 5 / per; 823 } 824 825 826 /* 14bit output */ 827 static void 828 aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i) 829 { 830 u_char *ch0; 831 u_char *ch3; 832 833 ch0 = dmap[0]; 834 ch3 = dmap[1]; /* XXX should be 3 */ 835 while (i--) { 836 *ch0++ = *p++; 837 *ch3++ = *p++ >> 2; 838 } 839 } 840 841 /* 14bit stereo output */ 842 static void 843 aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i) 844 { 845 u_char *ch0; 846 u_char *ch1; 847 u_char *ch2; 848 u_char *ch3; 849 850 ch0 = dmap[0]; 851 ch1 = dmap[1]; 852 ch2 = dmap[2]; 853 ch3 = dmap[3]; 854 while (i--) { 855 *ch0++ = *p++; 856 *ch3++ = *p++ >> 2; 857 *ch1++ = *p++; 858 *ch2++ = *p++ >> 2; 859 } 860 } 861 862 static void 863 aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i) 864 { 865 u_char *ch0; 866 u_char *ch1; 867 u_char *ch2; 868 869 ch0 = dmap[0]; 870 ch1 = dmap[1]; 871 ch2 = dmap[2]; 872 while (i--) { 873 *ch0++ = *p++; p++; 874 *ch1++ = *p++; p++; 875 *ch2++ = *p++; p++; 876 } 877 } 878 879 static void 880 aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i) 881 { 882 u_char *ch0; 883 u_char *ch1; 884 u_char *ch2; 885 u_char *ch3; 886 887 ch0 = dmap[0]; 888 ch1 = dmap[1]; 889 ch2 = dmap[2]; 890 ch3 = dmap[3]; 891 while (i--) { 892 *ch0++ = *p++; p++; 893 *ch1++ = *p++; p++; 894 *ch2++ = *p++; p++; 895 *ch3++ = *p++; p++; 896 } 897 } 898 899 #endif /* NAUCC > 0 */ 900