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