esa.c revision 1.7
1/* $NetBSD: esa.c,v 1.7 2002/01/14 19:24:39 pooka Exp $ */ 2 3/* 4 * Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill@invisible.yi.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. The name of the author may not be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28/* 29 * ESS Allegro-1 / Maestro3 Audio Driver 30 * 31 * Based on the FreeBSD maestro3 driver and the NetBSD eap driver. 32 * Original driver by Don Kim. 33 */ 34 35#include <sys/types.h> 36#include <sys/errno.h> 37#include <sys/null.h> 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/device.h> 42#include <sys/conf.h> 43#include <sys/exec.h> 44#include <sys/select.h> 45#include <sys/audioio.h> 46 47#include <machine/bus.h> 48#include <machine/intr.h> 49 50#include <dev/pci/pcidevs.h> 51#include <dev/pci/pcivar.h> 52 53#include <dev/audio_if.h> 54#include <dev/mulaw.h> 55#include <dev/auconv.h> 56#include <dev/ic/ac97var.h> 57#include <dev/ic/ac97reg.h> 58 59#include <dev/pci/esareg.h> 60#include <dev/pci/esadsp.h> 61#include <dev/pci/esavar.h> 62 63#define PCI_CBIO 0x10 64 65#define ESA_DAC_DATA 0x1100 66 67enum { 68 ESS_ALLEGRO1, 69 ESS_MAESTRO3 70}; 71 72static struct esa_card_type { 73 u_int16_t pci_vendor_id; 74 u_int16_t pci_product_id; 75 int type; 76 int delay1, delay2; 77} esa_card_types[] = { 78 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_ALLEGRO1, 79 ESS_ALLEGRO1, 50, 800 }, 80 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3, 81 ESS_MAESTRO3, 20, 500 }, 82 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3_2, 83 ESS_MAESTRO3, 20, 500 }, 84 { 0, 0, 0, 0, 0 } 85}; 86 87struct audio_device esa_device = { 88 "ESS Allegro", 89 "", 90 "esa" 91}; 92 93int esa_match(struct device *, struct cfdata *, void *); 94void esa_attach(struct device *, struct device *, void *); 95int esa_detach(struct device *, int); 96 97/* audio(9) functions */ 98int esa_open(void *, int); 99void esa_close(void *); 100int esa_query_encoding(void *, struct audio_encoding *); 101int esa_set_params(void *, int, int, struct audio_params *, 102 struct audio_params *); 103int esa_round_blocksize(void *, int); 104int esa_init_output(void *, void *, int); 105int esa_halt_output(void *); 106int esa_halt_input(void *); 107int esa_set_port(void *, mixer_ctrl_t *); 108int esa_get_port(void *, mixer_ctrl_t *); 109int esa_query_devinfo(void *, mixer_devinfo_t *); 110void * esa_malloc(void *, int, size_t, int, int); 111void esa_free(void *, void *, int); 112int esa_getdev(void *, struct audio_device *); 113size_t esa_round_buffersize(void *, int, size_t); 114int esa_get_props(void *); 115int esa_trigger_output(void *, void *, void *, int, 116 void (*)(void *), void *, 117 struct audio_params *); 118int esa_trigger_input(void *, void *, void *, int, 119 void (*)(void *), void *, 120 struct audio_params *); 121 122int esa_intr(void *); 123int esa_allocmem(struct esa_softc *, size_t, size_t, 124 struct esa_dma *); 125int esa_freemem(struct esa_softc *, struct esa_dma *); 126paddr_t esa_mappage(void *addr, void *mem, off_t off, int prot); 127 128/* Supporting subroutines */ 129u_int16_t esa_read_assp(struct esa_softc *, u_int16_t, u_int16_t); 130void esa_write_assp(struct esa_softc *, u_int16_t, u_int16_t, 131 u_int16_t); 132int esa_init_codec(struct esa_softc *); 133int esa_attach_codec(void *, struct ac97_codec_if *); 134int esa_read_codec(void *, u_int8_t, u_int16_t *); 135int esa_write_codec(void *, u_int8_t, u_int16_t); 136void esa_reset_codec(void *); 137enum ac97_host_flags esa_flags_codec(void *); 138int esa_wait(struct esa_softc *); 139int esa_init(struct esa_softc *); 140void esa_config(struct esa_softc *); 141u_int8_t esa_assp_halt(struct esa_softc *); 142void esa_codec_reset(struct esa_softc *); 143int esa_amp_enable(struct esa_softc *); 144void esa_enable_interrupts(struct esa_softc *); 145u_int32_t esa_get_pointer(struct esa_softc *, struct esa_channel *); 146 147/* power management */ 148int esa_power(struct esa_softc *, int); 149void esa_powerhook(int, void *); 150int esa_suspend(struct esa_softc *); 151int esa_resume(struct esa_softc *); 152 153struct device * audio_attach_mi_lkm(struct audio_hw_if *, void *, 154 struct device *); 155 156static audio_encoding_t esa_encoding[] = { 157 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 }, 158 { 1, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 159 AUDIO_ENCODINGFLAG_EMULATED }, 160 { 2, AudioEalaw, AUDIO_ENCODING_ALAW, 8, AUDIO_ENCODINGFLAG_EMULATED }, 161 { 3, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 162 AUDIO_ENCODINGFLAG_EMULATED }, /* XXX: Are you sure? */ 163 { 4, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 }, 164 { 5, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 165 AUDIO_ENCODINGFLAG_EMULATED }, 166 { 6, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 167 AUDIO_ENCODINGFLAG_EMULATED }, 168 { 7, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 169 AUDIO_ENCODINGFLAG_EMULATED } 170}; 171 172#define ESA_NENCODINGS 8 173 174struct audio_hw_if esa_hw_if = { 175 esa_open, 176 esa_close, 177 NULL, /* drain */ 178 esa_query_encoding, 179 esa_set_params, 180 esa_round_blocksize, 181 NULL, /* commit_settings */ 182 esa_init_output, 183 NULL, /* esa_init_input */ 184 NULL, /* start_output */ 185 NULL, /* start_input */ 186 esa_halt_output, 187 esa_halt_input, 188 NULL, /* speaker_ctl */ 189 esa_getdev, 190 NULL, /* getfd */ 191 esa_set_port, 192 esa_get_port, 193 esa_query_devinfo, 194 esa_malloc, 195 esa_free, 196 esa_round_buffersize, 197 esa_mappage, 198 esa_get_props, 199 esa_trigger_output, 200 esa_trigger_input 201}; 202 203struct cfattach esa_ca = { 204 sizeof(struct esa_softc), esa_match, esa_attach, 205 esa_detach, /*esa_activate*/ NULL 206}; 207 208/* 209 * audio(9) functions 210 */ 211 212int 213esa_open(void *hdl, int flags) 214{ 215 216 return (0); 217} 218 219void 220esa_close(void *hdl) 221{ 222 223 return; 224} 225 226int 227esa_query_encoding(void *hdl, struct audio_encoding *ae) 228{ 229 230 if (ae->index < 0 || ae->index >= ESA_NENCODINGS) 231 return (EINVAL); 232 *ae = esa_encoding[ae->index]; 233 234 return (0); 235} 236 237int 238esa_set_params(void *hdl, int setmode, int usemode, struct audio_params *play, 239 struct audio_params *rec) 240{ 241 struct esa_softc *sc = hdl; 242 struct esa_channel *ch; 243 struct audio_params *p; 244 u_int32_t data; 245 u_int32_t freq; 246 int mode; 247 248 for (mode = AUMODE_RECORD; mode != -1; 249 mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) { 250 if ((setmode & mode) == 0) 251 continue; 252 253 switch (mode) { 254 case AUMODE_PLAY: 255 p = play; 256 ch = &sc->play; 257 break; 258 case AUMODE_RECORD: 259 p = rec; 260 ch = &sc->rec; 261 break; 262 } 263 264 if (p->sample_rate < ESA_MINRATE || 265 p->sample_rate > ESA_MAXRATE || 266 (p->precision != 8 && p->precision != 16) || 267 (p->channels < 1 && p->channels > 2)) 268 return (EINVAL); 269 270 p->factor = 1; 271 p->sw_code = 0; 272 273 switch(p->encoding) { 274 case AUDIO_ENCODING_SLINEAR_BE: 275 if (p->precision == 16) 276 p->sw_code = swap_bytes; 277 else 278 p->sw_code = change_sign8; 279 break; 280 case AUDIO_ENCODING_SLINEAR_LE: 281 if (p->precision != 16) 282 p->sw_code = change_sign8; 283 break; 284 case AUDIO_ENCODING_ULINEAR_BE: 285 if (p->precision == 16) { 286 if (mode == AUMODE_PLAY) 287 p->sw_code = 288 swap_bytes_change_sign16_le; 289 else 290 p->sw_code = 291 change_sign16_swap_bytes_le; 292 } 293 break; 294 case AUDIO_ENCODING_ULINEAR_LE: 295 if (p->precision == 16) 296 p->sw_code = change_sign16_le; 297 break; 298 case AUDIO_ENCODING_ULAW: 299 if (mode == AUMODE_PLAY) { 300 p->factor = 2; 301 p->sw_code = mulaw_to_slinear16_le; 302 } else 303 p->sw_code = ulinear8_to_mulaw; 304 break; 305 case AUDIO_ENCODING_ALAW: 306 if (mode == AUMODE_PLAY) { 307 p->factor = 2; 308 p->sw_code = alaw_to_slinear16_le; 309 } else 310 p->sw_code = ulinear8_to_alaw; 311 break; 312 default: 313 return (EINVAL); 314 } 315 316 if (p->channels == 1) 317 data = 1; 318 else 319 data = 0; 320 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 321 ch->data_offset + ESA_SRC3_MODE_OFFSET, 322 data); 323 324 if (play->precision * play->factor == 8) 325 data = 1; 326 else 327 data = 0; 328 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 329 ch->data_offset + ESA_SRC3_WORD_LENGTH_OFFSET, 330 data); 331 332 if ((freq = ((p->sample_rate << 15) + 24000) / 48000) != 0) { 333 freq--; 334 } 335 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 336 ch->data_offset + ESA_CDATA_FREQUENCY, freq); 337 } 338 339 return (0); 340} 341 342int 343esa_round_blocksize(void *hdl, int bs) 344{ 345 struct esa_softc *sc = hdl; 346 347 sc->play.blksize = sc->rec.blksize = 4096; 348 349 return (sc->play.blksize); 350} 351 352int 353esa_init_output(void *hdl, void *buffer, int size) 354{ 355 356 return (0); 357} 358 359int 360esa_halt_output(void *hdl) 361{ 362 struct esa_softc *sc = hdl; 363 364 if (sc->play.active == 0) 365 return (0); 366 367 sc->play.active = 0; 368 369 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 370 ESA_KDATA_INSTANCE0_MINISRC, 0); 371 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0, 0); 372 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_MIXER_XFER0, 0); 373 374 return (0); 375} 376 377int 378esa_halt_input(void *hdl) 379{ 380 struct esa_softc *sc = hdl; 381 bus_space_tag_t iot = sc->sc_iot; 382 bus_space_handle_t ioh = sc->sc_ioh; 383 u_int32_t data; 384 385 if (sc->rec.active == 0) 386 return (0); 387 388 sc->rec.active = 0; 389 390 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 391 ESA_KDATA_TIMER_COUNT_RELOAD, 0); 392 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_TIMER_COUNT_CURRENT, 0); 393 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL); 394 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, data & ~ESA_CLKRUN_GEN_ENABLE); 395 396 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, sc->rec.data_offset + 397 ESA_CDATA_INSTANCE_READY, 0); 398 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_REQUEST, 0); 399 400 return (0); 401} 402 403void * 404esa_malloc(void *hdl, int direction, size_t size, int type, int flags) 405{ 406 struct esa_softc *sc = hdl; 407 struct esa_dma *p; 408 int error; 409 410 p = malloc(sizeof(*p), type, flags); 411 if (!p) 412 return (0); 413 error = esa_allocmem(sc, size, 16, p); 414 if (error) { 415 free(p, type); 416 printf("%s: esa_malloc: not enough memory\n", 417 sc->sc_dev.dv_xname); 418 return (0); 419 } 420 p->next = sc->sc_dmas; 421 sc->sc_dmas = p; 422 423 return (KERNADDR(p)); 424} 425 426void 427esa_free(void *hdl, void *addr, int type) 428{ 429 struct esa_softc *sc = hdl; 430 struct esa_dma *p; 431 struct esa_dma **pp; 432 433 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) 434 if (KERNADDR(p) == addr) { 435 esa_freemem(sc, p); 436 *pp = p->next; 437 free(p, type); 438 return; 439 } 440} 441 442int 443esa_getdev(void *hdl, struct audio_device *ret) 444{ 445 446 *ret = esa_device; 447 448 return (0); 449} 450 451int 452esa_set_port(void *hdl, mixer_ctrl_t *mc) 453{ 454 struct esa_softc *sc = hdl; 455 456 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, mc)); 457} 458 459int 460esa_get_port(void *hdl, mixer_ctrl_t *mc) 461{ 462 struct esa_softc *sc = hdl; 463 464 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, mc)); 465} 466 467int 468esa_query_devinfo(void *hdl, mixer_devinfo_t *di) 469{ 470 struct esa_softc *sc = hdl; 471 472 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, di)); 473} 474 475size_t 476esa_round_buffersize(void *hdl, int direction, size_t bufsize) 477{ 478 struct esa_softc *sc = hdl; 479 480 sc->play.bufsize = sc->rec.bufsize = 65536; 481 482 return (sc->play.bufsize); 483} 484 485int 486esa_get_props(void *hdl) 487{ 488 489 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX); 490} 491 492int 493esa_trigger_output(void *hdl, void *start, void *end, int blksize, 494 void (*intr)(void *), void *intrarg, 495 struct audio_params *param) 496{ 497 struct esa_softc *sc = hdl; 498 struct esa_dma *p; 499 bus_space_tag_t iot = sc->sc_iot; 500 bus_space_handle_t ioh = sc->sc_ioh; 501 u_int32_t data; 502 u_int32_t bufaddr; 503 u_int32_t i; 504 size_t size; 505 int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) + 506 (ESA_MINISRC_IN_BUFFER_SIZE & ~1) + 507 (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255) 508 &~ 255; 509 int dac_data = ESA_DAC_DATA + data_bytes; 510 int dsp_in_size = ESA_MINISRC_IN_BUFFER_SIZE - (0x20 * 2); 511 int dsp_out_size = ESA_MINISRC_OUT_BUFFER_SIZE - (0x20 * 2); 512 int dsp_in_buf = dac_data + (ESA_MINISRC_TMP_BUFFER_SIZE / 2); 513 int dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1; 514 sc->play.data_offset = dac_data; 515 516 if (sc->play.active) 517 return (EINVAL); 518 519 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 520 ; 521 if (!p) { 522 printf("%s: esa_trigger_output: bad addr %p\n", 523 sc->sc_dev.dv_xname, start); 524 return (EINVAL); 525 } 526 527 sc->play.active = 1; 528 sc->play.intr = intr; 529 sc->play.arg = intrarg; 530 sc->play.pos = 0; 531 sc->play.count = 0; 532 sc->play.buf = start; 533 size = (size_t)(((caddr_t)end - (caddr_t)start)); 534 bufaddr = DMAADDR(p); 535 sc->play.start = bufaddr; 536 537#define LO(x) ((x) & 0x0000ffff) 538#define HI(x) ((x) >> 16) 539 540 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 541 ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr)); 542 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 543 ESA_CDATA_HOST_SRC_ADDRH, HI(bufaddr)); 544 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 545 ESA_CDATA_HOST_SRC_END_PLUS_1L, LO(bufaddr + size)); 546 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 547 ESA_CDATA_HOST_SRC_END_PLUS_1H, HI(bufaddr + size)); 548 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 549 ESA_CDATA_HOST_SRC_CURRENTL, LO(bufaddr)); 550 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 551 ESA_CDATA_HOST_SRC_CURRENTH, HI(bufaddr)); 552 553 /* DSP buffers */ 554 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 555 ESA_CDATA_IN_BUF_BEGIN, dsp_in_buf); 556 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 557 ESA_CDATA_IN_BUF_END_PLUS_1, dsp_in_buf + (dsp_in_size / 2)); 558 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 559 ESA_CDATA_IN_BUF_HEAD, dsp_in_buf); 560 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 561 ESA_CDATA_IN_BUF_TAIL, dsp_in_buf); 562 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 563 ESA_CDATA_OUT_BUF_BEGIN, dsp_out_buf); 564 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 565 ESA_CDATA_OUT_BUF_END_PLUS_1, dsp_out_buf + (dsp_out_size / 2)); 566 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 567 ESA_CDATA_OUT_BUF_HEAD, dsp_out_buf); 568 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 569 ESA_CDATA_OUT_BUF_TAIL, dsp_out_buf); 570 571 /* Some per-client initializers */ 572 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 573 ESA_SRC3_DIRECTION_OFFSET + 12, dac_data + 40 + 8); 574 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 575 ESA_SRC3_DIRECTION_OFFSET + 19, 0x400 + ESA_MINISRC_COEF_LOC); 576 /* Enable or disable low-pass filter? (0xff if rate > 45000) */ 577 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 578 ESA_SRC3_DIRECTION_OFFSET + 22, 0); 579 /* Tell it which way DMA is going */ 580 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 581 ESA_CDATA_DMA_CONTROL, 582 ESA_DMACONTROL_AUTOREPEAT + ESA_DMAC_PAGE3_SELECTOR + 583 ESA_DMAC_BLOCKF_SELECTOR); 584 585 /* Set an armload of static initializers */ 586 for (i = 0; i < (sizeof(esa_playvals) / sizeof(esa_playvals[0])); i++) 587 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 588 esa_playvals[i].addr, esa_playvals[i].val); 589 590 /* Put us in the packed task lists */ 591 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 592 ESA_KDATA_INSTANCE0_MINISRC, 593 dac_data >> ESA_DP_SHIFT_COUNT); 594 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0, 595 dac_data >> ESA_DP_SHIFT_COUNT); 596 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_MIXER_XFER0, 597 dac_data >> ESA_DP_SHIFT_COUNT); 598#undef LO 599#undef HI 600 601 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 602 ESA_KDATA_TIMER_COUNT_RELOAD, 240); 603 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 604 ESA_KDATA_TIMER_COUNT_CURRENT, 240); 605 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL); 606 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 607 data | ESA_CLKRUN_GEN_ENABLE); 608 609 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + 610 ESA_CDATA_INSTANCE_READY, 1); 611 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 612 ESA_KDATA_MIXER_TASK_NUMBER, 1); 613 614 return (0); 615} 616 617int 618esa_trigger_input(void *hdl, void *start, void *end, int blksize, 619 void (*intr)(void *), void *intrarg, 620 struct audio_params *param) 621{ 622 struct esa_softc *sc = hdl; 623 struct esa_dma *p; 624 bus_space_tag_t iot = sc->sc_iot; 625 bus_space_handle_t ioh = sc->sc_ioh; 626 u_int32_t data; 627 u_int32_t bufaddr; 628 u_int32_t i; 629 size_t size; 630 int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) + 631 (ESA_MINISRC_IN_BUFFER_SIZE & ~1) + 632 (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255) 633 &~ 255; 634 int adc_data = ESA_DAC_DATA + data_bytes + (data_bytes / 2); 635 int dsp_in_size = ESA_MINISRC_IN_BUFFER_SIZE - (0x10 * 2); 636 int dsp_out_size = ESA_MINISRC_OUT_BUFFER_SIZE - (0x10 * 2); 637 int dsp_in_buf = adc_data + (ESA_MINISRC_TMP_BUFFER_SIZE / 2); 638 int dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1; 639 sc->rec.data_offset = adc_data; 640 641 if (sc->rec.active) 642 return (EINVAL); 643 644 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 645 ; 646 if (!p) { 647 printf("%s: esa_trigger_input: bad addr %p\n", 648 sc->sc_dev.dv_xname, start); 649 return (EINVAL); 650 } 651 652 sc->rec.active = 1; 653 sc->rec.intr = intr; 654 sc->rec.arg = intrarg; 655 sc->rec.pos = 0; 656 sc->rec.count = 0; 657 sc->rec.buf = start; 658 size = (size_t)(((caddr_t)end - (caddr_t)start)); 659 bufaddr = DMAADDR(p); 660 sc->rec.start = bufaddr; 661 662#define LO(x) ((x) & 0x0000ffff) 663#define HI(x) ((x) >> 16) 664 665 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 666 ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr)); 667 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 668 ESA_CDATA_HOST_SRC_ADDRH, HI(bufaddr)); 669 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 670 ESA_CDATA_HOST_SRC_END_PLUS_1L, LO(bufaddr + size)); 671 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 672 ESA_CDATA_HOST_SRC_END_PLUS_1H, HI(bufaddr + size)); 673 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 674 ESA_CDATA_HOST_SRC_CURRENTL, LO(bufaddr)); 675 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 676 ESA_CDATA_HOST_SRC_CURRENTH, HI(bufaddr)); 677 678 /* DSP buffers */ 679 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 680 ESA_CDATA_IN_BUF_BEGIN, dsp_in_buf); 681 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 682 ESA_CDATA_IN_BUF_END_PLUS_1, dsp_in_buf + (dsp_in_size / 2)); 683 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 684 ESA_CDATA_IN_BUF_HEAD, dsp_in_buf); 685 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 686 ESA_CDATA_IN_BUF_TAIL, dsp_in_buf); 687 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 688 ESA_CDATA_OUT_BUF_BEGIN, dsp_out_buf); 689 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 690 ESA_CDATA_OUT_BUF_END_PLUS_1, dsp_out_buf + (dsp_out_size / 2)); 691 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 692 ESA_CDATA_OUT_BUF_HEAD, dsp_out_buf); 693 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 694 ESA_CDATA_OUT_BUF_TAIL, dsp_out_buf); 695 696 /* Some per-client initializers */ 697 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 698 ESA_SRC3_DIRECTION_OFFSET + 12, adc_data + 40 + 8); 699 /* Tell it which way DMA is going */ 700 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 701 ESA_CDATA_DMA_CONTROL, 702 ESA_DMACONTROL_DIRECTION + ESA_DMACONTROL_AUTOREPEAT + 703 ESA_DMAC_PAGE3_SELECTOR + ESA_DMAC_BLOCKF_SELECTOR); 704 705 /* Set an armload of static initializers */ 706 for (i = 0; i < (sizeof(esa_recvals) / sizeof(esa_recvals[0])); i++) 707 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 708 esa_recvals[i].addr, esa_recvals[i].val); 709 710 /* Put us in the packed task lists */ 711 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 712 ESA_KDATA_INSTANCE0_MINISRC, 713 adc_data >> ESA_DP_SHIFT_COUNT); 714 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0, 715 adc_data >> ESA_DP_SHIFT_COUNT); 716 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_XFER0, 717 adc_data >> ESA_DP_SHIFT_COUNT); 718#undef LO 719#undef HI 720 721 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 722 ESA_KDATA_TIMER_COUNT_RELOAD, 240); 723 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 724 ESA_KDATA_TIMER_COUNT_CURRENT, 240); 725 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL); 726 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 727 data | ESA_CLKRUN_GEN_ENABLE); 728 729 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_REQUEST, 1); 730 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + 731 ESA_CDATA_INSTANCE_READY, 1); 732 733 return (0); 734} 735 736/* Interrupt handler */ 737 738int 739esa_intr(void *hdl) 740{ 741 struct esa_softc *sc = hdl; 742 bus_space_tag_t iot = sc->sc_iot; 743 bus_space_handle_t ioh = sc->sc_ioh; 744 u_int32_t status, ctl; 745 u_int32_t pos; 746 u_int32_t diff; 747 u_int32_t play_blksize = sc->play.blksize; 748 u_int32_t play_bufsize = sc->play.bufsize; 749 u_int32_t rec_blksize = sc->rec.blksize; 750 u_int32_t rec_bufsize = sc->rec.bufsize; 751 752 status = bus_space_read_1(iot, ioh, ESA_HOST_INT_STATUS); 753 if (!status) 754 return (0); 755 756 /* ack the interrupt */ 757 bus_space_write_1(iot, ioh, ESA_HOST_INT_STATUS, 0xff); 758 759 if (status & ESA_HV_INT_PENDING) { 760 u_int8_t event; 761 762 printf("%s: hardware volume interrupt\n", sc->sc_dev.dv_xname); 763 event = bus_space_read_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER); 764 switch(event) { 765 case 0x99: 766 case 0xaa: 767 case 0x66: 768 case 0x88: 769 printf("%s: esa_intr: FIXME\n", sc->sc_dev.dv_xname); 770 break; 771 default: 772 printf("%s: unknown hwvol event 0x%02x\n", 773 sc->sc_dev.dv_xname, event); 774 break; 775 } 776 bus_space_write_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER, 0x88); 777 } 778 779 if (status & ESA_ASSP_INT_PENDING) { 780 ctl = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_B); 781 if (!(ctl & ESA_STOP_ASSP_CLOCK)) { 782 ctl = bus_space_read_1(iot, ioh, 783 ESA_ASSP_HOST_INT_STATUS); 784 if (ctl & ESA_DSP2HOST_REQ_TIMER) { 785 bus_space_write_1(iot, ioh, 786 ESA_ASSP_HOST_INT_STATUS, 787 ESA_DSP2HOST_REQ_TIMER); 788 if (sc->play.active) { 789 pos = esa_get_pointer(sc, &sc->play) 790 % play_bufsize; 791 diff = (play_bufsize + pos - sc->play.pos) 792 % play_bufsize; 793 sc->play.pos = pos; 794 sc->play.count += diff; 795 while(sc->play.count >= play_blksize) { 796 sc->play.count -= play_blksize; 797 (*sc->play.intr)(sc->play.arg); 798 } 799 } 800 if (sc->rec.active) { 801 pos = esa_get_pointer(sc, &sc->rec) 802 % rec_bufsize; 803 diff = (rec_bufsize + pos - sc->rec.pos) 804 % rec_bufsize; 805 sc->rec.pos = pos; 806 sc->rec.count += diff; 807 while(sc->rec.count >= rec_blksize) { 808 sc->rec.count -= rec_blksize; 809 (*sc->rec.intr)(sc->rec.arg); 810 } 811 } 812 } 813 } 814 } 815 816 return (1); 817} 818 819int 820esa_allocmem(struct esa_softc *sc, size_t size, size_t align, 821 struct esa_dma *p) 822{ 823 int error; 824 825 p->size = size; 826 error = bus_dmamem_alloc(sc->sc_dmat, p->size, align, 0, 827 p->segs, sizeof(p->segs) / sizeof(p->segs[0]), 828 &p->nsegs, BUS_DMA_NOWAIT); 829 if (error) 830 return (error); 831 832 error = bus_dmamem_map(sc->sc_dmat, p->segs, p->nsegs, p->size, 833 &p->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 834 if (error) 835 goto free; 836 837 error = bus_dmamap_create(sc->sc_dmat, p->size, 1, p->size, 0, 838 BUS_DMA_NOWAIT, &p->map); 839 if (error) 840 goto unmap; 841 842 error = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, p->size, NULL, 843 BUS_DMA_NOWAIT); 844 if (error) 845 goto destroy; 846 847 return (0); 848 849destroy: 850 bus_dmamap_destroy(sc->sc_dmat, p->map); 851unmap: 852 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 853free: 854 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 855 856 return (error); 857} 858 859int 860esa_freemem(struct esa_softc *sc, struct esa_dma *p) 861{ 862 863 bus_dmamap_unload(sc->sc_dmat, p->map); 864 bus_dmamap_destroy(sc->sc_dmat, p->map); 865 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 866 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 867 868 return (0); 869} 870 871/* 872 * Supporting Subroutines 873 */ 874 875int 876esa_match(struct device *dev, struct cfdata *match, void *aux) 877{ 878 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 879 880 switch(PCI_VENDOR(pa->pa_id)) { 881 case PCI_VENDOR_ESSTECH: 882 switch(PCI_PRODUCT(pa->pa_id)) { 883 case PCI_PRODUCT_ESSTECH_ALLEGRO1: 884 case PCI_PRODUCT_ESSTECH_MAESTRO3: 885 case PCI_PRODUCT_ESSTECH_MAESTRO3_2: 886 return (1); 887 } 888 } 889 890 return (0); 891} 892 893void 894esa_attach(struct device *parent, struct device *self, void *aux) 895{ 896 struct esa_softc *sc = (struct esa_softc *)self; 897 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 898 pcitag_t tag = pa->pa_tag; 899 pci_chipset_tag_t pc = pa->pa_pc; 900 pci_intr_handle_t ih; 901 struct esa_card_type *card; 902 const char *intrstr; 903 u_int32_t data; 904 char devinfo[256]; 905 int revision, len; 906 907 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); 908 revision = PCI_REVISION(pa->pa_class); 909 printf(": %s (rev. 0x%02x)\n", devinfo, revision); 910 911 for (card = esa_card_types; card->pci_vendor_id; card++) 912 if (PCI_VENDOR(pa->pa_id) == card->pci_vendor_id && 913 PCI_PRODUCT(pa->pa_id) == card->pci_product_id) { 914 sc->type = card->type; 915 sc->delay1 = card->delay1; 916 sc->delay2 = card->delay2; 917 break; 918 } 919 920 data = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 921 data |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE 922 | PCI_COMMAND_MASTER_ENABLE); 923 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, data); 924 925 /* Map I/O register */ 926 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, 927 &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios)) { 928 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname); 929 return; 930 } 931 932 /* Initialize softc */ 933 sc->sc_tag = tag; 934 sc->sc_pct = pc; 935 sc->sc_dmat = pa->pa_dmat; 936 937 /* Map and establish an interrupt */ 938 if (pci_intr_map(pa, &ih)) { 939 printf("%s: can't map interrupt\n", sc->sc_dev.dv_xname); 940 return; 941 } 942 intrstr = pci_intr_string(pc, ih); 943 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, esa_intr, self); 944 if (sc->sc_ih == NULL) { 945 printf("%s: can't establish interrupt", sc->sc_dev.dv_xname); 946 if (intrstr != NULL) 947 printf(" at %s", intrstr); 948 printf("\n"); 949 return; 950 } 951 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); 952 953 /* Power up chip */ 954 esa_power(sc, PCI_PMCSR_STATE_D0); 955 956 /* Init chip */ 957 if (esa_init(sc) == -1) { 958 printf("%s: esa_attach: unable to initialize the card\n", 959 sc->sc_dev.dv_xname); 960 return; 961 } 962 963 /* create suspend save area */ 964 len = sizeof(u_int16_t) * (ESA_REV_B_CODE_MEMORY_LENGTH 965 + ESA_REV_B_DATA_MEMORY_LENGTH + 1); 966 sc->savemem = (u_int16_t *)malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); 967 if (sc->savemem == NULL) { 968 printf("%s: unable to allocate suspend buffer\n", 969 sc->sc_dev.dv_xname); 970 return; 971 } 972 973 /* 974 * Every card I've seen has had their channels swapped with respect 975 * to the mixer. Ie: 976 * $ mixerctl -w outputs.master=0,191 977 * Would result in the _right_ speaker being turned off. 978 * 979 * So, we will swap the left and right mixer channels to compensate 980 * for this. 981 */ 982 sc->codec_flags |= AC97_HOST_SWAPPED_CHANNELS; 983 sc->codec_flags |= AC97_HOST_DONT_READ; 984 985 /* Attach AC97 host interface */ 986 sc->host_if.arg = self; 987 sc->host_if.attach = esa_attach_codec; 988 sc->host_if.read = esa_read_codec; 989 sc->host_if.write = esa_write_codec; 990 sc->host_if.reset = esa_reset_codec; 991 sc->host_if.flags = esa_flags_codec; 992 993 if (ac97_attach(&sc->host_if) != 0) 994 return; 995 996 sc->sc_audiodev = audio_attach_mi(&esa_hw_if, self, &sc->sc_dev); 997 998 sc->powerhook = powerhook_establish(esa_powerhook, sc); 999 if (sc->powerhook == NULL) 1000 printf("%s: WARNING: unable to establish powerhook\n", 1001 sc->sc_dev.dv_xname); 1002 1003 return; 1004} 1005 1006int 1007esa_detach(struct device *self, int flags) 1008{ 1009 struct esa_softc *sc = (struct esa_softc *)self; 1010 int rv = 0; 1011 1012 if (sc->sc_audiodev != NULL) 1013 rv = config_detach(sc->sc_audiodev, flags); 1014 if (rv) 1015 return (rv); 1016 1017 if (sc->sc_ih != NULL) 1018 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 1019 if (sc->sc_ios) 1020 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 1021 1022 return (0); 1023} 1024 1025u_int16_t 1026esa_read_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index) 1027{ 1028 u_int16_t data; 1029 bus_space_tag_t iot = sc->sc_iot; 1030 bus_space_handle_t ioh = sc->sc_ioh; 1031 1032 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE, 1033 region & ESA_MEMTYPE_MASK); 1034 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index); 1035 data = bus_space_read_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA); 1036 1037 return (data); 1038} 1039 1040void 1041esa_write_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index, 1042 u_int16_t data) 1043{ 1044 bus_space_tag_t iot = sc->sc_iot; 1045 bus_space_handle_t ioh = sc->sc_ioh; 1046 1047 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE, 1048 region & ESA_MEMTYPE_MASK); 1049 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index); 1050 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA, data); 1051 1052 return; 1053} 1054 1055int 1056esa_init_codec(struct esa_softc *sc) 1057{ 1058 bus_space_tag_t iot = sc->sc_iot; 1059 bus_space_handle_t ioh = sc->sc_ioh; 1060 u_int32_t data; 1061 1062 data = bus_space_read_1(iot, ioh, ESA_CODEC_COMMAND); 1063 1064 return ((data & 0x1) ? 0 : 1); 1065} 1066 1067int 1068esa_attach_codec(void *aux, struct ac97_codec_if *codec_if) 1069{ 1070 struct esa_softc *sc = aux; 1071 1072 sc->codec_if = codec_if; 1073 1074 return (0); 1075} 1076 1077int 1078esa_read_codec(void *aux, u_int8_t reg, u_int16_t *result) 1079{ 1080 struct esa_softc *sc = aux; 1081 bus_space_tag_t iot = sc->sc_iot; 1082 bus_space_handle_t ioh = sc->sc_ioh; 1083 1084 if (esa_wait(sc)) 1085 printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname); 1086 bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, (reg & 0x7f) | 0x80); 1087 delay(50); 1088 if (esa_wait(sc)) 1089 printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname); 1090 *result = bus_space_read_2(iot, ioh, ESA_CODEC_DATA); 1091 1092 return (0); 1093} 1094 1095int 1096esa_write_codec(void *aux, u_int8_t reg, u_int16_t data) 1097{ 1098 struct esa_softc *sc = aux; 1099 bus_space_tag_t iot = sc->sc_iot; 1100 bus_space_handle_t ioh = sc->sc_ioh; 1101 1102 if (esa_wait(sc)) { 1103 printf("%s: esa_write_codec: timed out\n", sc->sc_dev.dv_xname); 1104 return (-1); 1105 } 1106 bus_space_write_2(iot, ioh, ESA_CODEC_DATA, data); 1107 bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, reg & 0x7f); 1108 delay(50); 1109 1110 return (0); 1111} 1112 1113void 1114esa_reset_codec(void *aux) 1115{ 1116 1117 return; 1118} 1119 1120enum ac97_host_flags 1121esa_flags_codec(void *aux) 1122{ 1123 struct esa_softc *sc = aux; 1124 1125 return (sc->codec_flags); 1126} 1127 1128int 1129esa_wait(struct esa_softc *sc) 1130{ 1131 int i, val; 1132 bus_space_tag_t iot = sc->sc_iot; 1133 bus_space_handle_t ioh = sc->sc_ioh; 1134 1135 for (i = 0; i < 20; i++) { 1136 val = bus_space_read_1(iot, ioh, ESA_CODEC_STATUS); 1137 if ((val & 1) == 0) 1138 return (0); 1139 delay(2); 1140 } 1141 1142 return (-1); 1143} 1144 1145int 1146esa_init(struct esa_softc *sc) 1147{ 1148 bus_space_tag_t iot = sc->sc_iot; 1149 bus_space_handle_t ioh = sc->sc_ioh; 1150 pcitag_t tag = sc->sc_tag; 1151 pci_chipset_tag_t pc = sc->sc_pct; 1152 u_int32_t data, i, size; 1153 u_int8_t reset_state; 1154 int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) + 1155 (ESA_MINISRC_IN_BUFFER_SIZE & ~1) + 1156 (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255) 1157 &~ 255; 1158 1159 /* Disable legacy emulation */ 1160 data = pci_conf_read(pc, tag, PCI_LEGACY_AUDIO_CTRL); 1161 data |= DISABLE_LEGACY; 1162 pci_conf_write(pc, tag, PCI_LEGACY_AUDIO_CTRL, data); 1163 1164 esa_config(sc); 1165 1166 reset_state = esa_assp_halt(sc); 1167 1168 esa_init_codec(sc); 1169 esa_codec_reset(sc); 1170 1171 /* Zero kernel and mixer data */ 1172 size = ESA_REV_B_DATA_MEMORY_UNIT_LENGTH * ESA_NUM_UNITS_KERNEL_DATA; 1173 for (i = 0; i < size / 2; i++) { 1174 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 1175 ESA_KDATA_BASE_ADDR + i, 0); 1176 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 1177 ESA_KDATA_BASE_ADDR2 + i, 0); 1178 } 1179 1180 /* Init DMA pointer */ 1181 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_CURRENT_DMA, 1182 ESA_KDATA_DMA_XFER0); 1183 1184 /* Write kernel code into memory */ 1185 size = sizeof(esa_assp_kernel_image); 1186 for (i = 0; i < size / 2; i++) 1187 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 1188 ESA_REV_B_CODE_MEMORY_BEGIN + i, esa_assp_kernel_image[i]); 1189 1190 size = sizeof(esa_assp_minisrc_image); 1191 for (i = 0; i < size / 2; i++) 1192 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 0x400 + i, 1193 esa_assp_minisrc_image[i]); 1194 1195 /* Write the coefficients for the low pass filter */ 1196 size = sizeof(esa_minisrc_lpf_image); 1197 for (i = 0; i < size / 2; i++) 1198 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 1199 0x400 + ESA_MINISRC_COEF_LOC + i, esa_minisrc_lpf_image[i]); 1200 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 1201 0x400 + ESA_MINISRC_COEF_LOC + size, 0x8000); 1202 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_TASK0, 0x400); 1203 /* Init the mixer number */ 1204 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 1205 ESA_KDATA_MIXER_TASK_NUMBER, 0); 1206 /* Extreme kernel master volume */ 1207 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DAC_LEFT_VOLUME, 1208 ESA_ARB_VOLUME); 1209 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 1210 ESA_KDATA_DAC_RIGHT_VOLUME, ESA_ARB_VOLUME); 1211 1212 if (esa_amp_enable(sc)) 1213 return (-1); 1214 1215 /* Zero entire DAC/ADC area */ 1216 for (i = 0x1100; i < 0x1c00; i++) 1217 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, i, 0); 1218 1219 /* set some sane defaults */ 1220 sc->play.data_offset = ESA_DAC_DATA + data_bytes; 1221 sc->rec.data_offset = ESA_DAC_DATA + data_bytes + (data_bytes / 2); 1222 1223 esa_enable_interrupts(sc); 1224 1225 bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B, 1226 reset_state | ESA_REGB_ENABLE_RESET); 1227 1228 return (0); 1229} 1230 1231void 1232esa_config(struct esa_softc *sc) 1233{ 1234 bus_space_tag_t iot = sc->sc_iot; 1235 bus_space_handle_t ioh = sc->sc_ioh; 1236 pcitag_t tag = sc->sc_tag; 1237 pci_chipset_tag_t pc = sc->sc_pct; 1238 u_int32_t data; 1239 1240 data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG); 1241 data &= ESA_REDUCED_DEBOUNCE; 1242 data |= ESA_PM_CTRL_ENABLE | ESA_CLK_DIV_BY_49 | ESA_USE_PCI_TIMING; 1243 pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data); 1244 1245 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RESET_ASSP); 1246 data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG); 1247 data &= ~ESA_INT_CLK_SELECT; 1248 if (sc->type == ESS_MAESTRO3) { 1249 data &= ~ESA_INT_CLK_MULT_ENABLE; 1250 data |= ESA_INT_CLK_SRC_NOT_PCI; 1251 } 1252 data &= ~(ESA_CLK_MULT_MODE_SELECT | ESA_CLK_MULT_MODE_SELECT_2); 1253 pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data); 1254 1255 if (sc->type == ESS_ALLEGRO1) { 1256 data = pci_conf_read(pc, tag, ESA_PCI_USER_CONFIG); 1257 data |= ESA_IN_CLK_12MHZ_SELECT; 1258 pci_conf_write(pc, tag, ESA_PCI_USER_CONFIG, data); 1259 } 1260 1261 data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_A); 1262 data &= ~(ESA_DSP_CLK_36MHZ_SELECT | ESA_ASSP_CLK_49MHZ_SELECT); 1263 data |= ESA_ASSP_CLK_49MHZ_SELECT; /* XXX: Assumes 49MHz DSP */ 1264 data |= ESA_ASSP_0_WS_ENABLE; 1265 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_A, data); 1266 1267 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RUN_ASSP); 1268 1269 return; 1270} 1271 1272u_int8_t 1273esa_assp_halt(struct esa_softc *sc) 1274{ 1275 bus_space_tag_t iot = sc->sc_iot; 1276 bus_space_handle_t ioh = sc->sc_ioh; 1277 u_int8_t data, reset_state; 1278 1279 data = bus_space_read_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B); 1280 reset_state = data & ~ESA_REGB_STOP_CLOCK; 1281 delay(10000); /* XXX use tsleep */ 1282 bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B, 1283 reset_state & ~ESA_REGB_ENABLE_RESET); 1284 delay(10000); /* XXX use tsleep */ 1285 1286 return (reset_state); 1287} 1288 1289void 1290esa_codec_reset(struct esa_softc *sc) 1291{ 1292 bus_space_tag_t iot = sc->sc_iot; 1293 bus_space_handle_t ioh = sc->sc_ioh; 1294 u_int16_t data, dir; 1295 int retry = 0; 1296 1297 do { 1298 data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION); 1299 dir = data | 0x10; /* assuming pci bus master? */ 1300 1301 /* remote codec config */ 1302 data = bus_space_read_2(iot, ioh, ESA_RING_BUS_CTRL_B); 1303 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_B, 1304 data & ~ESA_SECOND_CODEC_ID_MASK); 1305 data = bus_space_read_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL); 1306 bus_space_write_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL, 1307 data & ~ESA_COMMAND_ADDR_OUT); 1308 data = bus_space_read_2(iot, ioh, ESA_SDO_IN_DEST_CTRL); 1309 bus_space_write_2(iot, ioh, ESA_SDO_IN_DEST_CTRL, 1310 data & ~ESA_STATUS_ADDR_IN); 1311 1312 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A, 1313 ESA_IO_SRAM_ENABLE); 1314 delay(20); 1315 1316 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, 1317 dir & ~ESA_GPO_PRIMARY_AC97); 1318 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, 1319 ~ESA_GPO_PRIMARY_AC97); 1320 bus_space_write_2(iot, ioh, ESA_GPIO_DATA, 0); 1321 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, 1322 dir | ESA_GPO_PRIMARY_AC97); 1323 delay(sc->delay1 * 1000); 1324 bus_space_write_2(iot, ioh, ESA_GPIO_DATA, 1325 ESA_GPO_PRIMARY_AC97); 1326 delay(5); 1327 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A, 1328 ESA_IO_SRAM_ENABLE | ESA_SERIAL_AC_LINK_ENABLE); 1329 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0); 1330 delay(sc->delay2 * 1000); 1331 1332 esa_read_codec(sc, 0x7c, &data); 1333 if ((data == 0) || (data == 0xffff)) { 1334 retry++; 1335 if (retry > 3) { 1336 printf("%s: esa_codec_reset: failed\n", 1337 sc->sc_dev.dv_xname); 1338 break; 1339 } 1340 printf("%s: esa_codec_reset: retrying\n", 1341 sc->sc_dev.dv_xname); 1342 } else 1343 retry = 0; 1344 } while (retry); 1345 1346 return; 1347} 1348 1349int 1350esa_amp_enable(struct esa_softc *sc) 1351{ 1352 bus_space_tag_t iot = sc->sc_iot; 1353 bus_space_handle_t ioh = sc->sc_ioh; 1354 u_int32_t gpo, polarity_port, polarity; 1355 u_int16_t data; 1356 1357 switch (sc->type) { 1358 case ESS_ALLEGRO1: 1359 polarity_port = 0x1800; 1360 break; 1361 case ESS_MAESTRO3: 1362 polarity_port = 0x1100; 1363 break; 1364 default: 1365 printf("%s: esa_amp_enable: Unknown chip type!!!\n", 1366 sc->sc_dev.dv_xname); 1367 return (1); 1368 } 1369 1370 gpo = (polarity_port >> 8) & 0x0f; 1371 polarity = polarity_port >> 12; 1372 polarity = !polarity; /* Enable */ 1373 polarity = polarity << gpo; 1374 gpo = 1 << gpo; 1375 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~gpo); 1376 data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION); 1377 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, data | gpo); 1378 data = ESA_GPO_SECONDARY_AC97 | ESA_GPO_PRIMARY_AC97 | polarity; 1379 bus_space_write_2(iot, ioh, ESA_GPIO_DATA, data); 1380 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0); 1381 1382 return (0); 1383} 1384 1385void 1386esa_enable_interrupts(struct esa_softc *sc) 1387{ 1388 bus_space_tag_t iot = sc->sc_iot; 1389 bus_space_handle_t ioh = sc->sc_ioh; 1390 u_int8_t data; 1391 1392 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 1393 ESA_ASSP_INT_ENABLE | ESA_HV_INT_ENABLE); 1394 data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_C); 1395 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_C, 1396 data | ESA_ASSP_HOST_INT_ENABLE); 1397} 1398 1399int 1400esa_power(struct esa_softc *sc, int state) 1401{ 1402 pcitag_t tag = sc->sc_tag; 1403 pci_chipset_tag_t pc = sc->sc_pct; 1404 pcireg_t data; 1405 int pmcapreg; 1406 1407 if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &pmcapreg, 0)) { 1408 data = pci_conf_read(pc, tag, pmcapreg + 4); 1409 if ((data && PCI_PMCSR_STATE_MASK) != state) 1410 pci_conf_write(pc, tag, pmcapreg + 4, state); 1411 } 1412 1413 return (0); 1414} 1415 1416void 1417esa_powerhook(int why, void *hdl) 1418{ 1419 struct esa_softc *sc = (struct esa_softc *)hdl; 1420 1421 switch (why) { 1422 case PWR_SUSPEND: 1423 case PWR_STANDBY: 1424 esa_suspend(sc); 1425 break; 1426 case PWR_RESUME: 1427 esa_resume(sc); 1428 (sc->codec_if->vtbl->restore_ports)(sc->codec_if); 1429 break; 1430 } 1431} 1432 1433int 1434esa_suspend(struct esa_softc *sc) 1435{ 1436 bus_space_tag_t iot = sc->sc_iot; 1437 bus_space_handle_t ioh = sc->sc_ioh; 1438 int x, i, index; 1439 1440 index = 0; 1441 1442 x = splaudio(); 1443 esa_halt_output(sc); 1444 delay(10000); 1445 splx(x); 1446 1447 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 0); 1448 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_C, 0); 1449 1450 esa_assp_halt(sc); 1451 1452 /* Save ASSP state */ 1453 for (i = ESA_REV_B_CODE_MEMORY_BEGIN; i <= ESA_REV_B_CODE_MEMORY_END; 1454 i++) 1455 sc->savemem[index++] = esa_read_assp(sc, 1456 ESA_MEMTYPE_INTERNAL_CODE, i); 1457 for (i = ESA_REV_B_DATA_MEMORY_BEGIN; i <= ESA_REV_B_DATA_MEMORY_END; 1458 i++) 1459 sc->savemem[index++] = esa_read_assp(sc, 1460 ESA_MEMTYPE_INTERNAL_DATA, i); 1461 1462 esa_power(sc, PCI_PMCSR_STATE_D3); 1463 1464 return (0); 1465} 1466 1467int 1468esa_resume(struct esa_softc *sc) { 1469 bus_space_tag_t iot = sc->sc_iot; 1470 bus_space_handle_t ioh = sc->sc_ioh; 1471 int i, index; 1472 u_int8_t reset_state; 1473 1474 index = 0; 1475 1476 esa_power(sc, PCI_PMCSR_STATE_D0); 1477 delay(10000); 1478 1479 esa_config(sc); 1480 1481 reset_state = esa_assp_halt(sc); 1482 1483 /* restore ASSP */ 1484 for (i = ESA_REV_B_CODE_MEMORY_BEGIN; i <= ESA_REV_B_CODE_MEMORY_END; 1485 i++) 1486 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, i, 1487 sc->savemem[index++]); 1488 for (i = ESA_REV_B_DATA_MEMORY_BEGIN; i <= ESA_REV_B_DATA_MEMORY_END; 1489 i++) 1490 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, i, 1491 sc->savemem[index++]); 1492 1493 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_ACTIVE, 0); 1494 bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B, 1495 reset_state | ESA_REGB_ENABLE_RESET); 1496 1497 esa_enable_interrupts(sc); 1498 esa_amp_enable(sc); 1499 1500 return (0); 1501} 1502 1503u_int32_t 1504esa_get_pointer(struct esa_softc *sc, struct esa_channel *ch) 1505{ 1506 u_int16_t hi = 0, lo = 0; 1507 u_int32_t addr; 1508 int data_offset = ch->data_offset; 1509 1510 hi = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, data_offset + 1511 ESA_CDATA_HOST_SRC_CURRENTH); 1512 lo = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, data_offset + 1513 ESA_CDATA_HOST_SRC_CURRENTL); 1514 1515 addr = lo | ((u_int32_t)hi << 16); 1516 return (addr - ch->start); 1517} 1518 1519paddr_t 1520esa_mappage(void *addr, void *mem, off_t off, int prot) 1521{ 1522 struct esa_softc *sc = addr; 1523 struct esa_dma *p; 1524 1525 if (off < 0) 1526 return (-1); 1527 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 1528 ; 1529 if (!p) 1530 return (-1); 1531 return (bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nsegs, 1532 off, prot, BUS_DMA_WAITOK)); 1533} 1534