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