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