esa.c revision 1.2
1/* $NetBSD: esa.c,v 1.2 2002/01/06 16:58:23 augustss 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 60#include <dev/pci/esareg.h> 61#include <dev/pci/esadsp.h> 62#include <dev/pci/esavar.h> 63 64#define PCI_CBIO 0x10 65 66#define ESA_DAC_DATA 0x1100 67 68enum { 69 ESS_ALLEGRO1, 70 ESS_MAESTRO3 71}; 72 73static struct esa_card_type { 74 u_int16_t pci_vendor_id; 75 u_int16_t pci_product_id; 76 int type; 77 int delay1, delay2; 78} esa_card_types[] = { 79 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_ALLEGRO1, 80 ESS_ALLEGRO1, 50, 800 }, 81 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3, 82 ESS_MAESTRO3, 20, 500 }, 83 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3_2, 84 ESS_MAESTRO3, 20, 500 }, 85 { 0, 0, 0, 0, 0 } 86}; 87 88struct audio_device esa_device = { 89 "ESS Allegro", 90 "", 91 "esa" 92}; 93 94int esa_match(struct device *, struct cfdata *, void *); 95void esa_attach(struct device *, struct device *, void *); 96int esa_detach(struct device *, int); 97 98/* audio(9) functions */ 99int esa_open(void *, int); 100void esa_close(void *); 101int esa_query_encoding(void *, struct audio_encoding *); 102int esa_set_params(void *, int, int, struct audio_params *, 103 struct audio_params *); 104int esa_round_blocksize(void *, int); 105int esa_init_output(void *, void *, int); 106int esa_halt_output(void *); 107int esa_halt_input(void *); 108int esa_set_port(void *, mixer_ctrl_t *); 109int esa_get_port(void *, mixer_ctrl_t *); 110int esa_query_devinfo(void *, mixer_devinfo_t *); 111void * esa_malloc(void *, int, size_t, int, int); 112void esa_free(void *, void *, int); 113int esa_getdev(void *, struct audio_device *); 114size_t esa_round_buffersize(void *, int, size_t); 115int esa_get_props(void *); 116int esa_trigger_output(void *, void *, void *, int, 117 void (*)(void *), void *, 118 struct audio_params *); 119int esa_trigger_input(void *, void *, void *, int, 120 void (*)(void *), void *, 121 struct audio_params *); 122 123int esa_intr(void *); 124int esa_allocmem(struct esa_softc *, size_t, size_t, 125 struct esa_dma *); 126int esa_freemem(struct esa_softc *, struct esa_dma *); 127paddr_t esa_mappage(void *addr, void *mem, off_t off, int prot); 128 129/* Supporting subroutines */ 130u_int16_t esa_read_assp(struct esa_softc *, u_int16_t, u_int16_t); 131void esa_write_assp(struct esa_softc *, u_int16_t, u_int16_t, 132 u_int16_t); 133int esa_init_codec(struct esa_softc *); 134int esa_attach_codec(void *, struct ac97_codec_if *); 135int esa_read_codec(void *, u_int8_t, u_int16_t *); 136int esa_write_codec(void *, u_int8_t, u_int16_t); 137void esa_reset_codec(void *); 138enum ac97_host_flags esa_flags_codec(void *); 139int esa_wait(struct esa_softc *); 140int esa_init(struct esa_softc *); 141void esa_config(struct esa_softc *); 142u_int8_t esa_assp_halt(struct esa_softc *); 143void esa_codec_reset(struct esa_softc *); 144int esa_amp_enable(struct esa_softc *); 145void esa_enable_interrupts(struct esa_softc *); 146int esa_power(struct esa_softc *, int); 147u_int32_t esa_get_pointer(struct esa_softc *); 148 149struct device * audio_attach_mi_lkm(struct audio_hw_if *, void *, 150 struct device *); 151 152static audio_encoding_t esa_encoding[] = { 153 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 }, 154 { 1, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 155 AUDIO_ENCODINGFLAG_EMULATED }, 156 { 2, AudioEalaw, AUDIO_ENCODING_ALAW, 8, AUDIO_ENCODINGFLAG_EMULATED }, 157 { 3, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 158 AUDIO_ENCODINGFLAG_EMULATED }, /* XXX: Are you sure? */ 159 { 4, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 }, 160 { 5, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 161 AUDIO_ENCODINGFLAG_EMULATED }, 162 { 6, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 163 AUDIO_ENCODINGFLAG_EMULATED }, 164 { 7, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 165 AUDIO_ENCODINGFLAG_EMULATED } 166}; 167 168#define ESA_NENCODINGS 8 169 170struct audio_hw_if esa_hw_if = { 171 esa_open, 172 esa_close, 173 NULL, /* drain */ 174 esa_query_encoding, 175 esa_set_params, 176 esa_round_blocksize, 177 NULL, /* commit_settings */ 178 esa_init_output, 179 NULL, /* esa_init_input */ 180 NULL, /* start_output */ 181 NULL, /* start_input */ 182 esa_halt_output, 183 esa_halt_input, 184 NULL, /* speaker_ctl */ 185 esa_getdev, 186 NULL, /* getfd */ 187 esa_set_port, 188 esa_get_port, 189 esa_query_devinfo, 190 esa_malloc, 191 esa_free, 192 esa_round_buffersize, 193 esa_mappage, 194 esa_get_props, 195 esa_trigger_output, 196 esa_trigger_input 197}; 198 199struct cfattach esa_ca = { 200 sizeof(struct esa_softc), esa_match, esa_attach, 201 esa_detach, /*esa_activate*/ NULL 202}; 203 204/* 205 * audio(9) functions 206 */ 207 208int 209esa_open(void *hdl, int flags) 210{ 211 212 return (0); 213} 214 215void 216esa_close(void *hdl) 217{ 218 219 return; 220} 221 222int 223esa_query_encoding(void *hdl, struct audio_encoding *ae) 224{ 225 226 if (ae->index < 0 || ae->index >= ESA_NENCODINGS) 227 return (EINVAL); 228 *ae = esa_encoding[ae->index]; 229 230 return (0); 231} 232 233int 234esa_set_params(void *hdl, int setmode, int usemode, struct audio_params *play, 235 struct audio_params *rec) 236{ 237 struct esa_softc *sc = hdl; 238 u_int32_t data; 239 u_int32_t freq; 240 241 if ((setmode & AUMODE_PLAY) == 0) { 242 printf("%s: esa_set_params: only AUMODE_PLAY is supported\n", 243 sc->sc_dev.dv_xname); 244 return (EINVAL); 245 } 246 247 if (play->sample_rate < ESA_MINRATE || 248 play->sample_rate > ESA_MAXRATE || 249 (play->precision != 8 && play->precision != 16) || 250 (play->channels < 1 && play->channels > 2)) /* XXX: Are you sure? */ 251 return (EINVAL); 252 253 play->factor = 1; 254 play->sw_code = 0; 255 256 switch(play->encoding) { 257 case AUDIO_ENCODING_SLINEAR_BE: 258 if (play->precision == 16) 259 play->sw_code = swap_bytes; 260 else 261 play->sw_code = change_sign8; 262 break; 263 case AUDIO_ENCODING_SLINEAR_LE: 264 if (play->precision != 16) 265 play->sw_code = change_sign8; 266 break; 267 case AUDIO_ENCODING_ULINEAR_BE: 268 if (play->precision == 16) 269 play->sw_code = swap_bytes_change_sign16_le; 270 break; 271 case AUDIO_ENCODING_ULINEAR_LE: 272 if (play->precision == 16) 273 play->sw_code = change_sign16_le; 274 break; 275 case AUDIO_ENCODING_ULAW: 276 play->factor = 2; 277 play->sw_code = mulaw_to_slinear16_le; 278 break; 279 case AUDIO_ENCODING_ALAW: 280 play->factor = 2; 281 play->sw_code = alaw_to_slinear16_le; 282 break; 283 default: 284 return (EINVAL); 285 } 286 287 if (play->channels == 1) 288 data = 1; 289 else 290 data = 0; 291 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 292 ESA_DAC_DATA + ESA_SRC3_MODE_OFFSET, 293 data); 294 295 if (play->precision * play->factor == 8) 296 data = 1; 297 else 298 data = 0; 299 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 300 ESA_DAC_DATA + ESA_SRC3_WORD_LENGTH_OFFSET, data); 301 302 if ((freq = ((play->sample_rate << 15) + 24000) / 48000) != 0) { 303 freq--; 304 } 305 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 306 ESA_DAC_DATA + ESA_CDATA_FREQUENCY, freq); 307 308 return (0); 309} 310 311int 312esa_round_blocksize(void *hdl, int bs) 313{ 314 struct esa_softc *sc = hdl; 315 316 bs = 4096; /* XXX why? */ 317 sc->play.blksize = bs; 318 319 return (sc->play.blksize); 320} 321 322int 323esa_init_output(void *hdl, void *buffer, int size) 324{ 325 326 return (0); 327} 328 329int 330esa_halt_output(void *hdl) 331{ 332 struct esa_softc *sc = hdl; 333 334 if (sc->play.active == 0) 335 return (0); 336 337 sc->play.active = 0; 338 339 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 340 ESA_KDATA_INSTANCE0_MINISRC, 0); 341 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0, 0); 342 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_MIXER_XFER0, 0); 343 344 return (0); 345} 346 347int 348esa_halt_input(void *hdl) 349{ 350 351 return (EOPNOTSUPP); 352} 353 354void * 355esa_malloc(void *hdl, int direction, size_t size, int type, int flags) 356{ 357 struct esa_softc *sc = hdl; 358 struct esa_dma *p; 359 int error; 360 361 p = malloc(sizeof(*p), type, flags); 362 if (!p) 363 return (0); 364 error = esa_allocmem(sc, size, 16, p); 365 if (error) { 366 free(p, type); 367 printf("%s: esa_malloc: not enough memory\n", 368 sc->sc_dev.dv_xname); 369 return (0); 370 } 371 p->next = sc->sc_dmas; 372 sc->sc_dmas = p; 373 374 return (KERNADDR(p)); 375} 376 377void 378esa_free(void *hdl, void *addr, int type) 379{ 380 struct esa_softc *sc = hdl; 381 struct esa_dma *p; 382 struct esa_dma **pp; 383 384 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) 385 if (KERNADDR(p) == addr) { 386 esa_freemem(sc, p); 387 *pp = p->next; 388 free(p, type); 389 return; 390 } 391} 392 393int 394esa_getdev(void *hdl, struct audio_device *ret) 395{ 396 397 *ret = esa_device; 398 399 return (0); 400} 401 402int 403esa_set_port(void *hdl, mixer_ctrl_t *mc) 404{ 405 struct esa_softc *sc = hdl; 406 407 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, mc)); 408} 409 410int 411esa_get_port(void *hdl, mixer_ctrl_t *mc) 412{ 413 struct esa_softc *sc = hdl; 414 415 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, mc)); 416} 417 418int 419esa_query_devinfo(void *hdl, mixer_devinfo_t *di) 420{ 421 struct esa_softc *sc = hdl; 422 423 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, di)); 424} 425 426size_t 427esa_round_buffersize(void *hdl, int direction, size_t bufsize) 428{ 429 struct esa_softc *sc = hdl; 430 431 bufsize = 65536; /* XXX why? */ 432 sc->play.bufsize = bufsize; 433 434 return (sc->play.bufsize); 435} 436 437int 438esa_get_props(void *hdl) 439{ 440 441 return (AUDIO_PROP_MMAP); 442} 443 444int 445esa_trigger_output(void *hdl, void *start, void *end, int blksize, 446 void (*intr)(void *), void *intrarg, 447 struct audio_params *param) 448{ 449 struct esa_softc *sc = hdl; 450 struct esa_dma *p; 451 bus_space_tag_t iot = sc->sc_iot; 452 bus_space_handle_t ioh = sc->sc_ioh; 453 u_int32_t data; 454 u_int32_t bufaddr; 455 u_int32_t i; 456 size_t size; 457 int dsp_in_size = ESA_MINISRC_IN_BUFFER_SIZE - (0x20 * 2); 458 int dsp_out_size = ESA_MINISRC_OUT_BUFFER_SIZE - (0x20 * 2); 459 int dsp_in_buf = ESA_DAC_DATA + (ESA_MINISRC_TMP_BUFFER_SIZE / 2); 460 int dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1; 461 462 if (sc->play.active) 463 return (EINVAL); 464 465 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 466 ; 467 if (!p) { 468 printf("%s: esa_trigger_output: bad addr %p\n", 469 sc->sc_dev.dv_xname, start); 470 return (EINVAL); 471 } 472 473 sc->play.active = 1; 474 sc->intr = intr; 475 sc->arg = intrarg; 476 sc->play.pos = 0; 477 sc->play.count = 0; 478 sc->play.buf = start; 479 size = (size_t)(((caddr_t)end - (caddr_t)start)); 480 bufaddr = DMAADDR(p); 481 sc->play.start = bufaddr; 482 483#define LO(x) ((x) & 0x0000ffff) 484#define HI(x) ((x) >> 16) 485 486 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 487 ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr)); 488 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 489 ESA_CDATA_HOST_SRC_ADDRH, HI(bufaddr)); 490 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 491 ESA_CDATA_HOST_SRC_END_PLUS_1L, LO(bufaddr + size)); 492 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 493 ESA_CDATA_HOST_SRC_END_PLUS_1H, HI(bufaddr + size)); 494 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 495 ESA_CDATA_HOST_SRC_CURRENTL, LO(bufaddr)); 496 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 497 ESA_CDATA_HOST_SRC_CURRENTH, HI(bufaddr)); 498 499 /* DSP buffers */ 500 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 501 ESA_CDATA_IN_BUF_BEGIN, dsp_in_buf); 502 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 503 ESA_CDATA_IN_BUF_END_PLUS_1, dsp_in_buf + (dsp_in_size / 2)); 504 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 505 ESA_CDATA_IN_BUF_HEAD, dsp_in_buf); 506 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 507 ESA_CDATA_IN_BUF_TAIL, dsp_in_buf); 508 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 509 ESA_CDATA_OUT_BUF_BEGIN, dsp_out_buf); 510 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 511 ESA_CDATA_OUT_BUF_END_PLUS_1, dsp_out_buf + (dsp_out_size / 2)); 512 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 513 ESA_CDATA_OUT_BUF_HEAD, dsp_out_buf); 514 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 515 ESA_CDATA_OUT_BUF_TAIL, dsp_out_buf); 516 517 /* Some per-client initializers */ 518 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 519 ESA_SRC3_DIRECTION_OFFSET + 12, ESA_DAC_DATA + 40 + 8); 520 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 521 ESA_SRC3_DIRECTION_OFFSET + 19, 0x400 + ESA_MINISRC_COEF_LOC); 522 /* Enable or disable low-pass filter? (0xff if rate > 45000) */ 523 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 524 ESA_SRC3_DIRECTION_OFFSET + 22, 0); 525 /* Tell it which way DMA is going */ 526 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 527 ESA_CDATA_DMA_CONTROL, 528 ESA_DMACONTROL_AUTOREPEAT + ESA_DMAC_PAGE3_SELECTOR + 529 ESA_DMAC_BLOCKF_SELECTOR); 530 531 /* Set an armload of static initializers */ 532 for (i = 0; i < (sizeof(esa_playvals) / sizeof(esa_playvals[0])); i++) 533 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 534 esa_playvals[i].addr, esa_playvals[i].val); 535 536 /* Put us in the packed task lists */ 537 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 538 ESA_KDATA_INSTANCE0_MINISRC, 539 ESA_DAC_DATA >> ESA_DP_SHIFT_COUNT); 540 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_XFER0, 541 ESA_DAC_DATA >> ESA_DP_SHIFT_COUNT); 542 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_MIXER_XFER0, 543 ESA_DAC_DATA >> ESA_DP_SHIFT_COUNT); 544#undef LO 545#undef HI 546 547 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 548 ESA_KDATA_TIMER_COUNT_RELOAD, 240); 549 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 550 ESA_KDATA_TIMER_COUNT_CURRENT, 240); 551 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL); 552 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 553 data | ESA_CLKRUN_GEN_ENABLE); 554 555 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 556 ESA_CDATA_INSTANCE_READY, 1); 557 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 558 ESA_KDATA_MIXER_TASK_NUMBER, 1); 559 560 return (0); 561} 562 563int 564esa_trigger_input(void *hdl, void *start, void *end, int blksize, 565 void (*intr)(void *), void *intrarg, 566 struct audio_params *param) 567{ 568 569 return (EOPNOTSUPP); 570} 571 572/* Interrupt handler */ 573 574int 575esa_intr(void *hdl) 576{ 577 struct esa_softc *sc = hdl; 578 bus_space_tag_t iot = sc->sc_iot; 579 bus_space_handle_t ioh = sc->sc_ioh; 580 u_int32_t status, ctl; 581 u_int32_t pos; 582 u_int32_t diff; 583 u_int32_t blksize = sc->play.blksize; 584 u_int32_t bufsize = sc->play.bufsize; 585 586 status = bus_space_read_1(iot, ioh, ESA_HOST_INT_STATUS); 587 if (!status) 588 return (0); 589 590 /* ack the interrupt */ 591 bus_space_write_1(iot, ioh, ESA_HOST_INT_STATUS, 0xff); 592 593 if (status & ESA_HV_INT_PENDING) { 594 u_int8_t event; 595 596 printf("%s: hardware volume interrupt\n", sc->sc_dev.dv_xname); 597 event = bus_space_read_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER); 598 switch(event) { 599 case 0x99: 600 case 0xaa: 601 case 0x66: 602 case 0x88: 603 printf("%s: esa_intr: FIXME\n", sc->sc_dev.dv_xname); 604 break; 605 default: 606 printf("%s: unknown hwvol event 0x%02x\n", 607 sc->sc_dev.dv_xname, event); 608 break; 609 } 610 bus_space_write_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER, 0x88); 611 } 612 613 if (status & ESA_ASSP_INT_PENDING) { 614 ctl = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_B); 615 if (!(ctl & ESA_STOP_ASSP_CLOCK)) { 616 ctl = bus_space_read_1(iot, ioh, 617 ESA_ASSP_HOST_INT_STATUS); 618 if (ctl & ESA_DSP2HOST_REQ_TIMER) { 619 bus_space_write_1(iot, ioh, 620 ESA_ASSP_HOST_INT_STATUS, 621 ESA_DSP2HOST_REQ_TIMER); 622 if (sc->play.active) { 623 pos = esa_get_pointer(sc) % bufsize; 624 diff = (bufsize + pos - sc->play.pos) 625 % bufsize; 626 sc->play.pos = pos; 627 sc->play.count += diff; 628 while(sc->play.count >= blksize) { 629 sc->play.count -= blksize; 630 (*sc->intr)(sc->arg); 631 } 632 } 633 } 634 } 635 } 636 637 return (1); 638} 639 640int 641esa_allocmem(struct esa_softc *sc, size_t size, size_t align, 642 struct esa_dma *p) 643{ 644 int error; 645 646 p->size = size; 647 error = bus_dmamem_alloc(sc->sc_dmat, p->size, align, 0, 648 p->segs, sizeof(p->segs) / sizeof(p->segs[0]), 649 &p->nsegs, BUS_DMA_NOWAIT); 650 if (error) 651 return (error); 652 653 error = bus_dmamem_map(sc->sc_dmat, p->segs, p->nsegs, p->size, 654 &p->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 655 if (error) 656 goto free; 657 658 error = bus_dmamap_create(sc->sc_dmat, p->size, 1, p->size, 0, 659 BUS_DMA_NOWAIT, &p->map); 660 if (error) 661 goto unmap; 662 663 error = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, p->size, NULL, 664 BUS_DMA_NOWAIT); 665 if (error) 666 goto destroy; 667 668 return (0); 669 670destroy: 671 bus_dmamap_destroy(sc->sc_dmat, p->map); 672unmap: 673 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 674free: 675 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 676 677 return (error); 678} 679 680int 681esa_freemem(struct esa_softc *sc, struct esa_dma *p) 682{ 683 684 bus_dmamap_unload(sc->sc_dmat, p->map); 685 bus_dmamap_destroy(sc->sc_dmat, p->map); 686 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 687 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 688 689 return (0); 690} 691 692/* 693 * Supporting Subroutines 694 */ 695 696int 697esa_match(struct device *dev, struct cfdata *match, void *aux) 698{ 699 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 700 701 switch(PCI_VENDOR(pa->pa_id)) { 702 case PCI_VENDOR_ESSTECH: 703 switch(PCI_PRODUCT(pa->pa_id)) { 704 case PCI_PRODUCT_ESSTECH_ALLEGRO1: 705 case PCI_PRODUCT_ESSTECH_MAESTRO3: 706 case PCI_PRODUCT_ESSTECH_MAESTRO3_2: 707 return (1); 708 } 709 } 710 711 return (0); 712} 713 714void 715esa_attach(struct device *parent, struct device *self, void *aux) 716{ 717 struct esa_softc *sc = (struct esa_softc *)self; 718 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 719 pcitag_t tag = pa->pa_tag; 720 pci_chipset_tag_t pc = pa->pa_pc; 721 pci_intr_handle_t ih; 722 struct esa_card_type *card; 723 const char *intrstr; 724 u_int32_t data; 725 char devinfo[256]; 726 int revision; 727 728 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); 729 revision = PCI_REVISION(pa->pa_class); 730 printf(": %s (rev. 0x%02x)\n", devinfo, revision); 731 732 for (card = esa_card_types; card->pci_vendor_id; card++) 733 if (PCI_VENDOR(pa->pa_id) == card->pci_vendor_id && 734 PCI_PRODUCT(pa->pa_id) == card->pci_product_id) { 735 sc->type = card->type; 736 sc->delay1 = card->delay1; 737 sc->delay2 = card->delay2; 738 break; 739 } 740 741 data = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 742 data |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE 743 | PCI_COMMAND_MASTER_ENABLE); 744 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, data); 745 746 /* Map I/O register */ 747 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, 748 &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios)) { 749 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname); 750 return; 751 } 752 753 /* Initialize softc */ 754 sc->sc_tag = tag; 755 sc->sc_pct = pc; 756 sc->sc_dmat = pa->pa_dmat; 757 758 /* Map and establish an interrupt */ 759 if (pci_intr_map(pa, &ih)) { 760 printf("%s: can't map interrupt\n", sc->sc_dev.dv_xname); 761 return; 762 } 763 intrstr = pci_intr_string(pc, ih); 764 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, esa_intr, self); 765 if (sc->sc_ih == NULL) { 766 printf("%s: can't establish interrupt", sc->sc_dev.dv_xname); 767 if (intrstr != NULL) 768 printf(" at %s", intrstr); 769 printf("\n"); 770 return; 771 } 772 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); 773 774 /* Power up chip */ 775 esa_power(sc, 0); 776 777 /* Init chip */ 778 if (esa_init(sc) == -1) { 779 printf("%s: esa_attach: unable to initialize the card\n", 780 sc->sc_dev.dv_xname); 781 return; 782 } 783 784 /* Attach AC97 host interface */ 785 sc->host_if.arg = self; 786 sc->host_if.attach = esa_attach_codec; 787 sc->host_if.read = esa_read_codec; 788 sc->host_if.write = esa_write_codec; 789 sc->host_if.reset = esa_reset_codec; 790 sc->host_if.flags = esa_flags_codec; 791 792 if (ac97_attach(&sc->host_if) != 0) 793 return; 794 795 sc->sc_audiodev = audio_attach_mi(&esa_hw_if, self, &sc->sc_dev); 796 797 return; 798} 799 800int 801esa_detach(struct device *self, int flags) 802{ 803 struct esa_softc *sc = (struct esa_softc *)self; 804 int rv = 0; 805 806 if (sc->sc_audiodev != NULL) 807 rv = config_detach(sc->sc_audiodev, flags); 808 if (rv) 809 return (rv); 810 811 if (sc->sc_ih != NULL) 812 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 813 if (sc->sc_ios) 814 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 815 816 return (0); 817} 818 819u_int16_t 820esa_read_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index) 821{ 822 u_int16_t data; 823 bus_space_tag_t iot = sc->sc_iot; 824 bus_space_handle_t ioh = sc->sc_ioh; 825 826 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE, 827 region & ESA_MEMTYPE_MASK); 828 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index); 829 data = bus_space_read_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA); 830 831 return (data); 832} 833 834void 835esa_write_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index, 836 u_int16_t data) 837{ 838 bus_space_tag_t iot = sc->sc_iot; 839 bus_space_handle_t ioh = sc->sc_ioh; 840 841 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE, 842 region & ESA_MEMTYPE_MASK); 843 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index); 844 bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA, data); 845 846 return; 847} 848 849int 850esa_init_codec(struct esa_softc *sc) 851{ 852 bus_space_tag_t iot = sc->sc_iot; 853 bus_space_handle_t ioh = sc->sc_ioh; 854 u_int32_t data; 855 856 data = bus_space_read_1(iot, ioh, ESA_CODEC_COMMAND); 857 858 return ((data & 0x1) ? 0 : 1); 859} 860 861int 862esa_attach_codec(void *aux, struct ac97_codec_if *codec_if) 863{ 864 struct esa_softc *sc = aux; 865 866 sc->codec_if = codec_if; 867 868 return (0); 869} 870 871int 872esa_read_codec(void *aux, u_int8_t reg, u_int16_t *result) 873{ 874 struct esa_softc *sc = aux; 875 bus_space_tag_t iot = sc->sc_iot; 876 bus_space_handle_t ioh = sc->sc_ioh; 877 878 if (esa_wait(sc)) 879 printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname); 880 bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, (reg & 0x7f) | 0x80); 881 delay(50); 882 if (esa_wait(sc)) 883 printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname); 884 *result = bus_space_read_2(iot, ioh, ESA_CODEC_DATA); 885 886 return (0); 887} 888 889int 890esa_write_codec(void *aux, u_int8_t reg, u_int16_t data) 891{ 892 struct esa_softc *sc = aux; 893 bus_space_tag_t iot = sc->sc_iot; 894 bus_space_handle_t ioh = sc->sc_ioh; 895 896 if (esa_wait(sc)) { 897 printf("%s: esa_write_codec: timed out\n", sc->sc_dev.dv_xname); 898 return (-1); 899 } 900 bus_space_write_2(iot, ioh, ESA_CODEC_DATA, data); 901 bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, reg & 0x7f); 902 delay(50); 903 904 return (0); 905} 906 907void 908esa_reset_codec(void *aux) 909{ 910 911 return; 912} 913 914enum ac97_host_flags 915esa_flags_codec(void *aux) 916{ 917 struct esa_softc *sc = aux; 918 919 return (sc->codec_flags); 920} 921 922int 923esa_wait(struct esa_softc *sc) 924{ 925 int i, val; 926 bus_space_tag_t iot = sc->sc_iot; 927 bus_space_handle_t ioh = sc->sc_ioh; 928 929 for (i = 0; i < 20; i++) { 930 val = bus_space_read_1(iot, ioh, ESA_CODEC_STATUS); 931 if ((val & 1) == 0) 932 return (0); 933 delay(2); 934 } 935 936 return (-1); 937} 938 939int 940esa_init(struct esa_softc *sc) 941{ 942 bus_space_tag_t iot = sc->sc_iot; 943 bus_space_handle_t ioh = sc->sc_ioh; 944 pcitag_t tag = sc->sc_tag; 945 pci_chipset_tag_t pc = sc->sc_pct; 946 u_int32_t data, i, size; 947 u_int8_t reset_state; 948 949 /* Disable legacy emulation */ 950 data = pci_conf_read(pc, tag, PCI_LEGACY_AUDIO_CTRL); 951 data |= DISABLE_LEGACY; 952 pci_conf_write(pc, tag, PCI_LEGACY_AUDIO_CTRL, data); 953 954 esa_config(sc); 955 956 reset_state = esa_assp_halt(sc); 957 958 esa_init_codec(sc); 959 esa_codec_reset(sc); 960 961 /* Zero kernel and mixer data */ 962 size = ESA_REV_B_DATA_MEMORY_UNIT_LENGTH * ESA_NUM_UNITS_KERNEL_DATA; 963 for (i = 0; i < size / 2; i++) { 964 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 965 ESA_KDATA_BASE_ADDR + i, 0); 966 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 967 ESA_KDATA_BASE_ADDR2 + i, 0); 968 } 969 970 /* Init DMA pointer */ 971 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_CURRENT_DMA, 972 ESA_KDATA_DMA_XFER0); 973 974 /* Write kernel code into memory */ 975 size = sizeof(esa_assp_kernel_image); 976 for (i = 0; i < size / 2; i++) 977 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 978 ESA_REV_B_CODE_MEMORY_BEGIN + i, esa_assp_kernel_image[i]); 979 980 size = sizeof(esa_assp_minisrc_image); 981 for (i = 0; i < size / 2; i++) 982 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 0x400 + i, 983 esa_assp_minisrc_image[i]); 984 985 /* Write the coefficients for the low pass filter */ 986 size = sizeof(esa_minisrc_lpf_image); 987 for (i = 0; i < size / 2; i++) 988 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 989 0x400 + ESA_MINISRC_COEF_LOC + i, esa_minisrc_lpf_image[i]); 990 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 991 0x400 + ESA_MINISRC_COEF_LOC + size, 0x8000); 992 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_TASK0, 0x400); 993 /* Init the mixer number */ 994 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 995 ESA_KDATA_MIXER_TASK_NUMBER, 0); 996 /* Extreme kernel master volume */ 997 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DAC_LEFT_VOLUME, 998 ESA_ARB_VOLUME); 999 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, 1000 ESA_KDATA_DAC_RIGHT_VOLUME, ESA_ARB_VOLUME); 1001 1002 if (esa_amp_enable(sc)) 1003 return (-1); 1004 1005 /* Zero entire DAC/ADC area */ 1006 for (i = 0x1100; i < 0x1c00; i++) 1007 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, i, 0); 1008 1009 esa_enable_interrupts(sc); 1010 1011 bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B, 1012 reset_state | ESA_REGB_ENABLE_RESET); 1013 1014 return (0); 1015} 1016 1017void 1018esa_config(struct esa_softc *sc) 1019{ 1020 bus_space_tag_t iot = sc->sc_iot; 1021 bus_space_handle_t ioh = sc->sc_ioh; 1022 pcitag_t tag = sc->sc_tag; 1023 pci_chipset_tag_t pc = sc->sc_pct; 1024 u_int32_t data; 1025 1026 data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG); 1027 data &= ESA_REDUCED_DEBOUNCE; 1028 data |= ESA_PM_CTRL_ENABLE | ESA_CLK_DIV_BY_49 | ESA_USE_PCI_TIMING; 1029 pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data); 1030 1031 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RESET_ASSP); 1032 data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG); 1033 data &= ~ESA_INT_CLK_SELECT; 1034 if (sc->type == ESS_MAESTRO3) { 1035 data &= ~ESA_INT_CLK_MULT_ENABLE; 1036 data |= ESA_INT_CLK_SRC_NOT_PCI; 1037 } 1038 data &= ~(ESA_CLK_MULT_MODE_SELECT | ESA_CLK_MULT_MODE_SELECT_2); 1039 pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data); 1040 1041 if (sc->type == ESS_ALLEGRO1) { 1042 data = pci_conf_read(pc, tag, ESA_PCI_USER_CONFIG); 1043 data |= ESA_IN_CLK_12MHZ_SELECT; 1044 pci_conf_write(pc, tag, ESA_PCI_USER_CONFIG, data); 1045 } 1046 1047 data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_A); 1048 data &= ~(ESA_DSP_CLK_36MHZ_SELECT | ESA_ASSP_CLK_49MHZ_SELECT); 1049 data |= ESA_ASSP_CLK_49MHZ_SELECT; /* XXX: Assumes 49MHz DSP */ 1050 data |= ESA_ASSP_0_WS_ENABLE; 1051 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_A, data); 1052 1053 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RUN_ASSP); 1054 1055 return; 1056} 1057 1058u_int8_t 1059esa_assp_halt(struct esa_softc *sc) 1060{ 1061 bus_space_tag_t iot = sc->sc_iot; 1062 bus_space_handle_t ioh = sc->sc_ioh; 1063 u_int8_t data, reset_state; 1064 1065 data = bus_space_read_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B); 1066 reset_state = data & ~ESA_REGB_STOP_CLOCK; 1067 delay(10000); /* XXX use tsleep */ 1068 bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B, 1069 reset_state & ~ESA_REGB_ENABLE_RESET); 1070 delay(10000); /* XXX use tsleep */ 1071 1072 return (reset_state); 1073} 1074 1075void 1076esa_codec_reset(struct esa_softc *sc) 1077{ 1078 bus_space_tag_t iot = sc->sc_iot; 1079 bus_space_handle_t ioh = sc->sc_ioh; 1080 u_int16_t data, dir; 1081 int retry = 0; 1082 1083 do { 1084 data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION); 1085 dir = data | 0x10; /* assuming pci bus master? */ 1086 1087 /* remote codec config */ 1088 data = bus_space_read_2(iot, ioh, ESA_RING_BUS_CTRL_B); 1089 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_B, 1090 data & ~ESA_SECOND_CODEC_ID_MASK); 1091 data = bus_space_read_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL); 1092 bus_space_write_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL, 1093 data & ~ESA_COMMAND_ADDR_OUT); 1094 data = bus_space_read_2(iot, ioh, ESA_SDO_IN_DEST_CTRL); 1095 bus_space_write_2(iot, ioh, ESA_SDO_IN_DEST_CTRL, 1096 data & ~ESA_STATUS_ADDR_IN); 1097 1098 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A, 1099 ESA_IO_SRAM_ENABLE); 1100 delay(20); 1101 1102 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, 1103 dir & ~ESA_GPO_PRIMARY_AC97); 1104 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, 1105 ~ESA_GPO_PRIMARY_AC97); 1106 bus_space_write_2(iot, ioh, ESA_GPIO_DATA, 0); 1107 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, 1108 dir | ESA_GPO_PRIMARY_AC97); 1109 delay(sc->delay1 * 1000); 1110 bus_space_write_2(iot, ioh, ESA_GPIO_DATA, 1111 ESA_GPO_PRIMARY_AC97); 1112 delay(5); 1113 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A, 1114 ESA_IO_SRAM_ENABLE | ESA_SERIAL_AC_LINK_ENABLE); 1115 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0); 1116 delay(sc->delay2 * 1000); 1117 1118 esa_read_codec(sc, 0x7c, &data); 1119 if ((data == 0) || (data == 0xffff)) { 1120 retry++; 1121 if (retry > 3) { 1122 printf("%s: esa_codec_reset: failed\n", 1123 sc->sc_dev.dv_xname); 1124 break; 1125 } 1126 printf("%s: esa_codec_reset: retrying\n", 1127 sc->sc_dev.dv_xname); 1128 } else 1129 retry = 0; 1130 } while (retry); 1131 1132 return; 1133} 1134 1135int 1136esa_amp_enable(struct esa_softc *sc) 1137{ 1138 bus_space_tag_t iot = sc->sc_iot; 1139 bus_space_handle_t ioh = sc->sc_ioh; 1140 u_int32_t gpo, polarity_port, polarity; 1141 u_int16_t data; 1142 1143 switch (sc->type) { 1144 case ESS_ALLEGRO1: 1145 polarity_port = 0x1800; 1146 break; 1147 case ESS_MAESTRO3: 1148 polarity_port = 0x1100; 1149 break; 1150 default: 1151 printf("%s: esa_amp_enable: Unknown chip type!!!\n", 1152 sc->sc_dev.dv_xname); 1153 return (1); 1154 } 1155 1156 gpo = (polarity_port >> 8) & 0x0f; 1157 polarity = polarity_port >> 12; 1158 polarity = !polarity; /* Enable */ 1159 polarity = polarity << gpo; 1160 gpo = 1 << gpo; 1161 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~gpo); 1162 data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION); 1163 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, data | gpo); 1164 data = ESA_GPO_SECONDARY_AC97 | ESA_GPO_PRIMARY_AC97 | polarity; 1165 bus_space_write_2(iot, ioh, ESA_GPIO_DATA, data); 1166 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0); 1167 1168 return (0); 1169} 1170 1171void 1172esa_enable_interrupts(struct esa_softc *sc) 1173{ 1174 bus_space_tag_t iot = sc->sc_iot; 1175 bus_space_handle_t ioh = sc->sc_ioh; 1176 u_int8_t data; 1177 1178 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 1179 ESA_ASSP_INT_ENABLE | ESA_HV_INT_ENABLE); 1180 data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_C); 1181 bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_C, 1182 data | ESA_ASSP_HOST_INT_ENABLE); 1183} 1184 1185int 1186esa_power(struct esa_softc *sc, int state) 1187{ 1188 pcitag_t tag = sc->sc_tag; 1189 pci_chipset_tag_t pc = sc->sc_pct; 1190 u_int32_t data; 1191 1192 data = pci_conf_read(pc, tag, 0x34); 1193 if (pci_conf_read(pc, tag, data) == 1) 1194 pci_conf_write(pc, tag, data + 4, state); 1195 1196 return (0); 1197} 1198 1199u_int32_t 1200esa_get_pointer(struct esa_softc *sc) 1201{ 1202 u_int16_t hi = 0, lo = 0; 1203 u_int32_t addr; 1204 1205 hi = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 1206 ESA_CDATA_HOST_SRC_CURRENTH); 1207 lo = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_DAC_DATA + 1208 ESA_CDATA_HOST_SRC_CURRENTL); 1209 1210 addr = lo | ((u_int32_t)hi << 16); 1211 return (addr - sc->play.start); 1212} 1213 1214paddr_t 1215esa_mappage(void *addr, void *mem, off_t off, int prot) 1216{ 1217 struct esa_softc *sc = addr; 1218 struct esa_dma *p; 1219 1220 if (off < 0) 1221 return (-1); 1222 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 1223 ; 1224 if (!p) 1225 return (-1); 1226 return (bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nsegs, 1227 off, prot, BUS_DMA_WAITOK)); 1228} 1229 1230