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