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