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