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