1 /* $NetBSD: cs4280.c,v 1.18 2001/11/13 07:48:41 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1999, 2000 Tatoku Ogaito. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Tatoku Ogaito 17 * for the NetBSD Project. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Cirrus Logic CS4280 (and maybe CS461x) driver. 35 * Data sheets can be found 36 * http://www.cirrus.com/ftp/pubs/4280.pdf 37 * http://www.cirrus.com/ftp/pubs/4297.pdf 38 * ftp://ftp.alsa-project.org/pub/manuals/cirrus/embedded_audio_spec.pdf 39 * ftp://ftp.alsa-project.org/pub/manuals/cirrus/embedded_audio_spec.doc 40 * 41 * Note: CS4610/CS4611 + CS423x ISA codec should be worked with 42 * wss* at pnpbios? 43 * or 44 * sb* at pnpbios? 45 * Since I could not find any documents on handling ISA codec, 46 * clcs does not support those chips. 47 */ 48 49 /* 50 * TODO 51 * Joystick support 52 */ 53 54 #include <sys/cdefs.h> 55 __KERNEL_RCSID(0, "$NetBSD: cs4280.c,v 1.18 2001/11/13 07:48:41 lukem Exp $"); 56 57 #include "midi.h" 58 59 #include <sys/param.h> 60 #include <sys/systm.h> 61 #include <sys/kernel.h> 62 #include <sys/fcntl.h> 63 #include <sys/malloc.h> 64 #include <sys/device.h> 65 #include <sys/proc.h> 66 #include <sys/types.h> 67 #include <sys/systm.h> 68 69 #include <dev/pci/pcidevs.h> 70 #include <dev/pci/pcivar.h> 71 #include <dev/pci/cs4280reg.h> 72 #include <dev/pci/cs4280_image.h> 73 #include <dev/pci/cs428xreg.h> 74 75 #include <sys/audioio.h> 76 #include <dev/audio_if.h> 77 #include <dev/midi_if.h> 78 #include <dev/mulaw.h> 79 #include <dev/auconv.h> 80 81 #include <dev/ic/ac97reg.h> 82 #include <dev/ic/ac97var.h> 83 84 #include <dev/pci/cs428x.h> 85 86 #include <machine/bus.h> 87 #include <machine/bswap.h> 88 89 #define BA1READ4(sc, r) bus_space_read_4((sc)->ba1t, (sc)->ba1h, (r)) 90 #define BA1WRITE4(sc, r, x) bus_space_write_4((sc)->ba1t, (sc)->ba1h, (r), (x)) 91 92 /* IF functions for audio driver */ 93 int cs4280_match(struct device *, struct cfdata *, void *); 94 void cs4280_attach(struct device *, struct device *, void *); 95 int cs4280_intr(void *); 96 int cs4280_query_encoding(void *, struct audio_encoding *); 97 int cs4280_set_params(void *, int, int, struct audio_params *, struct audio_params *); 98 int cs4280_halt_output(void *); 99 int cs4280_halt_input(void *); 100 int cs4280_getdev(void *, struct audio_device *); 101 int cs4280_trigger_output(void *, void *, void *, int, void (*)(void *), 102 void *, struct audio_params *); 103 int cs4280_trigger_input(void *, void *, void *, int, void (*)(void *), 104 void *, struct audio_params *); 105 106 void cs4280_reset_codec(void *); 107 108 /* For PowerHook */ 109 void cs4280_power(int, void *); 110 111 /* Internal functions */ 112 void cs4280_set_adc_rate(struct cs428x_softc *, int ); 113 void cs4280_set_dac_rate(struct cs428x_softc *, int ); 114 int cs4280_download(struct cs428x_softc *, const u_int32_t *, u_int32_t, u_int32_t); 115 int cs4280_download_image(struct cs428x_softc *); 116 void cs4280_reset(void *); 117 int cs4280_get_portnum_by_name(struct cs428x_softc *, char *, char *, char *); 118 int cs4280_init(struct cs428x_softc *, int); 119 void cs4280_clear_fifos(struct cs428x_softc *); 120 121 #if CS4280_DEBUG > 10 122 /* Thease two function is only for checking image loading is succeeded or not. */ 123 int cs4280_check_images(struct cs428x_softc *); 124 int cs4280_checkimage(struct cs428x_softc *, u_int32_t *, u_int32_t, u_int32_t); 125 #endif 126 127 struct audio_hw_if cs4280_hw_if = { 128 cs428x_open, 129 cs428x_close, 130 NULL, 131 cs4280_query_encoding, 132 cs4280_set_params, 133 cs428x_round_blocksize, 134 NULL, 135 NULL, 136 NULL, 137 NULL, 138 NULL, 139 cs4280_halt_output, 140 cs4280_halt_input, 141 NULL, 142 cs4280_getdev, 143 NULL, 144 cs428x_mixer_set_port, 145 cs428x_mixer_get_port, 146 cs428x_query_devinfo, 147 cs428x_malloc, 148 cs428x_free, 149 cs428x_round_buffersize, 150 cs428x_mappage, 151 cs428x_get_props, 152 cs4280_trigger_output, 153 cs4280_trigger_input, 154 NULL, 155 }; 156 157 #if NMIDI > 0 158 /* Midi Interface */ 159 int cs4280_midi_open(void *, int, void (*)(void *, int), 160 void (*)(void *), void *); 161 void cs4280_midi_close(void*); 162 int cs4280_midi_output(void *, int); 163 void cs4280_midi_getinfo(void *, struct midi_info *); 164 165 struct midi_hw_if cs4280_midi_hw_if = { 166 cs4280_midi_open, 167 cs4280_midi_close, 168 cs4280_midi_output, 169 cs4280_midi_getinfo, 170 0, 171 }; 172 #endif 173 174 struct cfattach clcs_ca = { 175 sizeof(struct cs428x_softc), cs4280_match, cs4280_attach 176 }; 177 178 struct audio_device cs4280_device = { 179 "CS4280", 180 "", 181 "cs4280" 182 }; 183 184 185 int 186 cs4280_match(parent, match, aux) 187 struct device *parent; 188 struct cfdata *match; 189 void *aux; 190 { 191 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 192 193 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CIRRUS) 194 return 0; 195 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CIRRUS_CS4280 196 #if 0 /* I can't confirm */ 197 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CIRRUS_CS4610 198 #endif 199 ) 200 return 1; 201 return 0; 202 } 203 204 void 205 cs4280_attach(parent, self, aux) 206 struct device *parent; 207 struct device *self; 208 void *aux; 209 { 210 struct cs428x_softc *sc = (struct cs428x_softc *)self; 211 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 212 pci_chipset_tag_t pc = pa->pa_pc; 213 char const *intrstr; 214 pci_intr_handle_t ih; 215 pcireg_t reg; 216 char devinfo[256]; 217 mixer_ctrl_t ctl; 218 u_int32_t mem; 219 int pci_pwrmgmt_cap_reg, pci_pwrmgmt_csr_reg; 220 221 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); 222 printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); 223 224 /* Map I/O register */ 225 if (pci_mapreg_map(pa, PCI_BA0, 226 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, 227 &sc->ba0t, &sc->ba0h, NULL, NULL)) { 228 printf("%s: can't map BA0 space\n", sc->sc_dev.dv_xname); 229 return; 230 } 231 if (pci_mapreg_map(pa, PCI_BA1, 232 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, 233 &sc->ba1t, &sc->ba1h, NULL, NULL)) { 234 printf("%s: can't map BA1 space\n", sc->sc_dev.dv_xname); 235 return; 236 } 237 238 sc->sc_dmatag = pa->pa_dmat; 239 240 /* Check and set Power State */ 241 if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT, 242 &pci_pwrmgmt_cap_reg, 0)) { 243 pci_pwrmgmt_csr_reg = pci_pwrmgmt_cap_reg + 4; 244 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 245 pci_pwrmgmt_csr_reg); 246 DPRINTF(("%s: Power State is %d\n", 247 sc->sc_dev.dv_xname, reg & PCI_PMCSR_STATE_MASK)); 248 if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) { 249 pci_conf_write(pc, pa->pa_tag, pci_pwrmgmt_csr_reg, 250 (reg & ~PCI_PMCSR_STATE_MASK) | 251 PCI_PMCSR_STATE_D0); 252 } 253 } 254 255 /* Enable the device (set bus master flag) */ 256 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 257 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 258 reg | PCI_COMMAND_MASTER_ENABLE); 259 260 /* LATENCY_TIMER setting */ 261 mem = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); 262 if ( PCI_LATTIMER(mem) < 32 ) { 263 mem &= 0xffff00ff; 264 mem |= 0x00002000; 265 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, mem); 266 } 267 268 /* Map and establish the interrupt. */ 269 if (pci_intr_map(pa, &ih)) { 270 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); 271 return; 272 } 273 intrstr = pci_intr_string(pc, ih); 274 275 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, cs4280_intr, sc); 276 if (sc->sc_ih == NULL) { 277 printf("%s: couldn't establish interrupt",sc->sc_dev.dv_xname); 278 if (intrstr != NULL) 279 printf(" at %s", intrstr); 280 printf("\n"); 281 return; 282 } 283 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); 284 285 /* Initialization */ 286 if(cs4280_init(sc, 1) != 0) 287 return; 288 289 sc->type = TYPE_CS4280; 290 sc->halt_input = cs4280_halt_input; 291 sc->halt_output = cs4280_halt_output; 292 293 /* setup buffer related parameters */ 294 sc->dma_size = CS4280_DCHUNK; 295 sc->dma_align = CS4280_DALIGN; 296 sc->hw_blocksize = CS4280_ICHUNK; 297 298 /* AC 97 attachment */ 299 sc->host_if.arg = sc; 300 sc->host_if.attach = cs428x_attach_codec; 301 sc->host_if.read = cs428x_read_codec; 302 sc->host_if.write = cs428x_write_codec; 303 sc->host_if.reset = cs4280_reset_codec; 304 if (ac97_attach(&sc->host_if) != 0) { 305 printf("%s: ac97_attach failed\n", sc->sc_dev.dv_xname); 306 return; 307 } 308 309 /* Turn mute off of DAC, CD and master volumes by default */ 310 ctl.type = AUDIO_MIXER_ENUM; 311 ctl.un.ord = 0; /* off */ 312 313 ctl.dev = cs4280_get_portnum_by_name(sc, AudioCoutputs, 314 AudioNmaster, AudioNmute); 315 cs428x_mixer_set_port(sc, &ctl); 316 317 ctl.dev = cs4280_get_portnum_by_name(sc, AudioCinputs, 318 AudioNdac, AudioNmute); 319 cs428x_mixer_set_port(sc, &ctl); 320 321 ctl.dev = cs4280_get_portnum_by_name(sc, AudioCinputs, 322 AudioNcd, AudioNmute); 323 cs428x_mixer_set_port(sc, &ctl); 324 325 audio_attach_mi(&cs4280_hw_if, sc, &sc->sc_dev); 326 327 #if NMIDI > 0 328 midi_attach_mi(&cs4280_midi_hw_if, sc, &sc->sc_dev); 329 #endif 330 331 sc->sc_suspend = PWR_RESUME; 332 sc->sc_powerhook = powerhook_establish(cs4280_power, sc); 333 } 334 335 /* Interrupt handling function */ 336 int 337 cs4280_intr(p) 338 void *p; 339 { 340 /* 341 * XXX 342 * 343 * Since CS4280 has only 4kB dma buffer and 344 * interrupt occurs every 2kB block, I create dummy buffer 345 * which returns to audio driver and actual dma buffer 346 * using in DMA transfer. 347 * 348 * 349 * ring buffer in audio.c is pointed by BUFADDR 350 * <------ ring buffer size == 64kB ------> 351 * <-----> blksize == 2048*(sc->sc_[pr]count) kB 352 * |= = = =|= = = =|= = = =|= = = =|= = = =| 353 * | | | | | | <- call audio_intp every 354 * sc->sc_[pr]_count time. 355 * 356 * actual dma buffer is pointed by KERNADDR 357 * <-> dma buffer size = 4kB 358 * |= =| 359 * 360 * 361 */ 362 struct cs428x_softc *sc = p; 363 u_int32_t intr, mem; 364 char * empty_dma; 365 int handled = 0; 366 367 /* grab interrupt register then clear it */ 368 intr = BA0READ4(sc, CS4280_HISR); 369 BA0WRITE4(sc, CS4280_HICR, HICR_CHGM | HICR_IEV); 370 371 /* Playback Interrupt */ 372 if (intr & HISR_PINT) { 373 handled = 1; 374 mem = BA1READ4(sc, CS4280_PFIE); 375 BA1WRITE4(sc, CS4280_PFIE, (mem & ~PFIE_PI_MASK) | PFIE_PI_DISABLE); 376 if (sc->sc_pintr) { 377 if ((sc->sc_pi%sc->sc_pcount) == 0) 378 sc->sc_pintr(sc->sc_parg); 379 } else { 380 printf("unexpected play intr\n"); 381 } 382 /* copy buffer */ 383 ++sc->sc_pi; 384 empty_dma = sc->sc_pdma->addr; 385 if (sc->sc_pi&1) 386 empty_dma += sc->hw_blocksize; 387 memcpy(empty_dma, sc->sc_pn, sc->hw_blocksize); 388 sc->sc_pn += sc->hw_blocksize; 389 if (sc->sc_pn >= sc->sc_pe) 390 sc->sc_pn = sc->sc_ps; 391 BA1WRITE4(sc, CS4280_PFIE, mem); 392 } 393 /* Capture Interrupt */ 394 if (intr & HISR_CINT) { 395 int i; 396 int16_t rdata; 397 398 handled = 1; 399 mem = BA1READ4(sc, CS4280_CIE); 400 BA1WRITE4(sc, CS4280_CIE, (mem & ~CIE_CI_MASK) | CIE_CI_DISABLE); 401 ++sc->sc_ri; 402 empty_dma = sc->sc_rdma->addr; 403 if ((sc->sc_ri&1) == 0) 404 empty_dma += sc->hw_blocksize; 405 406 /* 407 * XXX 408 * I think this audio data conversion should be 409 * happend in upper layer, but I put this here 410 * since there is no conversion function available. 411 */ 412 switch(sc->sc_rparam) { 413 case CF_16BIT_STEREO: 414 /* just copy it */ 415 memcpy(sc->sc_rn, empty_dma, sc->hw_blocksize); 416 sc->sc_rn += sc->hw_blocksize; 417 break; 418 case CF_16BIT_MONO: 419 for (i = 0; i < 512; i++) { 420 rdata = *((int16_t *)empty_dma)++>>1; 421 rdata += *((int16_t *)empty_dma)++>>1; 422 *((int16_t *)sc->sc_rn)++ = rdata; 423 } 424 break; 425 case CF_8BIT_STEREO: 426 for (i = 0; i < 512; i++) { 427 rdata = *((int16_t*)empty_dma)++; 428 *sc->sc_rn++ = rdata >> 8; 429 rdata = *((int16_t*)empty_dma)++; 430 *sc->sc_rn++ = rdata >> 8; 431 } 432 break; 433 case CF_8BIT_MONO: 434 for (i = 0; i < 512; i++) { 435 rdata = *((int16_t*)empty_dma)++ >>1; 436 rdata += *((int16_t*)empty_dma)++ >>1; 437 *sc->sc_rn++ = rdata >>8; 438 } 439 break; 440 default: 441 /* Should not reach here */ 442 printf("unknown sc->sc_rparam: %d\n", sc->sc_rparam); 443 } 444 if (sc->sc_rn >= sc->sc_re) 445 sc->sc_rn = sc->sc_rs; 446 BA1WRITE4(sc, CS4280_CIE, mem); 447 if (sc->sc_rintr) { 448 if ((sc->sc_ri%(sc->sc_rcount)) == 0) 449 sc->sc_rintr(sc->sc_rarg); 450 } else { 451 printf("unexpected record intr\n"); 452 } 453 } 454 455 #if NMIDI > 0 456 /* Midi port Interrupt */ 457 if (intr & HISR_MIDI) { 458 int data; 459 460 handled = 1; 461 DPRINTF(("i: %d: ", 462 BA0READ4(sc, CS4280_MIDSR))); 463 /* Read the received data */ 464 while ((sc->sc_iintr != NULL) && 465 ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_RBE) == 0)) { 466 data = BA0READ4(sc, CS4280_MIDRP) & MIDRP_MASK; 467 DPRINTF(("r:%x\n",data)); 468 sc->sc_iintr(sc->sc_arg, data); 469 } 470 471 /* Write the data */ 472 #if 1 473 /* XXX: 474 * It seems "Transmit Buffer Full" never activate until EOI 475 * is deliverd. Shall I throw EOI top of this routine ? 476 */ 477 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) { 478 DPRINTF(("w: ")); 479 if (sc->sc_ointr != NULL) 480 sc->sc_ointr(sc->sc_arg); 481 } 482 #else 483 while ((sc->sc_ointr != NULL) && 484 ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0)) { 485 DPRINTF(("w: ")); 486 sc->sc_ointr(sc->sc_arg); 487 } 488 #endif 489 DPRINTF(("\n")); 490 } 491 #endif 492 493 return handled; 494 } 495 496 int 497 cs4280_query_encoding(addr, fp) 498 void *addr; 499 struct audio_encoding *fp; 500 { 501 switch (fp->index) { 502 case 0: 503 strcpy(fp->name, AudioEulinear); 504 fp->encoding = AUDIO_ENCODING_ULINEAR; 505 fp->precision = 8; 506 fp->flags = 0; 507 break; 508 case 1: 509 strcpy(fp->name, AudioEmulaw); 510 fp->encoding = AUDIO_ENCODING_ULAW; 511 fp->precision = 8; 512 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 513 break; 514 case 2: 515 strcpy(fp->name, AudioEalaw); 516 fp->encoding = AUDIO_ENCODING_ALAW; 517 fp->precision = 8; 518 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 519 break; 520 case 3: 521 strcpy(fp->name, AudioEslinear); 522 fp->encoding = AUDIO_ENCODING_SLINEAR; 523 fp->precision = 8; 524 fp->flags = 0; 525 break; 526 case 4: 527 strcpy(fp->name, AudioEslinear_le); 528 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 529 fp->precision = 16; 530 fp->flags = 0; 531 break; 532 case 5: 533 strcpy(fp->name, AudioEulinear_le); 534 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 535 fp->precision = 16; 536 fp->flags = 0; 537 break; 538 case 6: 539 strcpy(fp->name, AudioEslinear_be); 540 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 541 fp->precision = 16; 542 fp->flags = 0; 543 break; 544 case 7: 545 strcpy(fp->name, AudioEulinear_be); 546 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 547 fp->precision = 16; 548 fp->flags = 0; 549 break; 550 default: 551 return EINVAL; 552 } 553 return 0; 554 } 555 556 int 557 cs4280_set_params(addr, setmode, usemode, play, rec) 558 void *addr; 559 int setmode, usemode; 560 struct audio_params *play, *rec; 561 { 562 struct cs428x_softc *sc = addr; 563 struct audio_params *p; 564 int mode; 565 566 for (mode = AUMODE_RECORD; mode != -1; 567 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1 ) { 568 if ((setmode & mode) == 0) 569 continue; 570 571 p = mode == AUMODE_PLAY ? play : rec; 572 573 if (p == play) { 574 DPRINTFN(5,("play: sample=%ld precision=%d channels=%d\n", 575 p->sample_rate, p->precision, p->channels)); 576 /* play back data format may be 8- or 16-bit and 577 * either stereo or mono. 578 * playback rate may range from 8000Hz to 48000Hz 579 */ 580 if (p->sample_rate < 8000 || p->sample_rate > 48000 || 581 (p->precision != 8 && p->precision != 16) || 582 (p->channels != 1 && p->channels != 2) ) { 583 return EINVAL; 584 } 585 } else { 586 DPRINTFN(5,("rec: sample=%ld precision=%d channels=%d\n", 587 p->sample_rate, p->precision, p->channels)); 588 /* capture data format must be 16bit stereo 589 * and sample rate range from 11025Hz to 48000Hz. 590 * 591 * XXX: it looks like to work with 8000Hz, 592 * although data sheets say lower limit is 593 * 11025 Hz. 594 */ 595 596 if (p->sample_rate < 8000 || p->sample_rate > 48000 || 597 (p->precision != 8 && p->precision != 16) || 598 (p->channels != 1 && p->channels != 2) ) { 599 return EINVAL; 600 } 601 } 602 p->factor = 1; 603 p->sw_code = 0; 604 605 /* capturing data is slinear */ 606 switch (p->encoding) { 607 case AUDIO_ENCODING_SLINEAR_BE: 608 if (mode == AUMODE_RECORD) { 609 if (p->precision == 16) 610 p->sw_code = swap_bytes; 611 } 612 break; 613 case AUDIO_ENCODING_SLINEAR_LE: 614 break; 615 case AUDIO_ENCODING_ULINEAR_BE: 616 if (mode == AUMODE_RECORD) { 617 if (p->precision == 16) 618 p->sw_code = change_sign16_swap_bytes_le; 619 else 620 p->sw_code = change_sign8; 621 } 622 break; 623 case AUDIO_ENCODING_ULINEAR_LE: 624 if (mode == AUMODE_RECORD) { 625 if (p->precision == 16) 626 p->sw_code = change_sign16_le; 627 else 628 p->sw_code = change_sign8; 629 } 630 break; 631 case AUDIO_ENCODING_ULAW: 632 if (mode == AUMODE_PLAY) { 633 p->factor = 2; 634 p->sw_code = mulaw_to_slinear16_le; 635 } else { 636 p->sw_code = slinear8_to_mulaw; 637 } 638 break; 639 case AUDIO_ENCODING_ALAW: 640 if (mode == AUMODE_PLAY) { 641 p->factor = 2; 642 p->sw_code = alaw_to_slinear16_le; 643 } else { 644 p->sw_code = slinear8_to_alaw; 645 } 646 break; 647 default: 648 return EINVAL; 649 } 650 } 651 652 /* set sample rate */ 653 cs4280_set_dac_rate(sc, play->sample_rate); 654 cs4280_set_adc_rate(sc, rec->sample_rate); 655 return 0; 656 } 657 658 int 659 cs4280_halt_output(addr) 660 void *addr; 661 { 662 struct cs428x_softc *sc = addr; 663 u_int32_t mem; 664 665 mem = BA1READ4(sc, CS4280_PCTL); 666 BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK); 667 sc->sc_prun = 0; 668 return 0; 669 } 670 671 int 672 cs4280_halt_input(addr) 673 void *addr; 674 { 675 struct cs428x_softc *sc = addr; 676 u_int32_t mem; 677 678 mem = BA1READ4(sc, CS4280_CCTL); 679 BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK); 680 sc->sc_rrun = 0; 681 return 0; 682 } 683 684 int 685 cs4280_getdev(addr, retp) 686 void *addr; 687 struct audio_device *retp; 688 { 689 *retp = cs4280_device; 690 return 0; 691 } 692 693 int 694 cs4280_trigger_output(addr, start, end, blksize, intr, arg, param) 695 void *addr; 696 void *start, *end; 697 int blksize; 698 void (*intr) __P((void *)); 699 void *arg; 700 struct audio_params *param; 701 { 702 struct cs428x_softc *sc = addr; 703 u_int32_t pfie, pctl, pdtc; 704 struct cs428x_dma *p; 705 706 #ifdef DIAGNOSTIC 707 if (sc->sc_prun) 708 printf("cs4280_trigger_output: already running\n"); 709 #endif 710 sc->sc_prun = 1; 711 712 DPRINTF(("cs4280_trigger_output: sc=%p start=%p end=%p " 713 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 714 sc->sc_pintr = intr; 715 sc->sc_parg = arg; 716 717 /* stop playback DMA */ 718 BA1WRITE4(sc, CS4280_PCTL, BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK); 719 720 /* setup PDTC */ 721 pdtc = BA1READ4(sc, CS4280_PDTC); 722 pdtc &= ~PDTC_MASK; 723 pdtc |= CS4280_MK_PDTC(param->precision * param->channels); 724 BA1WRITE4(sc, CS4280_PDTC, pdtc); 725 726 DPRINTF(("param: precision=%d factor=%d channels=%d encoding=%d\n", 727 param->precision, param->factor, param->channels, 728 param->encoding)); 729 for (p = sc->sc_dmas; p != NULL && BUFADDR(p) != start; p = p->next) 730 ; 731 if (p == NULL) { 732 printf("cs4280_trigger_output: bad addr %p\n", start); 733 return EINVAL; 734 } 735 if (DMAADDR(p) % sc->dma_align != 0 ) { 736 printf("cs4280_trigger_output: DMAADDR(p)=0x%lx does not start" 737 "4kB align\n", DMAADDR(p)); 738 return EINVAL; 739 } 740 741 sc->sc_pcount = blksize / sc->hw_blocksize; /* sc->hw_blocksize is fixed hardware blksize*/ 742 sc->sc_ps = (char *)start; 743 sc->sc_pe = (char *)end; 744 sc->sc_pdma = p; 745 sc->sc_pbuf = KERNADDR(p); 746 sc->sc_pi = 0; 747 sc->sc_pn = sc->sc_ps; 748 if (blksize >= sc->dma_size) { 749 sc->sc_pn = sc->sc_ps + sc->dma_size; 750 memcpy(sc->sc_pbuf, start, sc->dma_size); 751 ++sc->sc_pi; 752 } else { 753 sc->sc_pn = sc->sc_ps + sc->hw_blocksize; 754 memcpy(sc->sc_pbuf, start, sc->hw_blocksize); 755 } 756 757 /* initiate playback dma */ 758 BA1WRITE4(sc, CS4280_PBA, DMAADDR(p)); 759 760 /* set PFIE */ 761 pfie = BA1READ4(sc, CS4280_PFIE) & ~PFIE_MASK; 762 763 if (param->precision * param->factor == 8) 764 pfie |= PFIE_8BIT; 765 if (param->channels == 1) 766 pfie |= PFIE_MONO; 767 768 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 769 param->encoding == AUDIO_ENCODING_SLINEAR_BE) 770 pfie |= PFIE_SWAPPED; 771 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 772 param->encoding == AUDIO_ENCODING_ULINEAR_LE) 773 pfie |= PFIE_UNSIGNED; 774 775 BA1WRITE4(sc, CS4280_PFIE, pfie | PFIE_PI_ENABLE); 776 777 sc->sc_prate = param->sample_rate; 778 cs4280_set_dac_rate(sc, param->sample_rate); 779 780 pctl = BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK; 781 pctl |= sc->pctl; 782 BA1WRITE4(sc, CS4280_PCTL, pctl); 783 return 0; 784 } 785 786 int 787 cs4280_trigger_input(addr, start, end, blksize, intr, arg, param) 788 void *addr; 789 void *start, *end; 790 int blksize; 791 void (*intr) __P((void *)); 792 void *arg; 793 struct audio_params *param; 794 { 795 struct cs428x_softc *sc = addr; 796 u_int32_t cctl, cie; 797 struct cs428x_dma *p; 798 799 #ifdef DIAGNOSTIC 800 if (sc->sc_rrun) 801 printf("cs4280_trigger_input: already running\n"); 802 #endif 803 sc->sc_rrun = 1; 804 805 DPRINTF(("cs4280_trigger_input: sc=%p start=%p end=%p " 806 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 807 sc->sc_rintr = intr; 808 sc->sc_rarg = arg; 809 810 /* stop capture DMA */ 811 BA1WRITE4(sc, CS4280_CCTL, BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK); 812 813 for (p = sc->sc_dmas; p && BUFADDR(p) != start; p = p->next) 814 ; 815 if (p == NULL) { 816 printf("cs4280_trigger_input: bad addr %p\n", start); 817 return EINVAL; 818 } 819 if (DMAADDR(p) % sc->dma_align != 0) { 820 printf("cs4280_trigger_input: DMAADDR(p)=0x%lx does not start" 821 "4kB align\n", DMAADDR(p)); 822 return EINVAL; 823 } 824 825 sc->sc_rcount = blksize / sc->hw_blocksize; /* sc->hw_blocksize is fixed hardware blksize*/ 826 sc->sc_rs = (char *)start; 827 sc->sc_re = (char *)end; 828 sc->sc_rdma = p; 829 sc->sc_rbuf = KERNADDR(p); 830 sc->sc_ri = 0; 831 sc->sc_rn = sc->sc_rs; 832 833 /* initiate capture dma */ 834 BA1WRITE4(sc, CS4280_CBA, DMAADDR(p)); 835 836 /* setup format information for internal converter */ 837 sc->sc_rparam = 0; 838 if (param->precision == 8) { 839 sc->sc_rparam += CF_8BIT; 840 sc->sc_rcount <<= 1; 841 } 842 if (param->channels == 1) { 843 sc->sc_rparam += CF_MONO; 844 sc->sc_rcount <<= 1; 845 } 846 847 /* set CIE */ 848 cie = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK; 849 BA1WRITE4(sc, CS4280_CIE, cie | CIE_CI_ENABLE); 850 851 sc->sc_rrate = param->sample_rate; 852 cs4280_set_adc_rate(sc, param->sample_rate); 853 854 cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK; 855 cctl |= sc->cctl; 856 BA1WRITE4(sc, CS4280_CCTL, cctl); 857 return 0; 858 } 859 860 /* Power Hook */ 861 void 862 cs4280_power(why, v) 863 int why; 864 void *v; 865 { 866 struct cs428x_softc *sc = (struct cs428x_softc *)v; 867 static u_int32_t pctl = 0, pba = 0, pfie = 0, pdtc = 0; 868 static u_int32_t cctl = 0, cba = 0, cie = 0; 869 870 DPRINTF(("%s: cs4280_power why=%d\n", 871 sc->sc_dev.dv_xname, why)); 872 switch (why) { 873 case PWR_SUSPEND: 874 case PWR_STANDBY: 875 sc->sc_suspend = why; 876 877 /* save current playback status */ 878 if ( sc->sc_prun ) { 879 pctl = BA1READ4(sc, CS4280_PCTL); 880 pfie = BA1READ4(sc, CS4280_PFIE); 881 pba = BA1READ4(sc, CS4280_PBA); 882 pdtc = BA1READ4(sc, CS4280_PDTC); 883 DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n", 884 pctl, pfie, pba, pdtc)); 885 } 886 887 /* save current capture status */ 888 if ( sc->sc_rrun ) { 889 cctl = BA1READ4(sc, CS4280_CCTL); 890 cie = BA1READ4(sc, CS4280_CIE); 891 cba = BA1READ4(sc, CS4280_CBA); 892 DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n", 893 cctl, cie, cba)); 894 } 895 896 /* Stop DMA */ 897 BA1WRITE4(sc, CS4280_PCTL, pctl & ~PCTL_MASK); 898 BA1WRITE4(sc, CS4280_CCTL, BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK); 899 break; 900 case PWR_RESUME: 901 if (sc->sc_suspend == PWR_RESUME) { 902 printf("cs4280_power: odd, resume without suspend.\n"); 903 sc->sc_suspend = why; 904 return; 905 } 906 sc->sc_suspend = why; 907 cs4280_init(sc, 0); 908 cs4280_reset_codec(sc); 909 910 /* restore ac97 registers */ 911 (*sc->codec_if->vtbl->restore_ports)(sc->codec_if); 912 913 /* restore DMA related status */ 914 if(sc->sc_prun) { 915 DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n", 916 pctl, pfie, pba, pdtc)); 917 cs4280_set_dac_rate(sc, sc->sc_prate); 918 BA1WRITE4(sc, CS4280_PDTC, pdtc); 919 BA1WRITE4(sc, CS4280_PBA, pba); 920 BA1WRITE4(sc, CS4280_PFIE, pfie); 921 BA1WRITE4(sc, CS4280_PCTL, pctl); 922 } 923 924 if (sc->sc_rrun) { 925 DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n", 926 cctl, cie, cba)); 927 cs4280_set_adc_rate(sc, sc->sc_rrate); 928 BA1WRITE4(sc, CS4280_CBA, cba); 929 BA1WRITE4(sc, CS4280_CIE, cie); 930 BA1WRITE4(sc, CS4280_CCTL, cctl); 931 } 932 break; 933 case PWR_SOFTSUSPEND: 934 case PWR_SOFTSTANDBY: 935 case PWR_SOFTRESUME: 936 break; 937 } 938 } 939 940 /* control AC97 codec */ 941 void 942 cs4280_reset_codec(void *addr) 943 { 944 struct cs428x_softc *sc; 945 int n; 946 947 sc = addr; 948 949 /* Reset codec */ 950 BA0WRITE4(sc, CS428X_ACCTL, 0); 951 delay(100); /* delay 100us */ 952 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_RSTN); 953 954 /* 955 * It looks like we do the following procedure, too 956 */ 957 958 /* Enable AC-link sync generation */ 959 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN | ACCTL_RSTN); 960 delay(50*1000); /* XXX delay 50ms */ 961 962 /* Assert valid frame signal */ 963 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 964 965 /* Wait for valid AC97 input slot */ 966 n = 0; 967 while ((BA0READ4(sc, CS428X_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) != 968 (ACISV_ISV3 | ACISV_ISV4)) { 969 delay(1000); 970 if (++n > 1000) { 971 printf("reset_codec: AC97 inputs slot ready timeout\n"); 972 return; 973 } 974 } 975 } 976 977 978 /* Internal functions */ 979 980 void 981 cs4280_set_adc_rate(sc, rate) 982 struct cs428x_softc *sc; 983 int rate; 984 { 985 /* calculate capture rate: 986 * 987 * capture_coefficient_increment = -round(rate*128*65536/48000; 988 * capture_phase_increment = floor(48000*65536*1024/rate); 989 * cx = round(48000*65536*1024 - capture_phase_increment*rate); 990 * cy = floor(cx/200); 991 * capture_sample_rate_correction = cx - 200*cy; 992 * capture_delay = ceil(24*48000/rate); 993 * capture_num_triplets = floor(65536*rate/24000); 994 * capture_group_length = 24000/GCD(rate, 24000); 995 * where GCD means "Greatest Common Divisor". 996 * 997 * capture_coefficient_increment, capture_phase_increment and 998 * capture_num_triplets are 32-bit signed quantities. 999 * capture_sample_rate_correction and capture_group_length are 1000 * 16-bit signed quantities. 1001 * capture_delay is a 14-bit unsigned quantity. 1002 */ 1003 u_int32_t cci,cpi,cnt,cx,cy, tmp1; 1004 u_int16_t csrc, cgl, cdlay; 1005 1006 /* XXX 1007 * Even though, embedded_audio_spec says capture rate range 11025 to 1008 * 48000, dhwiface.cpp says, 1009 * 1010 * "We can only decimate by up to a factor of 1/9th the hardware rate. 1011 * Return an error if an attempt is made to stray outside that limit." 1012 * 1013 * so assume range as 48000/9 to 48000 1014 */ 1015 1016 if (rate < 8000) 1017 rate = 8000; 1018 if (rate > 48000) 1019 rate = 48000; 1020 1021 cx = rate << 16; 1022 cci = cx / 48000; 1023 cx -= cci * 48000; 1024 cx <<= 7; 1025 cci <<= 7; 1026 cci += cx / 48000; 1027 cci = - cci; 1028 1029 cx = 48000 << 16; 1030 cpi = cx / rate; 1031 cx -= cpi * rate; 1032 cx <<= 10; 1033 cpi <<= 10; 1034 cy = cx / rate; 1035 cpi += cy; 1036 cx -= cy * rate; 1037 1038 cy = cx / 200; 1039 csrc = cx - 200*cy; 1040 1041 cdlay = ((48000 * 24) + rate - 1) / rate; 1042 #if 0 1043 cdlay &= 0x3fff; /* make sure cdlay is 14-bit */ 1044 #endif 1045 1046 cnt = rate << 16; 1047 cnt /= 24000; 1048 1049 cgl = 1; 1050 for (tmp1 = 2; tmp1 <= 64; tmp1 *= 2) { 1051 if (((rate / tmp1) * tmp1) != rate) 1052 cgl *= 2; 1053 } 1054 if (((rate / 3) * 3) != rate) 1055 cgl *= 3; 1056 for (tmp1 = 5; tmp1 <= 125; tmp1 *= 5) { 1057 if (((rate / tmp1) * tmp1) != rate) 1058 cgl *= 5; 1059 } 1060 #if 0 1061 /* XXX what manual says */ 1062 tmp1 = BA1READ4(sc, CS4280_CSRC) & ~CSRC_MASK; 1063 tmp1 |= csrc<<16; 1064 BA1WRITE4(sc, CS4280_CSRC, tmp1); 1065 #else 1066 /* suggested by cs461x.c (ALSA driver) */ 1067 BA1WRITE4(sc, CS4280_CSRC, CS4280_MK_CSRC(csrc, cy)); 1068 #endif 1069 1070 #if 0 1071 /* I am confused. The sample rate calculation section says 1072 * cci *is* 32-bit signed quantity but in the parameter description 1073 * section, CCI only assigned 16bit. 1074 * I believe size of the variable. 1075 */ 1076 tmp1 = BA1READ4(sc, CS4280_CCI) & ~CCI_MASK; 1077 tmp1 |= cci<<16; 1078 BA1WRITE4(sc, CS4280_CCI, tmp1); 1079 #else 1080 BA1WRITE4(sc, CS4280_CCI, cci); 1081 #endif 1082 1083 tmp1 = BA1READ4(sc, CS4280_CD) & ~CD_MASK; 1084 tmp1 |= cdlay <<18; 1085 BA1WRITE4(sc, CS4280_CD, tmp1); 1086 1087 BA1WRITE4(sc, CS4280_CPI, cpi); 1088 1089 tmp1 = BA1READ4(sc, CS4280_CGL) & ~CGL_MASK; 1090 tmp1 |= cgl; 1091 BA1WRITE4(sc, CS4280_CGL, tmp1); 1092 1093 BA1WRITE4(sc, CS4280_CNT, cnt); 1094 1095 tmp1 = BA1READ4(sc, CS4280_CGC) & ~CGC_MASK; 1096 tmp1 |= cgl; 1097 BA1WRITE4(sc, CS4280_CGC, tmp1); 1098 } 1099 1100 void 1101 cs4280_set_dac_rate(sc, rate) 1102 struct cs428x_softc *sc; 1103 int rate; 1104 { 1105 /* 1106 * playback rate may range from 8000Hz to 48000Hz 1107 * 1108 * play_phase_increment = floor(rate*65536*1024/48000) 1109 * px = round(rate*65536*1024 - play_phase_incremnt*48000) 1110 * py=floor(px/200) 1111 * play_sample_rate_correction = px - 200*py 1112 * 1113 * play_phase_increment is a 32bit signed quantity. 1114 * play_sample_rate_correction is a 16bit signed quantity. 1115 */ 1116 int32_t ppi; 1117 int16_t psrc; 1118 u_int32_t px, py; 1119 1120 if (rate < 8000) 1121 rate = 8000; 1122 if (rate > 48000) 1123 rate = 48000; 1124 px = rate << 16; 1125 ppi = px/48000; 1126 px -= ppi*48000; 1127 ppi <<= 10; 1128 px <<= 10; 1129 py = px / 48000; 1130 ppi += py; 1131 px -= py*48000; 1132 py = px/200; 1133 px -= py*200; 1134 psrc = px; 1135 #if 0 1136 /* what manual says */ 1137 px = BA1READ4(sc, CS4280_PSRC) & ~PSRC_MASK; 1138 BA1WRITE4(sc, CS4280_PSRC, 1139 ( ((psrc<<16) & PSRC_MASK) | px )); 1140 #else 1141 /* suggested by cs461x.c (ALSA driver) */ 1142 BA1WRITE4(sc, CS4280_PSRC, CS4280_MK_PSRC(psrc,py)); 1143 #endif 1144 BA1WRITE4(sc, CS4280_PPI, ppi); 1145 } 1146 1147 /* Download Proceessor Code and Data image */ 1148 int 1149 cs4280_download(sc, src, offset, len) 1150 struct cs428x_softc *sc; 1151 const u_int32_t *src; 1152 u_int32_t offset, len; 1153 { 1154 u_int32_t ctr; 1155 1156 #if CS4280_DEBUG > 10 1157 u_int32_t con, data; 1158 u_int8_t c0,c1,c2,c3; 1159 #endif 1160 if ((offset&3) || (len&3)) 1161 return -1; 1162 1163 len /= sizeof(u_int32_t); 1164 for (ctr = 0; ctr < len; ctr++) { 1165 /* XXX: 1166 * I cannot confirm this is the right thing or not 1167 * on BIG-ENDIAN machines. 1168 */ 1169 BA1WRITE4(sc, offset+ctr*4, htole32(*(src+ctr))); 1170 #if CS4280_DEBUG > 10 1171 data = htole32(*(src+ctr)); 1172 c0 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+0); 1173 c1 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+1); 1174 c2 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+2); 1175 c3 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+3); 1176 con = ( (c3<<24) | (c2<<16) | (c1<<8) | c0 ); 1177 if (data != con ) { 1178 printf("0x%06x: write=0x%08x read=0x%08x\n", 1179 offset+ctr*4, data, con); 1180 return -1; 1181 } 1182 #endif 1183 } 1184 return 0; 1185 } 1186 1187 int 1188 cs4280_download_image(sc) 1189 struct cs428x_softc *sc; 1190 { 1191 int idx, err; 1192 u_int32_t offset = 0; 1193 1194 err = 0; 1195 for (idx = 0; idx < BA1_MEMORY_COUNT; ++idx) { 1196 err = cs4280_download(sc, &BA1Struct.map[offset], 1197 BA1Struct.memory[idx].offset, 1198 BA1Struct.memory[idx].size); 1199 if (err != 0) { 1200 printf("%s: load_image failed at %d\n", 1201 sc->sc_dev.dv_xname, idx); 1202 return -1; 1203 } 1204 offset += BA1Struct.memory[idx].size / sizeof(u_int32_t); 1205 } 1206 return err; 1207 } 1208 1209 /* Processor Soft Reset */ 1210 void 1211 cs4280_reset(sc_) 1212 void *sc_; 1213 { 1214 struct cs428x_softc *sc = sc_; 1215 1216 /* Set RSTSP bit in SPCR (also clear RUN, RUNFR, and DRQEN) */ 1217 BA1WRITE4(sc, CS4280_SPCR, SPCR_RSTSP); 1218 delay(100); 1219 /* Clear RSTSP bit in SPCR */ 1220 BA1WRITE4(sc, CS4280_SPCR, 0); 1221 /* enable DMA reqest */ 1222 BA1WRITE4(sc, CS4280_SPCR, SPCR_DRQEN); 1223 } 1224 1225 int 1226 cs4280_get_portnum_by_name(sc, class, device, qualifier) 1227 struct cs428x_softc *sc; 1228 char *class, *device, *qualifier; 1229 { 1230 return (sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, class, 1231 device, qualifier)); 1232 } 1233 1234 int 1235 cs4280_init(sc, init) 1236 struct cs428x_softc *sc; 1237 int init; 1238 { 1239 int n; 1240 u_int32_t mem; 1241 1242 /* Start PLL out in known state */ 1243 BA0WRITE4(sc, CS4280_CLKCR1, 0); 1244 /* Start serial ports out in known state */ 1245 BA0WRITE4(sc, CS4280_SERMC1, 0); 1246 1247 /* Specify type of CODEC */ 1248 /* XXX should not be here */ 1249 #define SERACC_CODEC_TYPE_1_03 1250 #ifdef SERACC_CODEC_TYPE_1_03 1251 BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_1_03); /* AC 97 1.03 */ 1252 #else 1253 BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_2_0); /* AC 97 2.0 */ 1254 #endif 1255 1256 /* Reset codec */ 1257 BA0WRITE4(sc, CS428X_ACCTL, 0); 1258 delay(100); /* delay 100us */ 1259 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_RSTN); 1260 1261 /* Enable AC-link sync generation */ 1262 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN | ACCTL_RSTN); 1263 delay(50*1000); /* delay 50ms */ 1264 1265 /* Set the serial port timing configuration */ 1266 BA0WRITE4(sc, CS4280_SERMC1, SERMC1_PTC_AC97); 1267 1268 /* Setup clock control */ 1269 BA0WRITE4(sc, CS4280_PLLCC, PLLCC_CDR_STATE|PLLCC_LPF_STATE); 1270 BA0WRITE4(sc, CS4280_PLLM, PLLM_STATE); 1271 BA0WRITE4(sc, CS4280_CLKCR2, CLKCR2_PDIVS_8); 1272 1273 /* Power up the PLL */ 1274 BA0WRITE4(sc, CS4280_CLKCR1, CLKCR1_PLLP); 1275 delay(50*1000); /* delay 50ms */ 1276 1277 /* Turn on clock */ 1278 mem = BA0READ4(sc, CS4280_CLKCR1) | CLKCR1_SWCE; 1279 BA0WRITE4(sc, CS4280_CLKCR1, mem); 1280 1281 /* Set the serial port FIFO pointer to the 1282 * first sample in FIFO. (not documented) */ 1283 cs4280_clear_fifos(sc); 1284 1285 #if 0 1286 /* Set the serial port FIFO pointer to the first sample in the FIFO */ 1287 BA0WRITE4(sc, CS4280_SERBSP, 0); 1288 #endif 1289 1290 /* Configure the serial port */ 1291 BA0WRITE4(sc, CS4280_SERC1, SERC1_SO1EN | SERC1_SO1F_AC97); 1292 BA0WRITE4(sc, CS4280_SERC2, SERC2_SI1EN | SERC2_SI1F_AC97); 1293 BA0WRITE4(sc, CS4280_SERMC1, SERMC1_MSPE | SERMC1_PTC_AC97); 1294 1295 /* Wait for CODEC ready */ 1296 n = 0; 1297 while ((BA0READ4(sc, CS428X_ACSTS) & ACSTS_CRDY) == 0) { 1298 delay(125); 1299 if (++n > 1000) { 1300 printf("%s: codec ready timeout\n", 1301 sc->sc_dev.dv_xname); 1302 return(1); 1303 } 1304 } 1305 1306 /* Assert valid frame signal */ 1307 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 1308 1309 /* Wait for valid AC97 input slot */ 1310 n = 0; 1311 while ((BA0READ4(sc, CS428X_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) != 1312 (ACISV_ISV3 | ACISV_ISV4)) { 1313 delay(1000); 1314 if (++n > 1000) { 1315 printf("AC97 inputs slot ready timeout\n"); 1316 return(1); 1317 } 1318 } 1319 1320 /* Set AC97 output slot valid signals */ 1321 BA0WRITE4(sc, CS428X_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); 1322 1323 /* reset the processor */ 1324 cs4280_reset(sc); 1325 1326 /* Download the image to the processor */ 1327 if (cs4280_download_image(sc) != 0) { 1328 printf("%s: image download error\n", sc->sc_dev.dv_xname); 1329 return(1); 1330 } 1331 1332 /* Save playback parameter and then write zero. 1333 * this ensures that DMA doesn't immediately occur upon 1334 * starting the processor core 1335 */ 1336 mem = BA1READ4(sc, CS4280_PCTL); 1337 sc->pctl = mem & PCTL_MASK; /* save startup value */ 1338 BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK); 1339 if (init != 0) 1340 sc->sc_prun = 0; 1341 1342 /* Save capture parameter and then write zero. 1343 * this ensures that DMA doesn't immediately occur upon 1344 * starting the processor core 1345 */ 1346 mem = BA1READ4(sc, CS4280_CCTL); 1347 sc->cctl = mem & CCTL_MASK; /* save startup value */ 1348 BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK); 1349 if (init != 0) 1350 sc->sc_rrun = 0; 1351 1352 /* Processor Startup Procedure */ 1353 BA1WRITE4(sc, CS4280_FRMT, FRMT_FTV); 1354 BA1WRITE4(sc, CS4280_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); 1355 1356 /* Monitor RUNFR bit in SPCR for 1 to 0 transition */ 1357 n = 0; 1358 while (BA1READ4(sc, CS4280_SPCR) & SPCR_RUNFR) { 1359 delay(10); 1360 if (++n > 1000) { 1361 printf("SPCR 1->0 transition timeout\n"); 1362 return(1); 1363 } 1364 } 1365 1366 n = 0; 1367 while (!(BA1READ4(sc, CS4280_SPCS) & SPCS_SPRUN)) { 1368 delay(10); 1369 if (++n > 1000) { 1370 printf("SPCS 0->1 transition timeout\n"); 1371 return(1); 1372 } 1373 } 1374 /* Processor is now running !!! */ 1375 1376 /* Setup volume */ 1377 BA1WRITE4(sc, CS4280_PVOL, 0x80008000); 1378 BA1WRITE4(sc, CS4280_CVOL, 0x80008000); 1379 1380 /* Interrupt enable */ 1381 BA0WRITE4(sc, CS4280_HICR, HICR_IEV|HICR_CHGM); 1382 1383 /* playback interrupt enable */ 1384 mem = BA1READ4(sc, CS4280_PFIE) & ~PFIE_PI_MASK; 1385 mem |= PFIE_PI_ENABLE; 1386 BA1WRITE4(sc, CS4280_PFIE, mem); 1387 /* capture interrupt enable */ 1388 mem = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK; 1389 mem |= CIE_CI_ENABLE; 1390 BA1WRITE4(sc, CS4280_CIE, mem); 1391 1392 #if NMIDI > 0 1393 /* Reset midi port */ 1394 mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK; 1395 BA0WRITE4(sc, CS4280_MIDCR, mem | MIDCR_MRST); 1396 DPRINTF(("midi reset: 0x%x\n", BA0READ4(sc, CS4280_MIDCR))); 1397 /* midi interrupt enable */ 1398 mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE; 1399 BA0WRITE4(sc, CS4280_MIDCR, mem); 1400 #endif 1401 return(0); 1402 } 1403 1404 void 1405 cs4280_clear_fifos(sc) 1406 struct cs428x_softc *sc; 1407 { 1408 int pd = 0, cnt, n; 1409 u_int32_t mem; 1410 1411 /* 1412 * If device power down, power up the device and keep power down 1413 * state. 1414 */ 1415 mem = BA0READ4(sc, CS4280_CLKCR1); 1416 if (!(mem & CLKCR1_SWCE)) { 1417 printf("cs4280_clear_fifo: power down found.\n"); 1418 BA0WRITE4(sc, CS4280_CLKCR1, mem | CLKCR1_SWCE); 1419 pd = 1; 1420 } 1421 BA0WRITE4(sc, CS4280_SERBWP, 0); 1422 for (cnt = 0; cnt < 256; cnt++) { 1423 n = 0; 1424 while (BA0READ4(sc, CS4280_SERBST) & SERBST_WBSY) { 1425 delay(1000); 1426 if (++n > 1000) { 1427 printf("clear_fifo: fist timeout cnt=%d\n", cnt); 1428 break; 1429 } 1430 } 1431 BA0WRITE4(sc, CS4280_SERBAD, cnt); 1432 BA0WRITE4(sc, CS4280_SERBCM, SERBCM_WRC); 1433 } 1434 if (pd) 1435 BA0WRITE4(sc, CS4280_CLKCR1, mem); 1436 } 1437 1438 #if NMIDI > 0 1439 int 1440 cs4280_midi_open(addr, flags, iintr, ointr, arg) 1441 void *addr; 1442 int flags; 1443 void (*iintr)__P((void *, int)); 1444 void (*ointr)__P((void *)); 1445 void *arg; 1446 { 1447 struct cs428x_softc *sc = addr; 1448 u_int32_t mem; 1449 1450 DPRINTF(("midi_open\n")); 1451 sc->sc_iintr = iintr; 1452 sc->sc_ointr = ointr; 1453 sc->sc_arg = arg; 1454 1455 /* midi interrupt enable */ 1456 mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK; 1457 mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE | MIDCR_MLB; 1458 BA0WRITE4(sc, CS4280_MIDCR, mem); 1459 #ifdef CS4280_DEBUG 1460 if (mem != BA0READ4(sc, CS4280_MIDCR)) { 1461 DPRINTF(("midi_open: MIDCR=%d\n", BA0READ4(sc, CS4280_MIDCR))); 1462 return(EINVAL); 1463 } 1464 DPRINTF(("MIDCR=0x%x\n", BA0READ4(sc, CS4280_MIDCR))); 1465 #endif 1466 return 0; 1467 } 1468 1469 void 1470 cs4280_midi_close(addr) 1471 void *addr; 1472 { 1473 struct cs428x_softc *sc = addr; 1474 u_int32_t mem; 1475 1476 DPRINTF(("midi_close\n")); 1477 tsleep(sc, PWAIT, "cs0clm", hz/10); /* give uart a chance to drain */ 1478 mem = BA0READ4(sc, CS4280_MIDCR); 1479 mem &= ~MIDCR_MASK; 1480 BA0WRITE4(sc, CS4280_MIDCR, mem); 1481 1482 sc->sc_iintr = 0; 1483 sc->sc_ointr = 0; 1484 } 1485 1486 int 1487 cs4280_midi_output(addr, d) 1488 void *addr; 1489 int d; 1490 { 1491 struct cs428x_softc *sc = addr; 1492 u_int32_t mem; 1493 int x; 1494 1495 for (x = 0; x != MIDI_BUSY_WAIT; x++) { 1496 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) { 1497 mem = BA0READ4(sc, CS4280_MIDWP) & ~MIDWP_MASK; 1498 mem |= d & MIDWP_MASK; 1499 DPRINTFN(5,("midi_output d=0x%08x",d)); 1500 BA0WRITE4(sc, CS4280_MIDWP, mem); 1501 #ifdef DIAGNOSTIC 1502 if (mem != BA0READ4(sc, CS4280_MIDWP)) { 1503 DPRINTF(("Bad write data: %d %d", 1504 mem, BA0READ4(sc, CS4280_MIDWP))); 1505 return(EIO); 1506 } 1507 #endif 1508 return 0; 1509 } 1510 delay(MIDI_BUSY_DELAY); 1511 } 1512 return (EIO); 1513 } 1514 1515 void 1516 cs4280_midi_getinfo(addr, mi) 1517 void *addr; 1518 struct midi_info *mi; 1519 { 1520 mi->name = "CS4280 MIDI UART"; 1521 mi->props = MIDI_PROP_CAN_INPUT | MIDI_PROP_OUT_INTR; 1522 } 1523 1524 #endif 1525 1526 /* DEBUG functions */ 1527 #if CS4280_DEBUG > 10 1528 int 1529 cs4280_checkimage(sc, src, offset, len) 1530 struct cs428x_softc *sc; 1531 u_int32_t *src; 1532 u_int32_t offset, len; 1533 { 1534 u_int32_t ctr, data; 1535 int err = 0; 1536 1537 if ((offset&3) || (len&3)) 1538 return -1; 1539 1540 len /= sizeof(u_int32_t); 1541 for (ctr = 0; ctr < len; ctr++) { 1542 /* I cannot confirm this is the right thing 1543 * on BIG-ENDIAN machines 1544 */ 1545 data = BA1READ4(sc, offset+ctr*4); 1546 if (data != htole32(*(src+ctr))) { 1547 printf("0x%06x: 0x%08x(0x%08x)\n", 1548 offset+ctr*4, data, *(src+ctr)); 1549 *(src+ctr) = data; 1550 ++err; 1551 } 1552 } 1553 return err; 1554 } 1555 1556 int 1557 cs4280_check_images(sc) 1558 struct cs428x_softc *sc; 1559 { 1560 int idx, err; 1561 u_int32_t offset = 0; 1562 1563 err = 0; 1564 /*for (idx=0; idx < BA1_MEMORY_COUNT; ++idx) { */ 1565 for (idx = 0; idx < 1; ++idx) { 1566 err = cs4280_checkimage(sc, &BA1Struct.map[offset], 1567 BA1Struct.memory[idx].offset, 1568 BA1Struct.memory[idx].size); 1569 if (err != 0) { 1570 printf("%s: check_image failed at %d\n", 1571 sc->sc_dev.dv_xname, idx); 1572 } 1573 offset += BA1Struct.memory[idx].size / sizeof(u_int32_t); 1574 } 1575 return err; 1576 } 1577 1578 #endif 1579