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