1 /* $NetBSD: cs4280.c,v 1.63 2011/11/24 03:35:58 mrg 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.63 2011/11/24 03:35:58 mrg 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/systm.h> 67 #include <sys/audioio.h> 68 #include <sys/bus.h> 69 #include <sys/bswap.h> 70 71 #include <dev/audio_if.h> 72 #include <dev/midi_if.h> 73 #include <dev/mulaw.h> 74 #include <dev/auconv.h> 75 76 #include <dev/ic/ac97reg.h> 77 #include <dev/ic/ac97var.h> 78 79 #include <dev/pci/pcidevs.h> 80 #include <dev/pci/pcivar.h> 81 #include <dev/pci/cs4280reg.h> 82 #include <dev/pci/cs4280_image.h> 83 #include <dev/pci/cs428xreg.h> 84 #include <dev/pci/cs428x.h> 85 86 #define BA1READ4(sc, r) bus_space_read_4((sc)->ba1t, (sc)->ba1h, (r)) 87 #define BA1WRITE4(sc, r, x) bus_space_write_4((sc)->ba1t, (sc)->ba1h, (r), (x)) 88 89 /* IF functions for audio driver */ 90 static int cs4280_match(device_t, cfdata_t, void *); 91 static void cs4280_attach(device_t, device_t, void *); 92 static int cs4280_intr(void *); 93 static int cs4280_query_encoding(void *, struct audio_encoding *); 94 static int cs4280_set_params(void *, int, int, audio_params_t *, 95 audio_params_t *, stream_filter_list_t *, 96 stream_filter_list_t *); 97 static int cs4280_halt_output(void *); 98 static int cs4280_halt_input(void *); 99 static int cs4280_getdev(void *, struct audio_device *); 100 static int cs4280_trigger_output(void *, void *, void *, int, void (*)(void *), 101 void *, const audio_params_t *); 102 static int cs4280_trigger_input(void *, void *, void *, int, void (*)(void *), 103 void *, const audio_params_t *); 104 static int cs4280_read_codec(void *, u_int8_t, u_int16_t *); 105 static int cs4280_write_codec(void *, u_int8_t, u_int16_t); 106 #if 0 107 static int cs4280_reset_codec(void *); 108 #endif 109 static enum ac97_host_flags cs4280_flags_codec(void *); 110 111 static bool cs4280_resume(device_t, const pmf_qual_t *); 112 static bool cs4280_suspend(device_t, const pmf_qual_t *); 113 114 /* Internal functions */ 115 static const struct cs4280_card_t * cs4280_identify_card(const struct pci_attach_args *); 116 static int cs4280_piix4_match(const struct pci_attach_args *); 117 static void cs4280_clkrun_hack(struct cs428x_softc *, int); 118 static void cs4280_clkrun_hack_init(struct cs428x_softc *); 119 static void cs4280_set_adc_rate(struct cs428x_softc *, int ); 120 static void cs4280_set_dac_rate(struct cs428x_softc *, int ); 121 static int cs4280_download(struct cs428x_softc *, const uint32_t *, uint32_t, 122 uint32_t); 123 static int cs4280_download_image(struct cs428x_softc *); 124 static void cs4280_reset(void *); 125 static int cs4280_init(struct cs428x_softc *, int); 126 static void cs4280_clear_fifos(struct cs428x_softc *); 127 128 #if CS4280_DEBUG > 10 129 /* Thease two function is only for checking image loading is succeeded or not. */ 130 static int cs4280_check_images(struct cs428x_softc *); 131 static int cs4280_checkimage(struct cs428x_softc *, uint32_t *, uint32_t, 132 uint32_t); 133 #endif 134 135 /* Special cards */ 136 struct cs4280_card_t 137 { 138 pcireg_t id; 139 enum cs428x_flags flags; 140 }; 141 142 #define _card(vend, prod, flags) \ 143 {PCI_ID_CODE(vend, prod), flags} 144 145 static const struct cs4280_card_t cs4280_cards[] = { 146 #if 0 /* untested, from ALSA driver */ 147 _card(PCI_VENDOR_MITAC, PCI_PRODUCT_MITAC_MI6020, 148 CS428X_FLAG_INVAC97EAMP), 149 #endif 150 _card(PCI_VENDOR_TURTLE_BEACH, PCI_PRODUCT_TURTLE_BEACH_SANTA_CRUZ, 151 CS428X_FLAG_INVAC97EAMP), 152 _card(PCI_VENDOR_IBM, PCI_PRODUCT_IBM_TPAUDIO, 153 CS428X_FLAG_CLKRUNHACK) 154 }; 155 156 #undef _card 157 158 #define CS4280_CARDS_SIZE (sizeof(cs4280_cards)/sizeof(cs4280_cards[0])) 159 160 static const struct audio_hw_if cs4280_hw_if = { 161 NULL, /* open */ 162 NULL, /* close */ 163 NULL, 164 cs4280_query_encoding, 165 cs4280_set_params, 166 cs428x_round_blocksize, 167 NULL, 168 NULL, 169 NULL, 170 NULL, 171 NULL, 172 cs4280_halt_output, 173 cs4280_halt_input, 174 NULL, 175 cs4280_getdev, 176 NULL, 177 cs428x_mixer_set_port, 178 cs428x_mixer_get_port, 179 cs428x_query_devinfo, 180 cs428x_malloc, 181 cs428x_free, 182 cs428x_round_buffersize, 183 cs428x_mappage, 184 cs428x_get_props, 185 cs4280_trigger_output, 186 cs4280_trigger_input, 187 NULL, 188 cs428x_get_locks, 189 }; 190 191 #if NMIDI > 0 192 /* Midi Interface */ 193 static int cs4280_midi_open(void *, int, void (*)(void *, int), 194 void (*)(void *), void *); 195 static void cs4280_midi_close(void*); 196 static int cs4280_midi_output(void *, int); 197 static void cs4280_midi_getinfo(void *, struct midi_info *); 198 199 static const struct midi_hw_if cs4280_midi_hw_if = { 200 cs4280_midi_open, 201 cs4280_midi_close, 202 cs4280_midi_output, 203 cs4280_midi_getinfo, 204 0, 205 cs428x_get_locks, 206 }; 207 #endif 208 209 CFATTACH_DECL(clcs, sizeof(struct cs428x_softc), 210 cs4280_match, cs4280_attach, NULL, NULL); 211 212 static struct audio_device cs4280_device = { 213 "CS4280", 214 "", 215 "cs4280" 216 }; 217 218 219 static int 220 cs4280_match(device_t parent, cfdata_t match, void *aux) 221 { 222 struct pci_attach_args *pa; 223 224 pa = (struct pci_attach_args *)aux; 225 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CIRRUS) 226 return 0; 227 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CIRRUS_CS4280 228 #if 0 /* I can't confirm */ 229 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CIRRUS_CS4610 230 #endif 231 ) 232 return 1; 233 return 0; 234 } 235 236 static void 237 cs4280_attach(device_t parent, device_t self, void *aux) 238 { 239 struct cs428x_softc *sc; 240 struct pci_attach_args *pa; 241 pci_chipset_tag_t pc; 242 const struct cs4280_card_t *cs_card; 243 char const *intrstr; 244 const char *vendor, *product; 245 pcireg_t reg; 246 char devinfo[256]; 247 uint32_t mem; 248 int error; 249 250 sc = device_private(self); 251 pa = (struct pci_attach_args *)aux; 252 pc = pa->pa_pc; 253 aprint_naive(": Audio controller\n"); 254 255 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 256 aprint_normal(": %s (rev. 0x%02x)\n", devinfo, 257 PCI_REVISION(pa->pa_class)); 258 259 cs_card = cs4280_identify_card(pa); 260 if (cs_card != NULL) { 261 vendor = pci_findvendor(cs_card->id); 262 product = pci_findproduct(cs_card->id); 263 if (vendor == NULL) 264 aprint_normal_dev(&sc->sc_dev, 265 "vendor 0x%04x product 0x%04x\n", 266 PCI_VENDOR(cs_card->id), 267 PCI_PRODUCT(cs_card->id)); 268 else if (product == NULL) 269 aprint_normal_dev(&sc->sc_dev, "%s product 0x%04x\n", 270 vendor, PCI_PRODUCT(cs_card->id)); 271 else 272 aprint_normal_dev(&sc->sc_dev, "%s %s\n", 273 vendor, product); 274 sc->sc_flags = cs_card->flags; 275 } else { 276 sc->sc_flags = CS428X_FLAG_NONE; 277 } 278 279 sc->sc_pc = pa->pa_pc; 280 sc->sc_pt = pa->pa_tag; 281 282 /* Map I/O register */ 283 if (pci_mapreg_map(pa, PCI_BA0, 284 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, 285 &sc->ba0t, &sc->ba0h, NULL, NULL)) { 286 aprint_error_dev(&sc->sc_dev, "can't map BA0 space\n"); 287 return; 288 } 289 if (pci_mapreg_map(pa, PCI_BA1, 290 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, 291 &sc->ba1t, &sc->ba1h, NULL, NULL)) { 292 aprint_error_dev(&sc->sc_dev, "can't map BA1 space\n"); 293 return; 294 } 295 296 sc->sc_dmatag = pa->pa_dmat; 297 298 /* power up chip */ 299 if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self, 300 pci_activate_null)) && error != EOPNOTSUPP) { 301 aprint_error_dev(&sc->sc_dev, "cannot activate %d\n", error); 302 return; 303 } 304 305 /* Enable the device (set bus master flag) */ 306 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 307 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 308 reg | PCI_COMMAND_MASTER_ENABLE); 309 310 /* LATENCY_TIMER setting */ 311 mem = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); 312 if ( PCI_LATTIMER(mem) < 32 ) { 313 mem &= 0xffff00ff; 314 mem |= 0x00002000; 315 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, mem); 316 } 317 318 /* CLKRUN hack initialization */ 319 cs4280_clkrun_hack_init(sc); 320 321 /* Map and establish the interrupt. */ 322 if (pci_intr_map(pa, &sc->intrh)) { 323 aprint_error_dev(&sc->sc_dev, "couldn't map interrupt\n"); 324 return; 325 } 326 intrstr = pci_intr_string(pc, sc->intrh); 327 328 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 329 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 330 331 sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->intrh, IPL_AUDIO, 332 cs4280_intr, sc); 333 if (sc->sc_ih == NULL) { 334 aprint_error_dev(&sc->sc_dev, "couldn't establish interrupt"); 335 if (intrstr != NULL) 336 aprint_error(" at %s", intrstr); 337 aprint_error("\n"); 338 mutex_destroy(&sc->sc_lock); 339 mutex_destroy(&sc->sc_intr_lock); 340 return; 341 } 342 aprint_normal_dev(&sc->sc_dev, "interrupting at %s\n", intrstr); 343 344 /* Initialization */ 345 if(cs4280_init(sc, 1) != 0) { 346 mutex_destroy(&sc->sc_lock); 347 mutex_destroy(&sc->sc_intr_lock); 348 return; 349 } 350 351 sc->type = TYPE_CS4280; 352 sc->halt_input = cs4280_halt_input; 353 sc->halt_output = cs4280_halt_output; 354 355 /* setup buffer related parameters */ 356 sc->dma_size = CS4280_DCHUNK; 357 sc->dma_align = CS4280_DALIGN; 358 sc->hw_blocksize = CS4280_ICHUNK; 359 360 /* AC 97 attachment */ 361 sc->host_if.arg = sc; 362 sc->host_if.attach = cs428x_attach_codec; 363 sc->host_if.read = cs4280_read_codec; 364 sc->host_if.write = cs4280_write_codec; 365 #if 0 366 sc->host_if.reset = cs4280_reset_codec; 367 #else 368 sc->host_if.reset = NULL; 369 #endif 370 sc->host_if.flags = cs4280_flags_codec; 371 if (ac97_attach(&sc->host_if, self, &sc->sc_lock) != 0) { 372 aprint_error_dev(&sc->sc_dev, "ac97_attach failed\n"); 373 return; 374 } 375 376 audio_attach_mi(&cs4280_hw_if, sc, &sc->sc_dev); 377 378 #if NMIDI > 0 379 midi_attach_mi(&cs4280_midi_hw_if, sc, &sc->sc_dev); 380 #endif 381 382 if (!pmf_device_register(self, cs4280_suspend, cs4280_resume)) 383 aprint_error_dev(self, "couldn't establish power handler\n"); 384 } 385 386 /* Interrupt handling function */ 387 static int 388 cs4280_intr(void *p) 389 { 390 /* 391 * XXX 392 * 393 * Since CS4280 has only 4kB DMA buffer and 394 * interrupt occurs every 2kB block, I create dummy buffer 395 * which returns to audio driver and actual DMA buffer 396 * using in DMA transfer. 397 * 398 * 399 * ring buffer in audio.c is pointed by BUFADDR 400 * <------ ring buffer size == 64kB ------> 401 * <-----> blksize == 2048*(sc->sc_[pr]count) kB 402 * |= = = =|= = = =|= = = =|= = = =|= = = =| 403 * | | | | | | <- call audio_intp every 404 * sc->sc_[pr]_count time. 405 * 406 * actual DMA buffer is pointed by KERNADDR 407 * <-> DMA buffer size = 4kB 408 * |= =| 409 * 410 * 411 */ 412 struct cs428x_softc *sc; 413 uint32_t intr, mem; 414 char * empty_dma; 415 int handled; 416 417 sc = p; 418 handled = 0; 419 420 mutex_spin_enter(&sc->sc_intr_lock); 421 422 /* grab interrupt register then clear it */ 423 intr = BA0READ4(sc, CS4280_HISR); 424 BA0WRITE4(sc, CS4280_HICR, HICR_CHGM | HICR_IEV); 425 426 /* not for us ? */ 427 if ((intr & HISR_INTENA) == 0) { 428 mutex_spin_exit(&sc->sc_intr_lock); 429 return 0; 430 } 431 432 /* Playback Interrupt */ 433 if (intr & HISR_PINT) { 434 handled = 1; 435 mem = BA1READ4(sc, CS4280_PFIE); 436 BA1WRITE4(sc, CS4280_PFIE, (mem & ~PFIE_PI_MASK) | PFIE_PI_DISABLE); 437 if (sc->sc_prun) { 438 if ((sc->sc_pi%sc->sc_pcount) == 0) 439 sc->sc_pintr(sc->sc_parg); 440 /* copy buffer */ 441 ++sc->sc_pi; 442 empty_dma = sc->sc_pdma->addr; 443 if (sc->sc_pi&1) 444 empty_dma += sc->hw_blocksize; 445 memcpy(empty_dma, sc->sc_pn, sc->hw_blocksize); 446 sc->sc_pn += sc->hw_blocksize; 447 if (sc->sc_pn >= sc->sc_pe) 448 sc->sc_pn = sc->sc_ps; 449 } else { 450 aprint_error_dev(&sc->sc_dev, "unexpected play intr\n"); 451 } 452 BA1WRITE4(sc, CS4280_PFIE, mem); 453 } 454 /* Capture Interrupt */ 455 if (intr & HISR_CINT) { 456 int i; 457 int16_t rdata; 458 459 handled = 1; 460 mem = BA1READ4(sc, CS4280_CIE); 461 BA1WRITE4(sc, CS4280_CIE, (mem & ~CIE_CI_MASK) | CIE_CI_DISABLE); 462 463 if (sc->sc_rrun) { 464 ++sc->sc_ri; 465 empty_dma = sc->sc_rdma->addr; 466 if ((sc->sc_ri&1) == 0) 467 empty_dma += sc->hw_blocksize; 468 469 /* 470 * XXX 471 * I think this audio data conversion should be 472 * happend in upper layer, but I put this here 473 * since there is no conversion function available. 474 */ 475 switch(sc->sc_rparam) { 476 case CF_16BIT_STEREO: 477 /* just copy it */ 478 memcpy(sc->sc_rn, empty_dma, sc->hw_blocksize); 479 sc->sc_rn += sc->hw_blocksize; 480 break; 481 case CF_16BIT_MONO: 482 for (i = 0; i < 512; i++) { 483 rdata = *((int16_t *)empty_dma)>>1; 484 empty_dma += 2; 485 rdata += *((int16_t *)empty_dma)>>1; 486 empty_dma += 2; 487 *((int16_t *)sc->sc_rn) = rdata; 488 sc->sc_rn += 2; 489 } 490 break; 491 case CF_8BIT_STEREO: 492 for (i = 0; i < 512; i++) { 493 rdata = *((int16_t*)empty_dma); 494 empty_dma += 2; 495 *sc->sc_rn++ = rdata >> 8; 496 rdata = *((int16_t*)empty_dma); 497 empty_dma += 2; 498 *sc->sc_rn++ = rdata >> 8; 499 } 500 break; 501 case CF_8BIT_MONO: 502 for (i = 0; i < 512; i++) { 503 rdata = *((int16_t*)empty_dma) >>1; 504 empty_dma += 2; 505 rdata += *((int16_t*)empty_dma) >>1; 506 empty_dma += 2; 507 *sc->sc_rn++ = rdata >>8; 508 } 509 break; 510 default: 511 /* Should not reach here */ 512 aprint_error_dev(&sc->sc_dev, 513 "unknown sc->sc_rparam: %d\n", 514 sc->sc_rparam); 515 } 516 if (sc->sc_rn >= sc->sc_re) 517 sc->sc_rn = sc->sc_rs; 518 } 519 BA1WRITE4(sc, CS4280_CIE, mem); 520 521 if (sc->sc_rrun) { 522 if ((sc->sc_ri%(sc->sc_rcount)) == 0) 523 sc->sc_rintr(sc->sc_rarg); 524 } else { 525 aprint_error_dev(&sc->sc_dev, 526 "unexpected record intr\n"); 527 } 528 } 529 530 #if NMIDI > 0 531 /* Midi port Interrupt */ 532 if (intr & HISR_MIDI) { 533 int data; 534 535 handled = 1; 536 DPRINTF(("i: %d: ", 537 BA0READ4(sc, CS4280_MIDSR))); 538 /* Read the received data */ 539 while ((sc->sc_iintr != NULL) && 540 ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_RBE) == 0)) { 541 data = BA0READ4(sc, CS4280_MIDRP) & MIDRP_MASK; 542 DPRINTF(("r:%x\n",data)); 543 sc->sc_iintr(sc->sc_arg, data); 544 } 545 546 /* Write the data */ 547 #if 1 548 /* XXX: 549 * It seems "Transmit Buffer Full" never activate until EOI 550 * is deliverd. Shall I throw EOI top of this routine ? 551 */ 552 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) { 553 DPRINTF(("w: ")); 554 if (sc->sc_ointr != NULL) 555 sc->sc_ointr(sc->sc_arg); 556 } 557 #else 558 while ((sc->sc_ointr != NULL) && 559 ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0)) { 560 DPRINTF(("w: ")); 561 sc->sc_ointr(sc->sc_arg); 562 } 563 #endif 564 DPRINTF(("\n")); 565 } 566 #endif 567 568 mutex_spin_exit(&sc->sc_intr_lock); 569 return handled; 570 } 571 572 static int 573 cs4280_query_encoding(void *addr, struct audio_encoding *fp) 574 { 575 switch (fp->index) { 576 case 0: 577 strcpy(fp->name, AudioEulinear); 578 fp->encoding = AUDIO_ENCODING_ULINEAR; 579 fp->precision = 8; 580 fp->flags = 0; 581 break; 582 case 1: 583 strcpy(fp->name, AudioEmulaw); 584 fp->encoding = AUDIO_ENCODING_ULAW; 585 fp->precision = 8; 586 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 587 break; 588 case 2: 589 strcpy(fp->name, AudioEalaw); 590 fp->encoding = AUDIO_ENCODING_ALAW; 591 fp->precision = 8; 592 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 593 break; 594 case 3: 595 strcpy(fp->name, AudioEslinear); 596 fp->encoding = AUDIO_ENCODING_SLINEAR; 597 fp->precision = 8; 598 fp->flags = 0; 599 break; 600 case 4: 601 strcpy(fp->name, AudioEslinear_le); 602 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 603 fp->precision = 16; 604 fp->flags = 0; 605 break; 606 case 5: 607 strcpy(fp->name, AudioEulinear_le); 608 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 609 fp->precision = 16; 610 fp->flags = 0; 611 break; 612 case 6: 613 strcpy(fp->name, AudioEslinear_be); 614 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 615 fp->precision = 16; 616 fp->flags = 0; 617 break; 618 case 7: 619 strcpy(fp->name, AudioEulinear_be); 620 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 621 fp->precision = 16; 622 fp->flags = 0; 623 break; 624 default: 625 return EINVAL; 626 } 627 return 0; 628 } 629 630 static int 631 cs4280_set_params(void *addr, int setmode, int usemode, 632 audio_params_t *play, audio_params_t *rec, stream_filter_list_t *pfil, 633 stream_filter_list_t *rfil) 634 { 635 audio_params_t hw; 636 struct cs428x_softc *sc; 637 struct audio_params *p; 638 stream_filter_list_t *fil; 639 int mode; 640 641 sc = addr; 642 for (mode = AUMODE_RECORD; mode != -1; 643 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1 ) { 644 if ((setmode & mode) == 0) 645 continue; 646 647 p = mode == AUMODE_PLAY ? play : rec; 648 649 if (p == play) { 650 DPRINTFN(5,("play: sample=%d precision=%d channels=%d\n", 651 p->sample_rate, p->precision, p->channels)); 652 /* play back data format may be 8- or 16-bit and 653 * either stereo or mono. 654 * playback rate may range from 8000Hz to 48000Hz 655 */ 656 if (p->sample_rate < 8000 || p->sample_rate > 48000 || 657 (p->precision != 8 && p->precision != 16) || 658 (p->channels != 1 && p->channels != 2) ) { 659 return EINVAL; 660 } 661 } else { 662 DPRINTFN(5,("rec: sample=%d precision=%d channels=%d\n", 663 p->sample_rate, p->precision, p->channels)); 664 /* capture data format must be 16bit stereo 665 * and sample rate range from 11025Hz to 48000Hz. 666 * 667 * XXX: it looks like to work with 8000Hz, 668 * although data sheets say lower limit is 669 * 11025 Hz. 670 */ 671 672 if (p->sample_rate < 8000 || p->sample_rate > 48000 || 673 (p->precision != 8 && p->precision != 16) || 674 (p->channels != 1 && p->channels != 2) ) { 675 return EINVAL; 676 } 677 } 678 fil = mode == AUMODE_PLAY ? pfil : rfil; 679 hw = *p; 680 hw.encoding = AUDIO_ENCODING_SLINEAR_LE; 681 682 /* capturing data is slinear */ 683 switch (p->encoding) { 684 case AUDIO_ENCODING_SLINEAR_BE: 685 if (mode == AUMODE_RECORD && p->precision == 16) { 686 fil->append(fil, swap_bytes, &hw); 687 } 688 break; 689 case AUDIO_ENCODING_SLINEAR_LE: 690 break; 691 case AUDIO_ENCODING_ULINEAR_BE: 692 if (mode == AUMODE_RECORD) { 693 fil->append(fil, p->precision == 16 694 ? swap_bytes_change_sign16 695 : change_sign8, &hw); 696 } 697 break; 698 case AUDIO_ENCODING_ULINEAR_LE: 699 if (mode == AUMODE_RECORD) { 700 fil->append(fil, p->precision == 16 701 ? change_sign16 : change_sign8, 702 &hw); 703 } 704 break; 705 case AUDIO_ENCODING_ULAW: 706 if (mode == AUMODE_PLAY) { 707 hw.precision = 16; 708 hw.validbits = 16; 709 fil->append(fil, mulaw_to_linear16, &hw); 710 } else { 711 fil->append(fil, linear8_to_mulaw, &hw); 712 } 713 break; 714 case AUDIO_ENCODING_ALAW: 715 if (mode == AUMODE_PLAY) { 716 hw.precision = 16; 717 hw.validbits = 16; 718 fil->append(fil, alaw_to_linear16, &hw); 719 } else { 720 fil->append(fil, linear8_to_alaw, &hw); 721 } 722 break; 723 default: 724 return EINVAL; 725 } 726 } 727 728 /* set sample rate */ 729 cs4280_set_dac_rate(sc, play->sample_rate); 730 cs4280_set_adc_rate(sc, rec->sample_rate); 731 return 0; 732 } 733 734 static int 735 cs4280_halt_output(void *addr) 736 { 737 struct cs428x_softc *sc; 738 uint32_t mem; 739 740 sc = addr; 741 mem = BA1READ4(sc, CS4280_PCTL); 742 BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK); 743 sc->sc_prun = 0; 744 cs4280_clkrun_hack(sc, -1); 745 746 return 0; 747 } 748 749 static int 750 cs4280_halt_input(void *addr) 751 { 752 struct cs428x_softc *sc; 753 uint32_t mem; 754 755 sc = addr; 756 mem = BA1READ4(sc, CS4280_CCTL); 757 BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK); 758 sc->sc_rrun = 0; 759 cs4280_clkrun_hack(sc, -1); 760 761 return 0; 762 } 763 764 static int 765 cs4280_getdev(void *addr, struct audio_device *retp) 766 { 767 768 *retp = cs4280_device; 769 return 0; 770 } 771 772 static int 773 cs4280_trigger_output(void *addr, void *start, void *end, int blksize, 774 void (*intr)(void *), void *arg, 775 const audio_params_t *param) 776 { 777 struct cs428x_softc *sc; 778 uint32_t pfie, pctl, pdtc; 779 struct cs428x_dma *p; 780 781 sc = addr; 782 #ifdef DIAGNOSTIC 783 if (sc->sc_prun) 784 printf("cs4280_trigger_output: already running\n"); 785 #endif 786 sc->sc_prun = 1; 787 cs4280_clkrun_hack(sc, 1); 788 789 DPRINTF(("cs4280_trigger_output: sc=%p start=%p end=%p " 790 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 791 sc->sc_pintr = intr; 792 sc->sc_parg = arg; 793 794 /* stop playback DMA */ 795 BA1WRITE4(sc, CS4280_PCTL, BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK); 796 797 /* setup PDTC */ 798 pdtc = BA1READ4(sc, CS4280_PDTC); 799 pdtc &= ~PDTC_MASK; 800 pdtc |= CS4280_MK_PDTC(param->precision * param->channels); 801 BA1WRITE4(sc, CS4280_PDTC, pdtc); 802 803 DPRINTF(("param: precision=%d channels=%d encoding=%d\n", 804 param->precision, param->channels, param->encoding)); 805 for (p = sc->sc_dmas; p != NULL && BUFADDR(p) != start; p = p->next) 806 continue; 807 if (p == NULL) { 808 printf("cs4280_trigger_output: bad addr %p\n", start); 809 return EINVAL; 810 } 811 if (DMAADDR(p) % sc->dma_align != 0 ) { 812 printf("cs4280_trigger_output: DMAADDR(p)=0x%lx does not start" 813 "4kB align\n", (ulong)DMAADDR(p)); 814 return EINVAL; 815 } 816 817 sc->sc_pcount = blksize / sc->hw_blocksize; /* sc->hw_blocksize is fixed hardware blksize*/ 818 sc->sc_ps = (char *)start; 819 sc->sc_pe = (char *)end; 820 sc->sc_pdma = p; 821 sc->sc_pbuf = KERNADDR(p); 822 sc->sc_pi = 0; 823 sc->sc_pn = sc->sc_ps; 824 if (blksize >= sc->dma_size) { 825 sc->sc_pn = sc->sc_ps + sc->dma_size; 826 memcpy(sc->sc_pbuf, start, sc->dma_size); 827 ++sc->sc_pi; 828 } else { 829 sc->sc_pn = sc->sc_ps + sc->hw_blocksize; 830 memcpy(sc->sc_pbuf, start, sc->hw_blocksize); 831 } 832 833 /* initiate playback DMA */ 834 BA1WRITE4(sc, CS4280_PBA, DMAADDR(p)); 835 836 /* set PFIE */ 837 pfie = BA1READ4(sc, CS4280_PFIE) & ~PFIE_MASK; 838 839 if (param->precision == 8) 840 pfie |= PFIE_8BIT; 841 if (param->channels == 1) 842 pfie |= PFIE_MONO; 843 844 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 845 param->encoding == AUDIO_ENCODING_SLINEAR_BE) 846 pfie |= PFIE_SWAPPED; 847 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE || 848 param->encoding == AUDIO_ENCODING_ULINEAR_LE) 849 pfie |= PFIE_UNSIGNED; 850 851 BA1WRITE4(sc, CS4280_PFIE, pfie | PFIE_PI_ENABLE); 852 853 sc->sc_prate = param->sample_rate; 854 cs4280_set_dac_rate(sc, param->sample_rate); 855 856 pctl = BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK; 857 pctl |= sc->pctl; 858 BA1WRITE4(sc, CS4280_PCTL, pctl); 859 return 0; 860 } 861 862 static int 863 cs4280_trigger_input(void *addr, void *start, void *end, int blksize, 864 void (*intr)(void *), void *arg, 865 const audio_params_t *param) 866 { 867 struct cs428x_softc *sc; 868 uint32_t cctl, cie; 869 struct cs428x_dma *p; 870 871 sc = addr; 872 #ifdef DIAGNOSTIC 873 if (sc->sc_rrun) 874 printf("cs4280_trigger_input: already running\n"); 875 #endif 876 sc->sc_rrun = 1; 877 cs4280_clkrun_hack(sc, 1); 878 879 DPRINTF(("cs4280_trigger_input: sc=%p start=%p end=%p " 880 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 881 sc->sc_rintr = intr; 882 sc->sc_rarg = arg; 883 884 /* stop capture DMA */ 885 BA1WRITE4(sc, CS4280_CCTL, BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK); 886 887 for (p = sc->sc_dmas; p && BUFADDR(p) != start; p = p->next) 888 continue; 889 if (p == NULL) { 890 printf("cs4280_trigger_input: bad addr %p\n", start); 891 return EINVAL; 892 } 893 if (DMAADDR(p) % sc->dma_align != 0) { 894 printf("cs4280_trigger_input: DMAADDR(p)=0x%lx does not start" 895 "4kB align\n", (ulong)DMAADDR(p)); 896 return EINVAL; 897 } 898 899 sc->sc_rcount = blksize / sc->hw_blocksize; /* sc->hw_blocksize is fixed hardware blksize*/ 900 sc->sc_rs = (char *)start; 901 sc->sc_re = (char *)end; 902 sc->sc_rdma = p; 903 sc->sc_rbuf = KERNADDR(p); 904 sc->sc_ri = 0; 905 sc->sc_rn = sc->sc_rs; 906 907 /* initiate capture DMA */ 908 BA1WRITE4(sc, CS4280_CBA, DMAADDR(p)); 909 910 /* setup format information for internal converter */ 911 sc->sc_rparam = 0; 912 if (param->precision == 8) { 913 sc->sc_rparam += CF_8BIT; 914 sc->sc_rcount <<= 1; 915 } 916 if (param->channels == 1) { 917 sc->sc_rparam += CF_MONO; 918 sc->sc_rcount <<= 1; 919 } 920 921 /* set CIE */ 922 cie = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK; 923 BA1WRITE4(sc, CS4280_CIE, cie | CIE_CI_ENABLE); 924 925 sc->sc_rrate = param->sample_rate; 926 cs4280_set_adc_rate(sc, param->sample_rate); 927 928 cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK; 929 cctl |= sc->cctl; 930 BA1WRITE4(sc, CS4280_CCTL, cctl); 931 return 0; 932 } 933 934 static bool 935 cs4280_suspend(device_t dv, const pmf_qual_t *qual) 936 { 937 struct cs428x_softc *sc = device_private(dv); 938 939 mutex_exit(&sc->sc_lock); 940 mutex_spin_enter(&sc->sc_intr_lock); 941 942 if (sc->sc_prun) { 943 sc->sc_suspend_state.cs4280.pctl = BA1READ4(sc, CS4280_PCTL); 944 sc->sc_suspend_state.cs4280.pfie = BA1READ4(sc, CS4280_PFIE); 945 sc->sc_suspend_state.cs4280.pba = BA1READ4(sc, CS4280_PBA); 946 sc->sc_suspend_state.cs4280.pdtc = BA1READ4(sc, CS4280_PDTC); 947 DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n", 948 sc->sc_suspend_state.cs4280.pctl, 949 sc->sc_suspend_state.cs4280.pfie, 950 sc->sc_suspend_state.cs4280.pba, 951 sc->sc_suspend_state.cs4280.pdtc)); 952 } 953 954 /* save current capture status */ 955 if (sc->sc_rrun) { 956 sc->sc_suspend_state.cs4280.cctl = BA1READ4(sc, CS4280_CCTL); 957 sc->sc_suspend_state.cs4280.cie = BA1READ4(sc, CS4280_CIE); 958 sc->sc_suspend_state.cs4280.cba = BA1READ4(sc, CS4280_CBA); 959 DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n", 960 sc->sc_suspend_state.cs4280.cctl, 961 sc->sc_suspend_state.cs4280.cie, 962 sc->sc_suspend_state.cs4280.cba)); 963 } 964 965 /* Stop DMA */ 966 BA1WRITE4(sc, CS4280_PCTL, sc->sc_suspend_state.cs4280.pctl & ~PCTL_MASK); 967 BA1WRITE4(sc, CS4280_CCTL, BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK); 968 969 mutex_spin_exit(&sc->sc_intr_lock); 970 mutex_exit(&sc->sc_lock); 971 972 return true; 973 } 974 975 static bool 976 cs4280_resume(device_t dv, const pmf_qual_t *qual) 977 { 978 struct cs428x_softc *sc = device_private(dv); 979 980 mutex_exit(&sc->sc_lock); 981 mutex_spin_enter(&sc->sc_intr_lock); 982 cs4280_init(sc, 0); 983 #if 0 984 cs4280_reset_codec(sc); 985 #endif 986 987 /* restore DMA related status */ 988 if(sc->sc_prun) { 989 DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n", 990 sc->sc_suspend_state.cs4280.pctl, 991 sc->sc_suspend_state.cs4280.pfie, 992 sc->sc_suspend_state.cs4280.pba, 993 sc->sc_suspend_state.cs4280.pdtc)); 994 cs4280_set_dac_rate(sc, sc->sc_prate); 995 BA1WRITE4(sc, CS4280_PDTC, sc->sc_suspend_state.cs4280.pdtc); 996 BA1WRITE4(sc, CS4280_PBA, sc->sc_suspend_state.cs4280.pba); 997 BA1WRITE4(sc, CS4280_PFIE, sc->sc_suspend_state.cs4280.pfie); 998 BA1WRITE4(sc, CS4280_PCTL, sc->sc_suspend_state.cs4280.pctl); 999 } 1000 1001 if (sc->sc_rrun) { 1002 DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n", 1003 sc->sc_suspend_state.cs4280.cctl, 1004 sc->sc_suspend_state.cs4280.cie, 1005 sc->sc_suspend_state.cs4280.cba)); 1006 cs4280_set_adc_rate(sc, sc->sc_rrate); 1007 BA1WRITE4(sc, CS4280_CBA, sc->sc_suspend_state.cs4280.cba); 1008 BA1WRITE4(sc, CS4280_CIE, sc->sc_suspend_state.cs4280.cie); 1009 BA1WRITE4(sc, CS4280_CCTL, sc->sc_suspend_state.cs4280.cctl); 1010 } 1011 1012 mutex_spin_exit(&sc->sc_intr_lock); 1013 1014 /* restore ac97 registers */ 1015 (*sc->codec_if->vtbl->restore_ports)(sc->codec_if); 1016 1017 mutex_exit(&sc->sc_lock); 1018 1019 return true; 1020 } 1021 1022 static int 1023 cs4280_read_codec(void *addr, u_int8_t reg, u_int16_t *result) 1024 { 1025 struct cs428x_softc *sc = addr; 1026 int rv; 1027 1028 cs4280_clkrun_hack(sc, 1); 1029 rv = cs428x_read_codec(addr, reg, result); 1030 cs4280_clkrun_hack(sc, -1); 1031 1032 return rv; 1033 } 1034 1035 static int 1036 cs4280_write_codec(void *addr, u_int8_t reg, u_int16_t data) 1037 { 1038 struct cs428x_softc *sc = addr; 1039 int rv; 1040 1041 cs4280_clkrun_hack(sc, 1); 1042 rv = cs428x_write_codec(addr, reg, data); 1043 cs4280_clkrun_hack(sc, -1); 1044 1045 return rv; 1046 } 1047 1048 #if 0 /* XXX buggy and not required */ 1049 /* control AC97 codec */ 1050 static int 1051 cs4280_reset_codec(void *addr) 1052 { 1053 struct cs428x_softc *sc; 1054 int n; 1055 1056 sc = addr; 1057 1058 /* Reset codec */ 1059 BA0WRITE4(sc, CS428X_ACCTL, 0); 1060 delay(100); /* delay 100us */ 1061 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_RSTN); 1062 1063 /* 1064 * It looks like we do the following procedure, too 1065 */ 1066 1067 /* Enable AC-link sync generation */ 1068 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN | ACCTL_RSTN); 1069 delay(50*1000); /* XXX delay 50ms */ 1070 1071 /* Assert valid frame signal */ 1072 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 1073 1074 /* Wait for valid AC97 input slot */ 1075 n = 0; 1076 while ((BA0READ4(sc, CS428X_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) != 1077 (ACISV_ISV3 | ACISV_ISV4)) { 1078 delay(1000); 1079 if (++n > 1000) { 1080 printf("reset_codec: AC97 inputs slot ready timeout\n"); 1081 return ETIMEDOUT; 1082 } 1083 } 1084 1085 return 0; 1086 } 1087 #endif 1088 1089 static enum ac97_host_flags 1090 cs4280_flags_codec(void *addr) 1091 { 1092 struct cs428x_softc *sc; 1093 1094 sc = addr; 1095 if (sc->sc_flags & CS428X_FLAG_INVAC97EAMP) 1096 return AC97_HOST_INVERTED_EAMP; 1097 1098 return 0; 1099 } 1100 1101 /* Internal functions */ 1102 1103 static const struct cs4280_card_t * 1104 cs4280_identify_card(const struct pci_attach_args *pa) 1105 { 1106 pcireg_t idreg; 1107 u_int16_t i; 1108 1109 idreg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); 1110 for (i = 0; i < CS4280_CARDS_SIZE; i++) { 1111 if (idreg == cs4280_cards[i].id) 1112 return &cs4280_cards[i]; 1113 } 1114 1115 return NULL; 1116 } 1117 1118 static int 1119 cs4280_piix4_match(const struct pci_attach_args *pa) 1120 { 1121 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL && 1122 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82371AB_PMC) { 1123 return 1; 1124 } 1125 1126 return 0; 1127 } 1128 1129 static void 1130 cs4280_clkrun_hack(struct cs428x_softc *sc, int change) 1131 { 1132 uint16_t control, val; 1133 1134 if (!(sc->sc_flags & CS428X_FLAG_CLKRUNHACK)) 1135 return; 1136 1137 sc->sc_active += change; 1138 val = control = bus_space_read_2(sc->sc_pm_iot, sc->sc_pm_ioh, 0x10); 1139 if (!sc->sc_active) 1140 val |= 0x2000; 1141 else 1142 val &= ~0x2000; 1143 if (val != control) 1144 bus_space_write_2(sc->sc_pm_iot, sc->sc_pm_ioh, 0x10, val); 1145 } 1146 1147 static void 1148 cs4280_clkrun_hack_init(struct cs428x_softc *sc) 1149 { 1150 struct pci_attach_args smbuspa; 1151 uint16_t reg; 1152 pcireg_t port; 1153 1154 if (!(sc->sc_flags & CS428X_FLAG_CLKRUNHACK)) 1155 return; 1156 1157 if (pci_find_device(&smbuspa, cs4280_piix4_match)) { 1158 sc->sc_active = 0; 1159 aprint_normal_dev(&sc->sc_dev, "enabling CLKRUN hack\n"); 1160 1161 reg = pci_conf_read(smbuspa.pa_pc, smbuspa.pa_tag, 0x40); 1162 port = reg & 0xffc0; 1163 aprint_normal_dev(&sc->sc_dev, "power management port 0x%x\n", 1164 port); 1165 1166 sc->sc_pm_iot = smbuspa.pa_iot; 1167 if (bus_space_map(sc->sc_pm_iot, port, 0x20 /* XXX */, 0, 1168 &sc->sc_pm_ioh) == 0) 1169 return; 1170 } 1171 1172 /* handle error */ 1173 sc->sc_flags &= ~CS428X_FLAG_CLKRUNHACK; 1174 aprint_normal_dev(&sc->sc_dev, "disabling CLKRUN hack\n"); 1175 } 1176 1177 static void 1178 cs4280_set_adc_rate(struct cs428x_softc *sc, int rate) 1179 { 1180 /* calculate capture rate: 1181 * 1182 * capture_coefficient_increment = -round(rate*128*65536/48000; 1183 * capture_phase_increment = floor(48000*65536*1024/rate); 1184 * cx = round(48000*65536*1024 - capture_phase_increment*rate); 1185 * cy = floor(cx/200); 1186 * capture_sample_rate_correction = cx - 200*cy; 1187 * capture_delay = ceil(24*48000/rate); 1188 * capture_num_triplets = floor(65536*rate/24000); 1189 * capture_group_length = 24000/GCD(rate, 24000); 1190 * where GCD means "Greatest Common Divisor". 1191 * 1192 * capture_coefficient_increment, capture_phase_increment and 1193 * capture_num_triplets are 32-bit signed quantities. 1194 * capture_sample_rate_correction and capture_group_length are 1195 * 16-bit signed quantities. 1196 * capture_delay is a 14-bit unsigned quantity. 1197 */ 1198 uint32_t cci, cpi, cnt, cx, cy, tmp1; 1199 uint16_t csrc, cgl, cdlay; 1200 1201 /* XXX 1202 * Even though, embedded_audio_spec says capture rate range 11025 to 1203 * 48000, dhwiface.cpp says, 1204 * 1205 * "We can only decimate by up to a factor of 1/9th the hardware rate. 1206 * Return an error if an attempt is made to stray outside that limit." 1207 * 1208 * so assume range as 48000/9 to 48000 1209 */ 1210 1211 if (rate < 8000) 1212 rate = 8000; 1213 if (rate > 48000) 1214 rate = 48000; 1215 1216 cx = rate << 16; 1217 cci = cx / 48000; 1218 cx -= cci * 48000; 1219 cx <<= 7; 1220 cci <<= 7; 1221 cci += cx / 48000; 1222 cci = - cci; 1223 1224 cx = 48000 << 16; 1225 cpi = cx / rate; 1226 cx -= cpi * rate; 1227 cx <<= 10; 1228 cpi <<= 10; 1229 cy = cx / rate; 1230 cpi += cy; 1231 cx -= cy * rate; 1232 1233 cy = cx / 200; 1234 csrc = cx - 200*cy; 1235 1236 cdlay = ((48000 * 24) + rate - 1) / rate; 1237 #if 0 1238 cdlay &= 0x3fff; /* make sure cdlay is 14-bit */ 1239 #endif 1240 1241 cnt = rate << 16; 1242 cnt /= 24000; 1243 1244 cgl = 1; 1245 for (tmp1 = 2; tmp1 <= 64; tmp1 *= 2) { 1246 if (((rate / tmp1) * tmp1) != rate) 1247 cgl *= 2; 1248 } 1249 if (((rate / 3) * 3) != rate) 1250 cgl *= 3; 1251 for (tmp1 = 5; tmp1 <= 125; tmp1 *= 5) { 1252 if (((rate / tmp1) * tmp1) != rate) 1253 cgl *= 5; 1254 } 1255 #if 0 1256 /* XXX what manual says */ 1257 tmp1 = BA1READ4(sc, CS4280_CSRC) & ~CSRC_MASK; 1258 tmp1 |= csrc<<16; 1259 BA1WRITE4(sc, CS4280_CSRC, tmp1); 1260 #else 1261 /* suggested by cs461x.c (ALSA driver) */ 1262 BA1WRITE4(sc, CS4280_CSRC, CS4280_MK_CSRC(csrc, cy)); 1263 #endif 1264 1265 #if 0 1266 /* I am confused. The sample rate calculation section says 1267 * cci *is* 32-bit signed quantity but in the parameter description 1268 * section, CCI only assigned 16bit. 1269 * I believe size of the variable. 1270 */ 1271 tmp1 = BA1READ4(sc, CS4280_CCI) & ~CCI_MASK; 1272 tmp1 |= cci<<16; 1273 BA1WRITE4(sc, CS4280_CCI, tmp1); 1274 #else 1275 BA1WRITE4(sc, CS4280_CCI, cci); 1276 #endif 1277 1278 tmp1 = BA1READ4(sc, CS4280_CD) & ~CD_MASK; 1279 tmp1 |= cdlay <<18; 1280 BA1WRITE4(sc, CS4280_CD, tmp1); 1281 1282 BA1WRITE4(sc, CS4280_CPI, cpi); 1283 1284 tmp1 = BA1READ4(sc, CS4280_CGL) & ~CGL_MASK; 1285 tmp1 |= cgl; 1286 BA1WRITE4(sc, CS4280_CGL, tmp1); 1287 1288 BA1WRITE4(sc, CS4280_CNT, cnt); 1289 1290 tmp1 = BA1READ4(sc, CS4280_CGC) & ~CGC_MASK; 1291 tmp1 |= cgl; 1292 BA1WRITE4(sc, CS4280_CGC, tmp1); 1293 } 1294 1295 static void 1296 cs4280_set_dac_rate(struct cs428x_softc *sc, int rate) 1297 { 1298 /* 1299 * playback rate may range from 8000Hz to 48000Hz 1300 * 1301 * play_phase_increment = floor(rate*65536*1024/48000) 1302 * px = round(rate*65536*1024 - play_phase_incremnt*48000) 1303 * py=floor(px/200) 1304 * play_sample_rate_correction = px - 200*py 1305 * 1306 * play_phase_increment is a 32bit signed quantity. 1307 * play_sample_rate_correction is a 16bit signed quantity. 1308 */ 1309 int32_t ppi; 1310 int16_t psrc; 1311 uint32_t px, py; 1312 1313 if (rate < 8000) 1314 rate = 8000; 1315 if (rate > 48000) 1316 rate = 48000; 1317 px = rate << 16; 1318 ppi = px/48000; 1319 px -= ppi*48000; 1320 ppi <<= 10; 1321 px <<= 10; 1322 py = px / 48000; 1323 ppi += py; 1324 px -= py*48000; 1325 py = px/200; 1326 px -= py*200; 1327 psrc = px; 1328 #if 0 1329 /* what manual says */ 1330 px = BA1READ4(sc, CS4280_PSRC) & ~PSRC_MASK; 1331 BA1WRITE4(sc, CS4280_PSRC, 1332 ( ((psrc<<16) & PSRC_MASK) | px )); 1333 #else 1334 /* suggested by cs461x.c (ALSA driver) */ 1335 BA1WRITE4(sc, CS4280_PSRC, CS4280_MK_PSRC(psrc,py)); 1336 #endif 1337 BA1WRITE4(sc, CS4280_PPI, ppi); 1338 } 1339 1340 /* Download Processor Code and Data image */ 1341 static int 1342 cs4280_download(struct cs428x_softc *sc, const uint32_t *src, 1343 uint32_t offset, uint32_t len) 1344 { 1345 uint32_t ctr; 1346 #if CS4280_DEBUG > 10 1347 uint32_t con, data; 1348 uint8_t c0, c1, c2, c3; 1349 #endif 1350 if ((offset & 3) || (len & 3)) 1351 return -1; 1352 1353 len /= sizeof(uint32_t); 1354 for (ctr = 0; ctr < len; ctr++) { 1355 /* XXX: 1356 * I cannot confirm this is the right thing or not 1357 * on BIG-ENDIAN machines. 1358 */ 1359 BA1WRITE4(sc, offset+ctr*4, htole32(*(src+ctr))); 1360 #if CS4280_DEBUG > 10 1361 data = htole32(*(src+ctr)); 1362 c0 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+0); 1363 c1 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+1); 1364 c2 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+2); 1365 c3 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+3); 1366 con = (c3 << 24) | (c2 << 16) | (c1 << 8) | c0; 1367 if (data != con ) { 1368 printf("0x%06x: write=0x%08x read=0x%08x\n", 1369 offset+ctr*4, data, con); 1370 return -1; 1371 } 1372 #endif 1373 } 1374 return 0; 1375 } 1376 1377 static int 1378 cs4280_download_image(struct cs428x_softc *sc) 1379 { 1380 int idx, err; 1381 uint32_t offset = 0; 1382 1383 err = 0; 1384 for (idx = 0; idx < BA1_MEMORY_COUNT; ++idx) { 1385 err = cs4280_download(sc, &BA1Struct.map[offset], 1386 BA1Struct.memory[idx].offset, 1387 BA1Struct.memory[idx].size); 1388 if (err != 0) { 1389 aprint_error_dev(&sc->sc_dev, 1390 "load_image failed at %d\n", idx); 1391 return -1; 1392 } 1393 offset += BA1Struct.memory[idx].size / sizeof(uint32_t); 1394 } 1395 return err; 1396 } 1397 1398 /* Processor Soft Reset */ 1399 static void 1400 cs4280_reset(void *sc_) 1401 { 1402 struct cs428x_softc *sc; 1403 1404 sc = sc_; 1405 /* Set RSTSP bit in SPCR (also clear RUN, RUNFR, and DRQEN) */ 1406 BA1WRITE4(sc, CS4280_SPCR, SPCR_RSTSP); 1407 delay(100); 1408 /* Clear RSTSP bit in SPCR */ 1409 BA1WRITE4(sc, CS4280_SPCR, 0); 1410 /* enable DMA reqest */ 1411 BA1WRITE4(sc, CS4280_SPCR, SPCR_DRQEN); 1412 } 1413 1414 static int 1415 cs4280_init(struct cs428x_softc *sc, int init) 1416 { 1417 int n; 1418 uint32_t mem; 1419 int rv; 1420 1421 rv = 1; 1422 cs4280_clkrun_hack(sc, 1); 1423 1424 /* Start PLL out in known state */ 1425 BA0WRITE4(sc, CS4280_CLKCR1, 0); 1426 /* Start serial ports out in known state */ 1427 BA0WRITE4(sc, CS4280_SERMC1, 0); 1428 1429 /* Specify type of CODEC */ 1430 /* XXX should not be here */ 1431 #define SERACC_CODEC_TYPE_1_03 1432 #ifdef SERACC_CODEC_TYPE_1_03 1433 BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_1_03); /* AC 97 1.03 */ 1434 #else 1435 BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_2_0); /* AC 97 2.0 */ 1436 #endif 1437 1438 /* Reset codec */ 1439 BA0WRITE4(sc, CS428X_ACCTL, 0); 1440 delay(100); /* delay 100us */ 1441 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_RSTN); 1442 1443 /* Enable AC-link sync generation */ 1444 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_ESYN | ACCTL_RSTN); 1445 delay(50*1000); /* delay 50ms */ 1446 1447 /* Set the serial port timing configuration */ 1448 BA0WRITE4(sc, CS4280_SERMC1, SERMC1_PTC_AC97); 1449 1450 /* Setup clock control */ 1451 BA0WRITE4(sc, CS4280_PLLCC, PLLCC_CDR_STATE|PLLCC_LPF_STATE); 1452 BA0WRITE4(sc, CS4280_PLLM, PLLM_STATE); 1453 BA0WRITE4(sc, CS4280_CLKCR2, CLKCR2_PDIVS_8); 1454 1455 /* Power up the PLL */ 1456 BA0WRITE4(sc, CS4280_CLKCR1, CLKCR1_PLLP); 1457 delay(50*1000); /* delay 50ms */ 1458 1459 /* Turn on clock */ 1460 mem = BA0READ4(sc, CS4280_CLKCR1) | CLKCR1_SWCE; 1461 BA0WRITE4(sc, CS4280_CLKCR1, mem); 1462 1463 /* Set the serial port FIFO pointer to the 1464 * first sample in FIFO. (not documented) */ 1465 cs4280_clear_fifos(sc); 1466 1467 #if 0 1468 /* Set the serial port FIFO pointer to the first sample in the FIFO */ 1469 BA0WRITE4(sc, CS4280_SERBSP, 0); 1470 #endif 1471 1472 /* Configure the serial port */ 1473 BA0WRITE4(sc, CS4280_SERC1, SERC1_SO1EN | SERC1_SO1F_AC97); 1474 BA0WRITE4(sc, CS4280_SERC2, SERC2_SI1EN | SERC2_SI1F_AC97); 1475 BA0WRITE4(sc, CS4280_SERMC1, SERMC1_MSPE | SERMC1_PTC_AC97); 1476 1477 /* Wait for CODEC ready */ 1478 n = 0; 1479 while ((BA0READ4(sc, CS428X_ACSTS) & ACSTS_CRDY) == 0) { 1480 delay(125); 1481 if (++n > 1000) { 1482 aprint_error_dev(&sc->sc_dev, "codec ready timeout\n"); 1483 goto exit; 1484 } 1485 } 1486 1487 /* Assert valid frame signal */ 1488 BA0WRITE4(sc, CS428X_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 1489 1490 /* Wait for valid AC97 input slot */ 1491 n = 0; 1492 while ((BA0READ4(sc, CS428X_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) != 1493 (ACISV_ISV3 | ACISV_ISV4)) { 1494 delay(1000); 1495 if (++n > 1000) { 1496 printf("AC97 inputs slot ready timeout\n"); 1497 goto exit; 1498 } 1499 } 1500 1501 /* Set AC97 output slot valid signals */ 1502 BA0WRITE4(sc, CS428X_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); 1503 1504 /* reset the processor */ 1505 cs4280_reset(sc); 1506 1507 /* Download the image to the processor */ 1508 if (cs4280_download_image(sc) != 0) { 1509 aprint_error_dev(&sc->sc_dev, "image download error\n"); 1510 goto exit; 1511 } 1512 1513 /* Save playback parameter and then write zero. 1514 * this ensures that DMA doesn't immediately occur upon 1515 * starting the processor core 1516 */ 1517 mem = BA1READ4(sc, CS4280_PCTL); 1518 sc->pctl = mem & PCTL_MASK; /* save startup value */ 1519 BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK); 1520 if (init != 0) 1521 sc->sc_prun = 0; 1522 1523 /* Save capture parameter and then write zero. 1524 * this ensures that DMA doesn't immediately occur upon 1525 * starting the processor core 1526 */ 1527 mem = BA1READ4(sc, CS4280_CCTL); 1528 sc->cctl = mem & CCTL_MASK; /* save startup value */ 1529 BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK); 1530 if (init != 0) 1531 sc->sc_rrun = 0; 1532 1533 /* Processor Startup Procedure */ 1534 BA1WRITE4(sc, CS4280_FRMT, FRMT_FTV); 1535 BA1WRITE4(sc, CS4280_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); 1536 1537 /* Monitor RUNFR bit in SPCR for 1 to 0 transition */ 1538 n = 0; 1539 while (BA1READ4(sc, CS4280_SPCR) & SPCR_RUNFR) { 1540 delay(10); 1541 if (++n > 1000) { 1542 printf("SPCR 1->0 transition timeout\n"); 1543 goto exit; 1544 } 1545 } 1546 1547 n = 0; 1548 while (!(BA1READ4(sc, CS4280_SPCS) & SPCS_SPRUN)) { 1549 delay(10); 1550 if (++n > 1000) { 1551 printf("SPCS 0->1 transition timeout\n"); 1552 goto exit; 1553 } 1554 } 1555 /* Processor is now running !!! */ 1556 1557 /* Setup volume */ 1558 BA1WRITE4(sc, CS4280_PVOL, 0x80008000); 1559 BA1WRITE4(sc, CS4280_CVOL, 0x80008000); 1560 1561 /* Interrupt enable */ 1562 BA0WRITE4(sc, CS4280_HICR, HICR_IEV|HICR_CHGM); 1563 1564 /* playback interrupt enable */ 1565 mem = BA1READ4(sc, CS4280_PFIE) & ~PFIE_PI_MASK; 1566 mem |= PFIE_PI_ENABLE; 1567 BA1WRITE4(sc, CS4280_PFIE, mem); 1568 /* capture interrupt enable */ 1569 mem = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK; 1570 mem |= CIE_CI_ENABLE; 1571 BA1WRITE4(sc, CS4280_CIE, mem); 1572 1573 #if NMIDI > 0 1574 /* Reset midi port */ 1575 mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK; 1576 BA0WRITE4(sc, CS4280_MIDCR, mem | MIDCR_MRST); 1577 DPRINTF(("midi reset: 0x%x\n", BA0READ4(sc, CS4280_MIDCR))); 1578 /* midi interrupt enable */ 1579 mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE; 1580 BA0WRITE4(sc, CS4280_MIDCR, mem); 1581 #endif 1582 1583 rv = 0; 1584 1585 exit: 1586 cs4280_clkrun_hack(sc, -1); 1587 return rv; 1588 } 1589 1590 static void 1591 cs4280_clear_fifos(struct cs428x_softc *sc) 1592 { 1593 int pd, cnt, n; 1594 uint32_t mem; 1595 1596 pd = 0; 1597 /* 1598 * If device power down, power up the device and keep power down 1599 * state. 1600 */ 1601 mem = BA0READ4(sc, CS4280_CLKCR1); 1602 if (!(mem & CLKCR1_SWCE)) { 1603 printf("cs4280_clear_fifo: power down found.\n"); 1604 BA0WRITE4(sc, CS4280_CLKCR1, mem | CLKCR1_SWCE); 1605 pd = 1; 1606 } 1607 BA0WRITE4(sc, CS4280_SERBWP, 0); 1608 for (cnt = 0; cnt < 256; cnt++) { 1609 n = 0; 1610 while (BA0READ4(sc, CS4280_SERBST) & SERBST_WBSY) { 1611 delay(1000); 1612 if (++n > 1000) { 1613 printf("clear_fifo: fist timeout cnt=%d\n", cnt); 1614 break; 1615 } 1616 } 1617 BA0WRITE4(sc, CS4280_SERBAD, cnt); 1618 BA0WRITE4(sc, CS4280_SERBCM, SERBCM_WRC); 1619 } 1620 if (pd) 1621 BA0WRITE4(sc, CS4280_CLKCR1, mem); 1622 } 1623 1624 #if NMIDI > 0 1625 static int 1626 cs4280_midi_open(void *addr, int flags, void (*iintr)(void *, int), 1627 void (*ointr)(void *), void *arg) 1628 { 1629 struct cs428x_softc *sc; 1630 uint32_t mem; 1631 1632 DPRINTF(("midi_open\n")); 1633 sc = addr; 1634 sc->sc_iintr = iintr; 1635 sc->sc_ointr = ointr; 1636 sc->sc_arg = arg; 1637 1638 /* midi interrupt enable */ 1639 mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK; 1640 mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE | MIDCR_MLB; 1641 BA0WRITE4(sc, CS4280_MIDCR, mem); 1642 #ifdef CS4280_DEBUG 1643 if (mem != BA0READ4(sc, CS4280_MIDCR)) { 1644 DPRINTF(("midi_open: MIDCR=%d\n", BA0READ4(sc, CS4280_MIDCR))); 1645 return(EINVAL); 1646 } 1647 DPRINTF(("MIDCR=0x%x\n", BA0READ4(sc, CS4280_MIDCR))); 1648 #endif 1649 return 0; 1650 } 1651 1652 static void 1653 cs4280_midi_close(void *addr) 1654 { 1655 struct cs428x_softc *sc; 1656 uint32_t mem; 1657 1658 DPRINTF(("midi_close\n")); 1659 sc = addr; 1660 /* give uart a chance to drain */ 1661 kpause("cs0clm", false, hz/10, &sc->sc_intr_lock); 1662 mem = BA0READ4(sc, CS4280_MIDCR); 1663 mem &= ~MIDCR_MASK; 1664 BA0WRITE4(sc, CS4280_MIDCR, mem); 1665 1666 sc->sc_iintr = 0; 1667 sc->sc_ointr = 0; 1668 } 1669 1670 static int 1671 cs4280_midi_output(void *addr, int d) 1672 { 1673 struct cs428x_softc *sc; 1674 uint32_t mem; 1675 int x; 1676 1677 sc = addr; 1678 for (x = 0; x != MIDI_BUSY_WAIT; x++) { 1679 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) { 1680 mem = BA0READ4(sc, CS4280_MIDWP) & ~MIDWP_MASK; 1681 mem |= d & MIDWP_MASK; 1682 DPRINTFN(5,("midi_output d=0x%08x",d)); 1683 BA0WRITE4(sc, CS4280_MIDWP, mem); 1684 #ifdef DIAGNOSTIC 1685 if (mem != BA0READ4(sc, CS4280_MIDWP)) { 1686 DPRINTF(("Bad write data: %d %d", 1687 mem, BA0READ4(sc, CS4280_MIDWP))); 1688 return EIO; 1689 } 1690 #endif 1691 return 0; 1692 } 1693 delay(MIDI_BUSY_DELAY); 1694 } 1695 return EIO; 1696 } 1697 1698 static void 1699 cs4280_midi_getinfo(void *addr, struct midi_info *mi) 1700 { 1701 1702 mi->name = "CS4280 MIDI UART"; 1703 mi->props = MIDI_PROP_CAN_INPUT | MIDI_PROP_OUT_INTR; 1704 } 1705 1706 #endif /* NMIDI */ 1707 1708 /* DEBUG functions */ 1709 #if CS4280_DEBUG > 10 1710 static int 1711 cs4280_checkimage(struct cs428x_softc *sc, uint32_t *src, 1712 uint32_t offset, uint32_t len) 1713 { 1714 uint32_t ctr, data; 1715 int err; 1716 1717 if ((offset & 3) || (len & 3)) 1718 return -1; 1719 1720 err = 0; 1721 len /= sizeof(uint32_t); 1722 for (ctr = 0; ctr < len; ctr++) { 1723 /* I cannot confirm this is the right thing 1724 * on BIG-ENDIAN machines 1725 */ 1726 data = BA1READ4(sc, offset+ctr*4); 1727 if (data != htole32(*(src+ctr))) { 1728 printf("0x%06x: 0x%08x(0x%08x)\n", 1729 offset+ctr*4, data, *(src+ctr)); 1730 *(src+ctr) = data; 1731 ++err; 1732 } 1733 } 1734 return err; 1735 } 1736 1737 static int 1738 cs4280_check_images(struct cs428x_softc *sc) 1739 { 1740 int idx, err; 1741 uint32_t offset; 1742 1743 offset = 0; 1744 err = 0; 1745 /*for (idx=0; idx < BA1_MEMORY_COUNT; ++idx)*/ 1746 for (idx = 0; idx < 1; ++idx) { 1747 err = cs4280_checkimage(sc, &BA1Struct.map[offset], 1748 BA1Struct.memory[idx].offset, 1749 BA1Struct.memory[idx].size); 1750 if (err != 0) { 1751 aprint_error_dev(&sc->sc_dev, 1752 "check_image failed at %d\n", idx); 1753 } 1754 offset += BA1Struct.memory[idx].size / sizeof(uint32_t); 1755 } 1756 return err; 1757 } 1758 1759 #endif /* CS4280_DEBUG */ 1760