1 /* $NetBSD: eap.c,v 1.45 2001/04/24 21:03:33 mycroft Exp $ */ 2 /* $OpenBSD: eap.c,v 1.6 1999/10/05 19:24:42 csapuntz Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Lennart Augustsson <augustss@netbsd.org> and Charles M. Hannum. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Debugging: Andreas Gustafsson <gson@araneus.fi> 42 * Testing: Chuck Cranor <chuck@maria.wustl.edu> 43 * Phil Nelson <phil@cs.wwu.edu> 44 * 45 * ES1371/AC97: Ezra Story <ezy@panix.com> 46 */ 47 48 /* 49 * Ensoniq ES1370 + AK4531 and ES1371/ES1373 + AC97 50 * 51 * Documentation links: 52 * 53 * ftp://ftp.alsa-project.org/pub/manuals/ensoniq/ 54 * ftp://ftp.alsa-project.org/pub/manuals/asahi_kasei/4531.pdf 55 * ftp://download.intel.com/ial/scalableplatforms/audio/ac97r21.pdf 56 */ 57 58 #include "midi.h" 59 60 #include <sys/param.h> 61 #include <sys/systm.h> 62 #include <sys/kernel.h> 63 #include <sys/fcntl.h> 64 #include <sys/malloc.h> 65 #include <sys/device.h> 66 #include <sys/proc.h> 67 68 #include <dev/pci/pcidevs.h> 69 #include <dev/pci/pcivar.h> 70 71 #include <sys/audioio.h> 72 #include <dev/audio_if.h> 73 #include <dev/midi_if.h> 74 #include <dev/mulaw.h> 75 #include <dev/auconv.h> 76 #include <dev/ic/ac97var.h> 77 78 #include <machine/bus.h> 79 80 #include <dev/pci/eapreg.h> 81 82 #define PCI_CBIO 0x10 83 84 /* Debug */ 85 #ifdef AUDIO_DEBUG 86 #define DPRINTF(x) if (eapdebug) printf x 87 #define DPRINTFN(n,x) if (eapdebug>(n)) printf x 88 int eapdebug = 0; 89 #else 90 #define DPRINTF(x) 91 #define DPRINTFN(n,x) 92 #endif 93 94 int eap_match(struct device *, struct cfdata *, void *); 95 void eap_attach(struct device *, struct device *, void *); 96 int eap_intr(void *); 97 98 struct eap_dma { 99 bus_dmamap_t map; 100 caddr_t addr; 101 bus_dma_segment_t segs[1]; 102 int nsegs; 103 size_t size; 104 struct eap_dma *next; 105 }; 106 107 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 108 #define KERNADDR(p) ((void *)((p)->addr)) 109 110 struct eap_softc { 111 struct device sc_dev; /* base device */ 112 void *sc_ih; /* interrupt vectoring */ 113 bus_space_tag_t iot; 114 bus_space_handle_t ioh; 115 bus_dma_tag_t sc_dmatag; /* DMA tag */ 116 117 struct eap_dma *sc_dmas; 118 119 void (*sc_pintr)(void *); /* dma completion intr handler */ 120 void *sc_parg; /* arg for sc_intr() */ 121 #ifdef DIAGNOSTIC 122 char sc_prun; 123 #endif 124 125 void (*sc_rintr)(void *); /* dma completion intr handler */ 126 void *sc_rarg; /* arg for sc_intr() */ 127 #ifdef DIAGNOSTIC 128 char sc_rrun; 129 #endif 130 131 #if NMIDI > 0 132 void (*sc_iintr)(void *, int); /* midi input ready handler */ 133 void (*sc_ointr)(void *); /* midi output ready handler */ 134 void *sc_arg; 135 #endif 136 137 u_short sc_port[AK_NPORTS]; /* mirror of the hardware setting */ 138 u_int sc_record_source; /* recording source mask */ 139 u_int sc_output_source; /* output source mask */ 140 u_int sc_mic_preamp; 141 char sc_1371; /* Using ES1371/AC97 codec */ 142 143 struct ac97_codec_if *codec_if; 144 struct ac97_host_if host_if; 145 }; 146 147 int eap_allocmem(struct eap_softc *, size_t, size_t, struct eap_dma *); 148 int eap_freemem(struct eap_softc *, struct eap_dma *); 149 150 #define EWRITE1(sc, r, x) bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)) 151 #define EWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)) 152 #define EWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)) 153 #define EREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r)) 154 #define EREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r)) 155 #define EREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r)) 156 157 struct cfattach eap_ca = { 158 sizeof(struct eap_softc), eap_match, eap_attach 159 }; 160 161 int eap_open(void *, int); 162 void eap_close(void *); 163 int eap_query_encoding(void *, struct audio_encoding *); 164 int eap_set_params(void *, int, int, struct audio_params *, struct audio_params *); 165 int eap_round_blocksize(void *, int); 166 int eap_trigger_output(void *, void *, void *, int, void (*)(void *), 167 void *, struct audio_params *); 168 int eap_trigger_input(void *, void *, void *, int, void (*)(void *), 169 void *, struct audio_params *); 170 int eap_halt_output(void *); 171 int eap_halt_input(void *); 172 void eap1370_write_codec(struct eap_softc *, int, int); 173 int eap_getdev(void *, struct audio_device *); 174 int eap1370_mixer_set_port(void *, mixer_ctrl_t *); 175 int eap1370_mixer_get_port(void *, mixer_ctrl_t *); 176 int eap1371_mixer_set_port(void *, mixer_ctrl_t *); 177 int eap1371_mixer_get_port(void *, mixer_ctrl_t *); 178 int eap1370_query_devinfo(void *, mixer_devinfo_t *); 179 void *eap_malloc(void *, int, size_t, int, int); 180 void eap_free(void *, void *, int); 181 size_t eap_round_buffersize(void *, int, size_t); 182 paddr_t eap_mappage(void *, void *, off_t, int); 183 int eap_get_props(void *); 184 void eap1370_set_mixer(struct eap_softc *sc, int a, int d); 185 u_int32_t eap1371_src_wait(struct eap_softc *sc); 186 void eap1371_set_adc_rate(struct eap_softc *sc, int rate); 187 void eap1371_set_dac_rate(struct eap_softc *sc, int rate, int which); 188 int eap1371_src_read(struct eap_softc *sc, int a); 189 void eap1371_src_write(struct eap_softc *sc, int a, int d); 190 int eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip); 191 192 int eap1371_attach_codec(void *sc, struct ac97_codec_if *); 193 int eap1371_read_codec(void *sc, u_int8_t a, u_int16_t *d); 194 int eap1371_write_codec(void *sc, u_int8_t a, u_int16_t d); 195 void eap1371_reset_codec(void *sc); 196 int eap1371_get_portnum_by_name(struct eap_softc *, char *, char *, 197 char *); 198 #if NMIDI > 0 199 void eap_midi_close(void *); 200 void eap_midi_getinfo(void *, struct midi_info *); 201 int eap_midi_open(void *, int, void (*)(void *, int), 202 void (*)(void *), void *); 203 int eap_midi_output(void *, int); 204 #endif 205 206 struct audio_hw_if eap1370_hw_if = { 207 eap_open, 208 eap_close, 209 NULL, 210 eap_query_encoding, 211 eap_set_params, 212 eap_round_blocksize, 213 NULL, 214 NULL, 215 NULL, 216 NULL, 217 NULL, 218 eap_halt_output, 219 eap_halt_input, 220 NULL, 221 eap_getdev, 222 NULL, 223 eap1370_mixer_set_port, 224 eap1370_mixer_get_port, 225 eap1370_query_devinfo, 226 eap_malloc, 227 eap_free, 228 eap_round_buffersize, 229 eap_mappage, 230 eap_get_props, 231 eap_trigger_output, 232 eap_trigger_input, 233 }; 234 235 struct audio_hw_if eap1371_hw_if = { 236 eap_open, 237 eap_close, 238 NULL, 239 eap_query_encoding, 240 eap_set_params, 241 eap_round_blocksize, 242 NULL, 243 NULL, 244 NULL, 245 NULL, 246 NULL, 247 eap_halt_output, 248 eap_halt_input, 249 NULL, 250 eap_getdev, 251 NULL, 252 eap1371_mixer_set_port, 253 eap1371_mixer_get_port, 254 eap1371_query_devinfo, 255 eap_malloc, 256 eap_free, 257 eap_round_buffersize, 258 eap_mappage, 259 eap_get_props, 260 eap_trigger_output, 261 eap_trigger_input, 262 }; 263 264 #if NMIDI > 0 265 struct midi_hw_if eap_midi_hw_if = { 266 eap_midi_open, 267 eap_midi_close, 268 eap_midi_output, 269 eap_midi_getinfo, 270 0, /* ioctl */ 271 }; 272 #endif 273 274 struct audio_device eap_device = { 275 "Ensoniq AudioPCI", 276 "", 277 "eap" 278 }; 279 280 int 281 eap_match(struct device *parent, struct cfdata *match, void *aux) 282 { 283 struct pci_attach_args *pa = (struct pci_attach_args *) aux; 284 285 switch (PCI_VENDOR(pa->pa_id)) { 286 case PCI_VENDOR_CREATIVELABS: 287 switch (PCI_PRODUCT(pa->pa_id)) { 288 case PCI_PRODUCT_CREATIVELABS_EV1938: 289 return (1); 290 } 291 break; 292 case PCI_VENDOR_ENSONIQ: 293 switch (PCI_PRODUCT(pa->pa_id)) { 294 case PCI_PRODUCT_ENSONIQ_AUDIOPCI: 295 case PCI_PRODUCT_ENSONIQ_AUDIOPCI97: 296 case PCI_PRODUCT_ENSONIQ_CT5880: 297 return (1); 298 } 299 break; 300 } 301 302 return (0); 303 } 304 305 void 306 eap1370_write_codec(struct eap_softc *sc, int a, int d) 307 { 308 int icss, to; 309 310 to = EAP_WRITE_TIMEOUT; 311 do { 312 icss = EREAD4(sc, EAP_ICSS); 313 DPRINTFN(5,("eap: codec %d prog: icss=0x%08x\n", a, icss)); 314 if (!to--) { 315 printf("eap: timeout writing to codec\n"); 316 return; 317 } 318 } while(icss & EAP_CWRIP); /* XXX could use CSTAT here */ 319 EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d)); 320 } 321 322 /* 323 * Reading and writing the CODEC is very convoluted. This mimics the 324 * FreeBSD and Linux drivers. 325 */ 326 327 static __inline void 328 eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd) 329 { 330 int to, s; 331 u_int32_t src, t; 332 333 for (to = 0; to < EAP_WRITE_TIMEOUT; to++) { 334 if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP)) 335 break; 336 delay(1); 337 } 338 if (to >= EAP_WRITE_TIMEOUT) 339 printf("%s: eap1371_ready_codec timeout 1\n", 340 sc->sc_dev.dv_xname); 341 342 s = splaudio(); 343 src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK; 344 EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK); 345 346 for (to = 0; to < EAP_READ_TIMEOUT; to++) { 347 t = EREAD4(sc, E1371_SRC); 348 if ((t & E1371_SRC_STATE_MASK) == 0) 349 break; 350 delay(1); 351 } 352 if (to >= EAP_READ_TIMEOUT) 353 printf("%s: eap1371_ready_codec timeout 2\n", 354 sc->sc_dev.dv_xname); 355 356 for (to = 0; to < EAP_READ_TIMEOUT; to++) { 357 t = EREAD4(sc, E1371_SRC); 358 if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK) 359 break; 360 delay(1); 361 } 362 if (to >= EAP_READ_TIMEOUT) 363 printf("%s: eap1371_ready_codec timeout 3\n", 364 sc->sc_dev.dv_xname); 365 366 EWRITE4(sc, E1371_CODEC, wd); 367 368 eap1371_src_wait(sc); 369 EWRITE4(sc, E1371_SRC, src); 370 371 splx(s); 372 } 373 374 int 375 eap1371_read_codec(void *sc_, u_int8_t a, u_int16_t *d) 376 { 377 struct eap_softc *sc = sc_; 378 int to; 379 u_int32_t t; 380 381 eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, 0) | E1371_CODEC_READ); 382 383 for (to = 0; to < EAP_WRITE_TIMEOUT; to++) { 384 if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP)) 385 break; 386 } 387 if (to > EAP_WRITE_TIMEOUT) 388 printf("%s: eap1371_read_codec timeout 1\n", 389 sc->sc_dev.dv_xname); 390 391 for (to = 0; to < EAP_WRITE_TIMEOUT; to++) { 392 t = EREAD4(sc, E1371_CODEC); 393 if (t & E1371_CODEC_VALID) 394 break; 395 } 396 if (to > EAP_WRITE_TIMEOUT) 397 printf("%s: eap1371_read_codec timeout 2\n", 398 sc->sc_dev.dv_xname); 399 400 *d = (u_int16_t)t; 401 402 DPRINTFN(10, ("eap1371: reading codec (%x) = %x\n", a, *d)); 403 404 return (0); 405 } 406 407 int 408 eap1371_write_codec(void *sc_, u_int8_t a, u_int16_t d) 409 { 410 struct eap_softc *sc = sc_; 411 412 eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, d)); 413 414 DPRINTFN(10, ("eap1371: writing codec %x --> %x\n", d, a)); 415 416 return (0); 417 } 418 419 u_int32_t 420 eap1371_src_wait(struct eap_softc *sc) 421 { 422 int to; 423 u_int32_t src; 424 425 for (to = 0; to < EAP_READ_TIMEOUT; to++) { 426 src = EREAD4(sc, E1371_SRC); 427 if (!(src & E1371_SRC_RBUSY)) 428 return (src); 429 delay(1); 430 } 431 printf("%s: eap1371_src_wait timeout\n", sc->sc_dev.dv_xname); 432 return (src); 433 } 434 435 int 436 eap1371_src_read(struct eap_softc *sc, int a) 437 { 438 int to; 439 u_int32_t src, t; 440 441 src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK; 442 src |= E1371_SRC_ADDR(a); 443 EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK); 444 445 if ((eap1371_src_wait(sc) & E1371_SRC_STATE_MASK) != E1371_SRC_STATE_OK) { 446 for (to = 0; to < EAP_READ_TIMEOUT; to++) { 447 t = EREAD4(sc, E1371_SRC); 448 if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK) 449 break; 450 delay(1); 451 } 452 } 453 454 EWRITE4(sc, E1371_SRC, src); 455 456 return t & E1371_SRC_DATAMASK; 457 } 458 459 void 460 eap1371_src_write(struct eap_softc *sc, int a, int d) 461 { 462 u_int32_t r; 463 464 r = eap1371_src_wait(sc) & E1371_SRC_CTLMASK; 465 r |= E1371_SRC_RAMWE | E1371_SRC_ADDR(a) | E1371_SRC_DATA(d); 466 EWRITE4(sc, E1371_SRC, r); 467 } 468 469 void 470 eap1371_set_adc_rate(struct eap_softc *sc, int rate) 471 { 472 int freq, n, truncm; 473 int out; 474 int s; 475 476 /* Whatever, it works, so I'll leave it :) */ 477 478 if (rate > 48000) 479 rate = 48000; 480 if (rate < 4000) 481 rate = 4000; 482 n = rate / 3000; 483 if ((1 << n) & SRC_MAGIC) 484 n--; 485 truncm = ((21 * n) - 1) | 1; 486 freq = ((48000 << 15) / rate) * n; 487 if (rate >= 24000) { 488 if (truncm > 239) 489 truncm = 239; 490 out = ESRC_SET_TRUNC((239 - truncm) / 2); 491 } else { 492 if (truncm > 119) 493 truncm = 119; 494 out = ESRC_SMF | ESRC_SET_TRUNC((119 - truncm) / 2); 495 } 496 out |= ESRC_SET_N(n); 497 s = splaudio(); 498 eap1371_src_write(sc, ESRC_ADC+ESRC_TRUNC_N, out); 499 500 501 out = eap1371_src_read(sc, ESRC_ADC+ESRC_IREGS) & 0xff; 502 eap1371_src_write(sc, ESRC_ADC+ESRC_IREGS, out | 503 ESRC_SET_VFI(freq >> 15)); 504 eap1371_src_write(sc, ESRC_ADC+ESRC_VFF, freq & 0x7fff); 505 eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(n)); 506 eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(n)); 507 splx(s); 508 } 509 510 void 511 eap1371_set_dac_rate(struct eap_softc *sc, int rate, int which) 512 { 513 int dac = which == 1 ? ESRC_DAC1 : ESRC_DAC2; 514 int freq, r; 515 int s; 516 517 /* Whatever, it works, so I'll leave it :) */ 518 519 if (rate > 48000) 520 rate = 48000; 521 if (rate < 4000) 522 rate = 4000; 523 freq = ((rate << 15) + 1500) / 3000; 524 525 s = splaudio(); 526 eap1371_src_wait(sc); 527 r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE | 528 E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC); 529 r |= (which == 1) ? E1371_SRC_DISP1 : E1371_SRC_DISP2; 530 EWRITE4(sc, E1371_SRC, r); 531 r = eap1371_src_read(sc, dac + ESRC_IREGS) & 0x00ff; 532 eap1371_src_write(sc, dac + ESRC_IREGS, r | ((freq >> 5) & 0xfc00)); 533 eap1371_src_write(sc, dac + ESRC_VFF, freq & 0x7fff); 534 r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE | 535 E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC); 536 r &= ~(which == 1 ? E1371_SRC_DISP1 : E1371_SRC_DISP2); 537 EWRITE4(sc, E1371_SRC, r); 538 splx(s); 539 } 540 541 void 542 eap_attach(struct device *parent, struct device *self, void *aux) 543 { 544 struct eap_softc *sc = (struct eap_softc *)self; 545 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 546 pci_chipset_tag_t pc = pa->pa_pc; 547 struct audio_hw_if *eap_hw_if; 548 char const *intrstr; 549 pci_intr_handle_t ih; 550 pcireg_t csr; 551 char devinfo[256]; 552 mixer_ctrl_t ctl; 553 int i; 554 int revision, ct5880; 555 const char *revstr = ""; 556 557 /* Flag if we're "creative" */ 558 sc->sc_1371 = !(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ && 559 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI); 560 561 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); 562 revision = PCI_REVISION(pa->pa_class); 563 if (sc->sc_1371) { 564 ct5880 = 0; 565 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ && 566 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_CT5880) 567 ct5880 = 1; 568 switch (revision) { 569 case EAP_EV1938_A: revstr = "EV1938A "; break; 570 case EAP_CT5880_C: revstr = "CT5880C "; ct5880 = 1; break; 571 case EAP_ES1373_A: revstr = "ES1373A "; break; 572 case EAP_ES1373_B: revstr = "ES1373B "; break; 573 case EAP_CT5880_A: revstr = "CT5880A "; ct5880 = 1; break; 574 case EAP_ES1371_B: revstr = "ES1371B "; break; 575 } 576 } 577 printf(": %s %s(rev. 0x%02x)\n", devinfo, revstr, revision); 578 579 /* Map I/O register */ 580 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, 581 &sc->iot, &sc->ioh, NULL, NULL)) { 582 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname); 583 return; 584 } 585 586 sc->sc_dmatag = pa->pa_dmat; 587 588 /* Enable the device. */ 589 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 590 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 591 csr | PCI_COMMAND_MASTER_ENABLE); 592 593 /* Map and establish the interrupt. */ 594 if (pci_intr_map(pa, &ih)) { 595 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); 596 return; 597 } 598 intrstr = pci_intr_string(pc, ih); 599 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, eap_intr, sc); 600 if (sc->sc_ih == NULL) { 601 printf("%s: couldn't establish interrupt", 602 sc->sc_dev.dv_xname); 603 if (intrstr != NULL) 604 printf(" at %s", intrstr); 605 printf("\n"); 606 return; 607 } 608 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); 609 610 if (!sc->sc_1371) { 611 /* Enable interrupts and looping mode. */ 612 /* enable the parts we need */ 613 EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN); 614 EWRITE4(sc, EAP_ICSC, EAP_CDC_EN); 615 616 /* reset codec */ 617 /* normal operation */ 618 /* select codec clocks */ 619 eap1370_write_codec(sc, AK_RESET, AK_PD); 620 eap1370_write_codec(sc, AK_RESET, AK_PD | AK_NRST); 621 eap1370_write_codec(sc, AK_CS, 0x0); 622 623 eap_hw_if = &eap1370_hw_if; 624 625 /* Enable all relevant mixer switches. */ 626 ctl.dev = EAP_OUTPUT_SELECT; 627 ctl.type = AUDIO_MIXER_SET; 628 ctl.un.mask = 1 << EAP_VOICE_VOL | 1 << EAP_FM_VOL | 629 1 << EAP_CD_VOL | 1 << EAP_LINE_VOL | 1 << EAP_AUX_VOL | 630 1 << EAP_MIC_VOL; 631 eap_hw_if->set_port(sc, &ctl); 632 633 ctl.type = AUDIO_MIXER_VALUE; 634 ctl.un.value.num_channels = 1; 635 for (ctl.dev = EAP_MASTER_VOL; ctl.dev < EAP_MIC_VOL; 636 ctl.dev++) { 637 ctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = VOL_0DB; 638 eap_hw_if->set_port(sc, &ctl); 639 } 640 ctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = 0; 641 eap_hw_if->set_port(sc, &ctl); 642 ctl.dev = EAP_MIC_PREAMP; 643 ctl.type = AUDIO_MIXER_ENUM; 644 ctl.un.ord = 0; 645 eap_hw_if->set_port(sc, &ctl); 646 ctl.dev = EAP_RECORD_SOURCE; 647 ctl.type = AUDIO_MIXER_SET; 648 ctl.un.mask = 1 << EAP_MIC_VOL; 649 eap_hw_if->set_port(sc, &ctl); 650 } else { 651 /* clean slate */ 652 653 EWRITE4(sc, EAP_SIC, 0); 654 EWRITE4(sc, EAP_ICSC, 0); 655 EWRITE4(sc, E1371_LEGACY, 0); 656 657 if (ct5880) { 658 EWRITE4(sc, EAP_ICSS, EAP_CT5880_AC97_RESET); 659 /* Let codec wake up */ 660 tsleep(sc, PRIBIO, "eapcdc", hz / 20); 661 } 662 663 /* Reset from es1371's perspective */ 664 EWRITE4(sc, EAP_ICSC, E1371_SYNC_RES); 665 delay(20); 666 EWRITE4(sc, EAP_ICSC, 0); 667 668 /* 669 * Must properly reprogram sample rate converter, 670 * or it locks up. Set some defaults for the life of the 671 * machine, and set up a sb default sample rate. 672 */ 673 EWRITE4(sc, E1371_SRC, E1371_SRC_DISABLE); 674 for (i = 0; i < 0x80; i++) 675 eap1371_src_write(sc, i, 0); 676 eap1371_src_write(sc, ESRC_DAC1+ESRC_TRUNC_N, ESRC_SET_N(16)); 677 eap1371_src_write(sc, ESRC_DAC2+ESRC_TRUNC_N, ESRC_SET_N(16)); 678 eap1371_src_write(sc, ESRC_DAC1+ESRC_IREGS, ESRC_SET_VFI(16)); 679 eap1371_src_write(sc, ESRC_DAC2+ESRC_IREGS, ESRC_SET_VFI(16)); 680 eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(16)); 681 eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(16)); 682 eap1371_src_write(sc, ESRC_DAC1_VOLL, ESRC_SET_DAC_VOLI(1)); 683 eap1371_src_write(sc, ESRC_DAC1_VOLR, ESRC_SET_DAC_VOLI(1)); 684 eap1371_src_write(sc, ESRC_DAC2_VOLL, ESRC_SET_DAC_VOLI(1)); 685 eap1371_src_write(sc, ESRC_DAC2_VOLR, ESRC_SET_DAC_VOLI(1)); 686 eap1371_set_adc_rate(sc, 22050); 687 eap1371_set_dac_rate(sc, 22050, 1); 688 eap1371_set_dac_rate(sc, 22050, 2); 689 690 EWRITE4(sc, E1371_SRC, 0); 691 692 /* Reset codec */ 693 694 /* Interrupt enable */ 695 sc->host_if.arg = sc; 696 sc->host_if.attach = eap1371_attach_codec; 697 sc->host_if.read = eap1371_read_codec; 698 sc->host_if.write = eap1371_write_codec; 699 sc->host_if.reset = eap1371_reset_codec; 700 701 if (ac97_attach(&sc->host_if) == 0) { 702 /* Interrupt enable */ 703 EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN); 704 } else 705 return; 706 707 eap_hw_if = &eap1371_hw_if; 708 709 /* Just enable the DAC and master volumes by default */ 710 ctl.type = AUDIO_MIXER_ENUM; 711 ctl.un.ord = 0; /* off */ 712 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCoutputs, 713 AudioNmaster, AudioNmute); 714 eap1371_mixer_set_port(sc, &ctl); 715 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCinputs, 716 AudioNdac, AudioNmute); 717 eap1371_mixer_set_port(sc, &ctl); 718 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCrecord, 719 AudioNvolume, AudioNmute); 720 eap1371_mixer_set_port(sc, &ctl); 721 722 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCrecord, 723 AudioNsource, NULL); 724 ctl.type = AUDIO_MIXER_ENUM; 725 ctl.un.ord = 0; 726 eap1371_mixer_set_port(sc, &ctl); 727 728 } 729 730 audio_attach_mi(eap_hw_if, sc, &sc->sc_dev); 731 732 #if NMIDI > 0 733 midi_attach_mi(&eap_midi_hw_if, sc, &sc->sc_dev); 734 #endif 735 } 736 737 int 738 eap1371_attach_codec(void *sc_, struct ac97_codec_if *codec_if) 739 { 740 struct eap_softc *sc = sc_; 741 742 sc->codec_if = codec_if; 743 return (0); 744 } 745 746 void 747 eap1371_reset_codec(void *sc_) 748 { 749 struct eap_softc *sc = sc_; 750 u_int32_t icsc; 751 int s; 752 753 s = splaudio(); 754 icsc = EREAD4(sc, EAP_ICSC); 755 EWRITE4(sc, EAP_ICSC, icsc | E1371_SYNC_RES); 756 delay(20); 757 EWRITE4(sc, EAP_ICSC, icsc & ~E1371_SYNC_RES); 758 delay(1); 759 splx(s); 760 761 return; 762 } 763 764 int 765 eap_intr(void *p) 766 { 767 struct eap_softc *sc = p; 768 u_int32_t intr, sic; 769 770 intr = EREAD4(sc, EAP_ICSS); 771 if (!(intr & EAP_INTR)) 772 return (0); 773 sic = EREAD4(sc, EAP_SIC); 774 DPRINTFN(5, ("eap_intr: ICSS=0x%08x, SIC=0x%08x\n", intr, sic)); 775 if (intr & EAP_I_ADC) { 776 #if 0 777 /* 778 * XXX This is a hack! 779 * The EAP chip sometimes generates the recording interrupt 780 * while it is still transferring the data. To make sure 781 * it has all arrived we busy wait until the count is right. 782 * The transfer we are waiting for is 8 longwords. 783 */ 784 int s, nw, n; 785 EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE); 786 s = EREAD4(sc, EAP_ADC_CSR); 787 nw = ((s & 0xffff) + 1) >> 2; /* # of words in DMA */ 788 n = 0; 789 while (((EREAD4(sc, EAP_ADC_SIZE) >> 16) + 8) % nw == 0) { 790 delay(10); 791 if (++n > 100) { 792 printf("eapintr: dma fix timeout"); 793 break; 794 } 795 } 796 /* Continue with normal interrupt handling. */ 797 #endif 798 EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN); 799 EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN); 800 if (sc->sc_rintr) 801 sc->sc_rintr(sc->sc_rarg); 802 } 803 if (intr & EAP_I_DAC2) { 804 EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN); 805 EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN); 806 if (sc->sc_pintr) 807 sc->sc_pintr(sc->sc_parg); 808 } 809 #if NMIDI > 0 810 if ((intr & EAP_I_UART) && sc->sc_iintr != NULL) { 811 u_int32_t data; 812 813 if (EREAD1(sc, EAP_UART_STATUS) & EAP_US_RXINT) { 814 while (EREAD1(sc, EAP_UART_STATUS) & EAP_US_RXRDY) { 815 data = EREAD1(sc, EAP_UART_DATA); 816 sc->sc_iintr(sc->sc_arg, data); 817 } 818 } 819 } 820 #endif 821 return (1); 822 } 823 824 int 825 eap_allocmem(struct eap_softc *sc, size_t size, size_t align, struct eap_dma *p) 826 { 827 int error; 828 829 p->size = size; 830 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0, 831 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 832 &p->nsegs, BUS_DMA_NOWAIT); 833 if (error) 834 return (error); 835 836 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 837 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 838 if (error) 839 goto free; 840 841 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size, 842 0, BUS_DMA_NOWAIT, &p->map); 843 if (error) 844 goto unmap; 845 846 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 847 BUS_DMA_NOWAIT); 848 if (error) 849 goto destroy; 850 return (0); 851 852 destroy: 853 bus_dmamap_destroy(sc->sc_dmatag, p->map); 854 unmap: 855 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 856 free: 857 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 858 return (error); 859 } 860 861 int 862 eap_freemem(struct eap_softc *sc, struct eap_dma *p) 863 { 864 bus_dmamap_unload(sc->sc_dmatag, p->map); 865 bus_dmamap_destroy(sc->sc_dmatag, p->map); 866 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 867 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 868 return (0); 869 } 870 871 int 872 eap_open(void *addr, int flags) 873 { 874 return (0); 875 } 876 877 /* 878 * Close function is called at splaudio(). 879 */ 880 void 881 eap_close(void *addr) 882 { 883 struct eap_softc *sc = addr; 884 885 eap_halt_output(sc); 886 eap_halt_input(sc); 887 888 sc->sc_pintr = 0; 889 sc->sc_rintr = 0; 890 } 891 892 int 893 eap_query_encoding(void *addr, struct audio_encoding *fp) 894 { 895 switch (fp->index) { 896 case 0: 897 strcpy(fp->name, AudioEulinear); 898 fp->encoding = AUDIO_ENCODING_ULINEAR; 899 fp->precision = 8; 900 fp->flags = 0; 901 return (0); 902 case 1: 903 strcpy(fp->name, AudioEmulaw); 904 fp->encoding = AUDIO_ENCODING_ULAW; 905 fp->precision = 8; 906 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 907 return (0); 908 case 2: 909 strcpy(fp->name, AudioEalaw); 910 fp->encoding = AUDIO_ENCODING_ALAW; 911 fp->precision = 8; 912 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 913 return (0); 914 case 3: 915 strcpy(fp->name, AudioEslinear); 916 fp->encoding = AUDIO_ENCODING_SLINEAR; 917 fp->precision = 8; 918 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 919 return (0); 920 case 4: 921 strcpy(fp->name, AudioEslinear_le); 922 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 923 fp->precision = 16; 924 fp->flags = 0; 925 return (0); 926 case 5: 927 strcpy(fp->name, AudioEulinear_le); 928 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 929 fp->precision = 16; 930 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 931 return (0); 932 case 6: 933 strcpy(fp->name, AudioEslinear_be); 934 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 935 fp->precision = 16; 936 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 937 return (0); 938 case 7: 939 strcpy(fp->name, AudioEulinear_be); 940 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 941 fp->precision = 16; 942 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 943 return (0); 944 default: 945 return (EINVAL); 946 } 947 } 948 949 int 950 eap_set_params(void *addr, int setmode, int usemode, 951 struct audio_params *play, struct audio_params *rec) 952 { 953 struct eap_softc *sc = addr; 954 struct audio_params *p; 955 int mode; 956 u_int32_t div; 957 958 /* 959 * The es1370 only has one clock, so make the sample rates match. 960 */ 961 if (!sc->sc_1371) { 962 if (play->sample_rate != rec->sample_rate && 963 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 964 if (setmode == AUMODE_PLAY) { 965 rec->sample_rate = play->sample_rate; 966 setmode |= AUMODE_RECORD; 967 } else if (setmode == AUMODE_RECORD) { 968 play->sample_rate = rec->sample_rate; 969 setmode |= AUMODE_PLAY; 970 } else 971 return (EINVAL); 972 } 973 } 974 975 for (mode = AUMODE_RECORD; mode != -1; 976 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 977 if ((setmode & mode) == 0) 978 continue; 979 980 p = mode == AUMODE_PLAY ? play : rec; 981 982 if (p->sample_rate < 4000 || p->sample_rate > 48000 || 983 (p->precision != 8 && p->precision != 16) || 984 (p->channels != 1 && p->channels != 2)) 985 return (EINVAL); 986 987 p->factor = 1; 988 p->sw_code = 0; 989 switch (p->encoding) { 990 case AUDIO_ENCODING_SLINEAR_BE: 991 if (p->precision == 16) 992 p->sw_code = swap_bytes; 993 else 994 p->sw_code = change_sign8; 995 break; 996 case AUDIO_ENCODING_SLINEAR_LE: 997 if (p->precision != 16) 998 p->sw_code = change_sign8; 999 break; 1000 case AUDIO_ENCODING_ULINEAR_BE: 1001 if (p->precision == 16) { 1002 if (mode == AUMODE_PLAY) 1003 p->sw_code = swap_bytes_change_sign16_le; 1004 else 1005 p->sw_code = change_sign16_swap_bytes_le; 1006 } 1007 break; 1008 case AUDIO_ENCODING_ULINEAR_LE: 1009 if (p->precision == 16) 1010 p->sw_code = change_sign16_le; 1011 break; 1012 case AUDIO_ENCODING_ULAW: 1013 if (mode == AUMODE_PLAY) { 1014 p->factor = 2; 1015 p->sw_code = mulaw_to_slinear16_le; 1016 } else 1017 p->sw_code = ulinear8_to_mulaw; 1018 break; 1019 case AUDIO_ENCODING_ALAW: 1020 if (mode == AUMODE_PLAY) { 1021 p->factor = 2; 1022 p->sw_code = alaw_to_slinear16_le; 1023 } else 1024 p->sw_code = ulinear8_to_alaw; 1025 break; 1026 default: 1027 return (EINVAL); 1028 } 1029 } 1030 1031 if (sc->sc_1371) { 1032 eap1371_set_dac_rate(sc, play->sample_rate, 1); 1033 eap1371_set_dac_rate(sc, play->sample_rate, 2); 1034 eap1371_set_adc_rate(sc, rec->sample_rate); 1035 } else { 1036 /* Set the speed */ 1037 DPRINTFN(2, ("eap_set_params: old ICSC = 0x%08x\n", 1038 EREAD4(sc, EAP_ICSC))); 1039 div = EREAD4(sc, EAP_ICSC) & ~EAP_PCLKBITS; 1040 /* 1041 * XXX 1042 * The -2 isn't documented, but seemed to make the wall 1043 * time match 1044 * what I expect. - mycroft 1045 */ 1046 if (usemode == AUMODE_RECORD) 1047 div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ / 1048 rec->sample_rate - 2); 1049 else 1050 div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ / 1051 play->sample_rate - 2); 1052 div |= EAP_CCB_INTRM; 1053 EWRITE4(sc, EAP_ICSC, div); 1054 DPRINTFN(2, ("eap_set_params: set ICSC = 0x%08x\n", div)); 1055 } 1056 1057 return (0); 1058 } 1059 1060 int 1061 eap_round_blocksize(void *addr, int blk) 1062 { 1063 return (blk & -32); /* keep good alignment */ 1064 } 1065 1066 int 1067 eap_trigger_output( 1068 void *addr, 1069 void *start, 1070 void *end, 1071 int blksize, 1072 void (*intr)(void *), 1073 void *arg, 1074 struct audio_params *param) 1075 { 1076 struct eap_softc *sc = addr; 1077 struct eap_dma *p; 1078 u_int32_t icsc, sic; 1079 int sampshift; 1080 1081 #ifdef DIAGNOSTIC 1082 if (sc->sc_prun) 1083 panic("eap_trigger_output: already running"); 1084 sc->sc_prun = 1; 1085 #endif 1086 1087 DPRINTFN(1, ("eap_trigger_output: sc=%p start=%p end=%p " 1088 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 1089 sc->sc_pintr = intr; 1090 sc->sc_parg = arg; 1091 1092 sic = EREAD4(sc, EAP_SIC); 1093 sic &= ~(EAP_P2_S_EB | EAP_P2_S_MB | EAP_INC_BITS); 1094 sic |= EAP_SET_P2_ST_INC(0) | EAP_SET_P2_END_INC(param->precision * param->factor / 8); 1095 sampshift = 0; 1096 if (param->precision * param->factor == 16) { 1097 sic |= EAP_P2_S_EB; 1098 sampshift++; 1099 } 1100 if (param->channels == 2) { 1101 sic |= EAP_P2_S_MB; 1102 sampshift++; 1103 } 1104 EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN); 1105 EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN); 1106 1107 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1108 ; 1109 if (!p) { 1110 printf("eap_trigger_output: bad addr %p\n", start); 1111 return (EINVAL); 1112 } 1113 1114 DPRINTF(("eap_trigger_output: DAC2_ADDR=0x%x, DAC2_SIZE=0x%x\n", 1115 (int)DMAADDR(p), 1116 EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1))); 1117 EWRITE4(sc, EAP_MEMPAGE, EAP_DAC_PAGE); 1118 EWRITE4(sc, EAP_DAC2_ADDR, DMAADDR(p)); 1119 EWRITE4(sc, EAP_DAC2_SIZE, 1120 EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)); 1121 1122 EWRITE4(sc, EAP_DAC2_CSR, (blksize >> sampshift) - 1); 1123 1124 if (sc->sc_1371) 1125 EWRITE4(sc, E1371_SRC, 0); 1126 1127 icsc = EREAD4(sc, EAP_ICSC); 1128 EWRITE4(sc, EAP_ICSC, icsc | EAP_DAC2_EN); 1129 1130 DPRINTFN(1, ("eap_trigger_output: set ICSC = 0x%08x\n", icsc)); 1131 1132 return (0); 1133 } 1134 1135 int 1136 eap_trigger_input( 1137 void *addr, 1138 void *start, 1139 void *end, 1140 int blksize, 1141 void (*intr)(void *), 1142 void *arg, 1143 struct audio_params *param) 1144 { 1145 struct eap_softc *sc = addr; 1146 struct eap_dma *p; 1147 u_int32_t icsc, sic; 1148 int sampshift; 1149 1150 #ifdef DIAGNOSTIC 1151 if (sc->sc_rrun) 1152 panic("eap_trigger_input: already running"); 1153 sc->sc_rrun = 1; 1154 #endif 1155 1156 DPRINTFN(1, ("eap_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 1157 addr, start, end, blksize, intr, arg)); 1158 sc->sc_rintr = intr; 1159 sc->sc_rarg = arg; 1160 1161 sic = EREAD4(sc, EAP_SIC); 1162 sic &= ~(EAP_R1_S_EB | EAP_R1_S_MB); 1163 sampshift = 0; 1164 if (param->precision * param->factor == 16) { 1165 sic |= EAP_R1_S_EB; 1166 sampshift++; 1167 } 1168 if (param->channels == 2) { 1169 sic |= EAP_R1_S_MB; 1170 sampshift++; 1171 } 1172 EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN); 1173 EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN); 1174 1175 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1176 ; 1177 if (!p) { 1178 printf("eap_trigger_input: bad addr %p\n", start); 1179 return (EINVAL); 1180 } 1181 1182 DPRINTF(("eap_trigger_input: ADC_ADDR=0x%x, ADC_SIZE=0x%x\n", 1183 (int)DMAADDR(p), 1184 EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1))); 1185 EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE); 1186 EWRITE4(sc, EAP_ADC_ADDR, DMAADDR(p)); 1187 EWRITE4(sc, EAP_ADC_SIZE, 1188 EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)); 1189 1190 EWRITE4(sc, EAP_ADC_CSR, (blksize >> sampshift) - 1); 1191 1192 if (sc->sc_1371) 1193 EWRITE4(sc, E1371_SRC, 0); 1194 1195 icsc = EREAD4(sc, EAP_ICSC); 1196 EWRITE4(sc, EAP_ICSC, icsc | EAP_ADC_EN); 1197 1198 DPRINTFN(1, ("eap_trigger_input: set ICSC = 0x%08x\n", icsc)); 1199 1200 return (0); 1201 } 1202 1203 int 1204 eap_halt_output(void *addr) 1205 { 1206 struct eap_softc *sc = addr; 1207 u_int32_t icsc; 1208 1209 DPRINTF(("eap: eap_halt_output\n")); 1210 icsc = EREAD4(sc, EAP_ICSC); 1211 EWRITE4(sc, EAP_ICSC, icsc & ~EAP_DAC2_EN); 1212 #ifdef DIAGNOSTIC 1213 sc->sc_prun = 0; 1214 #endif 1215 return (0); 1216 } 1217 1218 int 1219 eap_halt_input(void *addr) 1220 { 1221 struct eap_softc *sc = addr; 1222 u_int32_t icsc; 1223 1224 DPRINTF(("eap: eap_halt_input\n")); 1225 icsc = EREAD4(sc, EAP_ICSC); 1226 EWRITE4(sc, EAP_ICSC, icsc & ~EAP_ADC_EN); 1227 #ifdef DIAGNOSTIC 1228 sc->sc_rrun = 0; 1229 #endif 1230 return (0); 1231 } 1232 1233 int 1234 eap_getdev(void *addr, struct audio_device *retp) 1235 { 1236 *retp = eap_device; 1237 return (0); 1238 } 1239 1240 int 1241 eap1371_mixer_set_port(void *addr, mixer_ctrl_t *cp) 1242 { 1243 struct eap_softc *sc = addr; 1244 1245 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp)); 1246 } 1247 1248 int 1249 eap1371_mixer_get_port(void *addr, mixer_ctrl_t *cp) 1250 { 1251 struct eap_softc *sc = addr; 1252 1253 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp)); 1254 } 1255 1256 int 1257 eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip) 1258 { 1259 struct eap_softc *sc = addr; 1260 1261 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip)); 1262 } 1263 1264 int 1265 eap1371_get_portnum_by_name(struct eap_softc *sc, 1266 char *class, char *device, char *qualifier) 1267 { 1268 return (sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, class, 1269 device, qualifier)); 1270 } 1271 1272 void 1273 eap1370_set_mixer(struct eap_softc *sc, int a, int d) 1274 { 1275 eap1370_write_codec(sc, a, d); 1276 1277 sc->sc_port[a] = d; 1278 DPRINTFN(1, ("eap1370_mixer_set_port port 0x%02x = 0x%02x\n", a, d)); 1279 } 1280 1281 int 1282 eap1370_mixer_set_port(void *addr, mixer_ctrl_t *cp) 1283 { 1284 struct eap_softc *sc = addr; 1285 int lval, rval, l, r, la, ra; 1286 int l1, r1, l2, r2, m, o1, o2; 1287 1288 if (cp->dev == EAP_RECORD_SOURCE) { 1289 if (cp->type != AUDIO_MIXER_SET) 1290 return (EINVAL); 1291 m = sc->sc_record_source = cp->un.mask; 1292 l1 = l2 = r1 = r2 = 0; 1293 if (m & (1 << EAP_VOICE_VOL)) 1294 l2 |= AK_M_VOICE, r2 |= AK_M_VOICE; 1295 if (m & (1 << EAP_FM_VOL)) 1296 l1 |= AK_M_FM_L, r1 |= AK_M_FM_R; 1297 if (m & (1 << EAP_CD_VOL)) 1298 l1 |= AK_M_CD_L, r1 |= AK_M_CD_R; 1299 if (m & (1 << EAP_LINE_VOL)) 1300 l1 |= AK_M_LINE_L, r1 |= AK_M_LINE_R; 1301 if (m & (1 << EAP_AUX_VOL)) 1302 l2 |= AK_M2_AUX_L, r2 |= AK_M2_AUX_R; 1303 if (m & (1 << EAP_MIC_VOL)) 1304 l2 |= AK_M_TMIC, r2 |= AK_M_TMIC; 1305 eap1370_set_mixer(sc, AK_IN_MIXER1_L, l1); 1306 eap1370_set_mixer(sc, AK_IN_MIXER1_R, r1); 1307 eap1370_set_mixer(sc, AK_IN_MIXER2_L, l2); 1308 eap1370_set_mixer(sc, AK_IN_MIXER2_R, r2); 1309 return (0); 1310 } 1311 if (cp->dev == EAP_OUTPUT_SELECT) { 1312 if (cp->type != AUDIO_MIXER_SET) 1313 return (EINVAL); 1314 m = sc->sc_output_source = cp->un.mask; 1315 o1 = o2 = 0; 1316 if (m & (1 << EAP_VOICE_VOL)) 1317 o2 |= AK_M_VOICE_L | AK_M_VOICE_R; 1318 if (m & (1 << EAP_FM_VOL)) 1319 o1 |= AK_M_FM_L | AK_M_FM_R; 1320 if (m & (1 << EAP_CD_VOL)) 1321 o1 |= AK_M_CD_L | AK_M_CD_R; 1322 if (m & (1 << EAP_LINE_VOL)) 1323 o1 |= AK_M_LINE_L | AK_M_LINE_R; 1324 if (m & (1 << EAP_AUX_VOL)) 1325 o2 |= AK_M_AUX_L | AK_M_AUX_R; 1326 if (m & (1 << EAP_MIC_VOL)) 1327 o1 |= AK_M_MIC; 1328 eap1370_set_mixer(sc, AK_OUT_MIXER1, o1); 1329 eap1370_set_mixer(sc, AK_OUT_MIXER2, o2); 1330 return (0); 1331 } 1332 if (cp->dev == EAP_MIC_PREAMP) { 1333 if (cp->type != AUDIO_MIXER_ENUM) 1334 return (EINVAL); 1335 if (cp->un.ord != 0 && cp->un.ord != 1) 1336 return (EINVAL); 1337 sc->sc_mic_preamp = cp->un.ord; 1338 eap1370_set_mixer(sc, AK_MGAIN, cp->un.ord); 1339 return (0); 1340 } 1341 if (cp->type != AUDIO_MIXER_VALUE) 1342 return (EINVAL); 1343 if (cp->un.value.num_channels == 1) 1344 lval = rval = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 1345 else if (cp->un.value.num_channels == 2) { 1346 lval = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1347 rval = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1348 } else 1349 return (EINVAL); 1350 ra = -1; 1351 switch (cp->dev) { 1352 case EAP_MASTER_VOL: 1353 l = VOL_TO_ATT5(lval); 1354 r = VOL_TO_ATT5(rval); 1355 la = AK_MASTER_L; 1356 ra = AK_MASTER_R; 1357 break; 1358 case EAP_MIC_VOL: 1359 if (cp->un.value.num_channels != 1) 1360 return (EINVAL); 1361 la = AK_MIC; 1362 goto lr; 1363 case EAP_VOICE_VOL: 1364 la = AK_VOICE_L; 1365 ra = AK_VOICE_R; 1366 goto lr; 1367 case EAP_FM_VOL: 1368 la = AK_FM_L; 1369 ra = AK_FM_R; 1370 goto lr; 1371 case EAP_CD_VOL: 1372 la = AK_CD_L; 1373 ra = AK_CD_R; 1374 goto lr; 1375 case EAP_LINE_VOL: 1376 la = AK_LINE_L; 1377 ra = AK_LINE_R; 1378 goto lr; 1379 case EAP_AUX_VOL: 1380 la = AK_AUX_L; 1381 ra = AK_AUX_R; 1382 lr: 1383 l = VOL_TO_GAIN5(lval); 1384 r = VOL_TO_GAIN5(rval); 1385 break; 1386 default: 1387 return (EINVAL); 1388 } 1389 eap1370_set_mixer(sc, la, l); 1390 if (ra >= 0) { 1391 eap1370_set_mixer(sc, ra, r); 1392 } 1393 return (0); 1394 } 1395 1396 int 1397 eap1370_mixer_get_port(void *addr, mixer_ctrl_t *cp) 1398 { 1399 struct eap_softc *sc = addr; 1400 int la, ra, l, r; 1401 1402 switch (cp->dev) { 1403 case EAP_RECORD_SOURCE: 1404 if (cp->type != AUDIO_MIXER_SET) 1405 return (EINVAL); 1406 cp->un.mask = sc->sc_record_source; 1407 return (0); 1408 case EAP_OUTPUT_SELECT: 1409 if (cp->type != AUDIO_MIXER_SET) 1410 return (EINVAL); 1411 cp->un.mask = sc->sc_output_source; 1412 return (0); 1413 case EAP_MIC_PREAMP: 1414 if (cp->type != AUDIO_MIXER_ENUM) 1415 return (EINVAL); 1416 cp->un.ord = sc->sc_mic_preamp; 1417 return (0); 1418 case EAP_MASTER_VOL: 1419 l = ATT5_TO_VOL(sc->sc_port[AK_MASTER_L]); 1420 r = ATT5_TO_VOL(sc->sc_port[AK_MASTER_R]); 1421 break; 1422 case EAP_MIC_VOL: 1423 if (cp->un.value.num_channels != 1) 1424 return (EINVAL); 1425 la = ra = AK_MIC; 1426 goto lr; 1427 case EAP_VOICE_VOL: 1428 la = AK_VOICE_L; 1429 ra = AK_VOICE_R; 1430 goto lr; 1431 case EAP_FM_VOL: 1432 la = AK_FM_L; 1433 ra = AK_FM_R; 1434 goto lr; 1435 case EAP_CD_VOL: 1436 la = AK_CD_L; 1437 ra = AK_CD_R; 1438 goto lr; 1439 case EAP_LINE_VOL: 1440 la = AK_LINE_L; 1441 ra = AK_LINE_R; 1442 goto lr; 1443 case EAP_AUX_VOL: 1444 la = AK_AUX_L; 1445 ra = AK_AUX_R; 1446 lr: 1447 l = GAIN5_TO_VOL(sc->sc_port[la]); 1448 r = GAIN5_TO_VOL(sc->sc_port[ra]); 1449 break; 1450 default: 1451 return (EINVAL); 1452 } 1453 if (cp->un.value.num_channels == 1) 1454 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r) / 2; 1455 else if (cp->un.value.num_channels == 2) { 1456 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l; 1457 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r; 1458 } else 1459 return (EINVAL); 1460 return (0); 1461 } 1462 1463 int 1464 eap1370_query_devinfo(void *addr, mixer_devinfo_t *dip) 1465 { 1466 switch (dip->index) { 1467 case EAP_MASTER_VOL: 1468 dip->type = AUDIO_MIXER_VALUE; 1469 dip->mixer_class = EAP_OUTPUT_CLASS; 1470 dip->prev = dip->next = AUDIO_MIXER_LAST; 1471 strcpy(dip->label.name, AudioNmaster); 1472 dip->un.v.num_channels = 2; 1473 strcpy(dip->un.v.units.name, AudioNvolume); 1474 return (0); 1475 case EAP_VOICE_VOL: 1476 dip->type = AUDIO_MIXER_VALUE; 1477 dip->mixer_class = EAP_INPUT_CLASS; 1478 dip->prev = AUDIO_MIXER_LAST; 1479 dip->next = AUDIO_MIXER_LAST; 1480 strcpy(dip->label.name, AudioNdac); 1481 dip->un.v.num_channels = 2; 1482 strcpy(dip->un.v.units.name, AudioNvolume); 1483 return (0); 1484 case EAP_FM_VOL: 1485 dip->type = AUDIO_MIXER_VALUE; 1486 dip->mixer_class = EAP_INPUT_CLASS; 1487 dip->prev = AUDIO_MIXER_LAST; 1488 dip->next = AUDIO_MIXER_LAST; 1489 strcpy(dip->label.name, AudioNfmsynth); 1490 dip->un.v.num_channels = 2; 1491 strcpy(dip->un.v.units.name, AudioNvolume); 1492 return (0); 1493 case EAP_CD_VOL: 1494 dip->type = AUDIO_MIXER_VALUE; 1495 dip->mixer_class = EAP_INPUT_CLASS; 1496 dip->prev = AUDIO_MIXER_LAST; 1497 dip->next = AUDIO_MIXER_LAST; 1498 strcpy(dip->label.name, AudioNcd); 1499 dip->un.v.num_channels = 2; 1500 strcpy(dip->un.v.units.name, AudioNvolume); 1501 return (0); 1502 case EAP_LINE_VOL: 1503 dip->type = AUDIO_MIXER_VALUE; 1504 dip->mixer_class = EAP_INPUT_CLASS; 1505 dip->prev = AUDIO_MIXER_LAST; 1506 dip->next = AUDIO_MIXER_LAST; 1507 strcpy(dip->label.name, AudioNline); 1508 dip->un.v.num_channels = 2; 1509 strcpy(dip->un.v.units.name, AudioNvolume); 1510 return (0); 1511 case EAP_AUX_VOL: 1512 dip->type = AUDIO_MIXER_VALUE; 1513 dip->mixer_class = EAP_INPUT_CLASS; 1514 dip->prev = AUDIO_MIXER_LAST; 1515 dip->next = AUDIO_MIXER_LAST; 1516 strcpy(dip->label.name, AudioNaux); 1517 dip->un.v.num_channels = 2; 1518 strcpy(dip->un.v.units.name, AudioNvolume); 1519 return (0); 1520 case EAP_MIC_VOL: 1521 dip->type = AUDIO_MIXER_VALUE; 1522 dip->mixer_class = EAP_INPUT_CLASS; 1523 dip->prev = AUDIO_MIXER_LAST; 1524 dip->next = EAP_MIC_PREAMP; 1525 strcpy(dip->label.name, AudioNmicrophone); 1526 dip->un.v.num_channels = 1; 1527 strcpy(dip->un.v.units.name, AudioNvolume); 1528 return (0); 1529 case EAP_RECORD_SOURCE: 1530 dip->mixer_class = EAP_RECORD_CLASS; 1531 dip->prev = dip->next = AUDIO_MIXER_LAST; 1532 strcpy(dip->label.name, AudioNsource); 1533 dip->type = AUDIO_MIXER_SET; 1534 dip->un.s.num_mem = 6; 1535 strcpy(dip->un.s.member[0].label.name, AudioNmicrophone); 1536 dip->un.s.member[0].mask = 1 << EAP_MIC_VOL; 1537 strcpy(dip->un.s.member[1].label.name, AudioNcd); 1538 dip->un.s.member[1].mask = 1 << EAP_CD_VOL; 1539 strcpy(dip->un.s.member[2].label.name, AudioNline); 1540 dip->un.s.member[2].mask = 1 << EAP_LINE_VOL; 1541 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth); 1542 dip->un.s.member[3].mask = 1 << EAP_FM_VOL; 1543 strcpy(dip->un.s.member[4].label.name, AudioNaux); 1544 dip->un.s.member[4].mask = 1 << EAP_AUX_VOL; 1545 strcpy(dip->un.s.member[5].label.name, AudioNdac); 1546 dip->un.s.member[5].mask = 1 << EAP_VOICE_VOL; 1547 return (0); 1548 case EAP_OUTPUT_SELECT: 1549 dip->mixer_class = EAP_OUTPUT_CLASS; 1550 dip->prev = dip->next = AUDIO_MIXER_LAST; 1551 strcpy(dip->label.name, AudioNselect); 1552 dip->type = AUDIO_MIXER_SET; 1553 dip->un.s.num_mem = 6; 1554 strcpy(dip->un.s.member[0].label.name, AudioNmicrophone); 1555 dip->un.s.member[0].mask = 1 << EAP_MIC_VOL; 1556 strcpy(dip->un.s.member[1].label.name, AudioNcd); 1557 dip->un.s.member[1].mask = 1 << EAP_CD_VOL; 1558 strcpy(dip->un.s.member[2].label.name, AudioNline); 1559 dip->un.s.member[2].mask = 1 << EAP_LINE_VOL; 1560 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth); 1561 dip->un.s.member[3].mask = 1 << EAP_FM_VOL; 1562 strcpy(dip->un.s.member[4].label.name, AudioNaux); 1563 dip->un.s.member[4].mask = 1 << EAP_AUX_VOL; 1564 strcpy(dip->un.s.member[5].label.name, AudioNdac); 1565 dip->un.s.member[5].mask = 1 << EAP_VOICE_VOL; 1566 return (0); 1567 case EAP_MIC_PREAMP: 1568 dip->type = AUDIO_MIXER_ENUM; 1569 dip->mixer_class = EAP_INPUT_CLASS; 1570 dip->prev = EAP_MIC_VOL; 1571 dip->next = AUDIO_MIXER_LAST; 1572 strcpy(dip->label.name, AudioNpreamp); 1573 dip->un.e.num_mem = 2; 1574 strcpy(dip->un.e.member[0].label.name, AudioNoff); 1575 dip->un.e.member[0].ord = 0; 1576 strcpy(dip->un.e.member[1].label.name, AudioNon); 1577 dip->un.e.member[1].ord = 1; 1578 return (0); 1579 case EAP_OUTPUT_CLASS: 1580 dip->type = AUDIO_MIXER_CLASS; 1581 dip->mixer_class = EAP_OUTPUT_CLASS; 1582 dip->next = dip->prev = AUDIO_MIXER_LAST; 1583 strcpy(dip->label.name, AudioCoutputs); 1584 return (0); 1585 case EAP_RECORD_CLASS: 1586 dip->type = AUDIO_MIXER_CLASS; 1587 dip->mixer_class = EAP_RECORD_CLASS; 1588 dip->next = dip->prev = AUDIO_MIXER_LAST; 1589 strcpy(dip->label.name, AudioCrecord); 1590 return (0); 1591 case EAP_INPUT_CLASS: 1592 dip->type = AUDIO_MIXER_CLASS; 1593 dip->mixer_class = EAP_INPUT_CLASS; 1594 dip->next = dip->prev = AUDIO_MIXER_LAST; 1595 strcpy(dip->label.name, AudioCinputs); 1596 return (0); 1597 } 1598 return (ENXIO); 1599 } 1600 1601 void * 1602 eap_malloc(void *addr, int direction, size_t size, int pool, int flags) 1603 { 1604 struct eap_softc *sc = addr; 1605 struct eap_dma *p; 1606 int error; 1607 1608 p = malloc(sizeof(*p), pool, flags); 1609 if (!p) 1610 return (0); 1611 error = eap_allocmem(sc, size, 16, p); 1612 if (error) { 1613 free(p, pool); 1614 return (0); 1615 } 1616 p->next = sc->sc_dmas; 1617 sc->sc_dmas = p; 1618 return (KERNADDR(p)); 1619 } 1620 1621 void 1622 eap_free(void *addr, void *ptr, int pool) 1623 { 1624 struct eap_softc *sc = addr; 1625 struct eap_dma **pp, *p; 1626 1627 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 1628 if (KERNADDR(p) == ptr) { 1629 eap_freemem(sc, p); 1630 *pp = p->next; 1631 free(p, pool); 1632 return; 1633 } 1634 } 1635 } 1636 1637 size_t 1638 eap_round_buffersize(void *addr, int direction, size_t size) 1639 { 1640 return (size); 1641 } 1642 1643 paddr_t 1644 eap_mappage(void *addr, void *mem, off_t off, int prot) 1645 { 1646 struct eap_softc *sc = addr; 1647 struct eap_dma *p; 1648 1649 if (off < 0) 1650 return (-1); 1651 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 1652 ; 1653 if (!p) 1654 return (-1); 1655 return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 1656 off, prot, BUS_DMA_WAITOK)); 1657 } 1658 1659 int 1660 eap_get_props(void *addr) 1661 { 1662 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 1663 AUDIO_PROP_FULLDUPLEX); 1664 } 1665 1666 #if NMIDI > 0 1667 int 1668 eap_midi_open(void *addr, int flags, 1669 void (*iintr)(void *, int), 1670 void (*ointr)(void *), 1671 void *arg) 1672 { 1673 struct eap_softc *sc = addr; 1674 u_int32_t uctrl; 1675 1676 sc->sc_iintr = iintr; 1677 sc->sc_ointr = ointr; 1678 sc->sc_arg = arg; 1679 1680 EWRITE4(sc, EAP_ICSC, EREAD4(sc, EAP_ICSC) | EAP_UART_EN); 1681 uctrl = 0; 1682 if (flags & FREAD) 1683 uctrl |= EAP_UC_RXINTEN; 1684 #if 0 1685 /* I don't understand ../midi.c well enough to use output interrupts */ 1686 if (flags & FWRITE) 1687 uctrl |= EAP_UC_TXINTEN; */ 1688 #endif 1689 EWRITE1(sc, EAP_UART_CONTROL, uctrl); 1690 1691 return (0); 1692 } 1693 1694 void 1695 eap_midi_close(void *addr) 1696 { 1697 struct eap_softc *sc = addr; 1698 1699 tsleep(sc, PWAIT, "eapclm", hz/10); /* give uart a chance to drain */ 1700 EWRITE1(sc, EAP_UART_CONTROL, 0); 1701 EWRITE4(sc, EAP_ICSC, EREAD4(sc, EAP_ICSC) & ~EAP_UART_EN); 1702 1703 sc->sc_iintr = 0; 1704 sc->sc_ointr = 0; 1705 } 1706 1707 int 1708 eap_midi_output(void *addr, int d) 1709 { 1710 struct eap_softc *sc = addr; 1711 int x; 1712 1713 for (x = 0; x != MIDI_BUSY_WAIT; x++) { 1714 if (EREAD1(sc, EAP_UART_STATUS) & EAP_US_TXRDY) { 1715 EWRITE1(sc, EAP_UART_DATA, d); 1716 return (0); 1717 } 1718 delay(MIDI_BUSY_DELAY); 1719 } 1720 return (EIO); 1721 } 1722 1723 void 1724 eap_midi_getinfo(void *addr, struct midi_info *mi) 1725 { 1726 mi->name = "AudioPCI MIDI UART"; 1727 mi->props = MIDI_PROP_CAN_INPUT; 1728 } 1729 1730 #endif 1731