1 /* $OpenBSD: ce4231.c,v 1.15 2003/06/24 21:54:39 henric Exp $ */ 2 3 /* 4 * Copyright (c) 1999 Jason L. Wright (jason@thought.net) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Driver for CS4231 based audio found in some sun4m systems (cs4231) 31 * based on ideas from the S/Linux project and the NetBSD project. 32 * 33 * Effort sponsored in part by the Defense Advanced Research Projects 34 * Agency (DARPA) and Air Force Research Laboratory, Air Force 35 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 36 * 37 */ 38 39 #include "audio.h" 40 #if NAUDIO > 0 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/errno.h> 45 #include <sys/ioctl.h> 46 #include <sys/device.h> 47 #include <sys/proc.h> 48 #include <sys/malloc.h> 49 50 #include <machine/cpu.h> 51 #include <machine/bus.h> 52 #include <machine/intr.h> 53 #include <machine/autoconf.h> 54 55 #include <sys/audioio.h> 56 #include <dev/audio_if.h> 57 #include <dev/auconv.h> 58 59 #include <sparc64/dev/ebusreg.h> 60 #include <sparc64/dev/ebusvar.h> 61 #include <sparc64/dev/ce4231var.h> 62 63 #include <dev/ic/ad1848reg.h> 64 #include <dev/ic/cs4231reg.h> 65 66 #define CSAUDIO_DAC_LVL 0 67 #define CSAUDIO_LINE_IN_LVL 1 68 #define CSAUDIO_MIC_LVL 2 69 #define CSAUDIO_CD_LVL 3 70 #define CSAUDIO_MONITOR_LVL 4 71 #define CSAUDIO_OUTPUT_LVL 5 72 #define CSAUDIO_LINE_IN_MUTE 6 73 #define CSAUDIO_DAC_MUTE 7 74 #define CSAUDIO_CD_MUTE 8 75 #define CSAUDIO_MIC_MUTE 9 76 #define CSAUDIO_MONITOR_MUTE 10 77 #define CSAUDIO_OUTPUT_MUTE 11 78 #define CSAUDIO_REC_LVL 12 79 #define CSAUDIO_RECORD_SOURCE 13 80 #define CSAUDIO_OUTPUT 14 81 #define CSAUDIO_INPUT_CLASS 15 82 #define CSAUDIO_OUTPUT_CLASS 16 83 #define CSAUDIO_RECORD_CLASS 17 84 #define CSAUDIO_MONITOR_CLASS 18 85 86 #define CSPORT_AUX2 0 87 #define CSPORT_AUX1 1 88 #define CSPORT_DAC 2 89 #define CSPORT_LINEIN 3 90 #define CSPORT_MONO 4 91 #define CSPORT_MONITOR 5 92 #define CSPORT_SPEAKER 6 93 #define CSPORT_LINEOUT 7 94 #define CSPORT_HEADPHONE 8 95 96 #define MIC_IN_PORT 0 97 #define LINE_IN_PORT 1 98 #define AUX1_IN_PORT 2 99 #define DAC_IN_PORT 3 100 101 #ifdef AUDIO_DEBUG 102 #define DPRINTF(x) printf x 103 #else 104 #define DPRINTF(x) 105 #endif 106 107 #define CS_TIMEOUT 90000 108 109 #define CS_PC_LINEMUTE XCTL0_ENABLE 110 #define CS_PC_HDPHMUTE XCTL1_ENABLE 111 #define CS_AFS_PI 0x10 112 113 /* Read/write CS4231 direct registers */ 114 #define CS_WRITE(sc,r,v) \ 115 bus_space_write_1((sc)->sc_bustag, (sc)->sc_cshandle, (r) << 2, (v)) 116 #define CS_READ(sc,r) \ 117 bus_space_read_1((sc)->sc_bustag, (sc)->sc_cshandle, (r) << 2) 118 119 /* Read/write EBDMA playback registers */ 120 #define P_WRITE(sc,r,v) \ 121 bus_space_write_4((sc)->sc_bustag, (sc)->sc_pdmahandle, (r), (v)) 122 #define P_READ(sc,r) \ 123 bus_space_read_4((sc)->sc_bustag, (sc)->sc_pdmahandle, (r)) 124 125 /* Read/write EBDMA capture registers */ 126 #define C_WRITE(sc,r,v) \ 127 bus_space_write_4((sc)->sc_bustag, (sc)->sc_cdmahandle, (r), (v)) 128 #define C_READ(sc,r) \ 129 bus_space_read_4((sc)->sc_bustag, (sc)->sc_cdmahandle, (r)) 130 131 int ce4231_match(struct device *, void *, void *); 132 void ce4231_attach(struct device *, struct device *, void *); 133 int ce4231_cintr(void *); 134 int ce4231_pintr(void *); 135 136 int ce4231_set_speed(struct ce4231_softc *, u_long *); 137 void ce4231_setup_output(struct ce4231_softc *sc); 138 139 void ce4231_write(struct ce4231_softc *, u_int8_t, u_int8_t); 140 u_int8_t ce4231_read(struct ce4231_softc *, u_int8_t); 141 142 /* Audio interface */ 143 int ce4231_open(void *, int); 144 void ce4231_close(void *); 145 int ce4231_query_encoding(void *, struct audio_encoding *); 146 int ce4231_set_params(void *, int, int, struct audio_params *, 147 struct audio_params *); 148 int ce4231_round_blocksize(void *, int); 149 int ce4231_commit_settings(void *); 150 int ce4231_halt_output(void *); 151 int ce4231_halt_input(void *); 152 int ce4231_getdev(void *, struct audio_device *); 153 int ce4231_set_port(void *, mixer_ctrl_t *); 154 int ce4231_get_port(void *, mixer_ctrl_t *); 155 int ce4231_query_devinfo(void *addr, mixer_devinfo_t *); 156 void * ce4231_alloc(void *, int, size_t, int, int); 157 void ce4231_free(void *, void *, int); 158 size_t ce4231_round_buffersize(void *, int, size_t); 159 int ce4231_get_props(void *); 160 int ce4231_trigger_output(void *, void *, void *, int, 161 void (*intr)(void *), void *arg, struct audio_params *); 162 int ce4231_trigger_input(void *, void *, void *, int, 163 void (*intr)(void *), void *arg, struct audio_params *); 164 165 struct audio_hw_if ce4231_sa_hw_if = { 166 ce4231_open, 167 ce4231_close, 168 0, 169 ce4231_query_encoding, 170 ce4231_set_params, 171 ce4231_round_blocksize, 172 ce4231_commit_settings, 173 0, 174 0, 175 0, 176 0, 177 ce4231_halt_output, 178 ce4231_halt_input, 179 0, 180 ce4231_getdev, 181 0, 182 ce4231_set_port, 183 ce4231_get_port, 184 ce4231_query_devinfo, 185 ce4231_alloc, 186 ce4231_free, 187 ce4231_round_buffersize, 188 0, 189 ce4231_get_props, 190 ce4231_trigger_output, 191 ce4231_trigger_input 192 }; 193 194 struct cfattach audioce_ca = { 195 sizeof (struct ce4231_softc), ce4231_match, ce4231_attach 196 }; 197 198 struct cfdriver audioce_cd = { 199 NULL, "audioce", DV_DULL 200 }; 201 202 struct audio_device ce4231_device = { 203 "SUNW,CS4231", 204 "b", 205 "onboard1", 206 }; 207 208 int 209 ce4231_match(parent, vcf, aux) 210 struct device *parent; 211 void *vcf, *aux; 212 { 213 struct ebus_attach_args *ea = aux; 214 215 if (!strcmp("SUNW,CS4231", ea->ea_name) || 216 !strcmp("audio", ea->ea_name)) 217 return (1); 218 return (0); 219 } 220 221 void 222 ce4231_attach(parent, self, aux) 223 struct device *parent, *self; 224 void *aux; 225 { 226 struct ebus_attach_args *ea = aux; 227 struct ce4231_softc *sc = (struct ce4231_softc *)self; 228 int node; 229 230 node = ea->ea_node; 231 232 sc->sc_last_format = 0xffffffff; 233 234 /* Pass on the bus tags */ 235 sc->sc_bustag = ea->ea_memtag; 236 sc->sc_dmatag = ea->ea_dmatag; 237 238 /* Make sure things are sane. */ 239 if (ea->ea_nintrs != 2) { 240 printf(": expected 2 interrupts, got %d\n", ea->ea_nintrs); 241 return; 242 } 243 if (ea->ea_nregs != 4) { 244 printf(": expected 4 register set, got %d\n", 245 ea->ea_nregs); 246 return; 247 } 248 249 sc->sc_cih = bus_intr_establish(sc->sc_bustag, ea->ea_intrs[0], 250 IPL_AUDIO, 0, ce4231_cintr, sc, self->dv_xname); 251 if (sc->sc_cih == NULL) { 252 printf(": couldn't establish capture interrupt\n"); 253 return; 254 } 255 sc->sc_pih = bus_intr_establish(sc->sc_bustag, ea->ea_intrs[1], 256 IPL_AUDIO, 0, ce4231_pintr, sc, self->dv_xname); 257 if (sc->sc_pih == NULL) { 258 printf(": couldn't establish play interrupt1\n"); 259 return; 260 } 261 262 /* XXX what if prom has already mapped?! */ 263 264 if (ebus_bus_map(sc->sc_bustag, 0, 265 EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 266 BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cshandle) != 0) { 267 printf(": couldn't map cs4231 registers\n"); 268 return; 269 } 270 271 if (ebus_bus_map(sc->sc_bustag, 0, 272 EBUS_PADDR_FROM_REG(&ea->ea_regs[1]), ea->ea_regs[1].size, 273 BUS_SPACE_MAP_LINEAR, 0, &sc->sc_pdmahandle) != 0) { 274 printf(": couldn't map dma1 registers\n"); 275 return; 276 } 277 278 if (ebus_bus_map(sc->sc_bustag, 0, 279 EBUS_PADDR_FROM_REG(&ea->ea_regs[2]), ea->ea_regs[2].size, 280 BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cdmahandle) != 0) { 281 printf(": couldn't map dma2 registers\n"); 282 return; 283 } 284 285 if (ebus_bus_map(sc->sc_bustag, 0, 286 EBUS_PADDR_FROM_REG(&ea->ea_regs[3]), ea->ea_regs[3].size, 287 BUS_SPACE_MAP_LINEAR, 0, &sc->sc_auxhandle) != 0) { 288 printf(": couldn't map aux registers\n"); 289 return; 290 } 291 292 printf(": nvaddrs %d\n", ea->ea_nvaddrs); 293 294 evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt); 295 296 audio_attach_mi(&ce4231_sa_hw_if, sc, &sc->sc_dev); 297 298 /* Default to speaker, unmuted, reasonable volume */ 299 sc->sc_out_port = CSPORT_SPEAKER; 300 sc->sc_mute[CSPORT_SPEAKER] = 1; 301 sc->sc_mute[CSPORT_MONITOR] = 1; 302 sc->sc_volume[CSPORT_SPEAKER].left = 192; 303 sc->sc_volume[CSPORT_SPEAKER].right = 192; 304 305 /* XXX get real burst... */ 306 sc->sc_burst = EBDCSR_BURST_8; 307 } 308 309 /* 310 * Write to one of the indexed registers of cs4231. 311 */ 312 void 313 ce4231_write(sc, r, v) 314 struct ce4231_softc *sc; 315 u_int8_t r, v; 316 { 317 CS_WRITE(sc, AD1848_IADDR, r); 318 CS_WRITE(sc, AD1848_IDATA, v); 319 } 320 321 /* 322 * Read from one of the indexed registers of cs4231. 323 */ 324 u_int8_t 325 ce4231_read(sc, r) 326 struct ce4231_softc *sc; 327 u_int8_t r; 328 { 329 CS_WRITE(sc, AD1848_IADDR, r); 330 return (CS_READ(sc, AD1848_IDATA)); 331 } 332 333 int 334 ce4231_set_speed(sc, argp) 335 struct ce4231_softc *sc; 336 u_long *argp; 337 338 { 339 /* 340 * The available speeds are in the following table. Keep the speeds in 341 * the increasing order. 342 */ 343 typedef struct { 344 int speed; 345 u_char bits; 346 } speed_struct; 347 u_long arg = *argp; 348 349 static speed_struct speed_table[] = { 350 {5510, (0 << 1) | CLOCK_XTAL2}, 351 {5510, (0 << 1) | CLOCK_XTAL2}, 352 {6620, (7 << 1) | CLOCK_XTAL2}, 353 {8000, (0 << 1) | CLOCK_XTAL1}, 354 {9600, (7 << 1) | CLOCK_XTAL1}, 355 {11025, (1 << 1) | CLOCK_XTAL2}, 356 {16000, (1 << 1) | CLOCK_XTAL1}, 357 {18900, (2 << 1) | CLOCK_XTAL2}, 358 {22050, (3 << 1) | CLOCK_XTAL2}, 359 {27420, (2 << 1) | CLOCK_XTAL1}, 360 {32000, (3 << 1) | CLOCK_XTAL1}, 361 {33075, (6 << 1) | CLOCK_XTAL2}, 362 {33075, (4 << 1) | CLOCK_XTAL2}, 363 {44100, (5 << 1) | CLOCK_XTAL2}, 364 {48000, (6 << 1) | CLOCK_XTAL1}, 365 }; 366 367 int i, n, selected = -1; 368 369 n = sizeof(speed_table) / sizeof(speed_struct); 370 371 if (arg < speed_table[0].speed) 372 selected = 0; 373 if (arg > speed_table[n - 1].speed) 374 selected = n - 1; 375 376 for (i = 1; selected == -1 && i < n; i++) { 377 if (speed_table[i].speed == arg) 378 selected = i; 379 else if (speed_table[i].speed > arg) { 380 int diff1, diff2; 381 382 diff1 = arg - speed_table[i - 1].speed; 383 diff2 = speed_table[i].speed - arg; 384 if (diff1 < diff2) 385 selected = i - 1; 386 else 387 selected = i; 388 } 389 } 390 391 if (selected == -1) 392 selected = 3; 393 394 sc->sc_speed_bits = speed_table[selected].bits; 395 sc->sc_need_commit = 1; 396 *argp = speed_table[selected].speed; 397 398 return (0); 399 } 400 401 /* 402 * Audio interface functions 403 */ 404 int 405 ce4231_open(addr, flags) 406 void *addr; 407 int flags; 408 { 409 struct ce4231_softc *sc = addr; 410 int tries; 411 412 if (sc->sc_open) 413 return (EBUSY); 414 sc->sc_open = 1; 415 sc->sc_locked = 0; 416 sc->sc_rintr = 0; 417 sc->sc_rarg = 0; 418 sc->sc_pintr = 0; 419 sc->sc_parg = 0; 420 421 P_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET); 422 C_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET); 423 P_WRITE(sc, EBDMA_DCSR, sc->sc_burst); 424 C_WRITE(sc, EBDMA_DCSR, sc->sc_burst); 425 426 DELAY(20); 427 428 for (tries = CS_TIMEOUT; 429 tries && CS_READ(sc, AD1848_IADDR) == SP_IN_INIT; tries--) 430 DELAY(10); 431 if (tries == 0) 432 printf("%s: timeout waiting for reset\n", sc->sc_dev.dv_xname); 433 434 /* Turn on cs4231 mode */ 435 ce4231_write(sc, SP_MISC_INFO, 436 ce4231_read(sc, SP_MISC_INFO) | MODE2); 437 438 ce4231_setup_output(sc); 439 440 ce4231_write(sc, SP_PIN_CONTROL, 441 ce4231_read(sc, SP_PIN_CONTROL) | INTERRUPT_ENABLE); 442 443 return (0); 444 } 445 446 void 447 ce4231_setup_output(sc) 448 struct ce4231_softc *sc; 449 { 450 u_int8_t pc, mi, rm, lm; 451 452 pc = ce4231_read(sc, SP_PIN_CONTROL) | CS_PC_HDPHMUTE | CS_PC_LINEMUTE; 453 454 mi = ce4231_read(sc, CS_MONO_IO_CONTROL) | MONO_OUTPUT_MUTE; 455 456 lm = ce4231_read(sc, SP_LEFT_OUTPUT_CONTROL); 457 lm &= ~OUTPUT_ATTEN_BITS; 458 lm |= ((~(sc->sc_volume[CSPORT_SPEAKER].left >> 2)) & 459 OUTPUT_ATTEN_BITS) | OUTPUT_MUTE; 460 461 rm = ce4231_read(sc, SP_RIGHT_OUTPUT_CONTROL); 462 rm &= ~OUTPUT_ATTEN_BITS; 463 rm |= ((~(sc->sc_volume[CSPORT_SPEAKER].right >> 2)) & 464 OUTPUT_ATTEN_BITS) | OUTPUT_MUTE; 465 466 if (sc->sc_mute[CSPORT_MONITOR]) { 467 lm &= ~OUTPUT_MUTE; 468 rm &= ~OUTPUT_MUTE; 469 } 470 471 switch (sc->sc_out_port) { 472 case CSPORT_HEADPHONE: 473 if (sc->sc_mute[CSPORT_SPEAKER]) 474 pc &= ~CS_PC_HDPHMUTE; 475 break; 476 case CSPORT_SPEAKER: 477 if (sc->sc_mute[CSPORT_SPEAKER]) 478 mi &= ~MONO_OUTPUT_MUTE; 479 break; 480 case CSPORT_LINEOUT: 481 if (sc->sc_mute[CSPORT_SPEAKER]) 482 pc &= ~CS_PC_LINEMUTE; 483 break; 484 } 485 486 ce4231_write(sc, SP_LEFT_OUTPUT_CONTROL, lm); 487 ce4231_write(sc, SP_RIGHT_OUTPUT_CONTROL, rm); 488 ce4231_write(sc, SP_PIN_CONTROL, pc); 489 ce4231_write(sc, CS_MONO_IO_CONTROL, mi); 490 } 491 492 void 493 ce4231_close(addr) 494 void *addr; 495 { 496 struct ce4231_softc *sc = addr; 497 498 ce4231_halt_input(sc); 499 ce4231_halt_output(sc); 500 ce4231_write(sc, SP_PIN_CONTROL, 501 ce4231_read(sc, SP_PIN_CONTROL) & (~INTERRUPT_ENABLE)); 502 sc->sc_open = 0; 503 } 504 505 int 506 ce4231_query_encoding(addr, fp) 507 void *addr; 508 struct audio_encoding *fp; 509 { 510 int err = 0; 511 512 switch (fp->index) { 513 case 0: 514 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 515 fp->encoding = AUDIO_ENCODING_ULAW; 516 fp->precision = 8; 517 fp->flags = 0; 518 break; 519 case 1: 520 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 521 fp->encoding = AUDIO_ENCODING_ALAW; 522 fp->precision = 8; 523 fp->flags = 0; 524 break; 525 case 2: 526 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 527 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 528 fp->precision = 16; 529 fp->flags = 0; 530 break; 531 case 3: 532 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 533 fp->encoding = AUDIO_ENCODING_ULINEAR; 534 fp->precision = 8; 535 fp->flags = 0; 536 break; 537 case 4: 538 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 539 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 540 fp->precision = 16; 541 fp->flags = 0; 542 break; 543 case 5: 544 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 545 fp->encoding = AUDIO_ENCODING_SLINEAR; 546 fp->precision = 8; 547 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 548 break; 549 case 6: 550 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 551 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 552 fp->precision = 16; 553 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 554 break; 555 case 7: 556 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 557 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 558 fp->precision = 16; 559 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 560 break; 561 case 8: 562 strlcpy(fp->name, AudioEadpcm, sizeof fp->name); 563 fp->encoding = AUDIO_ENCODING_ADPCM; 564 fp->precision = 8; 565 fp->flags = 0; 566 break; 567 default: 568 err = EINVAL; 569 } 570 return (err); 571 } 572 573 int 574 ce4231_set_params(addr, setmode, usemode, p, r) 575 void *addr; 576 int setmode, usemode; 577 struct audio_params *p, *r; 578 { 579 struct ce4231_softc *sc = (struct ce4231_softc *)addr; 580 int err, bits, enc = p->encoding; 581 void (*pswcode)(void *, u_char *, int cnt) = NULL; 582 void (*rswcode)(void *, u_char *, int cnt) = NULL; 583 584 switch (enc) { 585 case AUDIO_ENCODING_ULAW: 586 if (p->precision != 8) 587 return (EINVAL); 588 bits = FMT_ULAW >> 5; 589 break; 590 case AUDIO_ENCODING_ALAW: 591 if (p->precision != 8) 592 return (EINVAL); 593 bits = FMT_ALAW >> 5; 594 break; 595 case AUDIO_ENCODING_SLINEAR_LE: 596 if (p->precision == 8) { 597 bits = FMT_PCM8 >> 5; 598 pswcode = rswcode = change_sign8; 599 } else if (p->precision == 16) 600 bits = FMT_TWOS_COMP >> 5; 601 else 602 return (EINVAL); 603 break; 604 case AUDIO_ENCODING_ULINEAR: 605 if (p->precision != 8) 606 return (EINVAL); 607 bits = FMT_PCM8 >> 5; 608 break; 609 case AUDIO_ENCODING_SLINEAR_BE: 610 if (p->precision == 8) { 611 bits = FMT_PCM8 >> 5; 612 pswcode = rswcode = change_sign8; 613 } else if (p->precision == 16) 614 bits = FMT_TWOS_COMP_BE >> 5; 615 else 616 return (EINVAL); 617 break; 618 case AUDIO_ENCODING_SLINEAR: 619 if (p->precision != 8) 620 return (EINVAL); 621 bits = FMT_PCM8 >> 5; 622 pswcode = rswcode = change_sign8; 623 break; 624 case AUDIO_ENCODING_ULINEAR_LE: 625 if (p->precision == 8) 626 bits = FMT_PCM8 >> 5; 627 else if (p->precision == 16) { 628 bits = FMT_TWOS_COMP >> 5; 629 pswcode = rswcode = change_sign16_le; 630 } else 631 return (EINVAL); 632 break; 633 case AUDIO_ENCODING_ULINEAR_BE: 634 if (p->precision == 8) 635 bits = FMT_PCM8 >> 5; 636 else if (p->precision == 16) { 637 bits = FMT_TWOS_COMP_BE >> 5; 638 pswcode = rswcode = change_sign16_be; 639 } else 640 return (EINVAL); 641 break; 642 case AUDIO_ENCODING_ADPCM: 643 if (p->precision != 8) 644 return (EINVAL); 645 bits = FMT_ADPCM >> 5; 646 break; 647 default: 648 return (EINVAL); 649 } 650 651 if (p->channels != 1 && p->channels != 2) 652 return (EINVAL); 653 654 err = ce4231_set_speed(sc, &p->sample_rate); 655 if (err) 656 return (err); 657 658 p->sw_code = pswcode; 659 r->sw_code = rswcode; 660 661 sc->sc_format_bits = bits; 662 sc->sc_channels = p->channels; 663 sc->sc_precision = p->precision; 664 sc->sc_need_commit = 1; 665 return (0); 666 } 667 668 int 669 ce4231_round_blocksize(addr, blk) 670 void *addr; 671 int blk; 672 { 673 return (blk & (-4)); 674 } 675 676 int 677 ce4231_commit_settings(addr) 678 void *addr; 679 { 680 struct ce4231_softc *sc = (struct ce4231_softc *)addr; 681 int s, tries; 682 u_int8_t r, fs; 683 684 if (sc->sc_need_commit == 0) 685 return (0); 686 687 fs = sc->sc_speed_bits | (sc->sc_format_bits << 5); 688 if (sc->sc_channels == 2) 689 fs |= FMT_STEREO; 690 691 if (sc->sc_last_format == fs) { 692 sc->sc_need_commit = 0; 693 return (0); 694 } 695 696 s = splaudio(); 697 698 r = ce4231_read(sc, SP_INTERFACE_CONFIG) | AUTO_CAL_ENABLE; 699 CS_WRITE(sc, AD1848_IADDR, MODE_CHANGE_ENABLE); 700 CS_WRITE(sc, AD1848_IADDR, MODE_CHANGE_ENABLE | SP_INTERFACE_CONFIG); 701 CS_WRITE(sc, AD1848_IDATA, r); 702 703 CS_WRITE(sc, AD1848_IADDR, MODE_CHANGE_ENABLE | SP_CLOCK_DATA_FORMAT); 704 CS_WRITE(sc, AD1848_IDATA, fs); 705 CS_READ(sc, AD1848_IDATA); 706 CS_READ(sc, AD1848_IDATA); 707 tries = CS_TIMEOUT; 708 for (tries = CS_TIMEOUT; 709 tries && CS_READ(sc, AD1848_IADDR) == SP_IN_INIT; tries--) 710 DELAY(10); 711 if (tries == 0) 712 printf("%s: timeout committing fspb\n", sc->sc_dev.dv_xname); 713 714 CS_WRITE(sc, AD1848_IADDR, MODE_CHANGE_ENABLE | CS_REC_FORMAT); 715 CS_WRITE(sc, AD1848_IDATA, fs); 716 CS_READ(sc, AD1848_IDATA); 717 CS_READ(sc, AD1848_IDATA); 718 for (tries = CS_TIMEOUT; 719 tries && CS_READ(sc, AD1848_IADDR) == SP_IN_INIT; tries--) 720 DELAY(10); 721 if (tries == 0) 722 printf("%s: timeout committing cdf\n", sc->sc_dev.dv_xname); 723 724 CS_WRITE(sc, AD1848_IADDR, 0); 725 for (tries = CS_TIMEOUT; 726 tries && CS_READ(sc, AD1848_IADDR) == SP_IN_INIT; tries--) 727 DELAY(10); 728 if (tries == 0) 729 printf("%s: timeout waiting for !mce\n", sc->sc_dev.dv_xname); 730 731 CS_WRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT); 732 for (tries = CS_TIMEOUT; 733 tries && CS_READ(sc, AD1848_IDATA) & AUTO_CAL_IN_PROG; tries--) 734 DELAY(10); 735 if (tries == 0) 736 printf("%s: timeout waiting for autocalibration\n", 737 sc->sc_dev.dv_xname); 738 739 splx(s); 740 741 sc->sc_need_commit = 0; 742 return (0); 743 } 744 745 int 746 ce4231_halt_output(addr) 747 void *addr; 748 { 749 struct ce4231_softc *sc = (struct ce4231_softc *)addr; 750 751 P_WRITE(sc, EBDMA_DCSR, 752 P_READ(sc, EBDMA_DCSR) & ~EBDCSR_DMAEN); 753 ce4231_write(sc, SP_INTERFACE_CONFIG, 754 ce4231_read(sc, SP_INTERFACE_CONFIG) & (~PLAYBACK_ENABLE)); 755 sc->sc_locked = 0; 756 return (0); 757 } 758 759 int 760 ce4231_halt_input(addr) 761 void *addr; 762 { 763 struct ce4231_softc *sc = (struct ce4231_softc *)addr; 764 765 C_WRITE(sc, EBDMA_DCSR, 766 C_READ(sc, EBDMA_DCSR) & ~EBDCSR_DMAEN); 767 ce4231_write(sc, SP_INTERFACE_CONFIG, 768 ce4231_read(sc, SP_INTERFACE_CONFIG) & (~CAPTURE_ENABLE)); 769 sc->sc_locked = 0; 770 return (0); 771 } 772 773 int 774 ce4231_getdev(addr, retp) 775 void *addr; 776 struct audio_device *retp; 777 { 778 *retp = ce4231_device; 779 return (0); 780 } 781 782 int 783 ce4231_set_port(addr, cp) 784 void *addr; 785 mixer_ctrl_t *cp; 786 { 787 struct ce4231_softc *sc = (struct ce4231_softc *)addr; 788 int error = EINVAL; 789 790 DPRINTF(("ce4231_set_port: port=%d type=%d\n", cp->dev, cp->type)); 791 792 switch (cp->dev) { 793 case CSAUDIO_DAC_LVL: 794 if (cp->type != AUDIO_MIXER_VALUE) 795 break; 796 if (cp->un.value.num_channels == 1) 797 ce4231_write(sc, SP_LEFT_AUX1_CONTROL, 798 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & 799 LINE_INPUT_ATTEN_BITS); 800 else if (cp->un.value.num_channels == 2) { 801 ce4231_write(sc, SP_LEFT_AUX1_CONTROL, 802 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] & 803 LINE_INPUT_ATTEN_BITS); 804 ce4231_write(sc, SP_RIGHT_AUX1_CONTROL, 805 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] & 806 LINE_INPUT_ATTEN_BITS); 807 } else 808 break; 809 error = 0; 810 break; 811 case CSAUDIO_LINE_IN_LVL: 812 if (cp->type != AUDIO_MIXER_VALUE) 813 break; 814 if (cp->un.value.num_channels == 1) 815 ce4231_write(sc, CS_LEFT_LINE_CONTROL, 816 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & 817 AUX_INPUT_ATTEN_BITS); 818 else if (cp->un.value.num_channels == 2) { 819 ce4231_write(sc, CS_LEFT_LINE_CONTROL, 820 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] & 821 AUX_INPUT_ATTEN_BITS); 822 ce4231_write(sc, CS_RIGHT_LINE_CONTROL, 823 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] & 824 AUX_INPUT_ATTEN_BITS); 825 } else 826 break; 827 error = 0; 828 break; 829 case CSAUDIO_MIC_LVL: 830 if (cp->type != AUDIO_MIXER_VALUE) 831 break; 832 if (cp->un.value.num_channels == 1) { 833 #if 0 834 ce4231_write(sc, CS_MONO_IO_CONTROL, 835 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & 836 MONO_INPUT_ATTEN_BITS); 837 #endif 838 } else 839 break; 840 error = 0; 841 break; 842 case CSAUDIO_CD_LVL: 843 if (cp->type != AUDIO_MIXER_VALUE) 844 break; 845 if (cp->un.value.num_channels == 1) { 846 ce4231_write(sc, SP_LEFT_AUX2_CONTROL, 847 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & 848 LINE_INPUT_ATTEN_BITS); 849 } else if (cp->un.value.num_channels == 2) { 850 ce4231_write(sc, SP_LEFT_AUX2_CONTROL, 851 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] & 852 LINE_INPUT_ATTEN_BITS); 853 ce4231_write(sc, SP_RIGHT_AUX2_CONTROL, 854 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] & 855 LINE_INPUT_ATTEN_BITS); 856 } else 857 break; 858 error = 0; 859 break; 860 case CSAUDIO_MONITOR_LVL: 861 if (cp->type != AUDIO_MIXER_VALUE) 862 break; 863 if (cp->un.value.num_channels == 1) 864 ce4231_write(sc, SP_DIGITAL_MIX, 865 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] << 2); 866 else 867 break; 868 error = 0; 869 break; 870 case CSAUDIO_OUTPUT_LVL: 871 if (cp->type != AUDIO_MIXER_VALUE) 872 break; 873 if (cp->un.value.num_channels == 1) { 874 sc->sc_volume[CSPORT_SPEAKER].left = 875 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 876 sc->sc_volume[CSPORT_SPEAKER].right = 877 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 878 } 879 else if (cp->un.value.num_channels == 2) { 880 sc->sc_volume[CSPORT_SPEAKER].left = 881 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 882 sc->sc_volume[CSPORT_SPEAKER].right = 883 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 884 } 885 else 886 break; 887 888 ce4231_setup_output(sc); 889 error = 0; 890 break; 891 case CSAUDIO_OUTPUT: 892 if (cp->type != AUDIO_MIXER_ENUM) 893 break; 894 if (cp->un.ord != CSPORT_LINEOUT && 895 cp->un.ord != CSPORT_SPEAKER && 896 cp->un.ord != CSPORT_HEADPHONE) 897 return (EINVAL); 898 sc->sc_out_port = cp->un.ord; 899 ce4231_setup_output(sc); 900 error = 0; 901 break; 902 case CSAUDIO_LINE_IN_MUTE: 903 if (cp->type != AUDIO_MIXER_ENUM) 904 break; 905 sc->sc_mute[CSPORT_LINEIN] = cp->un.ord ? 1 : 0; 906 error = 0; 907 break; 908 case CSAUDIO_DAC_MUTE: 909 if (cp->type != AUDIO_MIXER_ENUM) 910 break; 911 sc->sc_mute[CSPORT_AUX1] = cp->un.ord ? 1 : 0; 912 error = 0; 913 break; 914 case CSAUDIO_CD_MUTE: 915 if (cp->type != AUDIO_MIXER_ENUM) 916 break; 917 sc->sc_mute[CSPORT_AUX2] = cp->un.ord ? 1 : 0; 918 error = 0; 919 break; 920 case CSAUDIO_MIC_MUTE: 921 if (cp->type != AUDIO_MIXER_ENUM) 922 break; 923 sc->sc_mute[CSPORT_MONO] = cp->un.ord ? 1 : 0; 924 error = 0; 925 break; 926 case CSAUDIO_MONITOR_MUTE: 927 if (cp->type != AUDIO_MIXER_ENUM) 928 break; 929 sc->sc_mute[CSPORT_MONITOR] = cp->un.ord ? 1 : 0; 930 error = 0; 931 break; 932 case CSAUDIO_OUTPUT_MUTE: 933 if (cp->type != AUDIO_MIXER_ENUM) 934 break; 935 sc->sc_mute[CSPORT_SPEAKER] = cp->un.ord ? 1 : 0; 936 ce4231_setup_output(sc); 937 error = 0; 938 break; 939 case CSAUDIO_REC_LVL: 940 if (cp->type != AUDIO_MIXER_VALUE) 941 break; 942 break; 943 case CSAUDIO_RECORD_SOURCE: 944 if (cp->type != AUDIO_MIXER_ENUM) 945 break; 946 break; 947 } 948 949 return (error); 950 } 951 952 int 953 ce4231_get_port(addr, cp) 954 void *addr; 955 mixer_ctrl_t *cp; 956 { 957 struct ce4231_softc *sc = (struct ce4231_softc *)addr; 958 int error = EINVAL; 959 960 DPRINTF(("ce4231_get_port: port=%d type=%d\n", cp->dev, cp->type)); 961 962 switch (cp->dev) { 963 case CSAUDIO_DAC_LVL: 964 if (cp->type != AUDIO_MIXER_VALUE) 965 break; 966 if (cp->un.value.num_channels == 1) 967 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]= 968 ce4231_read(sc, SP_LEFT_AUX1_CONTROL) & 969 LINE_INPUT_ATTEN_BITS; 970 else if (cp->un.value.num_channels == 2) { 971 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 972 ce4231_read(sc, SP_LEFT_AUX1_CONTROL) & 973 LINE_INPUT_ATTEN_BITS; 974 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 975 ce4231_read(sc, SP_RIGHT_AUX1_CONTROL) & 976 LINE_INPUT_ATTEN_BITS; 977 } else 978 break; 979 error = 0; 980 break; 981 case CSAUDIO_LINE_IN_LVL: 982 if (cp->type != AUDIO_MIXER_VALUE) 983 break; 984 if (cp->un.value.num_channels == 1) 985 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 986 ce4231_read(sc, CS_LEFT_LINE_CONTROL) & AUX_INPUT_ATTEN_BITS; 987 else if (cp->un.value.num_channels == 2) { 988 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 989 ce4231_read(sc, CS_LEFT_LINE_CONTROL) & AUX_INPUT_ATTEN_BITS; 990 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 991 ce4231_read(sc, CS_RIGHT_LINE_CONTROL) & AUX_INPUT_ATTEN_BITS; 992 } else 993 break; 994 error = 0; 995 break; 996 case CSAUDIO_MIC_LVL: 997 if (cp->type != AUDIO_MIXER_VALUE) 998 break; 999 if (cp->un.value.num_channels == 1) { 1000 #if 0 1001 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1002 ce4231_read(sc, CS_MONO_IO_CONTROL) & 1003 MONO_INPUT_ATTEN_BITS; 1004 #endif 1005 } else 1006 break; 1007 error = 0; 1008 break; 1009 case CSAUDIO_CD_LVL: 1010 if (cp->type != AUDIO_MIXER_VALUE) 1011 break; 1012 if (cp->un.value.num_channels == 1) 1013 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1014 ce4231_read(sc, SP_LEFT_AUX2_CONTROL) & 1015 LINE_INPUT_ATTEN_BITS; 1016 else if (cp->un.value.num_channels == 2) { 1017 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1018 ce4231_read(sc, SP_LEFT_AUX2_CONTROL) & 1019 LINE_INPUT_ATTEN_BITS; 1020 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1021 ce4231_read(sc, SP_RIGHT_AUX2_CONTROL) & 1022 LINE_INPUT_ATTEN_BITS; 1023 } 1024 else 1025 break; 1026 error = 0; 1027 break; 1028 case CSAUDIO_MONITOR_LVL: 1029 if (cp->type != AUDIO_MIXER_VALUE) 1030 break; 1031 if (cp->un.value.num_channels != 1) 1032 break; 1033 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1034 ce4231_read(sc, SP_DIGITAL_MIX) >> 2; 1035 error = 0; 1036 break; 1037 case CSAUDIO_OUTPUT_LVL: 1038 if (cp->type != AUDIO_MIXER_VALUE) 1039 break; 1040 if (cp->un.value.num_channels == 1) 1041 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1042 sc->sc_volume[CSPORT_SPEAKER].left; 1043 else if (cp->un.value.num_channels == 2) { 1044 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1045 sc->sc_volume[CSPORT_SPEAKER].left; 1046 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1047 sc->sc_volume[CSPORT_SPEAKER].right; 1048 } 1049 else 1050 break; 1051 error = 0; 1052 break; 1053 case CSAUDIO_LINE_IN_MUTE: 1054 if (cp->type != AUDIO_MIXER_ENUM) 1055 break; 1056 cp->un.ord = sc->sc_mute[CSPORT_LINEIN] ? 1 : 0; 1057 error = 0; 1058 break; 1059 case CSAUDIO_DAC_MUTE: 1060 if (cp->type != AUDIO_MIXER_ENUM) 1061 break; 1062 cp->un.ord = sc->sc_mute[CSPORT_AUX1] ? 1 : 0; 1063 error = 0; 1064 break; 1065 case CSAUDIO_CD_MUTE: 1066 if (cp->type != AUDIO_MIXER_ENUM) 1067 break; 1068 cp->un.ord = sc->sc_mute[CSPORT_AUX2] ? 1 : 0; 1069 error = 0; 1070 break; 1071 case CSAUDIO_MIC_MUTE: 1072 if (cp->type != AUDIO_MIXER_ENUM) 1073 break; 1074 cp->un.ord = sc->sc_mute[CSPORT_MONO] ? 1 : 0; 1075 error = 0; 1076 break; 1077 case CSAUDIO_MONITOR_MUTE: 1078 if (cp->type != AUDIO_MIXER_ENUM) 1079 break; 1080 cp->un.ord = sc->sc_mute[CSPORT_MONITOR] ? 1 : 0; 1081 error = 0; 1082 break; 1083 case CSAUDIO_OUTPUT_MUTE: 1084 if (cp->type != AUDIO_MIXER_ENUM) 1085 break; 1086 cp->un.ord = sc->sc_mute[CSPORT_SPEAKER] ? 1 : 0; 1087 error = 0; 1088 break; 1089 case CSAUDIO_REC_LVL: 1090 if (cp->type != AUDIO_MIXER_VALUE) 1091 break; 1092 if (cp->un.value.num_channels == 1) { 1093 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1094 AUDIO_MIN_GAIN; 1095 } else if (cp->un.value.num_channels == 2) { 1096 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1097 AUDIO_MIN_GAIN; 1098 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1099 AUDIO_MIN_GAIN; 1100 } else 1101 break; 1102 error = 0; 1103 break; 1104 case CSAUDIO_RECORD_SOURCE: 1105 if (cp->type != AUDIO_MIXER_ENUM) 1106 break; 1107 cp->un.ord = MIC_IN_PORT; 1108 error = 0; 1109 break; 1110 case CSAUDIO_OUTPUT: 1111 if (cp->type != AUDIO_MIXER_ENUM) 1112 break; 1113 cp->un.ord = sc->sc_out_port; 1114 error = 0; 1115 break; 1116 } 1117 return (error); 1118 } 1119 1120 int 1121 ce4231_query_devinfo(addr, dip) 1122 void *addr; 1123 mixer_devinfo_t *dip; 1124 { 1125 int err = 0; 1126 1127 switch (dip->index) { 1128 case CSAUDIO_MIC_LVL: /* mono/microphone mixer */ 1129 dip->type = AUDIO_MIXER_VALUE; 1130 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1131 dip->prev = AUDIO_MIXER_LAST; 1132 dip->next = CSAUDIO_MIC_MUTE; 1133 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 1134 dip->un.v.num_channels = 1; 1135 strlcpy(dip->un.v.units.name, AudioNvolume, 1136 sizeof dip->un.v.units.name); 1137 break; 1138 case CSAUDIO_DAC_LVL: /* dacout */ 1139 dip->type = AUDIO_MIXER_VALUE; 1140 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1141 dip->prev = AUDIO_MIXER_LAST; 1142 dip->next = CSAUDIO_DAC_MUTE; 1143 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 1144 dip->un.v.num_channels = 2; 1145 strlcpy(dip->un.v.units.name, AudioNvolume, 1146 sizeof dip->un.v.units.name); 1147 break; 1148 case CSAUDIO_LINE_IN_LVL: /* line */ 1149 dip->type = AUDIO_MIXER_VALUE; 1150 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1151 dip->prev = AUDIO_MIXER_LAST; 1152 dip->next = CSAUDIO_LINE_IN_MUTE; 1153 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 1154 dip->un.v.num_channels = 2; 1155 strlcpy(dip->un.v.units.name, AudioNvolume, 1156 sizeof dip->un.v.units.name); 1157 break; 1158 case CSAUDIO_CD_LVL: /* cd */ 1159 dip->type = AUDIO_MIXER_VALUE; 1160 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1161 dip->prev = AUDIO_MIXER_LAST; 1162 dip->next = CSAUDIO_CD_MUTE; 1163 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 1164 dip->un.v.num_channels = 2; 1165 strlcpy(dip->un.v.units.name, AudioNvolume, 1166 sizeof dip->un.v.units.name); 1167 break; 1168 case CSAUDIO_MONITOR_LVL: /* monitor level */ 1169 dip->type = AUDIO_MIXER_VALUE; 1170 dip->mixer_class = CSAUDIO_MONITOR_CLASS; 1171 dip->prev = AUDIO_MIXER_LAST; 1172 dip->next = CSAUDIO_MONITOR_MUTE; 1173 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 1174 dip->un.v.num_channels = 1; 1175 strlcpy(dip->un.v.units.name, AudioNvolume, 1176 sizeof dip->un.v.units.name); 1177 break; 1178 case CSAUDIO_OUTPUT_LVL: 1179 dip->type = AUDIO_MIXER_VALUE; 1180 dip->mixer_class = CSAUDIO_OUTPUT_CLASS; 1181 dip->prev = AUDIO_MIXER_LAST; 1182 dip->next = CSAUDIO_OUTPUT_MUTE; 1183 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 1184 dip->un.v.num_channels = 2; 1185 strlcpy(dip->un.v.units.name, AudioNvolume, 1186 sizeof dip->un.v.units.name); 1187 break; 1188 case CSAUDIO_LINE_IN_MUTE: 1189 dip->type = AUDIO_MIXER_ENUM; 1190 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1191 dip->prev = CSAUDIO_LINE_IN_LVL; 1192 dip->next = AUDIO_MIXER_LAST; 1193 goto mute; 1194 case CSAUDIO_DAC_MUTE: 1195 dip->type = AUDIO_MIXER_ENUM; 1196 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1197 dip->prev = CSAUDIO_DAC_LVL; 1198 dip->next = AUDIO_MIXER_LAST; 1199 goto mute; 1200 case CSAUDIO_CD_MUTE: 1201 dip->type = AUDIO_MIXER_ENUM; 1202 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1203 dip->prev = CSAUDIO_CD_LVL; 1204 dip->next = AUDIO_MIXER_LAST; 1205 goto mute; 1206 case CSAUDIO_MIC_MUTE: 1207 dip->type = AUDIO_MIXER_ENUM; 1208 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1209 dip->prev = CSAUDIO_MIC_LVL; 1210 dip->next = AUDIO_MIXER_LAST; 1211 goto mute; 1212 case CSAUDIO_MONITOR_MUTE: 1213 dip->type = AUDIO_MIXER_ENUM; 1214 dip->mixer_class = CSAUDIO_OUTPUT_CLASS; 1215 dip->prev = CSAUDIO_MONITOR_LVL; 1216 dip->next = AUDIO_MIXER_LAST; 1217 goto mute; 1218 case CSAUDIO_OUTPUT_MUTE: 1219 dip->type = AUDIO_MIXER_ENUM; 1220 dip->mixer_class = CSAUDIO_OUTPUT_CLASS; 1221 dip->prev = CSAUDIO_OUTPUT_LVL; 1222 dip->next = AUDIO_MIXER_LAST; 1223 goto mute; 1224 1225 mute: 1226 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 1227 dip->un.e.num_mem = 2; 1228 strlcpy(dip->un.e.member[0].label.name, AudioNon, 1229 sizeof dip->un.e.member[0].label.name); 1230 dip->un.e.member[0].ord = 0; 1231 strlcpy(dip->un.e.member[1].label.name, AudioNoff, 1232 sizeof dip->un.e.member[1].label.name); 1233 dip->un.e.member[1].ord = 1; 1234 break; 1235 case CSAUDIO_REC_LVL: /* record level */ 1236 dip->type = AUDIO_MIXER_VALUE; 1237 dip->mixer_class = CSAUDIO_RECORD_CLASS; 1238 dip->prev = AUDIO_MIXER_LAST; 1239 dip->next = CSAUDIO_RECORD_SOURCE; 1240 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name); 1241 dip->un.v.num_channels = 2; 1242 strlcpy(dip->un.v.units.name, AudioNvolume, 1243 sizeof dip->un.v.units.name); 1244 break; 1245 case CSAUDIO_RECORD_SOURCE: 1246 dip->type = AUDIO_MIXER_ENUM; 1247 dip->mixer_class = CSAUDIO_RECORD_CLASS; 1248 dip->prev = CSAUDIO_REC_LVL; 1249 dip->next = AUDIO_MIXER_LAST; 1250 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 1251 dip->un.e.num_mem = 3; 1252 strlcpy(dip->un.e.member[0].label.name, AudioNcd, 1253 sizeof dip->un.e.member[0].label.name); 1254 dip->un.e.member[0].ord = DAC_IN_PORT; 1255 strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone, 1256 sizeof dip->un.e.member[1].label.name); 1257 dip->un.e.member[1].ord = MIC_IN_PORT; 1258 strlcpy(dip->un.e.member[2].label.name, AudioNdac, 1259 sizeof dip->un.e.member[2].label.name); 1260 dip->un.e.member[2].ord = AUX1_IN_PORT; 1261 strlcpy(dip->un.e.member[3].label.name, AudioNline, 1262 sizeof dip->un.e.member[3].label.name); 1263 dip->un.e.member[3].ord = LINE_IN_PORT; 1264 break; 1265 case CSAUDIO_OUTPUT: 1266 dip->type = AUDIO_MIXER_ENUM; 1267 dip->mixer_class = CSAUDIO_MONITOR_CLASS; 1268 dip->prev = dip->next = AUDIO_MIXER_LAST; 1269 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 1270 dip->un.e.num_mem = 3; 1271 strlcpy(dip->un.e.member[0].label.name, AudioNspeaker, 1272 sizeof dip->un.e.member[0].label.name); 1273 dip->un.e.member[0].ord = CSPORT_SPEAKER; 1274 strlcpy(dip->un.e.member[1].label.name, AudioNline, 1275 sizeof dip->un.e.member[1].label.name); 1276 dip->un.e.member[1].ord = CSPORT_LINEOUT; 1277 strlcpy(dip->un.e.member[2].label.name, AudioNheadphone, 1278 sizeof dip->un.e.member[2].label.name); 1279 dip->un.e.member[2].ord = CSPORT_HEADPHONE; 1280 break; 1281 case CSAUDIO_INPUT_CLASS: /* input class descriptor */ 1282 dip->type = AUDIO_MIXER_CLASS; 1283 dip->mixer_class = CSAUDIO_INPUT_CLASS; 1284 dip->prev = AUDIO_MIXER_LAST; 1285 dip->next = AUDIO_MIXER_LAST; 1286 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 1287 break; 1288 case CSAUDIO_OUTPUT_CLASS: /* output class descriptor */ 1289 dip->type = AUDIO_MIXER_CLASS; 1290 dip->mixer_class = CSAUDIO_OUTPUT_CLASS; 1291 dip->prev = AUDIO_MIXER_LAST; 1292 dip->next = AUDIO_MIXER_LAST; 1293 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 1294 break; 1295 case CSAUDIO_MONITOR_CLASS: /* monitor class descriptor */ 1296 dip->type = AUDIO_MIXER_CLASS; 1297 dip->mixer_class = CSAUDIO_MONITOR_CLASS; 1298 dip->prev = AUDIO_MIXER_LAST; 1299 dip->next = AUDIO_MIXER_LAST; 1300 strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name); 1301 break; 1302 case CSAUDIO_RECORD_CLASS: /* record class descriptor */ 1303 dip->type = AUDIO_MIXER_CLASS; 1304 dip->mixer_class = CSAUDIO_RECORD_CLASS; 1305 dip->prev = AUDIO_MIXER_LAST; 1306 dip->next = AUDIO_MIXER_LAST; 1307 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 1308 break; 1309 default: 1310 err = ENXIO; 1311 } 1312 1313 return (err); 1314 } 1315 1316 size_t 1317 ce4231_round_buffersize(addr, direction, size) 1318 void *addr; 1319 int direction; 1320 size_t size; 1321 { 1322 return (size); 1323 } 1324 1325 int 1326 ce4231_get_props(addr) 1327 void *addr; 1328 { 1329 return (AUDIO_PROP_FULLDUPLEX); 1330 } 1331 1332 /* 1333 * Hardware interrupt handler 1334 */ 1335 int 1336 ce4231_cintr(v) 1337 void *v; 1338 { 1339 return (0); 1340 } 1341 1342 int 1343 ce4231_pintr(v) 1344 void *v; 1345 { 1346 struct ce4231_softc *sc = (struct ce4231_softc *)v; 1347 u_int32_t csr; 1348 u_int8_t reg, status; 1349 struct cs_dma *p; 1350 int r = 0; 1351 1352 csr = P_READ(sc, EBDMA_DCSR); 1353 status = CS_READ(sc, AD1848_STATUS); 1354 if (status & (INTERRUPT_STATUS | SAMPLE_ERROR)) { 1355 reg = ce4231_read(sc, CS_IRQ_STATUS); 1356 if (reg & CS_AFS_PI) { 1357 ce4231_write(sc, SP_LOWER_BASE_COUNT, 0xff); 1358 ce4231_write(sc, SP_UPPER_BASE_COUNT, 0xff); 1359 } 1360 CS_WRITE(sc, AD1848_STATUS, 0); 1361 } 1362 1363 P_WRITE(sc, EBDMA_DCSR, csr); 1364 1365 if (csr & EBDCSR_INT) 1366 r = 1; 1367 1368 if ((csr & EBDCSR_TC) || ((csr & EBDCSR_A_LOADED) == 0)) { 1369 u_long nextaddr, togo; 1370 1371 p = sc->sc_nowplaying; 1372 togo = sc->sc_playsegsz - sc->sc_playcnt; 1373 if (togo == 0) { 1374 nextaddr = (u_int32_t)p->dmamap->dm_segs[0].ds_addr; 1375 sc->sc_playcnt = togo = sc->sc_blksz; 1376 } else { 1377 nextaddr = sc->sc_lastaddr; 1378 if (togo > sc->sc_blksz) 1379 togo = sc->sc_blksz; 1380 sc->sc_playcnt += togo; 1381 } 1382 1383 P_WRITE(sc, EBDMA_DCNT, togo); 1384 P_WRITE(sc, EBDMA_DADDR, nextaddr); 1385 sc->sc_lastaddr = nextaddr + togo; 1386 1387 if (sc->sc_pintr != NULL) 1388 (*sc->sc_pintr)(sc->sc_parg); 1389 r = 1; 1390 } 1391 1392 return (r); 1393 } 1394 1395 void * 1396 ce4231_alloc(addr, direction, size, pool, flags) 1397 void *addr; 1398 int direction; 1399 size_t size; 1400 int pool; 1401 int flags; 1402 { 1403 struct ce4231_softc *sc = (struct ce4231_softc *)addr; 1404 bus_dma_tag_t dmat = sc->sc_dmatag; 1405 struct cs_dma *p; 1406 1407 p = (struct cs_dma *)malloc(sizeof(struct cs_dma), pool, flags); 1408 if (p == NULL) 1409 goto fail; 1410 1411 if (bus_dmamap_create(dmat, size, 1, size, 0, 1412 BUS_DMA_NOWAIT, &p->dmamap) != 0) 1413 goto fail; 1414 1415 p->size = size; 1416 1417 if (bus_dmamem_alloc(dmat, size, 64*1024, 0, p->segs, 1418 sizeof(p->segs)/sizeof(p->segs[0]), &p->nsegs, 1419 BUS_DMA_NOWAIT) != 0) 1420 goto fail1; 1421 1422 if (bus_dmamem_map(dmat, p->segs, p->nsegs, p->size, 1423 &p->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) 1424 goto fail2; 1425 1426 if (bus_dmamap_load(dmat, p->dmamap, p->addr, size, NULL, 1427 BUS_DMA_NOWAIT) != 0) 1428 goto fail3; 1429 1430 p->next = sc->sc_dmas; 1431 sc->sc_dmas = p; 1432 return (p->addr); 1433 1434 fail3: 1435 bus_dmamem_unmap(dmat, p->addr, p->size); 1436 fail2: 1437 bus_dmamem_free(dmat, p->segs, p->nsegs); 1438 fail1: 1439 bus_dmamap_destroy(dmat, p->dmamap); 1440 fail: 1441 return (NULL); 1442 } 1443 1444 void 1445 ce4231_free(addr, ptr, pool) 1446 void *addr; 1447 void *ptr; 1448 int pool; 1449 { 1450 struct ce4231_softc *sc = addr; 1451 bus_dma_tag_t dmat = sc->sc_dmatag; 1452 struct cs_dma *p, **pp; 1453 1454 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &(*pp)->next) { 1455 if (p->addr != ptr) 1456 continue; 1457 bus_dmamap_unload(dmat, p->dmamap); 1458 bus_dmamem_unmap(dmat, p->addr, p->size); 1459 bus_dmamem_free(dmat, p->segs, p->nsegs); 1460 bus_dmamap_destroy(dmat, p->dmamap); 1461 *pp = p->next; 1462 free(p, pool); 1463 return; 1464 } 1465 printf("%s: attempt to free rogue pointer\n", sc->sc_dev.dv_xname); 1466 } 1467 1468 int 1469 ce4231_trigger_output(addr, start, end, blksize, intr, arg, param) 1470 void *addr, *start, *end; 1471 int blksize; 1472 void (*intr)(void *); 1473 void *arg; 1474 struct audio_params *param; 1475 { 1476 struct ce4231_softc *sc = addr; 1477 struct cs_dma *p; 1478 u_int32_t csr; 1479 vaddr_t n; 1480 1481 if (sc->sc_locked != 0) { 1482 printf("%s: trigger_output: already running\n", 1483 sc->sc_dev.dv_xname); 1484 return (EINVAL); 1485 } 1486 1487 sc->sc_locked = 1; 1488 sc->sc_pintr = intr; 1489 sc->sc_parg = arg; 1490 1491 for (p = sc->sc_dmas; p->addr != start; p = p->next) 1492 /*EMPTY*/; 1493 if (p == NULL) { 1494 printf("%s: trigger_output: bad addr: %p\n", 1495 sc->sc_dev.dv_xname, start); 1496 return (EINVAL); 1497 } 1498 1499 n = (char *)end - (char *)start; 1500 1501 /* 1502 * Do only `blksize' at a time, so audio_pint() is kept 1503 * synchronous with us... 1504 */ 1505 sc->sc_blksz = blksize; 1506 sc->sc_nowplaying = p; 1507 sc->sc_playsegsz = n; 1508 1509 if (n > sc->sc_blksz) 1510 n = sc->sc_blksz; 1511 1512 sc->sc_playcnt = n; 1513 1514 csr = P_READ(sc, EBDMA_DCSR); 1515 if (csr & EBDCSR_DMAEN) { 1516 P_WRITE(sc, EBDMA_DCNT, (u_long)n); 1517 P_WRITE(sc, EBDMA_DADDR, 1518 (u_long)p->dmamap->dm_segs[0].ds_addr); 1519 } else { 1520 P_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET); 1521 P_WRITE(sc, EBDMA_DCSR, sc->sc_burst); 1522 1523 P_WRITE(sc, EBDMA_DCNT, (u_long)n); 1524 P_WRITE(sc, EBDMA_DADDR, 1525 (u_long)p->dmamap->dm_segs[0].ds_addr); 1526 1527 P_WRITE(sc, EBDMA_DCSR, sc->sc_burst | EBDCSR_DMAEN | 1528 EBDCSR_INTEN | EBDCSR_CNTEN | EBDCSR_NEXTEN); 1529 1530 ce4231_write(sc, SP_LOWER_BASE_COUNT, 0xff); 1531 ce4231_write(sc, SP_UPPER_BASE_COUNT, 0xff); 1532 ce4231_write(sc, SP_INTERFACE_CONFIG, 1533 ce4231_read(sc, SP_INTERFACE_CONFIG) | PLAYBACK_ENABLE); 1534 } 1535 sc->sc_lastaddr = p->dmamap->dm_segs[0].ds_addr + n; 1536 1537 return (0); 1538 } 1539 1540 int 1541 ce4231_trigger_input(addr, start, end, blksize, intr, arg, param) 1542 void *addr, *start, *end; 1543 int blksize; 1544 void (*intr)(void *); 1545 void *arg; 1546 struct audio_params *param; 1547 { 1548 return (ENXIO); 1549 } 1550 1551 #endif /* NAUDIO > 0 */ 1552