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