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