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