1 /* $OpenBSD: cs4281.c,v 1.30 2013/12/06 21:03:03 deraadt Exp $ */ 2 /* $Tera: cs4281.c,v 1.18 2000/12/27 14:24:45 tacha Exp $ */ 3 4 /* 5 * Copyright (c) 2000 Tatoku Ogaito. 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 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Tatoku Ogaito 18 * for the NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Cirrus Logic CS4281 driver. 36 * Data sheets can be found 37 * http://www.cirrus.com/pubs/4281.pdf?DocumentID=30 38 * ftp://ftp.alsa-project.org/pub/manuals/cirrus/cs4281tm.pdf 39 * 40 * TODO: 41 * 1: midi and FM support 42 */ 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/kernel.h> 47 #include <sys/malloc.h> 48 #include <sys/fcntl.h> 49 #include <sys/device.h> 50 51 #include <dev/pci/pcidevs.h> 52 #include <dev/pci/pcivar.h> 53 #include <dev/pci/cs4281reg.h> 54 55 #include <sys/audioio.h> 56 #include <dev/audio_if.h> 57 #include <dev/midi_if.h> 58 #include <dev/mulaw.h> 59 #include <dev/auconv.h> 60 61 #include <dev/ic/ac97.h> 62 63 #include <machine/bus.h> 64 65 #define CSCC_PCI_BA0 0x10 66 #define CSCC_PCI_BA1 0x14 67 68 struct cs4281_dma { 69 bus_dmamap_t map; 70 caddr_t addr; /* real dma buffer */ 71 caddr_t dum; /* dummy buffer for audio driver */ 72 bus_dma_segment_t segs[1]; 73 int nsegs; 74 size_t size; 75 struct cs4281_dma *next; 76 }; 77 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 78 #define BUFADDR(p) ((void *)((p)->dum)) 79 #define KERNADDR(p) ((void *)((p)->addr)) 80 81 /* 82 * Software state 83 */ 84 struct cs4281_softc { 85 struct device sc_dev; 86 87 pci_intr_handle_t *sc_ih; 88 89 /* I/O (BA0) */ 90 bus_space_tag_t ba0t; 91 bus_space_handle_t ba0h; 92 93 /* BA1 */ 94 bus_space_tag_t ba1t; 95 bus_space_handle_t ba1h; 96 97 /* DMA */ 98 bus_dma_tag_t sc_dmatag; 99 struct cs4281_dma *sc_dmas; 100 size_t dma_size; 101 size_t dma_align; 102 103 int hw_blocksize; 104 105 /* playback */ 106 void (*sc_pintr)(void *); /* dma completion intr handler */ 107 void *sc_parg; /* arg for sc_intr() */ 108 char *sc_ps, *sc_pe, *sc_pn; 109 int sc_pcount; 110 int sc_pi; 111 struct cs4281_dma *sc_pdma; 112 char *sc_pbuf; 113 int (*halt_output)(void *); 114 #ifdef DIAGNOSTIC 115 char sc_prun; 116 #endif 117 118 /* capturing */ 119 void (*sc_rintr)(void *); /* dma completion intr handler */ 120 void *sc_rarg; /* arg for sc_intr() */ 121 char *sc_rs, *sc_re, *sc_rn; 122 int sc_rcount; 123 int sc_ri; 124 struct cs4281_dma *sc_rdma; 125 char *sc_rbuf; 126 int sc_rparam; /* record format */ 127 int (*halt_input)(void *); 128 #ifdef DIAGNOSTIC 129 char sc_rrun; 130 #endif 131 132 #if NMIDI > 0 133 void (*sc_iintr)(void *, int); /* midi input ready handler */ 134 void (*sc_ointr)(void *); /* midi output ready handler */ 135 void *sc_arg; 136 #endif 137 138 /* AC97 CODEC */ 139 struct ac97_codec_if *codec_if; 140 struct ac97_host_if host_if; 141 142 /* Power Management */ 143 u_int16_t ac97_reg[CS4281_SAVE_REG_MAX + 1]; /* Save ac97 registers */ 144 }; 145 146 #define BA0READ4(sc, r) bus_space_read_4((sc)->ba0t, (sc)->ba0h, (r)) 147 #define BA0WRITE4(sc, r, x) bus_space_write_4((sc)->ba0t, (sc)->ba0h, (r), (x)) 148 149 #if defined(ENABLE_SECONDARY_CODEC) 150 #define MAX_CHANNELS (4) 151 #define MAX_FIFO_SIZE 32 /* 128/4 channels */ 152 #else 153 #define MAX_CHANNELS (2) 154 #define MAX_FIFO_SIZE 64 /* 128/2 channels */ 155 #endif 156 157 int cs4281_match(struct device *, void *, void *); 158 void cs4281_attach(struct device *, struct device *, void *); 159 int cs4281_activate(struct device *, int); 160 int cs4281_intr(void *); 161 int cs4281_query_encoding(void *, struct audio_encoding *); 162 int cs4281_set_params(void *, int, int, struct audio_params *, 163 struct audio_params *); 164 int cs4281_halt_output(void *); 165 int cs4281_halt_input(void *); 166 int cs4281_getdev(void *, struct audio_device *); 167 int cs4281_trigger_output(void *, void *, void *, int, void (*)(void *), 168 void *, struct audio_params *); 169 int cs4281_trigger_input(void *, void *, void *, int, void (*)(void *), 170 void *, struct audio_params *); 171 u_int8_t cs4281_sr2regval(int); 172 void cs4281_set_dac_rate(struct cs4281_softc *, int); 173 void cs4281_set_adc_rate(struct cs4281_softc *, int); 174 int cs4281_init(struct cs4281_softc *); 175 176 int cs4281_open(void *, int); 177 void cs4281_close(void *); 178 int cs4281_round_blocksize(void *, int); 179 int cs4281_get_props(void *); 180 int cs4281_attach_codec(void *, struct ac97_codec_if *); 181 int cs4281_read_codec(void *, u_int8_t , u_int16_t *); 182 int cs4281_write_codec(void *, u_int8_t, u_int16_t); 183 void cs4281_reset_codec(void *); 184 185 int cs4281_mixer_set_port(void *, mixer_ctrl_t *); 186 int cs4281_mixer_get_port(void *, mixer_ctrl_t *); 187 int cs4281_query_devinfo(void *, mixer_devinfo_t *); 188 void *cs4281_malloc(void *, int, size_t, int, int); 189 size_t cs4281_round_buffersize(void *, int, size_t); 190 void cs4281_free(void *, void *, int); 191 paddr_t cs4281_mappage(void *, void *, off_t, int); 192 193 int cs4281_allocmem(struct cs4281_softc *, size_t, int, int, 194 struct cs4281_dma *); 195 int cs4281_src_wait(struct cs4281_softc *); 196 197 #if defined(CS4281_DEBUG) 198 #undef DPRINTF 199 #undef DPRINTFN 200 #define DPRINTF(x) if (cs4281_debug) printf x 201 #define DPRINTFN(n,x) if (cs4281_debug>(n)) printf x 202 int cs4281_debug = 5; 203 #else 204 #define DPRINTF(x) 205 #define DPRINTFN(n,x) 206 #endif 207 208 struct audio_hw_if cs4281_hw_if = { 209 cs4281_open, 210 cs4281_close, 211 NULL, 212 cs4281_query_encoding, 213 cs4281_set_params, 214 cs4281_round_blocksize, 215 NULL, 216 NULL, 217 NULL, 218 NULL, 219 NULL, 220 cs4281_halt_output, 221 cs4281_halt_input, 222 NULL, 223 cs4281_getdev, 224 NULL, 225 cs4281_mixer_set_port, 226 cs4281_mixer_get_port, 227 cs4281_query_devinfo, 228 cs4281_malloc, 229 cs4281_free, 230 cs4281_round_buffersize, 231 NULL, /* cs4281_mappage, */ 232 cs4281_get_props, 233 cs4281_trigger_output, 234 cs4281_trigger_input, 235 NULL 236 }; 237 238 #if NMIDI > 0 239 /* Midi Interface */ 240 void cs4281_midi_close(void *); 241 void cs4281_midi_getinfo(void *, struct midi_info *); 242 int cs4281_midi_open(void *, int, void (*)(void *, int), 243 void (*)(void *), void *); 244 int cs4281_midi_output(void *, int); 245 246 struct midi_hw_if cs4281_midi_hw_if = { 247 cs4281_midi_open, 248 cs4281_midi_close, 249 cs4281_midi_output, 250 cs4281_midi_getinfo, 251 0, 252 }; 253 #endif 254 255 struct cfattach clct_ca = { 256 sizeof(struct cs4281_softc), cs4281_match, cs4281_attach, NULL, 257 cs4281_activate 258 }; 259 260 struct cfdriver clct_cd = { 261 NULL, "clct", DV_DULL 262 }; 263 264 struct audio_device cs4281_device = { 265 "CS4281", 266 "", 267 "cs4281" 268 }; 269 270 271 int 272 cs4281_match(parent, match, aux) 273 struct device *parent; 274 void *match; 275 void *aux; 276 { 277 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 278 279 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CIRRUS || 280 PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_CIRRUS_CS4281) 281 return (0); 282 283 return (1); 284 } 285 286 void 287 cs4281_attach(parent, self, aux) 288 struct device *parent; 289 struct device *self; 290 void *aux; 291 { 292 struct cs4281_softc *sc = (struct cs4281_softc *)self; 293 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 294 pci_chipset_tag_t pc = pa->pa_pc; 295 char const *intrstr; 296 pci_intr_handle_t ih; 297 298 /* Map I/O register */ 299 if (pci_mapreg_map(pa, CSCC_PCI_BA0, 300 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ba0t, 301 &sc->ba0h, NULL, NULL, 0)) { 302 printf("%s: can't map BA0 space\n", sc->sc_dev.dv_xname); 303 return; 304 } 305 if (pci_mapreg_map(pa, CSCC_PCI_BA1, 306 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ba1t, 307 &sc->ba1h, NULL, NULL, 0)) { 308 printf("%s: can't map BA1 space\n", sc->sc_dev.dv_xname); 309 return; 310 } 311 312 sc->sc_dmatag = pa->pa_dmat; 313 314 /* 315 * Set Power State D0. 316 * Without doing this, 0xffffffff is read from all registers after 317 * using Windows and rebooting into OpenBSD. 318 * On my IBM ThinkPad X20, it is set to D3 after using Windows2000. 319 */ 320 pci_set_powerstate(pc, pa->pa_tag, PCI_PMCSR_STATE_D0); 321 322 /* Map and establish the interrupt. */ 323 if (pci_intr_map(pa, &ih)) { 324 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); 325 return; 326 } 327 intrstr = pci_intr_string(pc, ih); 328 329 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO | IPL_MPSAFE, 330 cs4281_intr, sc, sc->sc_dev.dv_xname); 331 if (sc->sc_ih == NULL) { 332 printf("%s: couldn't establish interrupt",sc->sc_dev.dv_xname); 333 if (intrstr != NULL) 334 printf(" at %s", intrstr); 335 printf("\n"); 336 return; 337 } 338 printf(" %s\n", intrstr); 339 340 /* 341 * Sound System start-up 342 */ 343 if (cs4281_init(sc) != 0) 344 return; 345 346 sc->halt_input = cs4281_halt_input; 347 sc->halt_output = cs4281_halt_output; 348 349 sc->dma_size = CS4281_BUFFER_SIZE / MAX_CHANNELS; 350 sc->dma_align = 0x10; 351 sc->hw_blocksize = sc->dma_size / 2; 352 353 /* AC 97 attachment */ 354 sc->host_if.arg = sc; 355 sc->host_if.attach = cs4281_attach_codec; 356 sc->host_if.read = cs4281_read_codec; 357 sc->host_if.write = cs4281_write_codec; 358 sc->host_if.reset = cs4281_reset_codec; 359 if (ac97_attach(&sc->host_if) != 0) { 360 printf("%s: ac97_attach failed\n", sc->sc_dev.dv_xname); 361 return; 362 } 363 audio_attach_mi(&cs4281_hw_if, sc, &sc->sc_dev); 364 365 #if NMIDI > 0 366 midi_attach_mi(&cs4281_midi_hw_if, sc, &sc->sc_dev); 367 #endif 368 } 369 370 371 int 372 cs4281_intr(p) 373 void *p; 374 { 375 struct cs4281_softc *sc = p; 376 u_int32_t intr, val; 377 char *empty_dma; 378 379 mtx_enter(&audio_lock); 380 intr = BA0READ4(sc, CS4281_HISR); 381 if (!(intr & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) { 382 BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); 383 mtx_leave(&audio_lock); 384 return (0); 385 } 386 DPRINTF(("cs4281_intr:")); 387 388 if (intr & HISR_DMA0) 389 val = BA0READ4(sc, CS4281_HDSR0); /* clear intr condition */ 390 if (intr & HISR_DMA1) 391 val = BA0READ4(sc, CS4281_HDSR1); /* clear intr condition */ 392 BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); 393 394 /* Playback Interrupt */ 395 if (intr & HISR_DMA0) { 396 DPRINTF((" PB DMA 0x%x(%d)", (int)BA0READ4(sc, CS4281_DCA0), 397 (int)BA0READ4(sc, CS4281_DCC0))); 398 if (sc->sc_pintr) { 399 if ((sc->sc_pi%sc->sc_pcount) == 0) 400 sc->sc_pintr(sc->sc_parg); 401 } else { 402 printf("unexpected play intr\n"); 403 } 404 /* copy buffer */ 405 ++sc->sc_pi; 406 empty_dma = sc->sc_pdma->addr; 407 if (sc->sc_pi&1) 408 empty_dma += sc->hw_blocksize; 409 memcpy(empty_dma, sc->sc_pn, sc->hw_blocksize); 410 sc->sc_pn += sc->hw_blocksize; 411 if (sc->sc_pn >= sc->sc_pe) 412 sc->sc_pn = sc->sc_ps; 413 } 414 if (intr & HISR_DMA1) { 415 val = BA0READ4(sc, CS4281_HDSR1); 416 /* copy from dma */ 417 DPRINTF((" CP DMA 0x%x(%d)", (int)BA0READ4(sc, CS4281_DCA1), 418 (int)BA0READ4(sc, CS4281_DCC1))); 419 ++sc->sc_ri; 420 empty_dma = sc->sc_rdma->addr; 421 if ((sc->sc_ri & 1) == 0) 422 empty_dma += sc->hw_blocksize; 423 memcpy(sc->sc_rn, empty_dma, sc->hw_blocksize); 424 if (sc->sc_rn >= sc->sc_re) 425 sc->sc_rn = sc->sc_rs; 426 if (sc->sc_rintr) { 427 if ((sc->sc_ri % sc->sc_rcount) == 0) 428 sc->sc_rintr(sc->sc_rarg); 429 } else { 430 printf("unexpected record intr\n"); 431 } 432 } 433 DPRINTF(("\n")); 434 mtx_leave(&audio_lock); 435 return (1); 436 } 437 438 int 439 cs4281_query_encoding(addr, fp) 440 void *addr; 441 struct audio_encoding *fp; 442 { 443 switch (fp->index) { 444 case 0: 445 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 446 fp->encoding = AUDIO_ENCODING_ULINEAR; 447 fp->precision = 8; 448 fp->flags = 0; 449 break; 450 case 1: 451 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 452 fp->encoding = AUDIO_ENCODING_ULAW; 453 fp->precision = 8; 454 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 455 break; 456 case 2: 457 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 458 fp->encoding = AUDIO_ENCODING_ALAW; 459 fp->precision = 8; 460 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 461 break; 462 case 3: 463 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 464 fp->encoding = AUDIO_ENCODING_SLINEAR; 465 fp->precision = 8; 466 fp->flags = 0; 467 break; 468 case 4: 469 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 470 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 471 fp->precision = 16; 472 fp->flags = 0; 473 break; 474 case 5: 475 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 476 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 477 fp->precision = 16; 478 fp->flags = 0; 479 break; 480 case 6: 481 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 482 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 483 fp->precision = 16; 484 fp->flags = 0; 485 break; 486 case 7: 487 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 488 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 489 fp->precision = 16; 490 fp->flags = 0; 491 break; 492 default: 493 return EINVAL; 494 } 495 fp->bps = AUDIO_BPS(fp->precision); 496 fp->msb = 1; 497 498 return (0); 499 } 500 501 int 502 cs4281_set_params(addr, setmode, usemode, play, rec) 503 void *addr; 504 int setmode, usemode; 505 struct audio_params *play, *rec; 506 { 507 struct cs4281_softc *sc = addr; 508 struct audio_params *p; 509 int mode; 510 511 for (mode = AUMODE_RECORD; mode != -1; 512 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 513 if ((setmode & mode) == 0) 514 continue; 515 516 p = mode == AUMODE_PLAY ? play : rec; 517 518 if (p == play) { 519 DPRINTFN(5,("play: samp=%ld precision=%d channels=%d\n", 520 p->sample_rate, p->precision, p->channels)); 521 } else { 522 DPRINTFN(5,("rec: samp=%ld precision=%d channels=%d\n", 523 p->sample_rate, p->precision, p->channels)); 524 } 525 if (p->sample_rate < 6023) 526 p->sample_rate = 6023; 527 if (p->sample_rate > 48000) 528 p->sample_rate = 48000; 529 if (p->precision > 16) 530 p->precision = 16; 531 if (p->channels > 2) 532 p->channels = 2; 533 p->factor = 1; 534 p->sw_code = 0; 535 536 switch (p->encoding) { 537 case AUDIO_ENCODING_SLINEAR_BE: 538 break; 539 case AUDIO_ENCODING_SLINEAR_LE: 540 break; 541 case AUDIO_ENCODING_ULINEAR_BE: 542 break; 543 case AUDIO_ENCODING_ULINEAR_LE: 544 break; 545 case AUDIO_ENCODING_ULAW: 546 if (mode == AUMODE_PLAY) { 547 p->sw_code = mulaw_to_slinear8; 548 } else { 549 p->sw_code = slinear8_to_mulaw; 550 } 551 break; 552 case AUDIO_ENCODING_ALAW: 553 if (mode == AUMODE_PLAY) { 554 p->sw_code = alaw_to_slinear8; 555 } else { 556 p->sw_code = slinear8_to_alaw; 557 } 558 break; 559 default: 560 return (EINVAL); 561 } 562 p->bps = AUDIO_BPS(p->precision); 563 p->msb = 1; 564 } 565 566 /* set sample rate */ 567 cs4281_set_dac_rate(sc, play->sample_rate); 568 cs4281_set_adc_rate(sc, rec->sample_rate); 569 return (0); 570 } 571 572 int 573 cs4281_halt_output(addr) 574 void *addr; 575 { 576 struct cs4281_softc *sc = addr; 577 578 BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK); 579 #ifdef DIAGNOSTIC 580 sc->sc_prun = 0; 581 #endif 582 return (0); 583 } 584 585 int 586 cs4281_halt_input(addr) 587 void *addr; 588 { 589 struct cs4281_softc *sc = addr; 590 591 BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK); 592 #ifdef DIAGNOSTIC 593 sc->sc_rrun = 0; 594 #endif 595 return (0); 596 } 597 598 /* trivial */ 599 int 600 cs4281_getdev(addr, retp) 601 void *addr; 602 struct audio_device *retp; 603 { 604 *retp = cs4281_device; 605 return (0); 606 } 607 608 609 int 610 cs4281_trigger_output(addr, start, end, blksize, intr, arg, param) 611 void *addr; 612 void *start, *end; 613 int blksize; 614 void (*intr)(void *); 615 void *arg; 616 struct audio_params *param; 617 { 618 struct cs4281_softc *sc = addr; 619 u_int32_t fmt=0; 620 struct cs4281_dma *p; 621 int dma_count; 622 623 #ifdef DIAGNOSTIC 624 if (sc->sc_prun) 625 printf("cs4281_trigger_output: already running\n"); 626 sc->sc_prun = 1; 627 #endif 628 629 DPRINTF(("cs4281_trigger_output: sc=%p start=%p end=%p " 630 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 631 sc->sc_pintr = intr; 632 sc->sc_parg = arg; 633 634 /* stop playback DMA */ 635 BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK); 636 637 DPRINTF(("param: precision=%d factor=%d channels=%d encoding=%d\n", 638 param->precision, param->factor, param->channels, 639 param->encoding)); 640 for (p = sc->sc_dmas; p != NULL && BUFADDR(p) != start; p = p->next) 641 ; 642 if (p == NULL) { 643 printf("cs4281_trigger_output: bad addr %p\n", start); 644 mtx_leave(&audio_lock); 645 return (EINVAL); 646 } 647 648 sc->sc_pcount = blksize / sc->hw_blocksize; 649 sc->sc_ps = (char *)start; 650 sc->sc_pe = (char *)end; 651 sc->sc_pdma = p; 652 sc->sc_pbuf = KERNADDR(p); 653 sc->sc_pi = 0; 654 sc->sc_pn = sc->sc_ps; 655 if (blksize >= sc->dma_size) { 656 sc->sc_pn = sc->sc_ps + sc->dma_size; 657 memcpy(sc->sc_pbuf, start, sc->dma_size); 658 ++sc->sc_pi; 659 } else { 660 sc->sc_pn = sc->sc_ps + sc->hw_blocksize; 661 memcpy(sc->sc_pbuf, start, sc->hw_blocksize); 662 } 663 664 dma_count = sc->dma_size; 665 if (param->precision * param->factor != 8) 666 dma_count /= 2; /* 16 bit */ 667 if (param->channels > 1) 668 dma_count /= 2; /* Stereo */ 669 670 DPRINTF(("cs4281_trigger_output: DMAADDR(p)=0x%x count=%d\n", 671 (int)DMAADDR(p), dma_count)); 672 BA0WRITE4(sc, CS4281_DBA0, DMAADDR(p)); 673 BA0WRITE4(sc, CS4281_DBC0, dma_count-1); 674 675 /* set playback format */ 676 fmt = BA0READ4(sc, CS4281_DMR0) & ~DMRn_FMTMSK; 677 if (param->precision * param->factor == 8) 678 fmt |= DMRn_SIZE8; 679 if (param->channels == 1) 680 fmt |= DMRn_MONO; 681 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 682 param->encoding == AUDIO_ENCODING_SLINEAR_BE) 683 fmt |= DMRn_BEND; 684 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 685 param->encoding == AUDIO_ENCODING_ULINEAR_LE) 686 fmt |= DMRn_USIGN; 687 BA0WRITE4(sc, CS4281_DMR0, fmt); 688 689 /* set sample rate */ 690 cs4281_set_dac_rate(sc, param->sample_rate); 691 692 /* start DMA */ 693 mtx_enter(&audio_lock); 694 BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) & ~DCRn_MSK); 695 /* Enable interrupts */ 696 BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); 697 698 BA0WRITE4(sc, CS4281_PPRVC, 7); 699 BA0WRITE4(sc, CS4281_PPLVC, 7); 700 701 DPRINTF(("HICR =0x%08x(expected 0x00000001)\n", BA0READ4(sc, CS4281_HICR))); 702 DPRINTF(("HIMR =0x%08x(expected 0x00f0fc3f)\n", BA0READ4(sc, CS4281_HIMR))); 703 DPRINTF(("DMR0 =0x%08x(expected 0x2???0018)\n", BA0READ4(sc, CS4281_DMR0))); 704 DPRINTF(("DCR0 =0x%08x(expected 0x00030000)\n", BA0READ4(sc, CS4281_DCR0))); 705 DPRINTF(("FCR0 =0x%08x(expected 0x81000f00)\n", BA0READ4(sc, CS4281_FCR0))); 706 DPRINTF(("DACSR=0x%08x(expected 1 for 44kHz 5 for 8kHz)\n", 707 BA0READ4(sc, CS4281_DACSR))); 708 DPRINTF(("SRCSA=0x%08x(expected 0x0b0a0100)\n", BA0READ4(sc, CS4281_SRCSA))); 709 DPRINTF(("SSPM&SSPM_PSRCEN =0x%08x(expected 0x00000010)\n", 710 BA0READ4(sc, CS4281_SSPM) & SSPM_PSRCEN)); 711 mtx_leave(&audio_lock); 712 return (0); 713 } 714 715 int 716 cs4281_trigger_input(addr, start, end, blksize, intr, arg, param) 717 void *addr; 718 void *start, *end; 719 int blksize; 720 void (*intr)(void *); 721 void *arg; 722 struct audio_params *param; 723 { 724 struct cs4281_softc *sc = addr; 725 struct cs4281_dma *p; 726 u_int32_t fmt=0; 727 int dma_count; 728 729 printf("cs4281_trigger_input: not implemented yet\n"); 730 #ifdef DIAGNOSTIC 731 if (sc->sc_rrun) 732 printf("cs4281_trigger_input: already running\n"); 733 sc->sc_rrun = 1; 734 #endif 735 DPRINTF(("cs4281_trigger_input: sc=%p start=%p end=%p " 736 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 737 sc->sc_rintr = intr; 738 sc->sc_rarg = arg; 739 740 /* stop recording DMA */ 741 BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK); 742 743 for (p = sc->sc_dmas; p && BUFADDR(p) != start; p = p->next) 744 ; 745 if (!p) { 746 printf("cs4281_trigger_input: bad addr %p\n", start); 747 return (EINVAL); 748 } 749 750 sc->sc_rcount = blksize / sc->hw_blocksize; 751 sc->sc_rs = (char *)start; 752 sc->sc_re = (char *)end; 753 sc->sc_rdma = p; 754 sc->sc_rbuf = KERNADDR(p); 755 sc->sc_ri = 0; 756 sc->sc_rn = sc->sc_rs; 757 758 dma_count = sc->dma_size; 759 if (param->precision * param->factor == 8) 760 dma_count /= 2; 761 if (param->channels > 1) 762 dma_count /= 2; 763 764 DPRINTF(("cs4281_trigger_input: DMAADDR(p)=0x%x count=%d\n", 765 (int)DMAADDR(p), dma_count)); 766 BA0WRITE4(sc, CS4281_DBA1, DMAADDR(p)); 767 BA0WRITE4(sc, CS4281_DBC1, dma_count-1); 768 769 /* set recording format */ 770 fmt = BA0READ4(sc, CS4281_DMR1) & ~DMRn_FMTMSK; 771 if (param->precision * param->factor == 8) 772 fmt |= DMRn_SIZE8; 773 if (param->channels == 1) 774 fmt |= DMRn_MONO; 775 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 776 param->encoding == AUDIO_ENCODING_SLINEAR_BE) 777 fmt |= DMRn_BEND; 778 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 779 param->encoding == AUDIO_ENCODING_ULINEAR_LE) 780 fmt |= DMRn_USIGN; 781 BA0WRITE4(sc, CS4281_DMR1, fmt); 782 783 /* set sample rate */ 784 cs4281_set_adc_rate(sc, param->sample_rate); 785 786 /* Start DMA */ 787 mtx_enter(&audio_lock); 788 BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) & ~DCRn_MSK); 789 /* Enable interrupts */ 790 BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); 791 792 DPRINTF(("HICR=0x%08x\n", BA0READ4(sc, CS4281_HICR))); 793 DPRINTF(("HIMR=0x%08x\n", BA0READ4(sc, CS4281_HIMR))); 794 DPRINTF(("DMR1=0x%08x\n", BA0READ4(sc, CS4281_DMR1))); 795 DPRINTF(("DCR1=0x%08x\n", BA0READ4(sc, CS4281_DCR1))); 796 mtx_leave(&audio_lock); 797 return (0); 798 } 799 800 /* convert sample rate to register value */ 801 u_int8_t 802 cs4281_sr2regval(rate) 803 int rate; 804 { 805 u_int8_t retval; 806 807 /* We don't have to change here. but anyway ... */ 808 if (rate > 48000) 809 rate = 48000; 810 if (rate < 6023) 811 rate = 6023; 812 813 switch (rate) { 814 case 8000: 815 retval = 5; 816 break; 817 case 11025: 818 retval = 4; 819 break; 820 case 16000: 821 retval = 3; 822 break; 823 case 22050: 824 retval = 2; 825 break; 826 case 44100: 827 retval = 1; 828 break; 829 case 48000: 830 retval = 0; 831 break; 832 default: 833 retval = 1536000/rate; /* == 24576000/(rate*16) */ 834 } 835 return (retval); 836 } 837 838 839 void 840 cs4281_set_dac_rate(sc, rate) 841 struct cs4281_softc *sc; 842 int rate; 843 { 844 BA0WRITE4(sc, CS4281_DACSR, cs4281_sr2regval(rate)); 845 } 846 847 void 848 cs4281_set_adc_rate(sc, rate) 849 struct cs4281_softc *sc; 850 int rate; 851 { 852 BA0WRITE4(sc, CS4281_ADCSR, cs4281_sr2regval(rate)); 853 } 854 855 int 856 cs4281_init(sc) 857 struct cs4281_softc *sc; 858 { 859 int n; 860 u_int16_t data; 861 u_int32_t dat32; 862 863 /* set "Configuration Write Protect" register to 864 * 0x4281 to allow to write */ 865 BA0WRITE4(sc, CS4281_CWPR, 0x4281); 866 867 /* 868 * Unset "Full Power-Down bit of Extended PCI Power Management 869 * Control" register to release the reset state. 870 */ 871 dat32 = BA0READ4(sc, CS4281_EPPMC); 872 if (dat32 & EPPMC_FPDN) 873 BA0WRITE4(sc, CS4281_EPPMC, dat32 & ~EPPMC_FPDN); 874 875 /* Start PLL out in known state */ 876 BA0WRITE4(sc, CS4281_CLKCR1, 0); 877 /* Start serial ports out in known state */ 878 BA0WRITE4(sc, CS4281_SERMC, 0); 879 880 /* Reset codec */ 881 BA0WRITE4(sc, CS4281_ACCTL, 0); 882 delay(50); /* delay 50us */ 883 884 BA0WRITE4(sc, CS4281_SPMC, 0); 885 delay(100); /* delay 100us */ 886 BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN); 887 #if defined(ENABLE_SECONDARY_CODEC) 888 BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E); 889 BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID); 890 #endif 891 delay(50000); /* XXX: delay 50ms */ 892 893 /* Turn on Sound System clocks based on ABITCLK */ 894 BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_DLLP); 895 delay(50000); /* XXX: delay 50ms */ 896 BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_SWCE | CLKCR1_DLLP); 897 898 /* Set enables for sections that are needed in the SSPM registers */ 899 BA0WRITE4(sc, CS4281_SSPM, 900 SSPM_MIXEN | /* Mixer */ 901 SSPM_CSRCEN | /* Capture SRC */ 902 SSPM_PSRCEN | /* Playback SRC */ 903 SSPM_JSEN | /* Joystick */ 904 SSPM_ACLEN | /* AC LINK */ 905 SSPM_FMEN /* FM */ 906 ); 907 908 /* Wait for clock stabilization */ 909 n = 0; 910 while ((BA0READ4(sc, CS4281_CLKCR1)& (CLKCR1_DLLRDY | CLKCR1_CLKON)) 911 != (CLKCR1_DLLRDY | CLKCR1_CLKON)) { 912 delay(100); 913 if (++n > 1000) 914 return (-1); 915 } 916 917 /* Enable ASYNC generation */ 918 BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN); 919 920 /* Wait for Codec ready. Linux driver wait 50ms here */ 921 n = 0; 922 while((BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY) == 0) { 923 delay(100); 924 if (++n > 1000) 925 return (-1); 926 } 927 928 #if defined(ENABLE_SECONDARY_CODEC) 929 /* secondary codec ready*/ 930 n = 0; 931 while((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) { 932 delay(100); 933 if (++n > 1000) 934 return (-1); 935 } 936 #endif 937 938 /* Set the serial timing configuration */ 939 /* XXX: undocumented but the Linux driver do this */ 940 BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 941 942 /* Wait for Codec ready signal */ 943 n = 0; 944 do { 945 delay(1000); 946 if (++n > 1000) { 947 printf("%s: Timeout waiting for Codec ready\n", 948 sc->sc_dev.dv_xname); 949 return -1; 950 } 951 dat32 = BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY; 952 } while (dat32 == 0); 953 954 /* Enable Valid Frame output on ASDOUT */ 955 BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN | ACCTL_VFRM); 956 957 /* Wait until Codec Calibration is finished. Codec register 26h */ 958 n = 0; 959 do { 960 delay(1); 961 if (++n > 1000) { 962 printf("%s: Timeout waiting for Codec calibration\n", 963 sc->sc_dev.dv_xname); 964 return -1; 965 } 966 cs4281_read_codec(sc, AC97_REG_POWER, &data); 967 } while ((data & 0x0f) != 0x0f); 968 969 /* Set the serial timing configuration again */ 970 /* XXX: undocumented but the Linux driver do this */ 971 BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 972 973 /* Wait until we've sampled input slots 3 & 4 as valid */ 974 n = 0; 975 do { 976 delay(1000); 977 if (++n > 1000) { 978 printf("%s: Timeout waiting for sampled input slots as valid\n", 979 sc->sc_dev.dv_xname); 980 return -1; 981 } 982 dat32 = BA0READ4(sc, CS4281_ACISV) & (ACISV_ISV3 | ACISV_ISV4); 983 } while (dat32 != (ACISV_ISV3 | ACISV_ISV4)); 984 985 /* Start digital data transfer of audio data to the codec */ 986 BA0WRITE4(sc, CS4281_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4)); 987 988 cs4281_write_codec(sc, AC97_REG_HEADPHONE_VOLUME, 0); 989 cs4281_write_codec(sc, AC97_REG_MASTER_VOLUME, 0); 990 991 /* Power on the DAC */ 992 cs4281_read_codec(sc, AC97_REG_POWER, &data); 993 cs4281_write_codec(sc, AC97_REG_POWER, data &= 0xfdff); 994 995 /* Wait until we sample a DAC ready state. 996 * Not documented, but Linux driver does. 997 */ 998 for (n = 0; n < 32; ++n) { 999 delay(1000); 1000 cs4281_read_codec(sc, AC97_REG_POWER, &data); 1001 if (data & 0x02) 1002 break; 1003 } 1004 1005 /* Power on the ADC */ 1006 cs4281_read_codec(sc, AC97_REG_POWER, &data); 1007 cs4281_write_codec(sc, AC97_REG_POWER, data &= 0xfeff); 1008 1009 /* Wait until we sample ADC ready state. 1010 * Not documented, but Linux driver does. 1011 */ 1012 for (n = 0; n < 32; ++n) { 1013 delay(1000); 1014 cs4281_read_codec(sc, AC97_REG_POWER, &data); 1015 if (data & 0x01) 1016 break; 1017 } 1018 1019 #if 0 1020 /* Initialize SSCR register features */ 1021 /* XXX: hardware volume setting */ 1022 BA0WRITE4(sc, CS4281_SSCR, ~SSCR_HVC); /* disable HW volume setting */ 1023 #endif 1024 1025 /* disable Sound Blaster Pro emulation */ 1026 /* XXX: 1027 * Cannot set since the documents does not describe which bit is 1028 * correspond to SSCR_SB. Since the reset value of SSCR is 0, 1029 * we can ignore it.*/ 1030 #if 0 1031 BA0WRITE4(sc, CS4281_SSCR, SSCR_SB); 1032 #endif 1033 1034 /* map AC97 PCM playback to DMA Channel 0 */ 1035 /* Reset FEN bit to setup first */ 1036 BA0WRITE4(sc, CS4281_FCR0, (BA0READ4(sc,CS4281_FCR0) & ~FCRn_FEN)); 1037 /* 1038 *| RS[4:0]/| | 1039 *| LS[4:0] | AC97 | Slot Function 1040 *|---------+--------+-------------------- 1041 *| 0 | 3 | Left PCM Playback 1042 *| 1 | 4 | Right PCM Playback 1043 *| 2 | 5 | Phone Line 1 DAC 1044 *| 3 | 6 | Center PCM Playback 1045 *.... 1046 * quoted from Table 29(p109) 1047 */ 1048 dat32 = 0x01 << 24 | /* RS[4:0] = 1 see above */ 1049 0x00 << 16 | /* LS[4:0] = 0 see above */ 1050 0x0f << 8 | /* SZ[6:0] = 15 size of buffer */ 1051 0x00 << 0 ; /* OF[6:0] = 0 offset */ 1052 BA0WRITE4(sc, CS4281_FCR0, dat32); 1053 BA0WRITE4(sc, CS4281_FCR0, dat32 | FCRn_FEN); 1054 1055 /* map AC97 PCM record to DMA Channel 1 */ 1056 /* Reset FEN bit to setup first */ 1057 BA0WRITE4(sc, CS4281_FCR1, (BA0READ4(sc,CS4281_FCR1) & ~FCRn_FEN)); 1058 /* 1059 *| RS[4:0]/| 1060 *| LS[4:0] | AC97 | Slot Function 1061 *|---------+------+------------------- 1062 *| 10 | 3 | Left PCM Record 1063 *| 11 | 4 | Right PCM Record 1064 *| 12 | 5 | Phone Line 1 ADC 1065 *| 13 | 6 | Mic ADC 1066 *.... 1067 * quoted from Table 30(p109) 1068 */ 1069 dat32 = 0x0b << 24 | /* RS[4:0] = 11 See above */ 1070 0x0a << 16 | /* LS[4:0] = 10 See above */ 1071 0x0f << 8 | /* SZ[6:0] = 15 Size of buffer */ 1072 0x10 << 0 ; /* OF[6:0] = 16 offset */ 1073 1074 /* XXX: I cannot understand why FCRn_PSH is needed here. */ 1075 BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_PSH); 1076 BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_FEN); 1077 1078 #if 0 1079 /* Disable DMA Channel 2, 3 */ 1080 BA0WRITE4(sc, CS4281_FCR2, (BA0READ4(sc,CS4281_FCR2) & ~FCRn_FEN)); 1081 BA0WRITE4(sc, CS4281_FCR3, (BA0READ4(sc,CS4281_FCR3) & ~FCRn_FEN)); 1082 #endif 1083 1084 /* Set the SRC Slot Assignment accordingly */ 1085 /*| PLSS[4:0]/ 1086 *| PRSS[4:0] | AC97 | Slot Function 1087 *|-----------+------+---------------- 1088 *| 0 | 3 | Left PCM Playback 1089 *| 1 | 4 | Right PCM Playback 1090 *| 2 | 5 | phone line 1 DAC 1091 *| 3 | 6 | Center PCM Playback 1092 *| 4 | 7 | Left Surround PCM Playback 1093 *| 5 | 8 | Right Surround PCM Playback 1094 *...... 1095 * 1096 *| CLSS[4:0]/ 1097 *| CRSS[4:0] | AC97 | Codec |Slot Function 1098 *|-----------+------+-------+----------------- 1099 *| 10 | 3 |Primary| Left PCM Record 1100 *| 11 | 4 |Primary| Right PCM Record 1101 *| 12 | 5 |Primary| Phone Line 1 ADC 1102 *| 13 | 6 |Primary| Mic ADC 1103 *|..... 1104 *| 20 | 3 | Sec. | Left PCM Record 1105 *| 21 | 4 | Sec. | Right PCM Record 1106 *| 22 | 5 | Sec. | Phone Line 1 ADC 1107 *| 23 | 6 | Sec. | Mic ADC 1108 */ 1109 dat32 = 0x0b << 24 | /* CRSS[4:0] Right PCM Record(primary) */ 1110 0x0a << 16 | /* CLSS[4:0] Left PCM Record(primary) */ 1111 0x01 << 8 | /* PRSS[4:0] Right PCM Playback */ 1112 0x00 << 0; /* PLSS[4:0] Left PCM Playback */ 1113 BA0WRITE4(sc, CS4281_SRCSA, dat32); 1114 1115 /* Set interrupt to occurred at Half and Full terminal 1116 * count interrupt enable for DMA channel 0 and 1. 1117 * To keep DMA stop, set MSK. 1118 */ 1119 dat32 = DCRn_HTCIE | DCRn_TCIE | DCRn_MSK; 1120 BA0WRITE4(sc, CS4281_DCR0, dat32); 1121 BA0WRITE4(sc, CS4281_DCR1, dat32); 1122 1123 /* Set Auto-Initialize Control enable */ 1124 BA0WRITE4(sc, CS4281_DMR0, 1125 DMRn_DMA | DMRn_AUTO | DMRn_TR_READ); 1126 BA0WRITE4(sc, CS4281_DMR1, 1127 DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); 1128 1129 /* Clear DMA Mask in HIMR */ 1130 dat32 = BA0READ4(sc, CS4281_HIMR) & 0xfffbfcff; 1131 BA0WRITE4(sc, CS4281_HIMR, dat32); 1132 return (0); 1133 } 1134 1135 int 1136 cs4281_activate(struct device *self, int act) 1137 { 1138 struct cs4281_softc *sc = (struct cs4281_softc *)self; 1139 int rv = 0; 1140 1141 switch (act) { 1142 case DVACT_SUSPEND: 1143 /* should I powerdown here ? */ 1144 cs4281_write_codec(sc, AC97_REG_POWER, CS4281_POWER_DOWN_ALL); 1145 break; 1146 case DVACT_RESUME: 1147 cs4281_init(sc); 1148 ac97_resume(&sc->host_if, sc->codec_if); 1149 rv = config_activate_children(self, act); 1150 break; 1151 default: 1152 rv = config_activate_children(self, act); 1153 break; 1154 } 1155 return (rv); 1156 } 1157 1158 void 1159 cs4281_reset_codec(void *addr) 1160 { 1161 struct cs4281_softc *sc; 1162 u_int16_t data; 1163 u_int32_t dat32; 1164 int n; 1165 1166 sc = addr; 1167 1168 DPRINTFN(3,("cs4281_reset_codec\n")); 1169 1170 /* Reset codec */ 1171 BA0WRITE4(sc, CS4281_ACCTL, 0); 1172 delay(50); /* delay 50us */ 1173 1174 BA0WRITE4(sc, CS4281_SPMC, 0); 1175 delay(100); /* delay 100us */ 1176 BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN); 1177 #if defined(ENABLE_SECONDARY_CODEC) 1178 BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E); 1179 BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID); 1180 #endif 1181 delay(50000); /* XXX: delay 50ms */ 1182 1183 /* Enable ASYNC generation */ 1184 BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN); 1185 1186 /* Wait for Codec ready. Linux driver wait 50ms here */ 1187 n = 0; 1188 while((BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY) == 0) { 1189 delay(100); 1190 if (++n > 1000) { 1191 printf("reset_codec: AC97 codec ready timeout\n"); 1192 return; 1193 } 1194 } 1195 #if defined(ENABLE_SECONDARY_CODEC) 1196 /* secondary codec ready*/ 1197 n = 0; 1198 while((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) { 1199 delay(100); 1200 if (++n > 1000) 1201 return; 1202 } 1203 #endif 1204 /* Set the serial timing configuration */ 1205 /* XXX: undocumented but the Linux driver do this */ 1206 BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 1207 1208 /* Wait for Codec ready signal */ 1209 n = 0; 1210 do { 1211 delay(1000); 1212 if (++n > 1000) { 1213 printf("%s: Timeout waiting for Codec ready\n", 1214 sc->sc_dev.dv_xname); 1215 return; 1216 } 1217 dat32 = BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY; 1218 } while (dat32 == 0); 1219 1220 /* Enable Valid Frame output on ASDOUT */ 1221 BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN | ACCTL_VFRM); 1222 1223 /* Wait until Codec Calibration is finished. Codec register 26h */ 1224 n = 0; 1225 do { 1226 delay(1); 1227 if (++n > 1000) { 1228 printf("%s: Timeout waiting for Codec calibration\n", 1229 sc->sc_dev.dv_xname); 1230 return ; 1231 } 1232 cs4281_read_codec(sc, AC97_REG_POWER, &data); 1233 } while ((data & 0x0f) != 0x0f); 1234 1235 /* Set the serial timing configuration again */ 1236 /* XXX: undocumented but the Linux driver do this */ 1237 BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97); 1238 1239 /* Wait until we've sampled input slots 3 & 4 as valid */ 1240 n = 0; 1241 do { 1242 delay(1000); 1243 if (++n > 1000) { 1244 printf("%s: Timeout waiting for sampled input slots as valid\n", 1245 sc->sc_dev.dv_xname); 1246 return; 1247 } 1248 dat32 = BA0READ4(sc, CS4281_ACISV) & (ACISV_ISV3 | ACISV_ISV4) ; 1249 } while (dat32 != (ACISV_ISV3 | ACISV_ISV4)); 1250 1251 /* Start digital data transfer of audio data to the codec */ 1252 BA0WRITE4(sc, CS4281_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4)); 1253 } 1254 1255 int 1256 cs4281_open(void *addr, int flags) 1257 { 1258 return (0); 1259 } 1260 1261 void 1262 cs4281_close(void *addr) 1263 { 1264 struct cs4281_softc *sc; 1265 1266 sc = addr; 1267 1268 (*sc->halt_output)(sc); 1269 (*sc->halt_input)(sc); 1270 1271 sc->sc_pintr = 0; 1272 sc->sc_rintr = 0; 1273 } 1274 1275 int 1276 cs4281_round_blocksize(void *addr, int blk) 1277 { 1278 struct cs4281_softc *sc; 1279 int retval; 1280 1281 DPRINTFN(5,("cs4281_round_blocksize blk=%d -> ", blk)); 1282 1283 sc=addr; 1284 if (blk < sc->hw_blocksize) 1285 retval = sc->hw_blocksize; 1286 else 1287 retval = blk & -(sc->hw_blocksize); 1288 1289 DPRINTFN(5,("%d\n", retval)); 1290 1291 return (retval); 1292 } 1293 1294 int 1295 cs4281_mixer_set_port(void *addr, mixer_ctrl_t *cp) 1296 { 1297 struct cs4281_softc *sc; 1298 int val; 1299 1300 sc = addr; 1301 val = sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp); 1302 DPRINTFN(3,("mixer_set_port: val=%d\n", val)); 1303 return (val); 1304 } 1305 1306 int 1307 cs4281_mixer_get_port(void *addr, mixer_ctrl_t *cp) 1308 { 1309 struct cs4281_softc *sc; 1310 1311 sc = addr; 1312 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp)); 1313 } 1314 1315 1316 int 1317 cs4281_query_devinfo(void *addr, mixer_devinfo_t *dip) 1318 { 1319 struct cs4281_softc *sc; 1320 1321 sc = addr; 1322 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip)); 1323 } 1324 1325 void * 1326 cs4281_malloc(void *addr, int direction, size_t size, int pool, int flags) 1327 { 1328 struct cs4281_softc *sc; 1329 struct cs4281_dma *p; 1330 int error; 1331 1332 sc = addr; 1333 1334 p = malloc(sizeof(*p), pool, flags); 1335 if (!p) 1336 return (0); 1337 1338 error = cs4281_allocmem(sc, size, pool, flags, p); 1339 1340 if (error) { 1341 free(p, pool); 1342 return (0); 1343 } 1344 1345 p->next = sc->sc_dmas; 1346 sc->sc_dmas = p; 1347 return (BUFADDR(p)); 1348 } 1349 1350 1351 1352 void 1353 cs4281_free(void *addr, void *ptr, int pool) 1354 { 1355 struct cs4281_softc *sc; 1356 struct cs4281_dma **pp, *p; 1357 1358 sc = addr; 1359 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 1360 if (BUFADDR(p) == ptr) { 1361 bus_dmamap_unload(sc->sc_dmatag, p->map); 1362 bus_dmamap_destroy(sc->sc_dmatag, p->map); 1363 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 1364 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 1365 free(p->dum, pool); 1366 *pp = p->next; 1367 free(p, pool); 1368 return; 1369 } 1370 } 1371 } 1372 1373 size_t 1374 cs4281_round_buffersize(void *addr, int direction, size_t size) 1375 { 1376 /* The real dma buffersize are 4KB for CS4280 1377 * and 64kB/MAX_CHANNELS for CS4281. 1378 * But they are too small for high quality audio, 1379 * let the upper layer(audio) use a larger buffer. 1380 * (originally suggested by Lennart Augustsson.) 1381 */ 1382 return (size); 1383 } 1384 1385 paddr_t 1386 cs4281_mappage(void *addr, void *mem, off_t off, int prot) 1387 { 1388 struct cs4281_softc *sc; 1389 struct cs4281_dma *p; 1390 1391 sc = addr; 1392 if (off < 0) 1393 return -1; 1394 1395 for (p = sc->sc_dmas; p && BUFADDR(p) != mem; p = p->next) 1396 ; 1397 1398 if (!p) { 1399 DPRINTF(("cs4281_mappage: bad buffer address\n")); 1400 return (-1); 1401 } 1402 1403 return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, off, prot, 1404 BUS_DMA_WAITOK)); 1405 } 1406 1407 1408 int 1409 cs4281_get_props(void *addr) 1410 { 1411 int retval; 1412 1413 retval = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1414 #ifdef MMAP_READY 1415 retval |= AUDIO_PROP_MMAP; 1416 #endif 1417 return (retval); 1418 } 1419 1420 /* AC97 */ 1421 int 1422 cs4281_attach_codec(void *addr, struct ac97_codec_if *codec_if) 1423 { 1424 struct cs4281_softc *sc; 1425 1426 DPRINTF(("cs4281_attach_codec:\n")); 1427 sc = addr; 1428 sc->codec_if = codec_if; 1429 return (0); 1430 } 1431 1432 1433 int 1434 cs4281_read_codec(void *addr, u_int8_t ac97_addr, u_int16_t *ac97_data) 1435 { 1436 struct cs4281_softc *sc; 1437 u_int32_t acctl; 1438 int n; 1439 1440 sc = addr; 1441 1442 DPRINTFN(5,("read_codec: add=0x%02x ", ac97_addr)); 1443 /* 1444 * Make sure that there is not data sitting around from a preivous 1445 * uncompleted access. 1446 */ 1447 BA0READ4(sc, CS4281_ACSDA); 1448 1449 /* Set up AC97 control registers. */ 1450 BA0WRITE4(sc, CS4281_ACCAD, ac97_addr); 1451 BA0WRITE4(sc, CS4281_ACCDA, 0); 1452 1453 acctl = ACCTL_ESYN | ACCTL_VFRM | ACCTL_CRW | ACCTL_DCV; 1454 BA0WRITE4(sc, CS4281_ACCTL, acctl); 1455 1456 if (cs4281_src_wait(sc) < 0) { 1457 printf("%s: AC97 read prob. (DCV!=0) for add=0x%0x\n", 1458 sc->sc_dev.dv_xname, ac97_addr); 1459 return 1; 1460 } 1461 1462 /* wait for valid status bit is active */ 1463 n = 0; 1464 while ((BA0READ4(sc, CS4281_ACSTS) & ACSTS_VSTS) == 0) { 1465 delay(1); 1466 while (++n > 1000) { 1467 printf("%s: AC97 read fail (VSTS==0) for add=0x%0x\n", 1468 sc->sc_dev.dv_xname, ac97_addr); 1469 return 1; 1470 } 1471 } 1472 *ac97_data = BA0READ4(sc, CS4281_ACSDA); 1473 DPRINTFN(5,("data=0x%04x\n", *ac97_data)); 1474 return (0); 1475 } 1476 1477 int 1478 cs4281_write_codec(void *addr, u_int8_t ac97_addr, u_int16_t ac97_data) 1479 { 1480 struct cs4281_softc *sc; 1481 u_int32_t acctl; 1482 1483 sc = addr; 1484 1485 DPRINTFN(5,("write_codec: add=0x%02x data=0x%04x\n", ac97_addr, ac97_data)); 1486 BA0WRITE4(sc, CS4281_ACCAD, ac97_addr); 1487 BA0WRITE4(sc, CS4281_ACCDA, ac97_data); 1488 1489 acctl = ACCTL_ESYN | ACCTL_VFRM | ACCTL_DCV; 1490 BA0WRITE4(sc, CS4281_ACCTL, acctl); 1491 1492 if (cs4281_src_wait(sc) < 0) { 1493 printf("%s: AC97 write fail (DCV!=0) for add=0x%02x data=" 1494 "0x%04x\n", sc->sc_dev.dv_xname, ac97_addr, ac97_data); 1495 return (1); 1496 } 1497 return (0); 1498 } 1499 1500 int 1501 cs4281_allocmem(struct cs4281_softc *sc, size_t size, int pool, int flags, 1502 struct cs4281_dma *p) 1503 { 1504 int error; 1505 size_t align; 1506 1507 align = sc->dma_align; 1508 p->size = sc->dma_size; 1509 /* allocate memory for upper audio driver */ 1510 p->dum = malloc(size, pool, flags); 1511 if (!p->dum) 1512 return (1); 1513 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0, 1514 p->segs, nitems(p->segs), 1515 &p->nsegs, BUS_DMA_NOWAIT); 1516 if (error) { 1517 printf("%s: unable to allocate dma. error=%d\n", 1518 sc->sc_dev.dv_xname, error); 1519 return (error); 1520 } 1521 1522 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 1523 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 1524 if (error) { 1525 printf("%s: unable to map dma, error=%d\n", 1526 sc->sc_dev.dv_xname, error); 1527 goto free; 1528 } 1529 1530 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size, 1531 0, BUS_DMA_NOWAIT, &p->map); 1532 if (error) { 1533 printf("%s: unable to create dma map, error=%d\n", 1534 sc->sc_dev.dv_xname, error); 1535 goto unmap; 1536 } 1537 1538 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 1539 BUS_DMA_NOWAIT); 1540 if (error) { 1541 printf("%s: unable to load dma map, error=%d\n", 1542 sc->sc_dev.dv_xname, error); 1543 goto destroy; 1544 } 1545 return (0); 1546 1547 destroy: 1548 bus_dmamap_destroy(sc->sc_dmatag, p->map); 1549 unmap: 1550 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 1551 free: 1552 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 1553 return (error); 1554 } 1555 1556 1557 int 1558 cs4281_src_wait(sc) 1559 struct cs4281_softc *sc; 1560 { 1561 int n; 1562 1563 n = 0; 1564 while ((BA0READ4(sc, CS4281_ACCTL) & ACCTL_DCV)) { 1565 delay(1000); 1566 if (++n > 1000) 1567 return (-1); 1568 } 1569 return (0); 1570 } 1571