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