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