1 /* $NetBSD: auich.c,v 1.36 2003/02/01 06:23:38 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (c) 2000 Michael Shalayeff 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. The name of the author may not be used to endorse or promote products 52 * derived from this software without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 60 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 62 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 63 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 64 * THE POSSIBILITY OF SUCH DAMAGE. 65 * 66 * from OpenBSD: ich.c,v 1.3 2000/08/11 06:17:18 mickey Exp 67 */ 68 69 /* 70 * Copyright (c) 2000 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp> 71 * Copyright (c) 2001 Cameron Grant <cg@freebsd.org> 72 * All rights reserved. 73 * 74 * Redistribution and use in source and binary forms, with or without 75 * modification, are permitted provided that the following conditions 76 * are met: 77 * 1. Redistributions of source code must retain the above copyright 78 * notice, this list of conditions and the following disclaimer. 79 * 2. Redistributions in binary form must reproduce the above copyright 80 * notice, this list of conditions and the following disclaimer in the 81 * documentation and/or other materials provided with the distribution. 82 * 83 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 84 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 85 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 86 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 87 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 88 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 89 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 90 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 91 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 92 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 93 * SUCH DAMAGE. 94 * 95 * auich_calibrate() was from FreeBSD: ich.c,v 1.22 2002/06/27 22:36:01 scottl Exp 96 */ 97 98 99 /* #define ICH_DEBUG */ 100 /* 101 * AC'97 audio found on Intel 810/820/440MX chipsets. 102 * http://developer.intel.com/design/chipsets/datashts/290655.htm 103 * http://developer.intel.com/design/chipsets/manuals/298028.htm 104 * ICH3:http://www.intel.com/design/chipsets/datashts/290716.htm 105 * ICH4:http://www.intel.com/design/chipsets/datashts/290744.htm 106 * 107 * TODO: 108 * - Add support for the dedicated microphone input. 109 * - 4ch/6ch support. 110 * 111 * NOTE: 112 * - The 440MX B-stepping at running 100MHz has a hardware erratum. 113 * It causes PCI master abort and hangups until cold reboot. 114 * http://www.intel.com/design/chipsets/specupdt/245051.htm 115 */ 116 117 #include <sys/cdefs.h> 118 __KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.36 2003/02/01 06:23:38 thorpej Exp $"); 119 120 #include <sys/param.h> 121 #include <sys/systm.h> 122 #include <sys/kernel.h> 123 #include <sys/malloc.h> 124 #include <sys/device.h> 125 #include <sys/fcntl.h> 126 #include <sys/proc.h> 127 128 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 129 130 #include <dev/pci/pcidevs.h> 131 #include <dev/pci/pcivar.h> 132 #include <dev/pci/auichreg.h> 133 134 #include <sys/audioio.h> 135 #include <dev/audio_if.h> 136 #include <dev/mulaw.h> 137 #include <dev/auconv.h> 138 139 #include <machine/bus.h> 140 141 #include <dev/ic/ac97reg.h> 142 #include <dev/ic/ac97var.h> 143 144 struct auich_dma { 145 bus_dmamap_t map; 146 caddr_t addr; 147 bus_dma_segment_t segs[1]; 148 int nsegs; 149 size_t size; 150 struct auich_dma *next; 151 }; 152 153 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 154 #define KERNADDR(p) ((void *)((p)->addr)) 155 156 struct auich_cdata { 157 struct auich_dmalist ic_dmalist_pcmo[ICH_DMALIST_MAX]; 158 struct auich_dmalist ic_dmalist_pcmi[ICH_DMALIST_MAX]; 159 struct auich_dmalist ic_dmalist_mici[ICH_DMALIST_MAX]; 160 }; 161 162 #define ICH_CDOFF(x) offsetof(struct auich_cdata, x) 163 #define ICH_PCMO_OFF(x) ICH_CDOFF(ic_dmalist_pcmo[(x)]) 164 #define ICH_PCMI_OFF(x) ICH_CDOFF(ic_dmalist_pcmi[(x)]) 165 #define ICH_MICI_OFF(x) ICH_CDOFF(ic_dmalist_mici[(x)]) 166 167 struct auich_softc { 168 struct device sc_dev; 169 void *sc_ih; 170 171 audio_device_t sc_audev; 172 173 bus_space_tag_t iot; 174 bus_space_handle_t mix_ioh; 175 bus_space_handle_t aud_ioh; 176 bus_dma_tag_t dmat; 177 178 struct ac97_codec_if *codec_if; 179 struct ac97_host_if host_if; 180 181 /* DMA scatter-gather lists. */ 182 bus_dmamap_t sc_cddmamap; 183 #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 184 185 struct auich_cdata *sc_cdata; 186 #define dmalist_pcmo sc_cdata->ic_dmalist_pcmo 187 #define dmalist_pcmi sc_cdata->ic_dmalist_pcmi 188 #define dmalist_mici sc_cdata->ic_dmalist_mici 189 190 int ptr_pcmo, 191 ptr_pcmi, 192 ptr_mici; 193 194 /* i/o buffer pointers */ 195 u_int32_t pcmo_start, pcmo_p, pcmo_end; 196 int pcmo_blksize, pcmo_fifoe; 197 198 u_int32_t pcmi_start, pcmi_p, pcmi_end; 199 int pcmi_blksize, pcmi_fifoe; 200 201 u_int32_t mici_start, mici_p, mici_end; 202 int mici_blksize, mici_fifoe; 203 204 struct auich_dma *sc_dmas; 205 206 #ifdef DIAGNOSTIC 207 pci_chipset_tag_t sc_pc; 208 pcitag_t sc_pt; 209 #endif 210 int sc_ignore_codecready; 211 /* SiS 7012 hack */ 212 int sc_sample_size; 213 int sc_sts_reg; 214 /* 440MX workaround */ 215 int sc_dmamap_flags; 216 217 void (*sc_pintr)(void *); 218 void *sc_parg; 219 220 void (*sc_rintr)(void *); 221 void *sc_rarg; 222 223 /* Power Management */ 224 void *sc_powerhook; 225 int sc_suspend; 226 u_int16_t ext_status; 227 }; 228 229 #define IS_FIXED_RATE(codec) !((codec)->vtbl->get_extcaps(codec) \ 230 & AC97_EXT_AUDIO_VRA) 231 232 /* Debug */ 233 #ifdef AUDIO_DEBUG 234 #define DPRINTF(l,x) do { if (auich_debug & (l)) printf x; } while(0) 235 int auich_debug = 0xfffe; 236 #define ICH_DEBUG_CODECIO 0x0001 237 #define ICH_DEBUG_DMA 0x0002 238 #define ICH_DEBUG_PARAM 0x0004 239 #else 240 #define DPRINTF(x,y) /* nothing */ 241 #endif 242 243 int auich_match(struct device *, struct cfdata *, void *); 244 void auich_attach(struct device *, struct device *, void *); 245 int auich_intr(void *); 246 247 CFATTACH_DECL(auich, sizeof(struct auich_softc), 248 auich_match, auich_attach, NULL, NULL); 249 250 int auich_open(void *, int); 251 void auich_close(void *); 252 int auich_query_encoding(void *, struct audio_encoding *); 253 int auich_set_params(void *, int, int, struct audio_params *, 254 struct audio_params *); 255 int auich_round_blocksize(void *, int); 256 int auich_halt_output(void *); 257 int auich_halt_input(void *); 258 int auich_getdev(void *, struct audio_device *); 259 int auich_set_port(void *, mixer_ctrl_t *); 260 int auich_get_port(void *, mixer_ctrl_t *); 261 int auich_query_devinfo(void *, mixer_devinfo_t *); 262 void *auich_allocm(void *, int, size_t, struct malloc_type *, int); 263 void auich_freem(void *, void *, struct malloc_type *); 264 size_t auich_round_buffersize(void *, int, size_t); 265 paddr_t auich_mappage(void *, void *, off_t, int); 266 int auich_get_props(void *); 267 int auich_trigger_output(void *, void *, void *, int, void (*)(void *), 268 void *, struct audio_params *); 269 int auich_trigger_input(void *, void *, void *, int, void (*)(void *), 270 void *, struct audio_params *); 271 272 int auich_alloc_cdata(struct auich_softc *); 273 274 int auich_allocmem(struct auich_softc *, size_t, size_t, 275 struct auich_dma *); 276 int auich_freemem(struct auich_softc *, struct auich_dma *); 277 278 void auich_powerhook(int, void *); 279 int auich_set_rate(struct auich_softc *, int, u_long); 280 void auich_calibrate(struct device *); 281 282 283 struct audio_hw_if auich_hw_if = { 284 auich_open, 285 auich_close, 286 NULL, /* drain */ 287 auich_query_encoding, 288 auich_set_params, 289 auich_round_blocksize, 290 NULL, /* commit_setting */ 291 NULL, /* init_output */ 292 NULL, /* init_input */ 293 NULL, /* start_output */ 294 NULL, /* start_input */ 295 auich_halt_output, 296 auich_halt_input, 297 NULL, /* speaker_ctl */ 298 auich_getdev, 299 NULL, /* getfd */ 300 auich_set_port, 301 auich_get_port, 302 auich_query_devinfo, 303 auich_allocm, 304 auich_freem, 305 auich_round_buffersize, 306 auich_mappage, 307 auich_get_props, 308 auich_trigger_output, 309 auich_trigger_input, 310 NULL, /* dev_ioctl */ 311 }; 312 313 int auich_attach_codec(void *, struct ac97_codec_if *); 314 int auich_read_codec(void *, u_int8_t, u_int16_t *); 315 int auich_write_codec(void *, u_int8_t, u_int16_t); 316 void auich_reset_codec(void *); 317 318 static const struct auich_devtype { 319 int vendor; 320 int product; 321 const char *name; 322 const char *shortname; 323 } auich_devices[] = { 324 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_ACA, 325 "i82801AA (ICH) AC-97 Audio", "ICH" }, 326 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_ACA, 327 "i82801AB (ICH0) AC-97 Audio", "ICH0" }, /* i810-L */ 328 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_ACA, 329 "i82801BA (ICH2) AC-97 Audio", "ICH2" }, 330 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440MX_ACA, 331 "i82440MX AC-97 Audio", "440MX" }, 332 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_AC, 333 "i82801CA (ICH3) AC-97 Audio", "ICH3" }, /* i830Mx i845MP/MZ*/ 334 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_AC, 335 "i82801DB (ICH4) AC-97 Audio", "ICH4" }, /* i845E i845Gx */ 336 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_7012_AC, 337 "SiS 7012 AC-97 Audio", "SiS7012" }, 338 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE_MCP_AC, 339 "nForce MCP AC-97 Audio", "nForce-MCP" }, 340 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE2_MCPT_AC, 341 "nForce2 MCP-T AC-97 Audio", "nForce-MCP-T" }, 342 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC768_AC, 343 "AMD768 AC-97 Audio", "AMD768" }, 344 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC8111_AC, 345 "AMD8111 AC-97 Audio", "AMD8111" }, 346 { 0, 347 NULL, NULL }, 348 }; 349 350 static const struct auich_devtype * 351 auich_lookup(struct pci_attach_args *pa) 352 { 353 const struct auich_devtype *d; 354 355 for (d = auich_devices; d->name != NULL; d++) { 356 if (PCI_VENDOR(pa->pa_id) == d->vendor 357 && PCI_PRODUCT(pa->pa_id) == d->product) 358 return (d); 359 } 360 361 return (NULL); 362 } 363 364 int 365 auich_match(struct device *parent, struct cfdata *match, void *aux) 366 { 367 struct pci_attach_args *pa = aux; 368 369 if (auich_lookup(pa) != NULL) 370 return (1); 371 372 return (0); 373 } 374 375 void 376 auich_attach(struct device *parent, struct device *self, void *aux) 377 { 378 struct auich_softc *sc = (struct auich_softc *)self; 379 struct pci_attach_args *pa = aux; 380 pci_intr_handle_t ih; 381 bus_size_t mix_size, aud_size; 382 pcireg_t csr; 383 const char *intrstr; 384 const struct auich_devtype *d; 385 u_int32_t status; 386 387 aprint_naive(": Audio controller\n"); 388 389 d = auich_lookup(pa); 390 if (d == NULL) 391 panic("auich_attach: impossible"); 392 393 #ifdef DIAGNOSTIC 394 sc->sc_pc = pa->pa_pc; 395 sc->sc_pt = pa->pa_tag; 396 #endif 397 398 aprint_normal(": %s\n", d->name); 399 400 if (pci_mapreg_map(pa, ICH_NAMBAR, PCI_MAPREG_TYPE_IO, 0, 401 &sc->iot, &sc->mix_ioh, NULL, &mix_size)) { 402 aprint_error("%s: can't map codec i/o space\n", 403 sc->sc_dev.dv_xname); 404 return; 405 } 406 if (pci_mapreg_map(pa, ICH_NABMBAR, PCI_MAPREG_TYPE_IO, 0, 407 &sc->iot, &sc->aud_ioh, NULL, &aud_size)) { 408 aprint_error("%s: can't map device i/o space\n", 409 sc->sc_dev.dv_xname); 410 return; 411 } 412 sc->dmat = pa->pa_dmat; 413 414 /* enable bus mastering */ 415 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 416 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 417 csr | PCI_COMMAND_MASTER_ENABLE); 418 419 /* Map and establish the interrupt. */ 420 if (pci_intr_map(pa, &ih)) { 421 aprint_error("%s: can't map interrupt\n", sc->sc_dev.dv_xname); 422 return; 423 } 424 intrstr = pci_intr_string(pa->pa_pc, ih); 425 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, 426 auich_intr, sc); 427 if (sc->sc_ih == NULL) { 428 aprint_error("%s: can't establish interrupt", 429 sc->sc_dev.dv_xname); 430 if (intrstr != NULL) 431 aprint_normal(" at %s", intrstr); 432 aprint_normal("\n"); 433 return; 434 } 435 aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); 436 437 sprintf(sc->sc_audev.name, "%s AC97", d->shortname); 438 sprintf(sc->sc_audev.version, "0x%02x", PCI_REVISION(pa->pa_class)); 439 strcpy(sc->sc_audev.config, sc->sc_dev.dv_xname); 440 441 /* SiS 7012 needs special handling */ 442 if (d->vendor == PCI_VENDOR_SIS 443 && d->product == PCI_PRODUCT_SIS_7012_AC) { 444 sc->sc_sts_reg = ICH_PICB; 445 sc->sc_sample_size = 1; 446 } else { 447 sc->sc_sts_reg = ICH_STS; 448 sc->sc_sample_size = 2; 449 } 450 /* nForce MCP quirk */ 451 if (d->vendor == PCI_VENDOR_NVIDIA 452 && d->product == PCI_PRODUCT_NVIDIA_NFORCE_MCP_AC) { 453 sc->sc_ignore_codecready = TRUE; 454 } 455 /* Workaround for a 440MX B-stepping erratum */ 456 sc->sc_dmamap_flags = BUS_DMA_COHERENT; 457 if (d->vendor == PCI_VENDOR_INTEL 458 && d->product == PCI_PRODUCT_INTEL_82440MX_ACA) { 459 sc->sc_dmamap_flags |= BUS_DMA_NOCACHE; 460 printf("%s: DMA bug workaround enabled\n", sc->sc_dev.dv_xname); 461 } 462 463 /* Set up DMA lists. */ 464 sc->ptr_pcmo = sc->ptr_pcmi = sc->ptr_mici = 0; 465 auich_alloc_cdata(sc); 466 467 DPRINTF(ICH_DEBUG_DMA, ("auich_attach: lists %p %p %p\n", 468 sc->dmalist_pcmo, sc->dmalist_pcmi, sc->dmalist_mici)); 469 470 /* Reset codec and AC'97 */ 471 auich_reset_codec(sc); 472 status = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GSTS); 473 if (!(status & ICH_PCR)) { /* reset failure */ 474 if (d->vendor == PCI_VENDOR_INTEL 475 && d->product == PCI_PRODUCT_INTEL_82801DB_AC) { 476 /* MSI 845G Max never return ICH_PCR */ 477 sc->sc_ignore_codecready = TRUE; 478 } else { 479 return; 480 } 481 } 482 /* Print capabilities though there are no supports for now */ 483 if ((status & ICH_SAMPLE_CAP) == ICH_POM20) 484 aprint_normal("%s: 20 bit precision support\n", 485 sc->sc_dev.dv_xname); 486 if ((status & ICH_CHAN_CAP) == ICH_PCM4) 487 aprint_normal("%s: 4ch PCM output support\n", 488 sc->sc_dev.dv_xname); 489 if ((status & ICH_CHAN_CAP) == ICH_PCM6) 490 aprint_normal("%s: 6ch PCM output support\n", 491 sc->sc_dev.dv_xname); 492 493 sc->host_if.arg = sc; 494 sc->host_if.attach = auich_attach_codec; 495 sc->host_if.read = auich_read_codec; 496 sc->host_if.write = auich_write_codec; 497 sc->host_if.reset = auich_reset_codec; 498 499 if (ac97_attach(&sc->host_if) != 0) 500 return; 501 502 audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev); 503 504 /* Watch for power change */ 505 sc->sc_suspend = PWR_RESUME; 506 sc->sc_powerhook = powerhook_establish(auich_powerhook, sc); 507 508 if (!IS_FIXED_RATE(sc->codec_if)) { 509 config_interrupts(self, auich_calibrate); 510 } 511 } 512 513 #define ICH_CODECIO_INTERVAL 10 514 int 515 auich_read_codec(void *v, u_int8_t reg, u_int16_t *val) 516 { 517 struct auich_softc *sc = v; 518 int i; 519 uint32_t status; 520 521 status = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GSTS); 522 if (!sc->sc_ignore_codecready && !(status & ICH_PCR)) { 523 printf("auich_read_codec: codec is not ready (0x%x)\n", status); 524 *val = 0xffff; 525 return -1; 526 } 527 /* wait for an access semaphore */ 528 for (i = ICH_SEMATIMO / ICH_CODECIO_INTERVAL; i-- && 529 bus_space_read_1(sc->iot, sc->aud_ioh, ICH_CAS) & 1; 530 DELAY(ICH_CODECIO_INTERVAL)); 531 532 if (i > 0) { 533 *val = bus_space_read_2(sc->iot, sc->mix_ioh, reg); 534 DPRINTF(ICH_DEBUG_CODECIO, 535 ("auich_read_codec(%x, %x)\n", reg, *val)); 536 status = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GSTS); 537 if (status & ICH_RCS) { 538 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_GSTS, 539 status & ~(ICH_SRI|ICH_PRI|ICH_GSCI)); 540 *val = 0xffff; 541 } 542 return 0; 543 } else { 544 DPRINTF(ICH_DEBUG_CODECIO, 545 ("%s: read_codec timeout\n", sc->sc_dev.dv_xname)); 546 return -1; 547 } 548 } 549 550 int 551 auich_write_codec(void *v, u_int8_t reg, u_int16_t val) 552 { 553 struct auich_softc *sc = v; 554 int i; 555 556 DPRINTF(ICH_DEBUG_CODECIO, ("auich_write_codec(%x, %x)\n", reg, val)); 557 if (!sc->sc_ignore_codecready 558 && !(bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GSTS) & ICH_PCR)) { 559 printf("auich_write_codec: codec is not ready."); 560 return -1; 561 } 562 /* wait for an access semaphore */ 563 for (i = ICH_SEMATIMO / ICH_CODECIO_INTERVAL; i-- && 564 bus_space_read_1(sc->iot, sc->aud_ioh, ICH_CAS) & 1; 565 DELAY(ICH_CODECIO_INTERVAL)); 566 567 if (i > 0) { 568 bus_space_write_2(sc->iot, sc->mix_ioh, reg, val); 569 return 0; 570 } else { 571 DPRINTF(ICH_DEBUG_CODECIO, 572 ("%s: write_codec timeout\n", sc->sc_dev.dv_xname)); 573 return -1; 574 } 575 } 576 577 int 578 auich_attach_codec(void *v, struct ac97_codec_if *cif) 579 { 580 struct auich_softc *sc = v; 581 582 sc->codec_if = cif; 583 return 0; 584 } 585 586 void 587 auich_reset_codec(void *v) 588 { 589 struct auich_softc *sc = v; 590 int i; 591 uint32_t control; 592 593 control = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GCTRL); 594 control &= ~(ICH_ACLSO | ICH_PCM246_MASK); 595 control |= (control & ICH_CRESET) ? ICH_WRESET : ICH_CRESET; 596 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_GCTRL, control); 597 598 for (i = 500000; i-- && 599 !(bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GSTS) & ICH_PCR); 600 DELAY(1)); /* or ICH_SCR? */ 601 if (i <= 0) 602 printf("%s: auich_reset_codec: time out\n", sc->sc_dev.dv_xname); 603 } 604 605 int 606 auich_open(void *v, int flags) 607 { 608 return 0; 609 } 610 611 void 612 auich_close(void *v) 613 { 614 struct auich_softc *sc = v; 615 616 auich_halt_output(sc); 617 auich_halt_input(sc); 618 619 sc->sc_pintr = NULL; 620 sc->sc_rintr = NULL; 621 } 622 623 int 624 auich_query_encoding(void *v, struct audio_encoding *aep) 625 { 626 627 switch (aep->index) { 628 case 0: 629 strcpy(aep->name, AudioEulinear); 630 aep->encoding = AUDIO_ENCODING_ULINEAR; 631 aep->precision = 8; 632 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 633 return (0); 634 case 1: 635 strcpy(aep->name, AudioEmulaw); 636 aep->encoding = AUDIO_ENCODING_ULAW; 637 aep->precision = 8; 638 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 639 return (0); 640 case 2: 641 strcpy(aep->name, AudioEalaw); 642 aep->encoding = AUDIO_ENCODING_ALAW; 643 aep->precision = 8; 644 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 645 return (0); 646 case 3: 647 strcpy(aep->name, AudioEslinear); 648 aep->encoding = AUDIO_ENCODING_SLINEAR; 649 aep->precision = 8; 650 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 651 return (0); 652 case 4: 653 strcpy(aep->name, AudioEslinear_le); 654 aep->encoding = AUDIO_ENCODING_SLINEAR_LE; 655 aep->precision = 16; 656 aep->flags = 0; 657 return (0); 658 case 5: 659 strcpy(aep->name, AudioEulinear_le); 660 aep->encoding = AUDIO_ENCODING_ULINEAR_LE; 661 aep->precision = 16; 662 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 663 return (0); 664 case 6: 665 strcpy(aep->name, AudioEslinear_be); 666 aep->encoding = AUDIO_ENCODING_SLINEAR_BE; 667 aep->precision = 16; 668 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 669 return (0); 670 case 7: 671 strcpy(aep->name, AudioEulinear_be); 672 aep->encoding = AUDIO_ENCODING_ULINEAR_BE; 673 aep->precision = 16; 674 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 675 return (0); 676 default: 677 return (EINVAL); 678 } 679 } 680 681 int 682 auich_set_rate(struct auich_softc *sc, int mode, u_long srate) 683 { 684 int reg; 685 u_long ratetmp; 686 687 ratetmp = srate; 688 reg = mode == AUMODE_PLAY 689 ? AC97_REG_PCM_FRONT_DAC_RATE : AC97_REG_PCM_LR_ADC_RATE; 690 return sc->codec_if->vtbl->set_rate(sc->codec_if, reg, &ratetmp); 691 } 692 693 int 694 auich_set_params(void *v, int setmode, int usemode, struct audio_params *play, 695 struct audio_params *rec) 696 { 697 struct auich_softc *sc = v; 698 struct audio_params *p; 699 int mode; 700 701 for (mode = AUMODE_RECORD; mode != -1; 702 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 703 if ((setmode & mode) == 0) 704 continue; 705 706 p = mode == AUMODE_PLAY ? play : rec; 707 if (p == NULL) 708 continue; 709 710 if ((p->sample_rate != 8000) && 711 (p->sample_rate != 11025) && 712 (p->sample_rate != 16000) && 713 (p->sample_rate != 22050) && 714 (p->sample_rate != 32000) && 715 (p->sample_rate != 44100) && 716 (p->sample_rate != 48000)) 717 return (EINVAL); 718 719 p->factor = 1; 720 if (p->precision == 8) 721 p->factor *= 2; 722 723 p->sw_code = NULL; 724 /* setup hardware formats */ 725 p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE; 726 p->hw_precision = 16; 727 728 /* If monaural is requested, aurateconv expands a monaural 729 * stream to stereo. */ 730 if (p->channels < 2) 731 p->hw_channels = 2; 732 733 switch (p->encoding) { 734 case AUDIO_ENCODING_SLINEAR_BE: 735 if (p->precision == 16) { 736 p->sw_code = swap_bytes; 737 } else { 738 if (mode == AUMODE_PLAY) 739 p->sw_code = linear8_to_linear16_le; 740 else 741 p->sw_code = linear16_to_linear8_le; 742 } 743 break; 744 745 case AUDIO_ENCODING_SLINEAR_LE: 746 if (p->precision != 16) { 747 if (mode == AUMODE_PLAY) 748 p->sw_code = linear8_to_linear16_le; 749 else 750 p->sw_code = linear16_to_linear8_le; 751 } 752 break; 753 754 case AUDIO_ENCODING_ULINEAR_BE: 755 if (p->precision == 16) { 756 if (mode == AUMODE_PLAY) 757 p->sw_code = 758 swap_bytes_change_sign16_le; 759 else 760 p->sw_code = 761 change_sign16_swap_bytes_le; 762 } else { 763 if (mode == AUMODE_PLAY) 764 p->sw_code = 765 ulinear8_to_slinear16_le; 766 else 767 p->sw_code = 768 slinear16_to_ulinear8_le; 769 } 770 break; 771 772 case AUDIO_ENCODING_ULINEAR_LE: 773 if (p->precision == 16) { 774 p->sw_code = change_sign16_le; 775 } else { 776 if (mode == AUMODE_PLAY) 777 p->sw_code = 778 ulinear8_to_slinear16_le; 779 else 780 p->sw_code = 781 slinear16_to_ulinear8_le; 782 } 783 break; 784 785 case AUDIO_ENCODING_ULAW: 786 if (mode == AUMODE_PLAY) { 787 p->sw_code = mulaw_to_slinear16_le; 788 } else { 789 p->sw_code = slinear16_to_mulaw_le; 790 } 791 break; 792 793 case AUDIO_ENCODING_ALAW: 794 if (mode == AUMODE_PLAY) { 795 p->sw_code = alaw_to_slinear16_le; 796 } else { 797 p->sw_code = slinear16_to_alaw_le; 798 } 799 break; 800 801 default: 802 return (EINVAL); 803 } 804 805 if (IS_FIXED_RATE(sc->codec_if)) { 806 p->hw_sample_rate = AC97_SINGLE_RATE; 807 /* If hw_sample_rate is changed, aurateconv works. */ 808 } else { 809 if (auich_set_rate(sc, mode, p->sample_rate)) 810 return EINVAL; 811 } 812 } 813 814 return (0); 815 } 816 817 int 818 auich_round_blocksize(void *v, int blk) 819 { 820 821 return (blk & ~0x3f); /* keep good alignment */ 822 } 823 824 int 825 auich_halt_output(void *v) 826 { 827 struct auich_softc *sc = v; 828 829 DPRINTF(ICH_DEBUG_DMA, ("%s: halt_output\n", sc->sc_dev.dv_xname)); 830 831 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CTRL, ICH_RR); 832 833 return (0); 834 } 835 836 int 837 auich_halt_input(void *v) 838 { 839 struct auich_softc *sc = v; 840 841 DPRINTF(ICH_DEBUG_DMA, 842 ("%s: halt_input\n", sc->sc_dev.dv_xname)); 843 844 /* XXX halt both unless known otherwise */ 845 846 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RR); 847 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_MICI + ICH_CTRL, ICH_RR); 848 849 return (0); 850 } 851 852 int 853 auich_getdev(void *v, struct audio_device *adp) 854 { 855 struct auich_softc *sc = v; 856 857 *adp = sc->sc_audev; 858 return (0); 859 } 860 861 int 862 auich_set_port(void *v, mixer_ctrl_t *cp) 863 { 864 struct auich_softc *sc = v; 865 866 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp)); 867 } 868 869 int 870 auich_get_port(void *v, mixer_ctrl_t *cp) 871 { 872 struct auich_softc *sc = v; 873 874 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp)); 875 } 876 877 int 878 auich_query_devinfo(void *v, mixer_devinfo_t *dp) 879 { 880 struct auich_softc *sc = v; 881 882 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dp)); 883 } 884 885 void * 886 auich_allocm(void *v, int direction, size_t size, struct malloc_type *pool, 887 int flags) 888 { 889 struct auich_softc *sc = v; 890 struct auich_dma *p; 891 int error; 892 893 if (size > (ICH_DMALIST_MAX * ICH_DMASEG_MAX)) 894 return (NULL); 895 896 p = malloc(sizeof(*p), pool, flags|M_ZERO); 897 if (p == NULL) 898 return (NULL); 899 900 error = auich_allocmem(sc, size, 0, p); 901 if (error) { 902 free(p, pool); 903 return (NULL); 904 } 905 906 p->next = sc->sc_dmas; 907 sc->sc_dmas = p; 908 909 return (KERNADDR(p)); 910 } 911 912 void 913 auich_freem(void *v, void *ptr, struct malloc_type *pool) 914 { 915 struct auich_softc *sc = v; 916 struct auich_dma *p, **pp; 917 918 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 919 if (KERNADDR(p) == ptr) { 920 auich_freemem(sc, p); 921 *pp = p->next; 922 free(p, pool); 923 return; 924 } 925 } 926 } 927 928 size_t 929 auich_round_buffersize(void *v, int direction, size_t size) 930 { 931 932 if (size > (ICH_DMALIST_MAX * ICH_DMASEG_MAX)) 933 size = ICH_DMALIST_MAX * ICH_DMASEG_MAX; 934 935 return size; 936 } 937 938 paddr_t 939 auich_mappage(void *v, void *mem, off_t off, int prot) 940 { 941 struct auich_softc *sc = v; 942 struct auich_dma *p; 943 944 if (off < 0) 945 return (-1); 946 947 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 948 ; 949 if (!p) 950 return (-1); 951 return (bus_dmamem_mmap(sc->dmat, p->segs, p->nsegs, 952 off, prot, BUS_DMA_WAITOK)); 953 } 954 955 int 956 auich_get_props(void *v) 957 { 958 struct auich_softc *sc = v; 959 int props; 960 961 props = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 962 /* 963 * Even if the codec is fixed-rate, set_param() succeeds for any sample 964 * rate because of aurateconv. Applications can't know what rate the 965 * device can process in the case of mmap(). 966 */ 967 if (!IS_FIXED_RATE(sc->codec_if)) 968 props |= AUDIO_PROP_MMAP; 969 return props; 970 } 971 972 int 973 auich_intr(void *v) 974 { 975 struct auich_softc *sc = v; 976 int ret = 0, sts, gsts, i, qptr; 977 978 #ifdef DIAGNOSTIC 979 int csts; 980 #endif 981 982 #ifdef DIAGNOSTIC 983 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 984 if (csts & PCI_STATUS_MASTER_ABORT) { 985 printf("auich_intr: PCI master abort\n"); 986 } 987 #endif 988 989 gsts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_GSTS); 990 DPRINTF(ICH_DEBUG_DMA, ("auich_intr: gsts=0x%x\n", gsts)); 991 992 if (gsts & ICH_POINT) { 993 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_PCMO+sc->sc_sts_reg); 994 DPRINTF(ICH_DEBUG_DMA, 995 ("auich_intr: osts=0x%x\n", sts)); 996 997 if (sts & ICH_FIFOE) { 998 printf("%s: fifo underrun # %u\n", 999 sc->sc_dev.dv_xname, ++sc->pcmo_fifoe); 1000 } 1001 1002 i = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CIV); 1003 if (sts & (ICH_LVBCI | ICH_CELV)) { 1004 struct auich_dmalist *q; 1005 1006 qptr = sc->ptr_pcmo; 1007 1008 while (qptr != i) { 1009 q = &sc->dmalist_pcmo[qptr]; 1010 1011 q->base = sc->pcmo_p; 1012 q->len = (sc->pcmo_blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1013 DPRINTF(ICH_DEBUG_DMA, 1014 ("auich_intr: %p, %p = %x @ 0x%x\n", 1015 &sc->dmalist_pcmo[i], q, 1016 sc->pcmo_blksize / 2, sc->pcmo_p)); 1017 1018 sc->pcmo_p += sc->pcmo_blksize; 1019 if (sc->pcmo_p >= sc->pcmo_end) 1020 sc->pcmo_p = sc->pcmo_start; 1021 1022 if (++qptr == ICH_DMALIST_MAX) 1023 qptr = 0; 1024 } 1025 1026 sc->ptr_pcmo = qptr; 1027 bus_space_write_1(sc->iot, sc->aud_ioh, 1028 ICH_PCMO + ICH_LVI, 1029 (sc->ptr_pcmo - 1) & ICH_LVI_MASK); 1030 } 1031 1032 if (sts & ICH_BCIS && sc->sc_pintr) 1033 sc->sc_pintr(sc->sc_parg); 1034 1035 /* int ack */ 1036 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_PCMO + sc->sc_sts_reg, 1037 sts & (ICH_LVBCI | ICH_CELV | ICH_BCIS | ICH_FIFOE)); 1038 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_POINT); 1039 ret++; 1040 } 1041 1042 if (gsts & ICH_PIINT) { 1043 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_PCMI+sc->sc_sts_reg); 1044 DPRINTF(ICH_DEBUG_DMA, 1045 ("auich_intr: ists=0x%x\n", sts)); 1046 1047 if (sts & ICH_FIFOE) { 1048 printf("%s: fifo overrun # %u\n", 1049 sc->sc_dev.dv_xname, ++sc->pcmi_fifoe); 1050 } 1051 1052 i = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CIV); 1053 if (sts & (ICH_LVBCI | ICH_CELV)) { 1054 struct auich_dmalist *q; 1055 1056 qptr = sc->ptr_pcmi; 1057 1058 while (qptr != i) { 1059 q = &sc->dmalist_pcmi[qptr]; 1060 1061 q->base = sc->pcmi_p; 1062 q->len = (sc->pcmi_blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1063 DPRINTF(ICH_DEBUG_DMA, 1064 ("auich_intr: %p, %p = %x @ 0x%x\n", 1065 &sc->dmalist_pcmi[i], q, 1066 sc->pcmi_blksize / 2, sc->pcmi_p)); 1067 1068 sc->pcmi_p += sc->pcmi_blksize; 1069 if (sc->pcmi_p >= sc->pcmi_end) 1070 sc->pcmi_p = sc->pcmi_start; 1071 1072 if (++qptr == ICH_DMALIST_MAX) 1073 qptr = 0; 1074 } 1075 1076 sc->ptr_pcmi = qptr; 1077 bus_space_write_1(sc->iot, sc->aud_ioh, 1078 ICH_PCMI + ICH_LVI, 1079 (sc->ptr_pcmi - 1) & ICH_LVI_MASK); 1080 } 1081 1082 if (sts & ICH_BCIS && sc->sc_rintr) 1083 sc->sc_rintr(sc->sc_rarg); 1084 1085 /* int ack */ 1086 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_PCMI + sc->sc_sts_reg, 1087 sts & (ICH_LVBCI | ICH_CELV | ICH_BCIS | ICH_FIFOE)); 1088 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_POINT); 1089 ret++; 1090 } 1091 1092 if (gsts & ICH_MIINT) { 1093 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_MICI+sc->sc_sts_reg); 1094 DPRINTF(ICH_DEBUG_DMA, 1095 ("auich_intr: ists=0x%x\n", sts)); 1096 if (sts & ICH_FIFOE) 1097 printf("%s: fifo overrun\n", sc->sc_dev.dv_xname); 1098 1099 /* TODO mic input dma */ 1100 1101 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_MIINT); 1102 } 1103 1104 return ret; 1105 } 1106 1107 int 1108 auich_trigger_output(void *v, void *start, void *end, int blksize, 1109 void (*intr)(void *), void *arg, struct audio_params *param) 1110 { 1111 struct auich_softc *sc = v; 1112 struct auich_dmalist *q; 1113 struct auich_dma *p; 1114 size_t size; 1115 #ifdef DIAGNOSTIC 1116 int csts; 1117 #endif 1118 1119 DPRINTF(ICH_DEBUG_DMA, 1120 ("auich_trigger_output(%p, %p, %d, %p, %p, %p)\n", 1121 start, end, blksize, intr, arg, param)); 1122 1123 sc->sc_pintr = intr; 1124 sc->sc_parg = arg; 1125 #ifdef DIAGNOSTIC 1126 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1127 if (csts & PCI_STATUS_MASTER_ABORT) { 1128 printf("auich_trigger_output: PCI master abort\n"); 1129 } 1130 #endif 1131 1132 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1133 ; 1134 if (!p) { 1135 printf("auich_trigger_output: bad addr %p\n", start); 1136 return (EINVAL); 1137 } 1138 1139 size = (size_t)((caddr_t)end - (caddr_t)start); 1140 1141 /* 1142 * The logic behind this is: 1143 * setup one buffer to play, then LVI dump out the rest 1144 * to the scatter-gather chain. 1145 */ 1146 sc->pcmo_start = DMAADDR(p); 1147 sc->pcmo_p = sc->pcmo_start + blksize; 1148 sc->pcmo_end = sc->pcmo_start + size; 1149 sc->pcmo_blksize = blksize; 1150 1151 sc->ptr_pcmo = 0; 1152 q = &sc->dmalist_pcmo[sc->ptr_pcmo]; 1153 q->base = sc->pcmo_start; 1154 q->len = (blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1155 if (++sc->ptr_pcmo == ICH_DMALIST_MAX) 1156 sc->ptr_pcmo = 0; 1157 1158 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_BDBAR, 1159 sc->sc_cddma + ICH_PCMO_OFF(0)); 1160 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CTRL, 1161 ICH_IOCE | ICH_FEIE | ICH_LVBIE | ICH_RPBM); 1162 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_LVI, 1163 (sc->ptr_pcmo - 1) & ICH_LVI_MASK); 1164 1165 return (0); 1166 } 1167 1168 int 1169 auich_trigger_input(v, start, end, blksize, intr, arg, param) 1170 void *v; 1171 void *start, *end; 1172 int blksize; 1173 void (*intr)(void *); 1174 void *arg; 1175 struct audio_params *param; 1176 { 1177 struct auich_softc *sc = v; 1178 struct auich_dmalist *q; 1179 struct auich_dma *p; 1180 size_t size; 1181 #ifdef DIAGNOSTIC 1182 int csts; 1183 #endif 1184 1185 DPRINTF(ICH_DEBUG_DMA, 1186 ("auich_trigger_input(%p, %p, %d, %p, %p, %p)\n", 1187 start, end, blksize, intr, arg, param)); 1188 1189 sc->sc_rintr = intr; 1190 sc->sc_rarg = arg; 1191 1192 #ifdef DIAGNOSTIC 1193 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1194 if (csts & PCI_STATUS_MASTER_ABORT) { 1195 printf("auich_trigger_input: PCI master abort\n"); 1196 } 1197 #endif 1198 1199 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1200 ; 1201 if (!p) { 1202 printf("auich_trigger_input: bad addr %p\n", start); 1203 return (EINVAL); 1204 } 1205 1206 size = (size_t)((caddr_t)end - (caddr_t)start); 1207 1208 /* 1209 * The logic behind this is: 1210 * setup one buffer to play, then LVI dump out the rest 1211 * to the scatter-gather chain. 1212 */ 1213 sc->pcmi_start = DMAADDR(p); 1214 sc->pcmi_p = sc->pcmi_start + blksize; 1215 sc->pcmi_end = sc->pcmi_start + size; 1216 sc->pcmi_blksize = blksize; 1217 1218 sc->ptr_pcmi = 0; 1219 q = &sc->dmalist_pcmi[sc->ptr_pcmi]; 1220 q->base = sc->pcmi_start; 1221 q->len = (blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1222 if (++sc->ptr_pcmi == ICH_DMALIST_MAX) 1223 sc->ptr_pcmi = 0; 1224 1225 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_BDBAR, 1226 sc->sc_cddma + ICH_PCMI_OFF(0)); 1227 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, 1228 ICH_IOCE | ICH_FEIE | ICH_LVBIE | ICH_RPBM); 1229 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_LVI, 1230 (sc->ptr_pcmi - 1) & ICH_LVI_MASK); 1231 1232 return (0); 1233 } 1234 1235 int 1236 auich_allocmem(struct auich_softc *sc, size_t size, size_t align, 1237 struct auich_dma *p) 1238 { 1239 int error; 1240 1241 p->size = size; 1242 error = bus_dmamem_alloc(sc->dmat, p->size, align, 0, 1243 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 1244 &p->nsegs, BUS_DMA_NOWAIT); 1245 if (error) 1246 return (error); 1247 1248 error = bus_dmamem_map(sc->dmat, p->segs, p->nsegs, p->size, 1249 &p->addr, BUS_DMA_NOWAIT|sc->sc_dmamap_flags); 1250 if (error) 1251 goto free; 1252 1253 error = bus_dmamap_create(sc->dmat, p->size, 1, p->size, 1254 0, BUS_DMA_NOWAIT, &p->map); 1255 if (error) 1256 goto unmap; 1257 1258 error = bus_dmamap_load(sc->dmat, p->map, p->addr, p->size, NULL, 1259 BUS_DMA_NOWAIT); 1260 if (error) 1261 goto destroy; 1262 return (0); 1263 1264 destroy: 1265 bus_dmamap_destroy(sc->dmat, p->map); 1266 unmap: 1267 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 1268 free: 1269 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 1270 return (error); 1271 } 1272 1273 int 1274 auich_freemem(struct auich_softc *sc, struct auich_dma *p) 1275 { 1276 1277 bus_dmamap_unload(sc->dmat, p->map); 1278 bus_dmamap_destroy(sc->dmat, p->map); 1279 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 1280 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 1281 return (0); 1282 } 1283 1284 int 1285 auich_alloc_cdata(struct auich_softc *sc) 1286 { 1287 bus_dma_segment_t seg; 1288 int error, rseg; 1289 1290 /* 1291 * Allocate the control data structure, and create and load the 1292 * DMA map for it. 1293 */ 1294 if ((error = bus_dmamem_alloc(sc->dmat, 1295 sizeof(struct auich_cdata), 1296 PAGE_SIZE, 0, &seg, 1, &rseg, 0)) != 0) { 1297 printf("%s: unable to allocate control data, error = %d\n", 1298 sc->sc_dev.dv_xname, error); 1299 goto fail_0; 1300 } 1301 1302 if ((error = bus_dmamem_map(sc->dmat, &seg, rseg, 1303 sizeof(struct auich_cdata), 1304 (caddr_t *) &sc->sc_cdata, 1305 sc->sc_dmamap_flags)) != 0) { 1306 printf("%s: unable to map control data, error = %d\n", 1307 sc->sc_dev.dv_xname, error); 1308 goto fail_1; 1309 } 1310 1311 if ((error = bus_dmamap_create(sc->dmat, sizeof(struct auich_cdata), 1, 1312 sizeof(struct auich_cdata), 0, 0, 1313 &sc->sc_cddmamap)) != 0) { 1314 printf("%s: unable to create control data DMA map, " 1315 "error = %d\n", sc->sc_dev.dv_xname, error); 1316 goto fail_2; 1317 } 1318 1319 if ((error = bus_dmamap_load(sc->dmat, sc->sc_cddmamap, 1320 sc->sc_cdata, sizeof(struct auich_cdata), 1321 NULL, 0)) != 0) { 1322 printf("%s: unable tp load control data DMA map, " 1323 "error = %d\n", sc->sc_dev.dv_xname, error); 1324 goto fail_3; 1325 } 1326 1327 return (0); 1328 1329 fail_3: 1330 bus_dmamap_destroy(sc->dmat, sc->sc_cddmamap); 1331 fail_2: 1332 bus_dmamem_unmap(sc->dmat, (caddr_t) sc->sc_cdata, 1333 sizeof(struct auich_cdata)); 1334 fail_1: 1335 bus_dmamem_free(sc->dmat, &seg, rseg); 1336 fail_0: 1337 return (error); 1338 } 1339 1340 void 1341 auich_powerhook(int why, void *addr) 1342 { 1343 struct auich_softc *sc = (struct auich_softc *)addr; 1344 1345 switch (why) { 1346 case PWR_SUSPEND: 1347 case PWR_STANDBY: 1348 /* Power down */ 1349 DPRINTF(1, ("%s: power down\n", sc->sc_dev.dv_xname)); 1350 sc->sc_suspend = why; 1351 auich_read_codec(sc, AC97_REG_EXT_AUDIO_CTRL, &sc->ext_status); 1352 break; 1353 1354 case PWR_RESUME: 1355 /* Wake up */ 1356 DPRINTF(1, ("%s: power resume\n", sc->sc_dev.dv_xname)); 1357 if (sc->sc_suspend == PWR_RESUME) { 1358 printf("%s: resume without suspend.\n", 1359 sc->sc_dev.dv_xname); 1360 sc->sc_suspend = why; 1361 return; 1362 } 1363 sc->sc_suspend = why; 1364 auich_reset_codec(sc); 1365 DELAY(1000); 1366 (sc->codec_if->vtbl->restore_ports)(sc->codec_if); 1367 auich_write_codec(sc, AC97_REG_EXT_AUDIO_CTRL, sc->ext_status); 1368 break; 1369 1370 case PWR_SOFTSUSPEND: 1371 case PWR_SOFTSTANDBY: 1372 case PWR_SOFTRESUME: 1373 break; 1374 } 1375 } 1376 1377 1378 /* -------------------------------------------------------------------- */ 1379 /* Calibrate card (some boards are overclocked and need scaling) */ 1380 1381 void 1382 auich_calibrate(struct device *self) 1383 { 1384 struct auich_softc *sc; 1385 struct timeval t1, t2; 1386 u_int8_t ociv, nciv; 1387 u_int32_t wait_us, actual_48k_rate, bytes, ac97rate; 1388 void *temp_buffer; 1389 struct auich_dma *p; 1390 1391 sc = (struct auich_softc*)self; 1392 /* 1393 * Grab audio from input for fixed interval and compare how 1394 * much we actually get with what we expect. Interval needs 1395 * to be sufficiently short that no interrupts are 1396 * generated. 1397 */ 1398 1399 /* Setup a buffer */ 1400 bytes = 16000; 1401 temp_buffer = auich_allocm(sc, AUMODE_RECORD, bytes, M_DEVBUF, M_WAITOK); 1402 for (p = sc->sc_dmas; p && KERNADDR(p) != temp_buffer; p = p->next) 1403 ; 1404 if (p == NULL) { 1405 printf("auich_calibrate: bad address %p\n", temp_buffer); 1406 return; 1407 } 1408 sc->dmalist_pcmi[0].base = DMAADDR(p); 1409 sc->dmalist_pcmi[0].len = (bytes / sc->sc_sample_size) | ICH_DMAF_IOC; 1410 1411 /* 1412 * our data format is stereo, 16 bit so each sample is 4 bytes. 1413 * assuming we get 48000 samples per second, we get 192000 bytes/sec. 1414 * we're going to start recording with interrupts disabled and measure 1415 * the time taken for one block to complete. we know the block size, 1416 * we know the time in microseconds, we calculate the sample rate: 1417 * 1418 * actual_rate [bps] = bytes / (time [s] * 4) 1419 * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4) 1420 * actual_rate [Hz] = (bytes * 250000) / time [us] 1421 */ 1422 1423 /* prepare */ 1424 ociv = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CIV); 1425 nciv = ociv; 1426 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_BDBAR, 1427 sc->sc_cddma + ICH_PCMI_OFF(0)); 1428 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_LVI, 1429 (0 - 1) & ICH_LVI_MASK); 1430 1431 /* start */ 1432 microtime(&t1); 1433 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RPBM); 1434 1435 /* wait */ 1436 while (nciv == ociv) { 1437 microtime(&t2); 1438 if (t2.tv_sec - t1.tv_sec > 1) 1439 break; 1440 nciv = bus_space_read_1(sc->iot, sc->aud_ioh, 1441 ICH_PCMI + ICH_CIV); 1442 } 1443 microtime(&t2); 1444 1445 /* stop */ 1446 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, 0); 1447 1448 /* reset */ 1449 DELAY(100); 1450 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RR); 1451 1452 /* turn time delta into us */ 1453 wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec; 1454 1455 auich_freem(sc, temp_buffer, M_DEVBUF); 1456 1457 if (nciv == ociv) { 1458 printf("%s: ac97 link rate calibration timed out after %d us\n", 1459 sc->sc_dev.dv_xname, wait_us); 1460 return; 1461 } 1462 1463 actual_48k_rate = (bytes * 250000U) / wait_us; 1464 1465 if (actual_48k_rate <= 48500) 1466 ac97rate = 48000; 1467 else 1468 ac97rate = actual_48k_rate; 1469 1470 printf("%s: measured ac97 link rate at %d Hz", 1471 sc->sc_dev.dv_xname, actual_48k_rate); 1472 if (ac97rate != actual_48k_rate) 1473 printf(", will use %d Hz", ac97rate); 1474 printf("\n"); 1475 1476 sc->codec_if->vtbl->set_clock(sc->codec_if, ac97rate); 1477 } 1478