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